]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-linux.c
try harder to flush the tty output buffer in disestablish_ppp
[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 is not loaded, or because the kernel is\n"
1622         "not configured for PPP.  See the README.linux file in the\n"
1623         "ppp-2.3.7 distribution.\n";
1624
1625 /*
1626  * Open a socket for doing the ioctl operations.
1627  */    
1628     s = socket(AF_INET, SOCK_DGRAM, 0);
1629     if (s < 0)
1630         return 0;
1631     
1632     strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1633     ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1634 /*
1635  * If the device did not exist then attempt to create one by putting the
1636  * current tty into the PPP discipline. If this works then obtain the
1637  * flags for the device again.
1638  */
1639     if (!ok) {
1640         if (ppp_registered()) {
1641             strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
1642             ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
1643         }
1644     }
1645 /*
1646  * Ensure that the hardware address is for PPP and not something else
1647  */
1648     if (ok)
1649         ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
1650
1651     if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
1652         ok = 0;
1653
1654 /*
1655  *  This is the PPP device. Validate the version of the driver at this
1656  *  point to ensure that this program will work with the driver.
1657  */
1658     if (ok) {
1659         char   abBuffer [1024];
1660
1661         ifr.ifr_data = abBuffer;
1662         size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
1663         if (size < 0) {
1664             error("Couldn't read driver version: %m");
1665             ok = 0;
1666             no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
1667
1668         } else {
1669             decode_version(abBuffer,
1670                            &driver_version,
1671                            &driver_modification,
1672                            &driver_patch);
1673 /*
1674  * Validate the version of the driver against the version that we used.
1675  */
1676             decode_version(VERSION,
1677                            &my_version,
1678                            &my_modification,
1679                            &my_patch);
1680
1681             /* The version numbers must match */
1682             if (driver_version != my_version)
1683                 ok = 0;
1684       
1685             /* The modification levels must be legal */
1686             if (driver_modification < 3) {
1687                 if (driver_modification >= 2) {
1688                     /* we can cope with 2.2.0 and above */
1689                     driver_is_old = 1;
1690                 } else {
1691                     ok = 0;
1692                 }
1693             }
1694
1695             close (s);
1696             if (!ok) {
1697                 slprintf(route_buffer, sizeof(route_buffer),
1698                          "Sorry - PPP driver version %d.%d.%d is out of date\n",
1699                          driver_version, driver_modification, driver_patch);
1700
1701                 no_ppp_msg = route_buffer;
1702             }
1703         }
1704     }
1705     return ok;
1706 }
1707
1708 /********************************************************************
1709  *
1710  * Update the wtmp file with the appropriate user name and tty device.
1711  */
1712
1713 void logwtmp (const char *line, const char *name, const char *host)
1714 {
1715     int    wtmp;
1716     struct utmp ut, *utp;
1717     pid_t  mypid = getpid();
1718 /*
1719  * Update the signon database for users.
1720  * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
1721  */
1722     utmpname(_PATH_UTMP);
1723     setutent();
1724     while ((utp = getutent()) && (utp->ut_pid != mypid))
1725         /* nothing */;
1726
1727     /* Is this call really necessary? There is another one after the 'put' */
1728     endutent();
1729     
1730     if (utp)
1731         memcpy(&ut, utp, sizeof(ut));
1732     else
1733         /* some gettys/telnetds don't initialize utmp... */
1734         memset(&ut, 0, sizeof(ut));
1735
1736     if (ut.ut_id[0] == 0)
1737         strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
1738         
1739     strncpy(ut.ut_user, name, sizeof(ut.ut_user));
1740     strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1741
1742     time(&ut.ut_time);
1743
1744     ut.ut_type = USER_PROCESS;
1745     ut.ut_pid  = mypid;
1746
1747     /* Insert the host name if one is supplied */
1748     if (*host)
1749         strncpy (ut.ut_host, host, sizeof(ut.ut_host));
1750
1751     /* Insert the IP address of the remote system if IP is enabled */
1752     if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
1753         memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
1754                  sizeof(ut.ut_addr));
1755         
1756     /* CL: Makes sure that the logout works */
1757     if (*host == 0 && *name==0)
1758         ut.ut_host[0]=0;
1759
1760     pututline(&ut);
1761     endutent();
1762 /*
1763  * Update the wtmp file.
1764  */
1765     wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
1766     if (wtmp >= 0) {
1767         flock(wtmp, LOCK_EX);
1768
1769         /* we really should check for error on the write for a full disk! */
1770         write (wtmp, (char *)&ut, sizeof(ut));
1771         close (wtmp);
1772
1773         flock(wtmp, LOCK_UN);
1774     }
1775 }
1776
1777 #if 0
1778 /********************************************************************
1779  * Code for locking/unlocking the serial device.
1780  * This code is derived from chat.c.
1781  */
1782
1783 #ifndef LOCK_PREFIX
1784 #define LOCK_PREFIX     "/var/lock/LCK.."
1785 #endif
1786
1787 static char *lock_file;
1788
1789 /*
1790  * lock - create a lock file for the named device
1791  */
1792
1793 int lock (char *dev)
1794 {
1795 #ifdef LOCKLIB
1796     int result;
1797     lock_file = strdup(dev);
1798     if (lock_file == NULL)
1799         novm("lock file name");
1800     result = mklock (dev, (void *) 0);
1801
1802     if (result > 0) {
1803         notice("Device %s is locked by pid %d", dev, result);
1804         free (lock_file);
1805         lock_file = NULL;
1806         result = -1;
1807     }
1808     else {
1809         if (result < 0) {
1810             error("Can't create lock file %s", lock_file);
1811             free (lock_file);
1812             lock_file = NULL;
1813             result = -1;
1814         }
1815     }
1816     return (result);
1817 #else
1818     char hdb_lock_buffer[12];
1819     int fd, n;
1820     int pid = getpid();
1821     char *p;
1822     size_t l;
1823
1824     p = strrchr(dev, '/');
1825     if (p != NULL)
1826         dev = ++p;
1827
1828     l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
1829     lock_file = malloc(l);
1830     if (lock_file == NULL)
1831         novm("lock file name");
1832
1833     slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
1834 /*
1835  * Attempt to create the lock file at this point.
1836  */
1837     while (1) {
1838         fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644);
1839         if (fd >= 0) {
1840             pid = getpid();
1841 #ifndef PID_BINARY
1842             slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%010d\n", pid);
1843             write (fd, hdb_lock_buffer, 11);
1844 #else
1845             write(fd, &pid, sizeof (pid));
1846 #endif
1847             close(fd);
1848             return 0;
1849         }
1850 /*
1851  * If the file exists then check to see if the pid is stale
1852  */
1853         if (errno == EEXIST) {
1854             fd = open(lock_file, O_RDONLY, 0);
1855             if (fd < 0) {
1856                 if (errno == ENOENT) /* This is just a timing problem. */
1857                     continue;
1858                 break;
1859             }
1860
1861             /* Read the lock file to find out who has the device locked */
1862             n = read (fd, hdb_lock_buffer, 11);
1863             close (fd);
1864             if (n < 0) {
1865                 error("Can't read pid from lock file %s", lock_file);
1866                 break;
1867             }
1868
1869             /* See the process still exists. */
1870             if (n > 0) {
1871 #ifndef PID_BINARY
1872                 hdb_lock_buffer[n] = '\0';
1873                 sscanf (hdb_lock_buffer, " %d", &pid);
1874 #else
1875                 pid = ((int *) hdb_lock_buffer)[0];
1876 #endif
1877                 if (pid == 0 || pid == getpid()
1878                     || (kill(pid, 0) == -1 && errno == ESRCH))
1879                     n = 0;
1880             }
1881
1882             /* If the process does not exist then try to remove the lock */
1883             if (n == 0 && unlink (lock_file) == 0) {
1884                 notice("Removed stale lock on %s (pid %d)",
1885                         dev, pid);
1886                 continue;
1887             }
1888
1889             notice("Device %s is locked by pid %d", dev, pid);
1890             break;
1891         }
1892
1893         error("Can't create lock file %s: %m(%d)", lock_file, errno);
1894         break;
1895     }
1896
1897     free(lock_file);
1898     lock_file = NULL;
1899     return -1;
1900 #endif
1901 }
1902
1903
1904 /********************************************************************
1905  *
1906  * unlock - remove our lockfile
1907  */
1908
1909 void unlock(void)
1910 {
1911     if (lock_file) {
1912 #ifdef LOCKLIB
1913         (void) rmlock (lock_file, (void *) 0);
1914 #else
1915         unlink(lock_file);
1916 #endif
1917         free(lock_file);
1918         lock_file = NULL;
1919     }
1920 }
1921 #endif
1922
1923 /********************************************************************
1924  *
1925  * sifvjcomp - config tcp header compression
1926  */
1927
1928 int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
1929 {
1930     u_int x = get_flags();
1931
1932     if (vjcomp) {
1933         if (ioctl (ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) {
1934             if (! ok_error (errno))
1935                 error("ioctl(PPPIOCSMAXCID): %m(%d)", errno);
1936             vjcomp = 0;
1937         }
1938     }
1939
1940     x = vjcomp  ? x | SC_COMP_TCP     : x &~ SC_COMP_TCP;
1941     x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID;
1942     set_flags (x);
1943
1944     return 1;
1945 }
1946
1947 /********************************************************************
1948  *
1949  * sifup - Config the interface up and enable IP packets to pass.
1950  */
1951
1952 int sifup (int u)
1953 {
1954     struct ifreq ifr;
1955
1956     memset (&ifr, '\0', sizeof (ifr));
1957     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1958     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
1959         if (! ok_error (errno))
1960             error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
1961         return 0;
1962     }
1963
1964     ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
1965     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
1966         if (! ok_error (errno))
1967             error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
1968         return 0;
1969     }
1970     if_is_up = 1;
1971     return 1;
1972 }
1973
1974 /********************************************************************
1975  *
1976  * sifdown - Config the interface down and disable IP.
1977  */
1978
1979 int sifdown (int u)
1980 {
1981     struct ifreq ifr;
1982
1983     if_is_up = 0;
1984
1985     memset (&ifr, '\0', sizeof (ifr));
1986     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1987     if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
1988         if (! ok_error (errno))
1989             error("ioctl (SIOCGIFFLAGS): %m(%d)", errno);
1990         return 0;
1991     }
1992
1993     ifr.ifr_flags &= ~IFF_UP;
1994     ifr.ifr_flags |= IFF_POINTOPOINT;
1995     if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
1996         if (! ok_error (errno))
1997             error("ioctl(SIOCSIFFLAGS): %m(%d)", errno);
1998         return 0;
1999     }
2000     return 1;
2001 }
2002
2003 /********************************************************************
2004  *
2005  * sifaddr - Config the interface IP addresses and netmask.
2006  */
2007
2008 int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
2009              u_int32_t net_mask)
2010 {
2011     struct ifreq   ifr; 
2012     struct rtentry rt;
2013     
2014     memset (&ifr, '\0', sizeof (ifr));
2015     memset (&rt,  '\0', sizeof (rt));
2016     
2017     SET_SA_FAMILY (ifr.ifr_addr,    AF_INET); 
2018     SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); 
2019     SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); 
2020
2021     strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
2022 /*
2023  *  Set our IP address
2024  */
2025     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr;
2026     if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2027         if (errno != EEXIST) {
2028             if (! ok_error (errno))
2029                 error("ioctl(SIOCSIFADDR): %m(%d)", errno);
2030         }
2031         else {
2032             warn("ioctl(SIOCSIFADDR): Address already exists");
2033         }
2034         return (0);
2035     }
2036 /*
2037  *  Set the gateway address
2038  */
2039     ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr;
2040     if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
2041         if (! ok_error (errno))
2042             error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno); 
2043         return (0);
2044     } 
2045 /*
2046  *  Set the netmask.
2047  *  For recent kernels, force the netmask to 255.255.255.255.
2048  */
2049     if (kernel_version >= KVERSION(2,1,16))
2050         net_mask = ~0L;
2051     if (net_mask != 0) {
2052         ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
2053         if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
2054             if (! ok_error (errno))
2055                 error("ioctl(SIOCSIFNETMASK): %m(%d)", errno); 
2056             return (0);
2057         } 
2058     }
2059 /*
2060  *  Add the device route
2061  */
2062     if (kernel_version < KVERSION(2,1,16)) {
2063         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2064         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2065         rt.rt_dev = ifname;
2066
2067         ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
2068         ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2069         rt.rt_flags = RTF_UP | RTF_HOST;
2070
2071         if (kernel_version > KVERSION(2,1,0)) {
2072             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2073             ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2074         }
2075
2076         if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
2077             if (! ok_error (errno))
2078                 error("ioctl(SIOCADDRT) device route: %m(%d)", errno);
2079             return (0);
2080         }
2081     }
2082     return 1;
2083 }
2084
2085 /********************************************************************
2086  *
2087  * cifaddr - Clear the interface IP addresses, and delete routes
2088  * through the interface if possible.
2089  */
2090
2091 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
2092 {
2093     struct rtentry rt;
2094
2095     if (kernel_version < KVERSION(2,1,16)) {
2096 /*
2097  *  Delete the route through the device
2098  */
2099         memset (&rt, '\0', sizeof (rt));
2100
2101         SET_SA_FAMILY (rt.rt_dst,     AF_INET);
2102         SET_SA_FAMILY (rt.rt_gateway, AF_INET);
2103         rt.rt_dev = ifname;
2104
2105         ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
2106         ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
2107         rt.rt_flags = RTF_UP | RTF_HOST;
2108
2109         if (kernel_version > KVERSION(2,1,0)) {
2110             SET_SA_FAMILY (rt.rt_genmask, AF_INET);
2111             ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
2112         }
2113
2114         if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
2115             if (still_ppp() && ! ok_error (errno))
2116                 error("ioctl(SIOCDELRT) device route: %m(%d)", errno);
2117             return (0);
2118         }
2119     }
2120     return 1;
2121 }
2122
2123 /*
2124  * get_pty - get a pty master/slave pair and chown the slave side
2125  * to the uid given.  Assumes slave_name points to >= 12 bytes of space.
2126  */
2127 int
2128 get_pty(master_fdp, slave_fdp, slave_name, uid)
2129     int *master_fdp;
2130     int *slave_fdp;
2131     char *slave_name;
2132     int uid;
2133 {
2134     int i, mfd, sfd;
2135     char pty_name[12];
2136     struct termios tios;
2137
2138     sfd = -1;
2139     for (i = 0; i < 64; ++i) {
2140         slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
2141                  'p' + i / 16, i % 16);
2142         mfd = open(pty_name, O_RDWR, 0);
2143         if (mfd >= 0) {
2144             pty_name[5] = 't';
2145             sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
2146             if (sfd >= 0)
2147                 break;
2148             close(mfd);
2149         }
2150     }
2151     if (sfd < 0)
2152         return 0;
2153
2154     strlcpy(slave_name, pty_name, 12);
2155     *master_fdp = mfd;
2156     *slave_fdp = sfd;
2157     fchown(sfd, uid, -1);
2158     fchmod(sfd, S_IRUSR | S_IWUSR);
2159     if (tcgetattr(sfd, &tios) == 0) {
2160         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
2161         tios.c_cflag |= CS8 | CREAD;
2162         tios.c_iflag  = IGNPAR | CLOCAL;
2163         tios.c_oflag  = 0;
2164         tios.c_lflag  = 0;
2165         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
2166             warn("couldn't set attributes on pty: %m");
2167     } else
2168         warn("couldn't get attributes on pty: %m");
2169
2170     return 1;
2171 }
2172
2173 /********************************************************************
2174  *
2175  * open_loopback - open the device we use for getting packets
2176  * in demand mode.  Under Linux, we use a pty master/slave pair.
2177  */
2178 int
2179 open_ppp_loopback(void)
2180 {
2181     int flags;
2182
2183     if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
2184         fatal("No free pty for loopback");
2185     SYSDEBUG(("using %s for loopback", loop_name));
2186
2187     set_ppp_fd(slave_fd);
2188
2189     flags = fcntl(master_fd, F_GETFL);
2190     if (flags == -1 ||
2191         fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2192         warn("couldn't set master loopback to nonblock: %m(%d)", errno);
2193
2194     flags = fcntl(ppp_fd, F_GETFL);
2195     if (flags == -1 ||
2196         fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
2197         warn("couldn't set slave loopback to nonblock: %m(%d)", errno);
2198
2199     if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
2200         fatal("ioctl(TIOCSETD): %m(%d)", errno);
2201 /*
2202  * Find out which interface we were given.
2203  */
2204     if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
2205         fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno);
2206 /*
2207  * Enable debug in the driver if requested.
2208  */
2209     set_kdebugflag (kdebugflag);
2210
2211     return master_fd;
2212 }
2213
2214 /********************************************************************
2215  *
2216  * restore_loop - reattach the ppp unit to the loopback.
2217  *
2218  * The kernel ppp driver automatically reattaches the ppp unit to
2219  * the loopback if the serial port is set to a line discipline other
2220  * than ppp, or if it detects a modem hangup.  The former will happen
2221  * in disestablish_ppp if the latter hasn't already happened, so we
2222  * shouldn't need to do anything.
2223  *
2224  * Just to be sure, set the real serial port to the normal discipline.
2225  */
2226
2227 void
2228 restore_loop(void)
2229 {
2230     if (ppp_fd != slave_fd) {
2231         (void) ioctl(ppp_fd, TIOCSETD, &tty_disc);
2232         set_ppp_fd(slave_fd);
2233     }
2234 }
2235
2236 /********************************************************************
2237  *
2238  * sifnpmode - Set the mode for handling packets for a given NP.
2239  */
2240
2241 int
2242 sifnpmode(u, proto, mode)
2243     int u;
2244     int proto;
2245     enum NPmode mode;
2246 {
2247     struct npioctl npi;
2248
2249     npi.protocol = proto;
2250     npi.mode     = mode;
2251     if (ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
2252         if (! ok_error (errno)) {
2253             error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)",
2254                    proto, mode, errno);
2255             error("ppp_fd=%d slave_fd=%d\n", ppp_fd, slave_fd);
2256         }
2257         return 0;
2258     }
2259     return 1;
2260 }
2261
2262 \f
2263 /********************************************************************
2264  *
2265  * sipxfaddr - Config the interface IPX networknumber
2266  */
2267
2268 int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
2269 {
2270     int    result = 1;
2271
2272 #ifdef IPX_CHANGE
2273     int    skfd; 
2274     struct ifreq         ifr;
2275     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2276
2277     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2278     if (skfd < 0) { 
2279         if (! ok_error (errno))
2280             dbglog("socket(AF_IPX): %m (%d)", errno);
2281         result = 0;
2282     }
2283     else {
2284         memset (&ifr, '\0', sizeof (ifr));
2285         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2286
2287         memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
2288         sipx->sipx_family  = AF_IPX;
2289         sipx->sipx_port    = 0;
2290         sipx->sipx_network = htonl (network);
2291         sipx->sipx_type    = IPX_FRAME_ETHERII;
2292         sipx->sipx_action  = IPX_CRTITF;
2293 /*
2294  *  Set the IPX device
2295  */
2296         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2297             result = 0;
2298             if (errno != EEXIST) {
2299                 if (! ok_error (errno))
2300                     dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno);
2301             }
2302             else {
2303                 warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
2304             }
2305         }
2306         close (skfd);
2307     }
2308 #endif
2309     return result;
2310 }
2311
2312 /********************************************************************
2313  *
2314  * cipxfaddr - Clear the information for the IPX network. The IPX routes
2315  *             are removed and the device is no longer able to pass IPX
2316  *             frames.
2317  */
2318
2319 int cipxfaddr (int unit)
2320 {
2321     int    result = 1;
2322
2323 #ifdef IPX_CHANGE
2324     int    skfd; 
2325     struct ifreq         ifr;
2326     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
2327
2328     skfd = socket (AF_IPX, SOCK_DGRAM, 0);
2329     if (skfd < 0) { 
2330         if (! ok_error (errno))
2331             dbglog("socket(AF_IPX): %m (%d)", errno);
2332         result = 0;
2333     }
2334     else {
2335         memset (&ifr, '\0', sizeof (ifr));
2336         strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
2337
2338         sipx->sipx_type    = IPX_FRAME_ETHERII;
2339         sipx->sipx_action  = IPX_DLTITF;
2340         sipx->sipx_family  = AF_IPX;
2341 /*
2342  *  Set the IPX device
2343  */
2344         if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
2345             if (! ok_error (errno))
2346                 info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno);
2347             result = 0;
2348         }
2349         close (skfd);
2350     }
2351 #endif
2352     return result;
2353 }
2354
2355 #if 0
2356 /*
2357  * daemon - Detach us from controlling terminal session.
2358  */
2359 int
2360 daemon(nochdir, noclose)
2361     int nochdir, noclose;
2362 {
2363     int pid;
2364
2365     if ((pid = fork()) < 0)
2366         return -1;
2367     if (pid != 0)
2368         exit(0);                /* parent dies */
2369     setsid();
2370     if (!nochdir)
2371         chdir("/");
2372     if (!noclose) {
2373         fclose(stdin);          /* don't need stdin, stdout, stderr */
2374         fclose(stdout);
2375         fclose(stderr);
2376     }
2377     return 0;
2378 }
2379 #endif
2380
2381 /*
2382  * Use the hostname as part of the random number seed.
2383  */
2384 int
2385 get_host_seed()
2386 {
2387     int h;
2388     char *p = hostname;
2389
2390     h = 407;
2391     for (p = hostname; *p != 0; ++p)
2392         h = h * 37 + *p;
2393     return h;
2394 }
2395
2396 /********************************************************************
2397  *
2398  * sys_check_options - check the options that the user specified
2399  */
2400
2401 int
2402 sys_check_options(void)
2403 {
2404 #ifdef IPX_CHANGE
2405     struct stat stat_buf;
2406 /*
2407  * Disable the IPX protocol if the support is not present in the kernel.
2408  * If we disable it then ensure that IP support is enabled.
2409  */
2410     while (ipxcp_protent.enabled_flag) {
2411         if (path_to_procfs()) {
2412             strlcat (route_buffer, "/net/ipx_interface", sizeof(route_buffer));
2413             if (lstat (route_buffer, &stat_buf) >= 0)
2414                 break;
2415         }
2416         error("IPX support is not present in the kernel\n");
2417         ipxcp_protent.enabled_flag = 0;
2418         ipcp_protent.enabled_flag  = 1;
2419         break;
2420     }
2421 #endif
2422     if (demand && driver_is_old) {
2423         option_error("demand dialling is not supported by kernel driver "
2424                      "version %d.%d.%d", driver_version, driver_modification,
2425                      driver_patch);
2426         return 0;
2427     }
2428     return 1;
2429 }