1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 22:21:29 +00:00
Commit Graph

207 Commits

Author SHA1 Message Date
david
ac606d846f Fallback check for an AF_UNSPEC interface in route_dst_netlink.
When an interface doesn't have an address set, getInterfaceByName can
fail because it checks the address family. The fatal error message would
be something like
	route_dst_netlink: can't find interface "tap0"
If we can't find an interface with a specific address family, fall back
with an AF_UNSPEC search.

http://seclists.org/nmap-dev/2012/q4/12
2012-10-03 21:06:43 +00:00
david
22d49bd5c9 Match against both destination and gateway in sysroutes_dnet_find_interfaces.
This commit fixes two different bugs:

(1) First in some situations Nmap will only see routes that are attached
to the device that handles the default route.

(2) On boxes without a default route, Nmap will not see any route.

These two bugs are caused by sysroutes_dnet_find_interfaces() logic
which will use only the geteway to match interface addresses.

To fix this, first check the current route and see if the gateway was set
otherwise use the destination address to match the address of an
interface.
2012-09-30 00:01:14 +00:00
david
6c8b5c7dd9 Assign sys_route interfaces immediately when iface names come from libdnet. 2012-09-30 00:01:13 +00:00
david
d319f8bf56 Uniformity and style in resolve functions. 2012-09-15 17:56:16 +00:00
david
113e0b975f Break out resolve and resolve_numeric.
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.
2012-09-15 17:56:11 +00:00
david
0e738370ee Make resolve return a getaddrinfo error code.
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.
2012-09-15 17:56:08 +00:00
david
e2d17adf9f Fix add_rtattr_addr.
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.
2012-09-15 17:17:59 +00:00
david
3fb047e237 Don't assign any routes to interfaces that are not up. 2012-09-14 15:51:12 +00:00
david
b5b558f162 Don't use the clobbered rtmsg->rtm_family to look up interfaces.
This value gets clobbered after the netlink recvmsg. It was giving me a
bogus address family (234), which caused the call to getInterfaceByName
to fail:
Could not find interface wlan0 which was specified by -e

This seems to have been exposed by r29754. Specifying a source address
that is not on any actual route seems to result in a netlink query
result with 0 entries, and the changed value of rtm_family. (The fact
that there are no routes returned is not a problem, because we bail out
early when -e is given, now that getInterfaceByName works again.)
2012-09-11 23:50:21 +00:00
david
5b8c1090e5 Add specifiers for source address and interface in route_dst_netlink.
We previously restricted by destination address; do it for source
address as well. This can matter in some configurations.

http://seclists.org/nmap-dev/2012/q3/831

There still seems to be a problem with the wrong route being chosen with
--send-ip, but this patch is reported to work with --send-eth.
2012-09-11 18:39:42 +00:00
david
be636dacaf Factor out a add_rtattr_addr function to add a source or destination spec.
This is used to restrict what routes the Netlink layer will return to
us.
2012-09-11 18:39:40 +00:00
david
f4e06ca3d7 Ignore RTN_UNREACHABLE routes in route_dst_netlink.
According to rtnetlink(7), such routes are "an unreachable destination."
I get such a route when I ifdown my he-ipv6 interface:

$ /sbin/route -n -A inet6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
::/0                           ::                         !n   -1  1 26122 lo

The problem with not ignoring such routes is that Nmap will think that
the interface to use is lo, and consequently that all the targets are
localhost addresses. Ping scan will succeed with a localhost-response,
but trying to send any packets will fail with "destination unreachable."

Maybe we should do the same thing for these additional values of
rtm_type?

              RTN_BLACKHOLE     a packet dropping route
              RTN_PROHIBIT      a packet rejection route
2012-07-24 00:24:11 +00:00
david
df55d1380a Comment typo. 2012-07-24 00:23:58 +00:00
david
18faddcc96 Fall back to using the interface address if get_srcaddr fails.
Since r24413, we have tried "connecting" a UDP socket and using
getsockname in order to infer our source address. This replaced previous
behavior of always using the interface address. However, this appears to
fail when scnning certain *.0 addresses on Windows XP. So fall back to
the old behavior.

