]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
pppd: Add option "stop-bits" to set number of serial port stop bits.
[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     if (stop_bits >= 2)
970         tios.c_cflag |= CSTOPB;
971
972     speed = translate_speed(inspeed);
973     if (speed) {
974         cfsetospeed (&tios, speed);
975         cfsetispeed (&tios, speed);
976     }
977 /*
978  * We can't proceed if the serial port speed is B0,
979  * since that implies that the serial port is disabled.
980  */
981     else {
982         speed = cfgetospeed(&tios);
983         if (speed == B0)
984             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
985     }
986
987     while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
988         if (errno != EINTR)
989             fatal("tcsetattr: %m (line %d)", __LINE__);
990
991     baud_rate    = baud_rate_of(speed);
992     restore_term = 1;
993 }
994
995 /********************************************************************
996  *
997  * setdtr - control the DTR line on the serial port.
998  * This is called from die(), so it shouldn't call die().
999  */
1000
1001 void setdtr (int tty_fd, int on)
1002 {
1003     int modembits = TIOCM_DTR;
1004
1005     ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
1006 }
1007
1008 /********************************************************************
1009  *
1010  * restore_tty - restore the terminal to the saved settings.
1011  */
1012
1013 void restore_tty (int tty_fd)
1014 {
1015     if (restore_term) {
1016         restore_term = 0;
1017 /*
1018  * Turn off echoing, because otherwise we can get into
1019  * a loop with the tty and the modem echoing to each other.
1020  * We presume we are the sole user of this tty device, so
1021  * when we close it, it will revert to its defaults anyway.
1022  */
1023         if (!default_device)
1024             inittermios.c_lflag &= ~(ECHO | ECHONL);
1025
1026         if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
1027             if (! ok_error (errno))
1028                 warn("tcsetattr: %m (line %d)", __LINE__);
1029         }
1030     }
1031 }
1032
1033 /********************************************************************
1034  *
1035  * output - Output PPP packet.
1036  */
1037
1038 void output (int unit, unsigned char *p, int len)
1039 {
1040     int fd = ppp_fd;
1041     int proto;
1042
1043     dump_packet("sent", p, len);
1044     if (snoop_send_hook) snoop_send_hook(p, len);
1045
1046     if (len < PPP_HDRLEN)
1047         return;
1048     if (new_style_driver) {
1049         p += 2;
1050         len -= 2;
1051         proto = (p[0] << 8) + p[1];
1052         if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
1053             fd = ppp_dev_fd;
1054     }
1055     if (write(fd, p, len) < 0) {
1056         if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
1057             || errno == ENXIO || errno == EIO || errno == EINTR)
1058             warn("write: warning: %m (%d)", errno);
1059         else
1060             error("write: %m (%d)", errno);
1061     }
1062 }
1063
1064 /********************************************************************
1065  *
1066  * wait_input - wait until there is data available,
1067  * for the length of time specified by *timo (indefinite
1068  * if timo is NULL).
1069  */
1070
1071 void wait_input(struct timeval *timo)
1072 {
1073     fd_set ready, exc;
1074     int n;
1075
1076     ready = in_fds;
1077     exc = in_fds;
1078     n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
1079     if (n < 0 && errno != EINTR)
1080         fatal("select: %m");
1081 }
1082
1083 /*
1084  * add_fd - add an fd to the set that wait_input waits for.
1085  */
1086 void add_fd(int fd)
1087 {
1088     if (fd >= FD_SETSIZE)
1089         fatal("internal error: file descriptor too large (%d)", fd);
1090     FD_SET(fd, &in_fds);
1091     if (fd > max_in_fd)
1092         max_in_fd = fd;
1093 }
1094
1095 /*
1096  * remove_fd - remove an fd from the set that wait_input waits for.
1097  */
1098 void remove_fd(int fd)
1099 {
1100     FD_CLR(fd, &in_fds);
1101 }
1102
1103
1104 /********************************************************************
1105  *
1106  * read_packet - get a PPP packet from the serial device.
1107  */
1108
1109 int read_packet (unsigned char *buf)
1110 {
1111     int len, nr;
1112
1113     len = PPP_MRU + PPP_HDRLEN;
1114     if (new_style_driver) {
1115         *buf++ = PPP_ALLSTATIONS;
1116         *buf++ = PPP_UI;
1117         len -= 2;
1118     }
1119     nr = -1;
1120     if (ppp_fd >= 0) {
1121         nr = read(ppp_fd, buf, len);
1122         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1123             && errno != EIO && errno != EINTR)
1124             error("read: %m");
1125         if (nr < 0 && errno == ENXIO)
1126             return 0;
1127     }
1128     if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
1129         /* N.B. we read ppp_fd first since LCP packets come in there. */
1130         nr = read(ppp_dev_fd, buf, len);
1131         if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
1132             && errno != EIO && errno != EINTR)
1133             error("read /dev/ppp: %m");
1134         if (nr < 0 && errno == ENXIO)
1135             nr = 0;
1136         if (nr == 0 && doing_multilink) {
1137             remove_fd(ppp_dev_fd);
1138             bundle_eof = 1;
1139         }
1140     }
1141     if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
1142         nr = 0;
1143     return (new_style_driver && nr > 0)? nr+2: nr;
1144 }
1145
1146 /********************************************************************
1147  *
1148  * get_loop_output - get outgoing packets from the ppp device,
1149  * and detect when we want to bring the real link up.
1150  * Return value is 1 if we need to bring up the link, 0 otherwise.
1151  */
1152 int
1153 get_loop_output(void)
1154 {
1155     int rv = 0;
1156     int n;
1157
1158     if (new_style_driver) {
1159         while ((n = read_packet(inpacket_buf)) > 0)
1160             if (loop_frame(inpacket_buf, n))
1161                 rv = 1;
1162         return rv;
1163     }
1164
1165     while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
1166         if (loop_chars(inbuf, n))
1167             rv = 1;
1168
1169     if (n == 0)
1170         fatal("eof on loopback");
1171
1172     if (errno != EWOULDBLOCK && errno != EAGAIN)
1173         fatal("read from loopback: %m(%d)", errno);
1174
1175     return rv;
1176 }
1177
1178 /*
1179  * netif_set_mtu - set the MTU on the PPP network interface.
1180  */
1181 void
1182 netif_set_mtu(int unit, int mtu)
1183 {
1184     struct ifreq ifr;
1185
1186     memset (&ifr, '\0', sizeof (ifr));
1187     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1188     ifr.ifr_mtu = mtu;
1189
1190     if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
1191         error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
1192 }
1193
1194 /*
1195  * netif_get_mtu - get the MTU on the PPP network interface.
1196  */
1197 int
1198 netif_get_mtu(int unit)
1199 {
1200     struct ifreq ifr;
1201
1202     memset (&ifr, '\0', sizeof (ifr));
1203     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1204
1205     if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
1206         error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
1207         return 0;
1208     }
1209     return ifr.ifr_mtu;
1210 }
1211
1212 /********************************************************************
1213  *
1214  * tty_send_config - configure the transmit characteristics of
1215  * the ppp interface.
1216  */
1217
1218 void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
1219 {
1220         int x;
1221
1222         if (!still_ppp())
1223                 return;
1224         link_mtu = mtu;
1225         if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
1226                 if (errno != EIO && errno != ENOTTY)
1227                         error("Couldn't set transmit async character map: %m");
1228                 ++error_count;
1229                 return;
1230         }
1231
1232         x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
1233             | (sync_serial? SC_SYNC: 0);
1234         modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
1235 }
1236
1237 /********************************************************************
1238  *
1239  * tty_set_xaccm - set the extended transmit ACCM for the interface.
1240  */
1241
1242 void tty_set_xaccm (ext_accm accm)
1243 {
1244     if (!still_ppp())
1245         return;
1246     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
1247         if ( ! ok_error (errno))
1248             warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
1249     }
1250 }
1251
1252 /********************************************************************
1253  *
1254  * tty_recv_config - configure the receive-side characteristics of
1255  * the ppp interface.
1256  */
1257
1258 void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
1259 {
1260 /*
1261  * If we were called because the link has gone down then there is nothing
1262  * which may be done. Just return without incident.
1263  */
1264         if (!still_ppp())
1265                 return;
1266 /*
1267  * Set the receiver parameters
1268  */
1269         if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
1270                 if (errno != EIO && errno != ENOTTY)
1271                         error("Couldn't set channel receive MRU: %m");
1272         }
1273         if (new_style_driver && ppp_dev_fd >= 0
1274             && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
1275                 error("Couldn't set MRU in generic PPP layer: %m");
1276
1277         if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
1278                 if (errno != EIO && errno != ENOTTY)
1279                         error("Couldn't set channel receive asyncmap: %m");
1280         }
1281 }
1282
1283 /********************************************************************
1284  *
1285  * ccp_test - ask kernel whether a given compression method
1286  * is acceptable for use.
1287  */
1288
1289 int
1290 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
1291 {
1292     struct ppp_option_data data;
1293
1294     memset (&data, '\0', sizeof (data));
1295     data.ptr      = opt_ptr;
1296     data.length   = opt_len;
1297     data.transmit = for_transmit;
1298
1299     if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
1300         return 1;
1301
1302     return (errno == ENOBUFS)? 0: -1;
1303 }
1304
1305 /********************************************************************
1306  *
1307  * ccp_flags_set - inform kernel about the current state of CCP.
1308  */
1309
1310 void ccp_flags_set (int unit, int isopen, int isup)
1311 {
1312         int x;
1313
1314         x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
1315         if (still_ppp() && ppp_dev_fd >= 0)
1316                 modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
1317 }
1318
1319 #ifdef PPP_FILTER
1320 /*
1321  * set_filters - set the active and pass filters in the kernel driver.
1322  */
1323 int set_filters(struct bpf_program *pass, struct bpf_program *active)
1324 {
1325         struct sock_fprog fp;
1326
1327         fp.len = pass->bf_len;
1328         fp.filter = (struct sock_filter *) pass->bf_insns;
1329         if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
1330                 if (errno == ENOTTY)
1331                         warn("kernel does not support PPP filtering");
1332                 else
1333                         error("Couldn't set pass-filter in kernel: %m");
1334                 return 0;
1335         }
1336         fp.len = active->bf_len;
1337         fp.filter = (struct sock_filter *) active->bf_insns;
1338         if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
1339                 error("Couldn't set active-filter in kernel: %m");
1340                 return 0;
1341         }
1342         return 1;
1343 }
1344 #endif /* PPP_FILTER */
1345
1346 /********************************************************************
1347  *
1348  * get_idle_time - return how long the link has been idle.
1349  */
1350 int
1351 get_idle_time(u, ip)
1352     int u;
1353     struct ppp_idle *ip;
1354 {
1355     return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
1356 }
1357
1358 /********************************************************************
1359  *
1360  * get_ppp_stats - return statistics for the link.
1361  */
1362 int
1363 get_ppp_stats(u, stats)
1364     int u;
1365     struct pppd_stats *stats;
1366 {
1367     struct ifpppstatsreq req;
1368
1369     memset (&req, 0, sizeof (req));
1370
1371     req.stats_ptr = (caddr_t) &req.stats;
1372     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
1373     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
1374         error("Couldn't get PPP statistics: %m");
1375         return 0;
1376     }
1377     stats->bytes_in = req.stats.p.ppp_ibytes;
1378     stats->bytes_out = req.stats.p.ppp_obytes;
1379     stats->pkts_in = req.stats.p.ppp_ipackets;
1380     stats->pkts_out = req.stats.p.ppp_opackets;
1381     return 1;
1382 }
1383
1384 /********************************************************************
1385  *
1386  * ccp_fatal_error - returns 1 if decompression was disabled as a
1387  * result of an error detected after decompression of a packet,
1388  * 0 otherwise.  This is necessary because of patent nonsense.
1389  */
1390
1391 int ccp_fatal_error (int unit)
1392 {
1393         int flags;
1394
1395         if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
1396                 error("Couldn't read compression error flags: %m");
1397                 flags = 0;
1398         }
1399         return flags & SC_DC_FERROR;
1400 }
1401
1402 /********************************************************************
1403  *
1404  * path_to_procfs - find the path to the proc file system mount point
1405  */
1406 static char proc_path[MAXPATHLEN];
1407 static int proc_path_len;
1408
1409 static char *path_to_procfs(const char *tail)
1410 {
1411     struct mntent *mntent;
1412     FILE *fp;
1413
1414     if (proc_path_len == 0) {
1415         /* Default the mount location of /proc */
1416         strlcpy (proc_path, "/proc", sizeof(proc_path));
1417         proc_path_len = 5;
1418         fp = fopen(MOUNTED, "r");
1419         if (fp != NULL) {
1420             while ((mntent = getmntent(fp)) != NULL) {
1421                 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1422                     continue;
1423                 if (strcmp(mntent->mnt_type, "proc") == 0) {
1424                     strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
1425                     proc_path_len = strlen(proc_path);
1426                     break;
1427                 }
1428             }
1429             fclose (fp);
1430         }
1431     }
1432
1433     strlcpy(proc_path + proc_path_len, tail,
1434             sizeof(proc_path) - proc_path_len);
1435     return proc_path;
1436 }
1437
1438 /*
1439  * /proc/net/route parsing stuff.
1440  */
1441 #define ROUTE_MAX_COLS  12
1442 FILE *route_fd = (FILE *) 0;
1443 static char route_buffer[512];
1444 static int route_dev_col, route_dest_col, route_gw_col;
1445 static int route_flags_col, route_mask_col;
1446 static int route_num_cols;
1447
1448 static int open_route_table (void);
1449 static void close_route_table (void);
1450 static int read_route_table (struct rtentry *rt);
1451
1452 /********************************************************************
1453  *
1454  * close_route_table - close the interface to the route table
1455  */
1456
1457 static void close_route_table (void)
1458 {
1459     if (route_fd != (FILE *) 0) {
1460         fclose (route_fd);
1461         route_fd = (FILE *) 0;
1462     }
1463 }
1464
1465 /********************************************************************
1466  *
1467  * open_route_table - open the interface to the route table
1468  */
1469 static char route_delims[] = " \t\n";
1470
1471 static int open_route_table (void)
1472 {
1473     char *path;
1474
1475     close_route_table();
1476
1477     path = path_to_procfs("/net/route");
1478     route_fd = fopen (path, "r");
1479     if (route_fd == NULL) {
1480         error("can't open routing table %s: %m", path);
1481         return 0;
1482     }
1483
1484     route_dev_col = 0;          /* default to usual columns */
1485     route_dest_col = 1;
1486     route_gw_col = 2;
1487     route_flags_col = 3;
1488     route_mask_col = 7;
1489     route_num_cols = 8;
1490
1491     /* parse header line */
1492     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1493         char *p = route_buffer, *q;
1494         int col;
1495         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1496             int used = 1;
1497             if ((q = strtok(p, route_delims)) == 0)
1498                 break;
1499             if (strcasecmp(q, "iface") == 0)
1500                 route_dev_col = col;
1501             else if (strcasecmp(q, "destination") == 0)
1502                 route_dest_col = col;
1503             else if (strcasecmp(q, "gateway") == 0)
1504                 route_gw_col = col;
1505             else if (strcasecmp(q, "flags") == 0)
1506                 route_flags_col = col;
1507             else if (strcasecmp(q, "mask") == 0)
1508                 route_mask_col = col;
1509             else
1510                 used = 0;
1511             if (used && col >= route_num_cols)
1512                 route_num_cols = col + 1;
1513             p = NULL;
1514         }
1515     }
1516
1517     return 1;
1518 }
1519
1520 /********************************************************************
1521  *
1522  * read_route_table - read the next entry from the route table
1523  */
1524
1525 static int read_route_table(struct rtentry *rt)
1526 {
1527     char *cols[ROUTE_MAX_COLS], *p;
1528     int col;
1529
1530     memset (rt, '\0', sizeof (struct rtentry));
1531
1532     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1533         return 0;
1534
1535     p = route_buffer;
1536     for (col = 0; col < route_num_cols; ++col) {
1537         cols[col] = strtok(p, route_delims);
1538         if (cols[col] == NULL)
1539             return 0;           /* didn't get enough columns */
1540         p = NULL;
1541     }
1542
1543     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
1544     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
1545     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
1546
1547     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1548     rt->rt_dev   = cols[route_dev_col];
1549
1550     return 1;
1551 }
1552
1553 /********************************************************************
1554  *
1555  * defaultroute_exists - determine if there is a default route
1556  */
1557
1558 static int defaultroute_exists (struct rtentry *rt)
1559 {
1560     int result = 0;
1561
1562     if (!open_route_table())
1563         return 0;
1564
1565     while (read_route_table(rt) != 0) {
1566         if ((rt->rt_flags & RTF_UP) == 0)
1567             continue;
1568
1569         if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
1570             continue;
1571         if (SIN_ADDR(rt->rt_dst) == 0L) {
1572             result = 1;
1573             break;
1574         }
1575     }
1576
1577     close_route_table();
1578     return result;
1579 }
1580
1581 /*
1582  * have_route_to - determine if the system has any route to
1583  * a given IP address.  `addr' is in network byte order.
1584  * Return value is 1 if yes, 0 if no, -1 if don't know.
1585  * For demand mode to work properly, we have to ignore routes
1586  * through our own interface.
1587  */
1588 int have_route_to(u_int32_t addr)
1589 {
1590     struct rtentry rt;
1591     int result = 0;
1592
1593     if (!open_route_table())
1594         return -1;              /* don't know */
1595
1596     while (read_route_table(&rt)) {
1597         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1598             continue;
1599         if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
1600             result = 1;
1601             break;
1602         }
1603     }
1604
1605     close_route_table();
1606     return result;
1607 }
1608
1609 /********************************************************************
1610  *
1611  * sifdefaultroute - assign a default route through the address given.
1612  */
1613
1614 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1615 {
1616     struct rtentry rt;
1617
1618     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1619         if (rt.rt_flags & RTF_GATEWAY)
1620             error("not replacing existing default route via %I",
1621                   SIN_ADDR(rt.rt_gateway));
1622         else
1623             error("not replacing existing default route through %s",
1624                   rt.rt_dev);
1625         return 0;
1626     }
1627
1628     memset (&rt, 0, sizeof (rt));
1629     SET_SA_FAMILY (rt.rt_dst, AF_INET);
1630
1631     rt.rt_dev = ifname;
1632
1633     if (kernel_version > KVERSION(2,1,0)) {
1634         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1635         SIN_ADDR(rt.rt_genmask) = 0L;
1636     }
1637
1638     rt.rt_flags = RTF_UP;
1639     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1640         if ( ! ok_error ( errno ))
1641             error("default route ioctl(SIOCADDRT): %m");
1642         return 0;
1643     }
1644
1645     have_default_route = 1;
1646     return 1;
1647 }
1648
1649 /********************************************************************
1650  *
1651  * cifdefaultroute - delete a default route through the address given.
1652  */
1653
1654 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1655 {
1656     struct rtentry rt;
1657
1658     have_default_route = 0;
1659
1660     memset (&rt, '\0', sizeof (rt));
1661     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1662     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1663
1664     rt.rt_dev = ifname;
1665
1666     if (kernel_version > KVERSION(2,1,0)) {
1667         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1668         SIN_ADDR(rt.rt_genmask) = 0L;
1669     }
1670
1671     rt.rt_flags = RTF_UP;
1672     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1673         if (still_ppp()) {
1674             if ( ! ok_error ( errno ))
1675                 error("default route ioctl(SIOCDELRT): %m");
1676             return 0;
1677         }
1678     }
1679
1680     return 1;
1681 }
1682
1683 /********************************************************************
1684  *
1685  * sifproxyarp - Make a proxy ARP entry for the peer.
1686  */
1687
1688 int sifproxyarp (int unit, u_int32_t his_adr)
1689 {
1690     struct arpreq arpreq;
1691     char *forw_path;
1692
1693     if (has_proxy_arp == 0) {
1694         memset (&arpreq, '\0', sizeof(arpreq));
1695
1696         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1697         SIN_ADDR(arpreq.arp_pa) = his_adr;
1698         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1699 /*
1700  * Get the hardware address of an interface on the same subnet
1701  * as our local address.
1702  */
1703         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1704                             sizeof(proxy_arp_dev))) {
1705             error("Cannot determine ethernet address for proxy ARP");
1706             return 0;
1707         }
1708         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1709
1710         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1711             if ( ! ok_error ( errno ))
1712                 error("ioctl(SIOCSARP): %m");
1713             return 0;
1714         }
1715         proxy_arp_addr = his_adr;
1716         has_proxy_arp = 1;
1717
1718         if (tune_kernel) {
1719             forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
1720             if (forw_path != 0) {
1721                 int fd = open(forw_path, O_WRONLY);
1722                 if (fd >= 0) {
1723                     if (write(fd, "1", 1) != 1)
1724                         error("Couldn't enable IP forwarding: %m");
1725                     close(fd);
1726                 }
1727             }
1728         }
1729     }
1730
1731     return 1;
1732 }
1733
1734 /********************************************************************
1735  *
1736  * cifproxyarp - Delete the proxy ARP entry for the peer.
1737  */
1738
1739 int cifproxyarp (int unit, u_int32_t his_adr)
1740 {
1741     struct arpreq arpreq;
1742
1743     if (has_proxy_arp) {
1744         has_proxy_arp = 0;
1745         memset (&arpreq, '\0', sizeof(arpreq));
1746         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1747         SIN_ADDR(arpreq.arp_pa) = his_adr;
1748         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1749         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1750
1751         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1752             if ( ! ok_error ( errno ))
1753                 warn("ioctl(SIOCDARP): %m");
1754             return 0;
1755         }
1756     }
1757     return 1;
1758 }
1759
1760 /********************************************************************
1761  *
1762  * get_ether_addr - get the hardware address of an interface on the
1763  * the same subnet as ipaddr.
1764  */
1765
1766 static int get_ether_addr (u_int32_t ipaddr,
1767                            struct sockaddr *hwaddr,
1768                            char *name, int namelen)
1769 {
1770     struct ifreq *ifr, *ifend;
1771     u_int32_t ina, mask;
1772     char *aliasp;
1773     struct ifreq ifreq, bestifreq;
1774     struct ifconf ifc;
1775     struct ifreq ifs[MAX_IFS];
1776
1777     u_int32_t bestmask=0;
1778     int found_interface = 0;
1779
1780     ifc.ifc_len = sizeof(ifs);
1781     ifc.ifc_req = ifs;
1782     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1783         if ( ! ok_error ( errno ))
1784             error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1785         return 0;
1786     }
1787
1788 /*
1789  * Scan through looking for an interface with an Internet
1790  * address on the same subnet as `ipaddr'.
1791  */
1792     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1793     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1794         if (ifr->ifr_addr.sa_family == AF_INET) {
1795             ina = SIN_ADDR(ifr->ifr_addr);
1796             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1797 /*
1798  * Check that the interface is up, and not point-to-point
1799  * nor loopback.
1800  */
1801             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1802                 continue;
1803
1804             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1805                 continue;
1806 /*
1807  * Get its netmask and check that it's on the right subnet.
1808  */
1809             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1810                 continue;
1811
1812             mask = SIN_ADDR(ifreq.ifr_addr);
1813
1814             if (((ipaddr ^ ina) & mask) != 0)
1815                 continue; /* no match */
1816             /* matched */
1817             if (mask >= bestmask) {
1818                 /* Compare using >= instead of > -- it is possible for
1819                    an interface to have a netmask of 0.0.0.0 */
1820                 found_interface = 1;
1821                 bestifreq = ifreq;
1822                 bestmask = mask;
1823             }
1824         }
1825     }
1826
1827     if (!found_interface) return 0;
1828
1829     strlcpy(name, bestifreq.ifr_name, namelen);
1830
1831     /* trim off the :1 in eth0:1 */
1832     aliasp = strchr(name, ':');
1833     if (aliasp != 0)
1834         *aliasp = 0;
1835
1836     info("found interface %s for proxy arp", name);
1837 /*
1838  * Now get the hardware address.
1839  */
1840     memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1841     if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
1842         error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
1843         return 0;
1844     }
1845
1846     memcpy (hwaddr,
1847             &bestifreq.ifr_hwaddr,
1848             sizeof (struct sockaddr));
1849
1850     return 1;
1851 }
1852
1853 /*
1854  * get_if_hwaddr - get the hardware address for the specified
1855  * network interface device.
1856  */
1857 int
1858 get_if_hwaddr(u_char *addr, char *name)
1859 {
1860         struct ifreq ifreq;
1861         int ret, sock_fd;
1862
1863         sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
1864         if (sock_fd < 0)
1865                 return 0;
1866         memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
1867         strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
1868         ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
1869         close(sock_fd);
1870         if (ret >= 0)
1871                 memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
1872         return ret;
1873 }
1874
1875 /*
1876  * get_first_ethernet - return the name of the first ethernet-style
1877  * interface on this system.
1878  */
1879 char *
1880 get_first_ethernet()
1881 {
1882         return "eth0";
1883 }
1884
1885 /********************************************************************
1886  *
1887  * Return user specified netmask, modified by any mask we might determine
1888  * for address `addr' (in network byte order).
1889  * Here we scan through the system's list of interfaces, looking for
1890  * any non-point-to-point interfaces which might appear to be on the same
1891  * network as `addr'.  If we find any, we OR in their netmask to the
1892  * user-specified netmask.
1893  */
1894
1895 u_int32_t GetMask (u_int32_t addr)
1896 {
1897     u_int32_t mask, nmask, ina;
1898     struct ifreq *ifr, *ifend, ifreq;
1899     struct ifconf ifc;
1900     struct ifreq ifs[MAX_IFS];
1901
1902     addr = ntohl(addr);
1903
1904     if (IN_CLASSA(addr))        /* determine network mask for address class */
1905         nmask = IN_CLASSA_NET;
1906     else if (IN_CLASSB(addr))
1907             nmask = IN_CLASSB_NET;
1908     else
1909             nmask = IN_CLASSC_NET;
1910
1911     /* class D nets are disallowed by bad_ip_adrs */
1912     mask = netmask | htonl(nmask);
1913 /*
1914  * Scan through the system's network interfaces.
1915  */
1916     ifc.ifc_len = sizeof(ifs);
1917     ifc.ifc_req = ifs;
1918     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1919         if ( ! ok_error ( errno ))
1920             warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
1921         return mask;
1922     }
1923
1924     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1925     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1926 /*
1927  * Check the interface's internet address.
1928  */
1929         if (ifr->ifr_addr.sa_family != AF_INET)
1930             continue;
1931         ina = SIN_ADDR(ifr->ifr_addr);
1932         if (((ntohl(ina) ^ addr) & nmask) != 0)
1933             continue;
1934 /*
1935  * Check that the interface is up, and not point-to-point nor loopback.
1936  */
1937         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1938         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1939             continue;
1940
1941         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1942             continue;
1943 /*
1944  * Get its netmask and OR it into our mask.
1945  */
1946         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1947             continue;
1948         mask |= SIN_ADDR(ifreq.ifr_addr);
1949         break;
1950     }
1951     return mask;
1952 }
1953
1954 /********************************************************************
1955  *
1956  * Internal routine to decode the version.modification.patch level
1957  */
1958
1959 static void decode_version (char *buf, int *version,
1960                             int *modification, int *patch)
1961 {
1962     char *endp;
1963
1964     *version      = (int) strtoul (buf, &endp, 10);
1965     *modification = 0;
1966     *patch        = 0;
1967
1968     if (endp != buf && *endp == '.') {
1969         buf = endp + 1;
1970         *modification = (int) strtoul (buf, &endp, 10);
1971         if (endp != buf && *endp == '.') {
1972             buf = endp + 1;
1973             *patch = (int) strtoul (buf, &buf, 10);
1974         }
1975     }
1976 }
1977
1978 /********************************************************************
1979  *
1980  * Procedure to determine if the PPP line discipline is registered.
1981  */
1982
1983 static int
1984 ppp_registered(void)
1985 {
1986     int local_fd;
1987     int mfd = -1;
1988     int ret = 0;
1989     char slave[16];
1990
1991     /*
1992      * We used to open the serial device and set it to the ppp line
1993      * discipline here, in order to create a ppp unit.  But that is
1994      * not a good idea - the user might have specified a device that
1995      * they can't open (permission, or maybe it doesn't really exist).
1996      * So we grab a pty master/slave pair and use that.
1997      */
1998     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1999         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
2000         return 0;
2001     }
2002
2003     /*
2004      * Try to put the device into the PPP discipline.
2005      */
2006     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
2007         error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
2008     } else
2009         ret = 1;
2010
2011     close(local_fd);
2012     close(mfd);
2013     return ret;
2014 }
2015
2016 /********************************************************************
2017  *
2018  * ppp_available - check whether the system has any ppp interfaces
2019  * (in fact we check whether we can do an ioctl on ppp0).
2020  */
2021
2022 int ppp_available(void)
2023 {
2024     int s, ok, fd;
2025     struct ifreq ifr;
2026     int    size;
2027     int    my_version, my_modification, my_patch;
2028     int osmaj, osmin, ospatch;
2029
2030     /* get the kernel version now, since we are called before sys_init */
2031     uname(&utsname);
2032     osmaj = osmin = ospatch = 0;
2033     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
2034     kernel_version = KVERSION(osmaj, osmin, ospatch);
2035
2036     fd = open("/dev/ppp", O_RDWR);
2037     if (fd >= 0) {
2038         new_style_driver = 1;
2039
2040         /* XXX should get from driver */
2041         driver_version = 2;
2042         driver_modification = 4;
2043         driver_patch = 0;
2044         close(fd);
2045         return 1;
2046     }
2047
2048     if (kernel_version >= KVERSION(2,3,13)) {
2049         error("Couldn't open the /dev/ppp device: %m");
2050         if (errno == ENOENT)
2051             no_ppp_msg =
2052                 "You need to create the /dev/ppp device node by\n"
2053                 "executing the following command as root:\n"
2054                 "       mknod /dev/ppp c 108 0\n";
2055         else if (errno == ENODEV || errno == ENXIO)
2056             no_ppp_msg =
2057                 "Please load the ppp_generic kernel module.\n";
2058         return 0;
2059     }
2060
2061     /* we are running on a really really old kernel */
2062     no_ppp_msg =
2063         "This system lacks kernel support for PPP.  This could be because\n"
2064         "the PPP kernel module could not be loaded, or because PPP was not\n"
2065         "included in the kernel configuration.  If PPP was included as a\n"
2066         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
2067         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
2068         "See README.linux file in the ppp distribution for more details.\n";
2069
2070 /*
2071  * Open a socket for doing the ioctl operations.
2072  */
2073     s = socket(AF_INET, SOCK_DGRAM, 0);
2074     if (s < 0)
2075         return 0;
2076
2077     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2078     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2079 /*
2080  * If the device did not exist then attempt to create one by putting the
2081  * current tty into the PPP discipline. If this works then obtain the
2082  * flags for the device again.
2083  */
2084     if (!ok) {
2085         if (ppp_registered()) {
2086             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
2087             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
2088         }
2089     }
2090 /*
2091  * Ensure that the hardware address is for PPP and not something else
2092  */
2093     if (ok)
2094         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
2095
2096     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
2097         ok = 0;
2098
2099 /*
2100  *  This is the PPP device. Validate the version of the driver at this
2101  *  point to ensure that this program will work with the driver.
2102  */
2103     if (ok) {
2104         char   abBuffer [1024];
2105
2106         ifr.ifr_data = abBuffer;
2107         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
2108         if (size < 0) {
2109             error("Couldn't read driver version: %m");
2110             ok = 0;
2111             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
2112
2113         } else {
2114             decode_version(abBuffer,
2115                            &driver_version,
2116                            &driver_modification,
2117                            &driver_patch);
2118 /*
2119  * Validate the version of the driver against the version that we used.
2120  */
2121             decode_version(VERSION,
2122                            &my_version,
2123                            &my_modification,
2124                            &my_patch);
2125
2126             /* The version numbers must match */
2127             if (driver_version != my_version)
2128                 ok = 0;
2129
2130             /* The modification levels must be legal */
2131             if (driver_modification < 3) {
2132                 if (driver_modification >= 2) {
2133                     /* we can cope with 2.2.0 and above */
2134                     driver_is_old = 1;
2135                 } else {
2136                     ok = 0;
2137                 }
2138             }
2139
2140             close (s);
2141             if (!ok) {
2142                 slprintf(route_buffer, sizeof(route_buffer),
2143                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
2144                          driver_version, driver_modification, driver_patch);
2145
2146                 no_ppp_msg = route_buffer;
2147             }
2148         }
2149     }
2150     return ok;
2151 }
2152
2153 #ifndef HAVE_LOGWTMP
2154 /********************************************************************
2155  *
2156  * Update the wtmp file with the appropriate user name and tty device.
2157  */
2158
2159 void logwtmp (const char *line, const char *name, const char *host)
2160 {
2161     struct utmp ut, *utp;
2162     pid_t  mypid = getpid();
2163 #if __GLIBC__ < 2
2164     int    wtmp;
2165 #endif
2166
2167 /*
2168  * Update the signon database for users.
2169  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
2170  */
2171     utmpname(_PATH_UTMP);
2172     setutent();
2173     while ((utp = getutent()) && (utp->ut_pid != mypid))
2174         /* nothing */;
2175
2176     if (utp)
2177         memcpy(&ut, utp, sizeof(ut));
2178     else
2179         /* some gettys/telnetds don't initialize utmp... */
2180         memset(&ut, 0, sizeof(ut));
2181
2182     if (ut.ut_id[0] == 0)
2183         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
2184
2185     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
2186     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
2187
2188     time(&ut.ut_time);
2189
2190     ut.ut_type = USER_PROCESS;
2191     ut.ut_pid  = mypid;
2192
2193     /* Insert the host name if one is supplied */
2194     if (*host)
2195         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
2196
2197     /* Insert the IP address of the remote system if IP is enabled */
2198     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
2199         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
2200                  sizeof(ut.ut_addr));
2201
2202     /* CL: Makes sure that the logout works */
2203     if (*host == 0 && *name==0)
2204         ut.ut_host[0]=0;
2205
2206     pututline(&ut);
2207     endutent();
2208 /*
2209  * Update the wtmp file.
2210  */
2211 #if __GLIBC__ >= 2
2212     updwtmp(_PATH_WTMP, &ut);
2213 #else
2214     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
2215     if (wtmp >= 0) {
2216         flock(wtmp, LOCK_EX);
2217
2218         if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
2219             warn("error writing %s: %m", _PATH_WTMP);
2220
2221         flock(wtmp, LOCK_UN);
2222
2223         close (wtmp);
2224     }
2225 #endif
2226 }
2227 #endif /* HAVE_LOGWTMP */
2228
2229 /********************************************************************
2230  *
2231  * sifvjcomp - config tcp header compression
2232  */
2233
2234 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2235 {
2236         u_int x;
2237
2238         if (vjcomp) {
2239                 if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
2240                         error("Couldn't set up TCP header compression: %m");
2241                         vjcomp = 0;
2242                 }
2243         }
2244
2245         x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
2246         modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
2247
2248         return 1;
2249 }
2250
2251 /********************************************************************
2252  *
2253  * sifup - Config the interface up and enable IP packets to pass.
2254  */
2255
2256 int sifup(int u)
2257 {
2258     struct ifreq ifr;
2259
2260     memset (&ifr, '\0', sizeof (ifr));
2261     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2262     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2263         if (! ok_error (errno))
2264             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2265         return 0;
2266     }
2267
2268     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2269     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2270         if (! ok_error (errno))
2271             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2272         return 0;
2273     }
2274     if_is_up++;
2275
2276     return 1;
2277 }
2278
2279 /********************************************************************
2280  *
2281  * sifdown - Disable the indicated protocol and config the interface
2282  *           down if there are no remaining protocols.
2283  */
2284
2285 int sifdown (int u)
2286 {
2287     struct ifreq ifr;
2288
2289     if (if_is_up && --if_is_up > 0)
2290         return 1;
2291
2292     memset (&ifr, '\0', sizeof (ifr));
2293     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2294     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
2295         if (! ok_error (errno))
2296             error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
2297         return 0;
2298     }
2299
2300     ifr.ifr_flags &= ~IFF_UP;
2301     ifr.ifr_flags |= IFF_POINTOPOINT;
2302     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
2303         if (! ok_error (errno))
2304             error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
2305         return 0;
2306     }
2307     return 1;
2308 }
2309
2310 /********************************************************************
2311  *
2312  * sifaddr - Config the interface IP addresses and netmask.
2313  */
2314
2315 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2316              u_int32_t net_mask)
2317 {
2318     struct ifreq   ifr;
2319     struct rtentry rt;
2320
2321     memset (&ifr, '\0', sizeof (ifr));
2322     memset (&rt,  '\0', sizeof (rt));
2323
2324     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET);
2325     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
2326     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
2327
2328     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2329 /*
2330  *  Set our IP address
2331  */
2332     SIN_ADDR(ifr.ifr_addr) = our_adr;
2333     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2334         if (errno != EEXIST) {
2335             if (! ok_error (errno))
2336                 error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2337         }
2338         else {
2339             warn("ioctl(SIOCSIFADDR): Address already exists");
2340         }
2341         return (0);
2342     }
2343 /*
2344  *  Set the gateway address
2345  */
2346     if (his_adr != 0) {
2347         SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
2348         if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2349             if (! ok_error (errno))
2350                 error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
2351             return (0);
2352         }
2353     }
2354 /*
2355  *  Set the netmask.
2356  *  For recent kernels, force the netmask to 255.255.255.255.
2357  */
2358     if (kernel_version >= KVERSION(2,1,16))
2359         net_mask = ~0L;
2360     if (net_mask != 0) {
2361         SIN_ADDR(ifr.ifr_netmask) = net_mask;
2362         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2363             if (! ok_error (errno))
2364                 error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
2365             return (0);
2366         }
2367     }
2368 /*
2369  *  Add the device route
2370  */
2371     if (kernel_version < KVERSION(2,1,16)) {
2372         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2373         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2374         rt.rt_dev = ifname;
2375
2376         SIN_ADDR(rt.rt_gateway) = 0L;
2377         SIN_ADDR(rt.rt_dst)     = his_adr;
2378         rt.rt_flags = RTF_UP | RTF_HOST;
2379
2380         if (kernel_version > KVERSION(2,1,0)) {
2381             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2382             SIN_ADDR(rt.rt_genmask) = -1L;
2383         }
2384
2385         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2386             if (! ok_error (errno))
2387                 error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
2388             return (0);
2389         }
2390     }
2391
2392     /* set ip_dynaddr in demand mode if address changes */
2393     if (demand && tune_kernel && !dynaddr_set
2394         && our_old_addr && our_old_addr != our_adr) {
2395         /* set ip_dynaddr if possible */
2396         char *path;
2397         int fd;
2398
2399         path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
2400         if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
2401             if (write(fd, "1", 1) != 1)
2402                 error("Couldn't enable dynamic IP addressing: %m");
2403             close(fd);
2404         }
2405         dynaddr_set = 1;        /* only 1 attempt */
2406     }
2407     our_old_addr = 0;
2408
2409     return 1;
2410 }
2411
2412 /********************************************************************
2413  *
2414  * cifaddr - Clear the interface IP addresses, and delete routes
2415  * through the interface if possible.
2416  */
2417
2418 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2419 {
2420     struct ifreq ifr;
2421
2422     if (kernel_version < KVERSION(2,1,16)) {
2423 /*
2424  *  Delete the route through the device
2425  */
2426         struct rtentry rt;
2427         memset (&rt, '\0', sizeof (rt));
2428
2429         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2430         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2431         rt.rt_dev = ifname;
2432
2433         SIN_ADDR(rt.rt_gateway) = 0;
2434         SIN_ADDR(rt.rt_dst)     = his_adr;
2435         rt.rt_flags = RTF_UP | RTF_HOST;
2436
2437         if (kernel_version > KVERSION(2,1,0)) {
2438             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2439             SIN_ADDR(rt.rt_genmask) = -1L;
2440         }
2441
2442         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2443             if (still_ppp() && ! ok_error (errno))
2444                 error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
2445             return (0);
2446         }
2447     }
2448
2449     /* This way it is possible to have an IPX-only or IPv6-only interface */
2450     memset(&ifr, 0, sizeof(ifr));
2451     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
2452     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2453
2454     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2455         if (! ok_error (errno)) {
2456             error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2457             return 0;
2458         }
2459     }
2460
2461     our_old_addr = our_adr;
2462
2463     return 1;
2464 }
2465
2466 #ifdef INET6
2467 /********************************************************************
2468  *
2469  * sif6addr - Config the interface with an IPv6 link-local address
2470  */
2471 int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2472 {
2473     struct in6_ifreq ifr6;
2474     struct ifreq ifr;
2475     struct in6_rtmsg rt6;
2476
2477     if (sock6_fd < 0) {
2478         errno = -sock6_fd;
2479         error("IPv6 socket creation failed: %m");
2480         return 0;
2481     }
2482     memset(&ifr, 0, sizeof (ifr));
2483     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2484     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2485         error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2486         return 0;
2487     }
2488
2489     /* Local interface */
2490     memset(&ifr6, 0, sizeof(ifr6));
2491     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2492     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2493     ifr6.ifr6_prefixlen = 10;
2494
2495     if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
2496         error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
2497         return 0;
2498     }
2499
2500     /* Route to remote host */
2501     memset(&rt6, 0, sizeof(rt6));
2502     IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
2503     rt6.rtmsg_flags = RTF_UP;
2504     rt6.rtmsg_dst_len = 10;
2505     rt6.rtmsg_ifindex = ifr.ifr_ifindex;
2506     rt6.rtmsg_metric = 1;
2507
2508     if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
2509         error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
2510         return 0;
2511     }
2512
2513     return 1;
2514 }
2515
2516
2517 /********************************************************************
2518  *
2519  * cif6addr - Remove IPv6 address from interface
2520  */
2521 int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
2522 {
2523     struct ifreq ifr;
2524     struct in6_ifreq ifr6;
2525
2526     if (sock6_fd < 0) {
2527         errno = -sock6_fd;
2528         error("IPv6 socket creation failed: %m");
2529         return 0;
2530     }
2531     memset(&ifr, 0, sizeof(ifr));
2532     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2533     if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
2534         error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
2535         return 0;
2536     }
2537
2538     memset(&ifr6, 0, sizeof(ifr6));
2539     IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
2540     ifr6.ifr6_ifindex = ifr.ifr_ifindex;
2541     ifr6.ifr6_prefixlen = 10;
2542
2543     if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
2544         if (errno != EADDRNOTAVAIL) {
2545             if (! ok_error (errno))
2546                 error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
2547         }
2548         else {
2549             warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
2550         }
2551         return (0);
2552     }
2553     return 1;
2554 }
2555 #endif /* INET6 */
2556
2557 /*
2558  * get_pty - get a pty master/slave pair and chown the slave side
2559  * to the uid given.  Assumes slave_name points to >= 16 bytes of space.
2560  */
2561 int
2562 get_pty(master_fdp, slave_fdp, slave_name, uid)
2563     int *master_fdp;
2564     int *slave_fdp;
2565     char *slave_name;
2566     int uid;
2567 {
2568     int i, mfd, sfd = -1;
2569     char pty_name[16];
2570     struct termios tios;
2571
2572 #ifdef TIOCGPTN
2573     /*
2574      * Try the unix98 way first.
2575      */
2576     mfd = open("/dev/ptmx", O_RDWR);
2577     if (mfd >= 0) {
2578         int ptn;
2579         if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2580             slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2581             chmod(pty_name, S_IRUSR | S_IWUSR);
2582 #ifdef TIOCSPTLCK
2583             ptn = 0;
2584             if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2585                 warn("Couldn't unlock pty slave %s: %m", pty_name);
2586 #endif
2587             if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
2588                 warn("Couldn't open pty slave %s: %m", pty_name);
2589         }
2590     }
2591 #endif /* TIOCGPTN */
2592
2593     if (sfd < 0) {
2594         /* the old way - scan through the pty name space */
2595         for (i = 0; i < 64; ++i) {
2596             slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2597                      'p' + i / 16, i % 16);
2598             mfd = open(pty_name, O_RDWR, 0);
2599             if (mfd >= 0) {
2600                 pty_name[5] = 't';
2601                 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2602                 if (sfd >= 0) {
2603                     fchown(sfd, uid, -1);
2604                     fchmod(sfd, S_IRUSR | S_IWUSR);
2605                     break;
2606                 }
2607                 close(mfd);
2608             }
2609         }
2610     }
2611
2612     if (sfd < 0)
2613         return 0;
2614
2615     strlcpy(slave_name, pty_name, 16);
2616     *master_fdp = mfd;
2617     *slave_fdp = sfd;
2618     if (tcgetattr(sfd, &tios) == 0) {
2619         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2620         tios.c_cflag |= CS8 | CREAD | CLOCAL;
2621         tios.c_iflag  = IGNPAR;
2622         tios.c_oflag  = 0;
2623         tios.c_lflag  = 0;
2624         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2625             warn("couldn't set attributes on pty: %m");
2626     } else
2627         warn("couldn't get attributes on pty: %m");
2628
2629     return 1;
2630 }
2631
2632 /********************************************************************
2633  *
2634  * open_loopback - open the device we use for getting packets
2635  * in demand mode.  Under Linux, we use a pty master/slave pair.
2636  */
2637 int
2638 open_ppp_loopback(void)
2639 {
2640     int flags;
2641
2642     looped = 1;
2643     if (new_style_driver) {
2644         /* allocate ourselves a ppp unit */
2645         if (make_ppp_unit() < 0)
2646             die(1);
2647         modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
2648         set_kdebugflag(kdebugflag);
2649         ppp_fd = -1;
2650         return ppp_dev_fd;
2651     }
2652
2653     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2654         fatal("No free pty for loopback");
2655
2656     set_ppp_fd(slave_fd);
2657
2658     flags = fcntl(master_fd, F_GETFL);
2659     if (flags == -1 ||
2660         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2661         warn("couldn't set master loopback to nonblock: %m");
2662
2663     flags = fcntl(ppp_fd, F_GETFL);
2664     if (flags == -1 ||
2665         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2666         warn("couldn't set slave loopback to nonblock: %m");
2667
2668     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2669         fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
2670 /*
2671  * Find out which interface we were given.
2672  */
2673     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2674         fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
2675 /*
2676  * Enable debug in the driver if requested.
2677  */
2678     set_kdebugflag (kdebugflag);
2679
2680     return master_fd;
2681 }
2682
2683 /********************************************************************
2684  *
2685  * sifnpmode - Set the mode for handling packets for a given NP.
2686  */
2687
2688 int
2689 sifnpmode(u, proto, mode)
2690     int u;
2691     int proto;
2692     enum NPmode mode;
2693 {
2694     struct npioctl npi;
2695
2696     npi.protocol = proto;
2697     npi.mode     = mode;
2698     if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2699         if (! ok_error (errno))
2700             error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
2701         return 0;
2702     }
2703     return 1;
2704 }
2705
2706 \f
2707 /********************************************************************
2708  *
2709  * sipxfaddr - Config the interface IPX networknumber
2710  */
2711
2712 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2713 {
2714     int    result = 1;
2715
2716 #ifdef IPX_CHANGE
2717     int    skfd;
2718     struct ifreq         ifr;
2719     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2720
2721     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2722     if (skfd < 0) {
2723         if (! ok_error (errno))
2724             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2725         result = 0;
2726     }
2727     else {
2728         memset (&ifr, '\0', sizeof (ifr));
2729         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2730
2731         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2732         sipx->sipx_family  = AF_IPX;
2733         sipx->sipx_port    = 0;
2734         sipx->sipx_network = htonl (network);
2735         sipx->sipx_type    = IPX_FRAME_ETHERII;
2736         sipx->sipx_action  = IPX_CRTITF;
2737 /*
2738  *  Set the IPX device
2739  */
2740         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2741             result = 0;
2742             if (errno != EEXIST) {
2743                 if (! ok_error (errno))
2744                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
2745             }
2746             else {
2747                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2748             }
2749         }
2750         close (skfd);
2751     }
2752 #endif
2753     return result;
2754 }
2755
2756 /********************************************************************
2757  *
2758  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2759  *             are removed and the device is no longer able to pass IPX
2760  *             frames.
2761  */
2762
2763 int cipxfaddr (int unit)
2764 {
2765     int    result = 1;
2766
2767 #ifdef IPX_CHANGE
2768     int    skfd;
2769     struct ifreq         ifr;
2770     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2771
2772     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2773     if (skfd < 0) {
2774         if (! ok_error (errno))
2775             dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
2776         result = 0;
2777     }
2778     else {
2779         memset (&ifr, '\0', sizeof (ifr));
2780         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2781
2782         sipx->sipx_type    = IPX_FRAME_ETHERII;
2783         sipx->sipx_action  = IPX_DLTITF;
2784         sipx->sipx_family  = AF_IPX;
2785 /*
2786  *  Set the IPX device
2787  */
2788         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2789             if (! ok_error (errno))
2790                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
2791             result = 0;
2792         }
2793         close (skfd);
2794     }
2795 #endif
2796     return result;
2797 }
2798
2799 /*
2800  * Use the hostname as part of the random number seed.
2801  */
2802 int
2803 get_host_seed()
2804 {
2805     int h;
2806     char *p = hostname;
2807
2808     h = 407;
2809     for (p = hostname; *p != 0; ++p)
2810         h = h * 37 + *p;
2811     return h;
2812 }
2813
2814 /********************************************************************
2815  *
2816  * sys_check_options - check the options that the user specified
2817  */
2818
2819 int
2820 sys_check_options(void)
2821 {
2822 #ifdef IPX_CHANGE
2823 /*
2824  * Disable the IPX protocol if the support is not present in the kernel.
2825  */
2826     char *path;
2827
2828     if (ipxcp_protent.enabled_flag) {
2829         struct stat stat_buf;
2830         if (  ((path = path_to_procfs("/net/ipx/interface")) == NULL
2831             && (path = path_to_procfs("/net/ipx_interface")) == NULL)
2832             || lstat(path, &stat_buf) < 0) {
2833             error("IPX support is not present in the kernel\n");
2834             ipxcp_protent.enabled_flag = 0;
2835         }
2836     }
2837 #endif
2838     if (demand && driver_is_old) {
2839         option_error("demand dialling is not supported by kernel driver "
2840                      "version %d.%d.%d", driver_version, driver_modification,
2841                      driver_patch);
2842         return 0;
2843     }
2844     if (multilink && !new_style_driver) {
2845         warn("Warning: multilink is not supported by the kernel driver");
2846         multilink = 0;
2847     }
2848     return 1;
2849 }
2850
2851 #ifdef INET6
2852 /*
2853  * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
2854  *
2855  * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
2856  * that the system has a properly configured Ethernet interface for this
2857  * function to return non-zero.
2858  */
2859 int
2860 ether_to_eui64(eui64_t *p_eui64)
2861 {
2862     struct ifreq ifr;
2863     int skfd;
2864     const unsigned char *ptr;
2865
2866     skfd = socket(PF_INET6, SOCK_DGRAM, 0);
2867     if(skfd == -1)
2868     {
2869         warn("could not open IPv6 socket");
2870         return 0;
2871     }
2872
2873     strcpy(ifr.ifr_name, "eth0");
2874     if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
2875     {
2876         close(skfd);
2877         warn("could not obtain hardware address for eth0");
2878         return 0;
2879     }
2880     close(skfd);
2881
2882     /*
2883      * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
2884      */
2885     ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
2886     p_eui64->e8[0] = ptr[0] | 0x02;
2887     p_eui64->e8[1] = ptr[1];
2888     p_eui64->e8[2] = ptr[2];
2889     p_eui64->e8[3] = 0xFF;
2890     p_eui64->e8[4] = 0xFE;
2891     p_eui64->e8[5] = ptr[3];
2892     p_eui64->e8[6] = ptr[4];
2893     p_eui64->e8[7] = ptr[5];
2894
2895     return 1;
2896 }
2897 #endif