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.1.2.2 2000/11/20 08:15:53 maxk Exp $
30 #include <sys/ioctl.h>
33 #include <sys/socket.h>
35 #include <net/if_tun.h>
40 * Allocate TUN device, returns opened fd.
41 * Stores dev name in the first arg(must be large enough).
43 int tun_open(char *dev
)
49 sprintf(tunname
, "/dev/%s", dev
);
50 return open(tunname
, O_RDWR
);
53 for(i
=0; i
< 255; i
++){
54 sprintf(tunname
, "/dev/tun%d", i
);
56 if( (fd
=open(tunname
, O_RDWR
)) > 0 ){
57 sprintf(dev
, "tun%d", i
);
64 int tun_close(int fd
, char *dev
)
66 dev
= NULL
; /*unused*/
70 /* Read/write frames from TUN device */
71 int tun_write(int fd
, char *buf
, int len
)
73 return write(fd
, buf
, len
);
76 int tun_read(int fd
, char *buf
, int len
)
78 return read(fd
, buf
, len
);
81 /***********************************************************************/
82 /* other support functions */
84 void config_tunnel(const char *dev
, struct in_addr myaddr
)
88 struct in_aliasreq ifra_old
, ifra_new
;
91 /* prepare socket and ifr */
92 sock
= socket (AF_INET
, SOCK_DGRAM
, 0);
94 error (1, errno
, "making socket");
95 memset (&ifr
, 0, sizeof(ifr
));
96 memset (&ifra_new
, 0, sizeof(ifra_new
));
97 memcpy (ifr
.ifr_name
, dev
, IFNAMSIZ
);
98 memcpy (ifra_new
.ifra_name
, dev
, IFNAMSIZ
);
101 ifra
.ifra_addr
.sa_family
= AF_INET
;
102 addr
= (uint8_t *)&((struct sockaddr_in
*)&ifra_new
.ifra_addr
)->sin_addr
;
103 memcpy (addr
, &myaddr
, 4);
105 /* set dest address (== my addr) */
106 ifra
.ifra_dstaddr
.sa_family
= AF_INET
;
107 addr
= (uint8_t *)&((struct sockaddr_in
*)&ifra_new
.ifra_dstaddr
)->sin_addr
;
108 memcpy (addr
, &myaddr
, 4);
110 /* set netmask (== 255.255.255.255) */
111 ifra
.ifra_mask
.sa_family
= AF_INET
;
112 addr
= (uint8_t *)&((struct sockaddr_in
*)&ifra_new
.ifra_mask
)->sin_addr
;
113 memset (addr
, 0xFF, 4);
116 /* The magic constants are:
117 1500 the normal ethernet MTU
118 -20 the size of an IP header
119 -8 the size of an ESP header
120 -2 minimum padding length
121 -12 the size of the HMAC
122 ifr.ifr_mtu = 1500-20-8-2-12;
123 Override: experimental found best value */
125 if (ioctl (sock
, SIOCSIFMTU
, &ifr
) != 0)
126 error (1, errno
, "setting interface MTU");
128 /* set interface flags */
129 if (ioctl (sock
, SIOCGIFFLAGS
, &ifr
) != 0)
130 error (1, errno
, "getting interface flags");
131 ifr
.ifr_flags
|= (IFF_UP
| IFF_RUNNING
);
132 if (ioctl (sock
, SIOCSIFFLAGS
, &ifr
) != 0)
133 error (1, errno
, "setting interface flags");
138 void error(int status
, int errornum
, const char *fmt
, ...)
144 vasprintf(&buf2
, fmt
, ap
);
146 fprintf(stderr
, "%s", buf2
);
148 fprintf(stderr
, ": %s\n", strerror(errornum
));
155 int getline(char **line
, size_t *length
, FILE *stream
)
160 tmpline
= fgetln(stream
, &len
);
164 *line
= malloc(len
+ 1);
167 if (*length
< len
+ 1) {
168 *line
= realloc(*line
, len
+ 1);
173 memcpy(*line
, tmpline
, len
);