]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
minor changes so it compiles with pre-ansi compiler;
[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         strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
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         strncpy (route_buffer, "/proc", sizeof (route_buffer)-10);
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     strncpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer)-10);
1148     route_buffer [sizeof (route_buffer)-10] = '\0';
1149     return 1;
1150 }
1151
1152 /********************************************************************
1153  *
1154  * path_to_route - find the path to the route tables in the proc file system
1155  */
1156
1157 static char *path_to_route (void)
1158 {
1159     if (!path_to_procfs()) {
1160         syslog (LOG_ERR, "proc file system not mounted");
1161         return 0;
1162     }
1163     strcat (route_buffer, "/net/route");
1164     return (route_buffer);
1165 }
1166
1167 /********************************************************************
1168  *
1169  * close_route_table - close the interface to the route table
1170  */
1171
1172 static void close_route_table (void)
1173 {
1174     if (route_fd != (FILE *) 0) {
1175         fclose (route_fd);
1176         route_fd = (FILE *) 0;
1177     }
1178 }
1179
1180 /********************************************************************
1181  *
1182  * open_route_table - open the interface to the route table
1183  */
1184 static char route_delims[] = " \t\n";
1185
1186 static int open_route_table (void)
1187 {
1188     char *path;
1189
1190     close_route_table();
1191
1192     path = path_to_route();
1193     if (path == NULL)
1194         return 0;
1195
1196     route_fd = fopen (path, "r");
1197     if (route_fd == NULL) {
1198         syslog (LOG_ERR, "can't open %s: %m (%d)", path, errno);
1199         return 0;
1200     }
1201
1202     route_dev_col = 0;          /* default to usual columns */
1203     route_dest_col = 1;
1204     route_gw_col = 2;
1205     route_flags_col = 3;
1206     route_mask_col = 7;
1207     route_num_cols = 8;
1208
1209     /* parse header line */
1210     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1211         char *p = route_buffer, *q;
1212         int col;
1213         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1214             int used = 1;
1215             if ((q = strtok(p, route_delims)) == 0)
1216                 break;
1217             if (strcasecmp(q, "iface") == 0)
1218                 route_dev_col = col;
1219             else if (strcasecmp(q, "destination") == 0)
1220                 route_dest_col = col;
1221             else if (strcasecmp(q, "gateway") == 0)
1222                 route_gw_col = col;
1223             else if (strcasecmp(q, "flags") == 0)
1224                 route_flags_col = col;
1225             else if (strcasecmp(q, "mask") == 0)
1226                 route_mask_col = col;
1227             else
1228                 used = 0;
1229             if (used && col >= route_num_cols)
1230                 route_num_cols = col + 1;
1231             p = NULL;
1232         }
1233     }
1234
1235     return 1;
1236 }
1237
1238 /********************************************************************
1239  *
1240  * read_route_table - read the next entry from the route table
1241  */
1242
1243 static int read_route_table(struct rtentry *rt)
1244 {
1245     char *cols[ROUTE_MAX_COLS], *p;
1246     int col;
1247         
1248     memset (rt, '\0', sizeof (struct rtentry));
1249
1250     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1251         return 0;
1252
1253     p = route_buffer;
1254     for (col = 0; col < route_num_cols; ++col) {
1255         cols[col] = strtok(p, route_delims);
1256         if (cols[col] == NULL)
1257             return 0;           /* didn't get enough columns */
1258     }
1259
1260     ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr =
1261         strtoul(cols[route_dest_col], NULL, 16);
1262
1263     ((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr =
1264         strtoul(cols[route_gw_col], NULL, 16);
1265
1266     ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr =
1267         strtoul(cols[route_mask_col], NULL, 16);
1268
1269     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1270     rt->rt_dev   = cols[route_dev_col];
1271
1272     return 1;
1273 }
1274
1275 /********************************************************************
1276  *
1277  * defaultroute_exists - determine if there is a default route
1278  */
1279
1280 static int defaultroute_exists (struct rtentry *rt)
1281 {
1282     int result = 0;
1283
1284     if (!open_route_table())
1285         return 0;
1286
1287     while (read_route_table(rt) != 0) {
1288         if ((rt->rt_flags & RTF_UP) == 0)
1289             continue;
1290
1291         if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L) {
1292             result = 1;
1293             break;
1294         }
1295     }
1296
1297     close_route_table();
1298     return result;
1299 }
1300
1301 /*
1302  * have_route_to - determine if the system has any route to
1303  * a given IP address.  `addr' is in network byte order.
1304  * Return value is 1 if yes, 0 if no, -1 if don't know.
1305  * For demand mode to work properly, we have to ignore routes
1306  * through our own interface.
1307  */
1308 int have_route_to(u_int32_t addr)
1309 {
1310     struct rtentry rt;
1311     int result = 0;
1312
1313     if (!open_route_table())
1314         return -1;              /* don't know */
1315
1316     while (read_route_table(&rt)) {
1317         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1318             continue;
1319         if ((addr & ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr)
1320             == ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr) {
1321             result = 1;
1322             break;
1323         }
1324     }
1325
1326     close_route_table();
1327     return result;
1328 }
1329
1330 /********************************************************************
1331  *
1332  * sifdefaultroute - assign a default route through the address given.
1333  */
1334
1335 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1336   {
1337     struct rtentry rt;
1338
1339     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0)
1340       {
1341         struct in_addr old_gateway =
1342           ((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
1343
1344         if (old_gateway.s_addr != gateway)
1345           {
1346             syslog (LOG_ERR,
1347                     "not replacing existing default route to %s [%s]",
1348                     rt.rt_dev, inet_ntoa (old_gateway));
1349           }
1350         return 0;
1351       }
1352
1353     memset (&rt, '\0', sizeof (rt));
1354     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1355     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1356
1357     if (kernel_version > KVERSION(2,1,0)) {
1358       SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1359       ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
1360     }
1361
1362     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1363     
1364     rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT;
1365     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0)
1366       {
1367         if ( ! ok_error ( errno ))
1368           {
1369             syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m(%d)", errno);
1370           }
1371         return 0;
1372       }
1373
1374     default_route_gateway = gateway;
1375     return 1;
1376   }
1377
1378 /********************************************************************
1379  *
1380  * cifdefaultroute - delete a default route through the address given.
1381  */
1382
1383 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1384   {
1385     struct rtentry rt;
1386
1387     default_route_gateway = 0;
1388
1389     memset (&rt, '\0', sizeof (rt));
1390     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1391     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1392
1393     if (kernel_version > KVERSION(2,1,0)) {
1394       SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1395       ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
1396     }
1397
1398     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1399     
1400     rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT;
1401     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1402       {
1403         if (still_ppp())
1404           {
1405             if ( ! ok_error ( errno ))
1406               {
1407                 syslog (LOG_ERR,
1408                         "default route ioctl(SIOCDELRT): %m(%d)", errno);
1409               }
1410             return 0;
1411           }
1412       }
1413
1414     return 1;
1415   }
1416
1417 /********************************************************************
1418  *
1419  * sifproxyarp - Make a proxy ARP entry for the peer.
1420  */
1421
1422 int sifproxyarp (int unit, u_int32_t his_adr)
1423   {
1424     struct arpreq arpreq;
1425
1426     if (has_proxy_arp == 0)
1427       {
1428         memset (&arpreq, '\0', sizeof(arpreq));
1429     
1430         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1431         ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1432         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1433 /*
1434  * Get the hardware address of an interface on the same subnet
1435  * as our local address.
1436  */
1437         if (!get_ether_addr(his_adr, &arpreq.arp_ha, arpreq.arp_dev))
1438           {
1439             syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP");
1440             return 0;
1441           }
1442         
1443         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0)
1444           {
1445             if ( ! ok_error ( errno ))
1446               {
1447                 syslog(LOG_ERR, "ioctl(SIOCSARP): %m(%d)", errno);
1448               }
1449             return 0;
1450           }
1451       }
1452
1453     proxy_arp_addr = his_adr;
1454     has_proxy_arp = 1;
1455     return 1;
1456   }
1457
1458 /********************************************************************
1459  *
1460  * cifproxyarp - Delete the proxy ARP entry for the peer.
1461  */
1462
1463 int cifproxyarp (int unit, u_int32_t his_adr)
1464   {
1465     struct arpreq arpreq;
1466
1467     if (has_proxy_arp == 1)
1468       {
1469         memset (&arpreq, '\0', sizeof(arpreq));
1470         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1471         ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1472         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1473
1474         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0)
1475           {
1476             if ( ! ok_error ( errno ))
1477               {
1478                 syslog(LOG_WARNING, "ioctl(SIOCDARP): %m(%d)", errno);
1479               }
1480             return 0;
1481           }
1482       }
1483     has_proxy_arp = 0;
1484     return 1;
1485   }
1486      
1487 /********************************************************************
1488  *
1489  * get_ether_addr - get the hardware address of an interface on the
1490  * the same subnet as ipaddr.
1491  */
1492
1493 static int get_ether_addr (u_int32_t ipaddr,
1494                            struct sockaddr *hwaddr,
1495                            char *name)
1496   {
1497     struct ifreq *ifr, *ifend;
1498     u_int32_t ina, mask;
1499     struct ifreq ifreq;
1500     struct ifconf ifc;
1501     struct ifreq ifs[MAX_IFS];
1502     
1503     ifc.ifc_len = sizeof(ifs);
1504     ifc.ifc_req = ifs;
1505     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0)
1506       {
1507         if ( ! ok_error ( errno ))
1508           {
1509             syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m(%d)", errno);
1510           }
1511         return 0;
1512       }
1513
1514     SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1515                 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1516 /*
1517  * Scan through looking for an interface with an Internet
1518  * address on the same subnet as `ipaddr'.
1519  */
1520     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1521     for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
1522       {
1523         if (ifr->ifr_addr.sa_family == AF_INET)
1524           {
1525             ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1526             strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1527             SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1528                         ifreq.ifr_name));
1529 /*
1530  * Check that the interface is up, and not point-to-point
1531  * nor loopback.
1532  */
1533             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1534               {
1535                 continue;
1536               }
1537
1538             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1539               {
1540                 continue;
1541               }
1542 /*
1543  * Get its netmask and check that it's on the right subnet.
1544  */
1545             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1546               {
1547                 continue;
1548               }
1549
1550             mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1551             SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1552                         ip_ntoa(ina), ntohl(mask)));
1553
1554             if (((ipaddr ^ ina) & mask) != 0)
1555               {
1556                 continue;
1557               }
1558             break;
1559           }
1560       }
1561     
1562     if (ifr >= ifend)
1563       {
1564         return 0;
1565       }
1566
1567     memcpy (name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
1568     syslog(LOG_INFO, "found interface %s for proxy arp", name);
1569 /*
1570  * Now get the hardware address.
1571  */
1572     memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1573     if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0)
1574       {
1575         syslog(LOG_ERR, "SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);
1576         return 0;
1577       }
1578
1579     memcpy (hwaddr,
1580             &ifreq.ifr_hwaddr,
1581             sizeof (struct sockaddr));
1582
1583     SYSDEBUG ((LOG_DEBUG,
1584            "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1585                 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1586                 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1587                 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1588                 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1589                 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1590                 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1591                 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1592                 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1593     return 1;
1594   }
1595
1596 /********************************************************************
1597  *
1598  * Return user specified netmask, modified by any mask we might determine
1599  * for address `addr' (in network byte order).
1600  * Here we scan through the system's list of interfaces, looking for
1601  * any non-point-to-point interfaces which might appear to be on the same
1602  * network as `addr'.  If we find any, we OR in their netmask to the
1603  * user-specified netmask.
1604  */
1605
1606 u_int32_t GetMask (u_int32_t addr)
1607   {
1608     u_int32_t mask, nmask, ina;
1609     struct ifreq *ifr, *ifend, ifreq;
1610     struct ifconf ifc;
1611     struct ifreq ifs[MAX_IFS];
1612
1613     addr = ntohl(addr);
1614     
1615     if (IN_CLASSA(addr))        /* determine network mask for address class */
1616       {
1617         nmask = IN_CLASSA_NET;
1618       }
1619     else
1620       {
1621         if (IN_CLASSB(addr))
1622           {
1623             nmask = IN_CLASSB_NET;
1624           }
1625         else
1626           {
1627             nmask = IN_CLASSC_NET;
1628           }
1629       }
1630     
1631     /* class D nets are disallowed by bad_ip_adrs */
1632     mask = netmask | htonl(nmask);
1633 /*
1634  * Scan through the system's network interfaces.
1635  */
1636     ifc.ifc_len = sizeof(ifs);
1637     ifc.ifc_req = ifs;
1638     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0)
1639       {
1640         if ( ! ok_error ( errno ))
1641           {
1642             syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m(%d)", errno);
1643           }
1644         return mask;
1645       }
1646     
1647     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1648     for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
1649       {
1650 /*
1651  * Check the interface's internet address.
1652  */
1653         if (ifr->ifr_addr.sa_family != AF_INET)
1654           {
1655             continue;
1656           }
1657         ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1658         if (((ntohl(ina) ^ addr) & nmask) != 0)
1659           {
1660             continue;
1661           }
1662 /*
1663  * Check that the interface is up, and not point-to-point nor loopback.
1664  */
1665         strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1666         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1667           {
1668             continue;
1669           }
1670         
1671         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1672           {
1673             continue;
1674           }
1675 /*
1676  * Get its netmask and OR it into our mask.
1677  */
1678         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1679           {
1680             continue;
1681           }
1682         mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
1683         break;
1684       }
1685     return mask;
1686   }
1687
1688 /********************************************************************
1689  *
1690  * Internal routine to decode the version.modification.patch level
1691  */
1692
1693 static void decode_version (char *buf, int *version,
1694                             int *modification, int *patch)
1695   {
1696     *version      = (int) strtoul (buf, &buf, 10);
1697     *modification = 0;
1698     *patch        = 0;
1699     
1700     if (*buf == '.')
1701       {
1702         ++buf;
1703         *modification = (int) strtoul (buf, &buf, 10);
1704         if (*buf == '.')
1705           {
1706             ++buf;
1707             *patch = (int) strtoul (buf, &buf, 10);
1708           }
1709       }
1710     
1711     if (*buf != '\0')
1712       {
1713         *version      =
1714         *modification =
1715         *patch        = 0;
1716       }
1717   }
1718
1719 /********************************************************************
1720  *
1721  * Procedure to determine if the PPP line discipline is registered.
1722  */
1723
1724 int
1725 ppp_registered(void)
1726   {
1727     int local_fd;
1728     int init_disc = -1;
1729     int initfdflags;
1730
1731     local_fd = open(devnam, O_NONBLOCK | O_RDWR, 0);
1732     if (local_fd < 0)
1733       {
1734         syslog(LOG_ERR, "Failed to open %s: %m(%d)", devnam, errno);
1735         return 0;
1736       }
1737
1738     initfdflags = fcntl(local_fd, F_GETFL);
1739     if (initfdflags == -1)
1740       {
1741         syslog(LOG_ERR, "Couldn't get device fd flags: %m(%d)", errno);
1742         close (local_fd);
1743         return 0;
1744       }
1745
1746     initfdflags &= ~O_NONBLOCK;
1747     fcntl(local_fd, F_SETFL, initfdflags);
1748 /*
1749  * Read the initial line dicipline and try to put the device into the
1750  * PPP dicipline.
1751  */
1752     if (ioctl(local_fd, TIOCGETD, &init_disc) < 0)
1753       {
1754         syslog(LOG_ERR, "ioctl(TIOCGETD): %m(%d)", errno);
1755         close (local_fd);
1756         return 0;
1757       }
1758     
1759     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0)
1760       {
1761         syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
1762         close (local_fd);
1763         return 0;
1764       }
1765     
1766     if (ioctl(local_fd, TIOCSETD, &init_disc) < 0)
1767       {
1768         syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
1769         close (local_fd);
1770         return 0;
1771       }
1772     
1773     close (local_fd);
1774     return 1;
1775   }
1776
1777 /********************************************************************
1778  *
1779  * ppp_available - check whether the system has any ppp interfaces
1780  * (in fact we check whether we can do an ioctl on ppp0).
1781  */
1782
1783 int ppp_available(void)
1784 {
1785     int s, ok;
1786     struct ifreq ifr;
1787     int    size;
1788     int    my_version, my_modification, my_patch;
1789     extern char *no_ppp_msg;
1790 /*
1791  * Open a socket for doing the ioctl operations.
1792  */    
1793     s = socket(AF_INET, SOCK_DGRAM, 0);
1794     if (s < 0)
1795     {
1796         return 0;
1797     }
1798     
1799     strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1800     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1801 /*
1802  * If the device did not exist then attempt to create one by putting the
1803  * current tty into the PPP discipline. If this works then obtain the
1804  * flags for the device again.
1805  */
1806     if (!ok)
1807     {
1808         if (ppp_registered())
1809         {
1810             strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1811             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1812         }
1813     }
1814 /*
1815  * Ensure that the hardware address is for PPP and not something else
1816  */
1817     if (ok)
1818     {
1819         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1820     }
1821
1822     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1823     {
1824         ok = 0;
1825     }
1826
1827     if (!ok)
1828     {
1829         no_ppp_msg = 
1830           "This system lacks kernel support for PPP.  This could be because\n"
1831           "the PPP kernel module is not loaded, or because the kernel is\n"
1832           "not configured for PPP.  See the README.linux file in the\n"
1833           "ppp-2.3.6 distribution.\n";
1834     }
1835 /*
1836  *  This is the PPP device. Validate the version of the driver at this
1837  *  point to ensure that this program will work with the driver.
1838  */
1839     else
1840     {
1841         char   abBuffer [1024];
1842
1843         ifr.ifr_data = abBuffer;
1844         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1845         if (size < 0) {
1846             syslog(LOG_ERR, "Couldn't read driver version: %m");
1847             ok = 0;
1848             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
1849
1850         } else {
1851             decode_version(abBuffer,
1852                            &driver_version,
1853                            &driver_modification,
1854                            &driver_patch);
1855 /*
1856  * Validate the version of the driver against the version that we used.
1857  */
1858             decode_version(VERSION,
1859                            &my_version,
1860                            &my_modification,
1861                            &my_patch);
1862
1863             /* The version numbers must match */
1864             if (driver_version != my_version)
1865             {
1866                 ok = 0;
1867             }
1868       
1869             /* The modification levels must be legal */
1870             if (driver_modification < 3)
1871             {
1872                 if (driver_modification >= 2) {
1873                     /* we can cope with 2.2.0 and above */
1874                     driver_is_old = 1;
1875                 } else {
1876                     ok = 0;
1877                 }
1878             }
1879
1880             close (s);
1881             if (!ok)
1882             {
1883                 sprintf (route_buffer,
1884                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
1885                          driver_version, driver_modification, driver_patch);
1886
1887                 no_ppp_msg = route_buffer;
1888             }
1889         }
1890     }
1891     return ok;
1892 }
1893
1894 /********************************************************************
1895  *
1896  * Update the wtmp file with the appropriate user name and tty device.
1897  */
1898
1899 void logwtmp (const char *line, const char *name, const char *host)
1900   {
1901     int    wtmp;
1902     struct utmp ut, *utp;
1903     pid_t  mypid = getpid();
1904 /*
1905  * Update the signon database for users.
1906  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1907  */
1908     utmpname(_PATH_UTMP);
1909     setutent();
1910     while ((utp = getutent()) && (utp->ut_pid != mypid))
1911         /* nothing */;
1912
1913     /* Is this call really necessary? There is another one after the 'put' */
1914     endutent();
1915     
1916     if (utp)
1917       {
1918         memcpy(&ut, utp, sizeof(ut));
1919       }
1920     else
1921       {
1922         /* some gettys/telnetds don't initialize utmp... */
1923         memset(&ut, 0, sizeof(ut));
1924       }
1925
1926     if (ut.ut_id[0] == 0)
1927       {
1928         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
1929       }
1930         
1931     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
1932     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1933
1934     time(&ut.ut_time);
1935
1936     ut.ut_type = USER_PROCESS;
1937     ut.ut_pid  = mypid;
1938
1939     /* Insert the host name if one is supplied */
1940     if (*host)
1941       {
1942         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
1943       }
1944
1945     /* Insert the IP address of the remote system if IP is enabled */
1946     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
1947       {
1948         memcpy  (&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
1949                  sizeof(ut.ut_addr));
1950       }
1951         
1952     /* CL: Makes sure that the logout works */
1953     if (*host == 0 && *name==0)
1954       {
1955         ut.ut_host[0]=0;
1956       }
1957
1958     pututline(&ut);
1959     endutent();
1960 /*
1961  * Update the wtmp file.
1962  */
1963     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
1964     if (wtmp >= 0)
1965       {
1966         flock(wtmp, LOCK_EX);
1967
1968         /* we really should check for error on the write for a full disk! */
1969         write (wtmp, (char *)&ut, sizeof(ut));
1970         close (wtmp);
1971
1972         flock(wtmp, LOCK_UN);
1973       }
1974   }
1975
1976 /********************************************************************
1977  * Code for locking/unlocking the serial device.
1978  * This code is derived from chat.c.
1979  */
1980
1981 /*
1982  * lock - create a lock file for the named device
1983  */
1984
1985 int lock (char *dev)
1986   {
1987 #ifdef LOCKLIB
1988     int result;
1989     lock_file = malloc(strlen(dev) + 1);
1990     if (lock_file == NULL)
1991       {
1992         novm("lock file name");
1993       }
1994     strcpy (lock_file, dev);
1995     result = mklock (dev, (void *) 0);
1996
1997     if (result > 0)
1998       {
1999         syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, result);
2000         free (lock_file);
2001         lock_file = NULL;
2002         result = -1;
2003       }
2004     else
2005       {
2006         if (result < 0)
2007           {
2008             syslog (LOG_ERR, "Can't create lock file %s", lock_file);
2009             free (lock_file);
2010             lock_file = NULL;
2011             result = -1;
2012           }
2013       }
2014     return (result);
2015 #else
2016     char hdb_lock_buffer[12];
2017     int fd, n;
2018     int pid = getpid();
2019     char *p;
2020
2021     p = strrchr(dev, '/');
2022     if (p != NULL)
2023       {
2024         dev = ++p;
2025       }
2026
2027     lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1);
2028     if (lock_file == NULL)
2029       {
2030         novm("lock file name");
2031       }
2032
2033     strcpy (lock_file, LOCK_PREFIX);
2034     strcat (lock_file, dev);
2035 /*
2036  * Attempt to create the lock file at this point.
2037  */
2038     while (1)
2039       {
2040         fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
2041         if (fd >= 0)
2042           {
2043             pid = getpid();
2044 #ifndef PID_BINARY
2045             sprintf (hdb_lock_buffer, "%010d\n", pid);
2046             write (fd, hdb_lock_buffer, 11);
2047 #else
2048             write(fd, &pid, sizeof (pid));
2049 #endif
2050             close(fd);
2051             return 0;
2052           }
2053 /*
2054  * If the file exists then check to see if the pid is stale
2055  */
2056         if (errno == EEXIST)
2057           {
2058             fd = open(lock_file, O_RDONLY, 0);
2059             if (fd < 0)
2060               {
2061                 if (errno == ENOENT) /* This is just a timing problem. */
2062                   {
2063                     continue;
2064                   }
2065                 break;
2066               }
2067
2068             /* Read the lock file to find out who has the device locked */
2069             n = read (fd, hdb_lock_buffer, 11);
2070             close (fd);
2071             if (n < 0)
2072               {
2073                 syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
2074                 break;
2075               }
2076
2077             /* See the process still exists. */
2078             if (n > 0)
2079               {
2080 #ifndef PID_BINARY
2081                 hdb_lock_buffer[n] = '\0';
2082                 sscanf (hdb_lock_buffer, " %d", &pid);
2083 #else
2084                 pid = ((int *) hdb_lock_buffer)[0];
2085 #endif
2086                 if (pid == 0 || pid == getpid()
2087                     || (kill(pid, 0) == -1 && errno == ESRCH))
2088                   {
2089                     n = 0;
2090                   }
2091               }
2092
2093             /* If the process does not exist then try to remove the lock */
2094             if (n == 0 && unlink (lock_file) == 0)
2095               {
2096                 syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)",
2097                         dev, pid);
2098                 continue;
2099               }
2100
2101             syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid);
2102             break;
2103           }
2104
2105         syslog(LOG_ERR, "Can't create lock file %s: %m(%d)", lock_file, errno);
2106         break;
2107       }
2108
2109     free(lock_file);
2110     lock_file = NULL;
2111     return -1;
2112 #endif
2113 }
2114
2115
2116 /********************************************************************
2117  *
2118  * unlock - remove our lockfile
2119  */
2120
2121 void unlock(void)
2122   {
2123     if (lock_file)
2124       {
2125 #ifdef LOCKLIB
2126         (void) rmlock (lock_file, (void *) 0);
2127 #else
2128         unlink(lock_file);
2129 #endif
2130         free(lock_file);
2131         lock_file = NULL;
2132       }
2133   }
2134
2135 /********************************************************************
2136  *
2137  * sifvjcomp - config tcp header compression
2138  */
2139
2140 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
2141   {
2142     u_int x = get_flags();
2143
2144     if (vjcomp)
2145       {
2146         if (ioctl (ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
2147           {
2148             if (! ok_error (errno))
2149               {
2150                 syslog (LOG_ERR, "ioctl(PPPIOCSMAXCID): %m(%d)", errno);
2151               }
2152             vjcomp = 0;
2153           }
2154       }
2155
2156     x = vjcomp  ? x | SC_COMP_TCP     : x &~ SC_COMP_TCP;
2157     x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
2158     set_flags (x);
2159
2160     return 1;
2161   }
2162
2163 /********************************************************************
2164  *
2165  * sifup - Config the interface up and enable IP packets to pass.
2166  */
2167
2168 int sifup (int u)
2169   {
2170     struct ifreq ifr;
2171
2172     memset (&ifr, '\0', sizeof (ifr));
2173     strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2174     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0)
2175       {
2176         if (! ok_error (errno))
2177           {
2178             syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2179           }
2180         return 0;
2181       }
2182
2183     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
2184     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0)
2185       {
2186         if (! ok_error (errno))
2187           {
2188             syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2189           }
2190         return 0;
2191       }
2192     if_is_up = 1;
2193     return 1;
2194   }
2195
2196 /********************************************************************
2197  *
2198  * sifdown - Config the interface down and disable IP.
2199  */
2200
2201 int sifdown (int u)
2202   {
2203     struct ifreq ifr;
2204
2205     if_is_up = 0;
2206
2207     memset (&ifr, '\0', sizeof (ifr));
2208     strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2209     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0)
2210       {
2211         if (! ok_error (errno))
2212           {
2213             syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m(%d)", errno);
2214           }
2215         return 0;
2216       }
2217
2218     ifr.ifr_flags &= ~IFF_UP;
2219     ifr.ifr_flags |= IFF_POINTOPOINT;
2220     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0)
2221       {
2222         if (! ok_error (errno))
2223           {
2224             syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m(%d)", errno);
2225           }
2226         return 0;
2227       }
2228     return 1;
2229   }
2230
2231 /********************************************************************
2232  *
2233  * sifaddr - Config the interface IP addresses and netmask.
2234  */
2235
2236 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2237              u_int32_t net_mask)
2238   {
2239     struct ifreq   ifr; 
2240     struct rtentry rt;
2241     
2242     memset (&ifr, '\0', sizeof (ifr));
2243     memset (&rt,  '\0', sizeof (rt));
2244     
2245     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET); 
2246     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); 
2247     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); 
2248
2249     strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2250 /*
2251  *  Set our IP address
2252  */
2253     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr;
2254     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0)
2255       {
2256         if (errno != EEXIST)
2257           {
2258             if (! ok_error (errno))
2259               {
2260                 syslog (LOG_ERR, "ioctl(SIOCAIFADDR): %m(%d)", errno);
2261               }
2262           }
2263         else
2264           {
2265             syslog (LOG_WARNING, "ioctl(SIOCAIFADDR): Address already exists");
2266           }
2267         return (0);
2268       } 
2269 /*
2270  *  Set the gateway address
2271  */
2272     ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr;
2273     if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0)
2274       {
2275         if (! ok_error (errno))
2276           {
2277             syslog (LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m(%d)", errno); 
2278           }
2279         return (0);
2280       } 
2281 /*
2282  *  Set the netmask.
2283  *  For recent kernels, force the netmask to 255.255.255.255.
2284  */
2285     if (kernel_version >= KVERSION(2,1,16))
2286       net_mask = ~0L;
2287     if (net_mask != 0)
2288       {
2289         ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
2290         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0)
2291           {
2292             if (! ok_error (errno))
2293               {
2294                 syslog (LOG_ERR, "ioctl(SIOCSIFNETMASK): %m(%d)", errno); 
2295               }
2296             return (0);
2297           } 
2298       }
2299 /*
2300  *  Add the device route
2301  */
2302     if (kernel_version < KVERSION(2,1,16)) {
2303       SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2304       SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2305       rt.rt_dev = ifname;
2306
2307       ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
2308       ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2309       rt.rt_flags = RTF_UP | RTF_HOST;
2310
2311       if (kernel_version > KVERSION(2,1,0)) {
2312         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2313         ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2314       }
2315
2316       if (ioctl(sock_fd, SIOCADDRT, &rt) < 0)
2317         {
2318           if (! ok_error (errno))
2319             {
2320               syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m(%d)", errno);
2321             }
2322           return (0);
2323         }
2324     }
2325     return 1;
2326   }
2327
2328 /********************************************************************
2329  *
2330  * cifaddr - Clear the interface IP addresses, and delete routes
2331  * through the interface if possible.
2332  */
2333
2334 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2335   {
2336     struct rtentry rt;
2337
2338     if (kernel_version < KVERSION(2,1,16)) {
2339 /*
2340  *  Delete the route through the device
2341  */
2342       memset (&rt, '\0', sizeof (rt));
2343
2344       SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2345       SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2346       rt.rt_dev = ifname;
2347
2348       ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
2349       ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2350       rt.rt_flags = RTF_UP | RTF_HOST;
2351
2352       if (kernel_version > KVERSION(2,1,0)) {
2353         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2354         ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2355       }
2356
2357       if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH)
2358         {
2359           if (still_ppp() && ! ok_error (errno))
2360             {
2361               syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m(%d)", errno);
2362             }
2363           return (0);
2364         }
2365     }
2366     return 1;
2367   }
2368
2369 /********************************************************************
2370  *
2371  * open_loopback - open the device we use for getting packets
2372  * in demand mode.  Under Linux, we use our existing fd
2373  * to the ppp driver.
2374  */
2375 void
2376 open_ppp_loopback(void)
2377   {
2378     int flags, i;
2379     struct termios tios;
2380
2381     master_fd = -1;
2382     for (i = 0; i < 64; ++i) {
2383       sprintf(loop_name, "/dev/pty%c%x", 'p' + i / 16, i % 16);
2384       master_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
2385       if (master_fd >= 0)
2386         break;
2387     }
2388     if (master_fd < 0) {
2389       syslog(LOG_ERR, "No free pty for loopback");
2390       die(1);
2391     }
2392     SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name));
2393     loop_name[5] = 't';
2394     slave_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
2395     if (slave_fd < 0) {
2396       syslog(LOG_ERR, "Couldn't open %s for loopback: %m", loop_name);
2397       die(1);
2398     }
2399
2400     set_ppp_fd(slave_fd);
2401
2402     if (tcgetattr(ppp_fd, &tios) == 0)
2403       {
2404         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2405         tios.c_cflag |= CS8 | CREAD;
2406         tios.c_iflag  = IGNPAR | CLOCAL;
2407         tios.c_oflag  = 0;
2408         tios.c_lflag  = 0;
2409         if (tcsetattr(ppp_fd, TCSAFLUSH, &tios) < 0)
2410           {
2411             syslog(LOG_WARNING, "couldn't set attributes on loopback: %m(%d)", errno);
2412           }
2413       }
2414
2415     flags = fcntl(master_fd, F_GETFL);
2416     if (flags == -1 ||
2417         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2418       {
2419         syslog(LOG_WARNING, "couldn't set master loopback to nonblock: %m(%d)", errno);
2420       }
2421
2422     flags = fcntl(ppp_fd, F_GETFL);
2423     if (flags == -1 ||
2424         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2425       {
2426         syslog(LOG_WARNING, "couldn't set slave loopback to nonblock: %m(%d)", errno);
2427       }
2428
2429     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2430       {
2431         syslog(LOG_ERR, "ioctl(TIOCSETD): %m(%d)", errno);
2432         die(1);
2433       }
2434 /*
2435  * Find out which interface we were given.
2436  */
2437     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2438       { 
2439         syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m(%d)", errno);
2440         die(1);
2441       }
2442 /*
2443  * Enable debug in the driver if requested.
2444  */
2445     set_kdebugflag (kdebugflag);
2446   }
2447
2448 /********************************************************************
2449  *
2450  * restore_loop - reattach the ppp unit to the loopback.
2451  *
2452  * The kernel ppp driver automatically reattaches the ppp unit to
2453  * the loopback if the serial port is set to a line discipline other
2454  * than ppp, or if it detects a modem hangup.  The former will happen
2455  * in disestablish_ppp if the latter hasn't already happened, so we
2456  * shouldn't need to do anything.
2457  *
2458  * Just to be sure, set the real serial port to the normal discipline.
2459  */
2460
2461 void
2462 restore_loop(void)
2463   {
2464     if (ppp_fd != slave_fd)
2465       {
2466         (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2467         set_ppp_fd(slave_fd);
2468       }
2469   }
2470
2471 /********************************************************************
2472  *
2473  * sifnpmode - Set the mode for handling packets for a given NP.
2474  */
2475
2476 int
2477 sifnpmode(u, proto, mode)
2478     int u;
2479     int proto;
2480     enum NPmode mode;
2481 {
2482     struct npioctl npi;
2483
2484     npi.protocol = proto;
2485     npi.mode     = mode;
2486     if (ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0)
2487       {
2488         if (! ok_error (errno))
2489           {
2490             syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE, %d, %d): %m(%d)",
2491                    proto, mode, errno);
2492             syslog(LOG_ERR, "ppp_fd=%d slave_fd=%d\n", ppp_fd, slave_fd);
2493           }
2494         return 0;
2495       }
2496     return 1;
2497   }
2498
2499 \f
2500 /********************************************************************
2501  *
2502  * sipxfaddr - Config the interface IPX networknumber
2503  */
2504
2505 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2506   {
2507     int    result = 1;
2508
2509 #ifdef IPX_CHANGE
2510     int    skfd; 
2511     struct ifreq         ifr;
2512     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2513
2514     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2515     if (skfd < 0)
2516       { 
2517         if (! ok_error (errno))
2518           {
2519             syslog (LOG_DEBUG, "socket(AF_IPX): %m(%d)", errno);
2520           }
2521         result = 0;
2522       }
2523     else
2524       {
2525         memset (&ifr, '\0', sizeof (ifr));
2526         strcpy (ifr.ifr_name, ifname);
2527
2528         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2529         sipx->sipx_family  = AF_IPX;
2530         sipx->sipx_port    = 0;
2531         sipx->sipx_network = htonl (network);
2532         sipx->sipx_type    = IPX_FRAME_ETHERII;
2533         sipx->sipx_action  = IPX_CRTITF;
2534 /*
2535  *  Set the IPX device
2536  */
2537         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0)
2538           {
2539             result = 0;
2540             if (errno != EEXIST)
2541               {
2542                 if (! ok_error (errno))
2543                   {
2544                     syslog (LOG_DEBUG,
2545                             "ioctl(SIOCAIFADDR, CRTITF): %m(%d)", errno);
2546                   }
2547               }
2548             else
2549               {
2550                 syslog (LOG_WARNING,
2551                         "ioctl(SIOCAIFADDR, CRTITF): Address already exists");
2552               }
2553           }
2554         close (skfd);
2555       }
2556 #endif
2557     return result;
2558   }
2559
2560 /********************************************************************
2561  *
2562  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2563  *             are removed and the device is no longer able to pass IPX
2564  *             frames.
2565  */
2566
2567 int cipxfaddr (int unit)
2568   {
2569     int    result = 1;
2570
2571 #ifdef IPX_CHANGE
2572     int    skfd; 
2573     struct ifreq         ifr;
2574     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2575
2576     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2577     if (skfd < 0)
2578       { 
2579         if (! ok_error (errno))
2580           {
2581             syslog (LOG_DEBUG, "socket(AF_IPX): %m(%d)", errno);
2582           }
2583         result = 0;
2584       }
2585     else
2586       {
2587         memset (&ifr, '\0', sizeof (ifr));
2588         strcpy (ifr.ifr_name, ifname);
2589
2590         sipx->sipx_type    = IPX_FRAME_ETHERII;
2591         sipx->sipx_action  = IPX_DLTITF;
2592         sipx->sipx_family  = AF_IPX;
2593 /*
2594  *  Set the IPX device
2595  */
2596         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0)
2597           {
2598             if (! ok_error (errno))
2599               {
2600                 syslog (LOG_INFO,
2601                         "ioctl(SIOCAIFADDR, IPX_DLTITF): %m(%d)", errno);
2602               }
2603             result = 0;
2604           }
2605         close (skfd);
2606       }
2607 #endif
2608     return result;
2609   }
2610
2611 /*
2612  * daemon - Detach us from controlling terminal session.
2613  */
2614 int
2615 daemon(nochdir, noclose)
2616     int nochdir, noclose;
2617 {
2618     int pid;
2619
2620     if ((pid = fork()) < 0)
2621         return -1;
2622     if (pid != 0)
2623         exit(0);                /* parent dies */
2624     setsid();
2625     if (!nochdir)
2626         chdir("/");
2627     if (!noclose) {
2628         fclose(stdin);          /* don't need stdin, stdout, stderr */
2629         fclose(stdout);
2630         fclose(stderr);
2631     }
2632     return 0;
2633 }
2634
2635 /*
2636  * Use the hostname as part of the random number seed.
2637  */
2638 int
2639 get_host_seed()
2640 {
2641     int h;
2642     char *p = hostname;
2643
2644     h = 407;
2645     for (p = hostname; *p != 0; ++p)
2646         h = h * 37 + *p;
2647     return h;
2648 }
2649
2650 /********************************************************************
2651  *
2652  * sys_check_options - check the options that the user specified
2653  */
2654
2655 int
2656 sys_check_options(void)
2657   {
2658 #ifdef IPX_CHANGE
2659     struct stat stat_buf;
2660 /*
2661  * Disable the IPX protocol if the support is not present in the kernel.
2662  * If we disable it then ensure that IP support is enabled.
2663  */
2664     while (ipxcp_protent.enabled_flag)
2665       {
2666         if (path_to_procfs())
2667           {
2668             strcat (route_buffer, "/net/ipx_interface");
2669             if (lstat (route_buffer, &stat_buf) >= 0)
2670               {
2671                 break;
2672               }
2673           }
2674         syslog (LOG_ERR, "IPX support is not present in the kernel\n");
2675         ipxcp_protent.enabled_flag = 0;
2676         ipcp_protent.enabled_flag  = 1;
2677         break;
2678       }
2679 #endif
2680     if (demand && driver_is_old) {
2681       option_error("demand dialling is not supported by kernel driver version "
2682                    "%d.%d.%d", driver_version, driver_modification,
2683                    driver_patch);
2684       return 0;
2685     }
2686     return 1;
2687   }