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