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