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.
This commit is contained in:
oliverschmidt 2006-10-06 22:39:31 +00:00
parent acade90174
commit ca05ae80a5
1 changed files with 112 additions and 40 deletions

View File

@ -30,15 +30,18 @@
*
* Author: Oliver Schmidt <ol.sc@web.de>
*
* $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 <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdlib.h>
#include <malloc.h>
#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 <IP addr of Ethernet card to share>\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 <IP addr of Ethernet card to share>\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();