2 VTun - Virtual Tunnel over TCP/IP network.
4 Copyright (C) 1998-2000 Maxim Krasnyansky <max_mk@yahoo.com>
6 VTun has been derived from VPPP package by Maxim Krasnyansky.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 * $Id: tun_dev.c,v 1.2.2.2 2000/11/20 08:15:53 maxk Exp $
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <sys/sockio.h>
36 #include <sys/ioctl.h>
41 #include <net/if_tun.h>
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
45 #include <netinet/tcp.h>
47 static int ip_fd
= -1, muxid
;
50 * Allocate TUN device, returns opened fd.
51 * Stores dev name in the first arg(must be large enough).
53 int tun_open(char *dev
)
55 int tun_fd
, if_fd
, ppa
= -1;
61 while( *ptr
&& !isdigit((int)*ptr
) ) ptr
++;
65 if( (ip_fd
= open("/dev/udp", O_RDWR
, 0)) < 0){
66 syslog(LOG_ERR
, "Can't open /dev/ip");
70 if( (tun_fd
= open("/dev/tun", O_RDWR
, 0)) < 0){
71 syslog(LOG_ERR
, "Can't open /dev/tun");
75 /* Assign a new PPA and get its unit number. */
76 if( (ppa
= ioctl(tun_fd
, TUNNEWPPA
, ppa
)) < 0){
77 syslog(LOG_ERR
, "Can't assign new interface");
81 if( (if_fd
= open("/dev/tun", O_RDWR
, 0)) < 0){
82 syslog(LOG_ERR
, "Can't open /dev/tun (2)");
85 if(ioctl(if_fd
, I_PUSH
, "ip") < 0){
86 syslog(LOG_ERR
, "Can't push IP module");
90 /* Assign ppa according to the unit number returned by tun device */
91 if(ioctl(if_fd
, IF_UNITSEL
, (char *)&ppa
) < 0){
92 syslog(LOG_ERR
, "Can't set PPA %d", ppa
);
95 if( (muxid
= ioctl(ip_fd
, I_PLINK
, if_fd
)) < 0){
96 syslog(LOG_ERR
, "Can't link TUN device to IP");
101 sprintf(dev
, "tun%d", ppa
);
103 memset(&ifr
, 0, sizeof(ifr
));
104 strcpy(ifr
.ifr_name
, dev
);
105 ifr
.ifr_ip_muxid
= muxid
;
107 if( ioctl(ip_fd
, SIOCSIFMUXID
, &ifr
) < 0 ){
108 ioctl(ip_fd
, I_PUNLINK
, muxid
);
109 syslog(LOG_ERR
, "Can't set multiplexor id");
119 int tun_close(int fd
, char *dev
)
123 memset(&ifr
, 0, sizeof(ifr
));
124 strcpy(ifr
.ifr_name
, dev
);
125 if( ioctl(ip_fd
, SIOCGIFFLAGS
, &ifr
) < 0 ){
126 syslog(LOG_ERR
, "Can't get iface flags");
131 if( ioctl(ip_fd
, SIOCGIFMUXID
, &ifr
) < 0 ){
132 syslog(LOG_ERR
, "Can't get multiplexor id");
135 muxid
= ifr
.ifr_ip_muxid
;
138 if( ioctl(ip_fd
, I_PUNLINK
, muxid
) < 0 ){
139 syslog(LOG_ERR
, "Can't unlink interface");
143 close(ip_fd
); close(fd
);
147 int tun_write(int fd
, char *buf
, int len
)
152 return putmsg(fd
, NULL
, &sbuf
, 0) >=0 ? sbuf
.len
: -1;
155 int tun_read(int fd
, char *buf
, int len
)
162 return getmsg(fd
, NULL
, &sbuf
, &f
) >=0 ? sbuf
.len
: -1;