added some comments in wirefilter
[vde.git] / vde-2 / tuntap.c
blobaf76f245bdf608dbd9dc46034a63e1927aaaf1fa
1 /* Copyright 2005 Renzo Davoli - VDE-2
2 * --pidfile/-p and cleanup management by Mattia Belletti (C) 2004.
3 * Licensed under the GPLv2
4 */
6 #include <config.h>
7 #include <stdio.h>
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <syslog.h>
13 #include <stdlib.h>
14 #include <libgen.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/ioctl.h>
18 #include <net/if.h>
19 #include <stdarg.h>
20 #define _GNU_SOURCE
21 #include <getopt.h>
23 #include <linux/if_tun.h>
25 #include <port.h>
26 #include <switch.h>
27 #include <consmgmt.h>
30 #define MAXCMD 128
31 #define MODULENAME "tuntap"
33 static struct swmodule swmi;
34 static struct mod_support modfun;
35 static unsigned int tap_type;
37 struct init_tap {
38 char *tap_dev;
39 struct init_tap *next;
42 struct init_tap *hinit_tap=NULL;
44 static void send_tap(int fd, int ctl_fd, void *packet, int len, void *unused, int port)
46 int n;
48 n = write(ctl_fd, packet, len);
49 if(n != len){
50 if(errno != EAGAIN) printlog(LOG_WARNING,"send_tap port %d: %s",port,strerror(errno));
54 static void closeport(int fd, int portno)
56 if (fd>0)
57 remove_fd(fd);
60 static void handle_input(unsigned char type,int fd,int revents,int *arg)
62 struct bipacket packet;
63 int len=read(fd, &(packet.p), sizeof(struct packet));
65 if(len < 0){
66 if(errno != EAGAIN) printlog(LOG_WARNING,"Reading tap data: %s",strerror(errno));
68 else if(len == 0) {
69 if(errno != EAGAIN) printlog(LOG_WARNING,"EOF tap data port: %s",strerror(errno));
70 /* close tap! */
71 } else if (len >= ETH_HEADER_SIZE)
72 handle_in_packet(*arg, &(packet.p), len);
76 static void cleanup(unsigned char type,int fd,int arg)
78 if (fd >= 0)
79 close(fd);
82 static struct option long_options[] = {
83 {"tap", 1, 0, 't'},
85 #define Nlong_options (sizeof(long_options)/sizeof(struct option));
87 static void usage(void)
89 printf(
90 "(opts from tuntap module)\n"
91 " -t, --tap TAP Enable routing through TAP tap interface\n"
95 static struct init_tap *add_init_tap(struct init_tap *p,char *arg)
97 if (p == NULL) {
98 p=malloc(sizeof(struct init_tap));
99 if (p==NULL)
100 printlog(LOG_WARNING,"Malloc Tap init:%s\n",strerror(errno));
101 else {
102 p->tap_dev=strdup(optarg);
103 p->next=NULL;
105 } else
106 p->next=add_init_tap(p->next,arg);
107 return(p);
110 static struct init_tap *free_init_tap(struct init_tap *p)
112 if (p != NULL) {
113 free_init_tap(p->next);
114 free(p);
116 return NULL;
119 static int parseopt(int c, char *optarg)
121 int outc=0;
122 switch (c) {
123 case 't':
124 hinit_tap=add_init_tap(hinit_tap,optarg);
125 break;
126 default:
127 outc=c;
129 return outc;
132 int open_tap(char *dev)
134 struct ifreq ifr;
135 int fd;
137 if((fd = open("/dev/net/tun", O_RDWR)) < 0){
138 printlog(LOG_ERR,"Failed to open /dev/net/tun %s",strerror(errno));
139 return(-1);
141 memset(&ifr, 0, sizeof(ifr));
142 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
143 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name) - 1);
144 /*printf("dev=\"%s\", ifr.ifr_name=\"%s\"\n", ifr.ifr_name, dev);*/
145 if(ioctl(fd, TUNSETIFF, (void *) &ifr) < 0){
146 printlog(LOG_ERR,"TUNSETIFF failed %s",strerror(errno));
147 close(fd);
148 return(-1);
150 return(fd);
153 static int newport(int fd, int portno)
155 return fd;
158 static int newtap(char *dev)
160 int tap_fd;
161 tap_fd = open_tap(dev);
162 if (tap_fd>0) {
163 int portno=setup_ep(0,tap_fd,NULL,&modfun);
164 if (portno >= 0) {
165 setup_description(portno,tap_fd,dev);
166 add_fd(tap_fd,tap_type,portno);
167 return portno;
168 } else
169 return -1;
170 } else
171 return -1;
174 static void init(void)
176 if(hinit_tap != NULL) {
177 struct init_tap *p;
178 tap_type=add_type(&swmi,1);
179 for(p=hinit_tap;p != NULL;p=p->next) {
180 if (newtap(p->tap_dev) < 0)
181 printlog(LOG_ERR,"ERROR OPENING tap interface: %s",p->tap_dev);
183 hinit_tap=free_init_tap(hinit_tap);
187 static void delep (int fd, void* data, void *descr)
189 if (descr) free(descr);
192 void start_tuntap(void)
194 modfun.modname=swmi.swmname=MODULENAME;
195 swmi.swmnopts=Nlong_options;
196 swmi.swmopts=long_options;
197 swmi.usage=usage;
198 swmi.parseopt=parseopt;
199 swmi.init=init;
200 swmi.handle_input=handle_input;
201 swmi.cleanup=cleanup;
202 modfun.sender=send_tap;
203 modfun.newport=newport;
204 modfun.delep=delep;
205 modfun.delport=closeport;
206 add_swm(&swmi);