1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-21 06:59:01 +00:00

libdnet stripped and integrated, ARP ping scan starting to work pretty well

This commit is contained in:
fyodor
2005-04-30 05:12:29 +00:00
parent 3922128b12
commit 4d2beed7c3
106 changed files with 65969 additions and 23 deletions

View File

@@ -0,0 +1,141 @@
/*
* arp-win32.c
*
* Copyright (c) 2002 Dug Song <dugsong@monkey.org>
*
* $Id: arp-win32.c,v 1.12 2005/01/23 07:36:54 dugsong Exp $
*/
#include "config.h"
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "dnet.h"
struct arp_handle {
MIB_IPNETTABLE *iptable;
};
arp_t *
arp_open(void)
{
return (calloc(1, sizeof(arp_t)));
}
int
arp_add(arp_t *arp, const struct arp_entry *entry)
{
MIB_IPFORWARDROW ipfrow;
MIB_IPNETROW iprow;
if (GetBestRoute(entry->arp_pa.addr_ip,
IP_ADDR_ANY, &ipfrow) != NO_ERROR)
return (-1);
iprow.dwIndex = ipfrow.dwForwardIfIndex;
iprow.dwPhysAddrLen = ETH_ADDR_LEN;
memcpy(iprow.bPhysAddr, &entry->arp_ha.addr_eth, ETH_ADDR_LEN);
iprow.dwAddr = entry->arp_pa.addr_ip;
iprow.dwType = 4; /* XXX - static */
if (CreateIpNetEntry(&iprow) != NO_ERROR)
return (-1);
return (0);
}
int
arp_delete(arp_t *arp, const struct arp_entry *entry)
{
MIB_IPFORWARDROW ipfrow;
MIB_IPNETROW iprow;
if (GetBestRoute(entry->arp_pa.addr_ip,
IP_ADDR_ANY, &ipfrow) != NO_ERROR)
return (-1);
memset(&iprow, 0, sizeof(iprow));
iprow.dwIndex = ipfrow.dwForwardIfIndex;
iprow.dwAddr = entry->arp_pa.addr_ip;
if (DeleteIpNetEntry(&iprow) != NO_ERROR) {
errno = ENXIO;
return (-1);
}
return (0);
}
static int
_arp_get_entry(const struct arp_entry *entry, void *arg)
{
struct arp_entry *e = (struct arp_entry *)arg;
if (addr_cmp(&entry->arp_pa, &e->arp_pa) == 0) {
memcpy(&e->arp_ha, &entry->arp_ha, sizeof(e->arp_ha));
return (1);
}
return (0);
}
int
arp_get(arp_t *arp, struct arp_entry *entry)
{
if (arp_loop(arp, _arp_get_entry, entry) != 1) {
errno = ENXIO;
SetLastError(ERROR_NO_DATA);
return (-1);
}
return (0);
}
int
arp_loop(arp_t *arp, arp_handler callback, void *arg)
{
struct arp_entry entry;
ULONG len;
int i, ret;
for (len = sizeof(arp->iptable[0]); ; ) {
if (arp->iptable)
free(arp->iptable);
arp->iptable = malloc(len);
ret = GetIpNetTable(arp->iptable, &len, FALSE);
if (ret == NO_ERROR)
break;
else if (ret != ERROR_INSUFFICIENT_BUFFER)
return (-1);
}
entry.arp_pa.addr_type = ADDR_TYPE_IP;
entry.arp_pa.addr_bits = IP_ADDR_BITS;
entry.arp_ha.addr_type = ADDR_TYPE_ETH;
entry.arp_ha.addr_bits = ETH_ADDR_BITS;
for (i = 0; i < (int)arp->iptable->dwNumEntries; i++) {
if (arp->iptable->table[i].dwPhysAddrLen != ETH_ADDR_LEN)
continue;
entry.arp_pa.addr_ip = arp->iptable->table[i].dwAddr;
memcpy(&entry.arp_ha.addr_eth,
arp->iptable->table[i].bPhysAddr, ETH_ADDR_LEN);
if ((ret = (*callback)(&entry, arg)) != 0)
return (ret);
}
return (0);
}
arp_t *
arp_close(arp_t *arp)
{
if (arp != NULL) {
if (arp->iptable != NULL)
free(arp->iptable);
free(arp);
}
return (NULL);
}