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 * Author: Oliver Schmidt <ol.sc@web.de> 00032 * 00033 */ 00034 00035 #define WIN32_LEAN_AND_MEAN 00036 #define _WIN32_WINNT 0x0501 00037 #include <windows.h> 00038 #include <winsock2.h> 00039 #include <iphlpapi.h> 00040 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 00044 #ifdef __CYGWIN__ 00045 #include <alloca.h> 00046 #else /* __CYGWIN__ */ 00047 #include <malloc.h> 00048 #endif /* __CYGWIN__ */ 00049 00050 #define DEBUG 0 00051 #if DEBUG 00052 #define PRINTF(...) printf(__VA_ARGS__) 00053 #else 00054 #define PRINTF(...) 00055 #endif 00056 00057 #include "contiki-net.h" 00058 #include "sys/log.h" 00059 00060 #include "net/wpcap.h" 00061 00062 /* Handle native-border-router case where the fallback has ethernet headers. 00063 * The command line args for native-border-router conflice with the passing 00064 * of the interface addresses to connect to, so both must be hard coded. 00065 * See comments in wpcap-drv.c 00066 */ 00067 #ifdef SELECT_CALLBACK 00068 #define FALLBACK_HAS_ETHERNET_HEADERS 1 00069 #endif 00070 00071 #if UIP_CONF_IPV6 00072 #include <ws2tcpip.h> 00073 struct in6_addr addr6; 00074 char addr6str[64]; 00075 /*---------------------------------------------------------------------------*/ 00076 uint8_t 00077 issame_ip6addr(struct in6_addr addr1, struct in6_addr addr2) 00078 { 00079 return ((addr1.s6_addr32[0]==addr2.s6_addr32[0]) && 00080 (addr1.s6_addr32[1]==addr2.s6_addr32[1]) && 00081 (addr1.s6_addr32[2]==addr2.s6_addr32[2]) && 00082 (addr1.s6_addr32[3]==addr2.s6_addr32[3]) ); 00083 } 00084 /*---------------------------------------------------------------------------*/ 00085 uint8_t 00086 iszero_ip6addr(struct in6_addr addr) 00087 { 00088 return ((addr.s6_addr32[0]==0) && 00089 (addr.s6_addr32[1]==0) && 00090 (addr.s6_addr32[2]==0) && 00091 (addr.s6_addr32[3]==0) ); 00092 } 00093 /*---------------------------------------------------------------------------*/ 00094 uint8_t 00095 sprint_ip6addr(struct in6_addr addr, char * result) 00096 { 00097 unsigned char i = 0; 00098 unsigned char zerocnt = 0; 00099 unsigned char numprinted = 0; 00100 char * starting = result; 00101 00102 *result++='['; 00103 while (numprinted < 8) { 00104 if ((addr.s6_addr16[i] == 0) && (zerocnt == 0)) { 00105 while(addr.s6_addr16[zerocnt + i] == 0) zerocnt++; 00106 if (zerocnt == 1) { 00107 *result++ = '0'; 00108 numprinted++; 00109 break; 00110 } 00111 i += zerocnt; 00112 numprinted += zerocnt; 00113 } else { 00114 result += sprintf(result, "%x", (unsigned int) uip_ntohs(addr.s6_addr16[i])); 00115 i++; 00116 numprinted++; 00117 } 00118 if (numprinted != 8) *result++ = ':'; 00119 } 00120 *result++=']'; 00121 *result=0; 00122 return (result - starting); 00123 } 00124 00125 #endif /* UIP_CONF_IPV6 */ 00126 00127 00128 #ifdef __CYGWIN__ 00129 __attribute__((dllimport)) extern char **__argv[]; 00130 #endif /* __CYGWIN__ */ 00131 00132 struct pcap; 00133 00134 struct pcap_if { 00135 struct pcap_if *next; 00136 char *name; 00137 char *description; 00138 struct pcap_addr { 00139 struct pcap_addr *next; 00140 struct sockaddr *addr; 00141 struct sockaddr *netmask; 00142 struct sockaddr *broadaddr; 00143 struct sockaddr *dstaddr; 00144 } *addresses; 00145 DWORD flags; 00146 }; 00147 00148 struct pcap_pkthdr { 00149 struct timeval ts; 00150 DWORD caplen; 00151 DWORD len; 00152 }; 00153 00154 HMODULE wpcap; 00155 00156 static struct pcap *pcap; 00157 00158 /* uip_ethaddr is defined in uip.c. It is not used in uip6.c. 00159 * If needed for some purpose it can be defined here 00160 */ 00161 #if UIP_CONF_IPV6 00162 //struct uip_eth_addr uip_ethaddr; 00163 #endif 00164 00165 static int (* pcap_findalldevs)(struct pcap_if **, char *); 00166 static struct pcap *(* pcap_open_live)(char *, int, int, int, char *); 00167 static int (* pcap_next_ex)(struct pcap *, struct pcap_pkthdr **, unsigned char **); 00168 static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int); 00169 00170 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 00171 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 00172 #define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00173 00174 #ifdef UIP_FALLBACK_INTERFACE 00175 static struct pcap *pfall; 00176 struct in_addr addrfall; 00177 #if UIP_CONF_IPV6 00178 struct in_addr6 addrfall6; 00179 #endif 00180 00181 /*---------------------------------------------------------------------------*/ 00182 static void 00183 init(void) 00184 { 00185 /* Nothing to do here */ 00186 } 00187 /*---------------------------------------------------------------------------*/ 00188 uint8_t wfall_send(uip_lladdr_t *lladdr); 00189 #if FALLBACK_HAS_ETHERNET_HEADERS 00190 #undef IPBUF 00191 #define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[14]) 00192 static uip_ipaddr_t last_sender; 00193 #endif 00194 00195 static void 00196 output(void) 00197 { 00198 #if FALLBACK_HAS_ETHERNET_HEADERS&&0 00199 if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { 00200 /* Do not bounce packets back to fallback if the packet was received from it */ 00201 PRINTF("FUT: trapping pingpong"); 00202 return; 00203 } 00204 uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); 00205 #endif 00206 PRINTF("FUT: %u\n", uip_len); 00207 wfall_send(0); 00208 } 00209 00210 const struct uip_fallback_interface rpl_interface = { 00211 init, output 00212 }; 00213 00214 #endif 00215 00216 /*---------------------------------------------------------------------------*/ 00217 static void 00218 error_exit(char *message) 00219 { 00220 printf("error_exit: %s", message); 00221 exit(EXIT_FAILURE); 00222 } 00223 /*---------------------------------------------------------------------------*/ 00224 static void 00225 set_ethaddr(struct in_addr addr) 00226 { 00227 PIP_ADAPTER_ADDRESSES adapters; 00228 ULONG size = 0; 00229 00230 if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | 00231 GAA_FLAG_SKIP_MULTICAST | 00232 GAA_FLAG_SKIP_DNS_SERVER, 00233 NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) { 00234 error_exit("error on access to adapter list size\n"); 00235 } 00236 adapters = alloca(size); 00237 if(GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | 00238 GAA_FLAG_SKIP_MULTICAST | 00239 GAA_FLAG_SKIP_DNS_SERVER, 00240 NULL, adapters, &size) != ERROR_SUCCESS) { 00241 error_exit("error on access to adapter list\n"); 00242 } 00243 00244 while(adapters != NULL) { 00245 00246 char buffer[256]; 00247 WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1, 00248 buffer, sizeof(buffer), NULL, NULL); 00249 log_message("set_ethaddr: found adapter: ", buffer); 00250 00251 if(adapters->FirstUnicastAddress != NULL && 00252 adapters->FirstUnicastAddress->Address.lpSockaddr != NULL && 00253 adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET) { 00254 00255 struct in_addr adapter_addr; 00256 adapter_addr = ((struct sockaddr_in *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin_addr; 00257 log_message("set_ethaddr: with address: ", inet_ntoa(adapter_addr)); 00258 00259 if(adapter_addr.s_addr == addr.s_addr) { 00260 if(adapters->PhysicalAddressLength != 6) { 00261 error_exit("ip addr specified on cmdline does not belong to an ethernet card\n"); 00262 } 00263 wsprintf(buffer, "%02X-%02X-%02X-%02X-%02X-%02X", 00264 adapters->PhysicalAddress[0], adapters->PhysicalAddress[1], 00265 adapters->PhysicalAddress[2], adapters->PhysicalAddress[3], 00266 adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]); 00267 log_message("set_ethaddr: ethernetaddr: ", buffer); 00268 #if UIP_CONF_IPV6 00269 // int i;for (i=0;i<6;i++) uip_ethaddr.addr[i] = adapters->PhysicalAddress[i]; 00270 #else 00271 uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress)); 00272 #endif 00273 break; 00274 } 00275 } 00276 adapters = adapters->Next; 00277 } 00278 00279 if(adapters == NULL) { 00280 error_exit("no adapter found with ip addr specified on cmdline\n"); 00281 } 00282 } 00283 00284 #if UIP_CONF_IPV6 00285 /*---------------------------------------------------------------------------*/ 00286 static void 00287 set_ethaddr6(struct in_addr6 addr) 00288 { 00289 PIP_ADAPTER_ADDRESSES adapters; 00290 ULONG size = 0; 00291 00292 if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_ANYCAST | 00293 GAA_FLAG_SKIP_MULTICAST | 00294 GAA_FLAG_SKIP_DNS_SERVER, 00295 NULL, NULL, &size) != ERROR_BUFFER_OVERFLOW) { 00296 error_exit("error on access to adapter list size\n"); 00297 } 00298 adapters = alloca(size); 00299 if(GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_ANYCAST | 00300 GAA_FLAG_SKIP_MULTICAST | 00301 GAA_FLAG_SKIP_DNS_SERVER, 00302 NULL, adapters, &size) != ERROR_SUCCESS) { 00303 error_exit("error on access to adapter list\n"); 00304 } 00305 00306 while(adapters != NULL) { 00307 00308 char buffer[256]; 00309 WideCharToMultiByte(CP_ACP, 0, adapters->Description, -1, 00310 buffer, sizeof(buffer), NULL, NULL); 00311 log_message("set_ethaddr: found adapter: ", buffer); 00312 00313 if(adapters->FirstUnicastAddress != NULL && 00314 adapters->FirstUnicastAddress->Address.lpSockaddr != NULL && 00315 adapters->FirstUnicastAddress->Address.lpSockaddr->sa_family == AF_INET6) { 00316 00317 struct in_addr6 adapter_addr; 00318 adapter_addr = ((struct sockaddr_in6 *)adapters->FirstUnicastAddress->Address.lpSockaddr)->sin6_addr; 00319 sprint_ip6addr(adapter_addr, addr6str); 00320 log_message("set_ethaddr: with ipv6 address: : ", addr6str); 00321 if(issame_ip6addr(adapter_addr,addr6)) { 00322 if(adapters->PhysicalAddressLength != 6) { 00323 error_exit("ip addr specified on cmdline does not belong to an ethernet card\n"); 00324 } 00325 wsprintf(buffer, "%02X-%02X-%02X-%02X-%02X-%02X", 00326 adapters->PhysicalAddress[0], adapters->PhysicalAddress[1], 00327 adapters->PhysicalAddress[2], adapters->PhysicalAddress[3], 00328 adapters->PhysicalAddress[4], adapters->PhysicalAddress[5]); 00329 log_message("set_ethaddr: ethernetaddr: ", buffer); 00330 #if UIP_CONF_IPV6 00331 // int i;for (i=0;i<6;i++) uip_ethaddr.addr[i] = adapters->PhysicalAddress[i]; //does this need doing? 00332 #else 00333 uip_setethaddr((*(struct uip_eth_addr *)adapters->PhysicalAddress)); 00334 #endif 00335 break; 00336 } 00337 } 00338 adapters = adapters->Next; 00339 } 00340 00341 if(adapters == NULL) { 00342 error_exit("no adapter found with ip addr specified on cmdline\n"); 00343 } 00344 } 00345 #endif 00346 /*---------------------------------------------------------------------------*/ 00347 static void 00348 init_pcap(struct in_addr addr) 00349 { 00350 struct pcap_if *interfaces; 00351 struct pcap_addr *paddr; 00352 char error[256]; 00353 00354 if(pcap_findalldevs(&interfaces, error) == -1) { 00355 error_exit(error); 00356 } 00357 00358 while(interfaces != NULL) { 00359 log_message("init_pcap: found interface: ", interfaces->description); 00360 00361 if(interfaces->addresses != NULL) { 00362 for(paddr = interfaces->addresses; 00363 paddr != NULL; 00364 paddr = paddr->next) { 00365 if(paddr->addr != NULL && paddr->addr->sa_family == AF_INET) { 00366 struct in_addr interface_addr; 00367 interface_addr = ((struct sockaddr_in *)paddr->addr)->sin_addr; 00368 log_message("init_pcap: with address: ", inet_ntoa(interface_addr)); 00369 00370 if(interface_addr.s_addr == addr.s_addr) { 00371 pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error); 00372 if(pcap == NULL) { 00373 error_exit(error); 00374 } 00375 #ifdef UIP_FALLBACK_INTERFACE 00376 log_message("init_pcap: Opened as primary interface",""); 00377 #else 00378 log_message("init_pcap: Opened as interface",""); 00379 #endif 00380 // pcap_setdirection(PCAP_D_IN); //Not implemented in windows yet? 00381 set_ethaddr(addr); 00382 00383 #ifdef UIP_FALLBACK_INTERFACE 00384 } 00385 if (pfall && pcap) return; 00386 if(interface_addr.s_addr == addrfall.s_addr) { 00387 pfall = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error); 00388 if(pfall == NULL) { 00389 error_exit(error); 00390 } 00391 log_message("init_pcap: Opened as fallback interface",""); 00392 if (pcap) return; 00393 } 00394 #else 00395 return; 00396 } 00397 #endif 00398 00399 #if UIP_CONF_IPV6 00400 00401 } else if(paddr->addr != NULL && paddr->addr->sa_family == AF_INET6) { 00402 struct in6_addr interface_addr; 00403 interface_addr = ((struct sockaddr_in6 *)paddr->addr)->sin6_addr; 00404 00405 sprint_ip6addr(interface_addr, addr6str); 00406 log_message("init_pcap: with ipv6 address: ", addr6str); 00407 00408 if (issame_ip6addr(interface_addr, addr6)) { 00409 pcap = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error); 00410 if(pcap == NULL) { 00411 error_exit(error); 00412 } 00413 #ifdef UIP_FALLBACK_INTERFACE 00414 log_message("init_pcap: Opened as primary interface",""); 00415 #endif 00416 set_ethaddr6(addr6); 00417 // pcap_setdirection(PCAP_D_IN); //Not implemented in windows yet? 00418 #ifdef UIP_FALLBACK_INTERFACE 00419 } 00420 if (pfall && pcap) return; //exit when we have both interfaces 00421 00422 if (issame_ip6addr(interface_addr, addrfall6)) { 00423 pfall = pcap_open_live(interfaces->name, UIP_BUFSIZE, 0, -1, error); 00424 if(pfall == NULL) { 00425 error_exit(error); 00426 } 00427 log_message("init_pcap: Opened as fallback interface",""); 00428 if (pcap) return; 00429 } 00430 #else 00431 return; 00432 } 00433 #endif 00434 #endif /* UIP_CONF_IPV6 */ 00435 } 00436 } 00437 } 00438 interfaces = interfaces->next; 00439 00440 } 00441 00442 if(interfaces == NULL) { 00443 error_exit("no interface found with specified ip address\n"); 00444 } 00445 } 00446 /*---------------------------------------------------------------------------*/ 00447 void 00448 wpcap_init(void) 00449 { 00450 struct in_addr addr; 00451 addr.s_addr = INADDR_NONE; //255.255.255.255 00452 #ifdef UIP_FALLBACK_INTERFACE 00453 addrfall.s_addr = INADDR_NONE; 00454 #endif 00455 00456 /* Pick up possible ip addresses from command line */ 00457 #ifdef __CYGWIN__ 00458 if ((*__argv)[1]) { 00459 addr.s_addr = inet_addr((*__argv)[1]); 00460 #if UIP_CONF_IPV6 00461 uiplib_ipaddrconv((*__argv)[1],(uip_ipaddr_t*) &addr6.s6_addr); 00462 #endif 00463 #ifdef UIP_FALLBACK_INTERFACE 00464 if ((*__argv)[2]) { 00465 addrfall.s_addr = inet_addr((*__argv)[2]); 00466 #if UIP_CONF_IPV6 00467 uiplib_ipaddrconv((*__argv)[2],(uip_ipaddr_t*) &addrfall6.s6_addr); 00468 #endif 00469 } 00470 #endif 00471 } 00472 00473 #else /* __CYGWIN__ */ 00474 /* VC++ build on win32 platform. Currently the platform has no ipv6 support */ 00475 addr.s_addr = inet_addr(__argv[1]); 00476 #if UIP_CONF_IPV6 00477 if((__argv)[1]) 00478 uiplib_ipaddrconv((__argv)[1],(uip_ipaddr_t*) &addr6.s6_addr); 00479 #endif 00480 #ifdef UIP_FALLBACK_INTERFACE 00481 addrfall.s_addr = inet_addr(__argv[2]); 00482 #if UIP_CONF_IPV6 00483 if((__argv)[2]) 00484 uiplib_ipaddrconv((__argv)[2],(uip_ipaddr_t*) &addrfall6.s6_addr); 00485 #endif 00486 #endif 00487 #endif /* __CYGWIN__ */ 00488 00489 #if DEBUG 00490 log_message("wpcap_init:Passed ipv4 ", inet_ntoa(addr)); 00491 sprint_ip6addr(addr6, addr6str); 00492 log_message("wpcap_init:Passed ipv6 ", addr6str); 00493 #ifdef UIP_FALLBACK_INTERFACE 00494 log_message("wpcap_init:Passed fallback ipv4 ", inet_ntoa(addrfall)); 00495 sprint_ip6addr(addrfall6, addr6str); 00496 log_message("wpcap_init:Passed fallback ipv6 ", addr6str); 00497 #endif 00498 #endif 00499 00500 /* Use build defaults if not enough addresses passed */ 00501 #if UIP_CONF_IPV6 00502 00503 #ifdef UIP_FALLBACK_INTERFACE 00504 if(addrfall.s_addr == INADDR_NONE) { 00505 if(iszero_ip6addr(addrfall6)) { 00506 #ifdef WPCAP_FALLBACK_ADDRESS 00507 addrfall.s_addr = inet_addr(WPCAP_FALLBACK_ADDRESS); 00508 // if(addrfall.s_addr == INADDR_NONE) { //use ipv6 if contiki-conf.h override 00509 uiplib_ipaddrconv(WPCAP_FALLBACK_ADDRESS,(uip_ipaddr_t*) &addrfall6.s6_addr); 00510 // } 00511 #else 00512 // addrfall.s_addr = inet_addr("10.2.10.10"); 00513 uiplib_ipaddrconv("bbbb::1",(uip_ipaddr_t*) &addrfall6.s6_addr); 00514 #endif 00515 } 00516 } 00517 #endif 00518 00519 if(addr.s_addr == INADDR_NONE) { 00520 if(iszero_ip6addr(addr6)) { 00521 #ifdef WPCAP_INTERFACE_ADDRESS 00522 addr.s_addr = inet_addr(WPCAP_INTERFACE_ADDRESS); 00523 // if(addr.s_addr == INADDR_NONE) { 00524 uiplib_ipaddrconv(WPCAP_INTERFACE_ADDRESS,(uip_ipaddr_t*) &addr6.s6_addr); 00525 // } 00526 #else 00527 addr.s_addr = inet_addr("10.10.10.10"); //prefer ipv4 default for legacy compatibility 00528 // uiplib_ipaddrconv("aaaa::1",(uip_ipaddr_t*) &addr6.s6_addr); 00529 #endif 00530 00531 #ifdef UIP_FALLBACK_INTERFACE 00532 log_message("usage: <program> <ip addr of interface> <ip addr of fallback>\n",""); 00533 if(addr.s_addr != INADDR_NONE) { 00534 log_message("-->I'll try interface address ", inet_ntoa(addr)); 00535 } else { 00536 sprint_ip6addr(addr6, addr6str); 00537 log_message("-->I'll try interface address ", addr6str); 00538 } 00539 if(addrfall.s_addr != INADDR_NONE) { 00540 log_message("--> and fallback address ", inet_ntoa(addrfall)); 00541 } else { 00542 sprint_ip6addr(addrfall6, addr6str); 00543 log_message("--> and fallback address ", addr6str); 00544 } 00545 #else 00546 if(addr.s_addr != INADDR_NONE) { 00547 log_message("usage: <program> <ip addr of ethernet card to share>\n-->I'll try guessing ", inet_ntoa(addr)); 00548 } else { 00549 sprint_ip6addr(addr6, addr6str); 00550 log_message("usage: <program> <ip addr of ethernet card to share>\n-->I'll try guessing ", addr6str); 00551 } 00552 #endif 00553 } 00554 } 00555 #else /* ip4 build */ 00556 if(addr.s_addr == INADDR_NONE) { 00557 #ifdef WPCAP_INTERFACE_ADDRESS 00558 addr.s_addr = inet_addr(WPCAP_INTERFACE_ADDRESS); 00559 #else 00560 addr.s_addr = inet_addr("10.10.10.10"); 00561 #endif 00562 log_message("usage: <program> <ip addr of ethernet card to share>\n-->I'll try guessing ", inet_ntoa(addr)); 00563 } 00564 #endif /* UIP_CONF_IPV6 */ 00565 00566 #if DEBUG 00567 log_message("wpcap_init:Using ipv4 ", inet_ntoa(addr)); 00568 sprint_ip6addr(addr6, addr6str); 00569 log_message("wpcap_init:Using ipv6 ", addr6str); 00570 #ifdef UIP_FALLBACK_INTERFACE 00571 log_message("wpcap_init:Using fallback ipv4 ", inet_ntoa(addrfall)); 00572 sprint_ip6addr(addrfall6, addr6str); 00573 log_message("wpcap_init:Using fallback ipv6 ", addr6str); 00574 #endif 00575 #endif 00576 00577 // log_message("wpcap_init:cmdline address: ", inet_ntoa(addr)); 00578 00579 00580 wpcap = LoadLibrary("wpcap.dll"); 00581 pcap_findalldevs = (int (*)(struct pcap_if **, char *)) 00582 GetProcAddress(wpcap, "pcap_findalldevs"); 00583 pcap_open_live = (struct pcap *(*)(char *, int, int, int, char *)) 00584 GetProcAddress(wpcap, "pcap_open_live"); 00585 pcap_next_ex = (int (*)(struct pcap *, struct pcap_pkthdr **, unsigned char **)) 00586 GetProcAddress(wpcap, "pcap_next_ex"); 00587 pcap_sendpacket = (int (*)(struct pcap *, unsigned char *, int)) 00588 GetProcAddress(wpcap, "pcap_sendpacket"); 00589 00590 if(pcap_findalldevs == NULL || pcap_open_live == NULL || 00591 pcap_next_ex == NULL || pcap_sendpacket == NULL) { 00592 error_exit("error on access to winpcap library\n"); 00593 } 00594 00595 init_pcap(addr); 00596 00597 } 00598 00599 /*---------------------------------------------------------------------------*/ 00600 uint16_t 00601 wpcap_poll(void) 00602 { 00603 struct pcap_pkthdr *packet_header; 00604 unsigned char *packet; 00605 00606 switch(pcap_next_ex(pcap, &packet_header, &packet)) { 00607 case -1: 00608 error_exit("error on poll\n"); 00609 case 0: 00610 return 0; 00611 } 00612 00613 #if UIP_CONF_IPV6 00614 /* Since pcap_setdirection(PCAP_D_IN) is not implemented in winpcap all outgoing packets 00615 * will be echoed back. The stack will ignore any packets not addressed to it, but initial 00616 * ipv6 neighbor solicitations are addressed to everyone and the echoed NS sent on startup 00617 * would be processed as a conflicting NS race which would cause a stack shutdown. 00618 * So discard all packets with our source address (packet starts destaddr, srcaddr, ...) 00619 * 00620 */ 00621 int i; 00622 for (i=0;i<UIP_LLADDR_LEN;i++) if (*(packet+UIP_LLADDR_LEN+i)!=uip_lladdr.addr[i]) break; 00623 if (i==UIP_LLADDR_LEN) { 00624 PRINTF("SIN: Discarding echoed packet\n"); 00625 return 0; 00626 } 00627 00628 /* To implement multihop, ignore packets to us from specified source macs 00629 */ 00630 // printf("ethtype=%x %x",*(packet+2*UIP_LLADDR_LEN),*(packet+2*UIP_LLADDR_LEN+1)); 00631 // printf("hopcount=%u",*(packet+21)); 00632 #if 0 00633 if (0 00634 // || (*(packet+11) ==0x1) //20 ignores router 00635 // || (*(packet+11) ==0x10) 00636 || (*(packet+11) ==0x20) //router ignores 20 00637 ) { 00638 printf("i%x",*(packet+11)); 00639 return 0; 00640 } 00641 /* If we are not the recipient, ignore packets from other RPL nodes */ 00642 if (0 00643 || (*(packet+5) !=0x1) //router 00644 // || (*(packet+11) ==0x10) 00645 // || (*(packet+11) ==0x20) //router ignores 20 00646 ) { 00647 printf("r%x",*(packet+11)); 00648 return 0; 00649 } 00650 #endif 00651 00652 #endif /* UIP_CONF_IPV6 */ 00653 00654 if(packet_header->caplen > UIP_BUFSIZE) { 00655 return 0; 00656 } 00657 // PRINTF("SIN: %lu\n", packet_header->caplen); 00658 CopyMemory(uip_buf, packet, packet_header->caplen); 00659 return (uint16_t)packet_header->caplen; 00660 00661 } 00662 00663 #ifdef UIP_FALLBACK_INTERFACE 00664 uint16_t 00665 wfall_poll(void) 00666 { 00667 struct pcap_pkthdr *packet_header; 00668 unsigned char *packet; 00669 00670 switch(pcap_next_ex(pfall, &packet_header, &packet)) { 00671 case -1: 00672 error_exit("error on fallback poll\n"); 00673 case 0: 00674 return 0; 00675 } 00676 #if UIP_CONF_IPV6 00677 #if FALLBACK_HAS_ETHERNET_HEADERS 00678 #define ETHERNET_LLADDR_LEN 6 00679 #else 00680 #define ETHERNET_LLADDR_LEN UIP_LLADDR_LEN 00681 #endif 00682 /* Since pcap_setdirection(PCAP_D_IN) is not implemented in winpcap all outgoing packets 00683 * will be echoed back. The stack will ignore any packets not addressed to it, but initial 00684 * ipv6 neighbor solicitations are addressed to everyone and the echoed NS sent on startup 00685 * would be processed as a conflicting NS race which would cause a stack shutdown. 00686 * So discard all packets with our source address (packet starts destaddr, srcaddr, ...) 00687 * 00688 */ 00689 int i; 00690 for (i=0;i<ETHERNET_LLADDR_LEN;i++) if (*(packet+ETHERNET_LLADDR_LEN+i)!=uip_lladdr.addr[i]) break; 00691 if (i==ETHERNET_LLADDR_LEN) { 00692 PRINTF("Discarding echoed packet\n"); 00693 return 0; 00694 } 00695 #endif /* UIP_CONF_IPV6 */ 00696 00697 if(packet_header->caplen > UIP_BUFSIZE) { 00698 return 0; 00699 } 00700 PRINTF("FIN: %lu\n", packet_header->caplen); 00701 CopyMemory(uip_buf, packet, packet_header->caplen); 00702 return (uint16_t)packet_header->caplen; 00703 00704 } 00705 00706 #endif 00707 00708 /*---------------------------------------------------------------------------*/ 00709 #if UIP_CONF_IPV6 00710 uint8_t 00711 wpcap_send(uip_lladdr_t *lladdr) 00712 { 00713 if(lladdr == NULL) { 00714 /* the dest must be multicast*/ 00715 (&BUF->dest)->addr[0] = 0x33; 00716 (&BUF->dest)->addr[1] = 0x33; 00717 (&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12]; 00718 (&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13]; 00719 (&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14]; 00720 (&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15]; 00721 } else { 00722 //when fallback used this gets ptr to lladdr of all zeroes on forwarded packets, turn them into multicast(?) 00723 if ((lladdr->addr[0]==0)&&(lladdr->addr[1]==0)&&(lladdr->addr[2]==0)&&(lladdr->addr[3]==0)&&(lladdr->addr[4]==0)&&(lladdr->addr[5]==0)) { 00724 (&BUF->dest)->addr[0] = 0x33; 00725 (&BUF->dest)->addr[1] = 0x33; 00726 (&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12]; 00727 (&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13]; 00728 (&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14]; 00729 (&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15]; 00730 } else { 00731 memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN); 00732 } 00733 } 00734 memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN); 00735 PRINTF("SUT: %u\n", uip_len); 00736 PRINTF("Src= %02x %02x %02x %02x %02x %02x",(&BUF->src)->addr[0],(&BUF->src)->addr[1],(&BUF->src)->addr[2],(&BUF->src)->addr[3],(&BUF->src)->addr[4],(&BUF->src)->addr[5]); 00737 PRINTF(" Dst= %02x %02x %02x %02x %02x %02x",(&BUF->dest)->addr[0],(&BUF->dest)->addr[1],(&BUF->dest)->addr[2],(&BUF->dest)->addr[3],(&BUF->dest)->addr[4],(&BUF->dest)->addr[5]); 00738 PRINTF(" Type=%04x\n",BUF->type); 00739 BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6); 00740 uip_len += sizeof(struct uip_eth_hdr); 00741 if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) { 00742 error_exit("error on send\n"); 00743 } 00744 return 0; 00745 } 00746 #ifdef UIP_FALLBACK_INTERFACE 00747 uint8_t 00748 wfall_send(uip_lladdr_t *lladdr) 00749 { 00750 #if FALLBACK_HAS_ETHERNET_HEADERS 00751 //make room for ethernet header 00752 //{int i;printf("\n");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");} 00753 {int i;for(i=uip_len;i>=0;--i) *(char *)(uip_buf+i+14) = *(char *)(uip_buf+i);} 00754 //{int i;printf("\n");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");} 00755 #endif 00756 if(lladdr == NULL) { 00757 /* the dest must be multicast*/ 00758 (&BUF->dest)->addr[0] = 0x33; 00759 (&BUF->dest)->addr[1] = 0x33; 00760 (&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12]; 00761 (&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13]; 00762 (&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14]; 00763 (&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15]; 00764 } else { 00765 memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN); 00766 } 00767 memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN); 00768 PRINTF("FUT: %u\n", uip_len); 00769 PRINTF("Srcf= %02x %02x %02x %02x %02x %02x",(&BUF->src)->addr[0],(&BUF->src)->addr[1],(&BUF->src)->addr[2],(&BUF->src)->addr[3],(&BUF->src)->addr[4],(&BUF->src)->addr[5]); 00770 PRINTF(" Dstf= %02x %02x %02x %02x %02x %02x",(&BUF->dest)->addr[0],(&BUF->dest)->addr[1],(&BUF->dest)->addr[2],(&BUF->dest)->addr[3],(&BUF->dest)->addr[4],(&BUF->dest)->addr[5]); 00771 PRINTF(" Typef=%04x\n",BUF->type); 00772 BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6); 00773 uip_len += sizeof(struct uip_eth_hdr); 00774 if(pcap_sendpacket(pfall, uip_buf, uip_len) == -1) { 00775 error_exit("error on fallback send\n"); 00776 } 00777 return 0; 00778 } 00779 #endif 00780 #else /* UIP_CONF_IPV6 */ 00781 void 00782 wpcap_send(void) 00783 { 00784 /* if(rand() % 1000 > 900) { 00785 printf("Drop\n"); 00786 return; 00787 } else { 00788 printf("Send\n"); 00789 }*/ 00790 00791 if(pcap_sendpacket(pcap, uip_buf, uip_len) == -1) { 00792 error_exit("error on send\n"); 00793 } 00794 } 00795 #endif /* UIP_CONF_IPV6 */ 00796 /*---------------------------------------------------------------------------*/ 00797 void 00798 wpcap_exit(void) 00799 { 00800 FreeLibrary(wpcap); 00801 } 00802 /*---------------------------------------------------------------------------*/