Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2001, 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 * 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 00016 * 3. Neither the name of the Institute nor the names of its contributors 00017 * may be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00024 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00025 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00026 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00027 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00028 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00029 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00030 * SUCH DAMAGE. 00031 * 00032 * Author: Adam Dunkels <adam@sics.se> 00033 * 00034 * $Id: tapdev6.c,v 1.4 2010/10/19 18:29:04 adamdunkels Exp $ 00035 */ 00036 00037 00038 #include <fcntl.h> 00039 #include <stdlib.h> 00040 #include <stdio.h> 00041 #include <unistd.h> 00042 #include <string.h> 00043 #include <sys/ioctl.h> 00044 #include <sys/socket.h> 00045 #include <sys/types.h> 00046 #include <sys/time.h> 00047 #include <sys/uio.h> 00048 #include <sys/socket.h> 00049 00050 00051 #ifdef linux 00052 #include <sys/ioctl.h> 00053 #include <linux/if.h> 00054 #include <linux/if_tun.h> 00055 #define DEVTAP "/dev/net/tun" 00056 #else /* linux */ 00057 #define DEVTAP "/dev/tap0" 00058 #endif /* linux */ 00059 00060 00061 #include "tapdev6.h" 00062 #include "contiki-net.h" 00063 00064 #define DROP 0 00065 00066 #if DROP 00067 static int drop = 0; 00068 #endif 00069 00070 static int fd; 00071 00072 static unsigned long lasttime; 00073 00074 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 00075 #define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00076 00077 #define DEBUG 0 00078 #if DEBUG 00079 #define PRINTF(...) printf(__VA_ARGS__) 00080 #define PRINT6ADDR(addr) PRINTF("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) 00081 #else 00082 #define PRINTF(...) 00083 #define PRINT6ADDR(addr) 00084 #endif 00085 00086 static void do_send(void); 00087 uint8_t tapdev_send(uip_lladdr_t *lladdr); 00088 00089 00090 uint16_t 00091 tapdev_poll(void) 00092 { 00093 fd_set fdset; 00094 struct timeval tv; 00095 int ret; 00096 00097 tv.tv_sec = 0; 00098 tv.tv_usec = 0; 00099 00100 FD_ZERO(&fdset); 00101 if(fd > 0) { 00102 FD_SET(fd, &fdset); 00103 } 00104 00105 ret = select(fd + 1, &fdset, NULL, NULL, &tv); 00106 00107 if(ret == 0) { 00108 return 0; 00109 } 00110 ret = read(fd, uip_buf, UIP_BUFSIZE); 00111 00112 PRINTF("tapdev6: read %d bytes (max %d)\n", ret, UIP_BUFSIZE); 00113 00114 if(ret == -1) { 00115 perror("tapdev_poll: read"); 00116 } 00117 return ret; 00118 } 00119 /*---------------------------------------------------------------------------*/ 00120 void 00121 tapdev_init(void) 00122 { 00123 char buf[1024]; 00124 00125 fd = open(DEVTAP, O_RDWR); 00126 if(fd == -1) { 00127 perror("tapdev: tapdev_init: open"); 00128 return; 00129 } 00130 00131 #ifdef linux 00132 { 00133 struct ifreq ifr; 00134 memset(&ifr, 0, sizeof(ifr)); 00135 ifr.ifr_flags = IFF_TAP|IFF_NO_PI; 00136 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { 00137 perror(buf); 00138 exit(1); 00139 } 00140 } 00141 #endif /* Linux */ 00142 00143 /* Linux (ubuntu) 00144 snprintf(buf, sizeof(buf), "ip link set tap0 up"); 00145 system(buf); 00146 PRINTF("%s\n", buf); 00147 snprintf(buf, sizeof(buf), "ip -6 address add fc00::231/7 dev tap0"); 00148 system(buf); 00149 PRINTF("%s\n", buf); 00150 snprintf(buf, sizeof(buf), "ip -6 route add fc00::0/7 dev tap0"); 00151 system(buf); 00152 PRINTF("%s\n", buf); 00153 */ 00154 /* freebsd */ 00155 snprintf(buf, sizeof(buf), "ifconfig tap0 up"); 00156 system(buf); 00157 printf("%s\n", buf); 00158 00159 /* */ 00160 lasttime = 0; 00161 00162 /* gdk_input_add(fd, GDK_INPUT_READ, 00163 read_callback, NULL);*/ 00164 00165 } 00166 /*---------------------------------------------------------------------------*/ 00167 static void 00168 do_send(void) 00169 { 00170 int ret; 00171 00172 if(fd <= 0) { 00173 return; 00174 } 00175 00176 00177 PRINTF("tapdev_send: sending %d bytes\n", uip_len); 00178 /* check_checksum(uip_buf, size);*/ 00179 #if DROP 00180 drop++; 00181 if(drop % 8 == 7) { 00182 PRINTF("Dropped an output packet!\n"); 00183 return; 00184 } 00185 #endif /* DROP */ 00186 00187 ret = write(fd, uip_buf, uip_len); 00188 00189 if(ret == -1) { 00190 perror("tap_dev: tapdev_send: writev"); 00191 exit(1); 00192 } 00193 } 00194 /*---------------------------------------------------------------------------*/ 00195 uint8_t tapdev_send(uip_lladdr_t *lladdr) 00196 { 00197 /* 00198 * If L3 dest is multicast, build L2 multicast address 00199 * as per RFC 2464 section 7 00200 * else fill with th eaddrsess in argument 00201 */ 00202 if(lladdr == NULL) { 00203 /* the dest must be multicast */ 00204 (&BUF->dest)->addr[0] = 0x33; 00205 (&BUF->dest)->addr[1] = 0x33; 00206 (&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12]; 00207 (&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13]; 00208 (&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14]; 00209 (&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15]; 00210 } else { 00211 memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN); 00212 } 00213 memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN); 00214 BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6); //math tmp 00215 00216 uip_len += sizeof(struct uip_eth_hdr); 00217 do_send(); 00218 return 0; 00219 } 00220 00221 /*---------------------------------------------------------------------------*/ 00222 void 00223 tapdev_do_send(void) 00224 { 00225 do_send(); 00226 } 00227 /*---------------------------------------------------------------------------*/ 00228 // math added function 00229 void 00230 tapdev_exit(void) 00231 { 00232 } 00233 /*---------------------------------------------------------------------------*/