http://seclists.org/nmap-dev/2012/q2/464
2012-06-07 23:59:09 +00:00
david
37d623d070 Limit the errors that cause Sendto to sleep and retry.
Sendto has logic to automatically sleep and retry a send if it fails.
Fyodor tells me that it was once necessary because of some transient
buffer shortage, though we can't remember the exact error it was in
response to.

The retry looks as though it has been slowly growing a list of
exceptional error codes for which sleeping is not done:
	EPERM EACCES EMSGSIZE EADDRNOTAVAIL EINVAL
The latest was EMSGSIZE in r19378.

I changed this to only sleep on specific errors. Not knowing what the
original error was, I have guessed
	ENOBUFS ENOMEM
2012-05-17 22:04:13 +00:00
david
685f5fa4c3 Define SOLARIS_BPF_PCAP_CAPTURE for Solaris 11.
Solaris 11 uses BPF packet capture rather than DLPI, which requires
different handling in many cases. The new preprocessor symbol tells when
this is the case; it is additional granularity on top of SOLARIS.
2012-04-07 08:07:41 +00:00
david
664dff4644 Add a long comment about Solaris 11 BPF.
I was surprised when I found that Solaris 11 scanning works now. I
thought that it would require a change in the defines around
pcap_selectable_fd_valid, because it's valid for Solaris 10 and earlier
but not for Solaris 11. Why it started working was the
pcap_selectable_fd_one_to_one test added in r28319. As a side effect of
that function overrides pcap_selectable_fd_valid for all Solaris
releases, it makes changes in pcap_selectable_fd_valid unnecessary.
However it is indirect in the way it does it, so I'm adding a comment
explaining the situation and a hope that there is an easy change to make
pcap_selectable_fd_valid correct on its own.
2012-04-03 23:06:07 +00:00
david
9958ed8ebe Protect pcap_selectable_fd_valid from platforms that don't have it.
Thanks jah for catching this.
2012-03-24 01:52:43 +00:00
david
cdcc9da0d8 Fix a bug in the last commit: need another level of indirection on packet pointer. 2012-03-22 00:32:31 +00:00
david
5008078dac Add a non-blocking workaround for pcaps that buffer packets.
This is designed to solve the following problem: On Solaris 10 (maybe other
platforms), doing a select on a pcap fd works, in that it returns true when
there are frames available to be read. However, after finding the fd selectable
and calling pcap_dispatch (or pcap_next, etc.), libpcap may read more than one
frame and buffer them internally. This means that later calls to select will
return false. So there may be a frame to be read, but you can't know without
calling pcap_dispatch to check, and that blocks indefinitely (on Solaris) if
you're wrong.

The way this works is that we do a non-blocking read on the pcap fd to see if
there is anything available. If not, we do a select with a timeout as usual.
(The select is to enforce the timeout and prevent spinning CPU by repeatedly
trying non-blocking reads.)

