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