]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
4cc8987cc57b84cce67e167de7b4779379da14e5
[ppp.git] / pppd / sys-linux.c
1 /*
2  * sys-linux.c - System-dependent procedures for setting up
3  * PPP interfaces on Linux systems
4  *
5  * Copyright (c) 1989 Carnegie Mellon University.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by Carnegie Mellon University.  The name of the
14  * University may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  */
20
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/time.h>
25 #include <sys/errno.h>
26 #include <sys/file.h>
27 #include <sys/stat.h>
28 #include <sys/utsname.h>
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <syslog.h>
33 #include <string.h>
34 #include <time.h>
35 #include <memory.h>
36 #include <utmp.h>
37 #include <mntent.h>
38 #include <signal.h>
39 #include <fcntl.h>
40 #include <ctype.h>
41 #include <termios.h>
42 #include <unistd.h>
43
44 /* This is in netdevice.h. However, this compile will fail miserably if
45    you attempt to include netdevice.h because it has so many references
46    to __memcpy functions which it should not attempt to do. So, since I
47    really don't use it, but it must be defined, define it now. */
48
49 #ifndef MAX_ADDR_LEN
50 #define MAX_ADDR_LEN 7
51 #endif
52
53 #if __GLIBC__ >= 2
54 #include <asm/types.h>          /* glibc 2 conflicts with linux/types.h */
55 #include <net/if.h>
56 #include <net/if_arp.h>
57 #include <net/route.h>
58 #include <netinet/if_ether.h>
59 #else
60 #include <linux/types.h>
61 #include <linux/if.h>
62 #include <linux/if_arp.h>
63 #include <linux/route.h>
64 #include <linux/if_ether.h>
65 #endif
66 #include <netinet/in.h>
67 #include <arpa/inet.h>
68
69 #include <linux/ppp_defs.h>
70 #include <linux/if_ppp.h>
71
72 #include "pppd.h"
73 #include "fsm.h"
74 #include "ipcp.h"
75 #include "patchlevel.h"
76
77 #ifdef IPX_CHANGE
78 #include "ipxcp.h"
79 #if __GLIBC__ >= 2 && \
80     !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
81 #include <netipx/ipx.h>
82 #else
83 #include <linux/ipx.h>
84 #endif
85 #endif /* IPX_CHANGE */
86
87 #ifdef LOCKLIB
88 #include <sys/locks.h>
89 #endif
90
91 #ifndef RTF_DEFAULT  /* Normally in <linux/route.h> from <net/route.h> */
92 #define RTF_DEFAULT  0
93 #endif
94
95 /* We can get an EIO error on an ioctl if the modem has hung up */
96 #define ok_error(num) ((num)==EIO)
97
98 static int tty_disc = N_TTY;    /* The TTY discipline */
99 static int ppp_disc = N_PPP;    /* The PPP discpline */
100 static int initfdflags = -1;    /* Initial file descriptor flags for fd */
101 static int ppp_fd = -1;         /* fd which is set to PPP discipline */
102 static int sock_fd = -1;        /* socket for doing interface ioctls */
103 static int slave_fd = -1;
104 static int master_fd = -1;
105
106 static fd_set in_fds;           /* set of fds that wait_input waits for */
107 static int max_in_fd;           /* highest fd set in in_fds */
108
109 static int has_proxy_arp       = 0;
110 static int driver_version      = 0;
111 static int driver_modification = 0;
112 static int driver_patch        = 0;
113 static int driver_is_old       = 0;
114 static int restore_term        = 0;     /* 1 => we've munged the terminal */
115 static struct termios inittermios;      /* Initial TTY termios */
116
117 static char loop_name[20];
118 static unsigned char inbuf[512]; /* buffer for chars read from loopback */
119
120 static int      if_is_up;       /* Interface has been marked up */
121 static u_int32_t default_route_gateway; /* Gateway for default route added */
122 static u_int32_t proxy_arp_addr;        /* Addr for proxy arp entry added */
123 static char proxy_arp_dev[16];          /* Device for proxy arp entry */
124
125 static struct utsname utsname;  /* for the kernel version */
126 static int kernel_version;
127 #define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
128
129 #define MAX_IFS         100
130
131 #define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
132 #define FLAGS_MASK (IFF_UP          | IFF_BROADCAST | \
133                     IFF_POINTOPOINT | IFF_LOOPBACK  | IFF_NOARP)
134
135 /* Prototypes for procedures local to this file. */
136 static int get_flags (void);
137 static void set_flags (int flags);
138 static int translate_speed (int bps);
139 static int baud_rate_of (int speed);
140 static char *path_to_route (void);
141 static void close_route_table (void);
142 static int open_route_table (void);
143 static int read_route_table (struct rtentry *rt);
144 static int defaultroute_exists (struct rtentry *rt);
145 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
146                            char *name, int namelen);
147 static void decode_version (char *buf, int *version, int *mod, int *patch);
148 static int set_kdebugflag(int level);
149 static int ppp_registered(void);
150
151 extern u_char   inpacket_buf[]; /* borrowed from main.c */
152
153 /*
154  * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
155  * if it exists.
156  */
157
158 #define SET_SA_FAMILY(addr, family)                     \
159     memset ((char *) &(addr), '\0', sizeof(addr));      \
160     addr.sa_family = (family);
161
162 /*
163  * Determine if the PPP connection should still be present.
164  */
165
166 extern int hungup;
167
168 static void set_ppp_fd (int new_fd)
169 {
170         SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd));
171         ppp_fd = new_fd;
172 }
173
174 static int still_ppp(void)
175 {
176         if (!hungup || ppp_fd == slave_fd)
177                 return 1;
178         if (slave_fd >= 0) {
179                 set_ppp_fd(slave_fd);
180                 return 1;
181         }
182         return 0;
183 }
184
185 /********************************************************************
186  *
187  * Functions to read and set the flags value in the device driver
188  */
189
190 static int get_flags (void)
191 {    
192     int flags;
193
194     if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) {
195         if ( ok_error (errno) )
196             flags = 0;
197         else
198             fatal("ioctl(PPPIOCGFLAGS): %m");
199     }
200
201     SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags));
202     return flags;
203 }
204
205 /********************************************************************/
206
207 static void set_flags (int flags)
208 {    
209     SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags));
210
211     if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) {
212         if (! ok_error (errno) )
213             fatal("ioctl(PPPIOCSFLAGS, %x): %m(%d)", flags, errno);
214     }
215 }
216
217 /********************************************************************
218  *
219  * sys_init - System-dependent initialization.
220  */
221
222 void sys_init(void)
223 {
224     int osmaj, osmin, ospatch;
225
226     openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
227     setlogmask(LOG_UPTO(LOG_INFO));
228     if (debug)
229         setlogmask(LOG_UPTO(LOG_DEBUG));
230     
231     /* Get an internet socket for doing socket ioctls. */
232     sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
233     if (sock_fd < 0) {
234         if ( ! ok_error ( errno ))
235             fatal("Couldn't create IP socket: %m(%d)", errno);
236     }
237
238     FD_ZERO(&in_fds);
239     max_in_fd = 0;
240
241     uname(&utsname);
242     osmaj = osmin = ospatch = 0;
243     sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
244     kernel_version = KVERSION(osmaj, osmin, ospatch);
245 }
246
247 /********************************************************************
248  *
249  * sys_cleanup - restore any system state we modified before exiting:
250  * mark the interface down, delete default route and/or proxy arp entry.
251  * This shouldn't call die() because it's called from die().
252  */
253
254 void sys_cleanup(void)
255 {
256 /*
257  * Take down the device
258  */
259     if (if_is_up)
260         sifdown(0);
261 /*
262  * Delete any routes through the device.
263  */
264     if (default_route_gateway != 0)
265         cifdefaultroute(0, 0, default_route_gateway);
266
267     if (has_proxy_arp)
268         cifproxyarp(0, proxy_arp_addr);
269 }
270
271 /********************************************************************
272  *
273  * sys_close - Clean up in a child process before execing.
274  */
275 void
276 sys_close(void)
277 {
278     if (sock_fd >= 0)
279         close(sock_fd);
280     if (slave_fd >= 0)
281         close(slave_fd);
282     if (master_fd >= 0)
283         close(master_fd);
284     closelog();
285 }
286
287 /********************************************************************
288  *
289  * set_kdebugflag - Define the debugging level for the kernel
290  */
291
292 static int set_kdebugflag (int requested_level)
293 {
294     if (ioctl(ppp_fd, PPPIOCSDEBUG, &requested_level) < 0) {
295         if ( ! ok_error (errno) )
296             error("ioctl(PPPIOCSDEBUG): %m");
297         return (0);
298     }
299     SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d",
300                 requested_level));
301     return (1);
302 }
303
304 /********************************************************************
305  *
306  * establish_ppp - Turn the serial port into a ppp interface.
307  */
308
309 int establish_ppp (int tty_fd)
310 {
311     int x;
312 /*
313  * The current PPP device will be the tty file.
314  */
315     set_ppp_fd (tty_fd);
316 /*
317  * Ensure that the tty device is in exclusive mode.
318  */
319     if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
320         if ( ! ok_error ( errno ))
321             warn("ioctl(TIOCEXCL): %m");
322     }
323 /*
324  * Demand mode - prime the old ppp device to relinquish the unit.
325  */
326     if (demand && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0)
327         fatal("ioctl(transfer ppp unit): %m(%d)", errno);
328 /*
329  * Set the current tty to the PPP discpline
330  */
331     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) {
332         if ( ! ok_error (errno) )
333             fatal("ioctl(TIOCSETD): %m(%d)", errno);
334     }
335 /*
336  * Find out which interface we were given.
337  */
338     if (ioctl(ppp_fd, PPPIOCGUNIT, &x) < 0) {   
339         if ( ! ok_error (errno))
340             fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
341     }
342 /*
343  * Check that we got the same unit again.
344  */
345     if (demand) {
346         if (x != ifunit)
347             fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
348     }
349
350     ifunit = x;
351 /*
352  * Enable debug in the driver if requested.
353  */
354     if (!demand)
355         set_kdebugflag (kdebugflag);
356
357     set_flags (get_flags() & ~(SC_RCV_B7_0 | SC_RCV_B7_1 |
358                                SC_RCV_EVNP | SC_RCV_ODDP));
359
360     SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver",
361             driver_version, driver_modification, driver_patch));
362 /*
363  * Fetch the initial file flags and reset blocking mode on the file.
364  */
365     initfdflags = fcntl(ppp_fd, F_GETFL);
366
367     if (initfdflags == -1 ||
368         fcntl(ppp_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
369         if ( ! ok_error (errno))
370             warn("Couldn't set device to non-blocking mode: %m");
371     }
372
373     return ppp_fd;
374 }
375
376 /********************************************************************
377  *
378  * disestablish_ppp - Restore the serial port to normal operation.
379  * This shouldn't call die() because it's called from die().
380  */
381
382 void disestablish_ppp(int tty_fd)
383 {
384     if (!hungup) {
385 /*
386  * Flush the tty output buffer so that the TIOCSETD doesn't hang.
387  */
388         if (tcflush(tty_fd, TCIOFLUSH) < 0)
389             warn("tcflush failed: %m");
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     x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
866     set_flags(x);
867 }
868
869 /********************************************************************
870  *
871  * ppp_set_xaccm - set the extended transmit ACCM for the interface.
872  */
873
874 void ppp_set_xaccm (int unit, ext_accm accm)
875 {
876     SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n",
877                 accm[0], accm[1], accm[2], accm[3]));
878
879     if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
880         if ( ! ok_error (errno))
881             warn("ioctl(set extended ACCM): %m(%d)", errno);
882     }
883 }
884
885 /********************************************************************
886  *
887  * ppp_recv_config - configure the receive-side characteristics of
888  * the ppp interface.
889  */
890
891 void ppp_recv_config (int unit,int mru,u_int32_t asyncmap,int pcomp,int accomp)
892 {
893     u_int x;
894
895     SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru));
896 /*
897  * If we were called because the link has gone down then there is nothing
898  * which may be done. Just return without incident.
899  */
900     if (!still_ppp())
901         return;
902 /*
903  * Set the receiver parameters
904  */
905     if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
906         if ( ! ok_error (errno))
907             error("ioctl(PPPIOCSMRU): %m(%d)", errno);
908     }
909
910     SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap));
911     if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
912         if (!ok_error(errno))
913             error("ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno);
914     }
915
916     x = get_flags();
917     x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC;
918     set_flags (x);
919 }
920
921 /********************************************************************
922  *
923  * ccp_test - ask kernel whether a given compression method
924  * is acceptable for use.
925  */
926
927 int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit)
928 {
929     struct ppp_option_data data;
930
931     memset (&data, '\0', sizeof (data));
932     data.ptr      = opt_ptr;
933     data.length   = opt_len;
934     data.transmit = for_transmit;
935
936     if (ioctl(ppp_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
937         return 1;
938
939     return (errno == ENOBUFS)? 0: -1;
940 }
941
942 /********************************************************************
943  *
944  * ccp_flags_set - inform kernel about the current state of CCP.
945  */
946
947 void ccp_flags_set (int unit, int isopen, int isup)
948 {
949     if (still_ppp()) {
950         int x = get_flags();
951         x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN;
952         x = isup?   x | SC_CCP_UP   : x &~ SC_CCP_UP;
953         set_flags (x);
954     }
955 }
956
957 /********************************************************************
958  *
959  * get_idle_time - return how long the link has been idle.
960  */
961 int
962 get_idle_time(u, ip)
963     int u;
964     struct ppp_idle *ip;
965 {
966     return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0;
967
968
969 /********************************************************************
970  *
971  * get_ppp_stats - return statistics for the link.
972  */
973 int
974 get_ppp_stats(u, stats)
975     int u;
976     struct pppd_stats *stats;
977 {
978     struct ifpppstatsreq req;
979
980     memset (&req, 0, sizeof (req));
981
982     req.stats_ptr = (caddr_t) &req.stats;
983     strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
984     if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
985         error("Couldn't get PPP statistics: %m");
986         return 0;
987     }
988     stats->bytes_in = req.stats.p.ppp_ibytes;
989     stats->bytes_out = req.stats.p.ppp_obytes;
990     return 1;
991 }
992
993 /********************************************************************
994  *
995  * ccp_fatal_error - returns 1 if decompression was disabled as a
996  * result of an error detected after decompression of a packet,
997  * 0 otherwise.  This is necessary because of patent nonsense.
998  */
999
1000 int ccp_fatal_error (int unit)
1001 {
1002     int x = get_flags();
1003
1004     return x & SC_DC_FERROR;
1005 }
1006
1007 /*
1008  * path_to_route - determine the path to the proc file system data
1009  */
1010 #define ROUTE_MAX_COLS  12
1011 FILE *route_fd = (FILE *) 0;
1012 static char route_buffer [512];
1013 static int route_dev_col, route_dest_col, route_gw_col;
1014 static int route_flags_col, route_mask_col;
1015 static int route_num_cols;
1016
1017 static char *path_to_route (void);
1018 static int open_route_table (void);
1019 static void close_route_table (void);
1020 static int read_route_table (struct rtentry *rt);
1021
1022 /********************************************************************
1023  *
1024  * path_to_procfs - find the path to the proc file system mount point
1025  */
1026
1027 static int path_to_procfs (const char *tail)
1028 {
1029     struct mntent *mntent;
1030     FILE *fp;
1031
1032     fp = fopen(MOUNTED, "r");
1033     if (fp == NULL) {
1034         /* Default the mount location of /proc */
1035         strlcpy (route_buffer, "/proc", sizeof (route_buffer));
1036         strlcat (route_buffer, tail, sizeof(route_buffer));
1037         return 1;
1038     }
1039
1040     while ((mntent = getmntent(fp)) != NULL) {
1041         if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1042             continue;
1043         if (strcmp(mntent->mnt_type, "proc") == 0)
1044             break;
1045     }
1046     fclose (fp);
1047     if (mntent == 0)
1048         return 0;
1049
1050     strlcpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer));
1051     strlcat (route_buffer, tail, sizeof(route_buffer));
1052     return 1;
1053 }
1054
1055 /********************************************************************
1056  *
1057  * path_to_route - find the path to the route tables in the proc file system
1058  */
1059
1060 static char *path_to_route (void)
1061 {
1062     if (!path_to_procfs("/net/route")) {
1063         error("proc file system not mounted");
1064         return 0;
1065     }
1066     return (route_buffer);
1067 }
1068
1069 /********************************************************************
1070  *
1071  * close_route_table - close the interface to the route table
1072  */
1073
1074 static void close_route_table (void)
1075 {
1076     if (route_fd != (FILE *) 0) {
1077         fclose (route_fd);
1078         route_fd = (FILE *) 0;
1079     }
1080 }
1081
1082 /********************************************************************
1083  *
1084  * open_route_table - open the interface to the route table
1085  */
1086 static char route_delims[] = " \t\n";
1087
1088 static int open_route_table (void)
1089 {
1090     char *path;
1091
1092     close_route_table();
1093
1094     path = path_to_route();
1095     if (path == NULL)
1096         return 0;
1097
1098     route_fd = fopen (path, "r");
1099     if (route_fd == NULL) {
1100         error("can't open %s: %m (%d)", path, errno);
1101         return 0;
1102     }
1103
1104     route_dev_col = 0;          /* default to usual columns */
1105     route_dest_col = 1;
1106     route_gw_col = 2;
1107     route_flags_col = 3;
1108     route_mask_col = 7;
1109     route_num_cols = 8;
1110
1111     /* parse header line */
1112     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1113         char *p = route_buffer, *q;
1114         int col;
1115         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1116             int used = 1;
1117             if ((q = strtok(p, route_delims)) == 0)
1118                 break;
1119             if (strcasecmp(q, "iface") == 0)
1120                 route_dev_col = col;
1121             else if (strcasecmp(q, "destination") == 0)
1122                 route_dest_col = col;
1123             else if (strcasecmp(q, "gateway") == 0)
1124                 route_gw_col = col;
1125             else if (strcasecmp(q, "flags") == 0)
1126                 route_flags_col = col;
1127             else if (strcasecmp(q, "mask") == 0)
1128                 route_mask_col = col;
1129             else
1130                 used = 0;
1131             if (used && col >= route_num_cols)
1132                 route_num_cols = col + 1;
1133             p = NULL;
1134         }
1135     }
1136
1137     return 1;
1138 }
1139
1140 /********************************************************************
1141  *
1142  * read_route_table - read the next entry from the route table
1143  */
1144
1145 static int read_route_table(struct rtentry *rt)
1146 {
1147     char *cols[ROUTE_MAX_COLS], *p;
1148     int col;
1149         
1150     memset (rt, '\0', sizeof (struct rtentry));
1151
1152     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1153         return 0;
1154
1155     p = route_buffer;
1156     for (col = 0; col < route_num_cols; ++col) {
1157         cols[col] = strtok(p, route_delims);
1158         if (cols[col] == NULL)
1159             return 0;           /* didn't get enough columns */
1160         p = NULL;
1161     }
1162
1163     ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr =
1164         strtoul(cols[route_dest_col], NULL, 16);
1165
1166     ((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr =
1167         strtoul(cols[route_gw_col], NULL, 16);
1168
1169     ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr =
1170         strtoul(cols[route_mask_col], NULL, 16);
1171
1172     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1173     rt->rt_dev   = cols[route_dev_col];
1174
1175     return 1;
1176 }
1177
1178 /********************************************************************
1179  *
1180  * defaultroute_exists - determine if there is a default route
1181  */
1182
1183 static int defaultroute_exists (struct rtentry *rt)
1184 {
1185     int result = 0;
1186
1187     if (!open_route_table())
1188         return 0;
1189
1190     while (read_route_table(rt) != 0) {
1191         if ((rt->rt_flags & RTF_UP) == 0)
1192             continue;
1193
1194         if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L) {
1195             result = 1;
1196             break;
1197         }
1198     }
1199
1200     close_route_table();
1201     return result;
1202 }
1203
1204 /*
1205  * have_route_to - determine if the system has any route to
1206  * a given IP address.  `addr' is in network byte order.
1207  * Return value is 1 if yes, 0 if no, -1 if don't know.
1208  * For demand mode to work properly, we have to ignore routes
1209  * through our own interface.
1210  */
1211 int have_route_to(u_int32_t addr)
1212 {
1213     struct rtentry rt;
1214     int result = 0;
1215
1216     if (!open_route_table())
1217         return -1;              /* don't know */
1218
1219     while (read_route_table(&rt)) {
1220         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1221             continue;
1222         if ((addr & ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr)
1223             == ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr) {
1224             result = 1;
1225             break;
1226         }
1227     }
1228
1229     close_route_table();
1230     return result;
1231 }
1232
1233 /********************************************************************
1234  *
1235  * sifdefaultroute - assign a default route through the address given.
1236  */
1237
1238 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1239 {
1240     struct rtentry rt;
1241
1242     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1243         struct in_addr old_gateway =
1244           ((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
1245
1246         if (old_gateway.s_addr != gateway)
1247             error("not replacing existing default route to %s [%I]",
1248                   rt.rt_dev, old_gateway);
1249         return 0;
1250     }
1251
1252     memset (&rt, '\0', sizeof (rt));
1253     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1254     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1255
1256     if (kernel_version > KVERSION(2,1,0)) {
1257         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1258         ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
1259     }
1260
1261     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1262     
1263     rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT;
1264     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1265         if ( ! ok_error ( errno ))
1266             error("default route ioctl(SIOCADDRT): %m(%d)", errno);
1267         return 0;
1268     }
1269
1270     default_route_gateway = gateway;
1271     return 1;
1272 }
1273
1274 /********************************************************************
1275  *
1276  * cifdefaultroute - delete a default route through the address given.
1277  */
1278
1279 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1280 {
1281     struct rtentry rt;
1282
1283     default_route_gateway = 0;
1284
1285     memset (&rt, '\0', sizeof (rt));
1286     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1287     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1288
1289     if (kernel_version > KVERSION(2,1,0)) {
1290         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1291         ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
1292     }
1293
1294     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1295     
1296     rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT;
1297     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1298         if (still_ppp()) {
1299             if ( ! ok_error ( errno ))
1300                 error("default route ioctl(SIOCDELRT): %m (%d)", errno);
1301             return 0;
1302         }
1303     }
1304
1305     return 1;
1306 }
1307
1308 /********************************************************************
1309  *
1310  * sifproxyarp - Make a proxy ARP entry for the peer.
1311  */
1312
1313 int sifproxyarp (int unit, u_int32_t his_adr)
1314 {
1315     struct arpreq arpreq;
1316
1317     if (has_proxy_arp == 0) {
1318         memset (&arpreq, '\0', sizeof(arpreq));
1319     
1320         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1321         ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1322         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1323 /*
1324  * Get the hardware address of an interface on the same subnet
1325  * as our local address.
1326  */
1327         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1328                             sizeof(proxy_arp_dev))) {
1329             error("Cannot determine ethernet address for proxy ARP");
1330             return 0;
1331         }
1332         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1333
1334         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1335             if ( ! ok_error ( errno ))
1336                 error("ioctl(SIOCSARP): %m(%d)", errno);
1337             return 0;
1338         }
1339         proxy_arp_addr = his_adr;
1340         has_proxy_arp = 1;
1341     }
1342
1343     return 1;
1344 }
1345
1346 /********************************************************************
1347  *
1348  * cifproxyarp - Delete the proxy ARP entry for the peer.
1349  */
1350
1351 int cifproxyarp (int unit, u_int32_t his_adr)
1352 {
1353     struct arpreq arpreq;
1354
1355     if (has_proxy_arp) {
1356         has_proxy_arp = 0;
1357         memset (&arpreq, '\0', sizeof(arpreq));
1358         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1359         ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1360         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1361         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1362
1363         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1364             if ( ! ok_error ( errno ))
1365                 warn("ioctl(SIOCDARP): %m(%d)", errno);
1366             return 0;
1367         }
1368     }
1369     return 1;
1370 }
1371      
1372 /********************************************************************
1373  *
1374  * get_ether_addr - get the hardware address of an interface on the
1375  * the same subnet as ipaddr.
1376  */
1377
1378 static int get_ether_addr (u_int32_t ipaddr,
1379                            struct sockaddr *hwaddr,
1380                            char *name, int namelen)
1381 {
1382     struct ifreq *ifr, *ifend;
1383     u_int32_t ina, mask;
1384     struct ifreq ifreq;
1385     struct ifconf ifc;
1386     struct ifreq ifs[MAX_IFS];
1387     
1388     ifc.ifc_len = sizeof(ifs);
1389     ifc.ifc_req = ifs;
1390     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1391         if ( ! ok_error ( errno ))
1392             error("ioctl(SIOCGIFCONF): %m(%d)", errno);
1393         return 0;
1394     }
1395
1396     SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1397                 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1398 /*
1399  * Scan through looking for an interface with an Internet
1400  * address on the same subnet as `ipaddr'.
1401  */
1402     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1403     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1404         if (ifr->ifr_addr.sa_family == AF_INET) {
1405             ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1406             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1407             SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1408                         ifreq.ifr_name));
1409 /*
1410  * Check that the interface is up, and not point-to-point
1411  * nor loopback.
1412  */
1413             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1414                 continue;
1415
1416             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1417                 continue;
1418 /*
1419  * Get its netmask and check that it's on the right subnet.
1420  */
1421             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1422                 continue;
1423
1424             mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1425             SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1426                         ip_ntoa(ina), ntohl(mask)));
1427
1428             if (((ipaddr ^ ina) & mask) != 0)
1429                 continue;
1430             break;
1431         }
1432     }
1433     
1434     if (ifr >= ifend)
1435         return 0;
1436
1437     strlcpy(name, ifreq.ifr_name, namelen);
1438     info("found interface %s for proxy arp", name);
1439 /*
1440  * Now get the hardware address.
1441  */
1442     memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1443     if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) {
1444         error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);
1445         return 0;
1446     }
1447
1448     memcpy (hwaddr,
1449             &ifreq.ifr_hwaddr,
1450             sizeof (struct sockaddr));
1451
1452     SYSDEBUG ((LOG_DEBUG,
1453            "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1454                 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1455                 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1456                 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1457                 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1458                 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1459                 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1460                 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1461                 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1462     return 1;
1463 }
1464
1465 /********************************************************************
1466  *
1467  * Return user specified netmask, modified by any mask we might determine
1468  * for address `addr' (in network byte order).
1469  * Here we scan through the system's list of interfaces, looking for
1470  * any non-point-to-point interfaces which might appear to be on the same
1471  * network as `addr'.  If we find any, we OR in their netmask to the
1472  * user-specified netmask.
1473  */
1474
1475 u_int32_t GetMask (u_int32_t addr)
1476 {
1477     u_int32_t mask, nmask, ina;
1478     struct ifreq *ifr, *ifend, ifreq;
1479     struct ifconf ifc;
1480     struct ifreq ifs[MAX_IFS];
1481
1482     addr = ntohl(addr);
1483     
1484     if (IN_CLASSA(addr))        /* determine network mask for address class */
1485         nmask = IN_CLASSA_NET;
1486     else if (IN_CLASSB(addr))
1487             nmask = IN_CLASSB_NET;
1488     else
1489             nmask = IN_CLASSC_NET;
1490     
1491     /* class D nets are disallowed by bad_ip_adrs */
1492     mask = netmask | htonl(nmask);
1493 /*
1494  * Scan through the system's network interfaces.
1495  */
1496     ifc.ifc_len = sizeof(ifs);
1497     ifc.ifc_req = ifs;
1498     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1499         if ( ! ok_error ( errno ))
1500             warn("ioctl(SIOCGIFCONF): %m(%d)", errno);
1501         return mask;
1502     }
1503     
1504     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1505     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1506 /*
1507  * Check the interface's internet address.
1508  */
1509         if (ifr->ifr_addr.sa_family != AF_INET)
1510             continue;
1511         ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1512         if (((ntohl(ina) ^ addr) & nmask) != 0)
1513             continue;
1514 /*
1515  * Check that the interface is up, and not point-to-point nor loopback.
1516  */
1517         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1518         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1519             continue;
1520         
1521         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1522             continue;
1523 /*
1524  * Get its netmask and OR it into our mask.
1525  */
1526         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1527             continue;
1528         mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
1529         break;
1530     }
1531     return mask;
1532 }
1533
1534 /********************************************************************
1535  *
1536  * Internal routine to decode the version.modification.patch level
1537  */
1538
1539 static void decode_version (char *buf, int *version,
1540                             int *modification, int *patch)
1541 {
1542     *version      = (int) strtoul (buf, &buf, 10);
1543     *modification = 0;
1544     *patch        = 0;
1545     
1546     if (*buf == '.') {
1547         ++buf;
1548         *modification = (int) strtoul (buf, &buf, 10);
1549         if (*buf == '.') {
1550             ++buf;
1551             *patch = (int) strtoul (buf, &buf, 10);
1552         }
1553     }
1554     
1555     if (*buf != '\0') {
1556         *version      =
1557         *modification =
1558         *patch        = 0;
1559     }
1560 }
1561
1562 /********************************************************************
1563  *
1564  * Procedure to determine if the PPP line discipline is registered.
1565  */
1566
1567 static int
1568 ppp_registered(void)
1569 {
1570     int local_fd;
1571     int mfd = -1;
1572     int ret = 0;
1573     char slave[16];
1574
1575     /*
1576      * We used to open the serial device and set it to the ppp line
1577      * discipline here, in order to create a ppp unit.  But that is
1578      * not a good idea - the user might have specified a device that
1579      * they can't open (permission, or maybe it doesn't really exist).
1580      * So we grab a pty master/slave pair and use that.
1581      */
1582     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1583         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1584         return 0;
1585     }
1586
1587     /*
1588      * Try to put the device into the PPP discipline.
1589      */
1590     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1591         error("ioctl(TIOCSETD(PPP)): %m(%d)", errno);
1592     } else
1593         ret = 1;
1594     
1595     close(local_fd);
1596     close(mfd);
1597     return ret;
1598 }
1599
1600 /********************************************************************
1601  *
1602  * ppp_available - check whether the system has any ppp interfaces
1603  * (in fact we check whether we can do an ioctl on ppp0).
1604  */
1605
1606 int ppp_available(void)
1607 {
1608     int s, ok;
1609     struct ifreq ifr;
1610     int    size;
1611     int    my_version, my_modification, my_patch;
1612
1613     no_ppp_msg = 
1614         "This system lacks kernel support for PPP.  This could be because\n"
1615         "the PPP kernel module could not be loaded, or because PPP was not\n"
1616         "included in the kernel configuration.  If PPP was included as a\n"
1617         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
1618         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
1619         "See README.linux file in the ppp distribution for more details.\n";
1620
1621 /*
1622  * Open a socket for doing the ioctl operations.
1623  */    
1624     s = socket(AF_INET, SOCK_DGRAM, 0);
1625     if (s < 0)
1626         return 0;
1627     
1628     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1629     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1630 /*
1631  * If the device did not exist then attempt to create one by putting the
1632  * current tty into the PPP discipline. If this works then obtain the
1633  * flags for the device again.
1634  */
1635     if (!ok) {
1636         if (ppp_registered()) {
1637             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1638             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1639         }
1640     }
1641 /*
1642  * Ensure that the hardware address is for PPP and not something else
1643  */
1644     if (ok)
1645         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1646
1647     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1648         ok = 0;
1649
1650 /*
1651  *  This is the PPP device. Validate the version of the driver at this
1652  *  point to ensure that this program will work with the driver.
1653  */
1654     if (ok) {
1655         char   abBuffer [1024];
1656
1657         ifr.ifr_data = abBuffer;
1658         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1659         if (size < 0) {
1660             error("Couldn't read driver version: %m");
1661             ok = 0;
1662             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
1663
1664         } else {
1665             decode_version(abBuffer,
1666                            &driver_version,
1667                            &driver_modification,
1668                            &driver_patch);
1669 /*
1670  * Validate the version of the driver against the version that we used.
1671  */
1672             decode_version(VERSION,
1673                            &my_version,
1674                            &my_modification,
1675                            &my_patch);
1676
1677             /* The version numbers must match */
1678             if (driver_version != my_version)
1679                 ok = 0;
1680       
1681             /* The modification levels must be legal */
1682             if (driver_modification < 3) {
1683                 if (driver_modification >= 2) {
1684                     /* we can cope with 2.2.0 and above */
1685                     driver_is_old = 1;
1686                 } else {
1687                     ok = 0;
1688                 }
1689             }
1690
1691             close (s);
1692             if (!ok) {
1693                 slprintf(route_buffer, sizeof(route_buffer),
1694                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
1695                          driver_version, driver_modification, driver_patch);
1696
1697                 no_ppp_msg = route_buffer;
1698             }
1699         }
1700     }
1701     return ok;
1702 }
1703
1704 /********************************************************************
1705  *
1706  * Update the wtmp file with the appropriate user name and tty device.
1707  */
1708
1709 void logwtmp (const char *line, const char *name, const char *host)
1710 {
1711     int    wtmp;
1712     struct utmp ut, *utp;
1713     pid_t  mypid = getpid();
1714 /*
1715  * Update the signon database for users.
1716  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1717  */
1718     utmpname(_PATH_UTMP);
1719     setutent();
1720     while ((utp = getutent()) && (utp->ut_pid != mypid))
1721         /* nothing */;
1722
1723     /* Is this call really necessary? There is another one after the 'put' */
1724     endutent();
1725     
1726     if (utp)
1727         memcpy(&ut, utp, sizeof(ut));
1728     else
1729         /* some gettys/telnetds don't initialize utmp... */
1730         memset(&ut, 0, sizeof(ut));
1731
1732     if (ut.ut_id[0] == 0)
1733         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
1734         
1735     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
1736     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1737
1738     time(&ut.ut_time);
1739
1740     ut.ut_type = USER_PROCESS;
1741     ut.ut_pid  = mypid;
1742
1743     /* Insert the host name if one is supplied */
1744     if (*host)
1745         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
1746
1747     /* Insert the IP address of the remote system if IP is enabled */
1748     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
1749         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
1750                  sizeof(ut.ut_addr));
1751         
1752     /* CL: Makes sure that the logout works */
1753     if (*host == 0 && *name==0)
1754         ut.ut_host[0]=0;
1755
1756     pututline(&ut);
1757     endutent();
1758 /*
1759  * Update the wtmp file.
1760  */
1761     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
1762     if (wtmp >= 0) {
1763         flock(wtmp, LOCK_EX);
1764
1765         /* we really should check for error on the write for a full disk! */
1766         write (wtmp, (char *)&ut, sizeof(ut));
1767         close (wtmp);
1768
1769         flock(wtmp, LOCK_UN);
1770     }
1771 }
1772
1773 #if 0
1774 /********************************************************************
1775  * Code for locking/unlocking the serial device.
1776  * This code is derived from chat.c.
1777  */
1778
1779 #ifndef LOCK_PREFIX
1780 #define LOCK_PREFIX     "/var/lock/LCK.."
1781 #endif
1782
1783 static char *lock_file;
1784
1785 /*
1786  * lock - create a lock file for the named device
1787  */
1788
1789 int lock (char *dev)
1790 {
1791 #ifdef LOCKLIB
1792     int result;
1793     lock_file = strdup(dev);
1794     if (lock_file == NULL)
1795         novm("lock file name");
1796     result = mklock (dev, (void *) 0);
1797
1798     if (result > 0) {
1799         notice("Device %s is locked by pid %d", dev, result);
1800         free (lock_file);
1801         lock_file = NULL;
1802         result = -1;
1803     }
1804     else {
1805         if (result < 0) {
1806             error("Can't create lock file %s", lock_file);
1807             free (lock_file);
1808             lock_file = NULL;
1809             result = -1;
1810         }
1811     }
1812     return (result);
1813 #else
1814     char hdb_lock_buffer[12];
1815     int fd, n;
1816     int pid = getpid();
1817     char *p;
1818     size_t l;
1819
1820     p = strrchr(dev, '/');
1821     if (p != NULL)
1822         dev = ++p;
1823
1824     l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
1825     lock_file = malloc(l);
1826     if (lock_file == NULL)
1827         novm("lock file name");
1828
1829     slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
1830 /*
1831  * Attempt to create the lock file at this point.
1832  */
1833     while (1) {
1834         fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
1835         if (fd >= 0) {
1836             pid = getpid();
1837 #ifndef PID_BINARY
1838             slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%010d\n", pid);
1839             write (fd, hdb_lock_buffer, 11);
1840 #else
1841             write(fd, &pid, sizeof (pid));
1842 #endif
1843             close(fd);
1844             return 0;
1845         }
1846 /*
1847  * If the file exists then check to see if the pid is stale
1848  */
1849         if (errno == EEXIST) {
1850             fd = open(lock_file, O_RDONLY, 0);
1851             if (fd < 0) {
1852                 if (errno == ENOENT) /* This is just a timing problem. */
1853                     continue;
1854                 break;
1855             }
1856
1857             /* Read the lock file to find out who has the device locked */
1858             n = read (fd, hdb_lock_buffer, 11);
1859             close (fd);
1860             if (n < 0) {
1861                 error("Can't read pid from lock file %s", lock_file);
1862                 break;
1863             }
1864
1865             /* See the process still exists. */
1866             if (n > 0) {
1867 #ifndef PID_BINARY
1868                 hdb_lock_buffer[n] = '\0';
1869                 sscanf (hdb_lock_buffer, " %d", &pid);
1870 #else
1871                 pid = ((int *) hdb_lock_buffer)[0];
1872 #endif
1873                 if (pid == 0 || pid == getpid()
1874                     || (kill(pid, 0) == -1 && errno == ESRCH))
1875                     n = 0;
1876             }
1877
1878             /* If the process does not exist then try to remove the lock */
1879             if (n == 0 && unlink (lock_file) == 0) {
1880                 notice("Removed stale lock on %s (pid %d)",
1881                         dev, pid);
1882                 continue;
1883             }
1884
1885             notice("Device %s is locked by pid %d", dev, pid);
1886             break;
1887         }
1888
1889         error("Can't create lock file %s: %m(%d)", lock_file, errno);
1890         break;
1891     }
1892
1893     free(lock_file);
1894     lock_file = NULL;
1895     return -1;
1896 #endif
1897 }
1898
1899
1900 /********************************************************************
1901  *
1902  * unlock - remove our lockfile
1903  */
1904
1905 void unlock(void)
1906 {
1907     if (lock_file) {
1908 #ifdef LOCKLIB
1909         (void) rmlock (lock_file, (void *) 0);
1910 #else
1911         unlink(lock_file);
1912 #endif
1913         free(lock_file);
1914         lock_file = NULL;
1915     }
1916 }
1917 #endif
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 >= 16 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 = -1;
2131     char pty_name[16];
2132     struct termios tios;
2133
2134 #ifdef TIOCGPTN
2135     /*
2136      * Try the unix98 way first.
2137      */
2138     mfd = open("/dev/ptmx", O_RDWR);
2139     if (mfd >= 0) {
2140         int ptn;
2141         if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
2142             slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
2143             chmod(pty_name, S_IRUSR | S_IWUSR);
2144 #ifdef TIOCSPTLCK
2145             ptn = 0;
2146             if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
2147                 warn("Couldn't unlock pty slave %s: %m", pty_name);
2148 #endif
2149             if ((sfd = open(pty_name, O_RDWR)) < 0)
2150                 warn("Couldn't open pty slave %s: %m", pty_name);
2151         }
2152     }
2153 #endif /* TIOCGPTN */
2154
2155     if (sfd < 0) {
2156         /* the old way - scan through the pty name space */
2157         for (i = 0; i < 64; ++i) {
2158             slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2159                      'p' + i / 16, i % 16);
2160             mfd = open(pty_name, O_RDWR, 0);
2161             if (mfd >= 0) {
2162                 pty_name[5] = 't';
2163                 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2164                 if (sfd >= 0) {
2165                     fchown(sfd, uid, -1);
2166                     fchmod(sfd, S_IRUSR | S_IWUSR);
2167                     break;
2168                 }
2169                 close(mfd);
2170             }
2171         }
2172     }
2173
2174     if (sfd < 0)
2175         return 0;
2176
2177     strlcpy(slave_name, pty_name, 16);
2178     *master_fdp = mfd;
2179     *slave_fdp = sfd;
2180     if (tcgetattr(sfd, &tios) == 0) {
2181         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2182         tios.c_cflag |= CS8 | CREAD;
2183         tios.c_iflag  = IGNPAR | CLOCAL;
2184         tios.c_oflag  = 0;
2185         tios.c_lflag  = 0;
2186         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2187             warn("couldn't set attributes on pty: %m");
2188     } else
2189         warn("couldn't get attributes on pty: %m");
2190
2191     return 1;
2192 }
2193
2194 /********************************************************************
2195  *
2196  * open_loopback - open the device we use for getting packets
2197  * in demand mode.  Under Linux, we use a pty master/slave pair.
2198  */
2199 int
2200 open_ppp_loopback(void)
2201 {
2202     int flags;
2203
2204     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2205         fatal("No free pty for loopback");
2206     SYSDEBUG(("using %s for loopback", loop_name));
2207
2208     set_ppp_fd(slave_fd);
2209
2210     flags = fcntl(master_fd, F_GETFL);
2211     if (flags == -1 ||
2212         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2213         warn("couldn't set master loopback to nonblock: %m(%d)", errno);
2214
2215     flags = fcntl(ppp_fd, F_GETFL);
2216     if (flags == -1 ||
2217         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2218         warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
2219
2220     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2221         fatal("ioctl(TIOCSETD): %m(%d)", errno);
2222 /*
2223  * Find out which interface we were given.
2224  */
2225     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2226         fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
2227 /*
2228  * Enable debug in the driver if requested.
2229  */
2230     set_kdebugflag (kdebugflag);
2231
2232     return master_fd;
2233 }
2234
2235 /********************************************************************
2236  *
2237  * restore_loop - reattach the ppp unit to the loopback.
2238  *
2239  * The kernel ppp driver automatically reattaches the ppp unit to
2240  * the loopback if the serial port is set to a line discipline other
2241  * than ppp, or if it detects a modem hangup.  The former will happen
2242  * in disestablish_ppp if the latter hasn't already happened, so we
2243  * shouldn't need to do anything.
2244  *
2245  * Just to be sure, set the real serial port to the normal discipline.
2246  */
2247
2248 void
2249 restore_loop(void)
2250 {
2251     if (ppp_fd != slave_fd) {
2252         (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2253         set_ppp_fd(slave_fd);
2254     }
2255 }
2256
2257 /********************************************************************
2258  *
2259  * sifnpmode - Set the mode for handling packets for a given NP.
2260  */
2261
2262 int
2263 sifnpmode(u, proto, mode)
2264     int u;
2265     int proto;
2266     enum NPmode mode;
2267 {
2268     struct npioctl npi;
2269
2270     npi.protocol = proto;
2271     npi.mode     = mode;
2272     if (ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2273         if (! ok_error (errno)) {
2274             error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
2275                    proto, mode, errno);
2276             error("ppp_fd=%d slave_fd=%d\n", ppp_fd, slave_fd);
2277         }
2278         return 0;
2279     }
2280     return 1;
2281 }
2282
2283 \f
2284 /********************************************************************
2285  *
2286  * sipxfaddr - Config the interface IPX networknumber
2287  */
2288
2289 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2290 {
2291     int    result = 1;
2292
2293 #ifdef IPX_CHANGE
2294     int    skfd; 
2295     struct ifreq         ifr;
2296     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2297
2298     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2299     if (skfd < 0) { 
2300         if (! ok_error (errno))
2301             dbglog("socket(AF_IPX): %m (%d)", errno);
2302         result = 0;
2303     }
2304     else {
2305         memset (&ifr, '\0', sizeof (ifr));
2306         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2307
2308         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2309         sipx->sipx_family  = AF_IPX;
2310         sipx->sipx_port    = 0;
2311         sipx->sipx_network = htonl (network);
2312         sipx->sipx_type    = IPX_FRAME_ETHERII;
2313         sipx->sipx_action  = IPX_CRTITF;
2314 /*
2315  *  Set the IPX device
2316  */
2317         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2318             result = 0;
2319             if (errno != EEXIST) {
2320                 if (! ok_error (errno))
2321                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);
2322             }
2323             else {
2324                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2325             }
2326         }
2327         close (skfd);
2328     }
2329 #endif
2330     return result;
2331 }
2332
2333 /********************************************************************
2334  *
2335  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2336  *             are removed and the device is no longer able to pass IPX
2337  *             frames.
2338  */
2339
2340 int cipxfaddr (int unit)
2341 {
2342     int    result = 1;
2343
2344 #ifdef IPX_CHANGE
2345     int    skfd; 
2346     struct ifreq         ifr;
2347     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2348
2349     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2350     if (skfd < 0) { 
2351         if (! ok_error (errno))
2352             dbglog("socket(AF_IPX): %m (%d)", errno);
2353         result = 0;
2354     }
2355     else {
2356         memset (&ifr, '\0', sizeof (ifr));
2357         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2358
2359         sipx->sipx_type    = IPX_FRAME_ETHERII;
2360         sipx->sipx_action  = IPX_DLTITF;
2361         sipx->sipx_family  = AF_IPX;
2362 /*
2363  *  Set the IPX device
2364  */
2365         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2366             if (! ok_error (errno))
2367                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);
2368             result = 0;
2369         }
2370         close (skfd);
2371     }
2372 #endif
2373     return result;
2374 }
2375
2376 #if 0
2377 /*
2378  * daemon - Detach us from controlling terminal session.
2379  */
2380 int
2381 daemon(nochdir, noclose)
2382     int nochdir, noclose;
2383 {
2384     int pid;
2385
2386     if ((pid = fork()) < 0)
2387         return -1;
2388     if (pid != 0)
2389         exit(0);                /* parent dies */
2390     setsid();
2391     if (!nochdir)
2392         chdir("/");
2393     if (!noclose) {
2394         fclose(stdin);          /* don't need stdin, stdout, stderr */
2395         fclose(stdout);
2396         fclose(stderr);
2397     }
2398     return 0;
2399 }
2400 #endif
2401
2402 /*
2403  * Use the hostname as part of the random number seed.
2404  */
2405 int
2406 get_host_seed()
2407 {
2408     int h;
2409     char *p = hostname;
2410
2411     h = 407;
2412     for (p = hostname; *p != 0; ++p)
2413         h = h * 37 + *p;
2414     return h;
2415 }
2416
2417 /********************************************************************
2418  *
2419  * sys_check_options - check the options that the user specified
2420  */
2421
2422 int
2423 sys_check_options(void)
2424 {
2425 #ifdef IPX_CHANGE
2426 /*
2427  * Disable the IPX protocol if the support is not present in the kernel.
2428  */
2429     if (ipxcp_protent.enabled_flag) {
2430         struct stat stat_buf;
2431         if (!path_to_procfs("/net/ipx_interface")
2432             || lstat (route_buffer, &stat_buf) < 0) {
2433             error("IPX support is not present in the kernel\n");
2434             ipxcp_protent.enabled_flag = 0;
2435         }
2436     }
2437 #endif
2438     if (demand && driver_is_old) {
2439         option_error("demand dialling is not supported by kernel driver "
2440                      "version %d.%d.%d", driver_version, driver_modification,
2441                      driver_patch);
2442         return 0;
2443     }
2444     return 1;
2445 }