I don't know if this phenomenon affects other platforms than Solaris 10
(more specifically, platforms using DLPI for libpcap). This same thing may be
safe or necessary on other platforms. But I have limited it to Solaris for now.
Solaris 11 uses BPF, not DLPI, for libpcap, but we can unconditionally follow
this code path on Solaris because BPF pcap fds can't be selected on.
2012-03-22 00:29:30 +00:00
david
e8c4db180d Don't duplicate #ifdefs. 2012-03-21 23:14:26 +00:00
david
f0f1419c5f Rearrange and document. 2012-03-21 23:04:13 +00:00
david
560e663867 Factor out common code from read_arp_reply_pcap and read_ns_reply_pcap. 2012-03-21 23:03:42 +00:00
david
29a4522c33 Pass a length argument to frame_is_arp. 2012-03-21 21:32:04 +00:00
david
8124bf69b9 More attempted header rearrangement for AIX compatibility. 2012-03-19 16:26:39 +00:00
david
2a71786fb9 Revert "Include <net/if.h> before <net/if_arp.h>" in netutil.cc.
This seems be broken on AIX 5.3.
2012-03-12 23:00:04 +00:00
david
941d609eef Include <net/if.h> before <net/if_arp.h>.
This may fix some build problems on AIX 5.3.
2012-03-07 03:39:11 +00:00
fyodor
684f42c4ad One more adjustment to the license text. Notes that Zenmap, Ncat, and Nping use this license. Note that contributions made directly in the src repository are treated the same as those in the mailing list. 2012-03-01 06:53:35 +00:00
fyodor
e96a7b7b24 Update the headers for each code file. This updates code copyright dates to 2012, notes the awesome NSE in the list of technology, and slightly rewords the derivative works clarification 2012-03-01 06:32:23 +00:00
david
49c6b65a5a Fix the display of "Unknown protocol" in ippackethdrinfo.
nexthdrtoa always returns the same static buffer, so it is never NULL.
Check for an empty string instead.
2012-02-24 05:01:41 +00:00
david
c1e1a12e2c Use ip_get_data_any, not ip_get_data, in ippackethdrinfo.
The difference is that ip_get_data_any doesn't require there to be an
upper-layer header at the end of an IPv6 chain. This avoids the message
"BOGUS!  Can't parse supposed IP packet" during -sO -6 scan. The -sO
sends non–upper-layer headers, some even with empty payloads, and so
causes this situation often.
2012-02-24 05:01:41 +00:00
david
d1ef18a245 Disable "WARNING: Unable to find appropriate interface for system route to...".
This often comes up these days with IPv6 routes that don't seem to
affect scanning. I don't think we have problems with routes being
removed when they shouldn't be anymore.
2011-12-23 05:05:07 +00:00
david
02ff5e83b6 Comment typo. 2011-11-27 19:50:17 +00:00
david
06b69fa9a3 Make some args const. 2011-10-29 19:40:15 +00:00
david
17e54e2d0e Document ip_get_data and ip_get_data_any. 2011-10-29 19:40:14 +00:00
david
c21d62d4e6 Revert r26741.
This makes Nmap assume that pcap sockets are selectable on Solaris again. I had
originally tested this on Solaris x86, and couldn't get a scan to complete witho
ut this change. But it was reported that it fails on Solaris SPARC (scans take a
 long time, indicating that pcap calls are blocking longer than their timeout).
I just tested it again on Solaris x86, and now I can't get a scan to complete wi
th r26741. So reverting.
2011-10-22 01:09:30 +00:00
david
6987814beb Remove extra const qualifiers.
Some function declared parameters like this:
	int f(const char * const s)
Where appropriate, I changed to
	int f(const char *s)

The second const is a qualifier on the pointer itself; i.e., the value
of s may not be changed (may not be made to point to anything else)
within the function. This is probably not what was intended. The first
const is what prevents modifying things referenced through s.
2011-10-13 20:52:03 +00:00
david
293a073c92 pcap sockets appear not to be selectable on Solaris. 2011-09-29 22:23:15 +00:00
david
c87da9aa8b Avoid using parameter names that are #defined on AIX.
AIX defines various things like ip_id as some implementation-dependent
submember of struct ip.
2011-09-21 07:31:37 +00:00
david
75f753b441 Rearrange include for AIX. 2011-09-21 07:31:35 +00:00
david
9bf2ec3884 Merge from /nmap-exp/luis/nmap-os6.
svn merge --ignore-ancestry svn://svn.insecure.org/nmap@26621 svn://svn.insecure.org/nmap-exp/luis/nmap-os6

This is the IPv6 OS detection branch. "nmap -6 -O" works now, though at
this point it only prints fingerprints and not OS guesses, because we
need to collect more submissions.
2011-09-19 18:31:46 +00:00
david
f41753c4e9 Add a sockaddr dst argument to send_ip function that use raw sockets.
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.
2011-09-19 16:13:35 +00:00
david
d91b131da0 Make various accessors and parameters const. 2011-09-19 16:13:33 +00:00
david
5898afd06b Canonicalize interface addresses returned from libdnet.
Mac OS X appears to have a new address convention that I can't find
documented. The link-local address fe80:4::X:X:X:X stands for
fe80::X:X:X:X%en0, if en0 is the interface with index 4. (I.e., it would
be fe80::X:X:X:X%4 on Windows.) The number 4 could be different numbers.

