Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 00033 #include "contiki-net.h" 00034 #include "net/uip-neighbor.h" 00035 #include "net/wpcap.h" 00036 00037 #include "net/wpcap-drv.h" 00038 #include <string.h> 00039 00040 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 00041 #define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00042 00043 /* It is not particularly easy to install tun interfaces in Windows/cygwin, so wpcap 00044 * is used instead. The ip4 or ip6 address of the interface to connect to is passed 00045 * on the command line that invokes the minimal-net and native executables. 00046 * 00047 * The minimal-net border router uses wpcap to connect to both primary 00048 * and fallback interfaces. It is passed two addresses, and the uip stack is compiled 00049 * with space for the ethernet headers on both interfaces. 00050 * 00051 * However the native border router uses wpcap to connect to a fallback interface only. 00052 * The primary interface is the serial connection to the slip radio, and the 00053 * uip stack is compiled without space for ethernet headers. 00054 * The following define adds or strips ethernet headers from the fallback interface. 00055 * Since it is at present used only with the native border router, it is also used 00056 * as a hack to bypass polling of the primary interface. 00057 * 00058 * SELECT_CALLBACK is defined in /examples/ipv6/native-border-router/project-conf.h 00059 */ 00060 #ifdef SELECT_CALLBACK 00061 #define FALLBACK_HAS_ETHERNET_HEADERS 1 00062 #endif 00063 00064 PROCESS(wpcap_process, "WinPcap driver"); 00065 00066 /*---------------------------------------------------------------------------*/ 00067 #if !UIP_CONF_IPV6 00068 uint8_t 00069 wpcap_output(void) 00070 { 00071 uip_arp_out(); 00072 wpcap_send(); 00073 00074 return 0; 00075 } 00076 #endif /* !UIP_CONF_IPV6 */ 00077 /*---------------------------------------------------------------------------*/ 00078 static void 00079 pollhandler(void) 00080 { 00081 #if !FALLBACK_HAS_ETHERNET_HEADERS //native br is fallback only 00082 process_poll(&wpcap_process); 00083 uip_len = wpcap_poll(); 00084 00085 if(uip_len > 0) { 00086 #if UIP_CONF_IPV6 00087 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { 00088 // printf("wpcap poll calls tcpip"); 00089 tcpip_input(); 00090 } else 00091 #endif /* UIP_CONF_IPV6 */ 00092 if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { 00093 uip_len -= sizeof(struct uip_eth_hdr); 00094 tcpip_input(); 00095 #if !UIP_CONF_IPV6 00096 } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { 00097 uip_arp_arpin(); //math 00098 /* If the above function invocation resulted in data that 00099 should be sent out on the network, the global variable 00100 uip_len is set to a value > 0. */ 00101 if(uip_len > 0) { 00102 wpcap_send(); 00103 } 00104 #endif /* !UIP_CONF_IPV6 */ 00105 } else { 00106 uip_len = 0; 00107 } 00108 } 00109 #endif 00110 #ifdef UIP_FALLBACK_INTERFACE 00111 00112 process_poll(&wpcap_process); 00113 uip_len = wfall_poll(); 00114 00115 if(uip_len > 0) { 00116 #if FALLBACK_HAS_ETHERNET_HEADERS 00117 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { 00118 //remove ethernet header and pass ipv6 packet to stack 00119 uip_len-=14; 00120 //{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(unsigned char*)(uip_buf+i));printf("\n");} 00121 // memcpy(uip_buf, uip_buf+14, uip_len); 00122 memcpy(&uip_buf[UIP_LLH_LEN], uip_buf+14, uip_len); //LLH_LEN is zero for native border router to slip radio 00123 // CopyMemory(uip_buf, uip_buf+14, uip_len); 00124 //{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");} 00125 tcpip_input(); 00126 } else 00127 goto bail; 00128 #elif UIP_CONF_IPV6 00129 if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) { 00130 tcpip_input(); 00131 } else 00132 goto bail; 00133 #endif /* UIP_CONF_IPV6 */ 00134 if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) { 00135 uip_len -= sizeof(struct uip_eth_hdr); 00136 tcpip_input(); 00137 #if !UIP_CONF_IPV6 00138 } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) { 00139 uip_arp_arpin(); //math 00140 /* If the above function invocation resulted in data that 00141 should be sent out on the network, the global variable 00142 uip_len is set to a value > 0. */ 00143 if(uip_len > 0) { 00144 wfall_send(); 00145 } 00146 #endif /* !UIP_CONF_IPV6 */ 00147 } else { 00148 bail: 00149 uip_len = 0; 00150 } 00151 } 00152 #endif 00153 00154 } 00155 /*---------------------------------------------------------------------------*/ 00156 PROCESS_THREAD(wpcap_process, ev, data) 00157 { 00158 PROCESS_POLLHANDLER(pollhandler()); 00159 00160 PROCESS_BEGIN(); 00161 00162 wpcap_init(); 00163 00164 #if !UIP_CONF_IPV6 00165 tcpip_set_outputfunc(wpcap_output); 00166 #else 00167 #if !FALLBACK_HAS_ETHERNET_HEADERS 00168 tcpip_set_outputfunc(wpcap_send); 00169 #endif 00170 #endif /* !UIP_CONF_IPV6 */ 00171 00172 process_poll(&wpcap_process); 00173 00174 PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT); 00175 00176 wpcap_exit(); 00177 00178 PROCESS_END(); 00179 } 00180 /*---------------------------------------------------------------------------*/