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