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