diff --git a/platform/minimal-net/Makefile.minimal-net b/platform/minimal-net/Makefile.minimal-net index ca9f770ff..53080f282 100644 --- a/platform/minimal-net/Makefile.minimal-net +++ b/platform/minimal-net/Makefile.minimal-net @@ -7,7 +7,12 @@ endif CONTIKI_TARGET_DIRS = . net CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} -CONTIKI_TARGET_SOURCEFILES = tapdev-service.c tapdev.c contiki-main.c dlloader.c clock.c leds.c leds-arch.c +CONTIKI_TARGET_SOURCEFILES = contiki-main.c dlloader.c clock.c leds.c leds-arch.c +ifeq ($(OS),Windows_NT) +CONTIKI_TARGET_SOURCEFILES += wpcap-service.c wpcap.c +else +CONTIKI_TARGET_SOURCEFILES += tapdev-service.c tapdev.c +endif CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) @@ -29,6 +34,9 @@ CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ -Wall -g -I. -I/usr/local/include CFLAGS += $(CFLAGSNO) LDFLAGS = -Wl,-Map=contiki.map,-export-dynamic +ifeq ($(OS),Windows_NT) +TARGET_LIBFILES = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a +endif ### Setup directory search path for source files diff --git a/platform/minimal-net/contiki-main.c b/platform/minimal-net/contiki-main.c index 9133eec3b..3191a5c31 100644 --- a/platform/minimal-net/contiki-main.c +++ b/platform/minimal-net/contiki-main.c @@ -29,17 +29,24 @@ * * This file is part of the Contiki OS * - * $Id: contiki-main.c,v 1.2 2006/08/10 19:23:13 bg- Exp $ + * $Id: contiki-main.c,v 1.3 2007/03/26 02:53:54 oliverschmidt Exp $ * */ #include "contiki.h" #include "net/uip.h" +#ifdef __CYGWIN__ +#include "net/wpcap-service.h" +#else #include "net/tapdev-service.h" +#endif -PROCINIT(&etimer_process, &tcpip_process, - &tapdev_process); +#ifdef __CYGWIN__ +PROCINIT(&etimer_process, &tcpip_process, &wpcap_process); +#else +PROCINIT(&etimer_process, &tcpip_process, &tapdev_process); +#endif /*---------------------------------------------------------------------------*/ int diff --git a/platform/minimal-net/net/wpcap-service.c b/platform/minimal-net/net/wpcap-service.c new file mode 100644 index 000000000..2ab966ef9 --- /dev/null +++ b/platform/minimal-net/net/wpcap-service.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt + * + * @(#)$Id: wpcap-service.c,v 1.1 2007/03/26 02:53:54 oliverschmidt Exp $ + */ + +#include "contiki-net.h" +#include "wpcap.h" +#include "net/uip-neighbor.h" + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +static u8_t output(void); + +SERVICE(wpcap_service, packet_service, { output }); + +PROCESS(wpcap_process, "WinPcap driver"); + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + uip_arp_out(); + wpcap_send(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ + process_poll(&wpcap_process); + uip_len = wpcap_poll(); + + if(uip_len > 0) { +#if UIP_CONF_IPV6 + if(BUF->type == htons(UIP_ETHTYPE_IPV6)) { + uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src); + tcpip_input(); + } else +#endif /* UIP_CONF_IPV6 */ + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + tcpip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + wpcap_send(); + } + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(wpcap_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + wpcap_init(); + + SERVICE_REGISTER(wpcap_service); + + process_poll(&wpcap_process); + + while(1) { + PROCESS_YIELD(); + if(ev == PROCESS_EVENT_POLL) { + pollhandler(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-net/net/wpcap-service.h b/platform/minimal-net/net/wpcap-service.h new file mode 100644 index 000000000..e4afeeee4 --- /dev/null +++ b/platform/minimal-net/net/wpcap-service.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt + * + * $Id: wpcap-service.h,v 1.1 2007/03/26 02:53:55 oliverschmidt Exp $ + */ + +#ifndef __WPCAP_SERVICE_H__ +#define __WPCAP_SERVICE_H__ + +#include "contiki.h" + +PROCESS_NAME(wpcap_process); + +#endif /* __WPCAP_SERVICE_H__ */ diff --git a/platform/minimal-net/net/wpcap.c b/platform/minimal-net/net/wpcap.c new file mode 100644 index 000000000..4d900f636 --- /dev/null +++ b/platform/minimal-net/net/wpcap.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt + * + * $Id: wpcap.c,v 1.1 2007/03/26 02:53:55 oliverschmidt Exp $ + */ + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0501 +#include +#include +#include + +#include +#include + +#define htons /* Avoid 'conflicting types' error. */ +#include "contiki-net.h" +#include "wpcap.h" + +extern char **__argv[]; + +struct pcap; + +struct pcap_if { + struct pcap_if *next; + char *name; + char *description; + struct pcap_addr { + struct pcap_addr *next; + struct sockaddr *addr; + struct sockaddr *netmask; + struct sockaddr *broadaddr; + struct sockaddr *dstaddr; + } *addresses; + uint32_t flags; +}; + +struct pcap_pkthdr { + struct timeval ts; + uint32_t caplen; + uint32_t len; +}; + +static struct pcap *pcap; + +static int (* pcap_findalldevs)(struct pcap_if **, char *); +static struct pcap *(* pcap_open_live)(char *, int, int, int, char *); +static int (* pcap_next_ex)(struct pcap *, struct pcap_pkthdr **, unsigned char **); +static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int); + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +/*---------------------------------------------------------------------------*/ +static void +error_exit(char *message) +{ + printf("error_exit: %s", message); + exit(EXIT_FAILURE); +} +/*---------------------------------------------------------------------------*/ +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) { + printf("init_pcap: 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; + printf("init_pcap: 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); + printf("set_ethaddr: 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; + printf("set_ethaddr: 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"); + } + printf("set_ethaddr: 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"); + } +} +/*---------------------------------------------------------------------------*/ +void +wpcap_init(void) +{ + struct in_addr addr; + HMODULE wpcap; + + addr.s_addr = inet_addr((*__argv)[1]); + if(addr.s_addr == INADDR_NONE) { + error_exit("usage: \n"); + } + printf("wpcap_init: 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"); + (FARPROC)pcap_next_ex = GetProcAddress(wpcap, "pcap_next_ex"); + (FARPROC)pcap_sendpacket = GetProcAddress(wpcap, "pcap_sendpacket"); + + if(pcap_findalldevs == NULL || pcap_open_live == NULL || + pcap_next_ex == NULL || pcap_sendpacket == NULL) { + error_exit("error on access to winpcap library\n"); + } + + init_pcap(addr); + set_ethaddr(addr); +} +/*---------------------------------------------------------------------------*/ +u16_t +wpcap_poll(void) +{ + struct pcap_pkthdr *packet_header; + unsigned char *packet; + + switch(pcap_next_ex(pcap, &packet_header, &packet)) { + case -1: + error_exit("error on poll\n"); + case 0: + return 0; + } + + CopyMemory(uip_buf, packet, packet_header->caplen); + return (u16_t)packet_header->caplen; +} +/*---------------------------------------------------------------------------*/ +void +wpcap_send(void) +{ + if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) { + error_exit("error on send\n"); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-net/net/wpcap.h b/platform/minimal-net/net/wpcap.h new file mode 100644 index 000000000..c2a36c5df --- /dev/null +++ b/platform/minimal-net/net/wpcap.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Oliver Schmidt + * + * $Id: wpcap.h,v 1.1 2007/03/26 02:53:55 oliverschmidt Exp $ + */ + +#ifndef __WPCAP_H__ +#define __WPCAP_H__ + +void wpcap_init(void); +u16_t wpcap_poll(void); +void wpcap_send(void); + +#endif /* __WPCAP_H__ */