]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
ba25a93ec843a653635adda286955dc3a603da99
[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     close(sock_fd);
285     sock_fd = -1;
286     closelog();
287 }
288
289 /********************************************************************
290  *
291  * set_kdebugflag - Define the debugging level for the kernel
292  */
293
294 static int set_kdebugflag (int requested_level)
295 {
296     if (ioctl(ppp_fd, PPPIOCSDEBUG, &requested_level) < 0) {
297         if ( ! ok_error (errno) )
298             error("ioctl(PPPIOCSDEBUG): %m");
299         return (0);
300     }
301     SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
302                 requested_level));
303     return (1);
304 }
305
306 /********************************************************************
307  *
308  * establish_ppp - Turn the serial port into a ppp interface.
309  */
310
311 int establish_ppp (int tty_fd)
312 {
313     int x;
314 /*
315  * The current PPP device will be the tty file.
316  */
317     set_ppp_fd (tty_fd);
318 /*
319  * Ensure that the tty device is in exclusive mode.
320  */
321     if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
322         if ( ! ok_error ( errno ))
323             warn("ioctl(TIOCEXCL): %m");
324     }
325 /*
326  * Demand mode - prime the old ppp device to relinquish the unit.
327  */
328     if (demand && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0)
329         fatal("ioctl(transfer ppp unit): %m(%d)", errno);
330 /*
331  * Set the current tty to the PPP discpline
332  */
333     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) {
334         if ( ! ok_error (errno) )
335             fatal("ioctl(TIOCSETD): %m(%d)", errno);
336     }
337 /*
338  * Find out which interface we were given.
339  */
340     if (ioctl(ppp_fd, PPPIOCGUNIT, &x) < 0) {   
341         if ( ! ok_error (errno))
342             fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
343     }
344 /*
345  * Check that we got the same unit again.
346  */
347     if (demand) {
348         if (x != ifunit)
349             fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
350     }
351
352     ifunit = x;
353 /*
354  * Enable debug in the driver if requested.
355  */
356     if (!demand)
357         set_kdebugflag (kdebugflag);
358
359     set_flags (get_flags() & ~(SC_RCV_B7_0 | SC_RCV_B7_1 |
360                                SC_RCV_EVNP | SC_RCV_ODDP));
361
362     SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
363             driver_version, driver_modification, driver_patch));
364 /*
365  * Fetch the initial file flags and reset blocking mode on the file.
366  */
367     initfdflags = fcntl(ppp_fd, F_GETFL);
368
369     if (initfdflags == -1 ||
370         fcntl(ppp_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
371         if ( ! ok_error (errno))
372             warn("Couldn't set device to non-blocking mode: %m");
373     }
374
375     return ppp_fd;
376 }
377
378 /********************************************************************
379  *
380  * disestablish_ppp - Restore the serial port to normal operation.
381  * This shouldn't call die() because it's called from die().
382  */
383
384 void disestablish_ppp(int tty_fd)
385 {
386 /*
387  * Attempt to restore the previous tty settings
388  */
389     if (!hungup) {
390 /*
391  * Restore the previous line discipline
392  */
393         if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
394             if ( ! ok_error (errno))
395                 error("ioctl(TIOCSETD, N_TTY): %m");
396         }
397         
398         if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
399             if ( ! ok_error (errno))
400                 warn("ioctl(TIOCNXCL): %m(%d)", errno);
401         }
402
403         /* Reset non-blocking mode on fd. */
404         if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
405             if ( ! ok_error (errno))
406                 warn("Couldn't restore device fd flags: %m");
407         }
408     }
409     initfdflags = -1;
410 }
411
412 /********************************************************************
413  *
414  * clean_check - Fetch the flags for the device and generate
415  * appropriate error messages.
416  */
417 void clean_check(void)
418 {
419     int x;
420     char *s;
421
422     if (still_ppp()) {
423         if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
424             s = NULL;
425             switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
426             case SC_RCV_B7_0:
427             case SC_RCV_B7_0 | SC_RCV_EVNP:
428             case SC_RCV_B7_0 | SC_RCV_ODDP:
429             case SC_RCV_B7_0 | SC_RCV_ODDP | SC_RCV_EVNP:
430                 s = "all had bit 7 set to 1";
431                 break;
432                 
433             case SC_RCV_B7_1:
434             case SC_RCV_B7_1 | SC_RCV_EVNP:
435             case SC_RCV_B7_1 | SC_RCV_ODDP:
436             case SC_RCV_B7_1 | SC_RCV_ODDP | SC_RCV_EVNP:
437                 s = "all had bit 7 set to 0";
438                 break;
439                 
440             case SC_RCV_EVNP:
441                 s = "all had odd parity";
442                 break;
443                 
444             case SC_RCV_ODDP:
445                 s = "all had even parity";
446                 break;
447             }
448             
449             if (s != NULL) {
450                 warn("Receive serial link is not 8-bit clean:");
451                 warn("Problem: %s", s);
452             }
453         }
454     }
455 }
456         
457
458 /*
459  * List of valid speeds.
460  */
461
462 struct speed {
463     int speed_int, speed_val;
464 } speeds[] = {
465 #ifdef B50
466     { 50, B50 },
467 #endif
468 #ifdef B75
469     { 75, B75 },
470 #endif
471 #ifdef B110
472     { 110, B110 },
473 #endif
474 #ifdef B134
475     { 134, B134 },
476 #endif
477 #ifdef B150
478     { 150, B150 },
479 #endif
480 #ifdef B200
481     { 200, B200 },
482 #endif
483 #ifdef B300
484     { 300, B300 },
485 #endif
486 #ifdef B600
487     { 600, B600 },
488 #endif
489 #ifdef B1200
490     { 1200, B1200 },
491 #endif
492 #ifdef B1800
493     { 1800, B1800 },
494 #endif
495 #ifdef B2000
496     { 2000, B2000 },
497 #endif
498 #ifdef B2400
499     { 2400, B2400 },
500 #endif
501 #ifdef B3600
502     { 3600, B3600 },
503 #endif
504 #ifdef B4800
505     { 4800, B4800 },
506 #endif
507 #ifdef B7200
508     { 7200, B7200 },
509 #endif
510 #ifdef B9600
511     { 9600, B9600 },
512 #endif
513 #ifdef B19200
514     { 19200, B19200 },
515 #endif
516 #ifdef B38400
517     { 38400, B38400 },
518 #endif
519 #ifdef B57600
520     { 57600, B57600 },
521 #endif
522 #ifdef B115200
523     { 115200, B115200 },
524 #endif
525 #ifdef EXTA
526     { 19200, EXTA },
527 #endif
528 #ifdef EXTB
529     { 38400, EXTB },
530 #endif
531 #ifdef B230400
532     { 230400, B230400 },
533 #endif
534 #ifdef B460800
535     { 460800, B460800 },
536 #endif
537     { 0, 0 }
538 };
539
540 /********************************************************************
541  *
542  * Translate from bits/second to a speed_t.
543  */
544
545 static int translate_speed (int bps)
546 {
547     struct speed *speedp;
548
549     if (bps != 0) {
550         for (speedp = speeds; speedp->speed_int; speedp++) {
551             if (bps == speedp->speed_int)
552                 return speedp->speed_val;
553         }
554         warn("speed %d not supported", bps);
555     }
556     return 0;
557 }
558
559 /********************************************************************
560  *
561  * Translate from a speed_t to bits/second.
562  */
563
564 static int baud_rate_of (int speed)
565 {
566     struct speed *speedp;
567     
568     if (speed != 0) {
569         for (speedp = speeds; speedp->speed_int; speedp++) {
570             if (speed == speedp->speed_val)
571                 return speedp->speed_int;
572         }
573     }
574     return 0;
575 }
576
577 /********************************************************************
578  *
579  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
580  * at the requested speed, etc.  If `local' is true, set CLOCAL
581  * regardless of whether the modem option was specified.
582  */
583
584 void set_up_tty(int tty_fd, int local)
585 {
586     int speed;
587     struct termios tios;
588
589     setdtr(tty_fd, 1);
590     if (tcgetattr(tty_fd, &tios) < 0) {
591         if (!ok_error(errno))
592             fatal("tcgetattr: %m(%d)", errno);
593         return;
594     }
595     
596     if (!restore_term)
597         inittermios = tios;
598     
599     tios.c_cflag     &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
600     tios.c_cflag     |= CS8 | CREAD | HUPCL;
601
602     tios.c_iflag      = IGNBRK | IGNPAR;
603     tios.c_oflag      = 0;
604     tios.c_lflag      = 0;
605     tios.c_cc[VMIN]   = 1;
606     tios.c_cc[VTIME]  = 0;
607     
608     if (local || !modem)
609         tios.c_cflag ^= (CLOCAL | HUPCL);
610
611     switch (crtscts) {
612     case 1:
613         tios.c_cflag |= CRTSCTS;
614         break;
615
616     case -2:
617         tios.c_iflag     |= IXON | IXOFF;
618         tios.c_cc[VSTOP]  = 0x13;       /* DC3 = XOFF = ^S */
619         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
620         break;
621
622     case -1:
623         tios.c_cflag &= ~CRTSCTS;
624         break;
625
626     default:
627         break;
628     }
629     
630     speed = translate_speed(inspeed);
631     if (speed) {
632         cfsetospeed (&tios, speed);
633         cfsetispeed (&tios, speed);
634     }
635 /*
636  * We can't proceed if the serial port speed is B0,
637  * since that implies that the serial port is disabled.
638  */
639     else {
640         speed = cfgetospeed(&tios);
641         if (speed == B0)
642             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
643     }
644
645     if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0)
646         if (!ok_error(errno))
647             fatal("tcsetattr: %m");
648     
649     baud_rate    = baud_rate_of(speed);
650     restore_term = 1;
651 }
652
653 /********************************************************************
654  *
655  * setdtr - control the DTR line on the serial port.
656  * This is called from die(), so it shouldn't call die().
657  */
658
659 void setdtr (int tty_fd, int on)
660 {
661     int modembits = TIOCM_DTR;
662
663     ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
664 }
665
666 /********************************************************************
667  *
668  * restore_tty - restore the terminal to the saved settings.
669  */
670
671 void restore_tty (int tty_fd)
672 {
673     if (restore_term) {
674         restore_term = 0;
675 /*
676  * Turn off echoing, because otherwise we can get into
677  * a loop with the tty and the modem echoing to each other.
678  * We presume we are the sole user of this tty device, so
679  * when we close it, it will revert to its defaults anyway.
680  */
681         if (!default_device)
682             inittermios.c_lflag &= ~(ECHO | ECHONL);
683         
684         if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
685             if (! ok_error (errno))
686                 warn("tcsetattr: %m");
687         }
688     }
689 }
690
691 /********************************************************************
692  *
693  * output - Output PPP packet.
694  */
695
696 void output (int unit, unsigned char *p, int len)
697 {
698     if (debug)
699         dbglog("sent %P", p, len);
700     
701     if (write(ppp_fd, p, len) < 0) {
702         if (errno == EWOULDBLOCK || errno == ENOBUFS
703             || errno == ENXIO || errno == EIO || errno == EINTR)
704             warn("write: warning: %m (%d)", errno);
705         else
706             error("write: %m (%d)", errno);
707     }
708 }
709
710 /********************************************************************
711  *
712  * wait_input - wait until there is data available,
713  * for the length of time specified by *timo (indefinite
714  * if timo is NULL).
715  */
716
717 void wait_input(struct timeval *timo)
718 {
719     fd_set ready;
720     int n;
721
722     ready = in_fds;
723     n = select(max_in_fd + 1, &ready, NULL, &ready, timo);
724     if (n < 0 && errno != EINTR)
725         fatal("select: %m(%d)", errno);
726 }
727
728 /*
729  * add_fd - add an fd to the set that wait_input waits for.
730  */
731 void add_fd(int fd)
732 {
733     FD_SET(fd, &in_fds);
734     if (fd > max_in_fd)
735         max_in_fd = fd;
736 }
737
738 /*
739  * remove_fd - remove an fd from the set that wait_input waits for.
740  */
741 void remove_fd(int fd)
742 {
743     FD_CLR(fd, &in_fds);
744 }
745
746 #if 0
747 /********************************************************************
748  *
749  * wait_loop_output - wait until there is data available on the
750  * loopback, for the length of time specified by *timo (indefinite
751  * if timo is NULL).
752  */
753 void wait_loop_output(timo)
754     struct timeval *timo;
755 {
756     fd_set ready;
757     int n;
758
759     FD_ZERO(&ready);
760     FD_SET(master_fd, &ready);
761     n = select(master_fd + 1, &ready, NULL, &ready, timo);
762     if (n < 0 && errno != EINTR)
763         fatal("select: %m(%d)", errno);
764 }
765
766 /********************************************************************
767  *
768  * wait_time - wait for a given length of time or until a
769  * signal is received.
770  */
771
772 void wait_time(timo)
773     struct timeval *timo;
774 {
775     int n;
776
777     n = select(0, NULL, NULL, NULL, timo);
778     if (n < 0 && errno != EINTR)
779         fatal("select: %m(%d)", errno);
780 }
781 #endif
782
783 /********************************************************************
784  *
785  * read_packet - get a PPP packet from the serial device.
786  */
787
788 int read_packet (unsigned char *buf)
789 {
790     int len;
791   
792     len = read(ppp_fd, buf, PPP_MTU + PPP_HDRLEN);
793     if (len < 0) {
794         if (errno == EWOULDBLOCK || errno == EIO)
795             return -1;
796         fatal("read: %m(%d)", errno);
797     }
798     return len;
799 }
800
801 /********************************************************************
802  *
803  * get_loop_output - get outgoing packets from the ppp device,
804  * and detect when we want to bring the real link up.
805  * Return value is 1 if we need to bring up the link, 0 otherwise.
806  */
807 int
808 get_loop_output(void)
809 {
810     int rv = 0;
811     int n  = read(master_fd, inbuf, sizeof(inbuf));
812
813     while (n > 0) {
814         if (loop_chars(inbuf, n))
815             rv = 1;
816         n = read(master_fd, inbuf, sizeof(inbuf));
817     }
818
819     if (n == 0)
820         fatal("eof on loopback");
821
822     if (errno != EWOULDBLOCK)
823         fatal("read from loopback: %m(%d)", errno);
824     
825     return rv;
826 }
827
828 /********************************************************************
829  *
830  * ppp_send_config - configure the transmit characteristics of
831  * the ppp interface.
832  */
833
834 void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp)
835 {
836     u_int x;
837     struct ifreq ifr;
838   
839     SYSDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu));
840 /*
841  * Ensure that the link is still up.
842  */
843     if (!still_ppp())
844         return;
845 /*
846  * Set the MTU and other parameters for the ppp device
847  */
848     memset (&ifr, '\0', sizeof (ifr));
849     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
850     ifr.ifr_mtu = mtu;
851         
852     if (ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
853         fatal("ioctl(SIOCSIFMTU): %m(%d)", errno);
854         
855     SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap));
856     if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
857         if (!ok_error(errno))
858             fatal("ioctl(PPPIOCSASYNCMAP): %m(%d)", errno);
859         return;
860     }
861     
862     x = get_flags();
863     x = pcomp  ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
864     x = accomp ? x | SC_COMP_AC   : x & ~SC_COMP_AC;
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 init_disc = -1;
1569     int initfdflags;
1570
1571     local_fd = open(devnam, O_NONBLOCK | O_RDWR, 0);
1572     if (local_fd < 0) {
1573         error("Failed to open %s: %m(%d)", devnam, errno);
1574         return 0;
1575     }
1576
1577     initfdflags = fcntl(local_fd, F_GETFL);
1578     if (initfdflags == -1) {
1579         error("Couldn't get device fd flags: %m(%d)", errno);
1580         close (local_fd);
1581         return 0;
1582     }
1583
1584     initfdflags &= ~O_NONBLOCK;
1585     fcntl(local_fd, F_SETFL, initfdflags);
1586 /*
1587  * Read the initial line dicipline and try to put the device into the
1588  * PPP dicipline.
1589  */
1590     if (ioctl(local_fd, TIOCGETD, &init_disc) < 0) {
1591         error("ioctl(TIOCGETD): %m(%d)", errno);
1592         close (local_fd);
1593         return 0;
1594     }
1595     
1596     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1597         error("ioctl(TIOCSETD): %m(%d)", errno);
1598         close (local_fd);
1599         return 0;
1600     }
1601     
1602     if (ioctl(local_fd, TIOCSETD, &init_disc) < 0) {
1603         error("ioctl(TIOCSETD): %m(%d)", errno);
1604         close (local_fd);
1605         return 0;
1606     }
1607     
1608     close (local_fd);
1609     return 1;
1610 }
1611
1612 /********************************************************************
1613  *
1614  * ppp_available - check whether the system has any ppp interfaces
1615  * (in fact we check whether we can do an ioctl on ppp0).
1616  */
1617
1618 int ppp_available(void)
1619 {
1620     int s, ok;
1621     struct ifreq ifr;
1622     int    size;
1623     int    my_version, my_modification, my_patch;
1624     extern char *no_ppp_msg;
1625 /*
1626  * Open a socket for doing the ioctl operations.
1627  */    
1628     s = socket(AF_INET, SOCK_DGRAM, 0);
1629     if (s < 0)
1630         return 0;
1631     
1632     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1633     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1634 /*
1635  * If the device did not exist then attempt to create one by putting the
1636  * current tty into the PPP discipline. If this works then obtain the
1637  * flags for the device again.
1638  */
1639     if (!ok) {
1640         if (ppp_registered()) {
1641             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1642             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1643         }
1644     }
1645 /*
1646  * Ensure that the hardware address is for PPP and not something else
1647  */
1648     if (ok)
1649         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1650
1651     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1652         ok = 0;
1653
1654     if (!ok)
1655         no_ppp_msg = 
1656           "This system lacks kernel support for PPP.  This could be because\n"
1657           "the PPP kernel module is not loaded, or because the kernel is\n"
1658           "not configured for PPP.  See the README.linux file in the\n"
1659           "ppp-2.3.6 distribution.\n";
1660
1661 /*
1662  *  This is the PPP device. Validate the version of the driver at this
1663  *  point to ensure that this program will work with the driver.
1664  */
1665     else {
1666         char   abBuffer [1024];
1667
1668         ifr.ifr_data = abBuffer;
1669         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1670         if (size < 0) {
1671             error("Couldn't read driver version: %m");
1672             ok = 0;
1673             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
1674
1675         } else {
1676             decode_version(abBuffer,
1677                            &driver_version,
1678                            &driver_modification,
1679                            &driver_patch);
1680 /*
1681  * Validate the version of the driver against the version that we used.
1682  */
1683             decode_version(VERSION,
1684                            &my_version,
1685                            &my_modification,
1686                            &my_patch);
1687
1688             /* The version numbers must match */
1689             if (driver_version != my_version)
1690                 ok = 0;
1691       
1692             /* The modification levels must be legal */
1693             if (driver_modification < 3) {
1694                 if (driver_modification >= 2) {
1695                     /* we can cope with 2.2.0 and above */
1696                     driver_is_old = 1;
1697                 } else {
1698                     ok = 0;
1699                 }
1700             }
1701
1702             close (s);
1703             if (!ok) {
1704                 slprintf(route_buffer, sizeof(route_buffer),
1705                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
1706                          driver_version, driver_modification, driver_patch);
1707
1708                 no_ppp_msg = route_buffer;
1709             }
1710         }
1711     }
1712     return ok;
1713 }
1714
1715 /********************************************************************
1716  *
1717  * Update the wtmp file with the appropriate user name and tty device.
1718  */
1719
1720 void logwtmp (const char *line, const char *name, const char *host)
1721 {
1722     int    wtmp;
1723     struct utmp ut, *utp;
1724     pid_t  mypid = getpid();
1725 /*
1726  * Update the signon database for users.
1727  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1728  */
1729     utmpname(_PATH_UTMP);
1730     setutent();
1731     while ((utp = getutent()) && (utp->ut_pid != mypid))
1732         /* nothing */;
1733
1734     /* Is this call really necessary? There is another one after the 'put' */
1735     endutent();
1736     
1737     if (utp)
1738         memcpy(&ut, utp, sizeof(ut));
1739     else
1740         /* some gettys/telnetds don't initialize utmp... */
1741         memset(&ut, 0, sizeof(ut));
1742
1743     if (ut.ut_id[0] == 0)
1744         strlcpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
1745         
1746     strlcpy(ut.ut_user, name, sizeof(ut.ut_user));
1747     strlcpy(ut.ut_line, line, sizeof(ut.ut_line));
1748
1749     time(&ut.ut_time);
1750
1751     ut.ut_type = USER_PROCESS;
1752     ut.ut_pid  = mypid;
1753
1754     /* Insert the host name if one is supplied */
1755     if (*host)
1756         strlcpy (ut.ut_host, host, sizeof(ut.ut_host));
1757
1758     /* Insert the IP address of the remote system if IP is enabled */
1759     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
1760         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
1761                  sizeof(ut.ut_addr));
1762         
1763     /* CL: Makes sure that the logout works */
1764     if (*host == 0 && *name==0)
1765         ut.ut_host[0]=0;
1766
1767     pututline(&ut);
1768     endutent();
1769 /*
1770  * Update the wtmp file.
1771  */
1772     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
1773     if (wtmp >= 0) {
1774         flock(wtmp, LOCK_EX);
1775
1776         /* we really should check for error on the write for a full disk! */
1777         write (wtmp, (char *)&ut, sizeof(ut));
1778         close (wtmp);
1779
1780         flock(wtmp, LOCK_UN);
1781     }
1782 }
1783
1784 /********************************************************************
1785  * Code for locking/unlocking the serial device.
1786  * This code is derived from chat.c.
1787  */
1788
1789 /*
1790  * lock - create a lock file for the named device
1791  */
1792
1793 int lock (char *dev)
1794 {
1795 #ifdef LOCKLIB
1796     int result;
1797     lock_file = strdup(dev);
1798     if (lock_file == NULL)
1799         novm("lock file name");
1800     result = mklock (dev, (void *) 0);
1801
1802     if (result > 0) {
1803         notice("Device %s is locked by pid %d", dev, result);
1804         free (lock_file);
1805         lock_file = NULL;
1806         result = -1;
1807     }
1808     else {
1809         if (result < 0) {
1810             error("Can't create lock file %s", lock_file);
1811             free (lock_file);
1812             lock_file = NULL;
1813             result = -1;
1814         }
1815     }
1816     return (result);
1817 #else
1818     char hdb_lock_buffer[12];
1819     int fd, n;
1820     int pid = getpid();
1821     char *p;
1822     size_t l;
1823
1824     p = strrchr(dev, '/');
1825     if (p != NULL)
1826         dev = ++p;
1827
1828     l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
1829     lock_file = malloc(l);
1830     if (lock_file == NULL)
1831         novm("lock file name");
1832
1833     slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
1834 /*
1835  * Attempt to create the lock file at this point.
1836  */
1837     while (1) {
1838         fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
1839         if (fd >= 0) {
1840             pid = getpid();
1841 #ifndef PID_BINARY
1842             slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%010d\n", pid);
1843             write (fd, hdb_lock_buffer, 11);
1844 #else
1845             write(fd, &pid, sizeof (pid));
1846 #endif
1847             close(fd);
1848             return 0;
1849         }
1850 /*
1851  * If the file exists then check to see if the pid is stale
1852  */
1853         if (errno == EEXIST) {
1854             fd = open(lock_file, O_RDONLY, 0);
1855             if (fd < 0) {
1856                 if (errno == ENOENT) /* This is just a timing problem. */
1857                     continue;
1858                 break;
1859             }
1860
1861             /* Read the lock file to find out who has the device locked */
1862             n = read (fd, hdb_lock_buffer, 11);
1863             close (fd);
1864             if (n < 0) {
1865                 error("Can't read pid from lock file %s", lock_file);
1866                 break;
1867             }
1868
1869             /* See the process still exists. */
1870             if (n > 0) {
1871 #ifndef PID_BINARY
1872                 hdb_lock_buffer[n] = '\0';
1873                 sscanf (hdb_lock_buffer, " %d", &pid);
1874 #else
1875                 pid = ((int *) hdb_lock_buffer)[0];
1876 #endif
1877                 if (pid == 0 || pid == getpid()
1878                     || (kill(pid, 0) == -1 && errno == ESRCH))
1879                     n = 0;
1880             }
1881
1882             /* If the process does not exist then try to remove the lock */
1883             if (n == 0 && unlink (lock_file) == 0) {
1884                 notice("Removed stale lock on %s (pid %d)",
1885                         dev, pid);
1886                 continue;
1887             }
1888
1889             notice("Device %s is locked by pid %d", dev, pid);
1890             break;
1891         }
1892
1893         error("Can't create lock file %s: %m(%d)", lock_file, errno);
1894         break;
1895     }
1896
1897     free(lock_file);
1898     lock_file = NULL;
1899     return -1;
1900 #endif
1901 }
1902
1903
1904 /********************************************************************
1905  *
1906  * unlock - remove our lockfile
1907  */
1908
1909 void unlock(void)
1910 {
1911     if (lock_file) {
1912 #ifdef LOCKLIB
1913         (void) rmlock (lock_file, (void *) 0);
1914 #else
1915         unlink(lock_file);
1916 #endif
1917         free(lock_file);
1918         lock_file = NULL;
1919     }
1920 }
1921
1922 /********************************************************************
1923  *
1924  * sifvjcomp - config tcp header compression
1925  */
1926
1927 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
1928 {
1929     u_int x = get_flags();
1930
1931     if (vjcomp) {
1932         if (ioctl (ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
1933             if (! ok_error (errno))
1934                 error("ioctl(PPPIOCSMAXCID): %m(%d)", errno);
1935             vjcomp = 0;
1936         }
1937     }
1938
1939     x = vjcomp  ? x | SC_COMP_TCP     : x &~ SC_COMP_TCP;
1940     x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
1941     set_flags (x);
1942
1943     return 1;
1944 }
1945
1946 /********************************************************************
1947  *
1948  * sifup - Config the interface up and enable IP packets to pass.
1949  */
1950
1951 int sifup (int u)
1952 {
1953     struct ifreq ifr;
1954
1955     memset (&ifr, '\0', sizeof (ifr));
1956     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1957     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
1958         if (! ok_error (errno))
1959             error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
1960         return 0;
1961     }
1962
1963     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
1964     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
1965         if (! ok_error (errno))
1966             error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
1967         return 0;
1968     }
1969     if_is_up = 1;
1970     return 1;
1971 }
1972
1973 /********************************************************************
1974  *
1975  * sifdown - Config the interface down and disable IP.
1976  */
1977
1978 int sifdown (int u)
1979 {
1980     struct ifreq ifr;
1981
1982     if_is_up = 0;
1983
1984     memset (&ifr, '\0', sizeof (ifr));
1985     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1986     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
1987         if (! ok_error (errno))
1988             error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
1989         return 0;
1990     }
1991
1992     ifr.ifr_flags &= ~IFF_UP;
1993     ifr.ifr_flags |= IFF_POINTOPOINT;
1994     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
1995         if (! ok_error (errno))
1996             error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
1997         return 0;
1998     }
1999     return 1;
2000 }
2001
2002 /********************************************************************
2003  *
2004  * sifaddr - Config the interface IP addresses and netmask.
2005  */
2006
2007 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2008              u_int32_t net_mask)
2009 {
2010     struct ifreq   ifr; 
2011     struct rtentry rt;
2012     
2013     memset (&ifr, '\0', sizeof (ifr));
2014     memset (&rt,  '\0', sizeof (rt));
2015     
2016     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET); 
2017     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); 
2018     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); 
2019
2020     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2021 /*
2022  *  Set our IP address
2023  */
2024     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr;
2025     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2026         if (errno != EEXIST) {
2027             if (! ok_error (errno))
2028                 error("ioctl(SIOCAIFADDR): %m(%d)", errno);
2029         }
2030         else {
2031             warn("ioctl(SIOCAIFADDR): Address already exists");
2032         }
2033         return (0);
2034     }
2035 /*
2036  *  Set the gateway address
2037  */
2038     ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr;
2039     if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2040         if (! ok_error (errno))
2041             error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno); 
2042         return (0);
2043     } 
2044 /*
2045  *  Set the netmask.
2046  *  For recent kernels, force the netmask to 255.255.255.255.
2047  */
2048     if (kernel_version >= KVERSION(2,1,16))
2049         net_mask = ~0L;
2050     if (net_mask != 0) {
2051         ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
2052         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2053             if (! ok_error (errno))
2054                 error("ioctl(SIOCSIFNETMASK): %m(%d)", errno); 
2055             return (0);
2056         } 
2057     }
2058 /*
2059  *  Add the device route
2060  */
2061     if (kernel_version < KVERSION(2,1,16)) {
2062         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2063         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2064         rt.rt_dev = ifname;
2065
2066         ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
2067         ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2068         rt.rt_flags = RTF_UP | RTF_HOST;
2069
2070         if (kernel_version > KVERSION(2,1,0)) {
2071             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2072             ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2073         }
2074
2075         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2076             if (! ok_error (errno))
2077                 error("ioctl(SIOCADDRT) device route: %m(%d)", errno);
2078             return (0);
2079         }
2080     }
2081     return 1;
2082 }
2083
2084 /********************************************************************
2085  *
2086  * cifaddr - Clear the interface IP addresses, and delete routes
2087  * through the interface if possible.
2088  */
2089
2090 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2091 {
2092     struct rtentry rt;
2093
2094     if (kernel_version < KVERSION(2,1,16)) {
2095 /*
2096  *  Delete the route through the device
2097  */
2098         memset (&rt, '\0', sizeof (rt));
2099
2100         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2101         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2102         rt.rt_dev = ifname;
2103
2104         ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
2105         ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2106         rt.rt_flags = RTF_UP | RTF_HOST;
2107
2108         if (kernel_version > KVERSION(2,1,0)) {
2109             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2110             ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2111         }
2112
2113         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2114             if (still_ppp() && ! ok_error (errno))
2115                 error("ioctl(SIOCDELRT) device route: %m(%d)", errno);
2116             return (0);
2117         }
2118     }
2119     return 1;
2120 }
2121
2122 /*
2123  * get_pty - get a pty master/slave pair and chown the slave side
2124  * to the uid given.  Assumes slave_name points to >= 12 bytes of space.
2125  */
2126 int
2127 get_pty(master_fdp, slave_fdp, slave_name, uid)
2128     int *master_fdp;
2129     int *slave_fdp;
2130     char *slave_name;
2131     int uid;
2132 {
2133     int i, mfd, sfd;
2134     char pty_name[12];
2135     struct termios tios;
2136
2137     sfd = -1;
2138     for (i = 0; i < 64; ++i) {
2139         slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2140                  'p' + i / 16, i % 16);
2141         mfd = open(pty_name, O_RDWR, 0);
2142         if (mfd >= 0) {
2143             pty_name[5] = 't';
2144             sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2145             if (sfd >= 0)
2146                 break;
2147             close(mfd);
2148         }
2149     }
2150     if (sfd < 0)
2151         return 0;
2152
2153     strlcpy(slave_name, pty_name, 12);
2154     *master_fdp = mfd;
2155     *slave_fdp = sfd;
2156     fchown(sfd, uid, -1);
2157     fchmod(sfd, S_IRUSR | S_IWUSR);
2158     if (tcgetattr(sfd, &tios) == 0) {
2159         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2160         tios.c_cflag |= CS8 | CREAD;
2161         tios.c_iflag  = IGNPAR | CLOCAL;
2162         tios.c_oflag  = 0;
2163         tios.c_lflag  = 0;
2164         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2165             warn("couldn't set attributes on pty: %m");
2166     } else
2167         warn("couldn't get attributes on pty: %m");
2168
2169     return 1;
2170 }
2171
2172 /********************************************************************
2173  *
2174  * open_loopback - open the device we use for getting packets
2175  * in demand mode.  Under Linux, we use a pty master/slave pair.
2176  */
2177 int
2178 open_ppp_loopback(void)
2179 {
2180     int flags;
2181
2182     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2183         fatal("No free pty for loopback");
2184     SYSDEBUG(("using %s for loopback", loop_name));
2185
2186     set_ppp_fd(slave_fd);
2187
2188     flags = fcntl(master_fd, F_GETFL);
2189     if (flags == -1 ||
2190         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2191         warn("couldn't set master loopback to nonblock: %m(%d)", errno);
2192
2193     flags = fcntl(ppp_fd, F_GETFL);
2194     if (flags == -1 ||
2195         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2196         warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
2197
2198     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2199         fatal("ioctl(TIOCSETD): %m(%d)", errno);
2200 /*
2201  * Find out which interface we were given.
2202  */
2203     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2204         fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
2205 /*
2206  * Enable debug in the driver if requested.
2207  */
2208     set_kdebugflag (kdebugflag);
2209
2210     return master_fd;
2211 }
2212
2213 /********************************************************************
2214  *
2215  * restore_loop - reattach the ppp unit to the loopback.
2216  *
2217  * The kernel ppp driver automatically reattaches the ppp unit to
2218  * the loopback if the serial port is set to a line discipline other
2219  * than ppp, or if it detects a modem hangup.  The former will happen
2220  * in disestablish_ppp if the latter hasn't already happened, so we
2221  * shouldn't need to do anything.
2222  *
2223  * Just to be sure, set the real serial port to the normal discipline.
2224  */
2225
2226 void
2227 restore_loop(void)
2228 {
2229     if (ppp_fd != slave_fd) {
2230         (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2231         set_ppp_fd(slave_fd);
2232     }
2233 }
2234
2235 /********************************************************************
2236  *
2237  * sifnpmode - Set the mode for handling packets for a given NP.
2238  */
2239
2240 int
2241 sifnpmode(u, proto, mode)
2242     int u;
2243     int proto;
2244     enum NPmode mode;
2245 {
2246     struct npioctl npi;
2247
2248     npi.protocol = proto;
2249     npi.mode     = mode;
2250     if (ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2251         if (! ok_error (errno)) {
2252             error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
2253                    proto, mode, errno);
2254             error("ppp_fd=%d slave_fd=%d\n", ppp_fd, slave_fd);
2255         }
2256         return 0;
2257     }
2258     return 1;
2259 }
2260
2261 \f
2262 /********************************************************************
2263  *
2264  * sipxfaddr - Config the interface IPX networknumber
2265  */
2266
2267 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2268 {
2269     int    result = 1;
2270
2271 #ifdef IPX_CHANGE
2272     int    skfd; 
2273     struct ifreq         ifr;
2274     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2275
2276     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2277     if (skfd < 0) { 
2278         if (! ok_error (errno))
2279             dbglog("socket(AF_IPX): %m (%d)", errno);
2280         result = 0;
2281     }
2282     else {
2283         memset (&ifr, '\0', sizeof (ifr));
2284         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2285
2286         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2287         sipx->sipx_family  = AF_IPX;
2288         sipx->sipx_port    = 0;
2289         sipx->sipx_network = htonl (network);
2290         sipx->sipx_type    = IPX_FRAME_ETHERII;
2291         sipx->sipx_action  = IPX_CRTITF;
2292 /*
2293  *  Set the IPX device
2294  */
2295         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2296             result = 0;
2297             if (errno != EEXIST) {
2298                 if (! ok_error (errno))
2299                     dbglog("ioctl(SIOCAIFADDR, CRTITF): %m (%d)", errno);
2300             }
2301             else {
2302                 warn("ioctl(SIOCAIFADDR, CRTITF): Address already exists");
2303             }
2304         }
2305         close (skfd);
2306     }
2307 #endif
2308     return result;
2309 }
2310
2311 /********************************************************************
2312  *
2313  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2314  *             are removed and the device is no longer able to pass IPX
2315  *             frames.
2316  */
2317
2318 int cipxfaddr (int unit)
2319 {
2320     int    result = 1;
2321
2322 #ifdef IPX_CHANGE
2323     int    skfd; 
2324     struct ifreq         ifr;
2325     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2326
2327     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2328     if (skfd < 0) { 
2329         if (! ok_error (errno))
2330             dbglog("socket(AF_IPX): %m (%d)", errno);
2331         result = 0;
2332     }
2333     else {
2334         memset (&ifr, '\0', sizeof (ifr));
2335         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2336
2337         sipx->sipx_type    = IPX_FRAME_ETHERII;
2338         sipx->sipx_action  = IPX_DLTITF;
2339         sipx->sipx_family  = AF_IPX;
2340 /*
2341  *  Set the IPX device
2342  */
2343         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2344             if (! ok_error (errno))
2345                 info("ioctl(SIOCAIFADDR, IPX_DLTITF): %m (%d)", errno);
2346             result = 0;
2347         }
2348         close (skfd);
2349     }
2350 #endif
2351     return result;
2352 }
2353
2354 /*
2355  * daemon - Detach us from controlling terminal session.
2356  */
2357 int
2358 daemon(nochdir, noclose)
2359     int nochdir, noclose;
2360 {
2361     int pid;
2362
2363     if ((pid = fork()) < 0)
2364         return -1;
2365     if (pid != 0)
2366         exit(0);                /* parent dies */
2367     setsid();
2368     if (!nochdir)
2369         chdir("/");
2370     if (!noclose) {
2371         fclose(stdin);          /* don't need stdin, stdout, stderr */
2372         fclose(stdout);
2373         fclose(stderr);
2374     }
2375     return 0;
2376 }
2377
2378 /*
2379  * Use the hostname as part of the random number seed.
2380  */
2381 int
2382 get_host_seed()
2383 {
2384     int h;
2385     char *p = hostname;
2386
2387     h = 407;
2388     for (p = hostname; *p != 0; ++p)
2389         h = h * 37 + *p;
2390     return h;
2391 }
2392
2393 /********************************************************************
2394  *
2395  * sys_check_options - check the options that the user specified
2396  */
2397
2398 int
2399 sys_check_options(void)
2400 {
2401 #ifdef IPX_CHANGE
2402     struct stat stat_buf;
2403 /*
2404  * Disable the IPX protocol if the support is not present in the kernel.
2405  * If we disable it then ensure that IP support is enabled.
2406  */
2407     while (ipxcp_protent.enabled_flag) {
2408         if (path_to_procfs()) {
2409             strlcat (route_buffer, "/net/ipx_interface", sizeof(route_buffer));
2410             if (lstat (route_buffer, &stat_buf) >= 0)
2411                 break;
2412         }
2413         error("IPX support is not present in the kernel\n");
2414         ipxcp_protent.enabled_flag = 0;
2415         ipcp_protent.enabled_flag  = 1;
2416         break;
2417     }
2418 #endif
2419     if (demand && driver_is_old) {
2420         option_error("demand dialling is not supported by kernel driver "
2421                      "version %d.%d.%d", driver_version, driver_modification,
2422                      driver_patch);
2423         return 0;
2424     }
2425     return 1;
2426 }