For some reason (probably by imitation of nmap_getservbyport), protocol
numbers, which are byte values 0–255, had htons called on them after
being read from nmap-protocols. On little-endian platforms, this turned
them into integers 0x0100, 0x0200, 0x0300, etc.
protocol_table is supposed to be an array of 256 linked lists, linking
all the protocol names of the same number. Because of the above htons
conversion, all protocols mapped to bucket 0 on lookup instead. Perhaps
in an attempt to work around this broken lookup, all protocols were
inserted into bucket 0 on init; all other buckets were empty. This
worked on little-endian platforms, but on big-endian platforms where
htons is a no-op, all protocol numbers but 0 mapped to an empty linked
list.
Remove all the htons stuff and just look things up by integers. Use the
same mapping on initial insertion and on lookup, so that the buckets are
acutally populated.
This was noticed by hejianet.
http://seclists.org/nmap-dev/2012/q3/1005
rpc.Comm.Connect was trying to bind to 424 reserved ports, which is
overkill. Since nsock doesn't do an actual bind(2) call until
socket:connect for TCP, that meant up to 424 connect calls, each of
which is currently leaking a socket. This commit contains 3 fixes:
1. Add nmap.new_socket calls for non-privileged code path that were
moved inside the privileged loop to originally address the leak.
2. Check for TIMEOUT on each of the TCP connect calls and abandon the
Connect, avoiding many timeouts.
3. Try 10 random reserved ports (from 1 to 1024) instead of 400+.
Should be good odds of finding one unused, even when lots of threads are
trying (though empirical results would be helpful). Also, this should
reduce load since thread n won't need to fail n-1 bind attempts.
It appears that connecting more than one with the same nse_nsock socket
leaks socket descriptor. For example,
local s = nmap.new_socket()
s:connect(host, port) --> TIMEOUT
s:connect(host, port) --> TIMEOUT
s:close()
leaks a socket descriptor, the one used in the first connect. Nsock
should really take care of this, but let's do this workaround because
rpc-grind has been causing problems due to using the above pattern:
http://seclists.org/nmap-dev/2012/q3/864http://seclists.org/nmap-dev/2012/q3/872http://seclists.org/nmap-dev/2012/q3/949
The difficulty is that the rpc library will tolerate around 400 of those
timeouts per RPC connection, which leads to rapidly running out of
descriptors.
There was a reverse table that was meant to map keys to their position
in the order table, to make it easy to table.remove an entry from order.
But removing something from order would shift the indices of all
following elements by 1, and those elements were not updated
correspondingly in the reverse table. Instead, do a linear lookup for
the the element to remove from order, after checking that the element
exists at all.
http://seclists.org/nmap-dev/2012/q3/905
These aren't getting regenerated even with "aclocal --force"; I think
it's because there is nothing to put in them. Running "aclocal
--verbose" shows that all the required macros are in acinclude.m4 files:
aclocal: saw macro PCAP_IS_SUITABLE
aclocal: saw macro RECVFROM_ARG6_TYPE
aclocal: saw macro PCAP_IS_SUITABLE
aclocal: saw macro CHECK_IPV6_IPPROTO_RAW
aclocal: saw macro APR_FIND_APR
aclocal: ../acinclude.m4 is already included by configure.ac
aclocal.m4 is autogenerated, so running aclocal would remove the
m4_include of acinclude.m4.
The exceptions are at the top of the source tree and in nsock/src, where
an acinclude.m4 lives; aclocal notices it there and automatically adds
an inclusion to the end of aclocal.m4, so no inclusion is needed in
configure.ac.
It was nmap_update_svn_cmdline_create_auth_baton, but should be
nmap_update_svn_cmdline_setup_auth_baton.
This was missed in r27746, which otherwise was making the same change.
This was noticed by John Spencer.
http://seclists.org/nmap-dev/2012/q3/942
Previously we always took the destination address from the packet
buffer, which failed for IPv6 link-local addresses because the packet
buffer does not contain the scope id.
Besides the confusingness of the nodns argument being negatively
phrased, it had the value 0 in every existing call. Split out the nodns
special case into a separate function resolve_numeric.
This also has the side effect of changing the number of parameters to
the resolve function, which will cause a compile error for any calls I
might have missed changing when I changed the return code meaning in the
previous commit.
Ncat has its own copy of resolve, which obeys the global o.nodns rather
than a parameter. I'm leaving that alone for now. But give it the same
resolve_internal function, and make resolve call it with different flags
depending on the value of o.nodns.
The only error we can have apart from a getaddrinfo error is a list of
zero addresses; return EAI_NONAME in that case.
This unfortunately inverts the truth value of the return code of
resolve; 0 now means success.
The second argument to RTA_NEXT was missing a dereference, so it was
changing the pointer rather than the integer pointed to. I got this
assertion failure with an IPv6 link-local address:
nmap: netutil.cc:3048: void add_rtattr_addr(nlmsghdr*, rtattr**, unsigned int*, unsigned char, const sockaddr_storage*): Assertion `((*len) >= (int)sizeof(struct rtattr) && (*rtattr)->rta_len >= sizeof(struct rtattr) && (*rtattr)->rta_len <= (*len))' failed.