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