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