Contiki 2.6

tapdev6.c

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 /*---------------------------------------------------------------------------*/