43 #include <sys/types.h> 50 #include <sys/ioctl.h> 51 #include <sys/socket.h> 55 #define LOG_MODULE "Tun6" 56 #define LOG_LEVEL LOG_LEVEL_WARN 60 #include <linux/if_tun.h> 67 static const char *config_ipaddr =
"fd00::1/64";
69 static char config_tundev[64] =
"tun0";
73 static int tunfd = -1;
75 static int set_fd(fd_set *rset, fd_set *wset);
76 static void handle_fd(fd_set *rset, fd_set *wset);
77 static const struct select_callback tun_select_callback = {
83 static int ssystem(
const char *fmt, ...)
84 __attribute__((__format__ (__printf__, 1, 2)));
86 ssystem(const
char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
89 static ssystem(const
char *fmt, ...)
94 vsnprintf(cmd,
sizeof(cmd), fmt, ap);
96 LOG_INFO(
"%s\n", cmd);
105 ssystem(
"ifconfig %s down", config_tundev);
107 ssystem(
"sysctl -w net.ipv6.conf.all.forwarding=1");
109 ssystem(
"netstat -nr" 110 " | awk '{ if ($2 == \"%s\") print \"route delete -net \"$1; }'" 117 sigcleanup(
int signo)
119 fprintf(stderr,
"signal %d\n", signo);
125 ifconf(
const char *tundev,
const char *
ipaddr)
128 ssystem(
"ifconfig %s inet `hostname` up", tundev);
129 ssystem(
"ifconfig %s add %s", tundev, ipaddr);
130 #elif defined(__APPLE__) 131 ssystem(
"ifconfig %s inet6 %s up", tundev, ipaddr);
132 ssystem(
"sysctl -w net.inet.ip.forwarding=1");
134 ssystem(
"ifconfig %s inet `hostname` %s up", tundev, ipaddr);
135 ssystem(
"sysctl -w net.inet.ip.forwarding=1");
139 ssystem(
"ifconfig %s\n", tundev);
148 LOG_INFO(
"Opening: %s\n", dev);
149 if( (fd = open(
"/dev/net/tun", O_RDWR)) < 0 ) {
154 memset(&ifr, 0,
sizeof(ifr));
159 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
161 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
163 if((err = ioctl(fd, TUNSETIFF, (
void *) &ifr)) < 0 ) {
169 LOG_INFO(
"Using '%s' vs '%s'\n", dev, ifr.ifr_name);
170 strncpy(dev, ifr.ifr_name, strlen(dev));
171 LOG_INFO(
"Using %s\n", dev);
176 devopen(
const char *dev,
int flags)
180 strncat(t, dev,
sizeof(t) - 5);
181 return open(t, flags);
187 LOG_INFO(
"Opening: %s\n", dev);
188 return devopen(dev, O_RDWR);
197 setvbuf(stdout, NULL, _IOLBF, 0);
207 setvbuf(stdout, NULL, _IOLBF, 0);
209 LOG_INFO(
"Initializing tun interface\n");
211 tunfd = tun_alloc(config_tundev);
213 LOG_WARN(
"Failed to open tun device (you may be lacking permission). Running without network.\n");
218 LOG_INFO(
"Tun open:%d\n", tunfd);
220 select_set_callback(tunfd, &tun_select_callback);
222 fprintf(stderr,
"opened %s device ``/dev/%s''\n",
223 "tun", config_tundev);
226 signal(SIGHUP, sigcleanup);
227 signal(SIGTERM, sigcleanup);
228 signal(SIGINT, sigcleanup);
229 ifconf(config_tundev, config_ipaddr);
234 tun_output(uint8_t *data,
int len)
237 if(tunfd != -1 && write(tunfd, data, len) != len) {
238 err(1,
"serial_to_tun: write");
245 tun_input(
unsigned char *data,
int maxlen)
254 if((size = read(tunfd, data, maxlen)) == -1) {
255 err(1,
"tun_input: read");
262 output(
const linkaddr_t *localdest)
275 set_fd(fd_set *rset, fd_set *wset)
288 handle_fd(fd_set *rset, fd_set *wset)
297 LOG_INFO(
"Tun6-handle FD\n");
299 if(FD_ISSET(tunfd, rset)) {
301 LOG_DBG(
"TUN data incoming read:%d\n", size);
308 static void input(
void)
311 LOG_DBG(
"Tun6 - input\n");
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
Header file for IPv6-related data structures.
#define UIP_LLH_LEN
The link level header length.
The structure of a network driver in Contiki.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
Header file for the uIP TCP/IP stack.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the logging system
static void input(void)
Process a received 6lowpan packet.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.