Dublin Traceroute

News - Blog

Dublin Traceroute now has a blog! Check it out at https://blog.dublin-traceroute.net .

What is it?

Dublin Traceroute is a NAT-aware multipath tracerouting tool

Again.. what?

You know, networks are way more complex now than years ago, and there can be multiple paths between two network entities (like your phone, your laptop, some remote server, etc). This way of routing packets is called ECMP, or Equal-Cost MultiPath, and is used to increase the capacity and the reliability of a network.
Running a regular traceroute in an ECMP-enabled network can cause headache, so tools like paris-traceroute exist.

How does it work?

Dublin Traceroute uses the techniques invented by the authors of Paris-traceroute to enumerate the paths of ECMP flow-based load balancing, but introduces a new technique for NAT detection.

For what matters the multi-path enumeration, there is a nice explanation on Paris-traceroute’s about page. In short, anyway, an IP packet travelling between two hosts may take different paths depending on whether (and how) the intermediate routers implement load balancing. This load balancing, as mentioned above, is called ECMP. The problem with ECMP and traceroute is that a regular traceroute cannot tell which path an hop corresponds to. A visual example will make it easier to understand:

multipath network
[diagram source]

In the graph above it’s easy to see that there are more than one “second hop” or “third hop” and so on. A regular traceroute is not able to force all the packets throuh the same path, so it may traverse the paths in an irregular way, for example:

regular traceroute on an ECMP network
[diagram source]

The black links are the possible paths, the red link is what a regular traceroute may see.

This is of course wrong. It gets ever worse when two equal cost paths have different lengths:

regular traceroute on variable-length ECMP network
[diagram source]

The team who created Paris-traceroute invented a technique that leverages the ECMP flow hashing to probe all the possible paths. Dublin Traceroute does what Paris-traceroute can do, plus a bit more.

So, what’s new?

Three things:

One is the way NATs are detected.
Dublin Traceroute forges the IP ID in the probe packet and analyzes the responses in order to detect all the encountered NATs. This is a new algorithm, not found in other network mapping solutions, despite the IP ID is not new for NAT-related tasks. For example, Paris-traceroute uses the IP ID to tell whether a loop in a traceroute is due to a NAT box, using the IP ID of the response packet as explained by Steven Bellovin in his paper A technique for Counting NATted Hosts.

I make this distinction because you may claim that Paris-traceroute already detects NAT boxes, but this is actually very different: Paris-traceroute can tell you whether a hop that appears as a loop in a traceroute is due to NAT, while Dublin Traceroute can tell you whether there is a NAT after a given point, and can also identify multiple NATs. At the best of my knowledge, there is no tool nor public research using this technique. If I am wrong, please let me know so that I can give the credit where due.

The second is that it is a modular rewrite.
Dublin Traceroute is written in C++11 on top of a beautiful network packet sniffing and crafting library, libtins. Dublin Traceroute also features a Python extension on top of the C++ core if you prefer. The bindings now live in a separate repository, see python-dublin-traceroute .

