1 /* Copyright 2005 Renzo Davoli - VDE-2
2 * --pidfile/-p and cleanup management by Mattia Belletti (C) 2004.
3 * Licensed under the GPLv2
15 #include <sys/types.h>
17 #include <sys/ioctl.h>
23 #include <linux/if_tun.h>
31 #define MODULENAME "tuntap"
33 static struct swmodule swmi
;
34 static struct mod_support modfun
;
35 static unsigned int tap_type
;
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
)
48 n
= write(ctl_fd
, packet
, len
);
50 if(errno
!= EAGAIN
) printlog(LOG_WARNING
,"send_tap port %d: %s",port
,strerror(errno
));
54 static void closeport(int fd
, int portno
)
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
));
66 if(errno
!= EAGAIN
) printlog(LOG_WARNING
,"Reading tap data: %s",strerror(errno
));
69 if(errno
!= EAGAIN
) printlog(LOG_WARNING
,"EOF tap data port: %s",strerror(errno
));
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
)
82 static struct option long_options
[] = {
85 #define Nlong_options (sizeof(long_options)/sizeof(struct option));
87 static void usage(void)
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
)
98 p
=malloc(sizeof(struct init_tap
));
100 printlog(LOG_WARNING
,"Malloc Tap init:%s\n",strerror(errno
));
102 p
->tap_dev
=strdup(optarg
);
106 p
->next
=add_init_tap(p
->next
,arg
);
110 static struct init_tap
*free_init_tap(struct init_tap
*p
)
113 free_init_tap(p
->next
);
119 static int parseopt(int c
, char *optarg
)
124 hinit_tap
=add_init_tap(hinit_tap
,optarg
);
132 int open_tap(char *dev
)
137 if((fd
= open("/dev/net/tun", O_RDWR
)) < 0){
138 printlog(LOG_ERR
,"Failed to open /dev/net/tun %s",strerror(errno
));
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
));
153 static int newport(int fd
, int portno
)
158 static int newtap(char *dev
)
161 tap_fd
= open_tap(dev
);
163 int portno
=setup_ep(0,tap_fd
,NULL
,&modfun
);
165 setup_description(portno
,tap_fd
,dev
);
166 add_fd(tap_fd
,tap_type
,portno
);
174 static void init(void)
176 if(hinit_tap
!= NULL
) {
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
;
198 swmi
.parseopt
=parseopt
;
200 swmi
.handle_input
=handle_input
;
201 swmi
.cleanup
=cleanup
;
202 modfun
.sender
=send_tap
;
203 modfun
.newport
=newport
;
205 modfun
.delport
=closeport
;