traceroute sends UDP packets to port 33434 (and up) by default.

I assume mtr -u (manual, homepage, github) does the same, but I can't find any documentation or test results to verify the destination port numbers.

Does mtr -u use destination port 33434 and then increment, like traceroute?

  • Use strace and grep for connect or sendto. This will show you the port numbers.
    – ctrl-d
    Jun 29 '18 at 21:33

TL;DR By default, it starts at 33000 and goes up.

You can observe it if you run a network trace at the same time:

tcpdump -i any -n host &
mtr -u --report -c 1
21:21:50.777482 IP [redacted].31507 > UDP, length 36
21:21:50.877579 IP [redacted].31507 > UDP, length 36
21:21:50.977694 IP [redacted].31507 > UDP, length 36
21:21:51.077850 IP [redacted].31507 > UDP, length 36
21:21:51.177966 IP [redacted].31507 > UDP, length 36
21:21:51.278081 IP [redacted].31507 > UDP, length 36
21:21:51.378198 IP [redacted].31507 > UDP, length 36
21:21:51.478341 IP [redacted].31507 > UDP, length 36
21:21:51.578498 IP [redacted].31507 > UDP, length 36
21:21:51.678646 IP [redacted].31507 > UDP, length 36
21:21:51.778801 IP [redacted].31507 > UDP, length 36
21:21:51.878949 IP [redacted].31507 > UDP, length 36
21:21:51.979117 IP [redacted].31507 > UDP, length 36

Here is why in the code.

The source code is at https://github.com/traviscross/mtr

If you analyze it, you observe the different behavior between TCP and UDP during parsing of command line arguments:

    case 'u':
        if (ctl->mtrtype != IPPROTO_ICMP) {
            error(EXIT_FAILURE, 0,
                  "-u , -T and -S are mutually exclusive");
        ctl->mtrtype = IPPROTO_UDP;
    case 'T':
        if (ctl->mtrtype != IPPROTO_ICMP) {
            error(EXIT_FAILURE, 0,
                  "-u , -T and -S are mutually exclusive");
        if (!ctl->remoteport) {
            ctl->remoteport = 80;
        ctl->mtrtype = IPPROTO_TCP;

So no port is set by default for UDP, where it is 80 by default for TCP.

mtr.h has

#define MinPort 1024
#define MaxPort 65535

but this is misleading, the true stuff happens in ui/net.c.

  1. net_send_query calls new_sequence
  2. and the results is passed among other things to send_probe_command
  3. new_sequence in this file has static int next_sequence = MinSequence;

Now, after a lot of hops you arrive in set_udp_ports which has:

    if (param->dest_port) {
    } else {
        udp->dstport = htons(sequence);

In short, the "sequence" number is really the UDP destination port.

And if we go back at ui/net.c we see it is defined as:

#define MinSequence 33000
#define MaxSequence 65536

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.