2 * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 RCSID("$Id: common.c,v 1.13.2.4 2000/10/18 23:31:51 assar Exp $");
38 sig_atomic_t disconnect = 0;
42 * Copy packets from `tundev' to `netdev' or vice versa.
43 * Mode is used when reading from `tundev'
47 copy_packets (int tundev, int netdev, int mtu, des_cblock *iv,
48 des_key_schedule schedule)
51 int num1 = 0, num2 = 0;
54 buf = malloc (mtu + 2);
56 warnx("malloc(%d) failed", mtu);
60 memcpy (&iv1, iv, sizeof(iv1));
61 memcpy (&iv2, iv, sizeof(iv2));
66 if (tundev >= FD_SETSIZE || netdev >= FD_SETSIZE) {
67 warnx ("fd too large");
72 FD_SET(tundev, &fdset);
73 FD_SET(netdev, &fdset);
75 ret = select (max(tundev, netdev)+1, &fdset, NULL, NULL, NULL);
82 if (FD_ISSET(tundev, &fdset)) {
83 ret = read (tundev, buf + 2, mtu);
97 des_cfb64_encrypt (buf, buf, ret, schedule,
98 &iv1, &num1, DES_ENCRYPT);
99 ret = krb_net_write (netdev, buf, ret);
105 if (FD_ISSET(netdev, &fdset)) {
106 ret = read (netdev, buf, 2);
117 des_cfb64_encrypt (buf, buf, 2, schedule,
118 &iv2, &num2, DES_DECRYPT);
119 len = (buf[0] << 8 ) | buf[1];
121 fatal (-1, "buffer too large", schedule, &iv2);
126 len = read (netdev, buf, mtu);
131 fatal (-1, buf, schedule, &iv2);
135 ret = krb_net_read (netdev, buf + 2, len);
146 des_cfb64_encrypt (buf + 2, buf + 2, len, schedule,
147 &iv2, &num2, DES_DECRYPT);
148 ret = krb_net_write (tundev, buf + 2, len);
159 * Signal handler that justs waits for the children when they die.
163 childhandler (int sig)
169 pid = waitpid (-1, &status, WNOHANG|WUNTRACED);
171 signal (SIGCHLD, childhandler);
176 * Find a free tunnel device and open it.
177 * Return the interface name in `name, len'.
181 tunnel_open (char *name, size_t len)
187 for (i = 0; i < 256; ++i) {
188 snprintf (devname, len, "%s%s%d", _PATH_DEV, TUNDEV, i);
189 fd = open (devname, O_RDWR, 0);
192 if (errno == ENOENT || errno == ENODEV) {
193 warn("open %s", name);
198 warn("open %s" ,name);
200 snprintf (name, len, "%s%d", TUNDEV, i);
205 * run the command `cmd' with (...). return 0 if succesful or error
206 * otherwise (and copy an error messages into `msg, len')
210 kip_exec (const char *cmd, char *msg, size_t len, ...)
217 argv = vstrcollect(&ap);
223 snprintf (msg, len, "fork: %s", strerror(errno));
226 int fd = open (_PATH_DEVNULL, O_RDWR, 0600);
228 snprintf (msg, len, "open " _PATH_DEVNULL ": %s", strerror(errno));
232 close (STDIN_FILENO);
233 close (STDOUT_FILENO);
234 close (STDERR_FILENO);
236 dup2 (fd, STDIN_FILENO);
237 dup2 (fd, STDOUT_FILENO);
238 dup2 (fd, STDERR_FILENO);
241 snprintf (msg, len, "execvp %s: %s", cmd, strerror(errno));
247 while (waitpid(pid, &status, 0) < 0)
248 if (errno != EINTR) {
249 snprintf (msg, len, "waitpid: %s", strerror(errno));
253 if (WIFEXITED(status)) {
254 if (WEXITSTATUS(status) == 0) {
257 snprintf (msg, len, "child returned with %d",
258 WEXITSTATUS(status));
261 } else if (WIFSIGNALED(status)) {
263 #define WCOREDUMP(X) 0
265 snprintf (msg, len, "terminated by signal num %d %s",
267 WCOREDUMP(status) ? " coredumped" : "");
269 } else if (WIFSTOPPED(status)) {
270 snprintf (msg, len, "process stoped by signal %d",
274 snprintf (msg, len, "child died in mysterious circumstances");
282 * fatal error `s' occured.
286 fatal (int fd, const char *s, des_key_schedule schedule, des_cblock *iv)
292 des_cfb64_encrypt ((unsigned char*) &err, (unsigned char*) &err,
293 sizeof(err), schedule, iv, &num, DES_ENCRYPT);
295 write (fd, &err, sizeof(err));
296 write (fd, s, strlen(s)+1);
299 syslog(LOG_ERR, "%s", s);
301 warnx ("fatal error: %s", s);