{ "info": { "author": "Ruairi Carroll", "author_email": "ruairi.carroll@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# traceflow\n\n[![PyPI - Status](https://img.shields.io/pypi/status/traceflow)](https://pypi.org/project/traceflow/)\n[![PyPI version](https://img.shields.io/pypi/v/traceflow.svg)](https://pypi.org/project/traceflow/)\n[![PyPI downloads](https://img.shields.io/pypi/dm/traceflow.svg)](https://pypistats.org/packages/traceflow)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/traceflow)](https://pypi.org/project/traceflow/)\n[![Docker Pulls](https://img.shields.io/docker/pulls/awlnx/traceflow)](https://hub.docker.com/r/awlnx/traceflow)\n[![Build Status](https://travis-ci.org/rucarrol/traceflow.svg)](https://travis-ci.org/rucarrol/traceflow)\n[![Coverage Status](https://coveralls.io/repos/github/rucarrol/traceflow/badge.svg)](https://coveralls.io/github/rucarrol/traceflow)\n[![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![GitHub](https://img.shields.io/github/license/rucarrol/traceflow.svg)](LICENSE)\n\n## Intro\n\n`traceflow` is a utility written for educational purposes.\n\n`traceflow` which attempts to enumerate the number of paths between this host and a given destination. The mechanism for this is by not varying the destination source or destination port by TTL, thus keeping the inputs to any flow hashing calculations by routers along the path consistent for a single run. Then for each new run, vary the source port.\n\nBy using raw sockets, `traceflow` can set the `IP.ID` of egress IP packets to both the Path ID and TTL, thus enabling us to match up return packets to a path easily.\n\nThe goal is to develop this utility to a point where it can be useful in production networks to detect the following:\n\n- Pre/post maintanace path changes\n- as-path relax scenarios across IXPs/ISPs\n- IP Topology discovery and visualisation\n\n\n## Installation\n\n`traceflow` can be installed via pip:\n\n```\npip install traceflow\n```\n\nAlternatively, you can build from source and install manually:\n\n```\npython3 setup.py bdist_wheel\npip install ./dist/traceflow*any.whl\n```\n\n## Usage\n\nUsage should be designed to be as straight forward as possible. There are currently 3 output formats supported - Vertical Output (`--format=vert`), Horizontal output(`--format=horiz`) and experimental Vis.js/Browser based output(`--format=viz`).\n\n```\n$ python3 traceflow.py www.telia.se\nResolved www.telia.se to 81.236.63.162\nLooking at Path ID 1 (src port:33453 , dst port:33452)\nLooking at Path ID 2 (src port:33454 , dst port:33452)\nLooking at Path ID 3 (src port:33455 , dst port:33452)\nLooking at Path ID 4 (src port:33456 , dst port:33452)\nTTL: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |\nPath ID 1 | 192.168.0.1 | 84.116.236.63 | 84.116.239.133 | 62.115.172.136 | 62.115.120.100 | 80.91.249.11 | 213.155.130.101 | 80.91.245.159 | 62.115.123.159 | 81.228.88.48 | 81.228.84.173 | 81.228.94.41 | 90.228.166.164 |\nPath ID 2 | 192.168.0.1 | 84.116.236.63 | 84.116.239.133 | 62.115.172.136 | 62.115.120.100 | 80.91.249.11 | 213.155.130.101 | 62.115.142.215 | 62.115.123.163 | 81.228.88.128 | 81.228.84.173 | 81.228.94.41 | 90.228.166.164 |\nPath ID 3 | 192.168.0.1 | 84.116.236.63 | 84.116.239.133 | 62.115.172.136 | 62.115.120.100 | 80.91.249.11 | 213.155.130.101 | 62.115.121.15 | 62.115.123.159 | 81.228.88.48 | 81.228.84.173 | 81.228.94.41 | 90.228.166.164 |\nPath ID 4 | 192.168.0.1 | 84.116.236.63 | 84.116.239.133 | 62.115.172.136 | 62.115.120.100 | 80.91.249.11 | 213.155.130.101 | 62.115.142.215 | 62.115.123.163 | 81.228.91.142 | 81.228.84.173 | 81.228.94.41 | 90.228.166.164 |\n```\n\nAn example of vis.js outputs is as follows:\n\n![vis.js](https://github.com/rucarrol/traceflow/raw/master/docs/traceflow_vis.png)\n\nMore detailed help available in `--help`.\n\n## Docker\n\n`traceflow` can also be ran as a Docker container.\n\nThe latest version of traceflow is also on Docker Hub (https://hub.docker.com/r/awlnx/traceflow).\n\n```\n$ docker run -i -t awlnx/traceflow www.telia.se\n```\n\nTo host the vis.js output through Docker:\n\n```\n$ docker run -p 127.0.0.1:8081:8081 -i -t awlnx/traceflow --format=viz --bind=0.0.0.0 www.telia.se\n```\n\nNote that it is required to bind the web server to the address of a public interface (inside the container) to be able to reach the web page.\n\nTo build it on your local machine do the following:\n\n```\n$ docker build -t traceflow .\n```\n\n## Why\n\nI wanted to learn more about raw sockets, traceroute and also wanted to try vary traceroute to be more flow/path aware, rather than hop aware.\n\n## Protocol used\n\nThe classical traceroutes (Dublin, Paris) attempt to enumerate the hops along a path by using many different entropy sources in the IP and UDP/TCP headers.\n\nThese days, most networks are using 3-tuple hashing in their forwarding decisions for load balancing: src/dst IP, proto, src/dst Port.\n\n`traceflow` does the exact opposite here. We only vary two fields on each run - IP.ID, TTL. Then for subsequent runs, we only vary the UDP source port. Thus we can attempt to reliably test which flows would normally be combined into one output from traceroute, Paris traceroute and Dublin traceroute.\n\nTo detect return packets, we use the IP.ID in the IP header to store state - the path ID we're looking up, and the TTL of the egress packet. This allows us to implement a much faster multithreaded approach, as well as detect uneven hashing. It does bring a downside of being a bit more chatty than regular traceroute.\n\nThis idea came to me in Stockholm, so I would like to call it Stockholm traceroute.\n\n\n## Features\n\n- Pure python3, only 1 single external dependency (argparse)\n- Multi-threaded approach, we no longer need to wait for a return packet for each probe\n- Will identify and print unique paths in three different formats (Including browser based)\n- Detects uneven path lengths\n- Has a packet encoding and decoding library\n\n\n\n## TODO\n\n- Duplicate path detection\n- IPv6 Support\n- MPLS Support (Sending and decoding)\n- TCP Support (Currently UDP only)\n- Support for vis.js\n- Understand raw sockets on OSX correctly to add support\n- Test on Windows\n- Add more resiliance to the code\n- Implement ICMP probes to detect hosts which dont generate Port Unreachable\n- Time stamps / latency\n\n\n## Bugs\n\n- Currently not very good at handling unequal length paths\n- Darwin/OSX not functional yet\n- Probably lots more\n\n## Debugging\n\nIt's possible to pass the `--debug` flag for very verbose logging.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rucarrol/traceflow", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "traceflow", "package_url": "https://pypi.org/project/traceflow/", "platform": "", "project_url": "https://pypi.org/project/traceflow/", "project_urls": { "Homepage": "https://github.com/rucarrol/traceflow" }, "release_url": "https://pypi.org/project/traceflow/0.4/", "requires_dist": null, "requires_python": ">=3.5", "summary": "Python version of traceroute which is path aware", "version": "0.4" }, "last_serial": 6003687, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "eead2deac5203a61a241da6a98b024a7", "sha256": "e4bb360b74c8afe08e6e3dd63bf7ff08a7d7d3e9699dc75e0db142dbc916458d" }, "downloads": -1, "filename": "traceflow-0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "eead2deac5203a61a241da6a98b024a7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 16956, "upload_time": "2019-09-24T07:40:22", "url": "https://files.pythonhosted.org/packages/2d/22/f181840a5e5fb35d8d8f0c85101da7cf08066b0f420161d6c9ad75dfd159/traceflow-0.1-py3-none-any.whl" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "9b2458ab16f64789566bafdbed01fff2", "sha256": "74ecf6004d44bba1ff50e1bd9a5fd962f15791f3e3f73feb260a64dab7554c55" }, "downloads": -1, "filename": "traceflow-0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "9b2458ab16f64789566bafdbed01fff2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 21444, "upload_time": "2019-09-24T16:48:25", "url": "https://files.pythonhosted.org/packages/b5/0b/c4d0fe1f23820ceebc3cca45527f80f72f8f564c3b76c289cd3d05148d6e/traceflow-0.2-py3-none-any.whl" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "4271821963cc1853ab1db2a393dd0d18", "sha256": "043ca29bb52adfe5d495607c1c4f9eebc9eeeea9c58bbdfa93182c59ee8e047e" }, "downloads": -1, "filename": "traceflow-0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "4271821963cc1853ab1db2a393dd0d18", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 21736, "upload_time": "2019-09-25T08:11:05", "url": "https://files.pythonhosted.org/packages/ec/e1/ed2bed5bb23c4356b596d4058f9d9d4d1e1b2ea849089fc5fa1270c8a7eb/traceflow-0.3-py3-none-any.whl" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "dd3b5a2b15ffd243483db24ee163c42a", "sha256": "9288c2586179fe673249ffd1def0b5871ba8b1b543eeaa0ddc18e9079ce275bd" }, "downloads": -1, "filename": "traceflow-0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "dd3b5a2b15ffd243483db24ee163c42a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16052, "upload_time": "2019-10-20T17:59:28", "url": "https://files.pythonhosted.org/packages/21/34/4153649b577ff7bbeca7eef68bfe005683153e4d008ea89ff77e022187be/traceflow-0.4-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "dd3b5a2b15ffd243483db24ee163c42a", "sha256": "9288c2586179fe673249ffd1def0b5871ba8b1b543eeaa0ddc18e9079ce275bd" }, "downloads": -1, "filename": "traceflow-0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "dd3b5a2b15ffd243483db24ee163c42a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16052, "upload_time": "2019-10-20T17:59:28", "url": "https://files.pythonhosted.org/packages/21/34/4153649b577ff7bbeca7eef68bfe005683153e4d008ea89ff77e022187be/traceflow-0.4-py3-none-any.whl" } ] }