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