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