mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 06:01:28 +00:00
2576 lines
85 KiB
Plaintext
2576 lines
85 KiB
Plaintext
$Id$
|
|
|
|
This is Dug Song's excellent Libdnet networking library version 1.12.
|
|
It has been stripped down for inclusion within Nmap and modified as follows:
|
|
|
|
o Removed the following directories:
|
|
python, test, man, trunk
|
|
|
|
o Removed the fw-* files except for fw-none because Nmap doesn't use
|
|
the firewall API. Changed configure.in to always use fw-non.
|
|
|
|
o Removed files in now-removed dirs that were referenced in the AC_OUTPUT
|
|
at the end of configure.in
|
|
|
|
o Ran "aclocal -I . -I config" to regenerate aclocal.m4 with my newer
|
|
aclocal.
|
|
|
|
o Added this NMAP_MODIFICATIONS file.
|
|
|
|
o Added include/winconfig.h, which is a modified config.h to better support
|
|
Windows compilation via Visual Studio. Added conditional includes
|
|
for it to a bunch of the dnet source files.
|
|
|
|
o A number of portability changes to remove errors/warnings during
|
|
Win32 Visual Studio.Net compilation. This was mostly a matter of
|
|
adding casts and a few extra include files.
|
|
|
|
o Added libdnet-stripped.vcproj -- A Visual Studio.Net project file
|
|
for dnet.
|
|
|
|
o Regenerated build files with Autoconf 2.63, Automake 1.10.1, and
|
|
libtool 2.2.6.
|
|
|
|
o Added a check for socklen_t in configure.in and used socklen_t when
|
|
calling getsockname and getsockopt to avoid a "pointer targets differ
|
|
in signedness" warning on platforms where socklen_t is unsigned.
|
|
|
|
o Made the following change for Windows Vista support (thanks to Dan
|
|
Griffin):
|
|
--- old/intf-win32.c 2005-12-28 16:30:38.000000000 -0800
|
|
+++ intf-win32.c 2006-11-26 20:46:13.000000000 -0800
|
|
@@ -31,7 +31,7 @@
|
|
int max;
|
|
};
|
|
|
|
-#define MIB_IF_TYPE_MAX 32 /* XXX - ipifcons.h */
|
|
+#define MIB_IF_TYPE_MAX MAX_IF_TYPE /* XXX - ipifcons.h */
|
|
|
|
struct intf_handle {
|
|
struct ifcombo ifcombo[MIB_IF_TYPE_MAX];
|
|
|
|
o Removed config.sub, config.guess, install-sh, ltmain.sh, and missing from the
|
|
config directory. These files are found in the parent (i.e., Nmap's)
|
|
directory. Also removed config/mkinstalldirs because it is replaced with
|
|
$(install_sh) -d. Change Makefile.am not to use ac_aux_dir, which is an
|
|
internal Autoconf variable.
|
|
Index: configure.in
|
|
===================================================================
|
|
--- configure.in (revision 6317)
|
|
+++ configure.in (working copy)
|
|
@@ -6,8 +6,6 @@
|
|
dnl $Id$
|
|
|
|
AC_INIT(include/dnet.h)
|
|
-AC_CONFIG_AUX_DIR(config)
|
|
-AC_SUBST(ac_aux_dir)
|
|
|
|
AM_INIT_AUTOMAKE(libdnet, 1.10)
|
|
AM_CONFIG_HEADER(include/config.h)
|
|
Index: Makefile.am
|
|
===================================================================
|
|
--- Makefile.am (revision 6317)
|
|
+++ Makefile.am (working copy)
|
|
@@ -10,16 +10,12 @@
|
|
|
|
CLEANFILES = dnet-config
|
|
|
|
-AUX_DIST = $(ac_aux_dir)/acinclude.m4 \
|
|
- $(ac_aux_dir)/config.guess \
|
|
- $(ac_aux_dir)/config.sub \
|
|
- $(ac_aux_dir)/install-sh \
|
|
- $(ac_aux_dir)/ltmain.sh \
|
|
- $(ac_aux_dir)/missing \
|
|
- $(ac_aux_dir)/mkinstalldirs
|
|
+aux_dir = config
|
|
|
|
+AUX_DIST = $(aux_dir)/acinclude.m4
|
|
+
|
|
dist-hook:
|
|
- (cd $(distdir) && mkdir $(ac_aux_dir))
|
|
+ (cd $(distdir) && mkdir $(aux_dir))
|
|
for file in $(AUX_DIST); do \
|
|
cp $$file $(distdir)/$$file; \
|
|
done
|
|
|
|
o Remember the entry->intf_len before zeroing entry in _ifrow_to_entry.
|
|
intf_loop relies on passing the length inside the structure to make sure
|
|
interface aliases are accounted for.
|
|
Index: src/intf-win32.c
|
|
===================================================================
|
|
--- src/intf-win32.c (revision 6288)
|
|
+++ src/intf-win32.c (working copy)
|
|
@@ -103,7 +103,12 @@
|
|
struct addr *ap, *lap;
|
|
int i;
|
|
|
|
+ /* The total length of the entry may be passed in inside entry.
|
|
+ Remember it and clear the entry. */
|
|
+ u_int intf_len = entry->intf_len;
|
|
memset(entry, 0, sizeof(*entry));
|
|
+ /* Restore the length. */
|
|
+ entry->intf_len = intf_len;
|
|
|
|
for (i = 0; i < intf->ifcombo[ifrow->dwType].cnt; i++) {
|
|
if (intf->ifcombo[ifrow->dwType].idx[i] == ifrow->dwIndex)
|
|
|
|
o Forced interface type numbers to be canonicalized to internal numbers to
|
|
avoid accessing uninitialized memory when an unknown device name is
|
|
given.
|
|
Index: libdnet-stripped/src/intf-win32.c
|
|
===================================================================
|
|
--- libdnet-stripped/src/intf-win32.c (revision 6413)
|
|
+++ libdnet-stripped/src/intf-win32.c (working copy)
|
|
@@ -42,9 +42,12 @@
|
|
static char *
|
|
_ifcombo_name(int type)
|
|
{
|
|
- char *name = "net"; /* XXX */
|
|
+ /* Unknown interface types get the prefix "net". */
|
|
+ char *name = "net";
|
|
|
|
- if (type == MIB_IF_TYPE_ETHERNET) {
|
|
+ if (type == MIB_IF_TYPE_ETHERNET || type == IF_TYPE_IEEE80211) {
|
|
+ /* INTF_TYPE_IEEE80211 is used for wireless devices on
|
|
+ Windows Vista. */
|
|
name = "eth";
|
|
} else if (type == MIB_IF_TYPE_TOKENRING) {
|
|
name = "tr";
|
|
@@ -60,9 +63,12 @@
|
|
return (name);
|
|
}
|
|
|
|
+/* Return a canonical internal interface type number for the given
|
|
+ * device string. */
|
|
static int
|
|
_ifcombo_type(const char *device)
|
|
{
|
|
+ /* Unknown device names (like "net") get mapped to INTF_TYPE_OTHER. */
|
|
int type = INTF_TYPE_OTHER;
|
|
|
|
if (strncmp(device, "eth", 3) == 0) {
|
|
@@ -81,6 +87,20 @@
|
|
return (type);
|
|
}
|
|
|
|
+/* Map an MIB_IFROW.dwType interface type into an internal interface
|
|
+ type. The internal types are never exposed to users of this library;
|
|
+ they exist only for the sake of ordering interface types within an
|
|
+ intf_handle, which has an array of ifcombo structures ordered by
|
|
+ type. Entries in an intf_handle must not be stored or accessed by a
|
|
+ raw MIB_IFROW.dwType number because they will not be able to be found
|
|
+ by a device name such as "net0" if the device name does not map
|
|
+ exactly to the dwType. */
|
|
+static int
|
|
+_if_type_canonicalize(int type)
|
|
+{
|
|
+ return _ifcombo_type(_ifcombo_name(type));
|
|
+}
|
|
+
|
|
static void
|
|
_ifcombo_add(struct ifcombo *ifc, DWORD idx)
|
|
{
|
|
@@ -102,6 +122,7 @@
|
|
{
|
|
struct addr *ap, *lap;
|
|
int i;
|
|
+ int type;
|
|
|
|
/* The total length of the entry may be passed in inside entry.
|
|
Remember it and clear the entry. */
|
|
@@ -110,14 +131,15 @@
|
|
/* Restore the length. */
|
|
entry->intf_len = intf_len;
|
|
|
|
- for (i = 0; i < intf->ifcombo[ifrow->dwType].cnt; i++) {
|
|
- if (intf->ifcombo[ifrow->dwType].idx[i] == ifrow->dwIndex)
|
|
+ type = _if_type_canonicalize(ifrow->dwType);
|
|
+ for (i = 0; i < intf->ifcombo[type].cnt; i++) {
|
|
+ if (intf->ifcombo[type].idx[i] == ifrow->dwIndex)
|
|
break;
|
|
}
|
|
- /* XXX - dwType matches MIB-II ifType. */
|
|
+ /* XXX - type matches MIB-II ifType. */
|
|
snprintf(entry->intf_name, sizeof(entry->intf_name), "%s%lu",
|
|
- _ifcombo_name(ifrow->dwType), i);
|
|
- entry->intf_type = (uint16_t)ifrow->dwType;
|
|
+ _ifcombo_name(type), i);
|
|
+ entry->intf_type = (uint16_t)type;
|
|
|
|
/* Get interface flags. */
|
|
entry->intf_flags = 0;
|
|
@@ -201,9 +223,11 @@
|
|
* XXX - like IP_ADAPTER_INFO ComboIndex
|
|
*/
|
|
for (i = 0; i < intf->iftable->dwNumEntries; i++) {
|
|
+ int type;
|
|
ifrow = &intf->iftable->table[i];
|
|
- if (ifrow->dwType < MIB_IF_TYPE_MAX) {
|
|
- _ifcombo_add(&intf->ifcombo[ifrow->dwType],
|
|
+ type = _if_type_canonicalize(ifrow->dwType);
|
|
+ if (type < MIB_IF_TYPE_MAX) {
|
|
+ _ifcombo_add(&intf->ifcombo[type],
|
|
ifrow->dwIndex);
|
|
} else
|
|
return (-1);
|
|
|
|
Index: configure.in
|
|
===================================================================
|
|
--- configure.in (revision 17500)
|
|
+++ configure.in (working copy)
|
|
@@ -32,6 +32,7 @@
|
|
AC_PROG_CC
|
|
AC_PROG_INSTALL
|
|
AC_LIBTOOL_DLOPEN
|
|
+AC_DISABLE_SHARED
|
|
AM_PROG_LIBTOOL
|
|
|
|
dnl Checks for Python.
|
|
|
|
o Made eth_get_pcap_devname compare interface descriptions as well as
|
|
MAC addresses when assigning interface names like eth0 on Windows.
|
|
Only comparing MAC addresses failed in the case of "teamed"
|
|
interfaces, when three interfaces (two physical, one virtual) could
|
|
have the same hardware address.
|
|
|
|
Index: include/dnet/intf.h
|
|
===================================================================
|
|
--- include/dnet/intf.h (revision 17541)
|
|
+++ include/dnet/intf.h (revision 17542)
|
|
@@ -60,6 +60,7 @@
|
|
int intf_get(intf_t *i, struct intf_entry *entry);
|
|
int intf_get_src(intf_t *i, struct intf_entry *entry, struct addr *src);
|
|
int intf_get_dst(intf_t *i, struct intf_entry *entry, struct addr *dst);
|
|
+int intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen);
|
|
int intf_set(intf_t *i, const struct intf_entry *entry);
|
|
int intf_loop(intf_t *i, intf_handler callback, void *arg);
|
|
intf_t *intf_close(intf_t *i);
|
|
Index: src/eth-win32.c
|
|
===================================================================
|
|
--- src/eth-win32.c (revision 17541)
|
|
+++ src/eth-win32.c (revision 17542)
|
|
@@ -34,56 +34,25 @@
|
|
eth_open(const char *device)
|
|
{
|
|
eth_t *eth;
|
|
- intf_t *intf;
|
|
- struct intf_entry ifent;
|
|
- eth_addr_t ea;
|
|
- char *p, *buf;
|
|
- ULONG len;
|
|
+ char pcapdev[128];
|
|
|
|
- /* Get interface entry. */
|
|
- memset(&ifent, 0, sizeof(ifent));
|
|
- if ((intf = intf_open()) != NULL) {
|
|
- strlcpy(ifent.intf_name, device, sizeof(ifent.intf_name));
|
|
- intf_get(intf, &ifent);
|
|
- intf_close(intf);
|
|
- }
|
|
- if (ifent.intf_link_addr.addr_type != ADDR_TYPE_ETH)
|
|
+ if (eth_get_pcap_devname(device, pcapdev, sizeof(pcapdev)) != 0)
|
|
return (NULL);
|
|
|
|
- /* Get Packet driver adapter name/desc lists. */
|
|
- buf = NULL;
|
|
- PacketGetAdapterNames(buf, &len);
|
|
- if (len > 0 && (buf = malloc(len)) != NULL) {
|
|
- if (!PacketGetAdapterNames(buf, &len)) {
|
|
- free(buf);
|
|
- buf = NULL;
|
|
- }
|
|
- }
|
|
- if (buf == NULL)
|
|
+ if ((eth = calloc(1, sizeof(*eth))) == NULL)
|
|
return (NULL);
|
|
-
|
|
- /* XXX - find adapter with matching interface MAC address. */
|
|
- if ((eth = calloc(1, sizeof(*eth))) == NULL) {
|
|
- free(buf);
|
|
+ eth->lpa = PacketOpenAdapter(pcapdev);
|
|
+ if (eth->lpa == NULL) {
|
|
+ eth_close(eth);
|
|
return (NULL);
|
|
}
|
|
- for (p = buf; *p != '\0'; p += strlen(p) + 1) {
|
|
- if ((eth->lpa = PacketOpenAdapter(p)) != NULL) {
|
|
- if (eth->lpa->hFile != INVALID_HANDLE_VALUE &&
|
|
- eth_get(eth, &ea) == 0 &&
|
|
- memcmp(&ea, &ifent.intf_link_addr.addr_eth,
|
|
- ETH_ADDR_LEN) == 0) {
|
|
- PacketSetBuff(eth->lpa, 512000);
|
|
- eth->pkt = PacketAllocatePacket();
|
|
- break;
|
|
- }
|
|
- PacketCloseAdapter(eth->lpa);
|
|
- }
|
|
+ PacketSetBuff(eth->lpa, 512000);
|
|
+ eth->pkt = PacketAllocatePacket();
|
|
+ if (eth->pkt == NULL) {
|
|
+ eth_close(eth);
|
|
+ return NULL;
|
|
}
|
|
- free(buf);
|
|
- if (eth->pkt == NULL)
|
|
- eth = eth_close(eth);
|
|
-
|
|
+
|
|
return (eth);
|
|
}
|
|
|
|
@@ -142,61 +111,8 @@
|
|
return (-1);
|
|
}
|
|
|
|
-
|
|
-/* Converts a dnet interface name (ifname) to its pcap equivalent, which is stored in
|
|
-pcapdev (up to a length of pcapdevlen). Returns 0 and fills in pcapdev if successful. */
|
|
-int eth_get_pcap_devname(const char *ifname, char *pcapdev, int pcapdevlen) {
|
|
- intf_t *intf;
|
|
- struct intf_entry ie;
|
|
- pcap_if_t *pcapdevs;
|
|
- pcap_if_t *pdev;
|
|
- char pname[128];
|
|
-
|
|
- if ((intf = intf_open()) == NULL)
|
|
- return -1;
|
|
-
|
|
- pname[0] = '\0';
|
|
- memset(&ie, 0, sizeof(ie));
|
|
- strlcpy(ie.intf_name, ifname, sizeof(ie.intf_name));
|
|
- if (intf_get(intf, &ie) != 0) {
|
|
- intf_close(intf);
|
|
- return -1;
|
|
- }
|
|
- intf_close(intf);
|
|
-
|
|
- /* Next we must find the pcap device name corresponding to the device.
|
|
- The device description used to be compared with those from PacketGetAdapterNames(), but
|
|
- that was unrelaible because dnet and pcap sometimes give different descriptions. For example,
|
|
- dnet gave me "AMD PCNET Family PCI Ethernet Adapter - Packet Scheduler Miniport" for one of my
|
|
- adapters (in vmware), while pcap described it as "VMware Accelerated AMD PCNet Adapter (Microsoft's
|
|
- Packet Scheduler)". Then IP addresses used to be compared, but that proved to be unreliable
|
|
- as well. Now we compare hardware addresses much like eth_open() does */
|
|
- if (pcap_findalldevs(&pcapdevs, NULL) == -1)
|
|
- return -1;
|
|
-
|
|
- if (pname[0] == '\0' && ie.intf_link_addr.addr_type == ADDR_TYPE_ETH) {
|
|
- for(pdev=pcapdevs; pdev && !pname[0]; pdev = pdev->next) {
|
|
- eth_t eth;
|
|
- eth_addr_t ea;
|
|
-
|
|
- eth.lpa = PacketOpenAdapter(pdev->name);
|
|
- if (eth.lpa == NULL)
|
|
- continue;
|
|
- if (eth.lpa->hFile != INVALID_HANDLE_VALUE &&
|
|
- eth_get(ð, &ea) == 0 &&
|
|
- memcmp(&ea, &ie.intf_link_addr.addr_eth,
|
|
- ETH_ADDR_LEN) == 0) {
|
|
- /* Found it -- Yay! */
|
|
- strlcpy(pname, pdev->name, sizeof(pname));
|
|
- }
|
|
- PacketCloseAdapter(eth.lpa);
|
|
- }
|
|
- }
|
|
-
|
|
- pcap_freealldevs(pcapdevs);
|
|
- if (pname[0]) {
|
|
- strlcpy(pcapdev, pname, pcapdevlen);
|
|
- return 0;
|
|
- }
|
|
- return -1;
|
|
+int
|
|
+eth_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
+{
|
|
+ return intf_get_pcap_devname(intf_name, pcapdev, pcapdevlen);
|
|
}
|
|
Index: src/intf-win32.c
|
|
===================================================================
|
|
--- src/intf-win32.c (revision 17541)
|
|
+++ src/intf-win32.c (revision 17542)
|
|
@@ -21,6 +21,9 @@
|
|
#include <string.h>
|
|
|
|
#include "dnet.h"
|
|
+#include "pcap.h"
|
|
+#include <Packet32.h>
|
|
+#include <Ntddndis.h>
|
|
|
|
struct ifcombo {
|
|
DWORD *idx;
|
|
@@ -384,3 +387,89 @@
|
|
}
|
|
return (NULL);
|
|
}
|
|
+
|
|
+/* Converts a libdnet interface name to its pcap equivalent. The pcap name is
|
|
+ stored in pcapdev up to a length of pcapdevlen, including the terminating
|
|
+ '\0'. Returns -1 on error. */
|
|
+int
|
|
+intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
+{
|
|
+ wchar_t descr_wc[512];
|
|
+ pcap_if_t *pcapdevs;
|
|
+ pcap_if_t *pdev;
|
|
+ intf_t *intf;
|
|
+ MIB_IFROW ifrow;
|
|
+
|
|
+ if ((intf = intf_open()) == NULL)
|
|
+ return (-1);
|
|
+ if (_refresh_tables(intf) < 0) {
|
|
+ intf_close(intf);
|
|
+ return (-1);
|
|
+ }
|
|
+ ifrow.dwIndex = _find_ifindex(intf, intf_name);
|
|
+ intf_close(intf);
|
|
+
|
|
+ if (GetIfEntry(&ifrow) != NO_ERROR)
|
|
+ return (-1);
|
|
+
|
|
+ /* OID_GEN_FRIENDLY_NAME returns a wide-character string, so convert
|
|
+ the description to wide characters for string comparison. */
|
|
+ mbstowcs(descr_wc, ifrow.bDescr, sizeof(descr_wc) / sizeof(descr_wc[0]) - 1);
|
|
+ descr_wc[sizeof(descr_wc) / sizeof(descr_wc[0]) - 1] = L'\0';
|
|
+
|
|
+ if (pcap_findalldevs(&pcapdevs, NULL) == -1)
|
|
+ return (-1);
|
|
+
|
|
+ /* Loop through all the pcap devices until we find a match. pcap gets
|
|
+ its interface list from the registry; dnet gets it from GetIfList.
|
|
+ We must match them up using values common to both data sets. We do
|
|
+ it by comparing hardware addresses and interface descriptions. */
|
|
+ for (pdev = pcapdevs; pdev != NULL; pdev = pdev->next) {
|
|
+ PACKET_OID_DATA *data;
|
|
+ u_char buf[512];
|
|
+ LPADAPTER lpa;
|
|
+
|
|
+ lpa = PacketOpenAdapter(pdev->name);
|
|
+ if (lpa == NULL)
|
|
+ continue;
|
|
+ if (lpa->hFile == INVALID_HANDLE_VALUE)
|
|
+ goto close_adapter;
|
|
+
|
|
+ data = (PACKET_OID_DATA *) buf;
|
|
+
|
|
+ /* Check the MAC address if available. */
|
|
+ data->Oid = OID_802_3_CURRENT_ADDRESS;
|
|
+ data->Length = sizeof(buf) - sizeof(*data);
|
|
+ if (PacketRequest(lpa, FALSE, data) == TRUE) {
|
|
+ if (data->Length != ifrow.dwPhysAddrLen)
|
|
+ goto close_adapter;
|
|
+ if (memcmp(ifrow.bPhysAddr, data->Data, data->Length) != 0)
|
|
+ goto close_adapter;
|
|
+ }
|
|
+
|
|
+ /* Distinct interfaces can have the same MAC address in the
|
|
+ case of "teamed" interfaces. Additionally check the
|
|
+ description string. */
|
|
+ data->Oid = OID_GEN_FRIENDLY_NAME;
|
|
+ data->Length = sizeof(buf) - sizeof(*data);
|
|
+ if (PacketRequest(lpa, FALSE, data) != TRUE)
|
|
+ goto close_adapter;
|
|
+ if (wcscmp(descr_wc, (wchar_t *) data->Data) != 0)
|
|
+ goto close_adapter;
|
|
+
|
|
+ /* Found it. */
|
|
+ PacketCloseAdapter(lpa);
|
|
+ break;
|
|
+
|
|
+close_adapter:
|
|
+ PacketCloseAdapter(lpa);
|
|
+ }
|
|
+
|
|
+ if (pdev != NULL)
|
|
+ strlcpy(pcapdev, pdev->name, pcapdevlen);
|
|
+ pcap_freealldevs(pcapdevs);
|
|
+ if (pdev == NULL)
|
|
+ return -1;
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
|
|
o Changed the name of sctp_chunkhdr to dnet_sctp_chunkhdr to avoid a
|
|
conflict with a struct of the same name in <netinet/sctp.h> in FreeBSD
|
|
and Linux.
|
|
|
|
Index: include/dnet/sctp.h
|
|
===================================================================
|
|
--- include/dnet/sctp.h (revision 20087)
|
|
+++ include/dnet/sctp.h (working copy)
|
|
@@ -36,7 +36,7 @@
|
|
sctp_pack_p->sh_vtag = htonl(vtag); \
|
|
} while (0)
|
|
|
|
-struct sctp_chunkhdr {
|
|
+struct dnet_sctp_chunkhdr {
|
|
uint8_t sch_type; /* chunk type */
|
|
uint8_t sch_flags; /* chunk flags */
|
|
uint16_t sch_length; /* chunk length */
|
|
@@ -70,7 +70,7 @@
|
|
#define SCTP_TYPEFLAG_SKIP 2
|
|
|
|
#define sctp_pack_chunkhdr(hdr, type, flags, length) do { \
|
|
- struct sctp_chunkhdr *sctp_pack_chp = (struct sctp_chunkhdr *)(hdr);\
|
|
+ struct dnet_sctp_chunkhdr *sctp_pack_chp = (struct dnet_sctp_chunkhdr *)(hdr);\
|
|
sctp_pack_chp->sch_type = type; \
|
|
sctp_pack_chp->sch_flags = flags; \
|
|
sctp_pack_chp->sch_length = htons(length); \
|
|
@@ -80,7 +80,7 @@
|
|
* INIT chunk
|
|
*/
|
|
struct sctp_chunkhdr_init {
|
|
- struct sctp_chunkhdr chunkhdr;
|
|
+ struct dnet_sctp_chunkhdr chunkhdr;
|
|
|
|
uint32_t schi_itag; /* Initiate Tag */
|
|
uint32_t schi_arwnd; /* Advertised Receiver Window Credit */
|
|
@@ -105,7 +105,7 @@
|
|
* INIT ACK chunk
|
|
*/
|
|
struct sctp_chunkhdr_init_ack {
|
|
- struct sctp_chunkhdr chunkhdr;
|
|
+ struct dnet_sctp_chunkhdr chunkhdr;
|
|
|
|
uint32_t schia_itag; /* Initiate Tag */
|
|
uint32_t schia_arwnd; /* Advertised Receiver Window Credit */
|
|
@@ -130,7 +130,7 @@
|
|
* ABORT chunk
|
|
*/
|
|
struct sctp_chunkhdr_abort {
|
|
- struct sctp_chunkhdr chunkhdr;
|
|
+ struct dnet_sctp_chunkhdr chunkhdr;
|
|
|
|
/* empty */
|
|
} __attribute__((__packed__));
|
|
@@ -145,7 +145,7 @@
|
|
* SHUTDOWN ACK chunk
|
|
*/
|
|
struct sctp_chunkhdr_shutdown_ack {
|
|
- struct sctp_chunkhdr chunkhdr;
|
|
+ struct dnet_sctp_chunkhdr chunkhdr;
|
|
|
|
/* empty */
|
|
} __attribute__((__packed__));
|
|
@@ -160,7 +160,7 @@
|
|
* COOKIE ECHO chunk
|
|
*/
|
|
struct sctp_chunkhdr_cookie_echo {
|
|
- struct sctp_chunkhdr chunkhdr;
|
|
+ struct dnet_sctp_chunkhdr chunkhdr;
|
|
|
|
/* empty */
|
|
} __attribute__((__packed__));
|
|
|
|
o Allowed reading interface indexes that exceed 255 on Linux.
|
|
|
|
--- libdnet-stripped/src/intf.c
|
|
+++ libdnet-stripped/src/intf.c
|
|
@@ -560,7 +560,7 @@ _intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
|
if ((f = fopen(PROC_INET6_FILE, "r")) != NULL) {
|
|
while (ap < lap &&
|
|
fgets(buf, sizeof(buf), f) != NULL) {
|
|
- sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %02x %02x %02x %02x %32s\n",
|
|
+ sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %x %02x %02x %02x %32s\n",
|
|
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
|
|
&idx, &bits, &scope, &flags, name);
|
|
if (strcmp(name, entry->intf_name) == 0) {
|
|
|
|
o Gave priority to the IFF_LOOPBACK flag when setting interface type.
|
|
|
|
--- libdnet-stripped/src/intf.c
|
|
+++ libdnet-stripped/src/intf.c
|
|
@@ -374,12 +374,12 @@ intf_set(intf_t *intf, const struct intf_entry *entry)
|
|
static void
|
|
_intf_set_type(struct intf_entry *entry)
|
|
{
|
|
- if ((entry->intf_flags & INTF_FLAG_BROADCAST) != 0)
|
|
+ if ((entry->intf_flags & INTF_FLAG_LOOPBACK) != 0)
|
|
+ entry->intf_type = INTF_TYPE_LOOPBACK;
|
|
+ else if ((entry->intf_flags & INTF_FLAG_BROADCAST) != 0)
|
|
entry->intf_type = INTF_TYPE_ETH;
|
|
else if ((entry->intf_flags & INTF_FLAG_POINTOPOINT) != 0)
|
|
entry->intf_type = INTF_TYPE_TUN;
|
|
- else if ((entry->intf_flags & INTF_FLAG_LOOPBACK) != 0)
|
|
- entry->intf_type = INTF_TYPE_LOOPBACK;
|
|
else
|
|
entry->intf_type = INTF_TYPE_OTHER;
|
|
}
|
|
|
|
===CHANGES ALREADY MERGED TO UPSTREAM LIBDNET GO BELOW THIS LINE===
|
|
|
|
o Fixed the ip6_pack_hdr macro with respect to traffic class and flow
|
|
label.
|
|
|
|
Index: include/dnet/ip6.h
|
|
===================================================================
|
|
--- include/dnet/ip6.h (revision 20527)
|
|
+++ include/dnet/ip6.h (revision 20528)
|
|
@@ -164,8 +164,8 @@
|
|
|
|
#define ip6_pack_hdr(hdr, fc, fl, plen, nxt, hlim, src, dst) do { \
|
|
struct ip6_hdr *ip6 = (struct ip6_hdr *)(hdr); \
|
|
- ip6->ip6_flow = htonl(((uint32_t)(fc) << 28) & \
|
|
- (IP6_FLOWLABEL_MASK | (fl))); \
|
|
+ ip6->ip6_flow = htonl(((uint32_t)(fc) << 20) | \
|
|
+ (0x000fffff & (fl))); \
|
|
ip6->ip6_vfc = (IP6_VERSION | ((fc) >> 4)); \
|
|
ip6->ip6_plen = htons((plen)); \
|
|
ip6->ip6_nxt = (nxt); ip6->ip6_hlim = (hlim); \
|
|
|
|
|
|
o Added some missing #ifdef AF_LINK guards to enable compiling on
|
|
Android. http://seclists.org/nmap-dev/2010/q2/1021. [Vlatko Kosturjak]
|
|
|
|
Index: src/addr.c
|
|
===================================================================
|
|
--- src/addr.c (revision 19860)
|
|
+++ src/addr.c (working copy)
|
|
@@ -253,7 +253,11 @@
|
|
# ifdef HAVE_SOCKADDR_SA_LEN
|
|
so->sdl.sdl_len = sizeof(so->sdl);
|
|
# endif
|
|
+# ifdef AF_LINK
|
|
so->sdl.sdl_family = AF_LINK;
|
|
+# else
|
|
+ so->sdl.sdl_family = AF_UNSPEC;
|
|
+# endif
|
|
so->sdl.sdl_alen = ETH_ADDR_LEN;
|
|
memcpy(LLADDR(&so->sdl), &a->addr_eth, ETH_ADDR_LEN);
|
|
#else
|
|
@@ -300,6 +304,7 @@
|
|
|
|
switch (sa->sa_family) {
|
|
#ifdef HAVE_NET_IF_DL_H
|
|
+# ifdef AF_LINK
|
|
case AF_LINK:
|
|
if (so->sdl.sdl_alen != ETH_ADDR_LEN) {
|
|
errno = EINVAL;
|
|
@@ -309,6 +314,7 @@
|
|
a->addr_bits = ETH_ADDR_BITS;
|
|
memcpy(&a->addr_eth, LLADDR(&so->sdl), ETH_ADDR_LEN);
|
|
break;
|
|
+# endif
|
|
#endif
|
|
case AF_UNSPEC:
|
|
case ARP_HRD_ETH: /* XXX- Linux arp(7) */
|
|
|
|
|
|
Index: config/acinclude.m4
|
|
===================================================================
|
|
--- config/acinclude.m4 (revision 17391)
|
|
+++ config/acinclude.m4 (working copy)
|
|
@@ -135,14 +135,18 @@
|
|
dnl usage: AC_DNET_LINUX_PF_PACKET
|
|
dnl results: HAVE_LINUX_PF_PACKET
|
|
dnl
|
|
+dnl This is a Linux-specific check, even though other operating systems
|
|
+dnl (OpenSolaris) may have the PF_PACKET interface. The eth-linux.c code
|
|
+dnl activated by this check is specific to Linux.
|
|
AC_DEFUN(AC_DNET_LINUX_PF_PACKET,
|
|
- [AC_MSG_CHECKING(for Linux PF_PACKET sockets)
|
|
- AC_CACHE_VAL(ac_cv_dnet_linux_pf_packet,
|
|
- if test -f /usr/include/netpacket/packet.h ; then
|
|
- ac_cv_dnet_linux_pf_packet=yes
|
|
- else
|
|
- ac_cv_dnet_linux_pf_packet=no
|
|
- fi)
|
|
+ [AC_CHECK_DECL([ETH_P_ALL],
|
|
+ ac_cv_dnet_linux_pf_packet=yes,
|
|
+ ac_cv_dnet_linux_pf_packet=no,
|
|
+ [
|
|
+#include <netpacket/packet.h>
|
|
+#include <linux/if_ether.h>
|
|
+])
|
|
+ AC_MSG_CHECKING(for Linux PF_PACKET sockets)
|
|
AC_MSG_RESULT($ac_cv_dnet_linux_pf_packet)
|
|
if test $ac_cv_dnet_linux_pf_packet = yes ; then
|
|
AC_DEFINE(HAVE_LINUX_PF_PACKET, 1,
|
|
|
|
o Changed the PPA extraction from DLPI interface names to use the last
|
|
string of digits, not the first. It was being fooled by the name
|
|
e1000g0, thinking the PPA was 1000.
|
|
|
|
Index: src/eth-dlpi.c
|
|
===================================================================
|
|
--- src/eth-dlpi.c (revision 16878)
|
|
+++ src/eth-dlpi.c (working copy)
|
|
@@ -113,6 +113,20 @@
|
|
}
|
|
return (ppa);
|
|
}
|
|
+#else
|
|
+static int
|
|
+dev_find_ppa(const char *dev)
|
|
+{
|
|
+ const char *p;
|
|
+
|
|
+ p = dev + strlen(dev);
|
|
+ while (p > dev && strchr("0123456789", *(p - 1)) != NULL)
|
|
+ p--;
|
|
+ if (*p == '\0')
|
|
+ return NULL;
|
|
+
|
|
+ return p;
|
|
+}
|
|
#endif
|
|
|
|
eth_t *
|
|
@@ -138,7 +152,7 @@
|
|
#else
|
|
e->fd = -1;
|
|
snprintf(dev, sizeof(dev), "/dev/%s", device);
|
|
- if ((p = strpbrk(dev, "0123456789")) == NULL) {
|
|
+ if ((p = dev_find_ppa(dev)) == NULL) {
|
|
errno = EINVAL;
|
|
return (eth_close(e));
|
|
}
|
|
|
|
o Made some code changes to intf.c (the patch below). This does the following:
|
|
|
|
o Preserve the alias qualifier from interface name in more cases
|
|
(e.g. don't blow away :2 from eth0:2 when it may still be needed.
|
|
|
|
o Set the SO_BROADCAST flag on the interface list descriptor so that
|
|
broadcast/network IPs can be investigated.
|
|
|
|
o Update _match_intf_src so that it checks interface aliases for the
|
|
given source address rather than only the main interface address.
|
|
|
|
o merged upstream libdnet r655
|
|
|
|
diff -Nruw old/src/intf.c nmap-3.83.new/src/intf.c
|
|
--- src/intf.c 2005-05-03 09:41:35.000000000 -0700
|
|
+++ src/intf.c 2005-07-16 20:55:05.000000000 -0700
|
|
@@ -119,12 +119,16 @@
|
|
intf_open(void)
|
|
{
|
|
intf_t *intf;
|
|
+ int one = 1;
|
|
|
|
if ((intf = calloc(1, sizeof(*intf))) != NULL) {
|
|
intf->fd = intf->fd6 = -1;
|
|
|
|
if ((intf->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
|
return (intf_close(intf));
|
|
+
|
|
+ setsockopt(intf->fd, SOL_SOCKET, SO_BROADCAST,
|
|
+ (const char *) &one, sizeof(one));
|
|
#ifdef SIOCGIFNETMASK_IN6
|
|
if ((intf->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
|
# ifdef EPROTONOSUPPORT
|
|
@@ -472,6 +476,7 @@
|
|
_intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
|
{
|
|
struct ifreq *ifr, *lifr;
|
|
+ struct ifreq tmpifr;
|
|
struct addr *ap, *lap;
|
|
char *p;
|
|
|
|
@@ -492,9 +497,12 @@
|
|
if ((p = strchr(ifr->ifr_name, ':')) != NULL)
|
|
*p = '\0';
|
|
|
|
- if (strcmp(ifr->ifr_name, entry->intf_name) != 0)
|
|
+ if (strcmp(ifr->ifr_name, entry->intf_name) != 0) {
|
|
+ if (p) *p = ':';
|
|
continue;
|
|
+ }
|
|
|
|
+ if (p) *p = ':'; /* Fix the name back up */
|
|
if (addr_ston(&ifr->ifr_addr, ap) < 0)
|
|
continue;
|
|
@@ -506,6 +514,11 @@
|
|
if (ap->addr_ip == entry->intf_addr.addr_ip ||
|
|
ap->addr_ip == entry->intf_dst_addr.addr_ip)
|
|
continue;
|
|
+ strlcpy(tmpifr.ifr_name, ifr->ifr_name,
|
|
+ sizeof(tmpifr.ifr_name));
|
|
+ if (ioctl(intf->fd, SIOCGIFNETMASK, &tmpifr) == 0)
|
|
+ addr_stob(&tmpifr.ifr_addr, &ap->addr_bits);
|
|
+
|
|
}
|
|
#ifdef SIOCGIFNETMASK_IN6
|
|
else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
|
|
@@ -547,10 +560,22 @@
|
|
static int
|
|
_match_intf_src(const struct intf_entry *entry, void *arg)
|
|
{
|
|
+ int matched = 0;
|
|
+ int cnt;
|
|
struct intf_entry *save = (struct intf_entry *)arg;
|
|
|
|
if (entry->intf_addr.addr_type == ADDR_TYPE_IP &&
|
|
- entry->intf_addr.addr_ip == save->intf_addr.addr_ip) {
|
|
+ entry->intf_addr.addr_ip == save->intf_addr.addr_ip)
|
|
+ matched = 1;
|
|
+
|
|
+ for (cnt = 0; !matched && cnt < (int) entry->intf_alias_num; cnt++) {
|
|
+ if (entry->intf_alias_addrs[cnt].addr_type != ADDR_TYPE_IP)
|
|
+ continue;
|
|
+ if (entry->intf_alias_addrs[cnt].addr_ip == save->intf_addr.addr_ip)
|
|
+ matched = 1;
|
|
+ }
|
|
+
|
|
+ if (matched) {
|
|
/* XXX - truncated result if entry is too small. */
|
|
if (save->intf_len < entry->intf_len)
|
|
memcpy(save, entry, save->intf_len);
|
|
@@ -678,14 +703,18 @@
|
|
if ((p = strchr(ifr->ifr_name, ':')) != NULL)
|
|
*p = '\0';
|
|
|
|
- if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0)
|
|
+ if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) {
|
|
+ if (p) *p = ':';
|
|
continue;
|
|
+ }
|
|
|
|
memset(ebuf, 0, sizeof(ebuf));
|
|
strlcpy(entry->intf_name, ifr->ifr_name,
|
|
sizeof(entry->intf_name));
|
|
entry->intf_len = sizeof(ebuf);
|
|
|
|
+ /* Repair the alias name back up. */
|
|
+ if (p) *p = ':';
|
|
if (_intf_get_noalias(intf, entry) < 0)
|
|
return (-1);
|
|
if (_intf_get_aliases(intf, entry) < 0)
|
|
|
|
o Fix a compiler "may be used unitialized" warning:
|
|
o Merged upstream r654
|
|
|
|
Index: addr-util.c
|
|
===================================================================
|
|
--- addr-util.c (revision 3855)
|
|
+++ addr-util.c (working copy)
|
|
@@ -177,6 +177,8 @@
|
|
struct { int base, len; } best, cur;
|
|
char *p = dst;
|
|
int i;
|
|
+
|
|
+ cur.len = best.len = 0;
|
|
|
|
if (len < 46)
|
|
return (NULL);
|
|
|
|
|
|
o Added eth_get_pcap_devname() that matches up a dnet name to its pcap
|
|
equivalent by matching hardwar addresses. It's similar to the code
|
|
used in eth_open()
|
|
|
|
o Handle the case of sa_len == 0 (meaning 0.0.0.0) in addr_stob.
|
|
o Merged upstream to libdnet r654
|
|
Index: src/addr.c
|
|
===================================================================
|
|
--- src/addr.c (revision 12591)
|
|
+++ src/addr.c (working copy)
|
|
@@ -385,11 +385,17 @@
|
|
} else
|
|
#endif
|
|
{
|
|
+ p = (u_char *)&so->sin.sin_addr.s_addr;
|
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
|
- if ((len = sa->sa_len - IP_ADDR_LEN) > IP_ADDR_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 > IP_ADDR_LEN)
|
|
+ len = IP_ADDR_LEN;
|
|
+#else
|
|
+ len = IP_ADDR_LEN;
|
|
#endif
|
|
- len = IP_ADDR_LEN;
|
|
- p = (u_char *)&so->sin.sin_addr.s_addr;
|
|
}
|
|
for (n = i = 0; i < len; i++, n += 8) {
|
|
if (p[i] != 0xff)
|
|
|
|
o Fixed a case where an open file may not be closed in intf_loop() [Josh]
|
|
Index: src/intf.c
|
|
===================================================================
|
|
--- src/intf.c (revision 14004)
|
|
+++ src/intf.c (working copy)
|
|
@@ -677,8 +677,10 @@
|
|
intf->ifc.ifc_buf = (caddr_t)intf->ifcbuf;
|
|
intf->ifc.ifc_len = sizeof(intf->ifcbuf);
|
|
|
|
- if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0)
|
|
+ if (ioctl(intf->fd, SIOCGIFCONF, &intf->ifc) < 0) {
|
|
+ fclose(fp);
|
|
return (-1);
|
|
+ }
|
|
|
|
ret = 0;
|
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
|
|
|
o Added casts to calls of ctype functions so that their arguments are explicitly
|
|
o Merged upstream libdnet r656
|
|
cast to (int) [Josh Marlow]
|
|
Index: src/blob.c
|
|
===================================================================
|
|
--- src/blob.c (revision 14763)
|
|
+++ src/blob.c (working copy)
|
|
@@ -162,7 +162,7 @@
|
|
for (p = (char *)fmt; *p != '\0'; p++) {
|
|
if (*p == '%') {
|
|
p++;
|
|
- if (isdigit((int)*p)) {
|
|
+ if (isdigit((int) (unsigned char) *p)) {
|
|
len = strtol(p, &p, 10);
|
|
} else if (*p == '*') {
|
|
len = va_arg(*ap, int);
|
|
Index: src/intf-win32.c
|
|
===================================================================
|
|
--- src/intf-win32.c (revision 14763)
|
|
+++ src/intf-win32.c (working copy)
|
|
@@ -234,7 +234,7 @@
|
|
char *p = (char *)device;
|
|
int n, type = _ifcombo_type(device);
|
|
|
|
- while (isalpha(*p)) p++;
|
|
+ while (isalpha((int) (unsigned char) *p)) p++;
|
|
n = atoi(p);
|
|
|
|
return (intf->ifcombo[type].idx[n]);
|
|
|
|
o Made some AIX/HP-UX portability changes sent in by Peter O'Gorman
|
|
(nmap-dev@mlists.thewrittenword.com), part 2:
|
|
Index: src/arp-ioctl.c
|
|
===================================================================
|
|
--- src/arp-ioctl.c (revision 3309)
|
|
+++ src/arp-ioctl.c (working copy)
|
|
@@ -383,7 +383,7 @@
|
|
}
|
|
return (ret);
|
|
}
|
|
-#elif defined(HAVE_NET_RADIX_H)
|
|
+#elif defined(HAVE_NET_RADIX_H) && !defined(_AIX)
|
|
/* XXX - Tru64, others? */
|
|
#include <netinet/if_ether.h>
|
|
#include <nlist.h>
|
|
Index: src/intf.c
|
|
===================================================================
|
|
--- src/intf.c (revision 3309)
|
|
+++ src/intf.c (working copy)
|
|
@@ -284,7 +284,9 @@
|
|
/* Set interface MTU. */
|
|
if (entry->intf_mtu != 0) {
|
|
ifr.ifr_mtu = entry->intf_mtu;
|
|
+#ifdef SIOCSIFMTU
|
|
if (ioctl(intf->fd, SIOCSIFMTU, &ifr) < 0)
|
|
+#endif
|
|
return (-1);
|
|
}
|
|
/* Set interface address. */
|
|
@@ -396,7 +398,9 @@
|
|
_intf_set_type(entry);
|
|
|
|
/* Get interface MTU. */
|
|
+#ifdef SIOCGIFMTU
|
|
if (ioctl(intf->fd, SIOCGIFMTU, &ifr) < 0)
|
|
+#endif
|
|
return (-1);
|
|
entry->intf_mtu = ifr.ifr_mtu;
|
|
|
|
|
|
o Made some AIX/HP-UX portability changes sent in by Peter O'Gorman
|
|
(nmap-dev@mlists.thewrittenword.com), part 1.
|
|
Merged to libdnet r653.
|
|
|
|
o Added SCTP support. [Daniel Roethlisberger]
|
|
Merged to libdnet r651 and r652.
|
|
|
|
o Applied a fix for building on GNU/kFreeBSD from Peter Salinger:
|
|
--- configure (revision 15144)
|
|
+++ configure (working copy)
|
|
@@ -14712,12 +14712,22 @@
|
|
|
|
elif test "$ac_cv_header_net_if_tun_h" = yes ; then
|
|
if test "$ac_cv_header_stropts_h" = yes ; then
|
|
- case " $LIBOBJS " in
|
|
+ case "$host_os" in
|
|
+ *kfreebsd*)
|
|
+ case " $LIBOBJS " in
|
|
+ *" tun-bsd.$ac_objext "* ) ;;
|
|
+ *) LIBOBJS="$LIBOBJS tun-bsd.$ac_objext"
|
|
+ ;;
|
|
+esac
|
|
+;;
|
|
+ *)
|
|
+ case " $LIBOBJS " in
|
|
*" tun-solaris.$ac_objext "* ) ;;
|
|
*) LIBOBJS="$LIBOBJS tun-solaris.$ac_objext"
|
|
;;
|
|
esac
|
|
-
|
|
+;;
|
|
+ esac
|
|
else
|
|
case " $LIBOBJS " in
|
|
*" tun-bsd.$ac_objext "* ) ;;
|
|
|
|
o Made a change to open bpf devices in read/write mode, to work around a
|
|
bug in Mac OS X 10.6. See http://seclists.org/nmap-dev/2009/q4/277.
|
|
|
|
Index: src/eth-bsd.c
|
|
===================================================================
|
|
--- src/eth-bsd.c (revision 16023)
|
|
+++ src/eth-bsd.c (working copy)
|
|
@@ -47,7 +47,11 @@
|
|
if ((e = calloc(1, sizeof(*e))) != NULL) {
|
|
for (i = 0; i < 128; i++) {
|
|
snprintf(file, sizeof(file), "/dev/bpf%d", i);
|
|
- e->fd = open(file, O_WRONLY);
|
|
+ /* This would be O_WRONLY, but Mac OS X 10.6 has a bug
|
|
+ where that prevents other users of the interface
|
|
+ from seeing incoming traffic, even in other
|
|
+ processes. */
|
|
+ e->fd = open(file, O_RDWR);
|
|
if (e->fd != -1 || errno != EBUSY)
|
|
break;
|
|
}
|
|
|
|
o Ignored Solaris IPMP interfaces.
|
|
|
|
diff --git src/intf.c src/intf.c
|
|
index 9f4ba19..25ae999 100644
|
|
--- src/intf.c
|
|
+++ src/intf.c
|
|
@@ -941,6 +941,22 @@ intf_loop(intf_t *intf, intf_handler callback, void *arg)
|
|
|
|
/* Repair the alias name back up */
|
|
if (p) *p = ':';
|
|
+
|
|
+ /* Ignore IPMP interfaces. These are virtual interfaces made up
|
|
+ * of physical interfaces. IPMP interfaces do not support things
|
|
+ * like packet sniffing; it is necessary to use one of the
|
|
+ * underlying physical interfaces instead. This works as long as
|
|
+ * the physical interface's test address is on the same subnet
|
|
+ * as the IPMP interface's address. */
|
|
+ if (ioctl(intf->fd, SIOCGLIFFLAGS, lifr) >= 0)
|
|
+ ;
|
|
+ else if (intf->fd6 != -1 && ioctl(intf->fd6, SIOCGLIFFLAGS, lifr) >= 0)
|
|
+ ;
|
|
+ else
|
|
+ return (-1);
|
|
+ if (lifr->lifr_flags & IFF_IPMP) {
|
|
+ continue;
|
|
+ }
|
|
|
|
if (_intf_get_noalias(intf, entry) < 0)
|
|
return (-1);
|
|
|
|
o Fixed a bug that caused Nmap to fail to find any network interface when
|
|
at least one of them is in the monitor mode. The fix was to define the
|
|
ARP_HRD_IEEE80211_RADIOTAP 802.11 radiotap header identifier in the
|
|
libdnet-stripped code. Network interfaces that are in this mode are used
|
|
by radiotap for 802.11 frame injection and reception. The bug was
|
|
reported by Tom Eichstaedt and Henri Doreau.
|
|
http://seclists.org/nmap-dev/2012/q2/449
|
|
http://seclists.org/nmap-dev/2012/q2/478
|
|
[Djalal Harouni, Henri Doreau]
|
|
|
|
Index: libdnet-stripped/include/dnet/arp.h
|
|
===================================================================
|
|
--- libdnet-stripped/include/dnet/arp.h (revision 28761)
|
|
+++ libdnet-stripped/include/dnet/arp.h (working copy)
|
|
@@ -39,6 +39,8 @@
|
|
#define ARP_HRD_ETH 0x0001 /* ethernet hardware */
|
|
#define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */
|
|
|
|
+#define ARP_HRD_IEEE80211_RADIOTAP 0x0323 /* IEEE 802.11 + radiotap header */
|
|
+
|
|
/*
|
|
* Protocol address format
|
|
*/
|
|
Index: libdnet-stripped/src/addr.c
|
|
===================================================================
|
|
--- libdnet-stripped/src/addr.c (revision 28761)
|
|
+++ libdnet-stripped/src/addr.c (working copy)
|
|
@@ -318,6 +318,7 @@
|
|
#endif
|
|
case AF_UNSPEC:
|
|
case ARP_HRD_ETH: /* XXX- Linux arp(7) */
|
|
+ case ARP_HRD_IEEE80211_RADIOTAP: /* IEEE 802.11 + radiotap header */
|
|
a->addr_type = ADDR_TYPE_ETH;
|
|
a->addr_bits = ETH_ADDR_BITS;
|
|
memcpy(&a->addr_eth, sa->sa_data, ETH_ADDR_LEN);
|
|
|
|
o Added addr_ston support for ARPHRD_VOID devices.
|
|
|
|
diff --git libdnet-stripped/include/dnet/arp.h libdnet-stripped/include/dnet/arp.h
|
|
index 2f3d0bf..ec020b4 100644
|
|
--- libdnet-stripped/include/dnet/arp.h
|
|
+++ libdnet-stripped/include/dnet/arp.h
|
|
@@ -40,6 +40,7 @@ struct arp_hdr {
|
|
#define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */
|
|
|
|
#define ARP_HRD_IEEE80211_RADIOTAP 0x0323 /* IEEE 802.11 + radiotap header */
|
|
+#define ARP_HRD_VOID 0xFFFF /* Void type, nothing is known */
|
|
|
|
/*
|
|
* Protocol address format
|
|
diff --git libdnet-stripped/src/addr.c libdnet-stripped/src/addr.c
|
|
index 392d44f..bf3e9e7 100644
|
|
--- libdnet-stripped/src/addr.c
|
|
+++ libdnet-stripped/src/addr.c
|
|
@@ -343,6 +343,9 @@ addr_ston(const struct sockaddr *sa, struct addr *a)
|
|
a->addr_bits = IP_ADDR_BITS;
|
|
a->addr_ip = so->sin.sin_addr.s_addr;
|
|
break;
|
|
+ case ARP_HRD_VOID:
|
|
+ memset(&a->addr_eth, 0, ETH_ADDR_LEN);
|
|
+ break;
|
|
default:
|
|
errno = EINVAL;
|
|
return (-1);
|
|
|
|
o Fixed strict aliasing warnings in ip6_ntop.
|
|
|
|
diff --git libdnet-stripped/src/addr-util.c libdnet-stripped/src/addr-util.c
|
|
index 6a32958..973f16c 100644
|
|
--- libdnet-stripped/src/addr-util.c
|
|
+++ libdnet-stripped/src/addr-util.c
|
|
@@ -174,6 +174,7 @@ ip_pton(const char *p, ip_addr_t *ip)
|
|
char *
|
|
ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
|
|
{
|
|
+ uint16_t data[IP6_ADDR_LEN / 2];
|
|
struct { int base, len; } best, cur;
|
|
char *p = dst;
|
|
int i;
|
|
@@ -183,12 +184,18 @@ ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
|
|
if (len < 46)
|
|
return (NULL);
|
|
|
|
+ /* Copy into 16-bit array. */
|
|
+ for (i = 0; i < IP6_ADDR_LEN / 2; i++) {
|
|
+ data[i] = ip6->data[2 * i] << 8;
|
|
+ data[i] |= ip6->data[2 * i + 1];
|
|
+ }
|
|
+
|
|
best.base = cur.base = -1;
|
|
/*
|
|
* Algorithm borrowed from Vixie's inet_pton6()
|
|
*/
|
|
for (i = 0; i < IP6_ADDR_LEN; i += 2) {
|
|
- if (*((uint16_t *)&ip6->data[i]) == 0) {
|
|
+ if (data[i / 2] == 0) {
|
|
if (cur.base == -1) {
|
|
cur.base = i;
|
|
cur.len = 0;
|
|
@@ -215,13 +222,13 @@ ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t len)
|
|
i += best.len;
|
|
} else if (i == 12 && best.base == 0 &&
|
|
(best.len == 10 || (best.len == 8 &&
|
|
- *((uint16_t *)&ip6->data[10]) == 0xffff))) {
|
|
- if (ip_ntop((ip_addr_t *)&ip6->data[12], p,
|
|
+ data[5] == 0xffff))) {
|
|
+ if (ip_ntop((ip_addr_t *)&data[6], p,
|
|
len - (p - dst)) == NULL)
|
|
return (NULL);
|
|
return (dst);
|
|
} else p += sprintf(p, "%x:",
|
|
- ntohs(*((uint16_t *)&ip6->data[i])));
|
|
+ ntohs(data[i / 2]));
|
|
}
|
|
if (best.base + 2 + best.len == IP6_ADDR_LEN) {
|
|
*p = '\0';
|
|
|
|
o Fixed interface listing on platforms where ifr_addr does not take up
|
|
the whole of struct ifreq.
|
|
|
|
diff --git libdnet-stripped/src/intf.c libdnet-stripped/src/intf.c
|
|
index 865e500..4fe059c 100644
|
|
--- libdnet-stripped/src/intf.c
|
|
+++ libdnet-stripped/src/intf.c
|
|
@@ -64,9 +64,10 @@
|
|
#endif
|
|
|
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
|
-# define NEXTIFR(i) ((struct ifreq *)((u_char *)&i->ifr_addr + \
|
|
- (i->ifr_addr.sa_len ? i->ifr_addr.sa_len : \
|
|
- sizeof(i->ifr_addr))))
|
|
+# define max(a, b) ((a) > (b) ? (a) : (b))
|
|
+# define NEXTIFR(i) ((struct ifreq *) \
|
|
+ max((u_char *)i + sizeof(struct ifreq), \
|
|
+ (u_char *)&i->ifr_addr + i->ifr_addr.sa_len))
|
|
#else
|
|
# define NEXTIFR(i) (i + 1)
|
|
#endif
|
|
|
|
o Support IEEE 802.11 devices and make addr_ston able to handle them
|
|
|
|
Index: libdnet-stripped/include/dnet/arp.h
|
|
===================================================================
|
|
--- libdnet-stripped/include/dnet/arp.h (revision 29875)
|
|
+++ libdnet-stripped/include/dnet/arp.h (working copy)
|
|
@@ -39,6 +39,7 @@
|
|
#define ARP_HRD_ETH 0x0001 /* ethernet hardware */
|
|
#define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */
|
|
|
|
+#define ARP_HDR_IEEE80211 0x0321 /* IEEE 802.11 */
|
|
#define ARP_HRD_IEEE80211_RADIOTAP 0x0323 /* IEEE 802.11 + radiotap header */
|
|
#define ARP_HRD_VOID 0xFFFF /* Void type, nothing is known */
|
|
|
|
Index: libdnet-stripped/src/addr.c
|
|
===================================================================
|
|
--- libdnet-stripped/src/addr.c (revision 29875)
|
|
+++ libdnet-stripped/src/addr.c (working copy)
|
|
@@ -318,6 +318,7 @@
|
|
#endif
|
|
case AF_UNSPEC:
|
|
case ARP_HRD_ETH: /* XXX- Linux arp(7) */
|
|
+ case ARP_HDR_IEEE80211: /* IEEE 802.11 */
|
|
case ARP_HRD_IEEE80211_RADIOTAP: /* IEEE 802.11 + radiotap header */
|
|
a->addr_type = ADDR_TYPE_ETH;
|
|
a->addr_bits = ETH_ADDR_BITS;
|
|
|
|
o Support IP-over-InfiniBand devices and make addr_ston able to handle
|
|
them. However, this support is not complete since IPoIB interfaces
|
|
use 20 bytes for the hardware address, and currently we only report
|
|
and handle 6 bytes. Nmap IP level scans should work without any
|
|
problem, please see Nmap's '--send-ip' switch.
|
|
|
|
For more information, please see this thread:
|
|
http://seclists.org/nmap-dev/2012/q3/642
|
|
|
|
Index: libdnet-stripped/include/dnet/arp.h
|
|
===================================================================
|
|
--- libdnet-stripped/include/dnet/arp.h (revision 29876)
|
|
+++ libdnet-stripped/include/dnet/arp.h (working copy)
|
|
@@ -39,6 +39,7 @@
|
|
#define ARP_HRD_ETH 0x0001 /* ethernet hardware */
|
|
#define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */
|
|
|
|
+#define ARP_HRD_INFINIBAND 0x0020 /* InfiniBand */
|
|
#define ARP_HDR_IEEE80211 0x0321 /* IEEE 802.11 */
|
|
#define ARP_HRD_IEEE80211_RADIOTAP 0x0323 /* IEEE 802.11 + radiotap header */
|
|
#define ARP_HRD_VOID 0xFFFF /* Void type, nothing is known */
|
|
Index: libdnet-stripped/src/addr.c
|
|
===================================================================
|
|
--- libdnet-stripped/src/addr.c (revision 29876)
|
|
+++ libdnet-stripped/src/addr.c (working copy)
|
|
@@ -318,6 +318,7 @@
|
|
#endif
|
|
case AF_UNSPEC:
|
|
case ARP_HRD_ETH: /* XXX- Linux arp(7) */
|
|
+ case ARP_HRD_INFINIBAND: /* InfiniBand */
|
|
case ARP_HDR_IEEE80211: /* IEEE 802.11 */
|
|
case ARP_HRD_IEEE80211_RADIOTAP: /* IEEE 802.11 + radiotap header */
|
|
a->addr_type = ADDR_TYPE_ETH;
|
|
|
|
o Added the interface name to struct route_entry, and caused it to be
|
|
filled in on Linux, Windows, and OS X.
|
|
|
|
diff --git a/libdnet-stripped/include/dnet/route.h b/libdnet-stripped/include/dnet/route.h
|
|
index 3807b45..7969772 100644
|
|
--- a/libdnet-stripped/include/dnet/route.h
|
|
+++ b/libdnet-stripped/include/dnet/route.h
|
|
@@ -15,6 +15,7 @@
|
|
* Routing table entry
|
|
*/
|
|
struct route_entry {
|
|
+ char intf_name[INTF_NAME_LEN]; /* interface name */
|
|
struct addr route_dst; /* destination address */
|
|
struct addr route_gw; /* gateway address */
|
|
};
|
|
diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c
|
|
index 9bfd58d..33f2985 100644
|
|
--- a/libdnet-stripped/src/route-bsd.c
|
|
+++ b/libdnet-stripped/src/route-bsd.c
|
|
@@ -35,6 +35,7 @@
|
|
#define route_t oroute_t /* XXX - unixware */
|
|
#include <net/route.h>
|
|
#undef route_t
|
|
+#include <net/if.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include <errno.h>
|
|
@@ -76,7 +77,7 @@ route_msg_print(struct rt_msghdr *rtm)
|
|
#endif
|
|
|
|
static int
|
|
-route_msg(route_t *r, int type, struct addr *dst, struct addr *gw)
|
|
+route_msg(route_t *r, int type, char intf_name[INTF_NAME_LEN], struct addr *dst, struct addr *gw)
|
|
{
|
|
struct addr net;
|
|
struct rt_msghdr *rtm;
|
|
@@ -153,6 +154,16 @@ route_msg(route_t *r, int type, struct addr *dst, struct addr *gw)
|
|
errno = ESRCH;
|
|
return (-1);
|
|
}
|
|
+
|
|
+ if (intf_name != NULL) {
|
|
+ char namebuf[IF_NAMESIZE];
|
|
+
|
|
+ if (if_indextoname(rtm->rtm_index, namebuf) == NULL) {
|
|
+ errno = ESRCH;
|
|
+ return (-1);
|
|
+ }
|
|
+ strlcpy(intf_name, namebuf, sizeof(intf_name));
|
|
+ }
|
|
}
|
|
return (0);
|
|
}
|
|
@@ -185,7 +196,7 @@ route_add(route_t *r, const struct route_entry *entry)
|
|
|
|
memcpy(&rtent, entry, sizeof(rtent));
|
|
|
|
- if (route_msg(r, RTM_ADD, &rtent.route_dst, &rtent.route_gw) < 0)
|
|
+ if (route_msg(r, RTM_ADD, NULL, &rtent.route_dst, &rtent.route_gw) < 0)
|
|
return (-1);
|
|
|
|
return (0);
|
|
@@ -201,7 +212,7 @@ route_delete(route_t *r, const struct route_entry *entry)
|
|
if (route_get(r, &rtent) < 0)
|
|
return (-1);
|
|
|
|
- if (route_msg(r, RTM_DELETE, &rtent.route_dst, &rtent.route_gw) < 0)
|
|
+ if (route_msg(r, RTM_DELETE, NULL, &rtent.route_dst, &rtent.route_gw) < 0)
|
|
return (-1);
|
|
|
|
return (0);
|
|
@@ -210,8 +221,9 @@ route_delete(route_t *r, const struct route_entry *entry)
|
|
int
|
|
route_get(route_t *r, struct route_entry *entry)
|
|
{
|
|
- if (route_msg(r, RTM_GET, &entry->route_dst, &entry->route_gw) < 0)
|
|
+ if (route_msg(r, RTM_GET, entry->intf_name, &entry->route_dst, &entry->route_gw) < 0)
|
|
return (-1);
|
|
+ entry->intf_name[0] = '\0';
|
|
|
|
return (0);
|
|
}
|
|
@@ -315,9 +327,14 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
* values, 1, 2, and 4 respectively. Cf. Unix Network Programming,
|
|
* p. 494, function get_rtaddrs. */
|
|
for (ret = 0; next < lim; next += rtm->rtm_msglen) {
|
|
+ char namebuf[IF_NAMESIZE];
|
|
rtm = (struct rt_msghdr *)next;
|
|
sa = (struct sockaddr *)(rtm + 1);
|
|
|
|
+ if (if_indextoname(rtm->rtm_index, namebuf) == NULL)
|
|
+ continue;
|
|
+ strlcpy(entry.intf_name, namebuf, sizeof(entry.intf_name));
|
|
+
|
|
if ((rtm->rtm_addrs & RTA_DST) == 0)
|
|
/* Need a destination. */
|
|
continue;
|
|
@@ -443,6 +460,8 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
rt->ipRouteNextHop == IP_ADDR_ANY)
|
|
continue;
|
|
|
|
+ entry.intf_name[0] = '\0';
|
|
+
|
|
sin.sin_addr.s_addr = rt->ipRouteNextHop;
|
|
addr_ston((struct sockaddr *)&sin,
|
|
&entry.route_gw);
|
|
@@ -535,6 +554,8 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
memcmp(&rt->ipv6RouteNextHop, IP6_ADDR_UNSPEC, IP6_ADDR_LEN) == 0)
|
|
continue;
|
|
|
|
+ entry.intf_name[0] = '\0';
|
|
+
|
|
sin6.sin6_addr = rt->ipv6RouteNextHop;
|
|
addr_ston((struct sockaddr *)&sin6,
|
|
&entry.route_gw);
|
|
@@ -576,6 +597,7 @@ _radix_walk(int fd, struct radix_node *rn, route_handler callback, void *arg)
|
|
_kread(fd, rn, &rnode, sizeof(rnode));
|
|
if (rnode.rn_b < 0) {
|
|
if (!(rnode.rn_flags & RNF_ROOT)) {
|
|
+ entry.intf_name[0] = '\0';
|
|
_kread(fd, rn, &rt, sizeof(rt));
|
|
_kread(fd, rt_key(&rt), &sin, sizeof(sin));
|
|
addr_ston((struct sockaddr *)&sin, &entry.route_dst);
|
|
diff --git a/libdnet-stripped/src/route-hpux.c b/libdnet-stripped/src/route-hpux.c
|
|
index a22efdf..a542347 100644
|
|
--- a/libdnet-stripped/src/route-hpux.c
|
|
+++ b/libdnet-stripped/src/route-hpux.c
|
|
@@ -116,6 +116,7 @@ route_get(route_t *r, struct route_entry *entry)
|
|
errno = ESRCH;
|
|
return (-1);
|
|
}
|
|
+ entry->intf_name[0] = '\0';
|
|
entry->route_gw.addr_type = ADDR_TYPE_IP;
|
|
entry->route_gw.addr_bits = IP_ADDR_BITS;
|
|
memcpy(&entry->route_gw.addr_ip, &rtr.rtr_gwayaddr, IP_ADDR_LEN);
|
|
@@ -147,8 +148,6 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
}
|
|
close_mib(fd);
|
|
|
|
- entry.route_dst.addr_type = entry.route_gw.addr_type = ADDR_TYPE_IP;
|
|
- entry.route_dst.addr_bits = entry.route_gw.addr_bits = IP_ADDR_BITS;
|
|
n /= sizeof(*rtentries);
|
|
ret = 0;
|
|
|
|
@@ -157,6 +156,9 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
rtentries[i].Type != NMREMOTE)
|
|
continue;
|
|
|
|
+ entry.intf_name[0] = '\0';
|
|
+ entry.route_dst.addr_type = entry.route_gw.addr_type = ADDR_TYPE_IP;
|
|
+ entry.route_dst.addr_bits = entry.route_gw.addr_bits = IP_ADDR_BITS;
|
|
entry.route_dst.addr_ip = rtentries[i].Dest;
|
|
addr_mtob(&rtentries[i].Mask, IP_ADDR_LEN,
|
|
&entry.route_dst.addr_bits);
|
|
diff --git a/libdnet-stripped/src/route-linux.c b/libdnet-stripped/src/route-linux.c
|
|
index bc788d6..a80b71b 100644
|
|
--- a/libdnet-stripped/src/route-linux.c
|
|
+++ b/libdnet-stripped/src/route-linux.c
|
|
@@ -14,6 +14,7 @@
|
|
#include <sys/uio.h>
|
|
|
|
#include <asm/types.h>
|
|
+#include <net/if.h>
|
|
#include <netinet/in.h>
|
|
#include <linux/netlink.h>
|
|
#include <linux/rtnetlink.h>
|
|
@@ -192,18 +193,31 @@ route_get(route_t *r, struct route_entry *entry)
|
|
|
|
i -= NLMSG_LENGTH(sizeof(*nmsg));
|
|
|
|
- while (RTA_OK(rta, i)) {
|
|
+ entry->route_gw.addr_type = ADDR_TYPE_NONE;
|
|
+ entry->intf_name[0] = '\0';
|
|
+ for (rta = RTM_RTA(rmsg); RTA_OK(rta, i); rta = RTA_NEXT(rta, i)) {
|
|
if (rta->rta_type == RTA_GATEWAY) {
|
|
entry->route_gw.addr_type = entry->route_dst.addr_type;
|
|
memcpy(entry->route_gw.addr_data8, RTA_DATA(rta), alen);
|
|
entry->route_gw.addr_bits = alen * 8;
|
|
- return (0);
|
|
+ } else if (rta->rta_type == RTA_OIF) {
|
|
+ char ifbuf[IFNAMSIZ];
|
|
+ char *p;
|
|
+ int intf_index;
|
|
+
|
|
+ intf_index = *(int *) RTA_DATA(rta);
|
|
+ p = if_indextoname(intf_index, ifbuf);
|
|
+ if (p == NULL)
|
|
+ return (-1);
|
|
+ strlcpy(entry->intf_name, ifbuf, sizeof(entry->intf_name));
|
|
}
|
|
- rta = RTA_NEXT(rta, i);
|
|
}
|
|
- errno = ESRCH;
|
|
+ if (entry->route_gw.addr_type == ADDR_TYPE_NONE) {
|
|
+ errno = ESRCH;
|
|
+ return (-1);
|
|
+ }
|
|
|
|
- return (-1);
|
|
+ return (0);
|
|
}
|
|
|
|
int
|
|
@@ -228,6 +242,8 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
if (i < 11 || !(iflags & RTF_UP))
|
|
continue;
|
|
|
|
+ strlcpy(entry.intf_name, ifbuf, sizeof(entry.intf_name));
|
|
+
|
|
entry.route_dst.addr_type = entry.route_gw.addr_type =
|
|
ADDR_TYPE_IP;
|
|
|
|
@@ -259,6 +275,8 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
if (i < 21 || !(iflags & RTF_UP))
|
|
continue;
|
|
|
|
+ strlcpy(entry.intf_name, ifbuf, sizeof(entry.intf_name));
|
|
+
|
|
snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s:%s:%s/%d",
|
|
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
|
dlen);
|
|
diff --git a/libdnet-stripped/src/route-win32.c b/libdnet-stripped/src/route-win32.c
|
|
index f12c8f7..ff86851 100644
|
|
--- a/libdnet-stripped/src/route-win32.c
|
|
+++ b/libdnet-stripped/src/route-win32.c
|
|
@@ -99,6 +99,8 @@ route_get(route_t *route, struct route_entry *entry)
|
|
{
|
|
MIB_IPFORWARDROW ipfrow;
|
|
DWORD mask;
|
|
+ intf_t *intf;
|
|
+ struct intf_entry intf_entry;
|
|
|
|
if (entry->route_dst.addr_type != ADDR_TYPE_IP ||
|
|
GetBestRoute(entry->route_dst.addr_ip,
|
|
@@ -118,6 +120,14 @@ route_get(route_t *route, struct route_entry *entry)
|
|
entry->route_gw.addr_type = ADDR_TYPE_IP;
|
|
entry->route_gw.addr_bits = IP_ADDR_BITS;
|
|
entry->route_gw.addr_ip = ipfrow.dwForwardNextHop;
|
|
+
|
|
+ entry->intf_name[0] = '\0';
|
|
+ intf = intf_open();
|
|
+ if (intf_get_index(intf, &intf_entry,
|
|
+ AF_INET, ipfrow.dwForwardIfIndex) == 0) {
|
|
+ strlcpy(entry->intf_name, intf_entry.intf_name, sizeof(entry->intf_name));
|
|
+ }
|
|
+ intf_close(intf);
|
|
|
|
return (0);
|
|
}
|
|
@@ -126,6 +136,7 @@ static int
|
|
route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg)
|
|
{
|
|
struct route_entry entry;
|
|
+ intf_t *intf;
|
|
ULONG len;
|
|
int i, ret;
|
|
|
|
@@ -139,23 +150,40 @@ route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg)
|
|
else if (ret != ERROR_INSUFFICIENT_BUFFER)
|
|
return (-1);
|
|
}
|
|
- entry.route_dst.addr_type = ADDR_TYPE_IP;
|
|
- entry.route_dst.addr_bits = IP_ADDR_BITS;
|
|
-
|
|
- entry.route_gw.addr_type = ADDR_TYPE_IP;
|
|
- entry.route_gw.addr_bits = IP_ADDR_BITS;
|
|
+
|
|
+ intf = intf_open();
|
|
|
|
+ ret = 0;
|
|
for (i = 0; i < (int)r->ipftable->dwNumEntries; i++) {
|
|
+ struct intf_entry intf_entry;
|
|
+
|
|
+ entry.route_dst.addr_type = ADDR_TYPE_IP;
|
|
+ entry.route_dst.addr_bits = IP_ADDR_BITS;
|
|
+
|
|
+ entry.route_gw.addr_type = ADDR_TYPE_IP;
|
|
+ entry.route_gw.addr_bits = IP_ADDR_BITS;
|
|
+
|
|
entry.route_dst.addr_ip = r->ipftable->table[i].dwForwardDest;
|
|
addr_mtob(&r->ipftable->table[i].dwForwardMask, IP_ADDR_LEN,
|
|
&entry.route_dst.addr_bits);
|
|
entry.route_gw.addr_ip =
|
|
r->ipftable->table[i].dwForwardNextHop;
|
|
+
|
|
+ /* Look up the interface name. */
|
|
+ entry.intf_name[0] = '\0';
|
|
+ intf_entry.intf_len = sizeof(intf_entry);
|
|
+ if (intf_get_index(intf, &intf_entry,
|
|
+ AF_INET, r->ipftable->table[i].dwForwardIfIndex) == 0) {
|
|
+ strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name));
|
|
+ }
|
|
|
|
if ((ret = (*callback)(&entry, arg)) != 0)
|
|
- return (ret);
|
|
+ break;
|
|
}
|
|
- return (0);
|
|
+
|
|
+ intf_close(intf);
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
static int
|
|
@@ -163,6 +191,7 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2,
|
|
route_t *r, route_handler callback, void *arg)
|
|
{
|
|
struct route_entry entry;
|
|
+ intf_t *intf;
|
|
ULONG i;
|
|
int ret;
|
|
|
|
@@ -170,18 +199,34 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2,
|
|
if (ret != NO_ERROR)
|
|
return (-1);
|
|
|
|
+ intf = intf_open();
|
|
+
|
|
+ ret = 0;
|
|
for (i = 0; i < r->ipftable2->NumEntries; i++) {
|
|
+ struct intf_entry intf_entry;
|
|
MIB_IPFORWARD_ROW2 *row;
|
|
|
|
row = &r->ipftable2->Table[i];
|
|
addr_ston((struct sockaddr *) &row->DestinationPrefix.Prefix, &entry.route_dst);
|
|
entry.route_dst.addr_bits = row->DestinationPrefix.PrefixLength;
|
|
addr_ston((struct sockaddr *) &row->NextHop, &entry.route_gw);
|
|
+
|
|
+ /* Look up the interface name. */
|
|
+ entry.intf_name[0] = '\0';
|
|
+ intf_entry.intf_len = sizeof(intf_entry);
|
|
+ if (intf_get_index(intf, &intf_entry,
|
|
+ row->DestinationPrefix.Prefix.si_family,
|
|
+ row->InterfaceIndex) == 0) {
|
|
+ strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name));
|
|
+ }
|
|
|
|
if ((ret = (*callback)(&entry, arg)) != 0)
|
|
- return (ret);
|
|
+ break;
|
|
}
|
|
- return (0);
|
|
+
|
|
+ intf_close(intf);
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
int
|
|
|
|
o Add some checks for allocation functions returning NULL.
|
|
|
|
commit 5b8a67e968aff12df2bc3cf189b96c16eec6ae3f
|
|
Author: David Fifield <david@bamsoftware.com>
|
|
Date: Wed Nov 21 16:47:21 2012 -0800
|
|
|
|
Check some libdnet mallocs for failure.
|
|
|
|
Patch based on one by Bill Parker.
|
|
http://seclists.org/nmap-dev/2012/q4/261
|
|
|
|
diff --git a/libdnet-stripped/src/arp-win32.c b/libdnet-stripped/src/arp-win32.c
|
|
index 98b01c5..4434804 100644
|
|
--- a/libdnet-stripped/src/arp-win32.c
|
|
+++ b/libdnet-stripped/src/arp-win32.c
|
|
@@ -108,6 +108,8 @@ arp_loop(arp_t *arp, arp_handler callback, void *arg)
|
|
if (arp->iptable)
|
|
free(arp->iptable);
|
|
arp->iptable = malloc(len);
|
|
+ if (arp->iptable == NULL)
|
|
+ return (-1);
|
|
ret = GetIpNetTable(arp->iptable, &len, FALSE);
|
|
if (ret == NO_ERROR)
|
|
break;
|
|
diff --git a/libdnet-stripped/src/route-win32.c b/libdnet-stripped/src/route-win32.c
|
|
index ff86851..b4536b3 100644
|
|
--- a/libdnet-stripped/src/route-win32.c
|
|
+++ b/libdnet-stripped/src/route-win32.c
|
|
@@ -35,6 +35,8 @@ route_open(void)
|
|
route_t *r;
|
|
|
|
r = calloc(1, sizeof(route_t));
|
|
+ if (r == NULL)
|
|
+ return NULL;
|
|
r->iphlpapi = GetModuleHandle("iphlpapi.dll");
|
|
|
|
return r;
|
|
@@ -144,6 +146,8 @@ route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg)
|
|
if (r->ipftable)
|
|
free(r->ipftable);
|
|
r->ipftable = malloc(len);
|
|
+ if (r->ipftable == NULL)
|
|
+ return (-1);
|
|
ret = GetIpForwardTable(r->ipftable, &len, FALSE);
|
|
if (ret == NO_ERROR)
|
|
break;
|
|
|
|
o Add metric to struct route_entry.
|
|
|
|
diff --git a/libdnet-stripped/include/dnet/route.h b/libdnet-stripped/include/dnet/route.h
|
|
index 7969772..b4bd4cc 100644
|
|
--- a/libdnet-stripped/include/dnet/route.h
|
|
+++ b/libdnet-stripped/include/dnet/route.h
|
|
@@ -18,6 +18,7 @@ struct route_entry {
|
|
char intf_name[INTF_NAME_LEN]; /* interface name */
|
|
struct addr route_dst; /* destination address */
|
|
struct addr route_gw; /* gateway address */
|
|
+ int metric; /* per-route metric */
|
|
};
|
|
|
|
typedef struct route_handle route_t;
|
|
diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c
|
|
index 33f2985..44e7dd2 100644
|
|
--- a/libdnet-stripped/src/route-bsd.c
|
|
+++ b/libdnet-stripped/src/route-bsd.c
|
|
@@ -224,6 +224,7 @@ route_get(route_t *r, struct route_entry *entry)
|
|
if (route_msg(r, RTM_GET, entry->intf_name, &entry->route_dst, &entry->route_gw) < 0)
|
|
return (-1);
|
|
entry->intf_name[0] = '\0';
|
|
+ entry->metric = 0;
|
|
|
|
return (0);
|
|
}
|
|
@@ -359,6 +360,8 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
continue;
|
|
}
|
|
|
|
+ entry.metric = 0;
|
|
+
|
|
if ((ret = callback(&entry, arg)) != 0)
|
|
break;
|
|
}
|
|
@@ -473,6 +476,8 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
sin.sin_addr.s_addr = rt->ipRouteMask;
|
|
addr_stob((struct sockaddr *)&sin,
|
|
&entry.route_dst.addr_bits);
|
|
+
|
|
+ entry.metric = 0;
|
|
|
|
if ((ret = callback(&entry, arg)) != 0)
|
|
return (ret);
|
|
@@ -608,6 +613,7 @@ _radix_walk(int fd, struct radix_node *rn, route_handler callback, void *arg)
|
|
}
|
|
_kread(fd, rt.rt_gateway, &sin, sizeof(sin));
|
|
addr_ston((struct sockaddr *)&sin, &entry.route_gw);
|
|
+ entry.metric = 0;
|
|
if ((ret = callback(&entry, arg)) != 0)
|
|
return (ret);
|
|
}
|
|
diff --git a/libdnet-stripped/src/route-hpux.c b/libdnet-stripped/src/route-hpux.c
|
|
index a542347..07e7f8c 100644
|
|
--- a/libdnet-stripped/src/route-hpux.c
|
|
+++ b/libdnet-stripped/src/route-hpux.c
|
|
@@ -120,6 +120,7 @@ route_get(route_t *r, struct route_entry *entry)
|
|
entry->route_gw.addr_type = ADDR_TYPE_IP;
|
|
entry->route_gw.addr_bits = IP_ADDR_BITS;
|
|
memcpy(&entry->route_gw.addr_ip, &rtr.rtr_gwayaddr, IP_ADDR_LEN);
|
|
+ entry->metric = 0;
|
|
|
|
return (0);
|
|
}
|
|
@@ -163,6 +164,7 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
addr_mtob(&rtentries[i].Mask, IP_ADDR_LEN,
|
|
&entry.route_dst.addr_bits);
|
|
entry.route_gw.addr_ip = rtentries[i].NextHop;
|
|
+ entry.metric = 0;
|
|
|
|
if ((ret = callback(&entry, arg)) != 0)
|
|
break;
|
|
diff --git a/libdnet-stripped/src/route-linux.c b/libdnet-stripped/src/route-linux.c
|
|
index a80b71b..b14c527 100644
|
|
--- a/libdnet-stripped/src/route-linux.c
|
|
+++ b/libdnet-stripped/src/route-linux.c
|
|
@@ -252,6 +252,7 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
continue;
|
|
|
|
entry.route_gw.addr_bits = IP_ADDR_BITS;
|
|
+ entry.metric = metric;
|
|
|
|
if ((ret = callback(&entry, arg)) != 0)
|
|
break;
|
|
@@ -260,17 +261,17 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
}
|
|
if (ret == 0 && (fp = fopen(PROC_IPV6_ROUTE_FILE, "r")) != NULL) {
|
|
char s[33], d[8][5], n[8][5];
|
|
- int i, iflags;
|
|
+ int i, iflags, metric;
|
|
u_int slen, dlen;
|
|
|
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
|
i = sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %02x "
|
|
"%32s %02x %04s%04s%04s%04s%04s%04s%04s%04s "
|
|
- "%*x %*x %*x %x %15s",
|
|
+ "%x %*x %*x %x %15s",
|
|
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
|
&dlen, s, &slen,
|
|
n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
|
|
- &iflags, ifbuf);
|
|
+ &metric, &iflags, ifbuf);
|
|
|
|
if (i < 21 || !(iflags & RTF_UP))
|
|
continue;
|
|
@@ -285,6 +286,7 @@ route_loop(route_t *r, route_handler callback, void *arg)
|
|
n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
|
|
IP6_ADDR_BITS);
|
|
addr_aton(buf, &entry.route_gw);
|
|
+ entry.metric = metric;
|
|
|
|
if ((ret = callback(&entry, arg)) != 0)
|
|
break;
|
|
diff --git a/libdnet-stripped/src/route-win32.c b/libdnet-stripped/src/route-win32.c
|
|
index b4536b3..c69b29b 100644
|
|
--- a/libdnet-stripped/src/route-win32.c
|
|
+++ b/libdnet-stripped/src/route-win32.c
|
|
@@ -122,6 +122,7 @@ route_get(route_t *route, struct route_entry *entry)
|
|
entry->route_gw.addr_type = ADDR_TYPE_IP;
|
|
entry->route_gw.addr_bits = IP_ADDR_BITS;
|
|
entry->route_gw.addr_ip = ipfrow.dwForwardNextHop;
|
|
+ entry->metric = ipfrow.dwForwardMetric1;
|
|
|
|
entry->intf_name[0] = '\0';
|
|
intf = intf_open();
|
|
@@ -172,6 +173,7 @@ route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg)
|
|
&entry.route_dst.addr_bits);
|
|
entry.route_gw.addr_ip =
|
|
r->ipftable->table[i].dwForwardNextHop;
|
|
+ entry.metric = r->ipftable->table[i].dwForwardMetric1;
|
|
|
|
/* Look up the interface name. */
|
|
entry.intf_name[0] = '\0';
|
|
@@ -209,6 +211,8 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2,
|
|
for (i = 0; i < r->ipftable2->NumEntries; i++) {
|
|
struct intf_entry intf_entry;
|
|
MIB_IPFORWARD_ROW2 *row;
|
|
+ MIB_IPINTERFACE_ROW ifrow;
|
|
+ ULONG metric;
|
|
|
|
row = &r->ipftable2->Table[i];
|
|
addr_ston((struct sockaddr *) &row->DestinationPrefix.Prefix, &entry.route_dst);
|
|
@@ -223,6 +227,18 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2,
|
|
row->InterfaceIndex) == 0) {
|
|
strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name));
|
|
}
|
|
+
|
|
+ ifrow.Family = row->DestinationPrefix.Prefix.si_family;
|
|
+ ifrow.InterfaceLuid = row->InterfaceLuid;
|
|
+ ifrow.InterfaceIndex = row->InterfaceIndex;
|
|
+ if (GetIpInterfaceEntry(&ifrow) != NO_ERROR) {
|
|
+ return (-1);
|
|
+ }
|
|
+ metric = ifrow.Metric + row->Metric;
|
|
+ if (metric < INT_MAX)
|
|
+ entry.metric = metric;
|
|
+ else
|
|
+ entry.metric = INT_MAX;
|
|
|
|
if ((ret = (*callback)(&entry, arg)) != 0)
|
|
break;
|
|
|
|
o Support Appletalk devices and make addr_ston able to handle
|
|
them. However, this support is not complete since ipddp interfaces
|
|
use different size hardware addresses than Ethernet.
|
|
Nmap IP level scans should work without any
|
|
problem, please see Nmap's '--send-ip' switch.
|
|
|
|
For more information, please see this thread:
|
|
http://seclists.org/nmap-dev/2013/q1/214
|
|
|
|
Index: libdnet-stripped/include/dnet/arp.h
|
|
===================================================================
|
|
--- libdnet-stripped/include/dnet/arp.h (revision 30609)
|
|
+++ libdnet-stripped/include/dnet/arp.h (working copy)
|
|
@@ -40,6 +40,7 @@
|
|
#define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */
|
|
|
|
#define ARP_HRD_INFINIBAND 0x0020 /* InfiniBand */
|
|
+#define ARP_HRD_APPLETALK 0x0309 /* AppleTalk DDP */
|
|
#define ARP_HDR_IEEE80211 0x0321 /* IEEE 802.11 */
|
|
#define ARP_HRD_IEEE80211_RADIOTAP 0x0323 /* IEEE 802.11 + radiotap header */
|
|
#define ARP_HRD_VOID 0xFFFF /* Void type, nothing is known */
|
|
Index: libdnet-stripped/src/addr.c
|
|
===================================================================
|
|
--- libdnet-stripped/src/addr.c (revision 30609)
|
|
+++ libdnet-stripped/src/addr.c (working copy)
|
|
@@ -318,6 +318,7 @@
|
|
#endif
|
|
case AF_UNSPEC:
|
|
case ARP_HRD_ETH: /* XXX- Linux arp(7) */
|
|
+ case ARP_HRD_APPLETALK: /* AppleTalk DDP */
|
|
case ARP_HRD_INFINIBAND: /* InfiniBand */
|
|
case ARP_HDR_IEEE80211: /* IEEE 802.11 */
|
|
case ARP_HRD_IEEE80211_RADIOTAP: /* IEEE 802.11 + radiotap header */
|
|
|
|
|
|
o Added compatibility patch for OpenBSD to not SIOCIFNETMASK before
|
|
SIOCIFADDR. (Giovanni Bechis)
|
|
|
|
diff --git a/libdnet-stripped/src/intf.c b/libdnet-stripped/src/intf.c
|
|
index 4fe059c..184c077 100644
|
|
--- a/libdnet-stripped/src/intf.c
|
|
+++ b/libdnet-stripped/src/intf.c
|
|
@@ -77,7 +77,13 @@
|
|
/* XXX - superset of ifreq, for portable SIOC{A,D}IFADDR */
|
|
struct dnet_ifaliasreq {
|
|
char ifra_name[IFNAMSIZ];
|
|
- struct sockaddr ifra_addr;
|
|
+ union {
|
|
+ struct sockaddr ifrau_addr;
|
|
+ int ifrau_align;
|
|
+ } ifra_ifrau;
|
|
+#ifndef ifra_addr
|
|
+#define ifra_addr ifra_ifrau.ifrau_addr
|
|
+#endif
|
|
struct sockaddr ifra_brdaddr;
|
|
struct sockaddr ifra_mask;
|
|
int ifra_cookie; /* XXX - IRIX!@#$ */
|
|
@@ -308,7 +314,7 @@ intf_set(intf_t *intf, const struct intf_entry *entry)
|
|
}
|
|
/* Set interface address. */
|
|
if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {
|
|
-#ifdef BSD
|
|
+#if defined(BSD) && !defined(__OPENBSD__)
|
|
/* XXX - why must this happen before SIOCSIFADDR? */
|
|
if (addr_btos(entry->intf_addr.addr_bits,
|
|
&ifr.ifr_addr) == 0) {
|
|
|
|
o Use the RT_ROUNDUP preprocessor macro for 64-bit rt_msghdr alignment
|
|
on NetBSD.
|
|
|
|
diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c
|
|
index 44e7dd2..47f3705 100644
|
|
--- a/libdnet-stripped/src/route-bsd.c
|
|
+++ b/libdnet-stripped/src/route-bsd.c
|
|
@@ -47,8 +47,14 @@
|
|
|
|
#include "dnet.h"
|
|
|
|
+#if defined(RT_ROUNDUP) && defined(__NetBSD__)
|
|
+/* NetBSD defines this macro rounding to 64-bit boundaries.
|
|
+ http://fxr.watson.org/fxr/ident?v=NETBSD;i=RT_ROUNDUP */
|
|
+#define ROUNDUP(a) RT_ROUNDUP(a)
|
|
+#else
|
|
#define ROUNDUP(a) \
|
|
((a) > 0 ? (1 + (((a) - 1) | (RT_MSGHDR_ALIGNMENT - 1))) : RT_MSGHDR_ALIGNMENT)
|
|
+#endif
|
|
|
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
|
#define NEXTSA(s) \
|
|
o Fix hw address getting on AIX
|
|
|
|
diff --git a/libdnet-stripped/src/intf.c b/libdnet-stripped/src/intf.c
|
|
index 184c077..2df6a4d 100644
|
|
--- a/libdnet-stripped/src/intf.c
|
|
+++ b/libdnet-stripped/src/intf.c
|
|
@@ -20,6 +20,10 @@
|
|
# include <sys/sockio.h>
|
|
#endif
|
|
/* XXX - AIX */
|
|
+#ifdef HAVE_GETKERNINFO
|
|
+#include <sys/ndd_var.h>
|
|
+#include <sys/kinfo.h>
|
|
+#endif
|
|
#ifndef IP_MULTICAST
|
|
# define IP_MULTICAST
|
|
#endif
|
|
@@ -477,6 +481,11 @@ static int
|
|
_intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
|
{
|
|
struct ifreq ifr;
|
|
+#ifdef HAVE_GETKERNINFO
|
|
+ int size;
|
|
+ struct kinfo_ndd *nddp;
|
|
+ void *end;
|
|
+#endif
|
|
|
|
/* Get interface index. */
|
|
entry->intf_index = if_nametoindex(entry->intf_name);
|
|
@@ -517,7 +526,39 @@ _intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
|
return (-1);
|
|
}
|
|
} else if (entry->intf_type == INTF_TYPE_ETH) {
|
|
-#if defined(SIOCGIFHWADDR)
|
|
+#if defined(HAVE_GETKERNINFO)
|
|
+ /* AIX also defines SIOCGIFHWADDR, but it fails silently?
|
|
+ * This is the method IBM recommends here:
|
|
+ * http://www-01.ibm.com/support/knowledgecenter/ssw_aix_53/com.ibm.aix.progcomm/doc/progcomc/skt_sndother_ex.htm%23ssqinc2joyc?lang=en
|
|
+ */
|
|
+ /* How many bytes will be returned? */
|
|
+ size = getkerninfo(KINFO_NDD, 0, 0, 0);
|
|
+ if (size <= 0) {
|
|
+ return -1;
|
|
+ }
|
|
+ nddp = (struct kinfo_ndd *)malloc(size);
|
|
+
|
|
+ if (!nddp) {
|
|
+ return -1;
|
|
+ }
|
|
+ /* Get all Network Device Driver (NDD) info */
|
|
+ if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
|
|
+ free(nddp);
|
|
+ return -1;
|
|
+ }
|
|
+ /* Loop over the returned values until we find a match */
|
|
+ end = (void *)nddp + size;
|
|
+ while ((void *)nddp < end) {
|
|
+ if (!strcmp(nddp->ndd_alias, entry->intf_name) ||
|
|
+ !strcmp(nddp->ndd_name, entry->intf_name)) {
|
|
+ addr_pack(&entry->intf_link_addr, ADDR_TYPE_ETH, ETH_ADDR_BITS,
|
|
+ nddp->ndd_addr, ETH_ADDR_LEN);
|
|
+ break;
|
|
+ } else
|
|
+ nddp++;
|
|
+ }
|
|
+ free(nddp);
|
|
+#elif defined(SIOCGIFHWADDR)
|
|
if (ioctl(intf->fd, SIOCGIFHWADDR, &ifr) < 0)
|
|
return (-1);
|
|
if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0)
|
|
|
|
o Support 802.11 Prism interfaces in monitor mode
|
|
|
|
diff --git a/libdnet-stripped/include/dnet/arp.h b/libdnet-stripped/include/dnet/arp.h
|
|
index 9bfdcaf..728f8c3 100644
|
|
--- a/libdnet-stripped/include/dnet/arp.h
|
|
+++ b/libdnet-stripped/include/dnet/arp.h
|
|
@@ -42,6 +42,7 @@ struct arp_hdr {
|
|
#define ARP_HRD_INFINIBAND 0x0020 /* InfiniBand */
|
|
#define ARP_HRD_APPLETALK 0x0309 /* AppleTalk DDP */
|
|
#define ARP_HDR_IEEE80211 0x0321 /* IEEE 802.11 */
|
|
+#define ARP_HRD_IEEE80211_PRISM 0x0322 /* IEEE 802.11 + prism header */
|
|
#define ARP_HRD_IEEE80211_RADIOTAP 0x0323 /* IEEE 802.11 + radiotap header */
|
|
#define ARP_HRD_VOID 0xFFFF /* Void type, nothing is known */
|
|
|
|
diff --git a/libdnet-stripped/src/addr.c b/libdnet-stripped/src/addr.c
|
|
index 8953b5b..05a0692 100644
|
|
--- a/libdnet-stripped/src/addr.c
|
|
+++ b/libdnet-stripped/src/addr.c
|
|
@@ -321,6 +321,7 @@ addr_ston(const struct sockaddr *sa, struct addr *a)
|
|
case ARP_HRD_APPLETALK: /* AppleTalk DDP */
|
|
case ARP_HRD_INFINIBAND: /* InfiniBand */
|
|
case ARP_HDR_IEEE80211: /* IEEE 802.11 */
|
|
+ case ARP_HRD_IEEE80211_PRISM: /* IEEE 802.11 + prism header */
|
|
case ARP_HRD_IEEE80211_RADIOTAP: /* IEEE 802.11 + radiotap header */
|
|
a->addr_type = ADDR_TYPE_ETH;
|
|
a->addr_bits = ETH_ADDR_BITS;
|
|
|
|
o Fix a crash when pcap_findalldevs encounters errors and tries to write to
|
|
errbuf. As demonstrated by WinPcap crashing on Surface Pro 3
|
|
|
|
diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c
|
|
index 22c2d59..22c1e6a 100644
|
|
--- a/libdnet-stripped/src/intf-win32.c
|
|
+++ b/libdnet-stripped/src/intf-win32.c
|
|
@@ -425,6 +425,7 @@ intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
pcap_if_t *pcapdevs;
|
|
pcap_if_t *pdev, *selected;
|
|
intf_t *intf;
|
|
+ char errbuf[PCAP_ERRBUF_SIZE];
|
|
|
|
if ((intf = intf_open()) == NULL)
|
|
return (-1);
|
|
@@ -439,7 +440,7 @@ intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
return (-1);
|
|
}
|
|
|
|
- if (pcap_findalldevs(&pcapdevs, NULL) == -1) {
|
|
+ if (pcap_findalldevs(&pcapdevs, errbuf) == -1) {
|
|
intf_close(intf);
|
|
return (-1);
|
|
}
|
|
|
|
o Fix a crash on Windows 8.1 with certain down interfaces:
|
|
http://seclists.org/nmap-dev/2015/q1/282
|
|
|
|
diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c
|
|
index 22c1e6a..3c09f9c 100644
|
|
--- a/libdnet-stripped/src/intf-win32.c
|
|
+++ b/libdnet-stripped/src/intf-win32.c
|
|
@@ -262,7 +262,8 @@ _find_adapter_address(intf_t *intf, const char *device)
|
|
n = atoi(p);
|
|
|
|
for (a = intf->iftable; a != NULL; a = a->Next) {
|
|
- if (intf->ifcombo[type].idx[n].ipv4 == a->IfIndex &&
|
|
+ if ( intf->ifcombo[type].idx != NULL &&
|
|
+ intf->ifcombo[type].idx[n].ipv4 == a->IfIndex &&
|
|
intf->ifcombo[type].idx[n].ipv6 == a->Ipv6IfIndex) {
|
|
return a;
|
|
}
|
|
|
|
o Fix address detection on Solaris due to SIOCGLIFFLAGS ioctl overwriting the
|
|
lifreq that _intf_get_aliases expects to be holding the output of
|
|
SIOCGLIFCONF ioctl. http://seclists.org/nmap-dev/2015/q2/1
|
|
|
|
diff --git a/libdnet-stripped/src/intf.c b/libdnet-stripped/src/intf.c
|
|
index 2df6a4d..b71fb82 100644
|
|
--- a/libdnet-stripped/src/intf.c
|
|
+++ b/libdnet-stripped/src/intf.c
|
|
@@ -953,6 +953,8 @@ intf_loop(intf_t *intf, intf_handler callback, void *arg)
|
|
struct lifreq *lifr, *llifr, *plifr;
|
|
char *p, ebuf[BUFSIZ];
|
|
int ret;
|
|
+ struct lifreq lifrflags;
|
|
+ memset(&lifrflags, 0, sizeof(struct lifreq));
|
|
|
|
entry = (struct intf_entry *)ebuf;
|
|
|
|
@@ -996,14 +998,15 @@ intf_loop(intf_t *intf, intf_handler callback, void *arg)
|
|
* underlying physical interfaces instead. This works as long as
|
|
* the physical interface's test address is on the same subnet
|
|
* as the IPMP interface's address. */
|
|
- if (ioctl(intf->fd, SIOCGLIFFLAGS, lifr) >= 0)
|
|
+ strlcpy(lifrflags.lifr_name, lifr->lifr_name, sizeof(lifrflags.lifr_name));
|
|
+ if (ioctl(intf->fd, SIOCGLIFFLAGS, &lifrflags) >= 0)
|
|
;
|
|
- else if (intf->fd6 != -1 && ioctl(intf->fd6, SIOCGLIFFLAGS, lifr) >= 0)
|
|
+ else if (intf->fd6 != -1 && ioctl(intf->fd6, SIOCGLIFFLAGS, &lifrflags) >= 0)
|
|
;
|
|
else
|
|
return (-1);
|
|
#ifdef IFF_IPMP
|
|
- if (lifr->lifr_flags & IFF_IPMP) {
|
|
+ if (lifrflags.lifr_flags & IFF_IPMP) {
|
|
continue;
|
|
}
|
|
#endif
|
|
|
|
o Avoid a strange hang with the WinPCAP driver when running multiple instances
|
|
of Nmap concurrently.
|
|
|
|
diff --git a/libdnet-stripped/src/eth-win32.c b/libdnet-stripped/src/eth-win32.c
|
|
index 9cbb3f9..de0320e 100644
|
|
--- a/libdnet-stripped/src/eth-win32.c
|
|
+++ b/libdnet-stripped/src/eth-win32.c
|
|
@@ -35,13 +35,21 @@ eth_open(const char *device)
|
|
{
|
|
eth_t *eth;
|
|
char pcapdev[128];
|
|
+ HANDLE pcapMutex;
|
|
+ DWORD wait;
|
|
|
|
if (eth_get_pcap_devname(device, pcapdev, sizeof(pcapdev)) != 0)
|
|
return (NULL);
|
|
|
|
if ((eth = calloc(1, sizeof(*eth))) == NULL)
|
|
return (NULL);
|
|
+ pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
|
|
+ wait = WaitForSingleObject(pcapMutex, INFINITE);
|
|
eth->lpa = PacketOpenAdapter(pcapdev);
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
if (eth->lpa == NULL) {
|
|
eth_close(eth);
|
|
return (NULL);
|
|
@@ -67,11 +75,21 @@ eth_send(eth_t *eth, const void *buf, size_t len)
|
|
eth_t *
|
|
eth_close(eth_t *eth)
|
|
{
|
|
+ HANDLE pcapMutex;
|
|
+ DWORD wait;
|
|
if (eth != NULL) {
|
|
if (eth->pkt != NULL)
|
|
PacketFreePacket(eth->pkt);
|
|
if (eth->lpa != NULL)
|
|
+ {
|
|
+ pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
|
|
+ wait = WaitForSingleObject(pcapMutex, INFINITE);
|
|
PacketCloseAdapter(eth->lpa);
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
+ }
|
|
free(eth);
|
|
}
|
|
return (NULL);
|
|
diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c
|
|
index 3c09f9c..77225b6 100644
|
|
--- a/libdnet-stripped/src/intf-win32.c
|
|
+++ b/libdnet-stripped/src/intf-win32.c
|
|
@@ -427,6 +427,8 @@ intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
pcap_if_t *pdev, *selected;
|
|
intf_t *intf;
|
|
char errbuf[PCAP_ERRBUF_SIZE];
|
|
+ HANDLE pcapMutex;
|
|
+ DWORD wait;
|
|
|
|
if ((intf = intf_open()) == NULL)
|
|
return (-1);
|
|
@@ -441,10 +443,20 @@ intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
return (-1);
|
|
}
|
|
|
|
+ pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
|
|
+ wait = WaitForSingleObject(pcapMutex, INFINITE);
|
|
if (pcap_findalldevs(&pcapdevs, errbuf) == -1) {
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
intf_close(intf);
|
|
return (-1);
|
|
}
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
|
|
/* Loop through all the pcap devices until we find a match. */
|
|
selected = NULL;
|
|
|
|
o (LATER REVERTED) Use a mutex on Windows to avoid a hang when accessing WinPCAP driver.
|
|
Reported by multiple users on Windows 8.1 and Windows Server 2012 R2.
|
|
Seems to hang when the WinPCAP driver is accessed via OpenServiceA by
|
|
multiple processes at once. Users report that this change, which uses a
|
|
mutex to avoid concurrent access, fixes the hang.
|
|
|
|
diff --git a/libdnet-stripped/src/eth-win32.c b/libdnet-stripped/src/eth-win32.c
|
|
index 9cbb3f9..de0320e 100644
|
|
--- a/libdnet-stripped/src/eth-win32.c
|
|
+++ b/libdnet-stripped/src/eth-win32.c
|
|
@@ -35,13 +35,21 @@ eth_open(const char *device)
|
|
{
|
|
eth_t *eth;
|
|
char pcapdev[128];
|
|
+ HANDLE pcapMutex;
|
|
+ DWORD wait;
|
|
|
|
if (eth_get_pcap_devname(device, pcapdev, sizeof(pcapdev)) != 0)
|
|
return (NULL);
|
|
|
|
if ((eth = calloc(1, sizeof(*eth))) == NULL)
|
|
return (NULL);
|
|
+ pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
|
|
+ wait = WaitForSingleObject(pcapMutex, INFINITE);
|
|
eth->lpa = PacketOpenAdapter(pcapdev);
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
if (eth->lpa == NULL) {
|
|
eth_close(eth);
|
|
return (NULL);
|
|
@@ -67,11 +75,21 @@ eth_send(eth_t *eth, const void *buf, size_t len)
|
|
eth_t *
|
|
eth_close(eth_t *eth)
|
|
{
|
|
+ HANDLE pcapMutex;
|
|
+ DWORD wait;
|
|
if (eth != NULL) {
|
|
if (eth->pkt != NULL)
|
|
PacketFreePacket(eth->pkt);
|
|
if (eth->lpa != NULL)
|
|
+ {
|
|
+ pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
|
|
+ wait = WaitForSingleObject(pcapMutex, INFINITE);
|
|
PacketCloseAdapter(eth->lpa);
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
+ }
|
|
free(eth);
|
|
}
|
|
return (NULL);
|
|
diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c
|
|
index 3c09f9c..77225b6 100644
|
|
--- a/libdnet-stripped/src/intf-win32.c
|
|
+++ b/libdnet-stripped/src/intf-win32.c
|
|
@@ -427,6 +427,8 @@ intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
pcap_if_t *pdev, *selected;
|
|
intf_t *intf;
|
|
char errbuf[PCAP_ERRBUF_SIZE];
|
|
+ HANDLE pcapMutex;
|
|
+ DWORD wait;
|
|
|
|
if ((intf = intf_open()) == NULL)
|
|
return (-1);
|
|
@@ -441,10 +443,20 @@ intf_get_pcap_devname(const char *intf_name, char *pcapdev, int pcapdevlen)
|
|
return (-1);
|
|
}
|
|
|
|
+ pcapMutex = CreateMutex(NULL, 0, "Global\\DnetPcapHangAvoidanceMutex");
|
|
+ wait = WaitForSingleObject(pcapMutex, INFINITE);
|
|
if (pcap_findalldevs(&pcapdevs, errbuf) == -1) {
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
intf_close(intf);
|
|
return (-1);
|
|
}
|
|
+ if (wait == WAIT_ABANDONED || wait == WAIT_OBJECT_0) {
|
|
+ ReleaseMutex(pcapMutex);
|
|
+ }
|
|
+ CloseHandle(pcapMutex);
|
|
|
|
/* Loop through all the pcap devices until we find a match. */
|
|
selected = NULL;
|
|
|
|
o Avoid bailing completely when an interface is encountered with an unsupported
|
|
hardware address type. Caused "INTERFACES: NONE FOUND!" bugs in Nmap.
|
|
|
|
diff --git a/libdnet-stripped/src/intf.c b/libdnet-stripped/src/intf.c
|
|
index b71fb82..315e7b0 100644
|
|
--- a/libdnet-stripped/src/intf.c
|
|
+++ b/libdnet-stripped/src/intf.c
|
|
@@ -561,8 +561,11 @@ _intf_get_noalias(intf_t *intf, struct intf_entry *entry)
|
|
#elif defined(SIOCGIFHWADDR)
|
|
if (ioctl(intf->fd, SIOCGIFHWADDR, &ifr) < 0)
|
|
return (-1);
|
|
- if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0)
|
|
- return (-1);
|
|
+ if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0) {
|
|
+ /* Likely we got an unsupported address type. Just use NONE for now. */
|
|
+ entry->intf_link_addr.addr_type = ADDR_TYPE_NONE;
|
|
+ entry->intf_link_addr.addr_bits = 0;
|
|
+ }
|
|
#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. */
|
|
|
|
o Avoid buffer overrun from scanning 32 chars plus terminator into a 16-byte buffer.
|
|
|
|
diff --git a/libdnet-stripped/src/intf.c b/libdnet-stripped/src/intf.c
|
|
index 315e7b0..6180d85 100644
|
|
--- a/libdnet-stripped/src/intf.c
|
|
+++ b/libdnet-stripped/src/intf.c
|
|
@@ -776,7 +776,8 @@ _intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
|
if ((f = fopen(PROC_INET6_FILE, "r")) != NULL) {
|
|
while (ap < lap &&
|
|
fgets(buf, sizeof(buf), f) != NULL) {
|
|
- sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %x %02x %02x %02x %32s\n",
|
|
+ /* scan up to INTF_NAME_LEN-1 bytes to reserve space for null terminator */
|
|
+ sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %x %02x %02x %02x %15s\n",
|
|
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
|
|
&idx, &bits, &scope, &flags, name);
|
|
if (strcmp(name, entry->intf_name) == 0) {
|
|
|
|
o Detect SNMP MIB2 STREAMS on Solaris even if /dev/ip is not present, as it is
|
|
not in some Zones configurations. Using /dev/arp is proper in this case.
|
|
|
|
diff --git a/libdnet-stripped/config/acinclude.m4 b/libdnet-stripped/config/acinclude.m4
|
|
index 622c6a2..3145975 100644
|
|
--- a/libdnet-stripped/config/acinclude.m4
|
|
+++ b/libdnet-stripped/config/acinclude.m4
|
|
@@ -161,12 +161,12 @@ dnl results: HAVE_STREAMS_MIB2
|
|
dnl
|
|
AC_DEFUN(AC_DNET_STREAMS_MIB2,
|
|
[AC_MSG_CHECKING(for SNMP MIB2 STREAMS)
|
|
- AC_CACHE_VAL(ac_cv_dnet_streams_mib2,
|
|
- if test -f /usr/include/inet/mib2.h -a -c /dev/ip ; then
|
|
+ AC_CACHE_VAL(ac_cv_dnet_streams_mib2,[
|
|
+ if test -f /usr/include/inet/mib2.h -a '(' -c /dev/ip -o -c /dev/arp ')' ; then
|
|
ac_cv_dnet_streams_mib2=yes
|
|
else
|
|
ac_cv_dnet_streams_mib2=no
|
|
- fi)
|
|
+ fi])
|
|
AC_MSG_RESULT($ac_cv_dnet_streams_mib2)
|
|
if test $ac_cv_dnet_streams_mib2 = yes ; then
|
|
AC_DEFINE(HAVE_STREAMS_MIB2, 1,
|
|
|
|
o Fix route detection on FreeBSD 11, where net/route.h requires sys/types.h
|
|
|
|
Index: configure.in
|
|
===================================================================
|
|
--- configure.in (revision 36845)
|
|
+++ configure.in (working copy)
|
|
@@ -165,10 +165,10 @@
|
|
AC_CHECK_HEADERS(fcntl.h unistd.h)
|
|
AC_CHECK_HEADERS(sys/bufmod.h sys/dlpi.h sys/dlpihdr.h sys/dlpi_ext.h \
|
|
sys/ioctl.h sys/mib.h sys/ndd_var.h sys/socket.h sys/sockio.h \
|
|
- sys/sysctl.h sys/time.h)
|
|
+ sys/sysctl.h sys/time.h sys/types.h)
|
|
AC_CHECK_HEADERS(net/bpf.h net/if.h net/if_var.h \
|
|
net/if_arp.h net/if_dl.h net/pfilt.h \
|
|
- net/pfvar.h net/radix.h net/raw.h net/route.h netinet/in_var.h \
|
|
+ net/pfvar.h net/radix.h net/raw.h netinet/in_var.h \
|
|
netinet/in6_var.h \
|
|
net/if_tun.h linux/if_tun.h netinet/ip_fw.h linux/ip_fw.h \
|
|
linux/ip_fwchains.h linux/netfilter_ipv4/ipchains_core.h)
|
|
@@ -175,6 +175,12 @@
|
|
AC_CHECK_HEADERS(ip_fil_compat.h netinet/ip_fil_compat.h ip_compat.h \
|
|
netinet/ip_compat.h ip_fil.h netinet/ip_fil.h)
|
|
AC_CHECK_HEADERS(hpsecurity.h stropts.h)
|
|
+ AC_CHECK_HEADERS(net/route.h, [], [],
|
|
+ [
|
|
+#ifdef HAVE_SYS_SOCKET_H
|
|
+#include <sys/socket.h>
|
|
+#endif
|
|
+ ])
|
|
fi
|
|
|
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
|
|
|
o Ensure we read 1 byte less than buffer size to allow for automatically-appended null char.
|
|
|
|
diff --git a/libdnet-stripped/src/arp-ioctl.c b/libdnet-stripped/src/arp-ioctl.c
|
|
index 434142e..31b9f8c 100644
|
|
--- a/libdnet-stripped/src/arp-ioctl.c
|
|
+++ b/libdnet-stripped/src/arp-ioctl.c
|
|
@@ -218,7 +218,7 @@ arp_loop(arp_t *a, arp_handler callback, void *arg)
|
|
|
|
ret = 0;
|
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
|
- i = sscanf(buf, "%s 0x%x 0x%x %100s %100s %100s\n",
|
|
+ i = sscanf(buf, "%s 0x%x 0x%x %99s %99s %99s\n",
|
|
ipbuf, &type, &flags, macbuf, maskbuf, devbuf);
|
|
|
|
if (i < 4 || (flags & ATF_COM) == 0)
|
|
|
|
o REVERTED the change that added a mutex protecting calls to OpenServiceA. We
|
|
are optimistic that Npcap does not have the reported problem.
|
|
|
|
o Add support for new loopback behavior in Npcap 0.9983. There is no KM-TEST
|
|
adapter in GetAdaptersAddresses in this case.
|
|
|
|
diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c
|
|
index 1399db2..352da4c 100644
|
|
--- a/libdnet-stripped/src/intf-win32.c
|
|
+++ b/libdnet-stripped/src/intf-win32.c
|
|
@@ -26,6 +26,7 @@
|
|
#include <Ntddndis.h>
|
|
|
|
int g_has_npcap_loopback = 0;
|
|
+#define _DEVICE_PREFIX "\\Device\\"
|
|
|
|
struct ifcombo {
|
|
struct {
|
|
@@ -214,6 +215,10 @@ _adapter_address_to_entry(intf_t *intf, IP_ADAPTER_ADDRESSES *a,
|
|
|
|
#define NPCAP_SERVICE_REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Services\\npcap"
|
|
|
|
+/* The name of the Npcap loopback adapter is stored in the npcap service's
|
|
+ * Registry key in the LoopbackAdapter value. For legacy loopback support, this
|
|
+ * is a name like "NPF_{GUID}", but for newer Npcap the name is "NPF_Loopback"
|
|
+ */
|
|
int intf_get_loopback_name(char *buffer, int buf_size)
|
|
{
|
|
HKEY hKey;
|
|
@@ -252,43 +257,65 @@ _update_tables_for_npcap_loopback(IP_ADAPTER_ADDRESSES *p)
|
|
IP_ADAPTER_ADDRESSES *a_original_loopback_prev = NULL;
|
|
IP_ADAPTER_ADDRESSES *a_original_loopback = NULL;
|
|
IP_ADAPTER_ADDRESSES *a_npcap_loopback = NULL;
|
|
- char npcap_loopback_name[1024];
|
|
- int has_npcap_loopback = 0;
|
|
+ static char npcap_loopback_name[1024] = {0};
|
|
|
|
- g_has_npcap_loopback = has_npcap_loopback = intf_get_loopback_name(npcap_loopback_name, 1024);
|
|
- if (has_npcap_loopback == 0)
|
|
+ /* Don't bother hitting the registry every time. Not ideal for long-running
|
|
+ * processes, but works for Nmap. */
|
|
+ if (npcap_loopback_name[0] == '\0')
|
|
+ g_has_npcap_loopback = intf_get_loopback_name(npcap_loopback_name, 1024);
|
|
+ if (g_has_npcap_loopback == 0)
|
|
return p;
|
|
|
|
if (!p)
|
|
return p;
|
|
|
|
+ /* Loop through the addresses looking for the dummy loopback interface from Windows. */
|
|
for (a = p; a != NULL; a = a->Next) {
|
|
if (a->IfType == IF_TYPE_SOFTWARE_LOOPBACK) {
|
|
+ /* Dummy loopback. Keep track of it. */
|
|
a_original_loopback = a;
|
|
a_original_loopback_prev = a_prev;
|
|
}
|
|
- else if (strcmp(a->AdapterName, npcap_loopback_name + strlen("\\Device\\")) == 0) {
|
|
+ else if (strcmp(a->AdapterName, npcap_loopback_name + strlen(_DEVICE_PREFIX) - 1) == 0) {
|
|
+ /* Legacy loopback adapter. The modern one doesn't show up in GetAdaptersAddresses. */
|
|
a_npcap_loopback = a;
|
|
}
|
|
a_prev = a;
|
|
}
|
|
|
|
- if (!a_original_loopback || !a_npcap_loopback)
|
|
+ /* If there's no loopback on this system, something's wrong. Windows is
|
|
+ * supposed to create this. */
|
|
+ if (!a_original_loopback)
|
|
return p;
|
|
-
|
|
- a_npcap_loopback->IfType = a_original_loopback->IfType;
|
|
- a_npcap_loopback->FirstUnicastAddress = a_original_loopback->FirstUnicastAddress;
|
|
- a_npcap_loopback->FirstPrefix = a_original_loopback->FirstPrefix;
|
|
- memset(a_npcap_loopback->PhysicalAddress, 0, ETH_ADDR_LEN);
|
|
- if (a_original_loopback_prev) {
|
|
- a_original_loopback_prev->Next = a_original_loopback_prev->Next->Next;
|
|
+ /* If we didn't find the legacy adapter, use the modern adapter name. */
|
|
+ if (!a_npcap_loopback) {
|
|
+ /* Overwrite the name we got from the Registry, in case it's a broken legacy
|
|
+ * install, in which case we'll never find the legacy adapter anyway. */
|
|
+ strlcpy(npcap_loopback_name, _DEVICE_PREFIX "NPF_Loopback", 1024);
|
|
+ /* Overwrite the AdapterName from the system's own loopback adapter with
|
|
+ * the NPF_Loopback name. This is what we use to open the adapter with
|
|
+ * Packet.dll later. */
|
|
+ a_original_loopback->AdapterName = npcap_loopback_name + sizeof(_DEVICE_PREFIX) - 1;
|
|
return p;
|
|
}
|
|
- else if (a_original_loopback == p) {
|
|
- return a_original_loopback->Next;
|
|
- }
|
|
else {
|
|
- return p;
|
|
+ /* Legacy loopback adapter was found. Copy some key info from the system's
|
|
+ * loopback adapter. */
|
|
+ a_npcap_loopback->IfType = a_original_loopback->IfType;
|
|
+ a_npcap_loopback->FirstUnicastAddress = a_original_loopback->FirstUnicastAddress;
|
|
+ a_npcap_loopback->FirstPrefix = a_original_loopback->FirstPrefix;
|
|
+ memset(a_npcap_loopback->PhysicalAddress, 0, ETH_ADDR_LEN);
|
|
+ /* Unlink the original loopback adapter from the list. We'll use Npcap's instead. */
|
|
+ if (a_original_loopback_prev) {
|
|
+ a_original_loopback_prev->Next = a_original_loopback_prev->Next->Next;
|
|
+ return p;
|
|
+ }
|
|
+ else if (a_original_loopback == p) {
|
|
+ return a_original_loopback->Next;
|
|
+ }
|
|
+ else {
|
|
+ return p;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -551,11 +578,17 @@ intf_get_pcap_devname_cached(const char *intf_name, char *pcapdev, int pcapdevle
|
|
for (pdev = pcapdevs; pdev != NULL; pdev = pdev->next) {
|
|
char *name;
|
|
|
|
- if (pdev->name == NULL)
|
|
- continue;
|
|
- name = strchr(pdev->name, '{');
|
|
- if (name == NULL)
|
|
+ if (pdev->name == NULL || strlen(pdev->name) < sizeof(_DEVICE_PREFIX))
|
|
continue;
|
|
+ /* "\\Device\\NPF_{GUID}"
|
|
+ * "\\Device\\NPF_Loopback"
|
|
+ * Find the '{'after device prefix.
|
|
+ */
|
|
+ name = strchr(pdev->name + sizeof(_DEVICE_PREFIX) - 1, '{');
|
|
+ if (name == NULL) {
|
|
+ /* If no GUID, just match the whole device name */
|
|
+ name = pdev->name + sizeof(_DEVICE_PREFIX) - 1;
|
|
+ }
|
|
if (strcmp(name, a->AdapterName) == 0)
|
|
break;
|
|
}
|
|
|
|
o Remove call to FreeLibrary after GetModuleHandle. Windows API docs say:
|
|
"do not pass a handle returned by GetModuleHandle to the FreeLibrary function.
|
|
Doing so can cause a DLL module to be unmapped prematurely."
|
|
|
|
diff --git a/libdnet-stripped/src/route-win32.c b/libdnet-stripped/src/route-win32.c
|
|
index c69b29b..8a9d2bc 100644
|
|
--- a/libdnet-stripped/src/route-win32.c
|
|
+++ b/libdnet-stripped/src/route-win32.c
|
|
@@ -269,8 +269,6 @@ route_t *
|
|
route_close(route_t *r)
|
|
{
|
|
if (r != NULL) {
|
|
- if (r->iphlpapi != NULL)
|
|
- FreeLibrary(r->iphlpapi);
|
|
if (r->ipftable != NULL)
|
|
free(r->ipftable);
|
|
if (r->ipftable2 != NULL)
|
|
o Additional fix for route detection on FreeBSD 11, where net/route.h
|
|
requires sys/types.h
|
|
--- a/libdnet-stripped/configure.in 2020-10-14 21:08:09.275534843 -0600
|
|
+++ b/libdnet-stripped/configure.in 2022-03-23 18:02:44.842111434 -0600
|
|
@@ -177,6 +177,7 @@
|
|
AC_CHECK_HEADERS(hpsecurity.h stropts.h)
|
|
AC_CHECK_HEADERS(net/route.h, [], [],
|
|
[
|
|
+AC_INCLUDES_DEFAULT
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
#include <sys/socket.h>
|
|
#endif
|