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