Add wpcap for cygwin/Windows native border router

This commit is contained in:
David Kopf 2012-01-08 13:37:56 -05:00
parent 777cc88872
commit b251619a2f
7 changed files with 139 additions and 21 deletions

View file

@ -36,10 +36,32 @@
#include "net/wpcap.h"
#include "net/wpcap-drv.h"
#include <string.h>
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/* It is not particularly easy to install tun interfaces in Windows/cygwin, so wpcap
* is used instead. The ip4 or ip6 address of the interface to connect to is passed
* on the command line that invokes the minimal-net and native executables.
*
* The minimal-net border router uses wpcap to connect to both primary
* and fallback interfaces. It is passed two addresses, and the uip stack is compiled
* with space for the ethernet headers on both interfaces.
*
* However the native border router uses wpcap to connect to a fallback interface only.
* The primary interface is the serial connection to the slip radio, and the
* uip stack is compiled without space for ethernet headers.
* The following define adds or strips ethernet headers from the fallback interface.
* Since it is at present used only with the native border router, it is also used
* as a hack to bypass polling of the primary interface.
*
* SELECT_CALLBACK is defined in /examples/ipv6/native-border-router/project-conf.h
*/
#ifdef SELECT_CALLBACK
#define FALLBACK_HAS_ETHERNET_HEADERS 1
#endif
PROCESS(wpcap_process, "WinPcap driver");
/*---------------------------------------------------------------------------*/
@ -57,12 +79,14 @@ wpcap_output(void)
static void
pollhandler(void)
{
#if !FALLBACK_HAS_ETHERNET_HEADERS //native br is fallback only
process_poll(&wpcap_process);
uip_len = wpcap_poll();
if(uip_len > 0) {
#if UIP_CONF_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
printf("wpcap poll calls tcpip");
tcpip_input();
} else
#endif /* UIP_CONF_IPV6 */
@ -83,14 +107,26 @@ pollhandler(void)
uip_len = 0;
}
}
#endif
#ifdef UIP_FALLBACK_INTERFACE
process_poll(&wpcap_process);
uip_len = wfall_poll();
if(uip_len > 0) {
#if UIP_CONF_IPV6
#if FALLBACK_HAS_ETHERNET_HEADERS
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
//remove ethernet header and pass ipv6 packet to stack
uip_len-=14;
//{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(unsigned char*)(uip_buf+i));printf("\n");}
// memcpy(uip_buf, uip_buf+14, uip_len);
memcpy(&uip_buf[UIP_LLH_LEN], uip_buf+14, uip_len); //LLH_LEN is zero for native border router to slip radio
// CopyMemory(uip_buf, uip_buf+14, uip_len);
//{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
tcpip_input();
} else
goto bail;
#elif UIP_CONF_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
tcpip_input();
} else
@ -129,7 +165,9 @@ PROCESS_THREAD(wpcap_process, ev, data)
#if !UIP_CONF_IPV6
tcpip_set_outputfunc(wpcap_output);
#else
#if !FALLBACK_HAS_ETHERNET_HEADERS
tcpip_set_outputfunc(wpcap_send);
#endif
#endif /* !UIP_CONF_IPV6 */
process_poll(&wpcap_process);

View file

