version 1.1.1.2, 2013/07/22 11:54:42
|
version 1.1.1.3, 2023/09/27 11:11:38
|
Line 1
|
Line 1
|
/* |
/* |
* $Id$ |
|
* |
|
* libnet |
* libnet |
* libnet_link_win32.c - low-level win32 libwpcap routines |
* libnet_link_win32.c - low-level win32 libwpcap routines |
* |
* |
Line 32
|
Line 30
|
* |
* |
*/ |
*/ |
|
|
#if (HAVE_CONFIG_H) | /* Libnet's unnamespaced ICMP6_ macros stomp on the enumerated versions of |
#include "../include/config.h" | these names in the MS headers, so pre-include this header. */ |
#endif | |
#include <winsock2.h> |
#include <winsock2.h> |
#include <iphlpapi.h> /* From the Microsoft Platform SDK */ |
#include <iphlpapi.h> /* From the Microsoft Platform SDK */ |
#include "../include/win32/libnet.h" | #include <iprtrmib.h> |
#include <assert.h> |
#include <assert.h> |
#include <Packet32.h> |
|
#include <Ntddndis.h> |
|
#include "iprtrmib.h" |
|
|
|
|
#include "common.h" |
|
|
|
/* |
|
* These are the types that are the same on all platforms, and that |
|
* have been defined by <net/bpf.h> for ages. |
|
*/ |
|
|
|
#ifndef DLT_NULL |
|
#define DLT_NULL 0 /* BSD loopback encapsulation */ |
|
#endif |
|
|
|
#ifndef DLT_EN10MB |
|
#define DLT_EN10MB 1 /* Ethernet (10Mb) */ |
|
#endif |
|
|
|
#ifndef DLT_EN3MB |
|
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ |
|
#endif |
|
|
|
#ifndef DLT_AX25 |
|
#define DLT_AX25 3 /* Amateur Radio AX.25 */ |
|
#endif |
|
|
|
#ifndef DLT_PRONET |
|
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ |
|
#endif |
|
|
|
#ifndef DLT_CHAOS |
|
#define DLT_CHAOS 5 /* Chaos */ |
|
#endif |
|
|
|
#ifndef DLT_IEEE802 |
|
#define DLT_IEEE802 6 /* 802.5 Token Ring */ |
|
#endif |
|
|
|
#ifndef DLT_ARCNET |
|
#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ |
|
#endif |
|
|
|
#ifndef DLT_SLIP |
|
#define DLT_SLIP 8 /* Serial Line IP */ |
|
#endif |
|
|
|
#ifndef DLT_PPP |
|
#define DLT_PPP 9 /* Point-to-point Protocol */ |
|
#endif |
|
|
|
#ifndef DLT_FDDI |
|
#define DLT_FDDI 10 /* FDDI */ |
|
#endif |
|
|
|
/* |
|
* These are types that are different on some platforms, and that |
|
* have been defined by <net/bpf.h> for ages. We use #ifdefs to |
|
* detect the BSDs that define them differently from the traditional |
|
* libpcap <net/bpf.h> |
|
* |
|
* XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, |
|
* but I don't know what the right #define is for BSD/OS. |
|
*/ |
|
|
|
#ifndef DLT_ATM_RFC1483 |
|
#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ |
|
#endif |
|
|
int |
int |
libnet_open_link(libnet_t *l) |
libnet_open_link(libnet_t *l) |
{ |
{ |
Line 50 libnet_open_link(libnet_t *l)
|
Line 110 libnet_open_link(libnet_t *l)
|
NetType IFType; |
NetType IFType; |
|
|
if (l == NULL) |
if (l == NULL) |
{ | { |
return (-1); |
return (-1); |
} | } |
|
|
if (l->device == NULL) |
if (l->device == NULL) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): NULL device\n", __func__); | "%s(): NULL device", __func__); |
return (-1); |
return (-1); |
} |
} |
|
|
l->lpAdapter = 0; |
l->lpAdapter = 0; |
|
|
/* open adapter */ |
/* open adapter */ |
l->lpAdapter = PacketOpenAdapter(l->device); | l->lpAdapter = PacketOpenAdapter(l->device); |
if (!l->lpAdapter || (l->lpAdapter->hFile == INVALID_HANDLE_VALUE)) |
if (!l->lpAdapter || (l->lpAdapter->hFile == INVALID_HANDLE_VALUE)) |
{ |
{ |
dwErrorCode=GetLastError(); |
dwErrorCode=GetLastError(); |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): unable to open the driver, error Code : %lx\n", | "%s(): unable to open the driver, error Code : %lx", |
__func__, dwErrorCode); | __func__, dwErrorCode); |
return (-1); |
return (-1); |
} |
} |
| |
/* increase the send buffer */ |
/* increase the send buffer */ |
PacketSetBuff(l->lpAdapter, 512000); |
PacketSetBuff(l->lpAdapter, 512000); |
|
|
Line 84 libnet_open_link(libnet_t *l)
|
Line 144 libnet_open_link(libnet_t *l)
|
{ |
{ |
switch(IFType.LinkType) |
switch(IFType.LinkType) |
{ |
{ |
case NdisMedium802_3: | case NdisMedium802_3: |
l->link_type = DLT_EN10MB; | l->link_type = DLT_EN10MB; |
l->link_offset = LIBNET_ETH_H; | l->link_offset = LIBNET_ETH_H; |
break; | break; |
case NdisMedium802_5: | case NdisMedium802_5: |
l->link_type = DLT_IEEE802; | l->link_type = DLT_IEEE802; |
l->link_offset = LIBNET_TOKEN_RING_H; | l->link_offset = LIBNET_TOKEN_RING_H; |
break; | break; |
case NdisMediumFddi: | case NdisMediumFddi: |
l->link_type = DLT_FDDI; | l->link_type = DLT_FDDI; |
l->link_offset = 0x15; | l->link_offset = 0x15; |
break; | break; |
case NdisMediumWan: | case NdisMediumWan: |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s():, WinPcap has disabled support for Network type (%d)\n", | "%s():, WinPcap has disabled support for Network type (%d)", |
__func__, IFType.LinkType); | __func__, IFType.LinkType); |
return (-1); | return (-1); |
break; | break; |
case NdisMediumAtm: | case NdisMediumAtm: |
l->link_type = DLT_ATM_RFC1483; | l->link_type = DLT_ATM_RFC1483; |
break; | break; |
case NdisMediumArcnet878_2: | case NdisMediumArcnet878_2: |
l->link_type = DLT_ARCNET; | l->link_type = DLT_ARCNET; |
break; | break; |
default: | default: |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): network type (%d) is not supported\n", | "%s(): network type (%d) is not supported", |
__func__, IFType.LinkType); | __func__, IFType.LinkType); |
return (-1); | return (-1); |
break; | break; |
} |
} |
} |
} |
else |
else |
{ |
{ |
dwErrorCode=GetLastError(); |
dwErrorCode=GetLastError(); |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): unable to determine the network type, error Code : %lx\n", | "%s(): unable to determine the network type, error Code : %lx", |
__func__, dwErrorCode); | __func__, dwErrorCode); |
return (-1); |
return (-1); |
} |
} |
return (1); |
return (1); |
Line 139 libnet_close_link_interface(libnet_t *l)
|
Line 199 libnet_close_link_interface(libnet_t *l)
|
} |
} |
|
|
int |
int |
libnet_write_link(libnet_t *l, const uint8_t *packet, uint32_t size) | libnet_write_link(libnet_t *l, const uint8_t *data, uint32_t size) |
{ |
{ |
LPPACKET lpPacket; | PACKET pkt; |
DWORD BytesTransfered; | DWORD BytesTransfered = -1; |
|
|
BytesTransfered = -1; | /* Packet* arguments aren't const, but aren't actually modified. |
| */ |
| PacketInitPacket(&pkt, (PVOID)data, size); |
|
|
if ((lpPacket = PacketAllocatePacket()) == NULL) | if (PacketSendPacket(l->lpAdapter, &pkt, TRUE)) |
{ | BytesTransfered = size; |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, | |
"%s(): failed to allocate the LPPACKET structure\n", __func__); | |
return (-1); | |
} | |
PacketInitPacket(lpPacket, packet, size); | |
|
|
/* PacketSendPacket returns a BOOLEAN */ |
|
if(PacketSendPacket(l->lpAdapter, lpPacket, TRUE)) |
|
{ |
|
BytesTransfered = size; |
|
} |
|
|
|
PacketFreePacket(lpPacket); |
|
return (BytesTransfered); |
return (BytesTransfered); |
} |
} |
|
|
struct libnet_ether_addr * |
struct libnet_ether_addr * |
libnet_get_hwaddr(libnet_t *l) |
libnet_get_hwaddr(libnet_t *l) |
{ |
{ |
/* This implementation is not-reentrant. */ | struct libnet_ether_addr *mac = &l->link_addr; |
static struct libnet_ether_addr *mac; | |
| |
ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1); |
ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA) + sizeof(ULONG) - 1); |
PPACKET_OID_DATA OidData; | PPACKET_OID_DATA OidData; |
| |
int i = 0; | |
|
|
if (l == NULL) | int i = 0; |
{ | |
| if (l == NULL) |
| { |
return (NULL); |
return (NULL); |
} | } |
|
|
if (l->device == NULL) | if (l->device == NULL) |
{ | { |
if (libnet_select_device(l) == -1) |
if (libnet_select_device(l) == -1) |
{ | { |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): can't figure out a device to use\n", __func__); | "%s(): can't figure out a device to use", __func__); |
return (NULL); |
return (NULL); |
} |
} |
} |
} |
|
|
mac = (struct libnet_ether_addr *)calloc(1,sizeof(struct libnet_ether_addr)); | OidData = (struct _PACKET_OID_DATA *)malloc(IoCtlBufferLength); |
if (mac == NULL) | if (OidData == NULL) |
{ | { |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, | snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): calloc error\n", __func__); | "%s(): OidData is NULL", __func__); |
return (NULL); | return(NULL); |
} | } |
|
|
OidData = (struct _PACKET_OID_DATA *) malloc(IoCtlBufferLength); | if (l->link_type == DLT_IEEE802) |
| { |
if (OidData == NULL) | OidData->Oid = OID_802_5_CURRENT_ADDRESS; |
{ | } |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, | else |
"%s(): OidData is NULL\n", __func__); | { |
return(NULL); | OidData->Oid = OID_802_3_CURRENT_ADDRESS; |
} | } |
|
|
if (l->link_type == DLT_IEEE802) | OidData->Length = 6; |
{ | if ((PacketRequest(l->lpAdapter, FALSE, OidData)) == FALSE) |
OidData->Oid = OID_802_5_CURRENT_ADDRESS; | { |
} | memset(mac, 0, 6); |
else | } |
{ | else |
OidData->Oid = OID_802_3_CURRENT_ADDRESS; | { |
} | for (i = 0; i < 6; i++) |
| { |
OidData->Length = 6; | mac->ether_addr_octet[i] = OidData->Data[i]; |
if((PacketRequest(l->lpAdapter, FALSE, OidData)) == FALSE) | } |
{ | } |
memset(mac, 0, 6); | free(OidData); |
} | return(mac); |
else | |
{ | |
for (i = 0; i < 6; i++) | |
{ | |
mac->ether_addr_octet[i] = OidData->Data[i]; | |
} | |
} | |
free(OidData); | |
return(mac); | |
} |
} |
|
|
struct hostent *gethostbyname2(const int8_t *name, int af) |
|
{ |
|
/* XXX not implemented */ |
|
return(NULL); |
|
} |
|
|
|
BYTE * |
BYTE * |
libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP) |
libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP) |
Line 251 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
|
Line 285 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
|
static BYTE bcastmac[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; |
static BYTE bcastmac[]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; |
|
|
BYTE *MAC = libnet_win32_read_arp_table(DestIP); |
BYTE *MAC = libnet_win32_read_arp_table(DestIP); |
| |
if (MAC==NULL) |
if (MAC==NULL) |
{ |
{ |
memset(pulMac, 0xff, sizeof (pulMac)); |
memset(pulMac, 0xff, sizeof (pulMac)); |
memset(&sin, 0, sizeof(sin)); |
memset(&sin, 0, sizeof(sin)); |
| |
if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR) |
if((hr = SendARP (DestIP, 0, pulMac, &ulLen)) != NO_ERROR) |
{ |
{ |
*(int32_t *)&sin.sin_addr = DestIP; |
*(int32_t *)&sin.sin_addr = DestIP; |
Line 280 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
|
Line 314 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
|
return(bcastmac); /* ff:ff:ff:ff:ff:ff */ |
return(bcastmac); /* ff:ff:ff:ff:ff:ff */ |
} |
} |
} |
} |
| |
pbHexMac = (PBYTE) pulMac; |
pbHexMac = (PBYTE) pulMac; |
|
|
return (pbHexMac); |
return (pbHexMac); |
Line 291 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
|
Line 325 libnet_win32_get_remote_mac(libnet_t *l, DWORD DestIP)
|
} |
} |
} |
} |
|
|
BYTE * libnet_win32_read_arp_table(DWORD DestIP) | BYTE *libnet_win32_read_arp_table(DWORD DestIP) |
{ |
{ |
static BYTE buffMAC[6]; | static BYTE buffMAC[6]; |
BOOL fOrder=TRUE; | BOOL fOrder = TRUE; |
BYTE *MAC=NULL; | DWORD status; |
DWORD status, i, ci; | |
| |
PMIB_IPNETTABLE pIpNetTable = NULL; | |
DWORD Size = 0; | |
| |
memset(buffMAC, 0, sizeof(buffMAC)); | |
|
|
if((status = GetIpNetTable(pIpNetTable, &Size, fOrder)) == ERROR_INSUFFICIENT_BUFFER) | MIB_IPNETTABLE *pIpNetTable = NULL; |
| DWORD Size = 0; |
| |
| memset(buffMAC, 0, sizeof(buffMAC)); |
| status = GetIpNetTable(NULL, &Size, fOrder); |
| if (status == ERROR_INSUFFICIENT_BUFFER) |
{ |
{ |
pIpNetTable = (PMIB_IPNETTABLE) malloc(Size); | pIpNetTable = alloca(Size); |
assert(pIpNetTable); | |
status = GetIpNetTable(pIpNetTable, &Size, fOrder); |
status = GetIpNetTable(pIpNetTable, &Size, fOrder); |
} |
} |
|
|
if(status == NO_ERROR) | if (status == NO_ERROR) |
{ | |
/* set current interface */ | |
ci = pIpNetTable->table[0].dwIndex; | |
| |
for (i = 0; i < pIpNetTable->dwNumEntries; ++i) | |
{ | |
if (pIpNetTable->table[i].dwIndex != ci) | |
ci = pIpNetTable->table[i].dwIndex; | |
| |
if(pIpNetTable->table[i].dwAddr == DestIP) /* found IP in arp cache */ | |
{ | |
memcpy(buffMAC, pIpNetTable->table[i].bPhysAddr, sizeof(buffMAC)); | |
free(pIpNetTable); | |
return buffMAC; | |
} | |
} | |
| |
if (pIpNetTable) | |
free (pIpNetTable); | |
return(NULL); | |
} | |
else | |
{ |
{ |
if (pIpNetTable) | DWORD i, ci = pIpNetTable->table[0].dwIndex; /* set current interface */ |
| |
| for (i = 0; i < pIpNetTable->dwNumEntries; ++i) |
{ |
{ |
free (pIpNetTable); | if (pIpNetTable->table[i].dwIndex != ci) |
| ci = pIpNetTable->table[i].dwIndex; |
| |
| if(pIpNetTable->table[i].dwAddr == DestIP) /* found IP in arp cache */ |
| { |
| memcpy(buffMAC, pIpNetTable->table[i].bPhysAddr, sizeof(buffMAC)); |
| return buffMAC; |
| } |
} |
} |
MAC=NULL; |
|
} |
} |
|
|
return(NULL); |
return(NULL); |
} |
} |
|
|
/* EOF */ | /** |
| * Local Variables: |
| * indent-tabs-mode: nil |
| * c-file-style: "stroustrup" |
| * End: |
| */ |