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