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