]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
Fix authentication on second time around with multilink and persist
[ppp.git] / pppd / sys-linux.c
1 /*
2  * sys-linux.c - System-dependent procedures for setting up
3  * PPP interfaces on Linux systems
4  *
5  * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. The name(s) of the authors of this software must not be used to
15  *    endorse or promote products derived from this software without
16  *    prior written permission.
17  *
18  * 3. Redistributions of any form whatsoever must retain the following
19  *    acknowledgment:
20  *    "This product includes software developed by Paul Mackerras
21  *     <paulus@samba.org>".
22  *
23  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
24  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
25  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
26  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
29  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30  *
31  * Derived from main.c and pppd.h, which are:
32  *
33  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  *
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  *
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in
44  *    the documentation and/or other materials provided with the
45  *    distribution.
46  *
47  * 3. The name "Carnegie Mellon University" must not be used to
48  *    endorse or promote products derived from this software without
49  *    prior written permission. For permission or any legal
50  *    details, please contact
51  *      Office of Technology Transfer
52  *      Carnegie Mellon University
53  *      5000 Forbes Avenue
54  *      Pittsburgh, PA  15213-3890
55  *      (412) 268-4387, fax: (412) 268-7395
56  *      tech-transfer@andrew.cmu.edu
57  *
58  * 4. Redistributions of any form whatsoever must retain the following
59  *    acknowledgment:
60  *    "This product includes software developed by Computing Services
61  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
62  *
63  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
64  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
65  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
66  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
67  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
68  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
69  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
70  */
71
72 #include <sys/ioctl.h>
73 #include <sys/types.h>
74 #include <sys/socket.h>
75 #include <sys/time.h>
76 #include <sys/errno.h>
77 #include <sys/file.h>
78 #include <sys/stat.h>
79 #include <sys/utsname.h>
80 #include <sys/sysmacros.h>
81
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <syslog.h>
85 #include <string.h>
86 #include <time.h>
87 #include <memory.h>
88 #include <utmp.h>
89 #include <mntent.h>
90 #include <signal.h>
91 #include <fcntl.h>
92 #include <ctype.h>
93 #include <termios.h>
94 #include <unistd.h>
95
96 /* This is in netdevice.h. However, this compile will fail miserably if
97    you attempt to include netdevice.h because it has so many references
98    to __memcpy functions which it should not attempt to do. So, since I
99    really don't use it, but it must be defined, define it now. */
100
101 #ifndef MAX_ADDR_LEN
102 #define MAX_ADDR_LEN 7
103 #endif
104
105 #if __GLIBC__ >= 2
106 #include <asm/types.h>          /* glibc 2 conflicts with linux/types.h */
107 #include <net/if.h>
108 #include <net/if_arp.h>
109 #include <net/route.h>
110 #include <netinet/if_ether.h>
111 #else
112 #include <linux/types.h>
113 #include <linux/if.h>
114 #include <linux/if_arp.h>
115 #include <linux/route.h>
116 #include <linux/if_ether.h>
117 #endif
118 #include <netinet/in.h>
119 #include <arpa/inet.h>
120
121 #include <linux/ppp_defs.h>
122 #include <linux/if_ppp.h>
123
124 #include "pppd.h"
125 #include "fsm.h"
126 #include "ipcp.h"
127
128 #ifdef IPX_CHANGE
129 #include "ipxcp.h"
130 #if __GLIBC__ >= 2 && \
131     !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
132 #include <netipx/ipx.h>
133 #else
134 #include <linux/ipx.h>
135 #endif
136 #endif /* IPX_CHANGE */
137
138 #ifdef PPP_FILTER
139 #include <pcap-bpf.h>
140 #include <linux/filter.h>
141 #endif /* PPP_FILTER */
142
143 #ifdef LOCKLIB
144 #include <sys/locks.h>
145 #endif
146
147 #ifdef INET6
148 #ifndef _LINUX_IN6_H
149 /*
150  *    This is in linux/include/net/ipv6.h.
151  */
152
153 struct in6_ifreq {
154     struct in6_addr ifr6_addr;
155     __u32 ifr6_prefixlen;
156     unsigned int ifr6_ifindex;
157 };
158 #endif
159
160 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {                 \
161         memset(&sin6.s6_addr, 0, sizeof(struct in6_addr));      \
162         sin6.s6_addr16[0] = htons(0xfe80);                      \
163         eui64_copy(eui64, sin6.s6_addr32[2]);                   \
164         } while (0)
165
166 #endif /* INET6 */
167
168 /* We can get an EIO error on an ioctl if the modem has hung up */
169 #define ok_error(num) ((num)==EIO)
170
171 static int tty_disc = N_TTY;    /* The TTY discipline */
172 static int ppp_disc = N_PPP;    /* The PPP discpline */
173 static int initfdflags = -1;    /* Initial file descriptor flags for fd */
174 static int ppp_fd = -1;         /* fd which is set to PPP discipline */
175 static int sock_fd = -1;        /* socket for doing interface ioctls */
176 static int slave_fd = -1;       /* pty for old-style demand mode, slave */
177 static int master_fd = -1;      /* pty for old-style demand mode, master */
178 #ifdef INET6
179 static int sock6_fd = -1;
180 #endif /* INET6 */
181
182 /*
183  * For the old-style kernel driver, this is the same as ppp_fd.
184  * For the new-style driver, it is the fd of an instance of /dev/ppp
185  * which is attached to the ppp unit and is used for controlling it.
186  */
187 int ppp_dev_fd = -1;            /* fd for /dev/ppp (new style driver) */
188
189 static int chindex;             /* channel index (new style driver) */
190
191 static fd_set in_fds;           /* set of fds that wait_input waits for */
192 static int max_in_fd;           /* highest fd set in in_fds */
193
194 static int has_proxy_arp       = 0;
195 static int driver_version      = 0;
196 static int driver_modification = 0;
197 static int driver_patch        = 0;
198 static int driver_is_old       = 0;
199 static int restore_term        = 0;     /* 1 => we've munged the terminal */
200 static struct termios inittermios;      /* Initial TTY termios */
201
202 int new_style_driver = 0;
203
204 static char loop_name[20];
205 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
206
207 static int      if_is_up;       /* Interface has been marked up */
208 static int      have_default_route;     /* Gateway for default route added */
209 static u_int32_t proxy_arp_addr;        /* Addr for proxy arp entry added */
210 static char proxy_arp_dev[16];          /* Device for proxy arp entry */
211 static u_int32_t our_old_addr;          /* for detecting address changes */
212 static int      dynaddr_set;            /* 1 if ip_dynaddr set */
213 static int      looped;                 /* 1 if using loop */
214 static int      link_mtu;               /* mtu for the link (not bundle) */
215
216 static struct utsname utsname;  /* for the kernel version */
217 static int kernel_version;
218 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
219
220 #define MAX_IFS         100
221
222 #define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
223 #define FLAGS_MASK (IFF_UP          | IFF_BROADCAST | \
224                     IFF_POINTOPOINT | IFF_LOOPBACK  | IFF_NOARP)
225
226 #define SIN_ADDR(x)     (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
227
228 /* Prototypes for procedures local to this file. */
229 static int modify_flags(int fd, int clear_bits, int set_bits);
230 static int translate_speed (int bps);
231 static int baud_rate_of (int speed);
232 static void close_route_table (void);
233 static int open_route_table (void);
234 static int read_route_table (struct rtentry *rt);
235 static int defaultroute_exists (struct rtentry *rt);
236 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
237                            char *name, int namelen);
238 static void decode_version (char *buf, int *version, int *mod, int *patch);
239 static int set_kdebugflag(int level);
240 static int ppp_registered(void);
241 static int make_ppp_unit(void);
242
243 extern u_char   inpacket_buf[]; /* borrowed from main.c */
244
245 /*
246  * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
247  * if it exists.
248  */
249
250 #define SET_SA_FAMILY(addr, family)                     \
251     memset ((char *) &(addr), '\0', sizeof(addr));      \
252     addr.sa_family = (family);
253
254 /*
255  * Determine if the PPP connection should still be present.
256  */
257
258 extern int hungup;
259
260 /* new_fd is the fd of a tty */
261 static void set_ppp_fd (int new_fd)
262 {
263         ppp_fd = new_fd;
264         if (!new_style_driver)
265                 ppp_dev_fd = new_fd;
266 }
267
268 static int still_ppp(void)
269 {
270         if (new_style_driver)
271                 return !hungup && ppp_fd >= 0;
272         if (!hungup || ppp_fd == slave_fd)
273                 return 1;
274         if (slave_fd >= 0) {
275                 set_ppp_fd(slave_fd);
276                 return 1;
277         }
278         return 0;
279 }
280
281 /*
282  * modify_flags - set and clear flag bits controlling the kernel
283  * PPP driver.
284  */
285 static int modify_flags(int fd, int clear_bits, int set_bits)
286 {
287         int flags;
288
289         if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
290                 goto err;
291         flags = (flags & ~clear_bits) | set_bits;
292         if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
293                 goto err;
294
295         return 0;
296
297  err:
298         if (errno != EIO)
299                 error("Failed to set PPP kernel option flags: %m");
300         return -1;
301 }
302
303 /********************************************************************
304  *
305  * sys_init - System-dependent initialization.
306  */
307
308 void sys_init(void)
309 {
310     /* Get an internet socket for doing socket ioctls. */
311     sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
312     if (sock_fd < 0)
313         fatal("Couldn't create IP socket: %m(%d)", errno);
314
315 #ifdef INET6
316     sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
317     if (sock6_fd < 0)
318         sock6_fd = -errno;      /* save errno for later */
319 #endif
320
321     FD_ZERO(&in_fds);
322     max_in_fd = 0;
323 }
324
325 /********************************************************************
326  *
327  * sys_cleanup - restore any system state we modified before exiting:
328  * mark the interface down, delete default route and/or proxy arp entry.
329  * This shouldn't call die() because it's called from die().
330  */
331
332 void sys_cleanup(void)
333 {
334 /*
335  * Take down the device
336  */
337     if (if_is_up) {
338         if_is_up = 0;
339         sifdown(0);
340     }
341 /*
342  * Delete any routes through the device.
343  */
344     if (have_default_route)
345         cifdefaultroute(0, 0, 0);
346
347     if (has_proxy_arp)
348         cifproxyarp(0, proxy_arp_addr);
349 }
350
351 /********************************************************************
352  *
353  * sys_close - Clean up in a child process before execing.
354  */
355 void
356 sys_close(void)
357 {
358     if (new_style_driver && ppp_dev_fd >= 0)
359         close(ppp_dev_fd);
360     if (sock_fd >= 0)
361         close(sock_fd);
362 #ifdef INET6
363     if (sock6_fd >= 0)
364         close(sock6_fd);
365 #endif
366     if (slave_fd >= 0)
367         close(slave_fd);
368     if (master_fd >= 0)
369         close(master_fd);
370 }
371
372 /********************************************************************
373  *
374  * set_kdebugflag - Define the debugging level for the kernel
375  */
376
377 static int set_kdebugflag (int requested_level)
378 {
379     if (ppp_dev_fd < 0)
380         return 1;
381     if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
382         if ( ! ok_error (errno) )
383             error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
384         return (0);
385     }
386     return (1);
387 }
388
389 /********************************************************************
390  *
391  * tty_establish_ppp - Turn the serial port into a ppp interface.
392  */
393
394 int tty_establish_ppp (int tty_fd)
395 {
396     int ret_fd;
397
398 /*
399  * Ensure that the tty device is in exclusive mode.
400  */
401     if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
402         if ( ! ok_error ( errno ))
403             warn("Couldn't make tty exclusive: %m");
404     }
405 /*
406  * Demand mode - prime the old ppp device to relinquish the unit.
407  */
408     if (!new_style_driver && looped
409         && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
410         error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
411         return -1;
412     }
413 /*
414  * Set the current tty to the PPP discpline
415  */
416
417 #ifndef N_SYNC_PPP
418 #define N_SYNC_PPP 14
419 #endif
420     ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
421     if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
422         if ( ! ok_error (errno) ) {
423             error("Couldn't set tty to PPP discipline: %m");
424             return -1;
425         }
426     }
427
428     ret_fd = generic_establish_ppp(tty_fd);
429
430 #define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
431 #define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
432                  | SC_LOG_FLUSH)
433
434     if (ret_fd >= 0) {
435         modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
436                      (kdebugflag * SC_DEBUG) & SC_LOGB);
437     } else {
438         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
439             warn("Couldn't reset tty to normal line discipline: %m");
440     }
441
442     return ret_fd;
443 }
444
445 /********************************************************************
446  *
447  * generic_establish_ppp - Turn the fd into a ppp interface.
448  */
449 int generic_establish_ppp (int fd)
450 {
451     int x;
452
453     if (new_style_driver) {
454         int flags;
455
456         /* Open an instance of /dev/ppp and connect the channel to it */
457         if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
458             error("Couldn't get channel number: %m");
459             goto err;
460         }
461         dbglog("using channel %d", chindex);
462         fd = open("/dev/ppp", O_RDWR);
463         if (fd < 0) {
464             error("Couldn't reopen /dev/ppp: %m");
465             goto err;
466         }
467         (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
468         if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
469             error("Couldn't attach to channel %d: %m", chindex);
470             goto err_close;
471         }
472         flags = fcntl(fd, F_GETFL);
473         if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
474             warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
475         set_ppp_fd(fd);
476
477         if (!looped)
478             ifunit = -1;
479         if (!looped && !multilink) {
480             /*
481              * Create a new PPP unit.
482              */
483             if (make_ppp_unit() < 0)
484                 goto err_close;
485         }
486
487         if (looped)
488             modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
489
490         if (!multilink) {
491             add_fd(ppp_dev_fd);
492             if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
493                 error("Couldn't attach to PPP unit %d: %m", ifunit);
494                 goto err_close;
495             }
496         }
497
498     } else {
499         /*
500          * Old-style driver: find out which interface we were given.
501          */
502         set_ppp_fd (fd);
503         if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
504             if (ok_error (errno))
505                 goto err;
506             fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
507         }
508         /* Check that we got the same unit again. */
509         if (looped && x != ifunit)
510             fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
511         ifunit = x;
512
513         /*
514          * Fetch the initial file flags and reset blocking mode on the file.
515          */
516         initfdflags = fcntl(fd, F_GETFL);
517         if (initfdflags == -1 ||
518             fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
519             if ( ! ok_error (errno))
520                 warn("Couldn't set device to non-blocking mode: %m");
521         }
522     }
523
524     /*
525      * Enable debug in the driver if requested.
526      */
527     if (!looped)
528         set_kdebugflag (kdebugflag);
529
530     looped = 0;
531
532     return ppp_fd;
533
534  err_close:
535     close(fd);
536  err:
537     return -1;
538 }
539
540 /********************************************************************
541  *
542  * tty_disestablish_ppp - Restore the serial port to normal operation.
543  * This shouldn't call die() because it's called from die().
544  */
545
546 void tty_disestablish_ppp(int tty_fd)
547 {
548     if (!hungup) {
549 /*
550  * Flush the tty output buffer so that the TIOCSETD doesn't hang.
551  */
552         if (tcflush(tty_fd, TCIOFLUSH) < 0)
553         {
554             warn("tcflush failed: %m");
555             goto flushfailed;
556         }
557 /*
558  * Restore the previous line discipline
559  */
560         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
561             if ( ! ok_error (errno))
562                 error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
563         }
564
565         if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
566             if ( ! ok_error (errno))
567                 warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
568         }
569
570         /* Reset non-blocking mode on fd. */
571         if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
572             if ( ! ok_error (errno))
573                 warn("Couldn't restore device fd flags: %m");
574         }
575     }
576 flushfailed:
577     initfdflags = -1;
578
579     generic_disestablish_ppp(tty_fd);
580 }
581
582 /********************************************************************
583  *
584  * generic_disestablish_ppp - Restore device components to normal
585  * operation, and reconnect the ppp unit to the loopback if in demand
586  * mode.  This shouldn't call die() because it's called from die().
587  */
588 void generic_disestablish_ppp(int dev_fd)
589 {
590     if (new_style_driver) {
591         close(ppp_fd);
592         ppp_fd = -1;
593         if (demand) {
594             modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
595             looped = 1;
596         } else if (!doing_multilink && ppp_dev_fd >= 0) {
597             close(ppp_dev_fd);
598             remove_fd(ppp_dev_fd);
599             ppp_dev_fd = -1;
600         }
601     } else {
602         /* old-style driver */
603         if (demand)
604             set_ppp_fd(slave_fd);
605         else
606             ppp_dev_fd = -1;
607     }
608 }
609
610 /*
611  * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
612  * Assumes new_style_driver.
613  */
614 static int make_ppp_unit()
615 {
616         int x, flags;
617
618         if (ppp_dev_fd >= 0) {
619                 dbglog("in make_ppp_unit, already had /dev/ppp open?");
620                 close(ppp_dev_fd);
621         }
622         ppp_dev_fd = open("/dev/ppp", O_RDWR);
623         if (ppp_dev_fd < 0)
624                 fatal("Couldn't open /dev/ppp: %m");
625         flags = fcntl(ppp_dev_fd, F_GETFL);
626         if (flags == -1
627             || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
628                 warn("Couldn't set /dev/ppp to nonblock: %m");
629
630         ifunit = req_unit;
631         x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
632         if (x < 0 && req_unit >= 0 && errno == EEXIST) {
633                 warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
634                 ifunit = -1;
635                 x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
636         }
637         if (x < 0)
638                 error("Couldn't create new ppp unit: %m");
639         return x;
640 }
641
642 /*
643  * cfg_bundle - configure the existing bundle.
644  * Used in demand mode.
645  */
646 void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
647 {
648         if (!new_style_driver)
649                 return;
650
651         /* set the mrru, mtu and flags */
652         if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
653                 error("Couldn't set MRRU: %m");
654
655         modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
656                      ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
657                       | (mrru? SC_MULTILINK: 0)));
658
659         /* connect up the channel */
660         if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
661                 fatal("Couldn't attach to PPP unit %d: %m", ifunit);
662         add_fd(ppp_dev_fd);
663 }
664
665 /*
666  * make_new_bundle - create a new PPP unit (i.e. a bundle)
667  * and connect our channel to it.  This should only get called
668  * if `multilink' was set at the time establish_ppp was called.
669  * In demand mode this uses our existing bundle instead of making
670  * a new one.
671  */
672 void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
673 {
674         if (!new_style_driver)
675                 return;
676
677         /* make us a ppp unit */
678         if (make_ppp_unit() < 0)
679                 die(1);
680
681         /* set the mrru and flags */
682         cfg_bundle(mrru, mtru, rssn, tssn);
683 }
684
685 /*
686  * bundle_attach - attach our link to a given PPP unit.
687  * We assume the unit is controlled by another pppd.
688  */
689 int bundle_attach(int ifnum)
690 {
691         int master_fd;
692
693         if (!new_style_driver)
694                 return -1;
695
696         master_fd = open("/dev/ppp", O_RDWR);
697         if (master_fd < 0)
698                 fatal("Couldn't open /dev/ppp: %m");
699         if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
700                 if (errno == ENXIO) {
701                         close(master_fd);
702                         return 0;       /* doesn't still exist */
703                 }
704                 fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
705         }
706         if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
707                 fatal("Couldn't connect to interface unit %d: %m", ifnum);
708         modify_flags(master_fd, 0, SC_MULTILINK);
709         close(master_fd);
710
711         ifunit = ifnum;
712         return 1;
713 }
714
715 /*
716  * destroy_bundle - tell the driver to destroy our bundle.
717  */
718 void destroy_bundle(void)
719 {
720         if (ppp_dev_fd >= 0) {
721                 close(ppp_dev_fd);
722                 remove_fd(ppp_dev_fd);
723                 ppp_dev_fd = -1;
724         }
725 }
726
727 /********************************************************************
728  *
729  * clean_check - Fetch the flags for the device and generate
730  * appropriate error messages.
731  */
732 void clean_check(void)
733 {
734     int x;
735     char *s;
736
737     if (still_ppp()) {
738         if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
739             s = NULL;
740             switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
741             case SC_RCV_B7_0:
742                 s = "all had bit 7 set to 1";
743                 break;
744
745             case SC_RCV_B7_1:
746                 s = "all had bit 7 set to 0";
747                 break;
748
749             case SC_RCV_EVNP:
750                 s = "all had odd parity";
751                 break;
752
753             case SC_RCV_ODDP:
754                 s = "all had even parity";
755                 break;
756             }
757
758             if (s != NULL) {
759                 warn("Receive serial link is not 8-bit clean:");
760                 warn("Problem: %s", s);
761             }
762         }
763     }
764 }
765
766
767 /*
768  * List of valid speeds.
769  */
770
771 struct speed {
772     int speed_int, speed_val;
773 } speeds[] = {
774 #ifdef B50
775     { 50, B50 },
776 #endif
777 #ifdef B75
778     { 75, B75 },
779 #endif
780 #ifdef B110
781     { 110, B110 },
782 #endif
783 #ifdef B134
784     { 134, B134 },
785 #endif
786 #ifdef B150
787     { 150, B150 },
788 #endif
789 #ifdef B200
790     { 200, B200 },
791 #endif
792 #ifdef B300
793     { 300, B300 },
794 #endif
795 #ifdef B600
796     { 600, B600 },
797 #endif
798 #ifdef B1200
799     { 1200, B1200 },
800 #endif
801 #ifdef B1800
802     { 1800, B1800 },
803 #endif
804 #ifdef B2000
805     { 2000, B2000 },
806 #endif
807 #ifdef B2400
808     { 2400, B2400 },
809 #endif
810 #ifdef B3600
811     { 3600, B3600 },
812 #endif
813 #ifdef B4800
814     { 4800, B4800 },
815 #endif
816 #ifdef B7200
817     { 7200, B7200 },
818 #endif
819 #ifdef B9600
820     { 9600, B9600 },
821 #endif
822 #ifdef B19200
823     { 19200, B19200 },
824 #endif
825 #ifdef B38400
826     { 38400, B38400 },
827 #endif
828 #ifdef B57600
829     { 57600, B57600 },
830 #endif
831 #ifdef B76800
832     { 76800, B76800 },
833 #endif
834 #ifdef B115200
835     { 115200, B115200 },
836 #endif
837 #ifdef EXTA
838     { 19200, EXTA },
839 #endif
840 #ifdef EXTB
841     { 38400, EXTB },
842 #endif
843 #ifdef B230400
844     { 230400, B230400 },
845 #endif
846 #ifdef B460800
847     { 460800, B460800 },
848 #endif
849 #ifdef B921600
850     { 921600, B921600 },
851 #endif
852 #ifdef B1000000
853     { 1000000, B1000000 },
854 #endif
855 #ifdef B1152000
856     { 1152000, B1152000 },
857 #endif
858 #ifdef B1500000
859     { 1500000, B1500000 },
860 #endif
861 #ifdef B2000000
862     { 2000000, B2000000 },
863 #endif
864 #ifdef B2500000
865     { 2500000, B2500000 },
866 #endif
867 #ifdef B3000000
868     { 3000000, B3000000 },
869 #endif
870 #ifdef B3500000
871     { 3500000, B3500000 },
872 #endif
873 #ifdef B4000000
874     { 4000000, B4000000 },
875 #endif
876     { 0, 0 }
877 };
878
879 /********************************************************************
880  *
881  * Translate from bits/second to a speed_t.
882  */
883
884 static int translate_speed (int bps)
885 {
886     struct speed *speedp;
887
888     if (bps != 0) {
889         for (speedp = speeds; speedp->speed_int; speedp++) {
890             if (bps == speedp->speed_int)
891                 return speedp->speed_val;
892         }
893         warn("speed %d not supported", bps);
894     }
895     return 0;
896 }
897
898 /********************************************************************
899  *
900  * Translate from a speed_t to bits/second.
901  */
902
903 static int baud_rate_of (int speed)
904 {
905     struct speed *speedp;
906
907     if (speed != 0) {
908         for (speedp = speeds; speedp->speed_int; speedp++) {
909             if (speed == speedp->speed_val)
910                 return speedp->speed_int;
911         }
912     }
913     return 0;
914 }
915
916 /********************************************************************
917  *
918  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
919  * at the requested speed, etc.  If `local' is true, set CLOCAL
920  * regardless of whether the modem option was specified.
921  */
922
923 void set_up_tty(int tty_fd, int local)
924 {
925     int speed;
926     struct termios tios;
927
928     setdtr(tty_fd, 1);
929     if (tcgetattr(tty_fd, &tios) < 0) {
930         if (!ok_error(errno))
931             fatal("tcgetattr: %m (line %d)", __LINE__);
932         return;
933     }
934
935     if (!restore_term)
936         inittermios = tios;
937
938     tios.c_cflag     &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
939     tios.c_cflag     |= CS8 | CREAD | HUPCL;
940
941     tios.c_iflag      = IGNBRK | IGNPAR;
942     tios.c_oflag      = 0;
943     tios.c_lflag      = 0;
944     tios.c_cc[VMIN]   = 1;
945     tios.c_cc[VTIME]  = 0;
946
947     if (local || !modem)
948         tios.c_cflag ^= (CLOCAL | HUPCL);
949
950     switch (crtscts) {
951     case 1:
952         tios.c_cflag |= CRTSCTS;
953         break;
954
955     case -2:
956         tios.c_iflag     |= IXON | IXOFF;
957         tios.c_cc[VSTOP]  = 0x13;       /* DC3 = XOFF = ^S */
958         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
959         break;
960
961     case -1:
962         tios.c_cflag &= ~CRTSCTS;
963         break;
964
965     default:
966         break;
967     }
968
969     speed = translate_speed(inspeed);
970     if (speed) {
971         cfsetospeed (&tios, speed);
972         cfsetispeed (&tios, speed);
973     }
974 /*
975  * We can't proceed if the serial port speed is B0,
976  * since that implies that the serial port is disabled.
977  */
978     else {
979         speed = cfgetospeed(&tios);
980         if (speed == B0)
981             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
982     }
983
984     while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
985         if (errno != EINTR)
986             fatal("tcsetattr: %m (line %d)", __LINE__);
987
988     baud_rate    = baud_rate_of(speed);
989     restore_term = 1;
990 }
991
992 /********************************************************************
993  *
994  * setdtr - control the DTR line on the serial port.
995  * This is called from die(), so it shouldn't call die().
996  */
997
998 void setdtr (int tty_fd, int on)
999 {
1000     int modembits = TIOCM_DTR;
1001
1002     ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1003 }
1004
1005 /********************************************************************
1006  *
1007  * restore_tty - restore the terminal to the saved settings.
1008  */
1009
1010 void restore_tty (int tty_fd)
1011 {
1012     if (restore_term) {
1013         restore_term = 0;
1014 /*
1015  * Turn off echoing, because otherwise we can get into
1016  * a loop with the tty and the modem echoing to each other.
1017  * We presume we are the sole user of this tty device, so
1018  * when we close it, it will revert to its defaults anyway.
1019  */
1020         if (!default_device)
1021             inittermios.c_lflag &= ~(ECHO | ECHONL);
1022
1023         if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1024             if (! ok_error (errno))
1025                 warn("tcsetattr: %m (line %d)", __LINE__);
1026         }
1027     }
1028 }
1029
1030 /********************************************************************
1031  *
1032  * output - Output PPP packet.
1033  */
1034
1035 void output (int unit, unsigned char *p, int len)
1036 {
1037     int fd = ppp_fd;
1038     int proto;
1039
1040     dump_packet("sent", p, len);
1041     if (snoop_send_hook) snoop_send_hook(p, len);
1042
1043     if (len < PPP_HDRLEN)
1044         return;
1045     if (new_style_driver) {
1046         p += 2;
1047         len -= 2;
1048         proto = (p[0] << 8) + p[1];
1049         if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1050             fd = ppp_dev_fd;
1051     }
1052     if (write(fd, p, len) < 0) {
1053         if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1054             || errno == ENXIO || errno == EIO || errno == EINTR)
1055             warn("write: warning: %m (%d)", errno);
1056         else
1057             error("write: %m (%d)", errno);
1058     }
1059 }
1060
1061 /********************************************************************
1062  *
1063  * wait_input - wait until there is data available,
1064  * for the length of time specified by *timo (indefinite
1065  * if timo is NULL).
1066  */
1067
1068 void wait_input(struct timeval *timo)
1069 {
1070     fd_set ready, exc;
1071     int n;
1072
1073     ready = in_fds;
1074     exc = in_fds;
1075     n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1076     if (n < 0 && errno != EINTR)
1077         fatal("select: %m");
1078 }
1079
1080 /*
1081  * add_fd - add an fd to the set that wait_input waits for.
1082  */
1083 void add_fd(int fd)
1084 {
1085     if (fd >= FD_SETSIZE)
1086         fatal("internal error: file descriptor too large (%d)", fd);
1087     FD_SET(fd, &in_fds);
1088     if (fd > max_in_fd)
1089         max_in_fd = fd;
1090 }
1091
1092 /*
1093  * remove_fd - remove an fd from the set that wait_input waits for.
1094  */
1095 void remove_fd(int fd)
1096 {
1097     FD_CLR(fd, &in_fds);
1098 }
1099
1100
1101 /********************************************************************
1102  *
1103  * read_packet - get a PPP packet from the serial device.
1104  */
1105
1106 int read_packet (unsigned char *buf)
1107 {
1108     int len, nr;
1109
1110     len = PPP_MRU + PPP_HDRLEN;
1111     if (new_style_driver) {
1112         *buf++ = PPP_ALLSTATIONS;
1113         *buf++ = PPP_UI;
1114         len -= 2;
1115     }
1116     nr = -1;
1117     if (ppp_fd >= 0) {
1118         nr = read(ppp_fd, buf, len);
1119         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1120             && errno != EIO && errno != EINTR)
1121             error("read: %m");
1122         if (nr < 0 && errno == ENXIO)
1123             return 0;
1124     }
1125     if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1126         /* N.B. we read ppp_fd first since LCP packets come in there. */
1127         nr = read(ppp_dev_fd, buf, len);
1128         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1129             && errno != EIO && errno != EINTR)
1130             error("read /dev/ppp: %m");
1131         if (nr < 0 && errno == ENXIO)
1132             nr = 0;
1133         if (nr == 0 && doing_multilink) {
1134             remove_fd(ppp_dev_fd);
1135             bundle_eof = 1;
1136         }
1137     }
1138     if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1139         nr = 0;
1140     return (new_style_driver && nr > 0)? nr+2: nr;
1141 }
1142
1143 /********************************************************************
1144  *
1145  * get_loop_output - get outgoing packets from the ppp device,
1146  * and detect when we want to bring the real link up.
1147  * Return value is 1 if we need to bring up the link, 0 otherwise.
1148  */
1149 int
1150 get_loop_output(void)
1151 {
1152     int rv = 0;
1153     int n;
1154
1155     if (new_style_driver) {
1156         while ((n = read_packet(inpacket_buf)) > 0)
1157             if (loop_frame(inpacket_buf, n))
1158                 rv = 1;
1159         return rv;
1160     }
1161
1162     while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1163         if (loop_chars(inbuf, n))
1164             rv = 1;
1165
1166     if (n == 0)
1167         fatal("eof on loopback");
1168
1169     if (errno != EWOULDBLOCK && errno != EAGAIN)
1170         fatal("read from loopback: %m(%d)", errno);
1171
1172     return rv;
1173 }
1174
1175 /*
1176  * netif_set_mtu - set the MTU on the PPP network interface.
1177  */
1178 void
1179 netif_set_mtu(int unit, int mtu)
1180 {
1181     struct ifreq ifr;
1182
1183     memset (&ifr, '\0', sizeof (ifr));
1184     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1185     ifr.ifr_mtu = mtu;
1186
1187     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1188         error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1189 }
1190
1191 /*
1192  * netif_get_mtu - get the MTU on the PPP network interface.
1193  */
1194 int
1195 netif_get_mtu(int unit)
1196 {
1197     struct ifreq ifr;
1198
1199     memset (&ifr, '\0', sizeof (ifr));
1200     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1201
1202     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1203         error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1204         return 0;
1205     }
1206     return ifr.ifr_mtu;
1207 }
1208
1209 /********************************************************************
1210  *
1211  * tty_send_config - configure the transmit characteristics of
1212  * the ppp interface.
1213  */
1214
1215 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1216 {
1217         int x;
1218
1219         if (!still_ppp())
1220                 return;
1221         link_mtu = mtu;
1222         if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1223                 if (errno != EIO && errno != ENOTTY)
1224                         error("Couldn't set transmit async character map: %m");
1225                 ++error_count;
1226                 return;
1227         }
1228
1229         x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1230             | (sync_serial? SC_SYNC: 0);
1231         modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1232 }
1233
1234 /********************************************************************
1235  *
1236  * tty_set_xaccm - set the extended transmit ACCM for the interface.
1237  */
1238
1239 void tty_set_xaccm (ext_accm accm)
1240 {
1241     if (!still_ppp())
1242         return;
1243     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1244         if ( ! ok_error (errno))
1245             warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1246     }
1247 }
1248
1249 /********************************************************************
1250  *
1251  * tty_recv_config - configure the receive-side characteristics of
1252  * the ppp interface.
1253  */
1254
1255 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1256 {
1257 /*
1258  * If we were called because the link has gone down then there is nothing
1259  * which may be done. Just return without incident.
1260  */
1261         if (!still_ppp())
1262                 return;
1263 /*
1264  * Set the receiver parameters
1265  */
1266         if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1267                 if (errno != EIO && errno != ENOTTY)
1268                         error("Couldn't set channel receive MRU: %m");
1269         }
1270         if (new_style_driver && ppp_dev_fd >= 0
1271             && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1272                 error("Couldn't set MRU in generic PPP layer: %m");
1273
1274         if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1275                 if (errno != EIO && errno != ENOTTY)
1276                         error("Couldn't set channel receive asyncmap: %m");
1277         }
1278 }
1279
1280 /********************************************************************
1281  *
1282  * ccp_test - ask kernel whether a given compression method
1283  * is acceptable for use.
1284  */
1285
1286 int
1287 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1288 {
1289     struct ppp_option_data data;
1290
1291     memset (&data, '\0', sizeof (data));
1292     data.ptr      = opt_ptr;
1293     data.length   = opt_len;
1294     data.transmit = for_transmit;
1295
1296     if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1297         return 1;
1298
1299     return (errno == ENOBUFS)? 0: -1;
1300 }
1301
1302 /********************************************************************
1303  *
1304  * ccp_flags_set - inform kernel about the current state of CCP.
1305  */
1306
1307 void ccp_flags_set (int unit, int isopen, int isup)
1308 {
1309         int x;
1310
1311         x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1312         if (still_ppp() && ppp_dev_fd >= 0)
1313                 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1314 }
1315
1316 #ifdef PPP_FILTER
1317 /*
1318  * set_filters - set the active and pass filters in the kernel driver.
1319  */
1320 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1321 {
1322         struct sock_fprog fp;
1323
1324         fp.len = pass->bf_len;
1325         fp.filter = (struct sock_filter *) pass->bf_insns;
1326         if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1327                 if (errno == ENOTTY)
1328                         warn("kernel does not support PPP filtering");
1329                 else
1330                         error("Couldn't set pass-filter in kernel: %m");
1331                 return 0;
1332         }
1333         fp.len = active->bf_len;
1334         fp.filter = (struct sock_filter *) active->bf_insns;
1335         if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1336                 error("Couldn't set active-filter in kernel: %m");
1337                 return 0;
1338         }
1339         return 1;
1340 }
1341 #endif /* PPP_FILTER */
1342
1343 /********************************************************************
1344  *
1345  * get_idle_time - return how long the link has been idle.
1346  */
1347 int
1348 get_idle_time(u, ip)
1349     int u;
1350     struct ppp_idle *ip;
1351 {
1352     return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1353 }
1354
1355 /********************************************************************
1356  *
1357  * get_ppp_stats - return statistics for the link.
1358  */
1359 int
1360 get_ppp_stats(u, stats)
1361     int u;
1362     struct pppd_stats *stats;
1363 {
1364     struct ifpppstatsreq req;
1365
1366     memset (&req, 0, sizeof (req));
1367
1368     req.stats_ptr = (caddr_t) &req.stats;
1369     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1370     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1371         error("Couldn't get PPP statistics: %m");
1372         return 0;
1373     }
1374     stats->bytes_in = req.stats.p.ppp_ibytes;
1375     stats->bytes_out = req.stats.p.ppp_obytes;
1376     stats->pkts_in = req.stats.p.ppp_ipackets;
1377     stats->pkts_out = req.stats.p.ppp_opackets;
1378     return 1;
1379 }
1380
1381 /********************************************************************
1382  *
1383  * ccp_fatal_error - returns 1 if decompression was disabled as a
1384  * result of an error detected after decompression of a packet,
1385  * 0 otherwise.  This is necessary because of patent nonsense.
1386  */
1387
1388 int ccp_fatal_error (int unit)
1389 {
1390         int flags;
1391
1392         if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1393                 error("Couldn't read compression error flags: %m");
1394                 flags = 0;
1395         }
1396         return flags & SC_DC_FERROR;
1397 }
1398
1399 /********************************************************************
1400  *
1401  * path_to_procfs - find the path to the proc file system mount point
1402  */
1403 static char proc_path[MAXPATHLEN];
1404 static int proc_path_len;
1405
1406 static char *path_to_procfs(const char *tail)
1407 {
1408     struct mntent *mntent;
1409     FILE *fp;
1410
1411     if (proc_path_len == 0) {
1412         /* Default the mount location of /proc */
1413         strlcpy (proc_path, "/proc", sizeof(proc_path));
1414         proc_path_len = 5;
1415         fp = fopen(MOUNTED, "r");
1416         if (fp != NULL) {
1417             while ((mntent = getmntent(fp)) != NULL) {
1418                 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1419                     continue;
1420                 if (strcmp(mntent->mnt_type, "proc") == 0) {
1421                     strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1422                     proc_path_len = strlen(proc_path);
1423                     break;
1424                 }
1425             }
1426             fclose (fp);
1427         }
1428     }
1429
1430     strlcpy(proc_path + proc_path_len, tail,
1431             sizeof(proc_path) - proc_path_len);
1432     return proc_path;
1433 }
1434
1435 /*
1436  * /proc/net/route parsing stuff.
1437  */
1438 #define ROUTE_MAX_COLS  12
1439 FILE *route_fd = (FILE *) 0;
1440 static char route_buffer[512];
1441 static int route_dev_col, route_dest_col, route_gw_col;
1442 static int route_flags_col, route_mask_col;
1443 static int route_num_cols;
1444
1445 static int open_route_table (void);
1446 static void close_route_table (void);
1447 static int read_route_table (struct rtentry *rt);
1448
1449 /********************************************************************
1450  *
1451  * close_route_table - close the interface to the route table
1452  */
1453
1454 static void close_route_table (void)
1455 {
1456     if (route_fd != (FILE *) 0) {
1457         fclose (route_fd);
1458         route_fd = (FILE *) 0;
1459     }
1460 }
1461
1462 /********************************************************************
1463  *
1464  * open_route_table - open the interface to the route table
1465  */
1466 static char route_delims[] = " \t\n";
1467
1468 static int open_route_table (void)
1469 {
1470     char *path;
1471
1472     close_route_table();
1473
1474     path = path_to_procfs("/net/route");
1475     route_fd = fopen (path, "r");
1476     if (route_fd == NULL) {
1477         error("can't open routing table %s: %m", path);
1478         return 0;
1479     }
1480
1481     route_dev_col = 0;          /* default to usual columns */
1482     route_dest_col = 1;
1483     route_gw_col = 2;
1484     route_flags_col = 3;
1485     route_mask_col = 7;
1486     route_num_cols = 8;
1487
1488     /* parse header line */
1489     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1490         char *p = route_buffer, *q;
1491         int col;
1492         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1493             int used = 1;
1494             if ((q = strtok(p, route_delims)) == 0)
1495                 break;
1496             if (strcasecmp(q, "iface") == 0)
1497                 route_dev_col = col;
1498             else if (strcasecmp(q, "destination") == 0)
1499                 route_dest_col = col;
1500             else if (strcasecmp(q, "gateway") == 0)
1501                 route_gw_col = col;
1502             else if (strcasecmp(q, "flags") == 0)
1503                 route_flags_col = col;
1504             else if (strcasecmp(q, "mask") == 0)
1505                 route_mask_col = col;
1506             else
1507                 used = 0;
1508             if (used && col >= route_num_cols)
1509                 route_num_cols = col + 1;
1510             p = NULL;
1511         }
1512     }
1513
1514     return 1;
1515 }
1516
1517 /********************************************************************
1518  *
1519  * read_route_table - read the next entry from the route table
1520  */
1521
1522 static int read_route_table(struct rtentry *rt)
1523 {
1524     char *cols[ROUTE_MAX_COLS], *p;
1525     int col;
1526
1527     memset (rt, '\0', sizeof (struct rtentry));
1528
1529     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1530         return 0;
1531
1532     p = route_buffer;
1533     for (col = 0; col < route_num_cols; ++col) {
1534         cols[col] = strtok(p, route_delims);
1535         if (cols[col] == NULL)
1536             return 0;           /* didn't get enough columns */
1537         p = NULL;
1538     }
1539
1540     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1541     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1542     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1543
1544     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1545     rt->rt_dev   = cols[route_dev_col];
1546
1547     return 1;
1548 }
1549
1550 /********************************************************************
1551  *
1552  * defaultroute_exists - determine if there is a default route
1553  */
1554
1555 static int defaultroute_exists (struct rtentry *rt)
1556 {
1557     int result = 0;
1558
1559     if (!open_route_table())
1560         return 0;
1561
1562     while (read_route_table(rt) != 0) {
1563         if ((rt->rt_flags & RTF_UP) == 0)
1564             continue;
1565
1566         if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1567             continue;
1568         if (SIN_ADDR(rt->rt_dst) == 0L) {
1569             result = 1;
1570             break;
1571         }
1572     }
1573
1574     close_route_table();
1575     return result;
1576 }
1577
1578 /*
1579  * have_route_to - determine if the system has any route to
1580  * a given IP address.  `addr' is in network byte order.
1581  * Return value is 1 if yes, 0 if no, -1 if don't know.
1582  * For demand mode to work properly, we have to ignore routes
1583  * through our own interface.
1584  */
1585 int have_route_to(u_int32_t addr)
1586 {
1587     struct rtentry rt;
1588     int result = 0;
1589
1590     if (!open_route_table())
1591         return -1;              /* don't know */
1592
1593     while (read_route_table(&rt)) {
1594         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1595             continue;
1596         if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1597             result = 1;
1598             break;
1599         }
1600     }
1601
1602     close_route_table();
1603     return result;
1604 }
1605
1606 /********************************************************************
1607  *
1608  * sifdefaultroute - assign a default route through the address given.
1609  */
1610
1611 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1612 {
1613     struct rtentry rt;
1614
1615     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1616         if (rt.rt_flags & RTF_GATEWAY)
1617             error("not replacing existing default route via %I",
1618                   SIN_ADDR(rt.rt_gateway));
1619         else
1620             error("not replacing existing default route through %s",
1621                   rt.rt_dev);
1622         return 0;
1623     }
1624
1625     memset (&rt, 0, sizeof (rt));
1626     SET_SA_FAMILY (rt.rt_dst, AF_INET);
1627
1628     rt.rt_dev = ifname;
1629
1630     if (kernel_version > KVERSION(2,1,0)) {
1631         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1632         SIN_ADDR(rt.rt_genmask) = 0L;
1633     }
1634
1635     rt.rt_flags = RTF_UP;
1636     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1637         if ( ! ok_error ( errno ))
1638             error("default route ioctl(SIOCADDRT): %m");
1639         return 0;
1640     }
1641
1642     have_default_route = 1;
1643     return 1;
1644 }
1645
1646 /********************************************************************
1647  *
1648  * cifdefaultroute - delete a default route through the address given.
1649  */
1650
1651 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1652 {
1653     struct rtentry rt;
1654
1655     have_default_route = 0;
1656
1657     memset (&rt, '\0', sizeof (rt));
1658     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1659     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1660
1661     if (kernel_version > KVERSION(2,1,0)) {
1662         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1663         SIN_ADDR(rt.rt_genmask) = 0L;
1664     }
1665
1666     rt.rt_flags = RTF_UP;
1667     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1668         if (still_ppp()) {
1669             if ( ! ok_error ( errno ))
1670                 error("default route ioctl(SIOCDELRT): %m");
1671             return 0;
1672         }
1673     }
1674
1675     return 1;
1676 }
1677
1678 /********************************************************************
1679  *
1680  * sifproxyarp - Make a proxy ARP entry for the peer.
1681  */
1682
1683 int sifproxyarp (int unit, u_int32_t his_adr)
1684 {
1685     struct arpreq arpreq;
1686     char *forw_path;
1687
1688     if (has_proxy_arp == 0) {
1689         memset (&arpreq, '\0', sizeof(arpreq));
1690
1691         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1692         SIN_ADDR(arpreq.arp_pa) = his_adr;
1693         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1694 /*
1695  * Get the hardware address of an interface on the same subnet
1696  * as our local address.
1697  */
1698         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1699                             sizeof(proxy_arp_dev))) {
1700             error("Cannot determine ethernet address for proxy ARP");
1701             return 0;
1702         }
1703         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1704
1705         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1706             if ( ! ok_error ( errno ))
1707                 error("ioctl(SIOCSARP): %m");
1708             return 0;
1709         }
1710         proxy_arp_addr = his_adr;
1711         has_proxy_arp = 1;
1712
1713         if (tune_kernel) {
1714             forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1715             if (forw_path != 0) {
1716                 int fd = open(forw_path, O_WRONLY);
1717                 if (fd >= 0) {
1718                     if (write(fd, "1", 1) != 1)
1719                         error("Couldn't enable IP forwarding: %m");
1720                     close(fd);
1721                 }
1722             }
1723         }
1724     }
1725
1726     return 1;
1727 }
1728
1729 /********************************************************************
1730  *
1731  * cifproxyarp - Delete the proxy ARP entry for the peer.
1732  */
1733
1734 int cifproxyarp (int unit, u_int32_t his_adr)
1735 {
1736     struct arpreq arpreq;
1737
1738     if (has_proxy_arp) {
1739         has_proxy_arp = 0;
1740         memset (&arpreq, '\0', sizeof(arpreq));
1741         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1742         SIN_ADDR(arpreq.arp_pa) = his_adr;
1743         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1744         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1745
1746         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1747             if ( ! ok_error ( errno ))
1748                 warn("ioctl(SIOCDARP): %m");
1749             return 0;
1750         }
1751     }
1752     return 1;
1753 }
1754
1755 /********************************************************************
1756  *
1757  * get_ether_addr - get the hardware address of an interface on the
1758  * the same subnet as ipaddr.
1759  */
1760
1761 static int get_ether_addr (u_int32_t ipaddr,
1762                            struct sockaddr *hwaddr,
1763                            char *name, int namelen)
1764 {
1765     struct ifreq *ifr, *ifend;
1766     u_int32_t ina, mask;
1767     char *aliasp;
1768     struct ifreq ifreq, bestifreq;
1769     struct ifconf ifc;
1770     struct ifreq ifs[MAX_IFS];
1771
1772     u_int32_t bestmask=0;
1773     int found_interface = 0;
1774
1775     ifc.ifc_len = sizeof(ifs);
1776     ifc.ifc_req = ifs;
1777     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1778         if ( ! ok_error ( errno ))
1779             error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1780         return 0;
1781     }
1782
1783 /*
1784  * Scan through looking for an interface with an Internet
1785  * address on the same subnet as `ipaddr'.
1786  */
1787     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1788     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1789         if (ifr->ifr_addr.sa_family == AF_INET) {
1790             ina = SIN_ADDR(ifr->ifr_addr);
1791             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1792 /*
1793  * Check that the interface is up, and not point-to-point
1794  * nor loopback.
1795  */
1796             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1797                 continue;
1798
1799             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1800                 continue;
1801 /*
1802  * Get its netmask and check that it's on the right subnet.
1803  */
1804             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1805                 continue;
1806
1807             mask = SIN_ADDR(ifreq.ifr_addr);
1808
1809             if (((ipaddr ^ ina) & mask) != 0)
1810                 continue; /* no match */
1811             /* matched */
1812             if (mask >= bestmask) {
1813                 /* Compare using >= instead of > -- it is possible for
1814                    an interface to have a netmask of 0.0.0.0 */
1815                 found_interface = 1;
1816                 bestifreq = ifreq;
1817                 bestmask = mask;
1818             }
1819         }
1820     }
1821
1822     if (!found_interface) return 0;
1823
1824     strlcpy(name, bestifreq.ifr_name, namelen);
1825
1826     /* trim off the :1 in eth0:1 */
1827     aliasp = strchr(name, ':');
1828     if (aliasp != 0)
1829         *aliasp = 0;
1830
1831     info("found interface %s for proxy arp", name);
1832 /*
1833  * Now get the hardware address.
1834  */
1835     memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1836     if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1837         error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1838         return 0;
1839     }
1840
1841     memcpy (hwaddr,
1842             &bestifreq.ifr_hwaddr,
1843             sizeof (struct sockaddr));
1844
1845     return 1;
1846 }
1847
1848 /*
1849  * get_if_hwaddr - get the hardware address for the specified
1850  * network interface device.
1851  */
1852 int
1853 get_if_hwaddr(u_char *addr, char *name)
1854 {
1855         struct ifreq ifreq;
1856         int ret, sock_fd;
1857
1858         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1859         if (sock_fd < 0)
1860                 return 0;
1861         memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1862         strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1863         ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1864         close(sock_fd);
1865         if (ret >= 0)
1866                 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1867         return ret;
1868 }
1869
1870 /*
1871  * get_first_ethernet - return the name of the first ethernet-style
1872  * interface on this system.
1873  */
1874 char *
1875 get_first_ethernet()
1876 {
1877         return "eth0";
1878 }
1879
1880 /********************************************************************
1881  *
1882  * Return user specified netmask, modified by any mask we might determine
1883  * for address `addr' (in network byte order).
1884  * Here we scan through the system's list of interfaces, looking for
1885  * any non-point-to-point interfaces which might appear to be on the same
1886  * network as `addr'.  If we find any, we OR in their netmask to the
1887  * user-specified netmask.
1888  */
1889
1890 u_int32_t GetMask (u_int32_t addr)
1891 {
1892     u_int32_t mask, nmask, ina;
1893     struct ifreq *ifr, *ifend, ifreq;
1894     struct ifconf ifc;
1895     struct ifreq ifs[MAX_IFS];
1896
1897     addr = ntohl(addr);
1898
1899     if (IN_CLASSA(addr))        /* determine network mask for address class */
1900         nmask = IN_CLASSA_NET;
1901     else if (IN_CLASSB(addr))
1902             nmask = IN_CLASSB_NET;
1903     else
1904             nmask = IN_CLASSC_NET;
1905
1906     /* class D nets are disallowed by bad_ip_adrs */
1907     mask = netmask | htonl(nmask);
1908 /*
1909  * Scan through the system's network interfaces.
1910  */
1911     ifc.ifc_len = sizeof(ifs);
1912     ifc.ifc_req = ifs;
1913     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1914         if ( ! ok_error ( errno ))
1915             warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1916         return mask;
1917     }
1918
1919     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1920     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1921 /*
1922  * Check the interface's internet address.
1923  */
1924         if (ifr->ifr_addr.sa_family != AF_INET)
1925             continue;
1926         ina = SIN_ADDR(ifr->ifr_addr);
1927         if (((ntohl(ina) ^ addr) & nmask) != 0)
1928             continue;
1929 /*
1930  * Check that the interface is up, and not point-to-point nor loopback.
1931  */
1932         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1933         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1934             continue;
1935
1936         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1937             continue;
1938 /*
1939  * Get its netmask and OR it into our mask.
1940  */
1941         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1942             continue;
1943         mask |= SIN_ADDR(ifreq.ifr_addr);
1944         break;
1945     }
1946     return mask;
1947 }
1948
1949 /********************************************************************
1950  *
1951  * Internal routine to decode the version.modification.patch level
1952  */
1953
1954 static void decode_version (char *buf, int *version,
1955                             int *modification, int *patch)
1956 {
1957     char *endp;
1958
1959     *version      = (int) strtoul (buf, &endp, 10);
1960     *modification = 0;
1961     *patch        = 0;
1962
1963     if (endp != buf && *endp == '.') {
1964         buf = endp + 1;
1965         *modification = (int) strtoul (buf, &endp, 10);
1966         if (endp != buf && *endp == '.') {
1967             buf = endp + 1;
1968             *patch = (int) strtoul (buf, &buf, 10);
1969         }
1970     }
1971 }
1972
1973 /********************************************************************
1974  *
1975  * Procedure to determine if the PPP line discipline is registered.
1976  */
1977
1978 static int
1979 ppp_registered(void)
1980 {
1981     int local_fd;
1982     int mfd = -1;
1983     int ret = 0;
1984     char slave[16];
1985
1986     /*
1987      * We used to open the serial device and set it to the ppp line
1988      * discipline here, in order to create a ppp unit.  But that is
1989      * not a good idea - the user might have specified a device that
1990      * they can't open (permission, or maybe it doesn't really exist).
1991      * So we grab a pty master/slave pair and use that.
1992      */
1993     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1994         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1995         return 0;
1996     }
1997
1998     /*
1999      * Try to put the device into the PPP discipline.
2000      */
2001     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2002         error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2003     } else
2004         ret = 1;
2005
2006     close(local_fd);
2007     close(mfd);
2008     return ret;
2009 }
2010
2011 /********************************************************************
2012  *
2013  * ppp_available - check whether the system has any ppp interfaces
2014  * (in fact we check whether we can do an ioctl on ppp0).
2015  */
2016
2017 int ppp_available(void)
2018 {
2019     int s, ok, fd, err;
2020     struct ifreq ifr;
2021     int    size;
2022     int    my_version, my_modification, my_patch;
2023     int osmaj, osmin, ospatch;
2024
2025     /* get the kernel version now, since we are called before sys_init */
2026     uname(&utsname);
2027     osmaj = osmin = ospatch = 0;
2028     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2029     kernel_version = KVERSION(osmaj, osmin, ospatch);
2030
2031     fd = open("/dev/ppp", O_RDWR);
2032     if (fd >= 0) {
2033         new_style_driver = 1;
2034
2035         /* XXX should get from driver */
2036         driver_version = 2;
2037         driver_modification = 4;
2038         driver_patch = 0;
2039         close(fd);
2040         return 1;
2041     }
2042     err = errno;
2043
2044     if (kernel_version >= KVERSION(2,3,13)) {
2045         error("Couldn't open the /dev/ppp device: %m");
2046         if (errno == ENOENT)
2047             no_ppp_msg =
2048                 "You need to create the /dev/ppp device node by\n"
2049                 "executing the following command as root:\n"
2050                 "       mknod /dev/ppp c 108 0\n";
2051         else if (errno == ENODEV || errno == ENXIO)
2052             no_ppp_msg =
2053                 "Please load the ppp_generic kernel module.\n";
2054         return 0;
2055     }
2056
2057     /* we are running on a really really old kernel */
2058     no_ppp_msg =
2059         "This system lacks kernel support for PPP.  This could be because\n"
2060         "the PPP kernel module could not be loaded, or because PPP was not\n"
2061         "included in the kernel configuration.  If PPP was included as a\n"
2062         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2063         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2064         "See README.linux file in the ppp distribution for more details.\n";
2065
2066 /*
2067  * Open a socket for doing the ioctl operations.
2068  */
2069     s = socket(AF_INET, SOCK_DGRAM, 0);
2070     if (s < 0)
2071         return 0;
2072
2073     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2074     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2075 /*
2076  * If the device did not exist then attempt to create one by putting the
2077  * current tty into the PPP discipline. If this works then obtain the
2078  * flags for the device again.
2079  */
2080     if (!ok) {
2081         if (ppp_registered()) {
2082             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2083             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2084         }
2085     }
2086 /*
2087  * Ensure that the hardware address is for PPP and not something else
2088  */
2089     if (ok)
2090         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2091
2092     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2093         ok = 0;
2094
2095 /*
2096  *  This is the PPP device. Validate the version of the driver at this
2097  *  point to ensure that this program will work with the driver.
2098  */
2099     if (ok) {
2100         char   abBuffer [1024];
2101
2102         ifr.ifr_data = abBuffer;
2103         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2104         if (size < 0) {
2105             error("Couldn't read driver version: %m");
2106             ok = 0;
2107             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2108
2109         } else {
2110             decode_version(abBuffer,
2111                            &driver_version,
2112                            &driver_modification,
2113                            &driver_patch);
2114 /*
2115  * Validate the version of the driver against the version that we used.
2116  */
2117             decode_version(VERSION,
2118                            &my_version,
2119                            &my_modification,
2120                            &my_patch);
2121
2122             /* The version numbers must match */
2123             if (driver_version != my_version)
2124                 ok = 0;
2125
2126             /* The modification levels must be legal */
2127             if (driver_modification < 3) {
2128                 if (driver_modification >= 2) {
2129                     /* we can cope with 2.2.0 and above */
2130                     driver_is_old = 1;
2131                 } else {
2132                     ok = 0;
2133                 }
2134             }
2135
2136             close (s);
2137             if (!ok) {
2138                 slprintf(route_buffer, sizeof(route_buffer),
2139                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
2140                          driver_version, driver_modification, driver_patch);
2141
2142                 no_ppp_msg = route_buffer;
2143             }
2144         }
2145     }
2146     return ok;
2147 }
2148
2149 /********************************************************************
2150  *
2151  * Update the wtmp file with the appropriate user name and tty device.
2152  */
2153
2154 void logwtmp (const char *line, const char *name, const char *host)
2155 {
2156     struct utmp ut, *utp;
2157     pid_t  mypid = getpid();
2158 #if __GLIBC__ < 2
2159     int    wtmp;
2160 #endif
2161
2162 /*
2163  * Update the signon database for users.
2164  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2165  */
2166     utmpname(_PATH_UTMP);
2167     setutent();
2168     while ((utp = getutent()) && (utp->ut_pid != mypid))
2169         /* nothing */;
2170
2171     if (utp)
2172         memcpy(&ut, utp, sizeof(ut));
2173     else
2174         /* some gettys/telnetds don't initialize utmp... */
2175         memset(&ut, 0, sizeof(ut));
2176
2177     if (ut.ut_id[0] == 0)
2178         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2179
2180     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2181     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2182
2183     time(&ut.ut_time);
2184
2185     ut.ut_type = USER_PROCESS;
2186     ut.ut_pid  = mypid;
2187
2188     /* Insert the host name if one is supplied */
2189     if (*host)
2190         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2191
2192     /* Insert the IP address of the remote system if IP is enabled */
2193     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2194         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2195                  sizeof(ut.ut_addr));
2196
2197     /* CL: Makes sure that the logout works */
2198     if (*host == 0 && *name==0)
2199         ut.ut_host[0]=0;
2200
2201     pututline(&ut);
2202     endutent();
2203 /*
2204  * Update the wtmp file.
2205  */
2206 #if __GLIBC__ >= 2
2207     updwtmp(_PATH_WTMP, &ut);
2208 #else
2209     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2210     if (wtmp >= 0) {
2211         flock(wtmp, LOCK_EX);
2212
2213         if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2214             warn("error writing %s: %m", _PATH_WTMP);
2215
2216         flock(wtmp, LOCK_UN);
2217
2218         close (wtmp);
2219     }
2220 #endif
2221 }
2222
2223
2224 /********************************************************************
2225  *
2226  * sifvjcomp - config tcp header compression
2227  */
2228
2229 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2230 {
2231         u_int x;
2232
2233         if (vjcomp) {
2234                 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2235                         error("Couldn't set up TCP header compression: %m");
2236                 vjcomp = 0;
2237         }
2238
2239         x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2240         modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2241
2242         return 1;
2243 }
2244
2245 /********************************************************************
2246  *
2247  * sifup - Config the interface up and enable IP packets to pass.
2248  */
2249
2250 int sifup(int u)
2251 {
2252     struct ifreq ifr;
2253
2254     memset (&ifr, '\0', sizeof (ifr));
2255     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2256     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2257         if (! ok_error (errno))
2258             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2259         return 0;
2260     }
2261
2262     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2263     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2264         if (! ok_error (errno))
2265             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2266         return 0;
2267     }
2268     if_is_up++;
2269
2270     return 1;
2271 }
2272
2273 /********************************************************************
2274  *
2275  * sifdown - Disable the indicated protocol and config the interface
2276  *           down if there are no remaining protocols.
2277  */
2278
2279 int sifdown (int u)
2280 {
2281     struct ifreq ifr;
2282
2283     if (if_is_up && --if_is_up > 0)
2284         return 1;
2285
2286     memset (&ifr, '\0', sizeof (ifr));
2287     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2288     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2289         if (! ok_error (errno))
2290             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2291         return 0;
2292     }
2293
2294     ifr.ifr_flags &= ~IFF_UP;
2295     ifr.ifr_flags |= IFF_POINTOPOINT;
2296     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2297         if (! ok_error (errno))
2298             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2299         return 0;
2300     }
2301     return 1;
2302 }
2303
2304 /********************************************************************
2305  *
2306  * sifaddr - Config the interface IP addresses and netmask.
2307  */
2308
2309 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2310              u_int32_t net_mask)
2311 {
2312     struct ifreq   ifr;
2313     struct rtentry rt;
2314
2315     memset (&ifr, '\0', sizeof (ifr));
2316     memset (&rt,  '\0', sizeof (rt));
2317
2318     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET);
2319     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2320     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2321
2322     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2323 /*
2324  *  Set our IP address
2325  */
2326     SIN_ADDR(ifr.ifr_addr) = our_adr;
2327     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2328         if (errno != EEXIST) {
2329             if (! ok_error (errno))
2330                 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2331         }
2332         else {
2333             warn("ioctl(SIOCSIFADDR): Address already exists");
2334         }
2335         return (0);
2336     }
2337 /*
2338  *  Set the gateway address
2339  */
2340     if (his_adr != 0) {
2341         SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2342         if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2343             if (! ok_error (errno))
2344                 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2345             return (0);
2346         }
2347     }
2348 /*
2349  *  Set the netmask.
2350  *  For recent kernels, force the netmask to 255.255.255.255.
2351  */
2352     if (kernel_version >= KVERSION(2,1,16))
2353         net_mask = ~0L;
2354     if (net_mask != 0) {
2355         SIN_ADDR(ifr.ifr_netmask) = net_mask;
2356         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2357             if (! ok_error (errno))
2358                 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2359             return (0);
2360         }
2361     }
2362 /*
2363  *  Add the device route
2364  */
2365     if (kernel_version < KVERSION(2,1,16)) {
2366         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2367         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2368         rt.rt_dev = ifname;
2369
2370         SIN_ADDR(rt.rt_gateway) = 0L;
2371         SIN_ADDR(rt.rt_dst)     = his_adr;
2372         rt.rt_flags = RTF_UP | RTF_HOST;
2373
2374         if (kernel_version > KVERSION(2,1,0)) {
2375             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2376             SIN_ADDR(rt.rt_genmask) = -1L;
2377         }
2378
2379         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2380             if (! ok_error (errno))
2381                 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2382             return (0);
2383         }
2384     }
2385
2386     /* set ip_dynaddr in demand mode if address changes */
2387     if (demand && tune_kernel && !dynaddr_set
2388         && our_old_addr && our_old_addr != our_adr) {
2389         /* set ip_dynaddr if possible */
2390         char *path;
2391         int fd;
2392
2393         path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2394         if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2395             if (write(fd, "1", 1) != 1)
2396                 error("Couldn't enable dynamic IP addressing: %m");
2397             close(fd);
2398         }
2399         dynaddr_set = 1;        /* only 1 attempt */
2400     }
2401     our_old_addr = 0;
2402
2403     return 1;
2404 }
2405
2406 /********************************************************************
2407  *
2408  * cifaddr - Clear the interface IP addresses, and delete routes
2409  * through the interface if possible.
2410  */
2411
2412 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2413 {
2414     struct ifreq ifr;
2415
2416     if (kernel_version < KVERSION(2,1,16)) {
2417 /*
2418  *  Delete the route through the device
2419  */
2420         struct rtentry rt;
2421         memset (&rt, '\0', sizeof (rt));
2422
2423         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2424         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2425         rt.rt_dev = ifname;
2426
2427         SIN_ADDR(rt.rt_gateway) = 0;
2428         SIN_ADDR(rt.rt_dst)     = his_adr;
2429         rt.rt_flags = RTF_UP | RTF_HOST;
2430
2431         if (kernel_version > KVERSION(2,1,0)) {
2432             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2433             SIN_ADDR(rt.rt_genmask) = -1L;
2434         }
2435
2436         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2437             if (still_ppp() && ! ok_error (errno))
2438                 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2439             return (0);
2440         }
2441     }
2442
2443     /* This way it is possible to have an IPX-only or IPv6-only interface */
2444     memset(&ifr, 0, sizeof(ifr));
2445     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2446     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2447
2448     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2449         if (! ok_error (errno)) {
2450             error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2451             return 0;
2452         }
2453     }
2454
2455     our_old_addr = our_adr;
2456
2457     return 1;
2458 }
2459
2460 #ifdef INET6
2461 /********************************************************************
2462  *
2463  * sif6addr - Config the interface with an IPv6 link-local address
2464  */
2465 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2466 {
2467     struct in6_ifreq ifr6;
2468     struct ifreq ifr;
2469     struct in6_rtmsg rt6;
2470
2471     if (sock6_fd < 0) {
2472         errno = -sock6_fd;
2473         error("IPv6 socket creation failed: %m");
2474         return 0;
2475     }
2476     memset(&ifr, 0, sizeof (ifr));
2477     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2478     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2479         error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2480         return 0;
2481     }
2482
2483     /* Local interface */
2484     memset(&ifr6, 0, sizeof(ifr6));
2485     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2486     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2487     ifr6.ifr6_prefixlen = 10;
2488
2489     if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2490         error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2491         return 0;
2492     }
2493
2494     /* Route to remote host */
2495     memset(&rt6, 0, sizeof(rt6));
2496     IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2497     rt6.rtmsg_flags = RTF_UP;
2498     rt6.rtmsg_dst_len = 10;
2499     rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2500     rt6.rtmsg_metric = 1;
2501
2502     if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2503         error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2504         return 0;
2505     }
2506
2507     return 1;
2508 }
2509
2510
2511 /********************************************************************
2512  *
2513  * cif6addr - Remove IPv6 address from interface
2514  */
2515 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2516 {
2517     struct ifreq ifr;
2518     struct in6_ifreq ifr6;
2519
2520     if (sock6_fd < 0) {
2521         errno = -sock6_fd;
2522         error("IPv6 socket creation failed: %m");
2523         return 0;
2524     }
2525     memset(&ifr, 0, sizeof(ifr));
2526     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2527     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2528         error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2529         return 0;
2530     }
2531
2532     memset(&ifr6, 0, sizeof(ifr6));
2533     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2534     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2535     ifr6.ifr6_prefixlen = 10;
2536
2537     if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2538         if (errno != EADDRNOTAVAIL) {
2539             if (! ok_error (errno))
2540                 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2541         }
2542         else {
2543             warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2544         }
2545         return (0);
2546     }
2547     return 1;
2548 }
2549 #endif /* INET6 */
2550
2551 /*
2552  * get_pty - get a pty master/slave pair and chown the slave side
2553  * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
2554  */
2555 int
2556 get_pty(master_fdp, slave_fdp, slave_name, uid)
2557     int *master_fdp;
2558     int *slave_fdp;
2559     char *slave_name;
2560     int uid;
2561 {
2562     int i, mfd, sfd = -1;
2563     char pty_name[16];
2564     struct termios tios;
2565
2566 #ifdef TIOCGPTN
2567     /*
2568      * Try the unix98 way first.
2569      */
2570     mfd = open("/dev/ptmx", O_RDWR);
2571     if (mfd >= 0) {
2572         int ptn;
2573         if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2574             slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2575             chmod(pty_name, S_IRUSR | S_IWUSR);
2576 #ifdef TIOCSPTLCK
2577             ptn = 0;
2578             if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2579                 warn("Couldn't unlock pty slave %s: %m", pty_name);
2580 #endif
2581             if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2582                 warn("Couldn't open pty slave %s: %m", pty_name);
2583         }
2584     }
2585 #endif /* TIOCGPTN */
2586
2587     if (sfd < 0) {
2588         /* the old way - scan through the pty name space */
2589         for (i = 0; i < 64; ++i) {
2590             slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2591                      'p' + i / 16, i % 16);
2592             mfd = open(pty_name, O_RDWR, 0);
2593             if (mfd >= 0) {
2594                 pty_name[5] = 't';
2595                 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2596                 if (sfd >= 0) {
2597                     fchown(sfd, uid, -1);
2598                     fchmod(sfd, S_IRUSR | S_IWUSR);
2599                     break;
2600                 }
2601                 close(mfd);
2602             }
2603         }
2604     }
2605
2606     if (sfd < 0)
2607         return 0;
2608
2609     strlcpy(slave_name, pty_name, 16);
2610     *master_fdp = mfd;
2611     *slave_fdp = sfd;
2612     if (tcgetattr(sfd, &tios) == 0) {
2613         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2614         tios.c_cflag |= CS8 | CREAD | CLOCAL;
2615         tios.c_iflag  = IGNPAR;
2616         tios.c_oflag  = 0;
2617         tios.c_lflag  = 0;
2618         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2619             warn("couldn't set attributes on pty: %m");
2620     } else
2621         warn("couldn't get attributes on pty: %m");
2622
2623     return 1;
2624 }
2625
2626 /********************************************************************
2627  *
2628  * open_loopback - open the device we use for getting packets
2629  * in demand mode.  Under Linux, we use a pty master/slave pair.
2630  */
2631 int
2632 open_ppp_loopback(void)
2633 {
2634     int flags;
2635
2636     looped = 1;
2637     if (new_style_driver) {
2638         /* allocate ourselves a ppp unit */
2639         if (make_ppp_unit() < 0)
2640             die(1);
2641         modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2642         set_kdebugflag(kdebugflag);
2643         ppp_fd = -1;
2644         return ppp_dev_fd;
2645     }
2646
2647     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2648         fatal("No free pty for loopback");
2649
2650     set_ppp_fd(slave_fd);
2651
2652     flags = fcntl(master_fd, F_GETFL);
2653     if (flags == -1 ||
2654         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2655         warn("couldn't set master loopback to nonblock: %m");
2656
2657     flags = fcntl(ppp_fd, F_GETFL);
2658     if (flags == -1 ||
2659         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2660         warn("couldn't set slave loopback to nonblock: %m");
2661
2662     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2663         fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2664 /*
2665  * Find out which interface we were given.
2666  */
2667     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2668         fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2669 /*
2670  * Enable debug in the driver if requested.
2671  */
2672     set_kdebugflag (kdebugflag);
2673
2674     return master_fd;
2675 }
2676
2677 /********************************************************************
2678  *
2679  * sifnpmode - Set the mode for handling packets for a given NP.
2680  */
2681
2682 int
2683 sifnpmode(u, proto, mode)
2684     int u;
2685     int proto;
2686     enum NPmode mode;
2687 {
2688     struct npioctl npi;
2689
2690     npi.protocol = proto;
2691     npi.mode     = mode;
2692     if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2693         if (! ok_error (errno))
2694             error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2695         return 0;
2696     }
2697     return 1;
2698 }
2699
2700 \f
2701 /********************************************************************
2702  *
2703  * sipxfaddr - Config the interface IPX networknumber
2704  */
2705
2706 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2707 {
2708     int    result = 1;
2709
2710 #ifdef IPX_CHANGE
2711     int    skfd;
2712     struct ifreq         ifr;
2713     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2714
2715     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2716     if (skfd < 0) {
2717         if (! ok_error (errno))
2718             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2719         result = 0;
2720     }
2721     else {
2722         memset (&ifr, '\0', sizeof (ifr));
2723         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2724
2725         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2726         sipx->sipx_family  = AF_IPX;
2727         sipx->sipx_port    = 0;
2728         sipx->sipx_network = htonl (network);
2729         sipx->sipx_type    = IPX_FRAME_ETHERII;
2730         sipx->sipx_action  = IPX_CRTITF;
2731 /*
2732  *  Set the IPX device
2733  */
2734         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2735             result = 0;
2736             if (errno != EEXIST) {
2737                 if (! ok_error (errno))
2738                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2739             }
2740             else {
2741                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2742             }
2743         }
2744         close (skfd);
2745     }
2746 #endif
2747     return result;
2748 }
2749
2750 /********************************************************************
2751  *
2752  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2753  *             are removed and the device is no longer able to pass IPX
2754  *             frames.
2755  */
2756
2757 int cipxfaddr (int unit)
2758 {
2759     int    result = 1;
2760
2761 #ifdef IPX_CHANGE
2762     int    skfd;
2763     struct ifreq         ifr;
2764     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2765
2766     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2767     if (skfd < 0) {
2768         if (! ok_error (errno))
2769             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2770         result = 0;
2771     }
2772     else {
2773         memset (&ifr, '\0', sizeof (ifr));
2774         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2775
2776         sipx->sipx_type    = IPX_FRAME_ETHERII;
2777         sipx->sipx_action  = IPX_DLTITF;
2778         sipx->sipx_family  = AF_IPX;
2779 /*
2780  *  Set the IPX device
2781  */
2782         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2783             if (! ok_error (errno))
2784                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2785             result = 0;
2786         }
2787         close (skfd);
2788     }
2789 #endif
2790     return result;
2791 }
2792
2793 /*
2794  * Use the hostname as part of the random number seed.
2795  */
2796 int
2797 get_host_seed()
2798 {
2799     int h;
2800     char *p = hostname;
2801
2802     h = 407;
2803     for (p = hostname; *p != 0; ++p)
2804         h = h * 37 + *p;
2805     return h;
2806 }
2807
2808 /********************************************************************
2809  *
2810  * sys_check_options - check the options that the user specified
2811  */
2812
2813 int
2814 sys_check_options(void)
2815 {
2816 #ifdef IPX_CHANGE
2817 /*
2818  * Disable the IPX protocol if the support is not present in the kernel.
2819  */
2820     char *path;
2821
2822     if (ipxcp_protent.enabled_flag) {
2823         struct stat stat_buf;
2824         if (  ((path = path_to_procfs("/net/ipx/interface")) == NULL
2825             && (path = path_to_procfs("/net/ipx_interface")) == NULL)
2826             || lstat(path, &stat_buf) < 0) {
2827             error("IPX support is not present in the kernel\n");
2828             ipxcp_protent.enabled_flag = 0;
2829         }
2830     }
2831 #endif
2832     if (demand && driver_is_old) {
2833         option_error("demand dialling is not supported by kernel driver "
2834                      "version %d.%d.%d", driver_version, driver_modification,
2835                      driver_patch);
2836         return 0;
2837     }
2838     if (multilink && !new_style_driver) {
2839         warn("Warning: multilink is not supported by the kernel driver");
2840         multilink = 0;
2841     }
2842     return 1;
2843 }
2844
2845 #ifdef INET6
2846 /*
2847  * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2848  *
2849  * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2850  * that the system has a properly configured Ethernet interface for this
2851  * function to return non-zero.
2852  */
2853 int
2854 ether_to_eui64(eui64_t *p_eui64)
2855 {
2856     struct ifreq ifr;
2857     int skfd;
2858     const unsigned char *ptr;
2859
2860     skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2861     if(skfd == -1)
2862     {
2863         warn("could not open IPv6 socket");
2864         return 0;
2865     }
2866
2867     strcpy(ifr.ifr_name, "eth0");
2868     if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2869     {
2870         close(skfd);
2871         warn("could not obtain hardware address for eth0");
2872         return 0;
2873     }
2874     close(skfd);
2875
2876     /*
2877      * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2878      */
2879     ptr = ifr.ifr_hwaddr.sa_data;
2880     p_eui64->e8[0] = ptr[0] | 0x02;
2881     p_eui64->e8[1] = ptr[1];
2882     p_eui64->e8[2] = ptr[2];
2883     p_eui64->e8[3] = 0xFF;
2884     p_eui64->e8[4] = 0xFE;
2885     p_eui64->e8[5] = ptr[3];
2886     p_eui64->e8[6] = ptr[4];
2887     p_eui64->e8[7] = ptr[5];
2888
2889     return 1;
2890 }
2891 #endif