]> git.ozlabs.org Git - ppp.git/blob - pppd/sys-osf.c
take out lock routines, they're now in utils.c
[ppp.git] / pppd / sys-osf.c
1 /*
2  * System-dependent procedures for pppd under Digital UNIX (OSF/1).
3  *
4  * Copyright (c) 1994 The Australian National University.
5  * All rights reserved.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation is hereby granted, provided that the above copyright
9  * notice appears in all copies.  This software is provided without any
10  * warranty, express or implied. The Australian National University
11  * makes no representations about the suitability of this software for
12  * any purpose.
13  *
14  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
15  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
17  * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
18  * OF SUCH DAMAGE.
19  *
20  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
21  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
23  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
24  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
25  * OR MODIFICATIONS.
26  */
27
28 #ifndef lint
29 static char rcsid[] = "$Id: sys-osf.c,v 1.26 1999/04/27 22:33:09 varadhan Exp $";
30 #endif
31
32 #include <stdio.h>
33 #include <stddef.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <termios.h>
41 #include <signal.h>
42 #include <malloc.h>
43 #include <utmp.h>
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/socket.h>
47 #include <sys/stream.h>
48 #include <sys/stropts.h>
49 #include <sys/stat.h>
50 #include <sys/time.h>
51 #include <sys/poll.h>
52 #include <sys/ioctl.h>
53 #include <net/if.h>
54 #include <net/if_dl.h>
55 #include <net/if_arp.h>
56 #include <net/route.h>
57 #include <net/ppp_defs.h>
58 #include <net/pppio.h>
59 #include <netinet/in.h>
60 #include <arpa/inet.h>
61
62 #include "pppd.h"
63
64 static int      pppfd;
65 static int      fdmuxid = -1;
66 static int      iffd;
67 static int      sockfd;
68
69 static int      restore_term;
70 static struct termios inittermios;
71 static struct winsize wsinfo;   /* Initial window size info */
72 static pid_t    tty_sid;        /* PID of our session leader */
73
74 extern u_char   inpacket_buf[]; /* borrowed from main.c */
75
76 static int      link_mtu, link_mru;
77
78 #define NMODULES        32
79 static int      tty_nmodules;
80 static char     tty_modules[NMODULES][FMNAMESZ+1];
81
82 static int closed_stdio;
83 static int initfdflags = -1;
84 static int orig_ttyfd = -1;
85
86 static int      if_is_up;       /* Interface has been marked up */
87 static u_int32_t ifaddrs[2];    /* local and remote addresses */
88 static u_int32_t default_route_gateway; /* Gateway for default route added */
89 static u_int32_t proxy_arp_addr;        /* Addr for proxy arp entry added */
90
91 #define MAX_POLLFDS     32
92 static struct pollfd pollfds[MAX_POLLFDS];
93 static int n_pollfds;
94
95 /* Prototypes for procedures local to this file. */
96 static int translate_speed __P((int));
97 static int baud_rate_of __P((int));
98 static int get_ether_addr __P((u_int32_t, struct sockaddr *));
99 static int strioctl __P((int, int, void *, int, int));
100
101
102 /*
103  * sys_init - System-dependent initialization.
104  */
105 void
106 sys_init()
107 {
108     int x;
109
110     openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
111     setlogmask(LOG_UPTO(LOG_INFO));
112     if (debug)
113         setlogmask(LOG_UPTO(LOG_DEBUG));
114
115     /* Get an internet socket for doing socket ioctl's on. */
116     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
117         fatal("Couldn't create IP socket: %m");
118
119     if (default_device)
120         tty_sid = getsid((pid_t)0);
121
122     /*
123      * Open the ppp device.
124      */
125     pppfd = open("/dev/streams/ppp", O_RDWR | O_NONBLOCK, 0);
126     if (pppfd < 0)
127         fatal("Can't open /dev/streams/ppp: %m");
128     if (kdebugflag) {
129         x = PPPDBG_LOG + PPPDBG_DRIVER;
130         strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0);
131     }
132
133     /* Assign a new PPA and get its unit number. */
134     if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0)
135         fatal("Can't create new PPP interface: %m");
136
137     /*
138      * Open the ppp device again and push the if_ppp module on it.
139      */
140     iffd = open("/dev/streams/ppp", O_RDWR, 0);
141     if (iffd < 0)
142         fatal("Can't open /dev/streams/ppp (2): %m");
143     if (kdebugflag) {
144         x = PPPDBG_LOG + PPPDBG_DRIVER;
145         strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
146     }
147     if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0)
148         fatal("Couldn't attach ppp interface to device: %m");
149     if (ioctl(iffd, I_PUSH, "if_ppp") < 0)
150         fatal("Can't push ppp interface module: %m");
151     if (kdebugflag) {
152         x = PPPDBG_LOG + PPPDBG_IF;
153         strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
154     }
155     if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0)
156         fatal("Couldn't create ppp interface unit: %m");
157     x = PPP_IP;
158     if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0)
159         fatal("Couldn't bind ppp interface to IP SAP: %m");
160
161     n_pollfds = 0;
162 }
163
164 /*
165  * sys_cleanup - restore any system state we modified before exiting:
166  * mark the interface down, delete default route and/or proxy arp entry.
167  * This shouldn't call die() because it's called from die().
168  */
169 void
170 sys_cleanup()
171 {
172     if (if_is_up)
173         sifdown(0);
174     if (ifaddrs[0])
175         cifaddr(0, ifaddrs[0], ifaddrs[1]);
176     if (default_route_gateway)
177         cifdefaultroute(0, 0, default_route_gateway);
178     if (proxy_arp_addr)
179         cifproxyarp(0, proxy_arp_addr);
180 }
181
182 /*
183  * sys_close - Clean up in a child process before execing.
184  */
185 void
186 sys_close()
187 {
188     close(iffd);
189     close(pppfd);
190     close(sockfd);
191     closelog();
192 }
193
194 /*
195  * sys_check_options - check the options that the user specified
196  */
197 int
198 sys_check_options()
199 {
200     return 1;
201 }
202
203 #if 0
204 /*
205  * daemon - Detach us from controlling terminal session.
206  */
207 int
208 daemon(nochdir, noclose)
209     int nochdir, noclose;
210 {
211     int pid;
212
213     if ((pid = fork()) < 0)
214         return -1;
215     if (pid != 0)
216         exit(0);                /* parent dies */
217     setsid();
218     if (!nochdir)
219         chdir("/");
220     if (!noclose) {
221         fclose(stdin);          /* don't need stdin, stdout, stderr */
222         fclose(stdout);
223         fclose(stderr);
224     }
225     return 0;
226 }
227 #endif
228
229 /*
230  * ppp_available - check whether the system has any ppp interfaces
231  */
232 int
233 ppp_available()
234 {
235     struct stat buf;
236
237     return stat("/dev/streams/ppp", &buf) >= 0;
238 }
239
240 char pipename[] = "/dev/streams/pipe";
241
242 /*
243  *  streampipe -- Opens a STREAMS based pipe.  Used by streamify().
244  */
245
246 int 
247 streampipe(int fd[2])
248 {
249     if ((fd[0]=open(pipename, O_RDWR)) == -1)
250         return(-1);
251     else if ((fd[1]=open(pipename, O_RDWR)) == -1) {
252         close(fd[0]);
253         return(-1);
254     } else if (ioctl(fd[0], I_PIPE, fd[1]) != 0) {
255         close(fd[0]);
256         close(fd[1]);
257         return(-1);
258     } else {
259         return(ioctl(fd[0], I_PUSH, "pipemod"));
260     }
261 }
262
263 /*
264  *  streamify -- Needed for Digital UNIX, since some tty devices are not STREAMS
265  *               modules (but ptys are, and pipes can be).
266  */
267
268 #define BUFFSIZE 1000     /*  Size of buffer for streamify()  */
269
270 int 
271 streamify(int fd)
272 {
273     int fdes[2];
274     fd_set readfds;
275     int ret, fret, rret, maxfd;
276     static char buffer[BUFFSIZE];
277     struct sigaction sa;
278
279     if (streampipe(fdes) != 0)
280         error("streampipe(): %m\n");
281     else if (isastream(fdes[0]) == 1) {
282         if ((fret=fork()) < 0) {
283             error("fork(): %m\n");
284         } else if (fret == 0) {
285             /*  Process to forward things from pipe to tty  */
286             sigemptyset(&(sa.sa_mask));
287             sa.sa_handler = SIG_DFL;
288             sa.sa_flags = 0;
289             sigaction(SIGHUP, &sa, NULL);   /*  Go back to default actions */
290             sigaction(SIGINT, &sa, NULL);   /*  for changed signals.  */
291             sigaction(SIGTERM, &sa, NULL);
292             sigaction(SIGCHLD, &sa, NULL);
293             sigaction(SIGUSR1, &sa, NULL);
294             sigaction(SIGUSR2, &sa, NULL);
295             close(fdes[0]);
296
297             maxfd = (fdes[1]>fd)?fdes[1]:fd;
298             while (1) {
299                 FD_ZERO(&readfds);
300                 FD_SET(fdes[1], &readfds);
301                 FD_SET(fd, &readfds);
302                 ret = select(maxfd+1, &readfds, NULL, NULL, NULL);
303                 if (FD_ISSET(fd, &readfds)) {
304                     rret = read(fd, buffer, BUFFSIZE);
305                     if (rret == 0) {
306                         SYSDEBUG(("slave died:  EOF on tty."));
307                         exit(0);
308                     } else {
309                         write(fdes[1], buffer, rret);
310                     }
311                 }
312                 if (FD_ISSET(fdes[1], &readfds)) {
313                     rret = read(fdes[1], buffer, BUFFSIZE);
314                     if (rret == 0) {
315                         SYSDEBUG(("slave died:  EOF on pipe."));
316                         exit(0);
317                     } else {
318                         write(fd, buffer, rret);
319                     }
320                 }
321             }
322         } else {
323             close(fdes[1]);
324             orig_ttyfd = fd;
325             return(fdes[0]);
326         }
327     }
328
329     return(-1);
330 }
331
332 /*
333  * establish_ppp - Turn the serial port into a ppp interface.
334  */
335 int
336 establish_ppp(fd)
337     int fd;
338 {
339     int i;
340
341     if (isastream(fd) != 1) {
342         if ((ttyfd = fd = streamify(fd)) < 0)
343             fatal("Couldn't get a STREAMS module!\n");
344     }
345
346     /* Pop any existing modules off the tty stream. */
347     for (i = 0;; ++i) {
348         if (ioctl(fd, I_LOOK, tty_modules[i]) < 0
349             || ioctl(fd, I_POP, 0) < 0)
350             break;
351         error("popping module %s\n", tty_modules[i]);
352     }
353
354     tty_nmodules = i;
355
356     /* Push the async hdlc module and the compressor module. */
357     if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0)
358         fatal("Couldn't push PPP Async HDLC module: %m");
359     if (ioctl(fd, I_PUSH, "ppp_comp") < 0)
360         error("Couldn't push PPP compression module: %m");
361
362     /* read mode, message non-discard mode */
363     if (ioctl(fd, I_SRDOPT, RMSGN|RPROTNORM) < 0)
364         fatal("ioctl(I_SRDOPT, RMSGN): %m");
365
366     /* Link the serial port under the PPP multiplexor. */
367     if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0)
368         fatal("Can't link tty to PPP mux: %m");
369
370     /* close stdin, stdout, stderr if they might refer to the device */
371     if (default_device && !closed_stdio) {
372         int i;
373
374         for (i = 0; i <= 2; ++i)
375             if (i != fd && i != sockfd)
376                 close(i);
377         closed_stdio = 1;
378     }
379
380     /*
381      * Set device for non-blocking reads.
382      * XXX why do we need to do this?  don't we use pppfd not fd?
383      */
384     if ((initfdflags = fcntl(fd, F_GETFL)) == -1
385         || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
386         warn("Couldn't set device to non-blocking mode: %m");
387     }
388
389     return pppfd;
390 }
391
392 /*
393  * restore_loop - reattach the ppp unit to the loopback.
394  * This doesn't need to do anything because disestablish_ppp does it.
395  */
396 void
397 restore_loop()
398 {
399 }
400
401 /*
402  * disestablish_ppp - Restore the serial port to normal operation.
403  * It attempts to reconstruct the stream with the previously popped
404  * modules.  This shouldn't call die() because it's called from die().
405  */
406 void
407 disestablish_ppp(fd)
408     int fd;
409 {
410     int i;
411
412     if (fdmuxid >= 0) {
413         if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) {
414             if (!hungup)
415                 error("Can't unlink tty from PPP mux: %m");
416         }
417         fdmuxid = -1;
418
419         /* Reset non-blocking mode on the file descriptor. */
420         if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)
421             warn("Couldn't restore device fd flags: %m");
422         initfdflags = -1;
423
424         if (!hungup) {
425             while (ioctl(fd, I_POP, 0) >= 0)
426                 ;
427             for (i = tty_nmodules - 1; i >= 0; --i)
428                 if (ioctl(fd, I_PUSH, tty_modules[i]) < 0)
429                     error("Couldn't restore tty module %s: %m",
430                            tty_modules[i]);
431         }
432
433         if (hungup && default_device && tty_sid > 0) {
434             /*
435              * If we have received a hangup, we need to send a SIGHUP
436              * to the terminal's controlling process.  The reason is
437              * that the original stream head for the terminal hasn't
438              * seen the M_HANGUP message (it went up through the ppp
439              * driver to the stream head for our fd to /dev/ppp).
440              */
441             dbglog("sending hangup to %d", tty_sid);
442             if (kill(tty_sid, SIGHUP) < 0)
443                 error("couldn't kill pgrp: %m");
444         }
445         if (orig_ttyfd >= 0) {
446             close(fd);
447             (void)wait((void *)0);
448             ttyfd = orig_ttyfd;
449             orig_ttyfd = -1;
450         }
451     }
452 }
453
454 /*
455  * Check whether the link seems not to be 8-bit clean.
456  */
457 void
458 clean_check()
459 {
460     int x;
461     char *s;
462
463     if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0)
464         return;
465     s = NULL;
466     switch (~x) {
467     case RCV_B7_0:
468         s = "bit 7 set to 1";
469         break;
470     case RCV_B7_1:
471         s = "bit 7 set to 0";
472         break;
473     case RCV_EVNP:
474         s = "odd parity";
475         break;
476     case RCV_ODDP:
477         s = "even parity";
478         break;
479     }
480     if (s != NULL) {
481         warn("Serial link is not 8-bit clean:");
482         warn("All received characters had %s", s);
483     }
484 }
485
486 /*
487  * List of valid speeds.
488  */
489 struct speed {
490     int speed_int, speed_val;
491 } speeds[] = {
492 #ifdef B50
493     { 50, B50 },
494 #endif
495 #ifdef B75
496     { 75, B75 },
497 #endif
498 #ifdef B110
499     { 110, B110 },
500 #endif
501 #ifdef B134
502     { 134, B134 },
503 #endif
504 #ifdef B150
505     { 150, B150 },
506 #endif
507 #ifdef B200
508     { 200, B200 },
509 #endif
510 #ifdef B300
511     { 300, B300 },
512 #endif
513 #ifdef B600
514     { 600, B600 },
515 #endif
516 #ifdef B1200
517     { 1200, B1200 },
518 #endif
519 #ifdef B1800
520     { 1800, B1800 },
521 #endif
522 #ifdef B2000
523     { 2000, B2000 },
524 #endif
525 #ifdef B2400
526     { 2400, B2400 },
527 #endif
528 #ifdef B3600
529     { 3600, B3600 },
530 #endif
531 #ifdef B4800
532     { 4800, B4800 },
533 #endif
534 #ifdef B7200
535     { 7200, B7200 },
536 #endif
537 #ifdef B9600
538     { 9600, B9600 },
539 #endif
540 #ifdef B19200
541     { 19200, B19200 },
542 #endif
543 #ifdef B38400
544     { 38400, B38400 },
545 #endif
546 #ifdef EXTA
547     { 19200, EXTA },
548 #endif
549 #ifdef EXTB
550     { 38400, EXTB },
551 #endif
552 #ifdef B57600
553     { 57600, B57600 },
554 #endif
555 #ifdef B115200
556     { 115200, B115200 },
557 #endif
558     { 0, 0 }
559 };
560
561 /*
562  * Translate from bits/second to a speed_t.
563  */
564 static int
565 translate_speed(bps)
566     int bps;
567 {
568     struct speed *speedp;
569
570     if (bps == 0)
571         return 0;
572     for (speedp = speeds; speedp->speed_int; speedp++)
573         if (bps == speedp->speed_int)
574             return speedp->speed_val;
575     warn("speed %d not supported", bps);
576     return 0;
577 }
578
579 /*
580  * Translate from a speed_t to bits/second.
581  */
582 static int
583 baud_rate_of(speed)
584     int speed;
585 {
586     struct speed *speedp;
587
588     if (speed == 0)
589         return 0;
590     for (speedp = speeds; speedp->speed_int; speedp++)
591         if (speed == speedp->speed_val)
592             return speedp->speed_int;
593     return 0;
594 }
595
596 /*
597  * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
598  * at the requested speed, etc.  If `local' is true, set CLOCAL
599  * regardless of whether the modem option was specified.
600  */
601 void
602 set_up_tty(fd, local)
603     int fd, local;
604 {
605     int speed;
606     struct termios tios;
607
608     if (tcgetattr(fd, &tios) < 0)
609         fatal("tcgetattr: %m");
610
611     if (!restore_term) {
612         inittermios = tios;
613         ioctl(fd, TIOCGWINSZ, &wsinfo);
614     }
615
616     tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
617     if (crtscts > 0)
618         tios.c_cflag |= CRTSCTS;
619     else if (crtscts < 0)
620         tios.c_cflag &= ~CRTSCTS;
621
622     tios.c_cflag |= CS8 | CREAD | HUPCL;
623     if (local || !modem)
624         tios.c_cflag |= CLOCAL;
625     tios.c_iflag = IGNBRK | IGNPAR;
626     tios.c_oflag = 0;
627     tios.c_lflag = 0;
628     tios.c_cc[VMIN] = 1;
629     tios.c_cc[VTIME] = 0;
630
631     if (crtscts == -2) {
632         tios.c_iflag |= IXON | IXOFF;
633         tios.c_cc[VSTOP] = 0x13;        /* DC3 = XOFF = ^S */
634         tios.c_cc[VSTART] = 0x11;       /* DC1 = XON  = ^Q */
635     }
636
637     speed = translate_speed(inspeed);
638     if (speed) {
639         cfsetospeed(&tios, speed);
640         cfsetispeed(&tios, speed);
641     } else {
642         speed = cfgetospeed(&tios);
643         /*
644          * We can't proceed if the serial port speed is 0,
645          * since that implies that the serial port is disabled.
646          */
647         if (speed == B0)
648             fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
649     }
650
651     if (tcsetattr(fd, TCSAFLUSH, &tios) < 0)
652         fatal("tcsetattr: %m");
653
654     baud_rate = inspeed = baud_rate_of(speed);
655     restore_term = 1;
656 }
657
658 /*
659  * restore_tty - restore the terminal to the saved settings.
660  */
661 void
662 restore_tty(fd)
663     int fd;
664 {
665     if (restore_term) {
666         if (!default_device) {
667             /*
668              * Turn off echoing, because otherwise we can get into
669              * a loop with the tty and the modem echoing to each other.
670              * We presume we are the sole user of this tty device, so
671              * when we close it, it will revert to its defaults anyway.
672              */
673             inittermios.c_lflag &= ~(ECHO | ECHONL);
674         }
675         if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
676             if (!hungup && errno != ENXIO)
677                 warn("tcsetattr: %m");
678         ioctl(fd, TIOCSWINSZ, &wsinfo);
679         restore_term = 0;
680     }
681 }
682
683 /*
684  * setdtr - control the DTR line on the serial port.
685  * This is called from die(), so it shouldn't call die().
686  */
687 void
688 setdtr(fd, on)
689 int fd, on;
690 {
691     int modembits = TIOCM_DTR;
692
693     ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
694 }
695
696 /*
697  * open_loopback - open the device we use for getting packets
698  * in demand mode.  Under Digital Unix, we use our existing fd
699  * to the ppp driver.
700  */
701 int
702 open_ppp_loopback()
703 {
704     return pppfd;
705 }
706
707 /*
708  * output - Output PPP packet.
709  */
710 void
711 output(unit, p, len)
712     int unit;
713     u_char *p;
714     int len;
715 {
716     struct strbuf data;
717     int retries;
718     struct pollfd pfd;
719
720     if (debug)
721         dbglog("sent %P", p, len);
722
723     data.len = len;
724     data.buf = (caddr_t) p;
725     retries = 4;
726     while (putmsg(pppfd, NULL, &data, 0) < 0) {
727         if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) {
728             if (errno != ENXIO)
729                 error("Couldn't send packet: %m");
730             break;
731         }
732         pfd.fd = pppfd;
733         pfd.events = POLLOUT;
734         poll(&pfd, 1, 250);     /* wait for up to 0.25 seconds */
735     }
736 }
737
738
739 /*
740  * wait_input - wait until there is data available on fd,
741  * for the length of time specified by *timo (indefinite
742  * if timo is NULL).
743  */
744 void
745 wait_input(timo)
746     struct timeval *timo;
747 {
748     int t;
749
750     t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000;
751     if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR)
752         fatal("poll: %m");
753 }
754
755 /*
756  * add_fd - add an fd to the set that wait_input waits for.
757  */
758 void add_fd(fd)
759     int fd;
760 {
761     int n;
762
763     for (n = 0; n < n_pollfds; ++n)
764         if (pollfds[n].fd == fd)
765             return;
766     if (n_pollfds < MAX_POLLFDS) {
767         pollfds[n_pollfds].fd = fd;
768         pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP;
769         ++n_pollfds;
770     } else
771         error("Too many inputs!");
772 }
773
774 /*
775  * remove_fd - remove an fd from the set that wait_input waits for.
776  */
777 void remove_fd(fd)
778     int fd;
779 {
780     int n;
781
782     for (n = 0; n < n_pollfds; ++n) {
783         if (pollfds[n].fd == fd) {
784             while (++n < n_pollfds)
785                 pollfds[n-1] = pollfds[n];
786             --n_pollfds;
787             break;
788         }
789     }
790 }
791
792 #if 0
793 /*
794  * wait_loop_output - wait until there is data available on the
795  * loopback, for the length of time specified by *timo (indefinite
796  * if timo is NULL).
797  */
798 void
799 wait_loop_output(timo)
800     struct timeval *timo;
801 {
802     wait_input(timo);
803 }
804
805 /*
806  * wait_time - wait for a given length of time or until a
807  * signal is received.
808  */
809 void
810 wait_time(timo)
811     struct timeval *timo;
812 {
813     int n;
814
815     n = select(0, NULL, NULL, NULL, timo);
816     if (n < 0 && errno != EINTR)
817         fatal("select: %m");
818 }
819 #endif
820
821 /*
822  * read_packet - get a PPP packet from the serial device.
823  */
824 int
825 read_packet(buf)
826     u_char *buf;
827 {
828     struct strbuf ctrl, data;
829     int flags, len;
830     unsigned char ctrlbuf[64];
831
832     for (;;) {
833         data.maxlen = PPP_MRU + PPP_HDRLEN;
834         data.buf = (caddr_t) buf;
835         ctrl.maxlen = sizeof(ctrlbuf);
836         ctrl.buf = (caddr_t) ctrlbuf;
837         flags = 0;
838         len = getmsg(pppfd, &ctrl, &data, &flags);
839         if (len < 0) {
840             if (errno = EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
841                 return -1;
842             fatal("Error reading packet: %m");
843         }
844
845         if (ctrl.len <= 0)
846             return data.len;
847
848         /*
849          * Got a M_PROTO or M_PCPROTO message.  Huh?
850          */
851         if (debug)
852             dbglog("got ctrl msg len=%d", ctrl.len);
853
854     }
855 }
856
857 /*
858  * get_loop_output - get outgoing packets from the ppp device,
859  * and detect when we want to bring the real link up.
860  * Return value is 1 if we need to bring up the link, 0 otherwise.
861  */
862 int
863 get_loop_output()
864 {
865     int len;
866     int rv = 0;
867
868     while ((len = read_packet(inpacket_buf)) > 0) {
869         if (loop_frame(inpacket_buf, len))
870             rv = 1;
871     }
872     return rv;
873 }
874
875 /*
876  * ppp_send_config - configure the transmit characteristics of
877  * the ppp interface.
878  */
879 void
880 ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
881     int unit, mtu;
882     u_int32_t asyncmap;
883     int pcomp, accomp;
884 {
885     int cf[2];
886
887     link_mtu = mtu;
888     if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
889         if (hungup && errno == ENXIO)
890             return;
891         error("Couldn't set MTU: %m");
892     }
893     if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
894         error("Couldn't set transmit ACCM: %m");
895     }
896     cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
897     cf[1] = COMP_PROT | COMP_AC;
898     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
899         error("Couldn't set prot/AC compression: %m");
900     }
901 }
902
903 /*
904  * ppp_set_xaccm - set the extended transmit ACCM for the interface.
905  */
906 void
907 ppp_set_xaccm(unit, accm)
908     int unit;
909     ext_accm accm;
910 {
911     if (strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) {
912         if (!hungup || errno != ENXIO)
913             warn("Couldn't set extended ACCM: %m");
914     }
915 }
916
917 /*
918  * ppp_recv_config - configure the receive-side characteristics of
919  * the ppp interface.
920  */
921 void
922 ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
923     int unit, mru;
924     u_int32_t asyncmap;
925     int pcomp, accomp;
926 {
927     int cf[2];
928
929     link_mru = mru;
930     if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
931         if (hungup && errno == ENXIO)
932             return;
933         error("Couldn't set MRU: %m");
934     }
935     if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
936         error("Couldn't set receive ACCM: %m");
937     }
938     cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
939     cf[1] = DECOMP_PROT | DECOMP_AC;
940     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
941         error("Couldn't set prot/AC decompression: %m");
942     }
943 }
944
945 /*
946  * ccp_test - ask kernel whether a given compression method
947  * is acceptable for use.
948  *
949  * In Digital UNIX the memory buckets for chunks >16K are not
950  * primed when the system comes up.  That means we're not
951  * likely to get the memory needed for the compressor on
952  * the first try.  The way we work around this is to have
953  * the driver spin off a thread to go get the memory for us
954  * (we can't block at that point in a streams context.)
955  *
956  * This code synchronizes with the thread when it has returned
957  * with the memory we need.  The driver will continue to return
958  * with EAGAIN until the thread comes back.  We give up here
959  * if after 10 attempts in one second we still don't have memory.
960  * It's up to the driver to not lose track of that memory if
961  * thread takes too long to return.
962  */
963 int
964 ccp_test(unit, opt_ptr, opt_len, for_transmit)
965     int unit, opt_len, for_transmit;
966     u_char *opt_ptr;
967 {
968     struct timeval tval;
969     int i;
970
971     tval.tv_sec = 0;
972     tval.tv_usec = 100000;
973     for (i = 0; i < 10; ++i) {
974         if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP),
975             opt_ptr, opt_len, 0) >= 0) {
976             return 1;
977         }
978         if (errno != EAGAIN)
979             break;
980         wait_time(&tval);
981     }
982     if (errno != 0)
983         error("hard failure trying to get memory for a compressor: %m");
984     return (errno == ENOSR)? 0: -1;
985 }
986
987 /*
988  * ccp_flags_set - inform kernel about the current state of CCP.
989  */
990 void
991 ccp_flags_set(unit, isopen, isup)
992     int unit, isopen, isup;
993 {
994     int cf[2];
995
996     cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0);
997     cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR;
998     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
999         if (!hungup || errno != ENXIO)
1000             error("Couldn't set kernel CCP state: %m");
1001     }
1002 }
1003
1004 /*
1005  * get_idle_time - return how long the link has been idle.
1006  */
1007 int
1008 get_idle_time(u, ip)
1009     int u;
1010     struct ppp_idle *ip;
1011 {
1012     return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;
1013 }
1014
1015 /*
1016  * get_ppp_stats - return statistics for the link.
1017  */
1018 int
1019 get_ppp_stats(u, stats)
1020     int u;
1021     struct pppd_stats *stats;
1022 {
1023     struct ppp_stats s;
1024
1025     if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {
1026         error("Couldn't get link statistics: %m");
1027         return 0;
1028     }
1029     stats->bytes_in = s.p.ppp_ibytes;
1030     stats->bytes_out = s.p.ppp_obytes;
1031     return 1;
1032 }
1033
1034
1035 /*
1036  * ccp_fatal_error - returns 1 if decompression was disabled as a
1037  * result of an error detected after decompression of a packet,
1038  * 0 otherwise.  This is necessary because of patent nonsense.
1039  */
1040 int
1041 ccp_fatal_error(unit)
1042     int unit;
1043 {
1044     int cf[2];
1045
1046     cf[0] = cf[1] = 0;
1047     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
1048         if (errno != ENXIO && errno != EINVAL)
1049             error("Couldn't get compression flags: %m");
1050         return 0;
1051     }
1052     return cf[0] & CCP_FATALERROR;
1053 }
1054
1055 /*
1056  * sifvjcomp - config tcp header compression
1057  */
1058 int
1059 sifvjcomp(u, vjcomp, xcidcomp, xmaxcid)
1060     int u, vjcomp, xcidcomp, xmaxcid;
1061 {
1062     int cf[2];
1063     char maxcid[2];
1064
1065     if (vjcomp) {
1066         maxcid[0] = xcidcomp;
1067         maxcid[1] = 15;         /* XXX should be rmaxcid */
1068         if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) {
1069             error("Couldn't initialize VJ compression: %m");
1070         }
1071     }
1072
1073     cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0)  /* XXX this is wrong */
1074         + (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0);
1075     cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID;
1076     if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
1077         if (vjcomp)
1078             error("Couldn't enable VJ compression: %m");
1079     }
1080
1081     return 1;
1082 }
1083
1084 /*
1085  * sifup - Config the interface up and enable IP packets to pass.
1086  */
1087 int
1088 sifup(u)
1089     int u;
1090 {
1091     struct ifreq ifr;
1092
1093     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1094     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
1095         error("Couldn't mark interface up (get): %m");
1096         return 0;
1097     }
1098     ifr.ifr_flags |= IFF_UP;
1099     if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
1100         error("Couldn't mark interface up (set): %m");
1101         return 0;
1102     }
1103     if_is_up = 1;
1104     return 1;
1105 }
1106
1107 /*
1108  * sifdown - Config the interface down and disable IP.
1109  */
1110 int
1111 sifdown(u)
1112     int u;
1113 {
1114     struct ifreq ifr;
1115
1116     bzero(&ifr, sizeof(ifr));
1117     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1118     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
1119         error("Couldn't mark interface down (get): %m");
1120         return 0;
1121     }
1122     if ((ifr.ifr_flags & IFF_UP) != 0) {
1123         ifr.ifr_flags &= ~IFF_UP;
1124         if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
1125             error("Couldn't mark interface down (set): %m");
1126             return 0;
1127         }
1128     }
1129     if_is_up = 0;
1130     return 1;
1131 }
1132
1133 /*
1134  * sifnpmode - Set the mode for handling packets for a given NP.
1135  */
1136 int
1137 sifnpmode(u, proto, mode)
1138     int u;
1139     int proto;
1140     enum NPmode mode;
1141 {
1142     int npi[2];
1143
1144     npi[0] = proto;
1145     npi[1] = (int) mode;
1146     if (strioctl(pppfd, PPPIO_NPMODE, npi, 2 * sizeof(int), 0) < 0) {
1147         error("ioctl(set NP %d mode to %d): %m", proto, mode);
1148         return 0;
1149     }
1150     return 1;
1151 }
1152
1153 #define INET_ADDR(x)    (((struct sockaddr_in *) &(x))->sin_addr.s_addr)
1154
1155 /*
1156  * SET_SA_FAMILY - initialize a struct sockaddr, setting the sa_family field.
1157  */
1158 #define SET_SA_FAMILY(addr, family)             \
1159     BZERO((char *) &(addr), sizeof(addr));      \
1160     addr.sa_family = (family);                  \
1161     addr.sa_len = sizeof ((addr))
1162
1163 /*
1164  * sifaddr - Config the interface IP addresses and netmask.
1165  */
1166 int
1167 sifaddr(u, o, h, m)
1168     int u;
1169     u_int32_t o, h, m;
1170 {
1171     struct ifreq ifr;
1172     struct ifaliasreq addreq;
1173     int ret;
1174
1175     ret = 1;
1176
1177     /* flush old address, if any
1178      */
1179     bzero(&ifr, sizeof (ifr));
1180     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1181     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
1182     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;
1183     if ((ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0)
1184         && errno != EADDRNOTAVAIL) {
1185         error("ioctl(SIOCDIFADDR): %m");
1186         ret = 0;
1187     }
1188
1189     bzero(&addreq, sizeof (addreq));
1190     strlcpy(addreq.ifra_name, ifname, sizeof (addreq.ifra_name));
1191     SET_SA_FAMILY(addreq.ifra_addr, AF_INET);
1192     SET_SA_FAMILY(addreq.ifra_broadaddr, AF_INET);
1193     ((struct sockaddr_in *)&addreq.ifra_addr)->sin_addr.s_addr = o;
1194     ((struct sockaddr_in *)&addreq.ifra_broadaddr)->sin_addr.s_addr = h;
1195
1196     if (m != 0) {
1197         ((struct sockaddr_in *)&addreq.ifra_mask)->sin_addr.s_addr = m;
1198         addreq.ifra_mask.sa_len = sizeof (struct sockaddr);
1199         info("Setting interface mask to %s\n", ip_ntoa(m));
1200     }
1201
1202     /* install new src/dst and (possibly) netmask
1203      */
1204     if (ioctl(sockfd, SIOCPIFADDR, &addreq) < 0) {
1205         error("ioctl(SIOCPIFADDR): %m");
1206         ret = 0;
1207     }
1208
1209     ifr.ifr_data = (caddr_t)&link_mtu;
1210
1211     if (ioctl(sockfd, SIOCSIPMTU, &ifr) < 0) {
1212         error("Couldn't set IP MTU: %m");
1213         ret = 0;
1214     }
1215
1216     ifaddrs[0] = o;
1217     ifaddrs[1] = h;
1218     return (ret);
1219 }
1220
1221
1222 /*
1223  * cifaddr - Clear the interface IP addresses, and delete routes
1224  * through the interface if possible.
1225  */
1226 int
1227 cifaddr(u, o, h)
1228     int u;
1229     u_int32_t o, h;
1230 {
1231     struct ifreq ifr;
1232
1233     ifaddrs[0] = 0;
1234     ifaddrs[1] = 0;
1235     bzero(&ifr, sizeof (ifr));
1236     strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1237     SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
1238     ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;
1239     if (ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) {
1240         error("ioctl(SIOCDIFADDR): %m");
1241         return 0;
1242     }
1243     return 1;
1244 }
1245
1246
1247 /*
1248  * sifdefaultroute - assign a default route through the address given.
1249  */
1250 int
1251 sifdefaultroute(u, l, g)
1252     int u;
1253     u_int32_t l, g;
1254 {
1255     struct ortentry rt;
1256
1257     BZERO(&rt, sizeof(rt));
1258     SET_SA_FAMILY(rt.rt_dst, AF_INET);
1259     SET_SA_FAMILY(rt.rt_gateway, AF_INET);
1260     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
1261     rt.rt_flags = RTF_GATEWAY;
1262     if (ioctl(sockfd, (int)SIOCADDRT, &rt) < 0) {
1263         error("default route ioctl(SIOCADDRT): %m");
1264         return 0;
1265     }
1266     default_route_gateway = g;
1267     return 1;
1268 }
1269
1270
1271 /*
1272  * cifdefaultroute - delete a default route through the address given.
1273  */
1274 int
1275 cifdefaultroute(u, l, g)
1276     int u;
1277     u_int32_t l, g;
1278 {
1279     struct ortentry rt;
1280
1281     BZERO(&rt, sizeof(rt));
1282     SET_SA_FAMILY(rt.rt_dst, AF_INET);
1283     SET_SA_FAMILY(rt.rt_gateway, AF_INET);
1284     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
1285     rt.rt_flags = RTF_GATEWAY;
1286     if (ioctl(sockfd, (int)SIOCDELRT, &rt) < 0) {
1287         error("default route ioctl(SIOCDELRT): %m");
1288         return 0;
1289     }
1290     default_route_gateway = 0;
1291     return 1;
1292 }
1293
1294 /*
1295  * sifproxyarp - Make a proxy ARP entry for the peer.
1296  */
1297 int
1298 sifproxyarp(unit, hisaddr)
1299     int unit;
1300     u_int32_t hisaddr;
1301 {
1302     struct arpreq arpreq;
1303
1304     BZERO(&arpreq, sizeof(arpreq));
1305
1306     /*
1307      * Get the hardware address of an interface on the same subnet
1308      * as our local address.
1309      */
1310     if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) {
1311         warn("Cannot determine ethernet address for proxy ARP");
1312         return 0;
1313     }
1314
1315     SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1316     ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
1317     arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1318     if (ioctl(sockfd, (int)SIOCSARP, (caddr_t)&arpreq) < 0) {
1319         error("ioctl(SIOCSARP): %m");
1320         return 0;
1321     }
1322
1323     proxy_arp_addr = hisaddr;
1324     return 1;
1325 }
1326
1327
1328 /*
1329  * cifproxyarp - Delete the proxy ARP entry for the peer.
1330  */
1331 int
1332 cifproxyarp(unit, hisaddr)
1333     int unit;
1334     u_int32_t hisaddr;
1335 {
1336     struct arpreq arpreq;
1337
1338     BZERO(&arpreq, sizeof(arpreq));
1339     SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1340     ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
1341     if (ioctl(sockfd, (int)SIOCDARP, (caddr_t)&arpreq) < 0) {
1342         error("ioctl(SIOCDARP): %m");
1343         return 0;
1344     }
1345     proxy_arp_addr = 0;
1346     return 1;
1347 }
1348
1349 /*
1350  * get_ether_addr - get the hardware address of an interface on the
1351  * the same subnet as ipaddr.
1352  */
1353 #define MAX_IFS         32
1354
1355 static int
1356 get_ether_addr(ipaddr, hwaddr)
1357     u_int32_t ipaddr;
1358     struct sockaddr *hwaddr;
1359 {
1360     struct ifreq *ifr, *ifend;
1361     u_int32_t ina, mask;
1362     struct ifreq ifreq;
1363     struct ifconf ifc;
1364     struct ifreq ifs[MAX_IFS];
1365     struct ifdevea ifdevreq;
1366
1367     ifc.ifc_len = sizeof(ifs);
1368     ifc.ifc_req = ifs;
1369     if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
1370         error("ioctl(SIOCGIFCONF): %m");
1371         return 0;
1372     }
1373
1374     /*
1375      * Scan through looking for an interface with an Internet
1376      * address on the same subnet as `ipaddr'.
1377      */
1378     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1379     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1380         if (ifr->ifr_addr.sa_family == AF_INET) {
1381
1382             /*
1383              * Check that the interface is up, and not point-to-point
1384              * or loopback.
1385              */
1386             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1387             if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
1388                 continue;
1389             if ((ifreq.ifr_flags &
1390                  (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
1391                  != (IFF_UP|IFF_BROADCAST))
1392                 continue;
1393
1394             /*
1395              * Get its netmask and check that it's on the right subnet.
1396              */
1397             if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
1398                 continue;
1399             ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1400             mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1401             if ((ipaddr & mask) != (ina & mask))
1402                 continue;
1403
1404             break;
1405         } else {
1406             if (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr))
1407                 ifr = (struct ifreq *)((caddr_t)ifr + (ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr)));
1408         }
1409     }
1410
1411     if (ifr >= ifend)
1412         return 0;
1413     info("found interface %s for proxy arp", ifr->ifr_name);
1414
1415     strlcpy(ifdevreq.ifr_name, ifr->ifr_name, sizeof(ifdevreq.ifr_name));
1416
1417     if (ioctl(sockfd, (int)SIOCRPHYSADDR, &ifdevreq) < 0) {
1418         perror("ioctl(SIOCRPHYSADDR)");
1419         return(0);
1420     }
1421
1422     hwaddr->sa_family = AF_UNSPEC;
1423     memcpy(hwaddr->sa_data, ifdevreq.current_pa, sizeof(ifdevreq.current_pa));
1424     return 1;
1425 }
1426
1427 #define WTMPFILE        "/usr/adm/wtmp"
1428
1429 void
1430 logwtmp(line, name, host)
1431     const char *line, *name, *host;
1432 {
1433     int fd;
1434     struct stat buf;
1435     struct utmp ut;
1436
1437     if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
1438         return;
1439     if (!fstat(fd, &buf)) {
1440         strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1441         strncpy(ut.ut_name, name, sizeof(ut.ut_name));
1442         strncpy(ut.ut_host, host, sizeof(ut.ut_host));
1443         (void)time(&ut.ut_time);
1444         if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
1445             (void)ftruncate(fd, buf.st_size);
1446     }
1447     close(fd);
1448 }
1449
1450 /*
1451  * Return user specified netmask, modified by any mask we might determine
1452  * for address `addr' (in network byte order).
1453  * Here we scan through the system's list of interfaces, looking for
1454  * any non-point-to-point interfaces which might appear to be on the same
1455  * network as `addr'.  If we find any, we OR in their netmask to the
1456  * user-specified netmask.
1457  */
1458 u_int32_t
1459 GetMask(addr)
1460     u_int32_t addr;
1461 {
1462     u_int32_t mask, nmask, ina;
1463     struct ifreq *ifr, *ifend, ifreq;
1464     struct ifconf ifc;
1465
1466     addr = ntohl(addr);
1467     if (IN_CLASSA(addr))        /* determine network mask for address class */
1468         nmask = IN_CLASSA_NET;
1469     else if (IN_CLASSB(addr))
1470         nmask = IN_CLASSB_NET;
1471     else
1472         nmask = IN_CLASSC_NET;
1473     /* class D nets are disallowed by bad_ip_adrs */
1474     mask = netmask | htonl(nmask);
1475
1476     /*
1477      * Scan through the system's network interfaces.
1478      */
1479     ifc.ifc_len = MAX_IFS * sizeof(struct ifreq);
1480     ifc.ifc_req = (struct ifreq *)alloca(ifc.ifc_len);
1481     if (ifc.ifc_req == 0)
1482         return mask;
1483     if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
1484         warn("Couldn't get system interface list: %m");
1485         return mask;
1486     }
1487     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1488     for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1489         /*
1490          * Check the interface's internet address.
1491          */
1492         if (ifr->ifr_addr.sa_family == AF_INET) {
1493             ina = INET_ADDR(ifr->ifr_addr);
1494             if ((ntohl(ina) & nmask) != (addr & nmask))
1495                 continue;
1496             /*
1497              * Check that the interface is up, and not point-to-point or loopback.
1498              */
1499             strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1500             if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
1501                 continue;
1502             if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
1503                 != IFF_UP)
1504                 continue;
1505             /*
1506              * Get its netmask and OR it into our mask.
1507              */
1508             if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
1509                 continue;
1510             mask |= INET_ADDR(ifreq.ifr_addr);
1511             break;
1512         } else {
1513             if (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr))
1514                 ifr = (struct ifreq *)((caddr_t)ifr + (ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr)));
1515         }
1516     }
1517
1518     return mask;
1519 }
1520
1521 /*
1522  * have_route_to - determine if the system has any route to
1523  * a given IP address.  `addr' is in network byte order.
1524  * For demand mode to work properly, we have to ignore routes
1525  * through our own interface.
1526  */
1527 int have_route_to(u_int32_t addr)
1528 {
1529         char buf[sizeof(struct rt_msghdr) + (sizeof(struct sockaddr_in))];
1530         int status;
1531         int s, n;
1532         struct rt_msghdr *rtm;
1533         struct sockaddr_in *sin;
1534         int msglen = sizeof(*rtm) + (sizeof(*sin));
1535         char *cp;
1536         char msg[2048];
1537
1538         rtm = (struct rt_msghdr *)buf;
1539         memset(rtm, 0, msglen);
1540         rtm->rtm_msglen = msglen;
1541         rtm->rtm_version = RTM_VERSION;
1542         rtm->rtm_type = RTM_GET;
1543         rtm->rtm_addrs = RTA_DST;
1544         /* rtm->rtm_addrs, rtm_flags  should be set on output */
1545
1546         sin = (struct sockaddr_in *)((u_char *)rtm + sizeof(*rtm));
1547         sin->sin_len = sizeof(*sin);
1548         sin->sin_family = AF_INET;
1549         sin->sin_addr.s_addr = addr;
1550
1551         status = 0;
1552
1553         if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
1554                 return -1;
1555         if (write(s, (char *)rtm, msglen) != msglen) {
1556                 close(s);
1557                 return status == ESRCH? 0: -1;
1558         }
1559
1560         n = read(s, msg, 2048);
1561         close(s);
1562         if (n <= 0)
1563                 return -1;
1564
1565         rtm = (struct rt_msghdr *) msg;
1566         if (rtm->rtm_version != RTM_VERSION)
1567                 return -1;
1568
1569         /* here we try to work out if the route is through our own interface */
1570         cp = (char *)(rtm + 1);
1571         if (rtm->rtm_addrs & RTA_DST) {
1572                 struct sockaddr *sa = (struct sockaddr *) cp;
1573                 cp = (char *)(((unsigned long)cp + sa->sa_len
1574                                + sizeof(long) - 1) & ~(sizeof(long) - 1));
1575         }
1576         if (rtm->rtm_addrs & RTA_GATEWAY) {
1577                 sin = (struct sockaddr_in *) cp;
1578                 if (sin->sin_addr.s_addr == ifaddrs[0]
1579                     || sin->sin_addr.s_addr == ifaddrs[1])
1580                         return 0;       /* route is through our interface */
1581         }
1582
1583         return 1;
1584 }
1585
1586 static int
1587 strioctl(fd, cmd, ptr, ilen, olen)
1588     int fd, cmd, ilen, olen;
1589     void *ptr;
1590 {
1591     struct strioctl str;
1592
1593     str.ic_cmd = cmd;
1594     str.ic_timout = 0;
1595     str.ic_len = ilen;
1596     str.ic_dp = ptr;
1597     if (ioctl(fd, I_STR, &str) == -1)
1598         return -1;
1599     if (str.ic_len != olen)
1600         dbglog("strioctl: expected %d bytes, got %d for cmd %x\n",
1601                olen, str.ic_len, cmd);
1602     return 0;
1603 }
1604
1605 /*
1606  * Use the hostid as part of the random number seed.
1607  */
1608 int
1609 get_host_seed()
1610 {
1611     return gethostid();
1612 }
1613
1614 /*
1615  * get_pty - get a pty master/slave pair and chown the slave side
1616  * to the uid given.  Assumes slave_name points to >= 12 bytes of space.
1617  */
1618 int
1619 get_pty(master_fdp, slave_fdp, slave_name, uid)
1620     int *master_fdp;
1621     int *slave_fdp;
1622     char *slave_name;
1623     int uid;
1624 {
1625     int i, mfd, sfd;
1626     char pty_name[12];
1627     struct termios tios;
1628
1629     sfd = -1;
1630     for (i = 0; i < 64; ++i) {
1631         slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
1632                  'p' + i / 16, i % 16);
1633         mfd = open(pty_name, O_RDWR, 0);
1634         if (mfd >= 0) {
1635             pty_name[5] = 't';
1636             sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
1637             if (sfd >= 0)
1638                 break;
1639             close(mfd);
1640         }
1641     }
1642     if (sfd < 0)
1643         return 0;
1644
1645     strlcpy(slave_name, pty_name, 12);
1646     *master_fdp = mfd;
1647     *slave_fdp = sfd;
1648     fchown(sfd, uid, -1);
1649     fchmod(sfd, S_IRUSR | S_IWUSR);
1650     if (tcgetattr(sfd, &tios) == 0) {
1651         tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
1652         tios.c_cflag |= CS8 | CREAD;
1653         tios.c_iflag  = IGNPAR | CLOCAL;
1654         tios.c_oflag  = 0;
1655         tios.c_lflag  = 0;
1656         if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
1657             warn("couldn't set attributes on pty: %m");
1658     } else
1659         warn("couldn't get attributes on pty: %m");
1660
1661     return 1;
1662 }
1663
1664 #if 0
1665 /*
1666  * Code for locking/unlocking the serial device.
1667  * This code is derived from chat.c.
1668  */
1669
1670 #if !defined(HDB) && !defined(SUNOS3)
1671 #define HDB     1               /* ascii lock files are the default */
1672 #endif
1673
1674 #ifndef LOCK_DIR
1675 # if HDB
1676 #  define       PIDSTRING
1677 #  define       LOCK_PREFIX     "/usr/spool/locks/LCK.."
1678 # else /* HDB */
1679 #  define       LOCK_PREFIX     "/usr/spool/uucp/LCK.."
1680 # endif /* HDB */
1681 #endif /* LOCK_DIR */
1682
1683 static char *lock_file;         /* name of lock file created */
1684
1685 /*
1686  * lock - create a lock file for the named device.
1687  */
1688 int
1689 lock(dev)
1690     char *dev;
1691 {
1692     char hdb_lock_buffer[12];
1693     int fd, pid, n;
1694     char *p;
1695     size_t l;
1696
1697     if ((p = strrchr(dev, '/')) != NULL)
1698         dev = p + 1;
1699     l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
1700     lock_file = malloc(l);
1701     if (lock_file == NULL)
1702         novm("lock file name");
1703     slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
1704
1705     while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
1706         if (errno == EEXIST
1707             && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
1708             /* Read the lock file to find out who has the device locked */
1709 #ifdef PIDSTRING
1710             n = read(fd, hdb_lock_buffer, 11);
1711             if (n > 0) {
1712                 hdb_lock_buffer[n] = 0;
1713                 pid = atoi(hdb_lock_buffer);
1714             }
1715 #else
1716             n = read(fd, &pid, sizeof(pid));
1717 #endif
1718             if (n <= 0) {
1719                 error("Can't read pid from lock file %s", lock_file);
1720                 close(fd);
1721             } else {
1722                 if (kill(pid, 0) == -1 && errno == ESRCH) {
1723                     /* pid no longer exists - remove the lock file */
1724                     if (unlink(lock_file) == 0) {
1725                         close(fd);
1726                         notice("Removed stale lock on %s (pid %d)",
1727                                dev, pid);
1728                         continue;
1729                     } else
1730                         warn("Couldn't remove stale lock on %s",
1731                                dev);
1732                 } else
1733                     notice("Device %s is locked by pid %d",
1734                            dev, pid);
1735             }
1736             close(fd);
1737         } else
1738             error("Can't create lock file %s: %m", lock_file);
1739         free(lock_file);
1740         lock_file = NULL;
1741         return -1;
1742     }
1743
1744 #ifdef PIDSTRING
1745     slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid());
1746     write(fd, hdb_lock_buffer, 11);
1747 #else
1748     pid = getpid();
1749     write(fd, &pid, sizeof pid);
1750 #endif
1751
1752     close(fd);
1753     return 0;
1754 }
1755
1756 /*
1757  * unlock - remove our lockfile
1758  */
1759 void
1760 unlock()
1761 {
1762     if (lock_file) {
1763         unlink(lock_file);
1764         free(lock_file);
1765         lock_file = NULL;
1766     }
1767 }
1768 #endif
1769
1770 int
1771 set_filters(pass, active)
1772     struct bpf_program *pass, *active;
1773 {
1774     return 1;
1775 }
1776
1777 int
1778 bpf_compile(program, buf, optimize)
1779     struct bpf_program *program;
1780     char *buf;
1781     int optimize;
1782 {
1783     return 0;
1784 }
1785
1786 char *
1787 bpf_geterr()
1788 {
1789     return 0;
1790 }
1791
1792 u_int
1793 bpf_filter(pc, p, wirelen, buflen)
1794     struct bpf_insn *pc;
1795     u_char *p;
1796     u_int wirelen;
1797     u_int buflen;
1798 {
1799     return 0;
1800 }