@ -59,6 +59,15 @@
#include "net/wpcap.h"
/* Handle native-border-router case where the fallback has ethernet headers.
* The command line args for native-border-router conflice with the passing
* of the interface addresses to connect to, so both must be hard coded.
* See comments in wpcap-drv.c
*/
#ifdef SELECT_CALLBACK
#define FALLBACK_HAS_ETHERNET_HEADERS 1
#endif
#if UIP_CONF_IPV6
#include <ws2tcpip.h>
struct in6_addr addr6;
@ -173,19 +182,27 @@ init(void)
}
/*---------------------------------------------------------------------------*/
u8_t wfall_send(uip_lladdr_t *lladdr);
#if FALLBACK_HAS_ETHERNET_HEADERS
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[14])
static uip_ipaddr_t last_sender;
#else
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#endif
static void
output(void)
{
#if 0
#if FALLBACK_HAS_ETHERNET_HEADERS&&0
if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
/* Do not bounce packets back to fallback if the packet was received from it */
PRINTF("fallback: Destination off-link but no route src=");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF(" dst=");
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
PRINTF("\n");
} else {
PRINTF("FUT: trapping pingpong");
return;
}
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
#endif
PRINTF("FUT: %u\n", uip_len);
wfall_send(0);
@ -197,9 +214,6 @@ const struct uip_fallback_interface rpl_interface = {
#endif
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*---------------------------------------------------------------------------*/
static void
error_exit(char *message)
@ -488,7 +502,7 @@ wpcap_init(void)
#ifdef UIP_FALLBACK_INTERFACE
if(addrfall.s_addr == INADDR_NONE) {
if(iszero_ip6addr(addrfall6)) {
#ifdef WPCAP_WPCAP_FALLBACK_ADDRESS
#ifdef WPCAP_FALLBACK_ADDRESS
addrfall.s_addr = inet_addr(WPCAP_FALLBACK_ADDRESS);
// if(addrfall.s_addr == INADDR_NONE) { //use ipv6 if contiki-conf.h override
uiplib_ipaddrconv(WPCAP_FALLBACK_ADDRESS,(uip_ipaddr_t*) &addrfall6.s6_addr);
@ -659,6 +673,11 @@ wfall_poll(void)
return 0;
}
#if UIP_CONF_IPV6
#if FALLBACK_HAS_ETHERNET_HEADERS
#define ETHERNET_LLADDR_LEN 6
#else
#define ETHERNET_LLADDR_LEN UIP_LLADDR_LEN
#endif
/* Since pcap_setdirection(PCAP_D_IN) is not implemented in winpcap all outgoing packets
* will be echoed back. The stack will ignore any packets not addressed to it, but initial
* ipv6 neighbor solicitations are addressed to everyone and the echoed NS sent on startup
@ -667,8 +686,8 @@ wfall_poll(void)
*
*/
int i;
for (i=0;i<UIP_LLADDR_LEN;i++) if (*(packet+UIP_LLADDR_LEN+i)!=uip_lladdr.addr[i]) break;
if (i==UIP_LLADDR_LEN) {
for (i=0;i<ETHERNET_LLADDR_LEN;i++) if (*(packet+ETHERNET_LLADDR_LEN+i)!=uip_lladdr.addr[i]) break;
if (i==ETHERNET_LLADDR_LEN) {
PRINTF("Discarding echoed packet\n");
return 0;
}
@ -727,6 +746,12 @@ return 0;
u8_t
wfall_send(uip_lladdr_t *lladdr)
{
#if FALLBACK_HAS_ETHERNET_HEADERS
//make room for ethernet header
//{int i;printf("\n");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
{int i;for(i=uip_len;i>=0;--i) *(char *)(uip_buf+i+14) = *(char *)(uip_buf+i);}
//{int i;printf("\n");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
#endif
if(lladdr == NULL) {
/* the dest must be multicast*/
(&BUF->dest)->addr[0] = 0x33;

View file

@ -269,7 +269,11 @@ write_to_serial(int outfd, const uint8_t *inbuf, int len)
int i;
if(slip_config_verbose > 2) {
#ifdef __CYGWIN__
printf("Packet from WPCAP of length %d - write SLIP\n", len);
#else
printf("Packet from TUN of length %d - write SLIP\n", len);
#endif
if(slip_config_verbose > 4) {
#if WIRESHARK_IMPORT_FORMAT
printf("0000");

View file

@ -74,9 +74,6 @@ extern uint16_t slip_config_basedelay;
static int tunfd;
static int initialized = 0;
static uint16_t delaymsec=0;
static uint32_t delaystartsec,delaystartmsec;
int ssystem(const char *fmt, ...)
__attribute__((__format__ (__printf__, 1, 2)));
int
@ -175,6 +172,24 @@ tun_alloc(char *dev)
return devopen(dev, O_RDWR);
}
#endif
#ifdef __CYGWIN__
/*wpcap process is used to connect to host interface */
void
tun_init()
{
setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */
slip_init();
initialized = 1;
}
#else
static uint16_t delaymsec=0;
static uint32_t delaystartsec,delaystartmsec;
/*---------------------------------------------------------------------------*/
void
tun_init()
@ -235,6 +250,9 @@ output(void)
const struct uip_fallback_interface rpl_interface = {
init, output
};
#endif /* __CYGWIN_ */
/*---------------------------------------------------------------------------*/
/* tun and slip select callback */
/*---------------------------------------------------------------------------*/
@ -259,6 +277,10 @@ handle_fd(fd_set *rset, fd_set *wset)
if(!initialized) return;
slip_handle_fd(rset, wset);
#ifdef __CYGWIN__
/* Packets from host interface are handled by wpcap process */
#else
/* Optional delay between outgoing packets */
/* Base delay times number of 6lowpan fragments to be sent */
@ -290,6 +312,7 @@ handle_fd(fd_set *rset, fd_set *wset)
}
}
}
#endif /* __CYGWIN__ */
}
/*---------------------------------------------------------------------------*/

View file

@ -13,6 +13,19 @@ CONTIKI_TARGET_SOURCEFILES = contiki-main.c clock.c leds.c leds-arch.c \
button-sensor.c pir-sensor.c vib-sensor.c xmem.c \
sensors.c irq.c cfs-posix.c cfs-posix-dir.c
ifeq ($(OS),Windows_NT)
CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c
TARGET_LIBFILES = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a
else
CONTIKI_TARGET_SOURCEFILES += tapdev-drv.c
#math
ifndef UIP_CONF_IPV6
CONTIKI_TARGET_SOURCEFILES += tapdev.c
else
CONTIKI_TARGET_SOURCEFILES += tapdev6.c
endif
endif
CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)
.SUFFIXES:

View file

@ -35,8 +35,9 @@
#define __CONTIKI_CONF_H__
#include <inttypes.h>
#ifndef WIN32_LEAN_AND_MEAN
#include <sys/select.h>
#endif
struct select_callback {
int (* set_fd)(int maxfd, fd_set *fdr, fd_set *fdw);
void (* handle_fd)(fd_set *fdr, fd_set *fdw);

View file

@ -38,6 +38,10 @@
#include <unistd.h>
#include <sys/select.h>
#ifdef __CYGWIN__
#include "net/wpcap-drv.h"
#endif /* __CYGWIN__ */
#include "contiki.h"
#include "net/netstack.h"
@ -98,7 +102,15 @@ char **contiki_argv;
int
main(int argc, char **argv)
{
printf("Starting Contiki:\n", UIP_CONF_IPV6);
#if UIP_CONF_IPV6
#if UIP_CONF_IPV6_RPL
printf("Starting Contiki IPV6, RPL\n");
#else
printf("Starting Contiki IPV6\n");
#endif
#else
printf("Starting Contiki IPV4\n");
#endif
/* crappy way of remembering and accessing argc/v */
contiki_argc = argc;
@ -113,7 +125,9 @@ main(int argc, char **argv)
memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr));
process_start(&tcpip_process, NULL);
#ifdef __CYGWIN__
process_start(&wpcap_process, NULL);
#endif
printf("Tentative link-local IPv6 address ");
{
uip_ds6_addr_t *lladdr;