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