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