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