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