]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
just do tcflush once, should be enough
[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 (void)
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         return 1;
1037     }
1038
1039     while ((mntent = getmntent(fp)) != NULL) {
1040         if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
1041             continue;
1042         if (strcmp(mntent->mnt_type, "proc") == 0)
1043             break;
1044     }
1045     fclose (fp);
1046     if (mntent == 0)
1047         return 0;
1048
1049     strlcpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer));
1050     return 1;
1051 }
1052
1053 /********************************************************************
1054  *
1055  * path_to_route - find the path to the route tables in the proc file system
1056  */
1057
1058 static char *path_to_route (void)
1059 {
1060     if (!path_to_procfs()) {
1061         error("proc file system not mounted");
1062         return 0;
1063     }
1064     strlcat (route_buffer, "/net/route", sizeof(route_buffer));
1065     return (route_buffer);
1066 }
1067
1068 /********************************************************************
1069  *
1070  * close_route_table - close the interface to the route table
1071  */
1072
1073 static void close_route_table (void)
1074 {
1075     if (route_fd != (FILE *) 0) {
1076         fclose (route_fd);
1077         route_fd = (FILE *) 0;
1078     }
1079 }
1080
1081 /********************************************************************
1082  *
1083  * open_route_table - open the interface to the route table
1084  */
1085 static char route_delims[] = " \t\n";
1086
1087 static int open_route_table (void)
1088 {
1089     char *path;
1090
1091     close_route_table();
1092
1093     path = path_to_route();
1094     if (path == NULL)
1095         return 0;
1096
1097     route_fd = fopen (path, "r");
1098     if (route_fd == NULL) {
1099         error("can't open %s: %m (%d)", path, errno);
1100         return 0;
1101     }
1102
1103     route_dev_col = 0;          /* default to usual columns */
1104     route_dest_col = 1;
1105     route_gw_col = 2;
1106     route_flags_col = 3;
1107     route_mask_col = 7;
1108     route_num_cols = 8;
1109
1110     /* parse header line */
1111     if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
1112         char *p = route_buffer, *q;
1113         int col;
1114         for (col = 0; col < ROUTE_MAX_COLS; ++col) {
1115             int used = 1;
1116             if ((q = strtok(p, route_delims)) == 0)
1117                 break;
1118             if (strcasecmp(q, "iface") == 0)
1119                 route_dev_col = col;
1120             else if (strcasecmp(q, "destination") == 0)
1121                 route_dest_col = col;
1122             else if (strcasecmp(q, "gateway") == 0)
1123                 route_gw_col = col;
1124             else if (strcasecmp(q, "flags") == 0)
1125                 route_flags_col = col;
1126             else if (strcasecmp(q, "mask") == 0)
1127                 route_mask_col = col;
1128             else
1129                 used = 0;
1130             if (used && col >= route_num_cols)
1131                 route_num_cols = col + 1;
1132             p = NULL;
1133         }
1134     }
1135
1136     return 1;
1137 }
1138
1139 /********************************************************************
1140  *
1141  * read_route_table - read the next entry from the route table
1142  */
1143
1144 static int read_route_table(struct rtentry *rt)
1145 {
1146     char *cols[ROUTE_MAX_COLS], *p;
1147     int col;
1148         
1149     memset (rt, '\0', sizeof (struct rtentry));
1150
1151     if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
1152         return 0;
1153
1154     p = route_buffer;
1155     for (col = 0; col < route_num_cols; ++col) {
1156         cols[col] = strtok(p, route_delims);
1157         if (cols[col] == NULL)
1158             return 0;           /* didn't get enough columns */
1159     }
1160
1161     ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr =
1162         strtoul(cols[route_dest_col], NULL, 16);
1163
1164     ((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr =
1165         strtoul(cols[route_gw_col], NULL, 16);
1166
1167     ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr =
1168         strtoul(cols[route_mask_col], NULL, 16);
1169
1170     rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
1171     rt->rt_dev   = cols[route_dev_col];
1172
1173     return 1;
1174 }
1175
1176 /********************************************************************
1177  *
1178  * defaultroute_exists - determine if there is a default route
1179  */
1180
1181 static int defaultroute_exists (struct rtentry *rt)
1182 {
1183     int result = 0;
1184
1185     if (!open_route_table())
1186         return 0;
1187
1188     while (read_route_table(rt) != 0) {
1189         if ((rt->rt_flags & RTF_UP) == 0)
1190             continue;
1191
1192         if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L) {
1193             result = 1;
1194             break;
1195         }
1196     }
1197
1198     close_route_table();
1199     return result;
1200 }
1201
1202 /*
1203  * have_route_to - determine if the system has any route to
1204  * a given IP address.  `addr' is in network byte order.
1205  * Return value is 1 if yes, 0 if no, -1 if don't know.
1206  * For demand mode to work properly, we have to ignore routes
1207  * through our own interface.
1208  */
1209 int have_route_to(u_int32_t addr)
1210 {
1211     struct rtentry rt;
1212     int result = 0;
1213
1214     if (!open_route_table())
1215         return -1;              /* don't know */
1216
1217     while (read_route_table(&rt)) {
1218         if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
1219             continue;
1220         if ((addr & ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr)
1221             == ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr) {
1222             result = 1;
1223             break;
1224         }
1225     }
1226
1227     close_route_table();
1228     return result;
1229 }
1230
1231 /********************************************************************
1232  *
1233  * sifdefaultroute - assign a default route through the address given.
1234  */
1235
1236 int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1237 {
1238     struct rtentry rt;
1239
1240     if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
1241         struct in_addr old_gateway =
1242           ((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
1243
1244         if (old_gateway.s_addr != gateway)
1245             error("not replacing existing default route to %s [%I]",
1246                   rt.rt_dev, old_gateway);
1247         return 0;
1248     }
1249
1250     memset (&rt, '\0', sizeof (rt));
1251     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1252     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1253
1254     if (kernel_version > KVERSION(2,1,0)) {
1255         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1256         ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
1257     }
1258
1259     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1260     
1261     rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT;
1262     if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
1263         if ( ! ok_error ( errno ))
1264             error("default route ioctl(SIOCADDRT): %m(%d)", errno);
1265         return 0;
1266     }
1267
1268     default_route_gateway = gateway;
1269     return 1;
1270 }
1271
1272 /********************************************************************
1273  *
1274  * cifdefaultroute - delete a default route through the address given.
1275  */
1276
1277 int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
1278 {
1279     struct rtentry rt;
1280
1281     default_route_gateway = 0;
1282
1283     memset (&rt, '\0', sizeof (rt));
1284     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
1285     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
1286
1287     if (kernel_version > KVERSION(2,1,0)) {
1288         SET_SA_FAMILY (rt.rt_genmask, AF_INET);
1289         ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
1290     }
1291
1292     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
1293     
1294     rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT;
1295     if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
1296         if (still_ppp()) {
1297             if ( ! ok_error ( errno ))
1298                 error("default route ioctl(SIOCDELRT): %m (%d)", errno);
1299             return 0;
1300         }
1301     }
1302
1303     return 1;
1304 }
1305
1306 /********************************************************************
1307  *
1308  * sifproxyarp - Make a proxy ARP entry for the peer.
1309  */
1310
1311 int sifproxyarp (int unit, u_int32_t his_adr)
1312 {
1313     struct arpreq arpreq;
1314
1315     if (has_proxy_arp == 0) {
1316         memset (&arpreq, '\0', sizeof(arpreq));
1317     
1318         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1319         ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1320         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1321 /*
1322  * Get the hardware address of an interface on the same subnet
1323  * as our local address.
1324  */
1325         if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
1326                             sizeof(proxy_arp_dev))) {
1327             error("Cannot determine ethernet address for proxy ARP");
1328             return 0;
1329         }
1330         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1331
1332         if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
1333             if ( ! ok_error ( errno ))
1334                 error("ioctl(SIOCSARP): %m(%d)", errno);
1335             return 0;
1336         }
1337         proxy_arp_addr = his_adr;
1338         has_proxy_arp = 1;
1339     }
1340
1341     return 1;
1342 }
1343
1344 /********************************************************************
1345  *
1346  * cifproxyarp - Delete the proxy ARP entry for the peer.
1347  */
1348
1349 int cifproxyarp (int unit, u_int32_t his_adr)
1350 {
1351     struct arpreq arpreq;
1352
1353     if (has_proxy_arp) {
1354         has_proxy_arp = 0;
1355         memset (&arpreq, '\0', sizeof(arpreq));
1356         SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1357         ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr;
1358         arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1359         strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
1360
1361         if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
1362             if ( ! ok_error ( errno ))
1363                 warn("ioctl(SIOCDARP): %m(%d)", errno);
1364             return 0;
1365         }
1366     }
1367     return 1;
1368 }
1369      
1370 /********************************************************************
1371  *
1372  * get_ether_addr - get the hardware address of an interface on the
1373  * the same subnet as ipaddr.
1374  */
1375
1376 static int get_ether_addr (u_int32_t ipaddr,
1377                            struct sockaddr *hwaddr,
1378                            char *name, int namelen)
1379 {
1380     struct ifreq *ifr, *ifend;
1381     u_int32_t ina, mask;
1382     struct ifreq ifreq;
1383     struct ifconf ifc;
1384     struct ifreq ifs[MAX_IFS];
1385     
1386     ifc.ifc_len = sizeof(ifs);
1387     ifc.ifc_req = ifs;
1388     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1389         if ( ! ok_error ( errno ))
1390             error("ioctl(SIOCGIFCONF): %m(%d)", errno);
1391         return 0;
1392     }
1393
1394     SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s",
1395                 ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr)));
1396 /*
1397  * Scan through looking for an interface with an Internet
1398  * address on the same subnet as `ipaddr'.
1399  */
1400     ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
1401     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1402         if (ifr->ifr_addr.sa_family == AF_INET) {
1403             ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1404             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1405             SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s",
1406                         ifreq.ifr_name));
1407 /*
1408  * Check that the interface is up, and not point-to-point
1409  * nor loopback.
1410  */
1411             if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1412                 continue;
1413
1414             if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1415                 continue;
1416 /*
1417  * Get its netmask and check that it's on the right subnet.
1418  */
1419             if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1420                 continue;
1421
1422             mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1423             SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx",
1424                         ip_ntoa(ina), ntohl(mask)));
1425
1426             if (((ipaddr ^ ina) & mask) != 0)
1427                 continue;
1428             break;
1429         }
1430     }
1431     
1432     if (ifr >= ifend)
1433         return 0;
1434
1435     strlcpy(name, ifreq.ifr_name, namelen);
1436     info("found interface %s for proxy arp", name);
1437 /*
1438  * Now get the hardware address.
1439  */
1440     memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
1441     if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) {
1442         error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno);
1443         return 0;
1444     }
1445
1446     memcpy (hwaddr,
1447             &ifreq.ifr_hwaddr,
1448             sizeof (struct sockaddr));
1449
1450     SYSDEBUG ((LOG_DEBUG,
1451            "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1452                 (int) ((unsigned char *) &hwaddr->sa_data)[0],
1453                 (int) ((unsigned char *) &hwaddr->sa_data)[1],
1454                 (int) ((unsigned char *) &hwaddr->sa_data)[2],
1455                 (int) ((unsigned char *) &hwaddr->sa_data)[3],
1456                 (int) ((unsigned char *) &hwaddr->sa_data)[4],
1457                 (int) ((unsigned char *) &hwaddr->sa_data)[5],
1458                 (int) ((unsigned char *) &hwaddr->sa_data)[6],
1459                 (int) ((unsigned char *) &hwaddr->sa_data)[7]));
1460     return 1;
1461 }
1462
1463 /********************************************************************
1464  *
1465  * Return user specified netmask, modified by any mask we might determine
1466  * for address `addr' (in network byte order).
1467  * Here we scan through the system's list of interfaces, looking for
1468  * any non-point-to-point interfaces which might appear to be on the same
1469  * network as `addr'.  If we find any, we OR in their netmask to the
1470  * user-specified netmask.
1471  */
1472
1473 u_int32_t GetMask (u_int32_t addr)
1474 {
1475     u_int32_t mask, nmask, ina;
1476     struct ifreq *ifr, *ifend, ifreq;
1477     struct ifconf ifc;
1478     struct ifreq ifs[MAX_IFS];
1479
1480     addr = ntohl(addr);
1481     
1482     if (IN_CLASSA(addr))        /* determine network mask for address class */
1483         nmask = IN_CLASSA_NET;
1484     else if (IN_CLASSB(addr))
1485             nmask = IN_CLASSB_NET;
1486     else
1487             nmask = IN_CLASSC_NET;
1488     
1489     /* class D nets are disallowed by bad_ip_adrs */
1490     mask = netmask | htonl(nmask);
1491 /*
1492  * Scan through the system's network interfaces.
1493  */
1494     ifc.ifc_len = sizeof(ifs);
1495     ifc.ifc_req = ifs;
1496     if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
1497         if ( ! ok_error ( errno ))
1498             warn("ioctl(SIOCGIFCONF): %m(%d)", errno);
1499         return mask;
1500     }
1501     
1502     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1503     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1504 /*
1505  * Check the interface's internet address.
1506  */
1507         if (ifr->ifr_addr.sa_family != AF_INET)
1508             continue;
1509         ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1510         if (((ntohl(ina) ^ addr) & nmask) != 0)
1511             continue;
1512 /*
1513  * Check that the interface is up, and not point-to-point nor loopback.
1514  */
1515         strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1516         if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
1517             continue;
1518         
1519         if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
1520             continue;
1521 /*
1522  * Get its netmask and OR it into our mask.
1523  */
1524         if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
1525             continue;
1526         mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
1527         break;
1528     }
1529     return mask;
1530 }
1531
1532 /********************************************************************
1533  *
1534  * Internal routine to decode the version.modification.patch level
1535  */
1536
1537 static void decode_version (char *buf, int *version,
1538                             int *modification, int *patch)
1539 {
1540     *version      = (int) strtoul (buf, &buf, 10);
1541     *modification = 0;
1542     *patch        = 0;
1543     
1544     if (*buf == '.') {
1545         ++buf;
1546         *modification = (int) strtoul (buf, &buf, 10);
1547         if (*buf == '.') {
1548             ++buf;
1549             *patch = (int) strtoul (buf, &buf, 10);
1550         }
1551     }
1552     
1553     if (*buf != '\0') {
1554         *version      =
1555         *modification =
1556         *patch        = 0;
1557     }
1558 }
1559
1560 /********************************************************************
1561  *
1562  * Procedure to determine if the PPP line discipline is registered.
1563  */
1564
1565 static int
1566 ppp_registered(void)
1567 {
1568     int local_fd;
1569     int mfd = -1;
1570     int ret = 0;
1571     char slave[16];
1572
1573     /*
1574      * We used to open the serial device and set it to the ppp line
1575      * discipline here, in order to create a ppp unit.  But that is
1576      * not a good idea - the user might have specified a device that
1577      * they can't open (permission, or maybe it doesn't really exist).
1578      * So we grab a pty master/slave pair and use that.
1579      */
1580     if (!get_pty(&mfd, &local_fd, slave, 0)) {
1581         no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
1582         return 0;
1583     }
1584
1585     /*
1586      * Try to put the device into the PPP discipline.
1587      */
1588     if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
1589         error("ioctl(TIOCSETD(PPP)): %m(%d)", errno);
1590     } else
1591         ret = 1;
1592     
1593     close(local_fd);
1594     close(mfd);
1595     return ret;
1596 }
1597
1598 /********************************************************************
1599  *
1600  * ppp_available - check whether the system has any ppp interfaces
1601  * (in fact we check whether we can do an ioctl on ppp0).
1602  */
1603
1604 int ppp_available(void)
1605 {
1606     int s, ok;
1607     struct ifreq ifr;
1608     int    size;
1609     int    my_version, my_modification, my_patch;
1610
1611     no_ppp_msg = 
1612         "This system lacks kernel support for PPP.  This could be because\n"
1613         "the PPP kernel module could not be loaded, or because PPP was not\n"
1614         "included in the kernel configuration.  If PPP was included as a\n"
1615         "module, try `/sbin/modprobe -v ppp'.  If that fails, check that\n"
1616         "ppp.o exists in /lib/modules/`uname -r`/net.\n"
1617         "See README.linux file in the ppp distribution for more details.\n";
1618
1619 /*
1620  * Open a socket for doing the ioctl operations.
1621  */    
1622     s = socket(AF_INET, SOCK_DGRAM, 0);
1623     if (s < 0)
1624         return 0;
1625     
1626     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1627     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1628 /*
1629  * If the device did not exist then attempt to create one by putting the
1630  * current tty into the PPP discipline. If this works then obtain the
1631  * flags for the device again.
1632  */
1633     if (!ok) {
1634         if (ppp_registered()) {
1635             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1636             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1637         }
1638     }
1639 /*
1640  * Ensure that the hardware address is for PPP and not something else
1641  */
1642     if (ok)
1643         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1644
1645     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1646         ok = 0;
1647
1648 /*
1649  *  This is the PPP device. Validate the version of the driver at this
1650  *  point to ensure that this program will work with the driver.
1651  */
1652     if (ok) {
1653         char   abBuffer [1024];
1654
1655         ifr.ifr_data = abBuffer;
1656         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1657         if (size < 0) {
1658             error("Couldn't read driver version: %m");
1659             ok = 0;
1660             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
1661
1662         } else {
1663             decode_version(abBuffer,
1664                            &driver_version,
1665                            &driver_modification,
1666                            &driver_patch);
1667 /*
1668  * Validate the version of the driver against the version that we used.
1669  */
1670             decode_version(VERSION,
1671                            &my_version,
1672                            &my_modification,
1673                            &my_patch);
1674
1675             /* The version numbers must match */
1676             if (driver_version != my_version)
1677                 ok = 0;
1678       
1679             /* The modification levels must be legal */
1680             if (driver_modification < 3) {
1681                 if (driver_modification >= 2) {
1682                     /* we can cope with 2.2.0 and above */
1683                     driver_is_old = 1;
1684                 } else {
1685                     ok = 0;
1686                 }
1687             }
1688
1689             close (s);
1690             if (!ok) {
1691                 slprintf(route_buffer, sizeof(route_buffer),
1692                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
1693                          driver_version, driver_modification, driver_patch);
1694
1695                 no_ppp_msg = route_buffer;
1696             }
1697         }
1698     }
1699     return ok;
1700 }
1701
1702 /********************************************************************
1703  *
1704  * Update the wtmp file with the appropriate user name and tty device.
1705  */
1706
1707 void logwtmp (const char *line, const char *name, const char *host)
1708 {
1709     int    wtmp;
1710     struct utmp ut, *utp;
1711     pid_t  mypid = getpid();
1712 /*
1713  * Update the signon database for users.
1714  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1715  */
1716     utmpname(_PATH_UTMP);
1717     setutent();
1718     while ((utp = getutent()) && (utp->ut_pid != mypid))
1719         /* nothing */;
1720
1721     /* Is this call really necessary? There is another one after the 'put' */
1722     endutent();
1723     
1724     if (utp)
1725         memcpy(&ut, utp, sizeof(ut));
1726     else
1727         /* some gettys/telnetds don't initialize utmp... */
1728         memset(&ut, 0, sizeof(ut));
1729
1730     if (ut.ut_id[0] == 0)
1731         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
1732         
1733     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
1734     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1735
1736     time(&ut.ut_time);
1737
1738     ut.ut_type = USER_PROCESS;
1739     ut.ut_pid  = mypid;
1740
1741     /* Insert the host name if one is supplied */
1742     if (*host)
1743         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
1744
1745     /* Insert the IP address of the remote system if IP is enabled */
1746     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
1747         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
1748                  sizeof(ut.ut_addr));
1749         
1750     /* CL: Makes sure that the logout works */
1751     if (*host == 0 && *name==0)
1752         ut.ut_host[0]=0;
1753
1754     pututline(&ut);
1755     endutent();
1756 /*
1757  * Update the wtmp file.
1758  */
1759     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
1760     if (wtmp >= 0) {
1761         flock(wtmp, LOCK_EX);
1762
1763         /* we really should check for error on the write for a full disk! */
1764         write (wtmp, (char *)&ut, sizeof(ut));
1765         close (wtmp);
1766
1767         flock(wtmp, LOCK_UN);
1768     }
1769 }
1770
1771 #if 0
1772 /********************************************************************
1773  * Code for locking/unlocking the serial device.
1774  * This code is derived from chat.c.
1775  */
1776
1777 #ifndef LOCK_PREFIX
1778 #define LOCK_PREFIX     "/var/lock/LCK.."
1779 #endif
1780
1781 static char *lock_file;
1782
1783 /*
1784  * lock - create a lock file for the named device
1785  */
1786
1787 int lock (char *dev)
1788 {
1789 #ifdef LOCKLIB
1790     int result;
1791     lock_file = strdup(dev);
1792     if (lock_file == NULL)
1793         novm("lock file name");
1794     result = mklock (dev, (void *) 0);
1795
1796     if (result > 0) {
1797         notice("Device %s is locked by pid %d", dev, result);
1798         free (lock_file);
1799         lock_file = NULL;
1800         result = -1;
1801     }
1802     else {
1803         if (result < 0) {
1804             error("Can't create lock file %s", lock_file);
1805             free (lock_file);
1806             lock_file = NULL;
1807             result = -1;
1808         }
1809     }
1810     return (result);
1811 #else
1812     char hdb_lock_buffer[12];
1813     int fd, n;
1814     int pid = getpid();
1815     char *p;
1816     size_t l;
1817
1818     p = strrchr(dev, '/');
1819     if (p != NULL)
1820         dev = ++p;
1821
1822     l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
1823     lock_file = malloc(l);
1824     if (lock_file == NULL)
1825         novm("lock file name");
1826
1827     slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
1828 /*
1829  * Attempt to create the lock file at this point.
1830  */
1831     while (1) {
1832         fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
1833         if (fd >= 0) {
1834             pid = getpid();
1835 #ifndef PID_BINARY
1836             slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%010d\n", pid);
1837             write (fd, hdb_lock_buffer, 11);
1838 #else
1839             write(fd, &pid, sizeof (pid));
1840 #endif
1841             close(fd);
1842             return 0;
1843         }
1844 /*
1845  * If the file exists then check to see if the pid is stale
1846  */
1847         if (errno == EEXIST) {
1848             fd = open(lock_file, O_RDONLY, 0);
1849             if (fd < 0) {
1850                 if (errno == ENOENT) /* This is just a timing problem. */
1851                     continue;
1852                 break;
1853             }
1854
1855             /* Read the lock file to find out who has the device locked */
1856             n = read (fd, hdb_lock_buffer, 11);
1857             close (fd);
1858             if (n < 0) {
1859                 error("Can't read pid from lock file %s", lock_file);
1860                 break;
1861             }
1862
1863             /* See the process still exists. */
1864             if (n > 0) {
1865 #ifndef PID_BINARY
1866                 hdb_lock_buffer[n] = '\0';
1867                 sscanf (hdb_lock_buffer, " %d", &pid);
1868 #else
1869                 pid = ((int *) hdb_lock_buffer)[0];
1870 #endif
1871                 if (pid == 0 || pid == getpid()
1872                     || (kill(pid, 0) == -1 && errno == ESRCH))
1873                     n = 0;
1874             }
1875
1876             /* If the process does not exist then try to remove the lock */
1877             if (n == 0 && unlink (lock_file) == 0) {
1878                 notice("Removed stale lock on %s (pid %d)",
1879                         dev, pid);
1880                 continue;
1881             }
1882
1883             notice("Device %s is locked by pid %d", dev, pid);
1884             break;
1885         }
1886
1887         error("Can't create lock file %s: %m(%d)", lock_file, errno);
1888         break;
1889     }
1890
1891     free(lock_file);
1892     lock_file = NULL;
1893     return -1;
1894 #endif
1895 }
1896
1897
1898 /********************************************************************
1899  *
1900  * unlock - remove our lockfile
1901  */
1902
1903 void unlock(void)
1904 {
1905     if (lock_file) {
1906 #ifdef LOCKLIB
1907         (void) rmlock (lock_file, (void *) 0);
1908 #else
1909         unlink(lock_file);
1910 #endif
1911         free(lock_file);
1912         lock_file = NULL;
1913     }
1914 }
1915 #endif
1916
1917 /********************************************************************
1918  *
1919  * sifvjcomp - config tcp header compression
1920  */
1921
1922 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
1923 {
1924     u_int x = get_flags();
1925
1926     if (vjcomp) {
1927         if (ioctl (ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
1928             if (! ok_error (errno))
1929                 error("ioctl(PPPIOCSMAXCID): %m(%d)", errno);
1930             vjcomp = 0;
1931         }
1932     }
1933
1934     x = vjcomp  ? x | SC_COMP_TCP     : x &~ SC_COMP_TCP;
1935     x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
1936     set_flags (x);
1937
1938     return 1;
1939 }
1940
1941 /********************************************************************
1942  *
1943  * sifup - Config the interface up and enable IP packets to pass.
1944  */
1945
1946 int sifup (int u)
1947 {
1948     struct ifreq ifr;
1949
1950     memset (&ifr, '\0', sizeof (ifr));
1951     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1952     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
1953         if (! ok_error (errno))
1954             error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
1955         return 0;
1956     }
1957
1958     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
1959     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
1960         if (! ok_error (errno))
1961             error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
1962         return 0;
1963     }
1964     if_is_up = 1;
1965     return 1;
1966 }
1967
1968 /********************************************************************
1969  *
1970  * sifdown - Config the interface down and disable IP.
1971  */
1972
1973 int sifdown (int u)
1974 {
1975     struct ifreq ifr;
1976
1977     if_is_up = 0;
1978
1979     memset (&ifr, '\0', sizeof (ifr));
1980     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1981     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
1982         if (! ok_error (errno))
1983             error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
1984         return 0;
1985     }
1986
1987     ifr.ifr_flags &= ~IFF_UP;
1988     ifr.ifr_flags |= IFF_POINTOPOINT;
1989     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
1990         if (! ok_error (errno))
1991             error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
1992         return 0;
1993     }
1994     return 1;
1995 }
1996
1997 /********************************************************************
1998  *
1999  * sifaddr - Config the interface IP addresses and netmask.
2000  */
2001
2002 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2003              u_int32_t net_mask)
2004 {
2005     struct ifreq   ifr; 
2006     struct rtentry rt;
2007     
2008     memset (&ifr, '\0', sizeof (ifr));
2009     memset (&rt,  '\0', sizeof (rt));
2010     
2011     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET); 
2012     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); 
2013     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); 
2014
2015     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2016 /*
2017  *  Set our IP address
2018  */
2019     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr;
2020     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2021         if (errno != EEXIST) {
2022             if (! ok_error (errno))
2023                 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
2024         }
2025         else {
2026             warn("ioctl(SIOCSIFADDR): Address already exists");
2027         }
2028         return (0);
2029     }
2030 /*
2031  *  Set the gateway address
2032  */
2033     ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr;
2034     if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2035         if (! ok_error (errno))
2036             error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno); 
2037         return (0);
2038     } 
2039 /*
2040  *  Set the netmask.
2041  *  For recent kernels, force the netmask to 255.255.255.255.
2042  */
2043     if (kernel_version >= KVERSION(2,1,16))
2044         net_mask = ~0L;
2045     if (net_mask != 0) {
2046         ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
2047         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2048             if (! ok_error (errno))
2049                 error("ioctl(SIOCSIFNETMASK): %m(%d)", errno); 
2050             return (0);
2051         } 
2052     }
2053 /*
2054  *  Add the device route
2055  */
2056     if (kernel_version < KVERSION(2,1,16)) {
2057         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2058         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2059         rt.rt_dev = ifname;
2060
2061         ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
2062         ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2063         rt.rt_flags = RTF_UP | RTF_HOST;
2064
2065         if (kernel_version > KVERSION(2,1,0)) {
2066             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2067             ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2068         }
2069
2070         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2071             if (! ok_error (errno))
2072                 error("ioctl(SIOCADDRT) device route: %m(%d)", errno);
2073             return (0);
2074         }
2075     }
2076     return 1;
2077 }
2078
2079 /********************************************************************
2080  *
2081  * cifaddr - Clear the interface IP addresses, and delete routes
2082  * through the interface if possible.
2083  */
2084
2085 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2086 {
2087     struct rtentry rt;
2088
2089     if (kernel_version < KVERSION(2,1,16)) {
2090 /*
2091  *  Delete the route through the device
2092  */
2093         memset (&rt, '\0', sizeof (rt));
2094
2095         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2096         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2097         rt.rt_dev = ifname;
2098
2099         ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
2100         ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2101         rt.rt_flags = RTF_UP | RTF_HOST;
2102
2103         if (kernel_version > KVERSION(2,1,0)) {
2104             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2105             ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2106         }
2107
2108         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2109             if (still_ppp() && ! ok_error (errno))
2110                 error("ioctl(SIOCDELRT) device route: %m(%d)", errno);
2111             return (0);
2112         }
2113     }
2114     return 1;
2115 }
2116
2117 /*
2118  * get_pty - get a pty master/slave pair and chown the slave side
2119  * to the uid given.  Assumes slave_name points to >= 12 bytes of space.
2120  */
2121 int
2122 get_pty(master_fdp, slave_fdp, slave_name, uid)
2123     int *master_fdp;
2124     int *slave_fdp;
2125     char *slave_name;
2126     int uid;
2127 {
2128     int i, mfd, sfd;
2129     char pty_name[12];
2130     struct termios tios;
2131
2132     sfd = -1;
2133     for (i = 0; i < 64; ++i) {
2134         slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2135                  'p' + i / 16, i % 16);
2136         mfd = open(pty_name, O_RDWR, 0);
2137         if (mfd >= 0) {
2138             pty_name[5] = 't';
2139             sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2140             if (sfd >= 0)
2141                 break;
2142             close(mfd);
2143         }
2144     }
2145     if (sfd < 0)
2146         return 0;
2147
2148     strlcpy(slave_name, pty_name, 12);
2149     *master_fdp = mfd;
2150     *slave_fdp = sfd;
2151     fchown(sfd, uid, -1);
2152     fchmod(sfd, S_IRUSR | S_IWUSR);
2153     if (tcgetattr(sfd, &tios) == 0) {
2154         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2155         tios.c_cflag |= CS8 | CREAD;
2156         tios.c_iflag  = IGNPAR | CLOCAL;
2157         tios.c_oflag  = 0;
2158         tios.c_lflag  = 0;
2159         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2160             warn("couldn't set attributes on pty: %m");
2161     } else
2162         warn("couldn't get attributes on pty: %m");
2163
2164     return 1;
2165 }
2166
2167 /********************************************************************
2168  *
2169  * open_loopback - open the device we use for getting packets
2170  * in demand mode.  Under Linux, we use a pty master/slave pair.
2171  */
2172 int
2173 open_ppp_loopback(void)
2174 {
2175     int flags;
2176
2177     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2178         fatal("No free pty for loopback");
2179     SYSDEBUG(("using %s for loopback", loop_name));
2180
2181     set_ppp_fd(slave_fd);
2182
2183     flags = fcntl(master_fd, F_GETFL);
2184     if (flags == -1 ||
2185         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2186         warn("couldn't set master loopback to nonblock: %m(%d)", errno);
2187
2188     flags = fcntl(ppp_fd, F_GETFL);
2189     if (flags == -1 ||
2190         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2191         warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
2192
2193     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2194         fatal("ioctl(TIOCSETD): %m(%d)", errno);
2195 /*
2196  * Find out which interface we were given.
2197  */
2198     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2199         fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
2200 /*
2201  * Enable debug in the driver if requested.
2202  */
2203     set_kdebugflag (kdebugflag);
2204
2205     return master_fd;
2206 }
2207
2208 /********************************************************************
2209  *
2210  * restore_loop - reattach the ppp unit to the loopback.
2211  *
2212  * The kernel ppp driver automatically reattaches the ppp unit to
2213  * the loopback if the serial port is set to a line discipline other
2214  * than ppp, or if it detects a modem hangup.  The former will happen
2215  * in disestablish_ppp if the latter hasn't already happened, so we
2216  * shouldn't need to do anything.
2217  *
2218  * Just to be sure, set the real serial port to the normal discipline.
2219  */
2220
2221 void
2222 restore_loop(void)
2223 {
2224     if (ppp_fd != slave_fd) {
2225         (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2226         set_ppp_fd(slave_fd);
2227     }
2228 }
2229
2230 /********************************************************************
2231  *
2232  * sifnpmode - Set the mode for handling packets for a given NP.
2233  */
2234
2235 int
2236 sifnpmode(u, proto, mode)
2237     int u;
2238     int proto;
2239     enum NPmode mode;
2240 {
2241     struct npioctl npi;
2242
2243     npi.protocol = proto;
2244     npi.mode     = mode;
2245     if (ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2246         if (! ok_error (errno)) {
2247             error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
2248                    proto, mode, errno);
2249             error("ppp_fd=%d slave_fd=%d\n", ppp_fd, slave_fd);
2250         }
2251         return 0;
2252     }
2253     return 1;
2254 }
2255
2256 \f
2257 /********************************************************************
2258  *
2259  * sipxfaddr - Config the interface IPX networknumber
2260  */
2261
2262 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2263 {
2264     int    result = 1;
2265
2266 #ifdef IPX_CHANGE
2267     int    skfd; 
2268     struct ifreq         ifr;
2269     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2270
2271     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2272     if (skfd < 0) { 
2273         if (! ok_error (errno))
2274             dbglog("socket(AF_IPX): %m (%d)", errno);
2275         result = 0;
2276     }
2277     else {
2278         memset (&ifr, '\0', sizeof (ifr));
2279         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2280
2281         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2282         sipx->sipx_family  = AF_IPX;
2283         sipx->sipx_port    = 0;
2284         sipx->sipx_network = htonl (network);
2285         sipx->sipx_type    = IPX_FRAME_ETHERII;
2286         sipx->sipx_action  = IPX_CRTITF;
2287 /*
2288  *  Set the IPX device
2289  */
2290         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2291             result = 0;
2292             if (errno != EEXIST) {
2293                 if (! ok_error (errno))
2294                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);
2295             }
2296             else {
2297                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2298             }
2299         }
2300         close (skfd);
2301     }
2302 #endif
2303     return result;
2304 }
2305
2306 /********************************************************************
2307  *
2308  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2309  *             are removed and the device is no longer able to pass IPX
2310  *             frames.
2311  */
2312
2313 int cipxfaddr (int unit)
2314 {
2315     int    result = 1;
2316
2317 #ifdef IPX_CHANGE
2318     int    skfd; 
2319     struct ifreq         ifr;
2320     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2321
2322     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2323     if (skfd < 0) { 
2324         if (! ok_error (errno))
2325             dbglog("socket(AF_IPX): %m (%d)", errno);
2326         result = 0;
2327     }
2328     else {
2329         memset (&ifr, '\0', sizeof (ifr));
2330         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2331
2332         sipx->sipx_type    = IPX_FRAME_ETHERII;
2333         sipx->sipx_action  = IPX_DLTITF;
2334         sipx->sipx_family  = AF_IPX;
2335 /*
2336  *  Set the IPX device
2337  */
2338         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2339             if (! ok_error (errno))
2340                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);
2341             result = 0;
2342         }
2343         close (skfd);
2344     }
2345 #endif
2346     return result;
2347 }
2348
2349 #if 0
2350 /*
2351  * daemon - Detach us from controlling terminal session.
2352  */
2353 int
2354 daemon(nochdir, noclose)
2355     int nochdir, noclose;
2356 {
2357     int pid;
2358
2359     if ((pid = fork()) < 0)
2360         return -1;
2361     if (pid != 0)
2362         exit(0);                /* parent dies */
2363     setsid();
2364     if (!nochdir)
2365         chdir("/");
2366     if (!noclose) {
2367         fclose(stdin);          /* don't need stdin, stdout, stderr */
2368         fclose(stdout);
2369         fclose(stderr);
2370     }
2371     return 0;
2372 }
2373 #endif
2374
2375 /*
2376  * Use the hostname as part of the random number seed.
2377  */
2378 int
2379 get_host_seed()
2380 {
2381     int h;
2382     char *p = hostname;
2383
2384     h = 407;
2385     for (p = hostname; *p != 0; ++p)
2386         h = h * 37 + *p;
2387     return h;
2388 }
2389
2390 /********************************************************************
2391  *
2392  * sys_check_options - check the options that the user specified
2393  */
2394
2395 int
2396 sys_check_options(void)
2397 {
2398 #ifdef IPX_CHANGE
2399     struct stat stat_buf;
2400 /*
2401  * Disable the IPX protocol if the support is not present in the kernel.
2402  * If we disable it then ensure that IP support is enabled.
2403  */
2404     while (ipxcp_protent.enabled_flag) {
2405         if (path_to_procfs()) {
2406             strlcat (route_buffer, "/net/ipx_interface", sizeof(route_buffer));
2407             if (lstat (route_buffer, &stat_buf) >= 0)
2408                 break;
2409         }
2410         error("IPX support is not present in the kernel\n");
2411         ipxcp_protent.enabled_flag = 0;
2412         ipcp_protent.enabled_flag  = 1;
2413         break;
2414     }
2415 #endif
2416     if (demand && driver_is_old) {
2417         option_error("demand dialling is not supported by kernel driver "
2418                      "version %d.%d.%d", driver_version, driver_modification,
2419                      driver_patch);
2420         return 0;
2421     }
2422     return 1;
2423 }