Skip to main content

Python version of traceroute which is path aware

Project description


PyPI - Status PyPI version PyPI downloads PyPI - Python Version Docker Pulls Build Status Coverage Status Code style: Black GitHub


traceflow is a utility written for educational purposes.

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.

By 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.

The goal is to develop this utility to a point where it can be useful in production networks to detect the following:

  • Pre/post maintanace path changes
  • as-path relax scenarios across IXPs/ISPs
  • IP Topology discovery and visualisation


traceflow can be installed via pip:

pip install traceflow

Alternatively, you can build from source and install manually:

python3 bdist_wheel
pip install ./dist/traceflow*any.whl


Usage 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).

$ python3
Resolved to
Looking at Path ID 1 (src port:33453 , dst port:33452)
Looking at Path ID 2 (src port:33454 , dst port:33452)
Looking at Path ID 3 (src port:33455 , dst port:33452)
Looking at Path ID 4 (src port:33456 , dst port:33452)
TTL:              | 1                 | 2                 | 3                 | 4                 | 5                 | 6                 | 7                 | 8                 | 9                 | 10                | 11                | 12                | 13                |
Path ID 1         |       |     |    |    |    |      |   |     |    |      |     |      |    |
Path ID 2         |       |     |    |    |    |      |   |    |    |     |     |      |    |
Path ID 3         |       |     |    |    |    |      |   |     |    |      |     |      |    |
Path ID 4         |       |     |    |    |    |      |   |    |    |     |     |      |    |

An example of vis.js outputs is as follows:


More detailed help available in --help.


traceflow can also be ran as a Docker container.

The latest version of traceflow is also on Docker Hub (

$ docker run -i -t awlnx/traceflow

To host the vis.js output through Docker:

$ docker run -p -i -t awlnx/traceflow --format=viz --bind=

Note 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.

To build it on your local machine do the following:

$ docker build -t traceflow .


I 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.

Protocol used

The 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.

These days, most networks are using 3-tuple hashing in their forwarding decisions for load balancing: src/dst IP, proto, src/dst Port.

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.

To 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.

This idea came to me in Stockholm, so I would like to call it Stockholm traceroute.


  • Pure python3, only 1 single external dependency (argparse)
  • Multi-threaded approach, we no longer need to wait for a return packet for each probe
  • Will identify and print unique paths in three different formats (Including browser based)
  • Detects uneven path lengths
  • Has a packet encoding and decoding library


  • Duplicate path detection
  • IPv6 Support
  • MPLS Support (Sending and decoding)
  • TCP Support (Currently UDP only)
  • Support for vis.js
  • Understand raw sockets on OSX correctly to add support
  • Test on Windows
  • Add more resiliance to the code
  • Implement ICMP probes to detect hosts which dont generate Port Unreachable
  • Time stamps / latency


  • Currently not very good at handling unequal length paths
  • Darwin/OSX not functional yet
  • Probably lots more


It's possible to pass the --debug flag for very verbose logging.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release. See tutorial on generating distribution archives.

Built Distribution

traceflow-0.4-py3-none-any.whl (16.1 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Fastly Fastly CDN Google Google Object Storage and Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page