The third is that it supports broken NATs. Dublin Traceroute is able to work with some broken NATs that some hosting providers use (~e.g. I found that Scaleway does that~ update: they fixed it, see https://github.com/insomniacslk/dublin-traceroute/issues/28). Neither paris-traceroute nor regular traceroute would work with it, but it’s not their fault as this is a network misconfiguration. When you run a regular traceroute or paris-traceroute through this kind of NAT, you will see no response from all the hops located just after these broken NAT boxes.

See the examples to see Dublin Traceroute at work.


Paris-traceroute is a nice tool, and the research behind it is really cool. The implementation is a good proof-of-concept, but I needed more.

It all started as an excuse to learn more about C++11. My curiosity started after finding a packet sniffing and crafting library that caught my attention. So I decided to write a C++11 implementation of Paris-traceroute, but I wanted it to be flexible, expressive and simple to understand. I have hence created a C++ shared library and a Python module to make it easily usable and embeddable.


Below the graphical output of a traceroute to Google’s public DNS, You can see the various paths, the NAT detecton and the ICMP codes of the received packets.

dublin-traceroute example

See the examples page for more examples on the command-line tool and the C++ and Python libraries.


Dublin Traceroute aims to be:

Installation instructions

From packages

Dublin Traceroute is packaged in Debian and Ubuntu, yet still in the testing repos. To install it (as root):

on Debian:

or alternatively without adding the repository:

apt-get install dublin-traceroute -t testing

on Ubuntu:

on CentOS 7:

Sorry, no GPG verification yet, and no CentOS 6 yet :(

From source

Independently of the OS, to build dublin-traceroute you need: * cmake * gcc >= 4.9 or clang >= 3.8

Building on Linux

Building on OS X

brew install https://raw.githubusercontent.com/insomniacslk/dublin-traceroute/master/homebrew/dublin-traceroute.rb

This will be as simple as brew install dublin-traceroute after https://github.com/Homebrew/homebrew/pull/50000 will be merged.


Note that if setcap is found when installing, it is used to set the

This allows any regular user to run ```dublin-traceroute``` without root privileges
but to be still able to use raw sockets, necessary to forge the traceroute packets.
If ```setcap``` is not found, the set-uid bit is set. If you don't want any of these,
you have to run it as root.

### Other hints

It will use your default compiler. Alternatively, if you prefer, you can force a
different compiler. For GCC:

bash CXX=g++ make

or for clang:

bash CXX=clang++ make

## Running

`dublin-traceroute` requires raw sockets. This means that you should need the CAP_NET_RAW capability set (see `setcap(8)`). Alternatively you can run it as root, but this is not recommended, and `dublin-traceroute` will print a warning.

The usage is very simple, and explained in the help message:

bash $ ./dublin-traceroute –help Dublin Traceroute v0.3.3 Written by Andrea Barberio - https://insomniac.slackware.it

Usage: dublin-traceroute [–sport=SRC_PORT] [–dport=dest_base_port] [–npaths=num_paths] [–min-ttl=min_ttl] [–max-ttl=max_ttl] [–delay=delay_in_ms] [–broken-nat] [–help] [–version]

Options: -h –help this help -v –version print the version of Dublin Traceroute -s SRC_PORT –sport=SRC_PORT the source port to send packets from -d DST_PORT –dport=DST_PORT the base destination port to send packets to -n NPATHS –npaths=NPATHS the number of paths to probe -t MIN_TTL –min-ttl=MIN_TTL the minimum TTL to probe -T MAX_TTL –max-ttl=MAX_TTL the maximum TTL to probe. Must be greater or equal than the minimum TTL -D DELAY –delay=DELAY the inter-packet delay -b –broken-nat the network has a broken NAT configuration (e.g. no payload fixup). Try this if you see fewer hops than expected

See documentation at https://dublin-traceroute.net Please report bugs at https://github.com/insomniacslk/dublin-traceroute Additional features in the Python module at https://github.com/insomniacslk/python-dublin-traceroute

## Running via Docker

You can see dublin-traceroute at work using the docker image [`insomniacslk/dublin-traceroute`](https://cloud.docker.com/u/insomniacslk/repository/docker/insomniacslk/dublin-traceroute).
Just run:

sudo docker run -v “$PWD/output:/output” insomniacslk/dublin-traceroute `` This will rundublin-traceroute produce output files in theoutput` directory.

What is missing?

At the moment, a lot of things, including:

See TODO.md for more details.


Why the name Dublin Traceroute?

Paris-traceroute was named after the french capital since the research and the development happened there. In my case, it happened in the city where I live and work, Dublin, hence the name.

You say this is your first C++ project. Is this an excuse to say that the code sucks?


How do I ask a question or contribute?

Go to the Dublin Traceroute mailing list or to IRC, #dublin-traceroute @ FreeNode, and just ask :)

Otherwise you can open an issue or make a pull request on the GitHub page of dublin-traceroute, or contact me directly (see below).

What is the license of Dublin Traceroute?

The 2-clause BSD

Who are you?

My name is Andrea Barberio, you can find more about me at https://insomniac.slackware.it