tapdev6.c
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
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  
00057 #define DEVTAP "/dev/tap0"
00058 #endif 
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", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15])
00081 #else
00082 #define PRINTF(...)
00083 #define PRINT6ADDR(addr)
00084 #endif
00085 
00086 static void do_send(void);
00087 u8_t tapdev_send(uip_lladdr_t *lladdr);
00088 
00089 
00090 u16_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 
00142 
00143   
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154   
00155   snprintf(buf, sizeof(buf), "ifconfig tap0 up");
00156   system(buf);
00157   printf("%s\n", buf);
00158   
00159   
00160   lasttime = 0;
00161   
00162   
00163 
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   
00179 #if DROP
00180   drop++;
00181   if(drop % 8 == 7) {
00182     PRINTF("Dropped an output packet!\n");
00183     return;
00184   }
00185 #endif 
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 u8_t tapdev_send(uip_lladdr_t *lladdr)
00196 {
00197   
00198 
00199 
00200 
00201 
00202   if(lladdr == NULL) {
00203     
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); 
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 
00229 void
00230 tapdev_exit(void)
00231 {
00232 }
00233