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