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