tapdev.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 #include <fcntl.h>
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <unistd.h>
00041 #include <string.h>
00042 #include <sys/ioctl.h>
00043 #include <sys/socket.h>
00044 #include <sys/types.h>
00045 #include <sys/time.h>
00046 #include <sys/uio.h>
00047 #include <sys/socket.h>
00048
00049 #ifdef linux
00050 #include <sys/ioctl.h>
00051 #include <linux/if.h>
00052 #include <linux/if_tun.h>
00053 #define DEVTAP "/dev/net/tun"
00054 #else
00055 #define DEVTAP "/dev/tap0"
00056 #endif
00057
00058 #include "contiki-net.h"
00059 #include "tapdev.h"
00060
00061 #define DROP 0
00062
00063 #if DROP
00064 static int drop = 0;
00065 #endif
00066
00067 static int fd;
00068
00069 static unsigned long lasttime;
00070
00071 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
00072
00073
00074 static void
00075 remove_route(void)
00076 {
00077 char buf[1024];
00078 snprintf(buf, sizeof(buf), "route delete -net 172.16.0.0");
00079 system(buf);
00080 printf("%s\n", buf);
00081
00082 }
00083
00084 void
00085 tapdev_init(void)
00086 {
00087 char buf[1024];
00088
00089 fd = open(DEVTAP, O_RDWR);
00090 if(fd == -1) {
00091 perror("tapdev: tapdev_init: open");
00092 return;
00093 }
00094
00095 #ifdef linux
00096 {
00097 struct ifreq ifr;
00098 memset(&ifr, 0, sizeof(ifr));
00099 ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
00100 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
00101 perror(buf);
00102 exit(1);
00103 }
00104 }
00105 #endif
00106
00107 snprintf(buf, sizeof(buf), "ifconfig tap0 inet 192.168.1.1");
00108 system(buf);
00109 printf("%s\n", buf);
00110 #ifdef linux
00111
00112 snprintf(buf, sizeof(buf), "route add -net 172.16.0.0/16 gw 192.168.1.2");
00113 #else
00114
00115 snprintf(buf, sizeof(buf), "route add -net 172.16.0.0/16 192.168.1.2");
00116 #endif
00117
00118 system(buf);
00119 printf("%s\n", buf);
00120 atexit(remove_route);
00121
00122 lasttime = 0;
00123 }
00124
00125 u16_t
00126 tapdev_poll(void)
00127 {
00128 fd_set fdset;
00129 struct timeval tv;
00130 int ret;
00131
00132 tv.tv_sec = 0;
00133 tv.tv_usec = 0;
00134
00135 FD_ZERO(&fdset);
00136 if(fd > 0) {
00137 FD_SET(fd, &fdset);
00138 }
00139
00140 ret = select(fd + 1, &fdset, NULL, NULL, &tv);
00141
00142 if(ret == 0) {
00143 return 0;
00144 }
00145 ret = read(fd, uip_buf, UIP_BUFSIZE);
00146
00147 if(ret == -1) {
00148 perror("tapdev_poll: read");
00149 }
00150 return ret;
00151 }
00152
00153 void
00154 tapdev_send(void)
00155 {
00156 int ret;
00157
00158 if(fd <= 0) {
00159 return;
00160 }
00161
00162
00163
00164
00165 #if DROP
00166 drop++;
00167 if(drop % 8 == 7) {
00168 printf("Dropped an output packet!\n");
00169 return;
00170 }
00171 #endif
00172
00173 ret = write(fd, uip_buf, uip_len);
00174
00175 if(ret == -1) {
00176 perror("tap_dev: tapdev_send: writev");
00177 exit(1);
00178 }
00179 }
00180
00181 void
00182 tapdev_exit(void)
00183 {
00184 }
00185