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