From 423c8380efabc3e8fb2b7045c209d294b08d3fd3 Mon Sep 17 00:00:00 2001 From: dmiller Date: Wed, 11 May 2016 02:23:21 +0000 Subject: [PATCH] Fix network prefix length on Windows. http://seclists.org/nmap-dev/2016/q2/101 --- CHANGELOG | 5 +++++ libdnet-stripped/NMAP_MODIFICATIONS | 34 +++++++++++++++++++++++++++++ libdnet-stripped/src/intf-win32.c | 11 ++++++++++ 3 files changed, 50 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 8944a7510..7f833f701 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ # Nmap Changelog ($Id$); -*-text-*- +o Retrieve the correct network prefix length for an adapter on Windows. If more + than one address was configured on an adapter, the same prefix length would + be used for both. This incorrect behavior is still used on Windows XP and + earlier. Reported by Niels Bohr. [Daniel Miller] + o [NSE] ssl-enum-ciphers will cap the score of an RC4-ciphersuite handshake at C and output a warning referencing RFC 7465. diff --git a/libdnet-stripped/NMAP_MODIFICATIONS b/libdnet-stripped/NMAP_MODIFICATIONS index 6e52a4f21..5003ef0ef 100644 --- a/libdnet-stripped/NMAP_MODIFICATIONS +++ b/libdnet-stripped/NMAP_MODIFICATIONS @@ -2284,3 +2284,37 @@ index b71fb82..315e7b0 100644 #elif defined(SIOCRPHYSADDR) /* Tru64 */ struct ifdevea *ifd = (struct ifdevea *)𝔦 /* XXX */ + +o Retrieve the correct network prefix length for an adapter on Windows. If more + than one address was configured on an adapter, the same prefix length would + be used for both. This incorrect behavior is still used on Windows XP and + earlier. Reported by Niels Bohr. [Daniel Miller] + +diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c +index 77225b6..baf02ce 100644 +--- a/libdnet-stripped/src/intf-win32.c ++++ b/libdnet-stripped/src/intf-win32.c +@@ -177,12 +177,23 @@ _adapter_address_to_entry(intf_t *intf, IP_ADAPTER_ADDRESSES *a, + OnLinkPrefixLength member that is stored right with the + unicast address. */ + bits = 0; ++ if (addr->Length >= 48) { ++ /* "The size of the IP_ADAPTER_UNICAST_ADDRESS structure changed on ++ * Windows Vista and later. The Length member should be used to determine ++ * which version of the IP_ADAPTER_UNICAST_ADDRESS structure is being ++ * used." ++ * Empirically, 48 is the value on Windows 8.1, so should include the ++ * OnLinkPrefixLength member.*/ ++ bits = addr->OnLinkPrefixLength; ++ } ++ else { + for (prefix = a->FirstPrefix; prefix != NULL; prefix = prefix->Next) { + if (prefix->Address.lpSockaddr->sa_family == addr->Address.lpSockaddr->sa_family) { + bits = (unsigned short) prefix->PrefixLength; + break; + } + } ++ } + + if (entry->intf_addr.addr_type == ADDR_TYPE_NONE) { + /* Set primary address if unset. */ diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c index 77225b643..baf02ce10 100644 --- a/libdnet-stripped/src/intf-win32.c +++ b/libdnet-stripped/src/intf-win32.c @@ -177,12 +177,23 @@ _adapter_address_to_entry(intf_t *intf, IP_ADAPTER_ADDRESSES *a, OnLinkPrefixLength member that is stored right with the unicast address. */ bits = 0; + if (addr->Length >= 48) { + /* "The size of the IP_ADAPTER_UNICAST_ADDRESS structure changed on + * Windows Vista and later. The Length member should be used to determine + * which version of the IP_ADAPTER_UNICAST_ADDRESS structure is being + * used." + * Empirically, 48 is the value on Windows 8.1, so should include the + * OnLinkPrefixLength member.*/ + bits = addr->OnLinkPrefixLength; + } + else { for (prefix = a->FirstPrefix; prefix != NULL; prefix = prefix->Next) { if (prefix->Address.lpSockaddr->sa_family == addr->Address.lpSockaddr->sa_family) { bits = (unsigned short) prefix->PrefixLength; break; } } + } if (entry->intf_addr.addr_type == ADDR_TYPE_NONE) { /* Set primary address if unset. */