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