From 0d44a381b14f7375b9fea59cc78381cbb6b3424a Mon Sep 17 00:00:00 2001 From: dmiller Date: Tue, 26 Jan 2016 04:52:28 +0000 Subject: [PATCH] Fix netmask handling on FreeBSD. Fixes #284 --- CHANGELOG | 4 ++++ libdnet-stripped/src/addr.c | 11 ++++++++++- libdnet-stripped/src/route-bsd.c | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index f7595a299..e23b12dc4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ # Nmap Changelog ($Id$); -*-text-*- +o [GH#284] Fix retrieval of route netmasks on FreeBSD. IPv6 routes were given + /32 netmasks regardless of actual netmask configured, resulting in failed + routing. Reported by Martin Gysi. [Daniel Miller] + o Use the same ScanProgressMeter for FTP bounce scan (-b) as for the other scan types, allowing periodic status updates with --stats-every or keypress events. [Daniel Miller] diff --git a/libdnet-stripped/src/addr.c b/libdnet-stripped/src/addr.c index 05a06924e..ee84af4c8 100644 --- a/libdnet-stripped/src/addr.c +++ b/libdnet-stripped/src/addr.c @@ -394,8 +394,17 @@ addr_stob(const struct sockaddr *sa, uint16_t *bits) #ifdef HAVE_SOCKADDR_IN6 if (sa->sa_family == AF_INET6) { - len = IP6_ADDR_LEN; p = (u_char *)&so->sin6.sin6_addr; +#ifdef HAVE_SOCKADDR_SA_LEN + len = sa->sa_len - ((void *) p - (void *) sa); + /* Handles the special case of sa->sa_len == 0. */ + if (len < 0) + len = 0; + else if (len > IP6_ADDR_LEN) + len = IP6_ADDR_LEN; +#else + len = IP6_ADDR_LEN; +#endif } else #endif { diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c index 9bc4bb092..7aa2eaf3e 100644 --- a/libdnet-stripped/src/route-bsd.c +++ b/libdnet-stripped/src/route-bsd.c @@ -335,8 +335,11 @@ route_loop(route_t *r, route_handler callback, void *arg) * p. 494, function get_rtaddrs. */ for (ret = 0; next < lim; next += rtm->rtm_msglen) { char namebuf[IF_NAMESIZE]; + sa_family_t sfam; rtm = (struct rt_msghdr *)next; sa = (struct sockaddr *)(rtm + 1); + /* peek at address family */ + sfam = sa->sa_family; if (if_indextoname(rtm->rtm_index, namebuf) == NULL) continue; @@ -362,6 +365,8 @@ route_loop(route_t *r, route_handler callback, void *arg) if (rtm->rtm_addrs & RTA_NETMASK) { sa = NEXTSA(sa); + /* FreeBSD for IPv6 uses a different AF for netmasks. Force the same one. */ + sa->sa_family = sfam; if (addr_stob(sa, &entry.route_dst.addr_bits) < 0) continue; }