The interface addresses seem to be stored with these pseudo-zone IDs at
a low level, because they appear that way when they come from libdnet.
This is what "nmap --iflist" shows:

lo0  (lo0)   fe80:1::1/64                   loopback    up   16384
en0  (en0)   fe80:4::xxxx:xxxx:xxxx:xxxx/64 ethernet    up   1500  XX:XX:XX:XX:XX:XX

The OS X network tools seem to hide this. This is what "ifconfig" and
"netstat -rn -f inet6" show:

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
en0: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
        inet6 fe80::xxxx:xxxx:xxxx:xxxx%en0 prefixlen 64 scopeid 0x4

fe80::1%lo0                             link#1                          UHLI            lo0
fe80::xxxx:xxxx:xxxx:xxxx%en0           XX:XX:XX:XX:XX:XX               UHLI            lo0

(Not the "scopeid 0x4".) Also, if you use one of these addresses, it
magically transforms into one without the pseudo-ID (getaddrinfo does
this):

$ ping6 fe80:4::1234
PING6(56=40+8+8 bytes) fe80::xxxx:xxxx:xxxx:xxxx%en0 --> fe80::1234%en0
$ ping6 fe80:1::1234
PING6(56=40+8+8 bytes) fe80::1%lo0 --> fe80::1234%lo0

This translation is messing up our netmask comparisons for the purpose
of routing. If you use a normal link-local address starting with fe80:0,
then it doesn't compare equal with the fe80:4/64 interface address. If
you try to use the 4, then getaddrinfo turns it into fe80:0 anyway, and
the comparison still fails.

So for this reason I added a canonicalize_address function, which calls
getnameinfo on an address, then calls getaddrinfo on the returned
string, to mangle an address the same way the OS would do it. One would
hope this is a no-op in cases other than the one I have described.

Now "nmap --iflist" shows:
lo0  (lo0)   fe80::1/64                   loopback    up   16384
en0  (en0)   fe80::xxxx:xxxx:xxxx:xxxx/64 ethernet    up   1500  XX:XX:XX:XX:XX:XX
2011-09-18 23:49:34 +00:00
david
1887aef067 Allow setting certain extension headers as ancillary data in send_ipv6_ip. 2011-09-18 23:46:54 +00:00
david
66cf4fbe4a Define __APPLE_USE_RFC_3542.
Since OS X 10.7, we must declare whether we want the IPv6 sockets API to
work like RFC 2292 or RFC 3542. As far as I know, we are compatible with
both, so just pick the more recent one, which Apple says will become the
default in the future.
2011-09-18 05:11:25 +00:00
david
a13313ad2f Don't double-count RTA_LENGTH in netlink messages.
For each rtattr we add to the netlink message, we were adding
RTA_LENGTH(rtattr->rta_len) to the length of the netlink message. But
rtattr->rta_len was already calculated as RTA_LENGTH of something, and
doing RTA_LENGTH twice made the length 4 bytes longer than it should be.
This caused a log in dmesg:
	netlink: 4 bytes leftover after parsing attributes.
or
	netlink: 8 bytes leftover after parsing attributes.
if there was an IPv6 scope ID (because that causes two rtattrs instead
of one).

The new code is consistent with the rtnetlink(3) man page, which does
	rta->rta_len = sizeof(unsigned int);
	req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(sizeof(unsigned int));
We do the equivalent
	rta->rta_len = sizeof(unsigned int);
	req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + rta->rta_len;
2011-09-03 17:22:07 +00:00
david
1ef0db4b33 Define CMSG_ALIGN, CMSG_SPACE, and CMSG_LEN for old Solaris.
This was reported by Dagobert Michelsen and comes from
http://wiki.opencsw.org/porting-faq#toc10.
2011-09-03 01:51:35 +00:00
david
77204b9d43 Add an ifindex member to interface_info.
This is a copy of intf_index from libdnet.
2011-08-30 23:55:08 +00:00
david
31be04c93c Factor out a function to get an interface name from an index. 2011-08-30 23:55:05 +00:00