From ca05ae80a5babffd65681bf59e73e4fc78a4ce05 Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Fri, 6 Oct 2006 22:39:31 +0000 Subject: [PATCH] Added automatic detection of Ethernet address - this makes the WinPcap packet driver service kind of working :-) First the WinPcap library is used to enumerate the existing interfaces to make sure that only those are taken into account which the WinPcap library is able to actually work with. Their IP addresses are compaired against the one on the cmdline to find the desired interface. Then the IP Helper API is used to enumerate the existing adapters to find out the the Ethernet address of the desired adapter. This Ethernet address is then used by Contiki too. --- platform/win32/net/wpcap-service.c | 152 +++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 40 deletions(-) diff --git a/platform/win32/net/wpcap-service.c b/platform/win32/net/wpcap-service.c index 6b7b6b614..acdf90c54 100644 --- a/platform/win32/net/wpcap-service.c +++ b/platform/win32/net/wpcap-service.c @@ -30,15 +30,18 @@ * * Author: Oliver Schmidt * - * $Id: wpcap-service.c,v 1.3 2006/10/03 11:27:51 oliverschmidt Exp $ + * $Id: wpcap-service.c,v 1.4 2006/10/06 22:39:31 oliverschmidt Exp $ */ #define WIN32_LEAN_AND_MEAN #include #include +#include #include +#include #pragma comment(lib, "wsock32") +#pragma comment(lib, "iphlpapi.lib") #define htons /* Avoid 'redefinition' error. */ #include "contiki.h" @@ -102,11 +105,13 @@ pollhandler(void) if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { debug_printf("I"); + uip_len -= sizeof(struct uip_eth_hdr); tcpip_input(); } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { debug_printf("A"); + uip_arp_arpin(); if(uip_len > 0) { if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) { @@ -126,14 +131,118 @@ send_packet(void) } } /*---------------------------------------------------------------------------*/ +static void +init_pcap(struct in_addr addr) +{ + struct pcap_if *interfaces; + char error[256]; + + if(pcap_findalldevs(&interfaces, error) == -1) { + error_exit(error); + } + + while(interfaces != NULL) { + debug_printf("Found interface: %s\n", interfaces->description); + + if(interfaces->addresses != NULL && + interfaces->addresses->addr != NULL && + interfaces->addresses->addr->sa_family == AF_INET) { + + struct in_addr interface_addr; + interface_addr = ((struct sockaddr_in *)interfaces->addresses->addr)->sin_addr; + debug_printf(" With address: %s\n", inet_ntoa(interface_addr)); + + if(interface_addr.s_addr == addr.s_addr) { + break; + } + } + interfaces = interfaces->next; + } + + if(interfaces == NULL) { + error_exit("No interface found with IP addr specified on cmdline\n"); + } + + pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error); + if(pcap == NULL) { + error_exit(error); + } +} +/*---------------------------------------------------------------------------*/ +static void +set_ethaddr(struct in_addr addr) +{ + PIP_ADAPTER_ADDRESSES adapters; + ULONG size = 0; + + if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER, + NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) { + error_exit("Error on access to adapter list size\n"); + } + adapters = alloca(size); + if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER, + NULL, adapters, &size) != ERROR_SUCCESS) { + error_exit("Error on access to adapter list\n"); + } + + while(adapters != NULL) { + + char description[256]; + WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1, + description, sizeof(description), NULL, NULL); + debug_printf("Found adapter: %s\n", description); + + if(adapters->FirstUnicastAddress != NULL && + adapters->FirstUnicastAddress->Address.lpSockaddr != NULL && + adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET) { + + struct in_addr adapter_addr; + adapter_addr = ((struct sockaddr_in *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin_addr; + debug_printf(" With address: %s\n", inet_ntoa(adapter_addr)); + + if(adapter_addr.s_addr == addr.s_addr) { + if(adapters->PhysicalAddressLength != 6) { + error_exit("IP addr specified on cmdline does not belong to an Ethernet card\n"); + } + debug_printf(" Ethernetaddr: %02X-%02X-%02X-%02X-%02X-%02X\n", + adapters->PhysicalAddress[0], + adapters->PhysicalAddress[1], + adapters->PhysicalAddress[2], + adapters->PhysicalAddress[3], + adapters->PhysicalAddress[4], + adapters->PhysicalAddress[5]); + + uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress)); + break; + } + } + adapters = adapters->Next; + } + + if(adapters == NULL) { + error_exit("No adapter found with IP addr specified on cmdline\n"); + } +} +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(wpcap_service_process, ev, data) { + static struct in_addr addr; static HMODULE wpcap; PROCESS_POLLHANDLER(pollhandler()); PROCESS_BEGIN(); + addr.s_addr = inet_addr(__argv[1]); + if(addr.s_addr == INADDR_NONE) { + error_exit("Usage: contiki \n"); + } + debug_printf("Cmdline address: %s\n", inet_ntoa(addr)); + wpcap = LoadLibrary("wpcap.dll"); (FARPROC)pcap_findalldevs = GetProcAddress(wpcap, "pcap_findalldevs"); (FARPROC)pcap_open_live = GetProcAddress(wpcap, "pcap_open_live"); @@ -145,45 +254,8 @@ PROCESS_THREAD(wpcap_service_process, ev, data) error_exit("Error on access to WinPcap library\n"); } - { - struct in_addr cmdline_addr; - struct pcap_if *interfaces; - char error[256]; - - cmdline_addr.s_addr = inet_addr(__argv[1]); - if(cmdline_addr.s_addr == INADDR_NONE) { - error_exit("Usage: contiki \n"); - } - debug_printf("Cmdline address: %s\n", inet_ntoa(cmdline_addr)); - - if(pcap_findalldevs(&interfaces, error) == -1) { - error_exit(error); - } - - while(interfaces != NULL) { - debug_printf("Found interface: %s\n", interfaces->description); - if(interfaces->addresses != NULL && - interfaces->addresses->addr != NULL && - interfaces->addresses->addr->sa_family == AF_INET) { - struct in_addr interface_addr; - interface_addr = ((struct sockaddr_in *)interfaces->addresses->addr)->sin_addr; - debug_printf(" With address: %s\n", inet_ntoa(interface_addr)); - if(interface_addr.s_addr == cmdline_addr.s_addr) { - break; - } - } - interfaces = interfaces->next; - } - - if(interfaces == NULL) { - error_exit("No Ethernet card found with IP addr specified on cmdline\n"); - } - - pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error); - if(pcap == NULL) { - error_exit(error); - } - } + init_pcap(addr); + set_ethaddr(addr); uip_arp_init();