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