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