The comment in struct_ip.h explains the reasoning for this. The AIX C library
uses #defines that change the names of members of struct ip, and conflict with
some existing code. (Notably struct ip_hdr in libdnet and IPv4Header::h in
libnetutil.) We can still use the AIX files if we include <netinet/ip.h> after
this other code has been preprocessed. That's hard to enforce when
<netinet/ip.h> is included from another header file; this new file allows
including it always late, and only where needed.
Heretofore we have always extracted teh destination address directly
from the packet contents. But the raw packet bytes do not contain enough
information in one case: IPv6 link-local addresses. For those we really
need the scope ID, and for that we must pass this information all the
way down.
Before this, I got "no route to host" on OS link-local addresses. I
think that it was working on Linux only on accident, by the OS picking a
default interface or something.
We should have the multiprotocol version be the main version, with
IPv4-only code being a noted exception. Also these functions are almost
the same so one can call the other.
before starting. There is a special function that does a trace of
directly connected targets without sending any packets, just by filling
in one hop directly to the target. The traceroute code was only checking
whether the first target in the group was directly connected, and if it
was, it assumed all of them were. Now it filters the list into two and
calls traceroute_direct on one and traceroute_remote on the other.
Fyodor discovered this problem today.
terminate called after throwing an instance of 'std::out_of_range'
what(): bitset::test
It happened when the preliminary distance guess for a target was
greater than 30, the size of an internal data structure. David and
Brandon tracked down the problem.
resolution. The initialization
struct sockaddr_in sin = { AF_INET };
didn't set sin.sin_family correctly, leading to a later assertion
failure:
Failed to convert target address to presentation format!?! Error: Address family not supported by protocol family
message. The dereferencing could not actually happen because it would
only happen with a trace of zero hops with no probes sent, and in that
case we skip the traceroute entirely. Patch by Ankur Nandwani.
the network distance in SCAN.DS was calculated. Its value can be "L"
for localhost, "D" for a direct connection, "I" for an ICMP TTL
calculation, and "T" for a traceroute hop count. This is mainly for
the benefit of OS integration, when it is sometimes important to
distinguish between DS=1%DC=I (probably the result of forged TTLs)
and DS=1%DC=D (a true one-hop connection.) [David]
was incorrect; the hopDistance member can be much higher than the actual
number of hops recorded. It was 33 when the real distance was 17.
Instead, enumerate and count all the probes that got a response.
mapping from source port number to probes. Upon output, the map was
transformed in place to a map of TTL values to probes. Operations that
worked before output wouldn't work after output and vice versa. Now the
TTL-to-probe map is kept separate in a local variable.
the list of consolidated hops (the ones that match the reference trace)
was printed out one hop further than it should have been. So if a trace
diverged from the reference trace at the sixth hop, it would print out
the first six hops of the reference trace when it should have done only
five. This extra row, as well as being incorrect, could cause an
assertion failure by making the output table one row bigger than its
preallocated capacity.
I can find the bug that causes too many rows to be printed in debugging
mode in some cases. I get an assertion failure when running
nmap scanme.nmap.org/26 --top-ports 10 --traceroute -n -d
With this change, the bug manifests itself as some peculiar output:
4 -- 66.54.149.185
5 -- 63.211.250.17
5 39.17 ms 63.211.250.17
6 47.12 ms 4.68.107.190
7 39.72 ms 4.69.132.37
(Note the doubled 5 with the same IP address.)
10 -- 207.88.13.122
11 -- 207.88.12.46
12 -- 207.88.12.61
13 -- 65.106.1.57
13 100.77 ms 65.106.1.65
14 91.75 ms 65.106.5.162
(Note the doubled 13 with a different IP address.)
4 -- 66.54.149.185
5 -- 63.211.250.17
5 ...
6 39.32 ms 4.68.107.190
(Note the doubled 5 with a timeout.)
can happen with -PN against a filtered host or with -PN -sP against any
host.
This works as expected when the remote host actually responds to the
ping probes, but takes a long time when the remote host ignores it. Take
this for example:
nmap -PN -sP --traceroute www.microsoft.com -n
TRACEROUTE (using proto 1/icmp)
HOP RTT ADDRESS
1 0.77 192.168.0.1
2 38.76 206.81.73.81
3 38.65 206.81.73.82
4 39.28 66.54.149.185
5 39.73 63.211.250.17
6 39.15 4.68.107.190
7 40.05 4.69.132.37
8 59.33 4.69.132.106
9 54.55 4.69.145.208
10 ...
11 ...
[Lots more lines]
49 ...
50 ...
! maximum TTL reached (50)
Nmap done: 1 IP address (1 host up) scanned in 2201.79 seconds
The traceroute can't stop, as it normally does, when it gets a response
from the target because no such response is forthcoming. So it keeps
going until it hits its own limit. The same trace against www.google.com
takes only about 30 seconds.