import of 0.2-rm+zomb-pre9
[vpnc.git] / sysdep-svr4.c
blobbc9fbd6f1f025a61f72ddbd5830cb3b8ff84ac2c
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.2.2.2 2000/11/20 08:15:53 maxk Exp $
21 */
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <stdarg.h>
30 #include <sys/time.h>
31 #include <sys/wait.h>
32 #include <syslog.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <sys/sockio.h>
36 #include <sys/ioctl.h>
37 #include <errno.h>
38 #include <signal.h>
39 #include <stropts.h>
40 #include <net/if.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;
49 /*
50 * Allocate TUN device, returns opened fd.
51 * Stores dev name in the first arg(must be large enough).
52 */
53 int tun_open(char *dev)
55 int tun_fd, if_fd, ppa = -1;
56 struct ifreq ifr;
57 char *ptr;
59 if( *dev ){
60 ptr = dev;
61 while( *ptr && !isdigit((int)*ptr) ) ptr++;
62 ppa = atoi(ptr);
65 if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
66 syslog(LOG_ERR, "Can't open /dev/ip");
67 return -1;
70 if( (tun_fd = open("/dev/tun", O_RDWR, 0)) < 0){
71 syslog(LOG_ERR, "Can't open /dev/tun");
72 return -1;
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");
78 return -1;
81 if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){
82 syslog(LOG_ERR, "Can't open /dev/tun (2)");
83 return -1;
85 if(ioctl(if_fd, I_PUSH, "ip") < 0){
86 syslog(LOG_ERR, "Can't push IP module");
87 return -1;
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);
93 return -1;
95 if( (muxid = ioctl(ip_fd, I_PLINK, if_fd)) < 0){
96 syslog(LOG_ERR, "Can't link TUN device to IP");
97 return -1;
99 close(if_fd);
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");
110 return -1;
113 return tun_fd;
117 * Close TUN device.
119 int tun_close(int fd, char *dev)
121 struct ifreq ifr;
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");
127 return 0;
130 #if 0
131 if( ioctl(ip_fd, SIOCGIFMUXID, &ifr) < 0 ){
132 syslog(LOG_ERR, "Can't get multiplexor id");
133 return 0;
135 muxid = ifr.ifr_ip_muxid;
136 #endif
138 if( ioctl(ip_fd, I_PUNLINK, muxid) < 0 ){
139 syslog(LOG_ERR, "Can't unlink interface");
140 return 0;
143 close(ip_fd); close(fd);
144 return 0;
147 int tun_write(int fd, char *buf, int len)
149 struct strbuf sbuf;
150 sbuf.len = len;
151 sbuf.buf = buf;
152 return putmsg(fd, NULL, &sbuf, 0) >=0 ? sbuf.len : -1;
155 int tun_read(int fd, char *buf, int len)
157 struct strbuf sbuf;
158 int f = 0;
160 sbuf.maxlen = len;
161 sbuf.buf = buf;
162 return getmsg(fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
165 /***********************************************************************/
166 /* other support functions */
168 const char *sysdep_config_script(void)
170 return "ifconfig $TUNDEV inet $INTERNAL_IP4_ADDRESS $INTERNAL_IP4_ADDRESS netmask 255.255.255.255 mtu 1412 up";
173 void error(int status, int errornum, const char *fmt, ...)
175 char *buf2;
176 va_list ap;
178 va_start(ap, fmt);
179 vasprintf(&buf2, fmt, ap);
180 va_end(ap);
181 fprintf(stderr, "%s", buf2);
182 if (errornum)
183 fprintf(stderr, ": %s\n", strerror(errornum));
184 free(buf2);
186 if (status)
187 exit(status);
190 int getline(char **line, size_t *length, FILE *stream)
192 char *tmpline;
193 size_t len;
195 tmpline = fgetln(stream, &len);
196 if (feof(stream))
197 return -1;
198 if (*line == NULL) {
199 *line = malloc(len + 1);
200 *length = len + 1;
202 if (*length < len + 1) {
203 *line = realloc(*line, len + 1);
204 *length = len + 1;
206 if (*line == NULL)
207 return -1;
208 memcpy(*line, tmpline, len);
209 (*line)[len] = '\0';
210 return len;