Nmap Development mailing list archives
[PATCH] Fix IPv6 scanning against link-local addresses
From: Kris Katterjohn <katterjohn () gmail com>
Date: Mon, 19 May 2008 13:20:02 -0500
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hey everyone, In the recent discussion on IPv6 support on Windows, Jah noted[1] that Nmap wasn't handling the Zone ID[2] correctly. This prohibited scanning IPv6 link-local addresses, usually by way of ICMP net or host unreaches. But Windows wasn't the only OS not working; I found out I couldn't scan link-local addresses on Linux either. I've attached a small patch to make Nmap understand the percent syntax for IPv6 Zone IDs, both numeric indexes and interface names. Windows only supports numeric indexes, but Linux and some other OSs can also handle interface names as well. Ex: fe80::20f:b0ff:fec6:15af%2 (Windows can only do this) fe80::20f:b0ff:fec6:15af%eth0 (Linux and others can do this too) I've tested it on Windows XP and Linux, and they both work great against link-local addresses now. The local target host is running Windows XP (no firewall), and I'm getting syn-ack's for ports 135 (msrpc) and 1025, and conn-refused's for other ports instead of the *-unreach's (Windows) and no-response's (Linux) I was getting before. I had a hunch that the struct sockaddr_in6 sin6_scope_id member was the way to handle this, and it certainly seems to be. If the zone ID passed to Nmap is numeric, that number is just stored in that member. If the ID is not fully numeric, it is assumed to be an interface name. I added the ifindex member to struct interface_info and I look it up with getInterfaceByName(). Any testing will be appreciated, especially on other OSs (like Vista and *BSD). Thanks, Kris Katterjohn [1] http://seclists.org/nmap-dev/2008/q2/0278.html [2] http://en.wikipedia.org/wiki/Ipv6#Zone_indices -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iQIVAwUBSDHE0P9K37xXYl36AQK5MQ/+MJBLNls8uss9MlsFNut+SG8hO2bYwSXc g8bPPyFeKDhIAUqhSd73uqRjH93NJBA6gU07yH4AsBh0twBBkaLS3YmD1vo98F9r RAYBdZWnQPH9uI8HA5BLrnsQQHk3FKFICZM7bFx2wgbV/JOXkS4hrzAb1lgWfqQP 8ArdGigRRRb08ANQaoMysM/Qvrdo9dGW4Xyqq2RmlqZAF5iTQyx9jfxsVxVI6EVJ 4jcHkHHqyKjsSIGf3derETIPoU/jTGsvcykUs22WTj//kHT7waPIDqZ1oMAG2s7m Zo9K8YsdFUFF0cypzCpbuhQsnUFWpxdRu9/I7qrb1CpumA/UPZNyE/CqNhHnLsVK 7R2xG5MIoNKX8Rgox8BDum4E/XZm3Yr/4enj5BR+nmG/Vx7pKUgpPrOB+Yu3V7Yi 1xLN6PArskZ00JkdyIc3+Kg34jawzgVVGR5Lk2YlqEVEqm04hEmNuVoqj0LKHlHu NFLqpyGvbeQkQPYm3RVRsqNeEBYqjPd/dPZbWTvunwxPc2eQFRU/vzMGG+1IU1Zi 77DgrmjwZB02gT4hP07UUHzU1H3/iHeGBaG3R90csGSh+eYVPNf8DIpFH40AaRNC bidUAwhhJjK7u0ztkqvTVVctLHLNKQu3XGfYt8QUGpCSA7exeegK20iacXUDEOGA ZomAhZCacK0= =QxQo -----END PGP SIGNATURE-----
Index: tcpip.cc =================================================================== --- tcpip.cc (revision 7540) +++ tcpip.cc (working copy) @@ -2824,6 +2824,8 @@ mydevs[numifaces].device_type = devt_p2p; else mydevs[numifaces].device_type = devt_other; + mydevs[numifaces].ifindex = ifr->ifr_ifindex; + if (ifflags & IFF_UP) mydevs[numifaces].device_up = true; else mydevs[numifaces].device_up = false; Index: tcpip.h =================================================================== --- tcpip.h (revision 7540) +++ tcpip.h (working copy) @@ -290,6 +290,7 @@ devtype device_type; /* devt_ethernet, devt_loopback, devt_p2p, devt_other */ bool device_up; /* True if the device is up (enabled) */ u8 mac[6]; /* Interface MAC address if device_type is devt_ethernet */ + u32 ifindex; /* Interface index, used for IPv6 scope zone ID */ }; struct route_nfo { Index: TargetGroup.cc =================================================================== --- TargetGroup.cc (revision 7540) +++ TargetGroup.cc (working copy) @@ -104,6 +104,7 @@ #include "TargetGroup.h" #include "NmapOps.h" #include "nmap_error.h" +#include "tcpip.h" extern NmapOps o; @@ -295,8 +296,32 @@ return 1; } assert(result->ai_addrlen == sizeof(struct sockaddr_in6)); + memset(&ip6, 0, sizeof ip6); struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) result->ai_addr; - memcpy(ip6.s6_addr, sin6->sin6_addr.s6_addr, 16); + memcpy(ip6.sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, 16); + if ((r = strchr(hostexp, '%'))) { + r++; + if (strspn(r, "0123456789") == strlen(r)) + ip6.sin6_scope_id = atoi(r); + else { +#ifdef WIN32 + error("Invalid zone ID for IPv6 address: %s (should be a numeric index)", hostexp); + free(hostexp); + freeaddrinfo(result); + return 1; +#else + struct interface_info *ifn = getInterfaceByName(r); + if (ifn) + ip6.sin6_scope_id = ifn->ifindex; + else { + error("Invalid zone ID for IPv6 address: %s (should be a valid interface name or a numeric index)", hostexp); + free(hostexp); + freeaddrinfo(result); + return 1; + } +#endif + } + } ipsleft = 1; freeaddrinfo(result); #else // HAVE_IPV6 @@ -443,7 +468,8 @@ #ifdef SIN_LEN sin6->sin6_len = *sslen; #endif /* SIN_LEN */ - memcpy(sin6->sin6_addr.s6_addr, ip6.s6_addr, 16); + memcpy(sin6->sin6_addr.s6_addr, ip6.sin6_addr.s6_addr, 16); + sin6->sin6_scope_id = ip6.sin6_scope_id; #else fatal("IPV6 not supported on this platform"); #endif // HAVE_IPV6 Index: TargetGroup.h =================================================================== --- TargetGroup.h (revision 7540) +++ TargetGroup.h (working copy) @@ -143,7 +143,7 @@ void Initialize(); #if HAVE_IPV6 - struct in6_addr ip6; + struct sockaddr_in6 ip6; #endif /* These 4 are used for the '/mask' style of specifying target
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- [PATCH] Fix IPv6 scanning against link-local addresses Kris Katterjohn (May 19)
- Re: [PATCH] Fix IPv6 scanning against link-local addresses Kris Katterjohn (May 19)