import of 0.2-rm+zomb-pre8
[vpnc.git] / sysdep-bsd-new.c
blobbc6a13f95f0aca3fe05222de6ea3bfefc282044d
1 /*
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 $
21 */
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <syslog.h>
30 #include <sys/ioctl.h>
31 #include <stdarg.h>
33 #include <sys/socket.h>
34 #include <net/if.h>
35 #include <net/if_tun.h>
37 #include "sysdep.h"
39 /*
40 * Allocate TUN device, returns opened fd.
41 * Stores dev name in the first arg(must be large enough).
42 */
43 int tun_open(char *dev)
45 char tunname[14];
46 int i, fd;
48 if( *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);
55 /* Open device */
56 if( (fd=open(tunname, O_RDWR)) > 0 ){
57 sprintf(dev, "tun%d", i);
58 return fd;
61 return -1;
64 int tun_close(int fd, char *dev)
66 dev = NULL; /*unused*/
67 return close(fd);
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)
86 int sock;
87 struct ifreq ifr;
88 struct in_aliasreq ifra_old, ifra_new;
89 uint8_t *addr;
91 /* prepare socket and ifr */
92 sock = socket (AF_INET, SOCK_DGRAM, 0);
93 if (sock < 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);
100 /* set my address */
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);
115 /* set MTU */
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 */
124 ifr.ifr_mtu = 1412;
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");
135 close (sock);
138 void error(int status, int errornum, const char *fmt, ...)
140 char *buf2;
141 va_list ap;
143 va_start(ap, fmt);
144 vasprintf(&buf2, fmt, ap);
145 va_end(ap);
146 fprintf(stderr, "%s", buf2);
147 if (errornum)
148 fprintf(stderr, ": %s\n", strerror(errornum));
149 free(buf2);
151 if (status)
152 exit(status);
155 int getline(char **line, size_t *length, FILE *stream)
157 char *tmpline;
158 size_t len;
160 tmpline = fgetln(stream, &len);
161 if (feof(stream))
162 return -1;
163 if (*line == NULL) {
164 *line = malloc(len + 1);
165 *length = len + 1;
167 if (*length < len + 1) {
168 *line = realloc(*line, len + 1);
169 *length = len + 1;
171 if (*line == NULL)
172 return -1;
173 memcpy(*line, tmpline, len);
174 (*line)[len] = '\0';
175 return len;