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