diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 54cde18c2b..8e2fc56de9 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -40,58 +40,66 @@ ifneq ($(HOSTOS),Cygwin) ifeq ($(CONFIG_SIM_X11FB),y) - USEX = y + USEX = y else - USEX = n + USEX = n endif else - USEX = n + USEX = n + CFLAGS += -DCYGWIN + HOSTCFLAGS += -DCYGWIN endif -CFLAGS += -I$(TOPDIR)/sched +CFLAGS += -I$(TOPDIR)/sched -ASRCS = up_setjmp.S -AOBJS = $(ASRCS:.S=$(OBJEXT)) -CSRCS = up_initialize.c up_idle.c up_interruptcontext.c \ +ASRCS = up_setjmp.S +AOBJS = $(ASRCS:.S=$(OBJEXT)) +CSRCS = up_initialize.c up_idle.c up_interruptcontext.c \ up_initialstate.c up_createstack.c up_usestack.c \ up_releasestack.c up_unblocktask.c up_blocktask.c \ up_releasepending.c up_reprioritizertr.c \ up_exit.c up_schedulesigaction.c up_allocateheap.c \ up_devconsole.c up_framebuffer.c -HOSTSRCS = up_stdio.c up_hostusleep.c +HOSTSRCS = up_stdio.c up_hostusleep.c ifeq ($(USEX),y) - HOSTSRCS += up_x11framebuffer.c + HOSTSRCS += up_x11framebuffer.c endif ifeq ($(CONFIG_FS_FAT),y) -CSRCS += up_blockdevice.c up_deviceimage.c +CSRCS += up_blockdevice.c up_deviceimage.c endif ifeq ($(CONFIG_NET),y) -CSRCS += up_uipdriver.c -HOSTSRCS += up_tapdev.c +CSRCS += up_uipdriver.c +HOSTCFLAGS += -DNETDEV_BUFSIZE=$(CONFIG_NET_BUFSIZE) +ifneq ($(HOSTOS),Cygwin) +HOSTSRCS += up_tapdev.c up_netdev.c +else +HOSTSRCS += up_wpcap.c up_netdev.c +DRVLIB = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a +endif endif -COBJS = $(CSRCS:.c=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) -NXOBJS = $(AOBJS) $(COBJS) -HOSTOBJS = $(HOSTSRCS:.c=$(OBJEXT)) +NXOBJS = $(AOBJS) $(COBJS) +HOSTOBJS = $(HOSTSRCS:.c=$(OBJEXT)) -SRCS = $(ASRCS) $(CSRCS) $(HOSTSRCS) -OBJS = $(AOBJS) $(COBJS) $(HOSTOBJS) +SRCS = $(ASRCS) $(CSRCS) $(HOSTSRCS) +OBJS = $(AOBJS) $(COBJS) $(HOSTOBJS) -LDFLAGS = $(ARCHSCRIPT) +LDFLAGS = $(ARCHSCRIPT) ifeq ($(USEX),y) - STDLIBS = -lX11 -lXext -lc + STDLIBS = -lX11 -lXext -lc else - STDLIBS = -lc + STDLIBS = -lc endif ifeq ($(CONFIG_FS_FAT),y) STDLIBS += -lz endif -LINKOBJS = up_head$(OBJEXT) -LINKLIBS = +LINKOBJS = up_head$(OBJEXT) +LINKLIBS = LDPATHS = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS))) -LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS)))) +LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS)))) all: up_head$(OBJEXT) libarch$(LIBEXT) .PHONY: clean distclean cleanrel depend @@ -134,7 +142,7 @@ nuttx.rel : libarch$(LIBEXT) $(HOSTOS)-names.dat $(LINKOBJS) nuttx$(EXEEXT): cleanrel nuttx.rel $(HOSTOBJS) @echo "LD: nuttx$(EXEEXT)" - @$(CC) $(LDFLAGS) $(LDPATHS) -o $(TOPDIR)/$@ nuttx.rel $(HOSTOBJS) $(STDLIBS) + @$(CC) $(LDFLAGS) $(LDPATHS) -o $(TOPDIR)/$@ nuttx.rel $(HOSTOBJS) $(DRVLIB) $(STDLIBS) @$(NM) $(TOPDIR)/$@ | \ grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ sort > $(TOPDIR)/System.map diff --git a/arch/sim/src/up_idle.c b/arch/sim/src/up_idle.c index 686be307a9..32efaa11b8 100644 --- a/arch/sim/src/up_idle.c +++ b/arch/sim/src/up_idle.c @@ -1,7 +1,7 @@ /**************************************************************************** * up_idle.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ void up_idle(void) /* Run the network if enabled */ -#if defined(CONFIG_NET) && defined(linux) +#ifdef CONFIG_NET uipdriver_loop(); #endif diff --git a/arch/sim/src/up_initialize.c b/arch/sim/src/up_initialize.c index eeea2abed4..257be8ab55 100644 --- a/arch/sim/src/up_initialize.c +++ b/arch/sim/src/up_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** * up_initialize.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -101,7 +101,7 @@ void up_initialize(void) #if defined(CONFIG_FS_FAT) && !defined(CONFIG_DISABLE_MOUNTPOINT) up_registerblockdevice(); /* Our FAT ramdisk at /dev/ram0 */ #endif -#if defined(CONFIG_NET) && defined(linux) +#ifdef CONFIG_NET uipdriver_init(); /* Our "real" netwok driver */ #endif } diff --git a/arch/sim/src/up_internal.h b/arch/sim/src/up_internal.h index 1b90c38091..e22422aeaa 100644 --- a/arch/sim/src/up_internal.h +++ b/arch/sim/src/up_internal.h @@ -113,20 +113,41 @@ extern char *up_deviceimage(void); extern size_t up_hostread(void *buffer, size_t len); extern size_t up_hostwrite(const void *buffer, size_t len); +/* up_netdev.c ************************************************************/ + +#ifdef CONFIG_NET +extern unsigned long up_getwalltime( void ); +#endif + /* up_tapdev.c ************************************************************/ -#ifdef CONFIG_NET -extern unsigned long up_getwalltime( void ); +#if defined(CONFIG_NET) && !defined(CYGWIN) extern void tapdev_init(void); -extern int tapdev_getmacaddr(unsigned char *macaddr); extern unsigned int tapdev_read(unsigned char *buf, unsigned int buflen); extern void tapdev_send(unsigned char *buf, unsigned int buflen); + +#define netdev_init() tapdev_init() +#define netdev_read(buf,buflen) tapdev_read(buf,buflen) +#define netdev_send(buf,buflen) tapdev_send(buf,buflen) +#endif + +/* up_wpcap.c *************************************************************/ + +#if defined(CONFIG_NET) && defined(CYGWIN) +extern void wpcap_init(void); +extern unsigned int wpcap_read(unsigned char *buf, unsigned int buflen); +extern void wpcap_send(unsigned char *buf, unsigned int buflen); + +#define netdev_init() wpcap_init() +#define netdev_read(buf,buflen) wpcap_read(buf,buflen) +#define netdev_send(buf,buflen) wpcap_send(buf,buflen) #endif /* up_uipdriver.c *********************************************************/ -#if defined(CONFIG_NET) && defined(linux) +#ifdef CONFIG_NET extern int uipdriver_init(void); +extern int uipdriver_setmacaddr(unsigned char *macaddr); extern void uipdriver_loop(void); #endif diff --git a/arch/sim/src/up_netdev.c b/arch/sim/src/up_netdev.c new file mode 100644 index 0000000000..742492971a --- /dev/null +++ b/arch/sim/src/up_netdev.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * up_tapdev.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 NuttX 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Private Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +unsigned long up_getwalltime( void ) +{ + struct timeval tm; + (void)gettimeofday(&tm, NULL); + return tm.tv_sec*1000 + tm.tv_usec/1000; +} diff --git a/arch/sim/src/up_tapdev.c b/arch/sim/src/up_tapdev.c index 2c9d5c6466..fd85a973e5 100644 --- a/arch/sim/src/up_tapdev.c +++ b/arch/sim/src/up_tapdev.c @@ -1,8 +1,7 @@ - /**************************************************************************** * up_tapdev.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Based on code from uIP which also has a BSD-like license: @@ -39,7 +38,7 @@ * ****************************************************************************/ -#ifdef linux +#ifndef CYGWIN /**************************************************************************** * Included Files @@ -63,6 +62,7 @@ #include extern int lib_rawprintf(const char *format, ...); +extern int uipdriver_setmacaddr(unsigned char *macaddr); /**************************************************************************** * Private Definitions @@ -133,17 +133,42 @@ static inline void dump_ethhdr(const char *msg, unsigned char *buf, int buflen) # define dump_ethhdr(m,b,l) #endif +static int up_setmacaddr(void) +{ + unsigned char macaddr[6]; + int ret = -1; + if (macaddr) + { + /* Get a socket (only so that we get access to the INET subsystem) */ + + int sockfd = socket(PF_INET, SOCK_DGRAM, 0); + if (sockfd >= 0) + { + struct ifreq req; + memset(&req, 0, sizeof(struct ifreq)); + + /* Put the driver name into the request */ + + strncpy(req.ifr_name, "tap0", IFNAMSIZ); + + /* Perform the ioctl to get the MAC address */ + + ret = ioctl(sockfd, SIOCGIFHWADDR, (unsigned long)&req); + if (!ret) + { + /* Set the MAC address */ + + ret = uipdriver_setmacaddr(&req.ifr_hwaddr.sa_data); + } + } + } + return ret; +} + /**************************************************************************** * Public Functions ****************************************************************************/ -unsigned long up_getwalltime( void ) -{ - struct timeval tm; - (void)gettimeofday(&tm, NULL); - return tm.tv_sec*1000 + tm.tv_usec/1000; -} - void tapdev_init(void) { struct ifreq ifr; @@ -175,37 +200,10 @@ void tapdev_init(void) snprintf(buf, sizeof(buf), "/sbin/ifconfig tap0 inet %d.%d.%d.%d\n", UIP_IPADDR0, UIP_IPADDR1, UIP_IPADDR2, UIP_IPADDR3); system(buf); -} -int tapdev_getmacaddr(unsigned char *macaddr) -{ - int ret = -1; - if (macaddr) - { - /* Get a socket (only so that we get access to the INET subsystem) */ + /* Set the MAC address */ - int sockfd = socket(PF_INET, SOCK_DGRAM, 0); - if (sockfd >= 0) - { - struct ifreq req; - memset (&req, 0, sizeof(struct ifreq)); - - /* Put the driver name into the request */ - - strncpy(req.ifr_name, "tap0", IFNAMSIZ); - - /* Perform the ioctl to get the MAC address */ - - ret = ioctl(sockfd, SIOCGIFHWADDR, (unsigned long)&req); - if (!ret) - { - /* Return the MAC address */ - - memcpy(macaddr, &req.ifr_hwaddr.sa_data, IFHWADDRLEN); - } - } - } - return ret; + up_setmacaddr(); } unsigned int tapdev_read(unsigned char *buf, unsigned int buflen) @@ -269,6 +267,6 @@ void tapdev_send(unsigned char *buf, unsigned int buflen) dump_ethhdr("write", buf, buflen); } -#endif /* linux */ +#endif /* !CYGWIN */ diff --git a/arch/sim/src/up_uipdriver.c b/arch/sim/src/up_uipdriver.c index 5258022e2e..e6dec219d7 100644 --- a/arch/sim/src/up_uipdriver.c +++ b/arch/sim/src/up_uipdriver.c @@ -1,7 +1,7 @@ /**************************************************************************** * up_uipdriver.c * - * Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009-2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Based on code from uIP which also has a BSD-like license: @@ -38,14 +38,14 @@ * ****************************************************************************/ -#ifdef linux - /**************************************************************************** * Included Files ****************************************************************************/ #include +#ifdef CONFIG_NET + #include #include #include @@ -124,7 +124,7 @@ static int sim_uiptxpoll(struct uip_driver_s *dev) if (g_sim_dev.d_len > 0) { uip_arp_out(&g_sim_dev); - tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } /* If zero is returned, the polling will continue until all connections have @@ -140,9 +140,9 @@ static int sim_uiptxpoll(struct uip_driver_s *dev) void uipdriver_loop(void) { - /* tapdev_read will return 0 on a timeout event and >0 on a data received event */ + /* netdev_read will return 0 on a timeout event and >0 on a data received event */ - g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, CONFIG_NET_BUFSIZE); + g_sim_dev.d_len = netdev_read((unsigned char*)g_sim_dev.d_buf, CONFIG_NET_BUFSIZE); /* Disable preemption through to the following so that it behaves a little more * like an interrupt (otherwise, the following logic gets pre-empted an behaves @@ -177,7 +177,7 @@ void uipdriver_loop(void) if (g_sim_dev.d_len > 0) { uip_arp_out(&g_sim_dev); - tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } else if (BUF->ether_type == htons(UIP_ETHTYPE_ARP)) @@ -191,7 +191,7 @@ void uipdriver_loop(void) if (g_sim_dev.d_len > 0) { - tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + netdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } } @@ -212,8 +212,7 @@ int uipdriver_init(void) /* Internal initalization */ timer_set(&g_periodic_timer, 500); - tapdev_init(); - (void)tapdev_getmacaddr(g_sim_dev.d_mac.ether_addr_octet); + netdev_init(); /* Register the device with the OS so that socket IOCTLs can be performed */ @@ -221,5 +220,11 @@ int uipdriver_init(void) return OK; } -#endif /* linux */ +int uipdriver_setmacaddr(unsigned char *macaddr) +{ + (void)memcpy(g_sim_dev.d_mac.ether_addr_octet, macaddr, IFHWADDRLEN); + return 0; +} + +#endif /* CONFIG_NET */ diff --git a/arch/sim/src/up_wpcap.c b/arch/sim/src/up_wpcap.c new file mode 100644 index 0000000000..9fd9e50647 --- /dev/null +++ b/arch/sim/src/up_wpcap.c @@ -0,0 +1,312 @@ +/**************************************************************************** + * up_wcap.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based on code from uIP which also has a BSD-like license: + * + * 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. + * + ****************************************************************************/ + +#ifdef CYGWIN + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0501 +#include +#include +#include + +#include +#include +#include + +extern int uipdriver_setmacaddr(unsigned char *macaddr); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +#ifndef CONFIG_EXAMPLE_UIP_DHCPC +# define UIP_IPADDR (10 << 24 | 0 << 16 | 0 << 8 | 1) +#else +# define UIP_IPADDR (0) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +__attribute__ ((dllimport)) 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; + DWORD flags; +}; + +struct pcap_pkthdr +{ + struct timeval ts; + DWORD caplen; + DWORD len; +}; + +/* DLL function types (for casting) */ + +typedef int (*pcap_findalldevs_t)(struct pcap_if **, char *); +typedef struct pcap *(*pcap_open_live_t)(char *, int, int, int, char *); +typedef int (*pcap_next_ex_t)(struct pcap *, struct pcap_pkthdr **, + unsigned char **); +typedef int (*pcap_sendpacket_t)(struct pcap *, unsigned char *, int); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +HMODULE wpcap; +static struct pcap *pcap; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static pcap_findalldevs_t pcap_findalldevs; +static pcap_open_live_t pcap_open_live; +static pcap_next_ex_t pcap_next_ex; +static pcap_sendpacket_t pcap_sendpacket; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +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 address\n"); + } + + pcap = pcap_open_live(interfaces->name, NETDEV_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 buffer[256]; + WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1, + buffer, sizeof(buffer), NULL, NULL); + printf("set_ethaddr: found adapter: %s\n", buffer); + + 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 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]); + + (void)uipdriver_setmacaddr(adapters->PhysicalAddress); + break; + } + } + adapters = adapters->Next; + } + + if (adapters == NULL) + { + error_exit("No adaptor found with IP address\n"); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void wpcap_init(void) +{ + struct in_addr addr; + FARPROC dlladdr; + + addr.s_addr = htonl(UIP_IPADDR); + printf("wpcap_init: IP address: %s\n", inet_ntoa(addr)); + + wpcap = LoadLibrary("wpcap.dll"); + dlladdr = GetProcAddress(wpcap, "pcap_findalldevs"); + pcap_findalldevs = (pcap_findalldevs_t)dlladdr; + + dlladdr = GetProcAddress(wpcap, "pcap_open_live"); + pcap_open_live = (pcap_open_live_t)dlladdr; + + dlladdr = GetProcAddress(wpcap, "pcap_next_ex"); + pcap_next_ex = (pcap_next_ex_t)dlladdr; + + dlladdr = GetProcAddress(wpcap, "pcap_sendpacket"); + pcap_sendpacket = (pcap_sendpacket_t)dlladdr; + + 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); +} + +unsigned int wpcap_read(unsigned char *buf, unsigned int buflen) +{ + struct pcap_pkthdr *packet_header; + unsigned char *packet; + + switch (pcap_next_ex(pcap, &packet_header, &packet)) + { + case -1: + error_exit("error on read\n"); + case 0: + return 0; + } + + if (packet_header->caplen > buflen) + { + return 0; + } + + memcpy(buf, packet, packet_header->caplen); + return packet_header->caplen; +} + +void wpcap_send(unsigned char *buf, unsigned int buflen) +{ + if (pcap_sendpacket(pcap, buf, buflen) == -1) + { + error_exit("error on send\n"); + } +} + +#endif /* CYGWIN */