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