Contiki 2.5
tapdev6.c
1 /*
2  * Copyright (c) 2001, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of the Institute nor the names of its contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * Author: Adam Dunkels <adam@sics.se>
33  *
34  * $Id: tapdev6.c,v 1.4 2010/10/19 18:29:04 adamdunkels Exp $
35  */
36 
37 
38 #include <fcntl.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <sys/ioctl.h>
44 #include <sys/socket.h>
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <sys/uio.h>
48 #include <sys/socket.h>
49 
50 
51 #ifdef linux
52 #include <sys/ioctl.h>
53 #include <linux/if.h>
54 #include <linux/if_tun.h>
55 #define DEVTAP "/dev/net/tun"
56 #else /* linux */
57 #define DEVTAP "/dev/tap0"
58 #endif /* linux */
59 
60 
61 #include "tapdev6.h"
62 #include "contiki-net.h"
63 
64 #define DROP 0
65 
66 #if DROP
67 static int drop = 0;
68 #endif
69 
70 static int fd;
71 
72 static unsigned long lasttime;
73 
74 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
75 #define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
76 
77 #define DEBUG 0
78 #if DEBUG
79 #define PRINTF(...) printf(__VA_ARGS__)
80 #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])
81 #else
82 #define PRINTF(...)
83 #define PRINT6ADDR(addr)
84 #endif
85 
86 static void do_send(void);
87 u8_t tapdev_send(uip_lladdr_t *lladdr);
88 
89 
90 u16_t
91 tapdev_poll(void)
92 {
93  fd_set fdset;
94  struct timeval tv;
95  int ret;
96 
97  tv.tv_sec = 0;
98  tv.tv_usec = 0;
99 
100  FD_ZERO(&fdset);
101  if(fd > 0) {
102  FD_SET(fd, &fdset);
103  }
104 
105  ret = select(fd + 1, &fdset, NULL, NULL, &tv);
106 
107  if(ret == 0) {
108  return 0;
109  }
110  ret = read(fd, uip_buf, UIP_BUFSIZE);
111 
112  PRINTF("tapdev6: read %d bytes (max %d)\n", ret, UIP_BUFSIZE);
113 
114  if(ret == -1) {
115  perror("tapdev_poll: read");
116  }
117  return ret;
118 }
119 /*---------------------------------------------------------------------------*/
120 void
121 tapdev_init(void)
122 {
123  char buf[1024];
124 
125  fd = open(DEVTAP, O_RDWR);
126  if(fd == -1) {
127  perror("tapdev: tapdev_init: open");
128  return;
129  }
130 
131 #ifdef linux
132  {
133  struct ifreq ifr;
134  memset(&ifr, 0, sizeof(ifr));
135  ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
136  if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
137  perror(buf);
138  exit(1);
139  }
140  }
141 #endif /* Linux */
142 
143  /* Linux (ubuntu)
144  snprintf(buf, sizeof(buf), "ip link set tap0 up");
145  system(buf);
146  PRINTF("%s\n", buf);
147  snprintf(buf, sizeof(buf), "ip -6 address add fc00::231/7 dev tap0");
148  system(buf);
149  PRINTF("%s\n", buf);
150  snprintf(buf, sizeof(buf), "ip -6 route add fc00::0/7 dev tap0");
151  system(buf);
152  PRINTF("%s\n", buf);
153  */
154  /* freebsd */
155  snprintf(buf, sizeof(buf), "ifconfig tap0 up");
156  system(buf);
157  printf("%s\n", buf);
158 
159  /* */
160  lasttime = 0;
161 
162  /* gdk_input_add(fd, GDK_INPUT_READ,
163  read_callback, NULL);*/
164 
165 }
166 /*---------------------------------------------------------------------------*/
167 static void
168 do_send(void)
169 {
170  int ret;
171 
172  if(fd <= 0) {
173  return;
174  }
175 
176 
177  PRINTF("tapdev_send: sending %d bytes\n", uip_len);
178  /* check_checksum(uip_buf, size);*/
179 #if DROP
180  drop++;
181  if(drop % 8 == 7) {
182  PRINTF("Dropped an output packet!\n");
183  return;
184  }
185 #endif /* DROP */
186 
187  ret = write(fd, uip_buf, uip_len);
188 
189  if(ret == -1) {
190  perror("tap_dev: tapdev_send: writev");
191  exit(1);
192  }
193 }
194 /*---------------------------------------------------------------------------*/
195 u8_t tapdev_send(uip_lladdr_t *lladdr)
196 {
197  /*
198  * If L3 dest is multicast, build L2 multicast address
199  * as per RFC 2464 section 7
200  * else fill with th eaddrsess in argument
201  */
202  if(lladdr == NULL) {
203  /* the dest must be multicast */
204  (&BUF->dest)->addr[0] = 0x33;
205  (&BUF->dest)->addr[1] = 0x33;
206  (&BUF->dest)->addr[2] = IPBUF->destipaddr.u8[12];
207  (&BUF->dest)->addr[3] = IPBUF->destipaddr.u8[13];
208  (&BUF->dest)->addr[4] = IPBUF->destipaddr.u8[14];
209  (&BUF->dest)->addr[5] = IPBUF->destipaddr.u8[15];
210  } else {
211  memcpy(&BUF->dest, lladdr, UIP_LLADDR_LEN);
212  }
213  memcpy(&BUF->src, &uip_lladdr, UIP_LLADDR_LEN);
214  BUF->type = UIP_HTONS(UIP_ETHTYPE_IPV6); //math tmp
215 
216  uip_len += sizeof(struct uip_eth_hdr);
217  do_send();
218  return 0;
219 }
220 
221 /*---------------------------------------------------------------------------*/
222 void
223 tapdev_do_send(void)
224 {
225  do_send();
226 }
227 /*---------------------------------------------------------------------------*/
228 // math added function
229 void
230 tapdev_exit(void)
231 {
232 }
233 /*---------------------------------------------------------------------------*/