diff --git a/CHANGELOG b/CHANGELOG index e5d776c5c..f70cdca23 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,18 @@ # Nmap Changelog ($Id$); -*-text-*- +4.20 + +o Fixed (I hope) the "getinterfaces: intf_loop() failed" error which + was seen on Windows Vista. The problem was apparently in + intf-win32.c of libcnet (need to define MIB_IF_TYPE_MAX to + MAX_IF_TYPE rather than 32). Thanks to Dan Griffin + (dan(a)jwsecure.com) for tracking this down! + +o Applied a couple minor bug fixes from Marek Majkowski to IP options + support (which he previously added) and packet tracing. + +o Incorporated SLNP (Simple Library Network Protocol) version + detection support. Thanks to Tibor Csogor (tibi(a)tiborius.net) for + the patch. 4.20RC1 diff --git a/libdnet-stripped/NMAP_MODIFICATIONS b/libdnet-stripped/NMAP_MODIFICATIONS index 6809d6399..58da795fb 100644 --- a/libdnet-stripped/NMAP_MODIFICATIONS +++ b/libdnet-stripped/NMAP_MODIFICATIONS @@ -297,3 +297,16 @@ Index: src/intf.c return (-1); entry->intf_mtu = ifr.ifr_mtu; +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]; diff --git a/libdnet-stripped/src/intf-win32.c b/libdnet-stripped/src/intf-win32.c index 572c4ec27..c5b49caae 100644 --- a/libdnet-stripped/src/intf-win32.c +++ b/libdnet-stripped/src/intf-win32.c @@ -1,452 +1,452 @@ -/* - * intf-win32.c - * - * Copyright (c) 2002 Dug Song - * - * $Id: intf-win32.c,v 1.24 2005/02/15 06:37:06 dugsong Exp $ - */ - -#ifdef _WIN32 -#include "dnet_winconfig.h" -#else -#include "config.h" -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "pcap.h" - -struct ifcombo { - DWORD *idx; - int cnt; - int max; -}; - -#define MIB_IF_TYPE_MAX 32 /* XXX - ipifcons.h */ - -struct intf_handle { - struct ifcombo ifcombo[MIB_IF_TYPE_MAX]; - MIB_IFTABLE *iftable; - MIB_IPADDRTABLE *iptable; -}; - -static char * -_ifcombo_name(int type) -{ - char *name = "net"; /* XXX */ - - if (type == MIB_IF_TYPE_ETHERNET) { - name = "eth"; - } else if (type == MIB_IF_TYPE_TOKENRING) { - name = "tr"; - } else if (type == MIB_IF_TYPE_FDDI) { - name = "fddi"; - } else if (type == MIB_IF_TYPE_PPP) { - name = "ppp"; - } else if (type == MIB_IF_TYPE_LOOPBACK) { - name = "lo"; - } else if (type == MIB_IF_TYPE_SLIP) { - name = "sl"; - } - return (name); -} - -static int -_ifcombo_type(const char *device) -{ - int type = INTF_TYPE_OTHER; - - if (strncmp(device, "eth", 3) == 0) { - type = INTF_TYPE_ETH; - } else if (strncmp(device, "tr", 2) == 0) { - type = INTF_TYPE_TOKENRING; - } else if (strncmp(device, "fd", 2) == 0) { - type = INTF_TYPE_FDDI; - } else if (strncmp(device, "ppp", 3) == 0) { - type = INTF_TYPE_PPP; - } else if (strncmp(device, "lo", 2) == 0) { - type = INTF_TYPE_LOOPBACK; - } else if (strncmp(device, "sl", 2) == 0) { - type = INTF_TYPE_SLIP; - } - return (type); -} - -static void -_ifcombo_add(struct ifcombo *ifc, DWORD idx) -{ - if (ifc->cnt == ifc->max) { - if (ifc->idx) { - ifc->max *= 2; - ifc->idx = realloc(ifc->idx, - sizeof(ifc->idx[0]) * ifc->max); - } else { - ifc->max = 8; - ifc->idx = malloc(sizeof(ifc->idx[0]) * ifc->max); - } - } - ifc->idx[ifc->cnt++] = idx; -} - -static void -_ifrow_to_entry(intf_t *intf, MIB_IFROW *ifrow, struct intf_entry *entry) -{ - struct addr *ap, *lap; - int i; - - memset(entry, 0, sizeof(*entry)); - - for (i = 0; i < intf->ifcombo[ifrow->dwType].cnt; i++) { - if (intf->ifcombo[ifrow->dwType].idx[i] == ifrow->dwIndex) - break; - } - /* XXX - dwType 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; - - /* Get interface flags. */ - entry->intf_flags = 0; - if (ifrow->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP && - (ifrow->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL || - ifrow->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED)) - entry->intf_flags |= INTF_FLAG_UP; - if (ifrow->dwType == MIB_IF_TYPE_LOOPBACK) - entry->intf_flags |= INTF_FLAG_LOOPBACK; - else - entry->intf_flags |= INTF_FLAG_MULTICAST; - - /* Get interface MTU. */ - entry->intf_mtu = ifrow->dwMtu; - - /* Get hardware address. */ - if (ifrow->dwPhysAddrLen == ETH_ADDR_LEN) { - entry->intf_link_addr.addr_type = ADDR_TYPE_ETH; - entry->intf_link_addr.addr_bits = ETH_ADDR_BITS; - memcpy(&entry->intf_link_addr.addr_eth, ifrow->bPhysAddr, - ETH_ADDR_LEN); - } - /* Get addresses. */ - ap = entry->intf_alias_addrs; - lap = ap + ((entry->intf_len - sizeof(*entry)) / - sizeof(entry->intf_alias_addrs[0])); - for (i = 0; i < (int)intf->iptable->dwNumEntries; i++) { - if (intf->iptable->table[i].dwIndex == ifrow->dwIndex && - intf->iptable->table[i].dwAddr != 0) { - if (entry->intf_addr.addr_type == ADDR_TYPE_NONE) { - /* Set primary address if unset. */ - entry->intf_addr.addr_type = ADDR_TYPE_IP; - entry->intf_addr.addr_ip = - intf->iptable->table[i].dwAddr; - addr_mtob(&intf->iptable->table[i].dwMask, - IP_ADDR_LEN, &entry->intf_addr.addr_bits); - } else if (ap < lap) { - /* Set aliases. */ - ap->addr_type = ADDR_TYPE_IP; - ap->addr_ip = intf->iptable->table[i].dwAddr; - addr_mtob(&intf->iptable->table[i].dwMask, - IP_ADDR_LEN, &ap->addr_bits); - ap++, entry->intf_alias_num++; - } - } - } - entry->intf_len = (unsigned int) ((u_char *)ap - (u_char *)entry); -} - -static int -_refresh_tables(intf_t *intf) -{ - MIB_IFROW *ifrow; - ULONG len; - u_int i, ret; - - /* Get interface table. */ - for (len = sizeof(intf->iftable[0]); ; ) { - if (intf->iftable) - free(intf->iftable); - intf->iftable = malloc(len); - ret = GetIfTable(intf->iftable, &len, FALSE); - if (ret == NO_ERROR) - break; - else if (ret != ERROR_INSUFFICIENT_BUFFER) - return (-1); - } - /* Get IP address table. */ - for (len = sizeof(intf->iptable[0]); ; ) { - if (intf->iptable) - free(intf->iptable); - intf->iptable = malloc(len); - ret = GetIpAddrTable(intf->iptable, &len, FALSE); - if (ret == NO_ERROR) - break; - else if (ret != ERROR_INSUFFICIENT_BUFFER) - return (-1); - } - /* - * Map "unfriendly" win32 interface indices to ours. - * XXX - like IP_ADAPTER_INFO ComboIndex - */ - for (i = 0; i < intf->iftable->dwNumEntries; i++) { - ifrow = &intf->iftable->table[i]; - if (ifrow->dwType < MIB_IF_TYPE_MAX) { - _ifcombo_add(&intf->ifcombo[ifrow->dwType], - ifrow->dwIndex); - } else - return (-1); - } - return (0); -} - -static int -_find_ifindex(intf_t *intf, const char *device) -{ - char *p = (char *)device; - int n, type = _ifcombo_type(device); - - while (isalpha(*p)) p++; - n = atoi(p); - - return (intf->ifcombo[type].idx[n]); -} - -intf_t * -intf_open(void) -{ - return (calloc(1, sizeof(intf_t))); -} - -int -intf_get(intf_t *intf, struct intf_entry *entry) -{ - MIB_IFROW ifrow; - - if (_refresh_tables(intf) < 0) - return (-1); - - ifrow.dwIndex = _find_ifindex(intf, entry->intf_name); - - if (GetIfEntry(&ifrow) != NO_ERROR) - return (-1); - - _ifrow_to_entry(intf, &ifrow, entry); - - return (0); -} - -/* XXX - gross hack required by eth-win32:eth_open() */ -const char * -intf_get_desc(intf_t *intf, const char *name) -{ - static char desc[MAXLEN_IFDESCR + 1]; - MIB_IFROW ifrow; - - if (_refresh_tables(intf) < 0) - return (NULL); - - ifrow.dwIndex = _find_ifindex(intf, name); - - if (GetIfEntry(&ifrow) != NO_ERROR) - return (NULL); - - - return (desc); -} - -/* 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 intf_get_pcap_devname(const char *ifname, char *pcapdev, int pcapdevlen) { - int i; - intf_t *intf; - struct intf_entry ie; - pcap_if_t *pcapdevs; - pcap_if_t *pdev; - char pname[128]; - struct sockaddr_in devip; - pcap_addr_t *pa; - - 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); - - /* Find the first IPv4 address for ie */ - if (ie.intf_addr.addr_type == ADDR_TYPE_IP) { - addr_ntos(&ie.intf_addr, (struct sockaddr *) &devip); - } else { - for(i=0; i < (int) ie.intf_alias_num; i++) { - if (ie.intf_alias_addrs[i].addr_type == ADDR_TYPE_IP) { - addr_ntos(&ie.intf_alias_addrs[i], (struct sockaddr *) &devip); - break; - } - } - if (i == ie.intf_alias_num) - return -1; // Failed to find IPv4 address, which is currently a requirement - } - - /* 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)". Plus, Packet* functions aren't really supported for external use by the - WinPcap folks. So I have rewritten this to compare interface addresses (which has its own - problems -- what if you want to listen an an interface with no IP address set?) --Fyodor */ - if (pcap_findalldevs(&pcapdevs, NULL) == -1) - return -1; - - for(pdev=pcapdevs; pdev && !pname[0]; pdev = pdev->next) { - for (pa=pdev->addresses; pa && !pname[0]; pa = pa->next) { - if (pa->addr->sa_family != AF_INET) - continue; - if (((struct sockaddr_in *)pa->addr)->sin_addr.s_addr == devip.sin_addr.s_addr) { - strlcpy(pname, pdev->name, sizeof(pname)); /* Found it -- Yay! */ - break; - } - } - } - - pcap_freealldevs(pcapdevs); - if (pname[0]) { - strlcpy(pcapdev, pname, pcapdevlen); - return 0; - } - return -1; -} - - -int -intf_get_src(intf_t *intf, struct intf_entry *entry, struct addr *src) -{ - MIB_IFROW ifrow; - MIB_IPADDRROW *iprow; - int i; - - if (src->addr_type != ADDR_TYPE_IP) { - errno = EINVAL; - return (-1); - } - if (_refresh_tables(intf) < 0) - return (-1); - - for (i = 0; i < (int)intf->iptable->dwNumEntries; i++) { - iprow = &intf->iptable->table[i]; - if (iprow->dwAddr == src->addr_ip) { - ifrow.dwIndex = iprow->dwIndex; - if (GetIfEntry(&ifrow) != NO_ERROR) - return (-1); - _ifrow_to_entry(intf, &ifrow, entry); - return (0); - } - } - errno = ENXIO; - return (-1); -} - -int -intf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst) -{ - MIB_IFROW ifrow; - - if (dst->addr_type != ADDR_TYPE_IP) { - errno = EINVAL; - return (-1); - } - if (GetBestInterface(dst->addr_ip, &ifrow.dwIndex) != NO_ERROR) - return (-1); - - if (GetIfEntry(&ifrow) != NO_ERROR) - return (-1); - - if (_refresh_tables(intf) < 0) - return (-1); - - _ifrow_to_entry(intf, &ifrow, entry); - - return (0); -} - -int -intf_set(intf_t *intf, const struct intf_entry *entry) -{ - /* - * XXX - could set interface up/down via SetIfEntry(), - * but what about the rest of the configuration? :-( - * {Add,Delete}IPAddress for 2000/XP only - */ -#if 0 - /* Set interface address. XXX - 2000/XP only? */ - if (entry->intf_addr.addr_type == ADDR_TYPE_IP) { - ULONG ctx = 0, inst = 0; - UINT ip, mask; - - memcpy(&ip, &entry->intf_addr.addr_ip, IP_ADDR_LEN); - addr_btom(entry->intf_addr.addr_bits, &mask, IP_ADDR_LEN); - - if (AddIPAddress(ip, mask, - _find_ifindex(intf, entry->intf_name), - &ctx, &inst) != NO_ERROR) { - return (-1); - } - return (0); - } -#endif - errno = ENOSYS; - SetLastError(ERROR_NOT_SUPPORTED); - return (-1); -} - -int -intf_loop(intf_t *intf, intf_handler callback, void *arg) -{ - struct intf_entry *entry; - u_char ebuf[1024]; - int i, ret = 0; - - if (_refresh_tables(intf) < 0) - return (-1); - - entry = (struct intf_entry *)ebuf; - - for (i = 0; i < (int)intf->iftable->dwNumEntries; i++) { - entry->intf_len = sizeof(ebuf); - _ifrow_to_entry(intf, &intf->iftable->table[i], entry); - if ((ret = (*callback)(entry, arg)) != 0) - break; - } - return (ret); -} - -intf_t * -intf_close(intf_t *intf) -{ - int i; - - if (intf != NULL) { - for (i = 0; i < MIB_IF_TYPE_MAX; i++) { - if (intf->ifcombo[i].idx) - free(intf->ifcombo[i].idx); - } - if (intf->iftable) - free(intf->iftable); - if (intf->iptable) - free(intf->iptable); - free(intf); - } - return (NULL); -} +/* + * intf-win32.c + * + * Copyright (c) 2002 Dug Song + * + * $Id: intf-win32.c,v 1.24 2005/02/15 06:37:06 dugsong Exp $ + */ + +#ifdef _WIN32 +#include "dnet_winconfig.h" +#else +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pcap.h" + +struct ifcombo { + DWORD *idx; + int cnt; + int max; +}; + +#define MIB_IF_TYPE_MAX MAX_IF_TYPE /* XXX - ipifcons.h */ + +struct intf_handle { + struct ifcombo ifcombo[MIB_IF_TYPE_MAX]; + MIB_IFTABLE *iftable; + MIB_IPADDRTABLE *iptable; +}; + +static char * +_ifcombo_name(int type) +{ + char *name = "net"; /* XXX */ + + if (type == MIB_IF_TYPE_ETHERNET) { + name = "eth"; + } else if (type == MIB_IF_TYPE_TOKENRING) { + name = "tr"; + } else if (type == MIB_IF_TYPE_FDDI) { + name = "fddi"; + } else if (type == MIB_IF_TYPE_PPP) { + name = "ppp"; + } else if (type == MIB_IF_TYPE_LOOPBACK) { + name = "lo"; + } else if (type == MIB_IF_TYPE_SLIP) { + name = "sl"; + } + return (name); +} + +static int +_ifcombo_type(const char *device) +{ + int type = INTF_TYPE_OTHER; + + if (strncmp(device, "eth", 3) == 0) { + type = INTF_TYPE_ETH; + } else if (strncmp(device, "tr", 2) == 0) { + type = INTF_TYPE_TOKENRING; + } else if (strncmp(device, "fd", 2) == 0) { + type = INTF_TYPE_FDDI; + } else if (strncmp(device, "ppp", 3) == 0) { + type = INTF_TYPE_PPP; + } else if (strncmp(device, "lo", 2) == 0) { + type = INTF_TYPE_LOOPBACK; + } else if (strncmp(device, "sl", 2) == 0) { + type = INTF_TYPE_SLIP; + } + return (type); +} + +static void +_ifcombo_add(struct ifcombo *ifc, DWORD idx) +{ + if (ifc->cnt == ifc->max) { + if (ifc->idx) { + ifc->max *= 2; + ifc->idx = realloc(ifc->idx, + sizeof(ifc->idx[0]) * ifc->max); + } else { + ifc->max = 8; + ifc->idx = malloc(sizeof(ifc->idx[0]) * ifc->max); + } + } + ifc->idx[ifc->cnt++] = idx; +} + +static void +_ifrow_to_entry(intf_t *intf, MIB_IFROW *ifrow, struct intf_entry *entry) +{ + struct addr *ap, *lap; + int i; + + memset(entry, 0, sizeof(*entry)); + + for (i = 0; i < intf->ifcombo[ifrow->dwType].cnt; i++) { + if (intf->ifcombo[ifrow->dwType].idx[i] == ifrow->dwIndex) + break; + } + /* XXX - dwType 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; + + /* Get interface flags. */ + entry->intf_flags = 0; + if (ifrow->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP && + (ifrow->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL || + ifrow->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED)) + entry->intf_flags |= INTF_FLAG_UP; + if (ifrow->dwType == MIB_IF_TYPE_LOOPBACK) + entry->intf_flags |= INTF_FLAG_LOOPBACK; + else + entry->intf_flags |= INTF_FLAG_MULTICAST; + + /* Get interface MTU. */ + entry->intf_mtu = ifrow->dwMtu; + + /* Get hardware address. */ + if (ifrow->dwPhysAddrLen == ETH_ADDR_LEN) { + entry->intf_link_addr.addr_type = ADDR_TYPE_ETH; + entry->intf_link_addr.addr_bits = ETH_ADDR_BITS; + memcpy(&entry->intf_link_addr.addr_eth, ifrow->bPhysAddr, + ETH_ADDR_LEN); + } + /* Get addresses. */ + ap = entry->intf_alias_addrs; + lap = ap + ((entry->intf_len - sizeof(*entry)) / + sizeof(entry->intf_alias_addrs[0])); + for (i = 0; i < (int)intf->iptable->dwNumEntries; i++) { + if (intf->iptable->table[i].dwIndex == ifrow->dwIndex && + intf->iptable->table[i].dwAddr != 0) { + if (entry->intf_addr.addr_type == ADDR_TYPE_NONE) { + /* Set primary address if unset. */ + entry->intf_addr.addr_type = ADDR_TYPE_IP; + entry->intf_addr.addr_ip = + intf->iptable->table[i].dwAddr; + addr_mtob(&intf->iptable->table[i].dwMask, + IP_ADDR_LEN, &entry->intf_addr.addr_bits); + } else if (ap < lap) { + /* Set aliases. */ + ap->addr_type = ADDR_TYPE_IP; + ap->addr_ip = intf->iptable->table[i].dwAddr; + addr_mtob(&intf->iptable->table[i].dwMask, + IP_ADDR_LEN, &ap->addr_bits); + ap++, entry->intf_alias_num++; + } + } + } + entry->intf_len = (unsigned int) ((u_char *)ap - (u_char *)entry); +} + +static int +_refresh_tables(intf_t *intf) +{ + MIB_IFROW *ifrow; + ULONG len; + u_int i, ret; + + /* Get interface table. */ + for (len = sizeof(intf->iftable[0]); ; ) { + if (intf->iftable) + free(intf->iftable); + intf->iftable = malloc(len); + ret = GetIfTable(intf->iftable, &len, FALSE); + if (ret == NO_ERROR) + break; + else if (ret != ERROR_INSUFFICIENT_BUFFER) + return (-1); + } + /* Get IP address table. */ + for (len = sizeof(intf->iptable[0]); ; ) { + if (intf->iptable) + free(intf->iptable); + intf->iptable = malloc(len); + ret = GetIpAddrTable(intf->iptable, &len, FALSE); + if (ret == NO_ERROR) + break; + else if (ret != ERROR_INSUFFICIENT_BUFFER) + return (-1); + } + /* + * Map "unfriendly" win32 interface indices to ours. + * XXX - like IP_ADAPTER_INFO ComboIndex + */ + for (i = 0; i < intf->iftable->dwNumEntries; i++) { + ifrow = &intf->iftable->table[i]; + if (ifrow->dwType < MIB_IF_TYPE_MAX) { + _ifcombo_add(&intf->ifcombo[ifrow->dwType], + ifrow->dwIndex); + } else + return (-1); + } + return (0); +} + +static int +_find_ifindex(intf_t *intf, const char *device) +{ + char *p = (char *)device; + int n, type = _ifcombo_type(device); + + while (isalpha(*p)) p++; + n = atoi(p); + + return (intf->ifcombo[type].idx[n]); +} + +intf_t * +intf_open(void) +{ + return (calloc(1, sizeof(intf_t))); +} + +int +intf_get(intf_t *intf, struct intf_entry *entry) +{ + MIB_IFROW ifrow; + + if (_refresh_tables(intf) < 0) + return (-1); + + ifrow.dwIndex = _find_ifindex(intf, entry->intf_name); + + if (GetIfEntry(&ifrow) != NO_ERROR) + return (-1); + + _ifrow_to_entry(intf, &ifrow, entry); + + return (0); +} + +/* XXX - gross hack required by eth-win32:eth_open() */ +const char * +intf_get_desc(intf_t *intf, const char *name) +{ + static char desc[MAXLEN_IFDESCR + 1]; + MIB_IFROW ifrow; + + if (_refresh_tables(intf) < 0) + return (NULL); + + ifrow.dwIndex = _find_ifindex(intf, name); + + if (GetIfEntry(&ifrow) != NO_ERROR) + return (NULL); + + + return (desc); +} + +/* 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 intf_get_pcap_devname(const char *ifname, char *pcapdev, int pcapdevlen) { + int i; + intf_t *intf; + struct intf_entry ie; + pcap_if_t *pcapdevs; + pcap_if_t *pdev; + char pname[128]; + struct sockaddr_in devip; + pcap_addr_t *pa; + + 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); + + /* Find the first IPv4 address for ie */ + if (ie.intf_addr.addr_type == ADDR_TYPE_IP) { + addr_ntos(&ie.intf_addr, (struct sockaddr *) &devip); + } else { + for(i=0; i < (int) ie.intf_alias_num; i++) { + if (ie.intf_alias_addrs[i].addr_type == ADDR_TYPE_IP) { + addr_ntos(&ie.intf_alias_addrs[i], (struct sockaddr *) &devip); + break; + } + } + if (i == ie.intf_alias_num) + return -1; // Failed to find IPv4 address, which is currently a requirement + } + + /* 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)". Plus, Packet* functions aren't really supported for external use by the + WinPcap folks. So I have rewritten this to compare interface addresses (which has its own + problems -- what if you want to listen an an interface with no IP address set?) --Fyodor */ + if (pcap_findalldevs(&pcapdevs, NULL) == -1) + return -1; + + for(pdev=pcapdevs; pdev && !pname[0]; pdev = pdev->next) { + for (pa=pdev->addresses; pa && !pname[0]; pa = pa->next) { + if (pa->addr->sa_family != AF_INET) + continue; + if (((struct sockaddr_in *)pa->addr)->sin_addr.s_addr == devip.sin_addr.s_addr) { + strlcpy(pname, pdev->name, sizeof(pname)); /* Found it -- Yay! */ + break; + } + } + } + + pcap_freealldevs(pcapdevs); + if (pname[0]) { + strlcpy(pcapdev, pname, pcapdevlen); + return 0; + } + return -1; +} + + +int +intf_get_src(intf_t *intf, struct intf_entry *entry, struct addr *src) +{ + MIB_IFROW ifrow; + MIB_IPADDRROW *iprow; + int i; + + if (src->addr_type != ADDR_TYPE_IP) { + errno = EINVAL; + return (-1); + } + if (_refresh_tables(intf) < 0) + return (-1); + + for (i = 0; i < (int)intf->iptable->dwNumEntries; i++) { + iprow = &intf->iptable->table[i]; + if (iprow->dwAddr == src->addr_ip) { + ifrow.dwIndex = iprow->dwIndex; + if (GetIfEntry(&ifrow) != NO_ERROR) + return (-1); + _ifrow_to_entry(intf, &ifrow, entry); + return (0); + } + } + errno = ENXIO; + return (-1); +} + +int +intf_get_dst(intf_t *intf, struct intf_entry *entry, struct addr *dst) +{ + MIB_IFROW ifrow; + + if (dst->addr_type != ADDR_TYPE_IP) { + errno = EINVAL; + return (-1); + } + if (GetBestInterface(dst->addr_ip, &ifrow.dwIndex) != NO_ERROR) + return (-1); + + if (GetIfEntry(&ifrow) != NO_ERROR) + return (-1); + + if (_refresh_tables(intf) < 0) + return (-1); + + _ifrow_to_entry(intf, &ifrow, entry); + + return (0); +} + +int +intf_set(intf_t *intf, const struct intf_entry *entry) +{ + /* + * XXX - could set interface up/down via SetIfEntry(), + * but what about the rest of the configuration? :-( + * {Add,Delete}IPAddress for 2000/XP only + */ +#if 0 + /* Set interface address. XXX - 2000/XP only? */ + if (entry->intf_addr.addr_type == ADDR_TYPE_IP) { + ULONG ctx = 0, inst = 0; + UINT ip, mask; + + memcpy(&ip, &entry->intf_addr.addr_ip, IP_ADDR_LEN); + addr_btom(entry->intf_addr.addr_bits, &mask, IP_ADDR_LEN); + + if (AddIPAddress(ip, mask, + _find_ifindex(intf, entry->intf_name), + &ctx, &inst) != NO_ERROR) { + return (-1); + } + return (0); + } +#endif + errno = ENOSYS; + SetLastError(ERROR_NOT_SUPPORTED); + return (-1); +} + +int +intf_loop(intf_t *intf, intf_handler callback, void *arg) +{ + struct intf_entry *entry; + u_char ebuf[1024]; + int i, ret = 0; + + if (_refresh_tables(intf) < 0) + return (-1); + + entry = (struct intf_entry *)ebuf; + + for (i = 0; i < (int)intf->iftable->dwNumEntries; i++) { + entry->intf_len = sizeof(ebuf); + _ifrow_to_entry(intf, &intf->iftable->table[i], entry); + if ((ret = (*callback)(entry, arg)) != 0) + break; + } + return (ret); +} + +intf_t * +intf_close(intf_t *intf) +{ + int i; + + if (intf != NULL) { + for (i = 0; i < MIB_IF_TYPE_MAX; i++) { + if (intf->ifcombo[i].idx) + free(intf->ifcombo[i].idx); + } + if (intf->iftable) + free(intf->iftable); + if (intf->iptable) + free(intf->iptable); + free(intf); + } + return (NULL); +} diff --git a/nmap-os-db b/nmap-os-db index f53999c47..5d02c6347 100644 --- a/nmap-os-db +++ b/nmap-os-db @@ -203,8 +203,7 @@ U1(DF=N%T=40%TG=40%TOS=0%IPL=38%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=0%RUL=G%RUD=G) IE(DFI=S%T=40%TG=40%TOSI=S%CD=S%SI=S%DLI=S) # Apple Mac OS 10.4.8/ppc (Darwin tetralyre 8.8.0 Darwin Kernel Version 8.8.0: Fri Sep 8 17:18:57 PDT -# Darwin 8.8.1 Darwin Kernel Version 8.8.1: Mon Sep 25 -19:42:00 PDT 2006; root:xnu-792.13.8.obj~1/RELEASE_I386 i386 i386 +# Darwin 8.8.1 Darwin Kernel Version 8.8.1: Mon Sep 25 19:42:00 PDT 2006; root:xnu-792.13.8.obj~1/RELEASE_I386 i386 i386 Fingerprint Apple Mac OS X 10.4.8 (Tiger) Class Apple | Mac OS X | 10.4.X | general purpose SEQ(SP=FB-105%GCD=<7%ISR=FF-10B%TI=I%II=I%SS=S%TS=0|1) @@ -638,7 +637,8 @@ IE(DFI=S%T=FF%TG=FF%TOSI=S%CD=S%SI=S|OS:S%DLI=S) # D-Link DI-624 wireless router rev. C, firmware 2.76 (24 Aug 2006) # D-Link DI-524 WAP Firmware 1.21 -Fingerprint D-Link DI-624 or DI-524 WAP +# D-Link DI-604, firmware 3.52 +Fingerprint D-Link DI-524, DI-604, or DI-624 WAP Class D-Link | embedded || broadband router SEQ(SP=B-15%GCD=FA7F|1F4FE|2EF7D|3E9FC|4E47B|5DEFA%ISR=96-A0%TI=I%II=I%SS=S%TS=U) OPS(O1=M5B0%O2=M5B0%O3=M5B0%O4=M5B0%O5=M5B0%O6=M5B0) diff --git a/nmap-services b/nmap-services index a36a810da..7ec21243d 100644 --- a/nmap-services +++ b/nmap-services @@ -1844,6 +1844,8 @@ ppp 3000/tcp # User-level ppp daemon, or chili!soft asp nessusd 3001/tcp # Nessus Security Scanner (www.nessus.org) Daemon or chili!soft asp deslogin 3005/tcp # encrypted symmetric telnet/login deslogind 3006/tcp # +slnp 3025/tcp # SLNP (Simple Library Network Protocol) by Sisis Informationssysteme GmbH +slnp 3045/tcp # SLNP (Simple Library Network Protocol) by Sisis Informationssysteme GmbH cfs 3049/tcp # cryptographic file system (nfs) (proposed) cfs 3049/udp # cryptographic file system (nfs) PowerChute 3052/tcp @@ -1859,11 +1861,15 @@ ccmail 3264/udp # cc:mail/lotus globalcatLDAP 3268/tcp # Global Catalog LDAP globalcatLDAPssl 3269/tcp # Global Catalog LDAP over ssl meetingmaker 3292/tcp # Meeting maker time management software +saprouter 3299/tcp # SAProuter mysql 3306/tcp # mySQL dec-notes 3333/tcp # DEC Notes dec-notes 3333/udp # DEC Notes msdtc 3372/tcp # MS distributed transaction coordinator ms-term-serv 3389/tcp # Microsoft Remote Display Protocol +saposs 3397/tcp # SAP Oss +sapcomm 3398/tcp # SAPcomm +sapeps 3399/tcp # SAP EPS squid-snmp 3401/udp # Squid proxy SNMP port bmap 3421/tcp # Bull Apprise portmapper bmap 3421/udp # Bull Apprise portmapper @@ -2119,6 +2125,7 @@ http-alt 8000/tcp # A common alternative http port ajp12 8007/tcp # Apache JServ Protocol 1.x ajp13 8009/tcp # Apache JServ Protocol 1.3 ftp-proxy 8021/tcp # Common FTP proxy port +slnp 8076/tcp # SLNP (Simple Library Network Protocol) by Sisis Informationssysteme GmbH http-proxy 8080/tcp # Common HTTP proxy/second web server port blackice-icecap 8081/tcp # ICECap user console blackice-alerts 8082/tcp # BlackIce Alerts sent to this port diff --git a/tcpip.cc b/tcpip.cc index d78b1d06a..312bd5de6 100644 --- a/tcpip.cc +++ b/tcpip.cc @@ -487,7 +487,7 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) { srchost, ntohs(tcp->th_sport), dsthost, ntohs(tcp->th_dport), ipinfo, tcpinfo); } else { // at least first 16 bytes of TCP header are there - snprintf(tcpinfo, sizeof(tcpinfo), "seq=%lu win=%hi", + snprintf(tcpinfo, sizeof(tcpinfo), "seq=%lu win=%hu", (unsigned long) ntohl(tcp->th_seq), ntohs(tcp->th_win)); p = tflags; @@ -500,7 +500,7 @@ static const char *ippackethdrinfo(const u8 *packet, u32 len) { *p++ = 'A'; snprintf(buf, sizeof(buf), " ack=%lu", (unsigned long) ntohl(tcp->th_ack)); - strncat(tcpinfo, buf, sizeof(tcpinfo) - 1); + strncat(tcpinfo, buf, sizeof(tcpinfo) - strlen(tcpinfo) - 1); } if (tcp->th_flags & TH_URG) *p++ = 'U'; if (tcp->th_flags & TH_ECE) *p++ = 'E'; /* rfc 2481/3168 */