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