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