Add winbind plugin from Andrew Bartlet.
[mpls-ppp.git] / pppd / sys-osf.c
blobe2f42184eb623a9fcfb1e192d8a63e360d8369cc
1 /*
2 * System-dependent procedures for pppd under Digital UNIX (OSF/1).
4 * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. The name(s) of the authors of this software must not be used to
14 * endorse or promote products derived from this software without
15 * prior written permission.
17 * 3. Redistributions of any form whatsoever must retain the following
18 * acknowledgment:
19 * "This product includes software developed by Paul Mackerras
20 * <paulus@samba.org>".
22 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 * Derived from main.c and pppd.h, which are:
32 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
36 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in
43 * the documentation and/or other materials provided with the
44 * distribution.
46 * 3. The name "Carnegie Mellon University" must not be used to
47 * endorse or promote products derived from this software without
48 * prior written permission. For permission or any legal
49 * details, please contact
50 * Office of Technology Transfer
51 * Carnegie Mellon University
52 * 5000 Forbes Avenue
53 * Pittsburgh, PA 15213-3890
54 * (412) 268-4387, fax: (412) 268-7395
55 * tech-transfer@andrew.cmu.edu
57 * 4. Redistributions of any form whatsoever must retain the following
58 * acknowledgment:
59 * "This product includes software developed by Computing Services
60 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
62 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
63 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
64 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
65 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
66 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
67 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
68 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
71 #define RCSID "$Id: sys-osf.c,v 1.33 2004/11/04 10:02:26 paulus Exp $"
73 #include <syslog.h>
74 #include <stdio.h>
75 #include <stddef.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include <ctype.h>
79 #include <errno.h>
80 #include <fcntl.h>
81 #include <unistd.h>
82 #include <termios.h>
83 #include <signal.h>
84 #include <malloc.h>
85 #include <utmp.h>
86 #include <sys/types.h>
87 #include <sys/param.h>
88 #include <sys/socket.h>
89 #include <sys/stream.h>
90 #include <sys/stropts.h>
91 #include <sys/stat.h>
92 #include <sys/time.h>
93 #include <sys/poll.h>
94 #include <sys/ioctl.h>
95 #include <net/if.h>
96 #include <net/if_dl.h>
97 #include <net/if_arp.h>
98 #include <net/route.h>
99 #include <net/ppp_defs.h>
100 #include <net/pppio.h>
101 #include <netinet/in.h>
102 #include <arpa/inet.h>
104 #include "pppd.h"
106 static const char rcsid[] = RCSID;
108 static int pppfd;
109 static int fdmuxid = -1;
110 static int iffd;
111 static int sockfd;
113 static int restore_term;
114 static struct termios inittermios;
115 static struct winsize wsinfo; /* Initial window size info */
116 static pid_t tty_sid; /* PID of our session leader */
118 extern u_char inpacket_buf[]; /* borrowed from main.c */
120 static int link_mtu, link_mru;
122 #define NMODULES 32
123 static int tty_nmodules;
124 static char tty_modules[NMODULES][FMNAMESZ+1];
126 static int closed_stdio;
127 static int initfdflags = -1;
128 static int orig_ttyfd = -1;
130 static int if_is_up; /* Interface has been marked up */
131 static u_int32_t ifaddrs[2]; /* local and remote addresses */
132 static u_int32_t default_route_gateway; /* Gateway for default route added */
133 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
135 #define MAX_POLLFDS 32
136 static struct pollfd pollfds[MAX_POLLFDS];
137 static int n_pollfds;
139 /* Prototypes for procedures local to this file. */
140 static int translate_speed __P((int));
141 static int baud_rate_of __P((int));
142 static int get_ether_addr __P((u_int32_t, struct sockaddr *));
143 static int strioctl __P((int, int, void *, int, int));
147 * sys_init - System-dependent initialization.
149 void
150 sys_init()
152 int x;
154 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
155 setlogmask(LOG_UPTO(LOG_INFO));
156 if (debug)
157 setlogmask(LOG_UPTO(LOG_DEBUG));
159 /* Get an internet socket for doing socket ioctl's on. */
160 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
161 fatal("Couldn't create IP socket: %m");
163 if (default_device)
164 tty_sid = getsid((pid_t)0);
167 * Open the ppp device.
169 pppfd = open("/dev/streams/ppp", O_RDWR | O_NONBLOCK, 0);
170 if (pppfd < 0)
171 fatal("Can't open /dev/streams/ppp: %m");
172 if (kdebugflag) {
173 x = PPPDBG_LOG + PPPDBG_DRIVER;
174 strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0);
177 /* Assign a new PPA and get its unit number. */
178 if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0)
179 fatal("Can't create new PPP interface: %m");
182 * Open the ppp device again and push the if_ppp module on it.
184 iffd = open("/dev/streams/ppp", O_RDWR, 0);
185 if (iffd < 0)
186 fatal("Can't open /dev/streams/ppp (2): %m");
187 if (kdebugflag) {
188 x = PPPDBG_LOG + PPPDBG_DRIVER;
189 strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
191 if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0)
192 fatal("Couldn't attach ppp interface to device: %m");
193 if (ioctl(iffd, I_PUSH, "if_ppp") < 0)
194 fatal("Can't push ppp interface module: %m");
195 if (kdebugflag) {
196 x = PPPDBG_LOG + PPPDBG_IF;
197 strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0);
199 if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0)
200 fatal("Couldn't create ppp interface unit: %m");
201 x = PPP_IP;
202 if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0)
203 fatal("Couldn't bind ppp interface to IP SAP: %m");
205 n_pollfds = 0;
209 * sys_cleanup - restore any system state we modified before exiting:
210 * mark the interface down, delete default route and/or proxy arp entry.
211 * This shouldn't call die() because it's called from die().
213 void
214 sys_cleanup()
216 if (if_is_up)
217 sifdown(0);
218 if (ifaddrs[0])
219 cifaddr(0, ifaddrs[0], ifaddrs[1]);
220 if (default_route_gateway)
221 cifdefaultroute(0, 0, default_route_gateway);
222 if (proxy_arp_addr)
223 cifproxyarp(0, proxy_arp_addr);
227 * sys_close - Clean up in a child process before execing.
229 void
230 sys_close()
232 close(iffd);
233 close(pppfd);
234 close(sockfd);
235 closelog();
239 * sys_check_options - check the options that the user specified
242 sys_check_options()
244 return 1;
247 #if 0
249 * daemon - Detach us from controlling terminal session.
252 daemon(nochdir, noclose)
253 int nochdir, noclose;
255 int pid;
257 if ((pid = fork()) < 0)
258 return -1;
259 if (pid != 0)
260 exit(0); /* parent dies */
261 setsid();
262 if (!nochdir)
263 chdir("/");
264 if (!noclose) {
265 fclose(stdin); /* don't need stdin, stdout, stderr */
266 fclose(stdout);
267 fclose(stderr);
269 return 0;
271 #endif
274 * ppp_available - check whether the system has any ppp interfaces
277 ppp_available()
279 struct stat buf;
281 return stat("/dev/streams/ppp", &buf) >= 0;
284 char pipename[] = "/dev/streams/pipe";
287 * streampipe -- Opens a STREAMS based pipe. Used by streamify().
290 int
291 streampipe(int fd[2])
293 if ((fd[0]=open(pipename, O_RDWR)) == -1)
294 return(-1);
295 else if ((fd[1]=open(pipename, O_RDWR)) == -1) {
296 close(fd[0]);
297 return(-1);
298 } else if (ioctl(fd[0], I_PIPE, fd[1]) != 0) {
299 close(fd[0]);
300 close(fd[1]);
301 return(-1);
302 } else {
303 return(ioctl(fd[0], I_PUSH, "pipemod"));
308 * streamify -- Needed for Digital UNIX, since some tty devices are not STREAMS
309 * modules (but ptys are, and pipes can be).
312 #define BUFFSIZE 1000 /* Size of buffer for streamify() */
314 int
315 streamify(int fd)
317 int fdes[2];
318 fd_set readfds;
319 int ret, fret, rret, maxfd;
320 static char buffer[BUFFSIZE];
321 struct sigaction sa;
323 if (streampipe(fdes) != 0)
324 error("streampipe(): %m\n");
325 else if (isastream(fdes[0]) == 1) {
326 if ((fret=fork()) < 0) {
327 error("fork(): %m\n");
328 } else if (fret == 0) {
329 /* Process to forward things from pipe to tty */
330 sigemptyset(&(sa.sa_mask));
331 sa.sa_handler = SIG_DFL;
332 sa.sa_flags = 0;
333 sigaction(SIGHUP, &sa, NULL); /* Go back to default actions */
334 sigaction(SIGINT, &sa, NULL); /* for changed signals. */
335 sigaction(SIGTERM, &sa, NULL);
336 sigaction(SIGCHLD, &sa, NULL);
337 sigaction(SIGUSR1, &sa, NULL);
338 sigaction(SIGUSR2, &sa, NULL);
339 close(fdes[0]);
341 maxfd = (fdes[1]>fd)?fdes[1]:fd;
342 while (1) {
343 FD_ZERO(&readfds);
344 FD_SET(fdes[1], &readfds);
345 FD_SET(fd, &readfds);
346 ret = select(maxfd+1, &readfds, NULL, NULL, NULL);
347 if (FD_ISSET(fd, &readfds)) {
348 rret = read(fd, buffer, BUFFSIZE);
349 if (rret == 0) {
350 SYSDEBUG(("slave died: EOF on tty."));
351 exit(0);
352 } else {
353 write(fdes[1], buffer, rret);
356 if (FD_ISSET(fdes[1], &readfds)) {
357 rret = read(fdes[1], buffer, BUFFSIZE);
358 if (rret == 0) {
359 SYSDEBUG(("slave died: EOF on pipe."));
360 exit(0);
361 } else {
362 write(fd, buffer, rret);
366 } else {
367 close(fdes[1]);
368 orig_ttyfd = fd;
369 return(fdes[0]);
373 return(-1);
377 * establish_ppp - Turn the serial port into a ppp interface.
380 establish_ppp(fd)
381 int fd;
383 int i;
385 if (isastream(fd) != 1) {
386 if ((ttyfd = fd = streamify(fd)) < 0)
387 fatal("Couldn't get a STREAMS module!\n");
390 /* Pop any existing modules off the tty stream. */
391 for (i = 0;; ++i) {
392 if (ioctl(fd, I_LOOK, tty_modules[i]) < 0
393 || ioctl(fd, I_POP, 0) < 0)
394 break;
395 error("popping module %s\n", tty_modules[i]);
398 tty_nmodules = i;
400 /* Push the async hdlc module and the compressor module. */
401 if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0)
402 fatal("Couldn't push PPP Async HDLC module: %m");
403 if (ioctl(fd, I_PUSH, "ppp_comp") < 0)
404 error("Couldn't push PPP compression module: %m");
406 /* read mode, message non-discard mode */
407 if (ioctl(fd, I_SRDOPT, RMSGN|RPROTNORM) < 0)
408 fatal("ioctl(I_SRDOPT, RMSGN): %m");
410 /* Link the serial port under the PPP multiplexor. */
411 if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0)
412 fatal("Can't link tty to PPP mux: %m");
414 /* close stdin, stdout, stderr if they might refer to the device */
415 if (default_device && !closed_stdio) {
416 int i;
418 for (i = 0; i <= 2; ++i)
419 if (i != fd && i != sockfd)
420 close(i);
421 closed_stdio = 1;
422 /* make sure 0, 1, 2 are open to /dev/null */
423 while ((i = open("/dev/null", O_RDWR)) >= 0) {
424 if (i > 2) {
425 close(i);
426 break;
432 * Set device for non-blocking reads.
433 * XXX why do we need to do this? don't we use pppfd not fd?
435 if ((initfdflags = fcntl(fd, F_GETFL)) == -1
436 || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
437 warn("Couldn't set device to non-blocking mode: %m");
440 return pppfd;
444 * restore_loop - reattach the ppp unit to the loopback.
445 * This doesn't need to do anything because disestablish_ppp does it.
447 void
448 restore_loop()
453 * disestablish_ppp - Restore the serial port to normal operation.
454 * It attempts to reconstruct the stream with the previously popped
455 * modules. This shouldn't call die() because it's called from die().
457 void
458 disestablish_ppp(fd)
459 int fd;
461 int i;
463 if (fdmuxid >= 0) {
464 if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) {
465 if (!hungup)
466 error("Can't unlink tty from PPP mux: %m");
468 fdmuxid = -1;
470 /* Reset non-blocking mode on the file descriptor. */
471 if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)
472 warn("Couldn't restore device fd flags: %m");
473 initfdflags = -1;
475 if (!hungup) {
476 while (ioctl(fd, I_POP, 0) >= 0)
478 for (i = tty_nmodules - 1; i >= 0; --i)
479 if (ioctl(fd, I_PUSH, tty_modules[i]) < 0)
480 error("Couldn't restore tty module %s: %m",
481 tty_modules[i]);
484 if (hungup && default_device && tty_sid > 0) {
486 * If we have received a hangup, we need to send a SIGHUP
487 * to the terminal's controlling process. The reason is
488 * that the original stream head for the terminal hasn't
489 * seen the M_HANGUP message (it went up through the ppp
490 * driver to the stream head for our fd to /dev/ppp).
492 dbglog("sending hangup to %d", tty_sid);
493 if (kill(tty_sid, SIGHUP) < 0)
494 error("couldn't kill pgrp: %m");
496 if (orig_ttyfd >= 0) {
497 close(fd);
498 (void)wait((void *)0);
499 ttyfd = orig_ttyfd;
500 orig_ttyfd = -1;
506 * Check whether the link seems not to be 8-bit clean.
508 void
509 clean_check()
511 int x;
512 char *s;
514 if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0)
515 return;
516 s = NULL;
517 switch (~x) {
518 case RCV_B7_0:
519 s = "bit 7 set to 1";
520 break;
521 case RCV_B7_1:
522 s = "bit 7 set to 0";
523 break;
524 case RCV_EVNP:
525 s = "odd parity";
526 break;
527 case RCV_ODDP:
528 s = "even parity";
529 break;
531 if (s != NULL) {
532 warn("Serial link is not 8-bit clean:");
533 warn("All received characters had %s", s);
538 * List of valid speeds.
540 struct speed {
541 int speed_int, speed_val;
542 } speeds[] = {
543 #ifdef B50
544 { 50, B50 },
545 #endif
546 #ifdef B75
547 { 75, B75 },
548 #endif
549 #ifdef B110
550 { 110, B110 },
551 #endif
552 #ifdef B134
553 { 134, B134 },
554 #endif
555 #ifdef B150
556 { 150, B150 },
557 #endif
558 #ifdef B200
559 { 200, B200 },
560 #endif
561 #ifdef B300
562 { 300, B300 },
563 #endif
564 #ifdef B600
565 { 600, B600 },
566 #endif
567 #ifdef B1200
568 { 1200, B1200 },
569 #endif
570 #ifdef B1800
571 { 1800, B1800 },
572 #endif
573 #ifdef B2000
574 { 2000, B2000 },
575 #endif
576 #ifdef B2400
577 { 2400, B2400 },
578 #endif
579 #ifdef B3600
580 { 3600, B3600 },
581 #endif
582 #ifdef B4800
583 { 4800, B4800 },
584 #endif
585 #ifdef B7200
586 { 7200, B7200 },
587 #endif
588 #ifdef B9600
589 { 9600, B9600 },
590 #endif
591 #ifdef B19200
592 { 19200, B19200 },
593 #endif
594 #ifdef B38400
595 { 38400, B38400 },
596 #endif
597 #ifdef EXTA
598 { 19200, EXTA },
599 #endif
600 #ifdef EXTB
601 { 38400, EXTB },
602 #endif
603 #ifdef B57600
604 { 57600, B57600 },
605 #endif
606 #ifdef B115200
607 { 115200, B115200 },
608 #endif
609 { 0, 0 }
613 * Translate from bits/second to a speed_t.
615 static int
616 translate_speed(bps)
617 int bps;
619 struct speed *speedp;
621 if (bps == 0)
622 return 0;
623 for (speedp = speeds; speedp->speed_int; speedp++)
624 if (bps == speedp->speed_int)
625 return speedp->speed_val;
626 warn("speed %d not supported", bps);
627 return 0;
631 * Translate from a speed_t to bits/second.
633 static int
634 baud_rate_of(speed)
635 int speed;
637 struct speed *speedp;
639 if (speed == 0)
640 return 0;
641 for (speedp = speeds; speedp->speed_int; speedp++)
642 if (speed == speedp->speed_val)
643 return speedp->speed_int;
644 return 0;
648 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
649 * at the requested speed, etc. If `local' is true, set CLOCAL
650 * regardless of whether the modem option was specified.
652 void
653 set_up_tty(fd, local)
654 int fd, local;
656 int speed;
657 struct termios tios;
659 if (tcgetattr(fd, &tios) < 0)
660 fatal("tcgetattr: %m");
662 if (!restore_term) {
663 inittermios = tios;
664 ioctl(fd, TIOCGWINSZ, &wsinfo);
667 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
668 if (crtscts > 0)
669 tios.c_cflag |= CRTSCTS;
670 else if (crtscts < 0)
671 tios.c_cflag &= ~CRTSCTS;
673 tios.c_cflag |= CS8 | CREAD | HUPCL;
674 if (local || !modem)
675 tios.c_cflag |= CLOCAL;
676 tios.c_iflag = IGNBRK | IGNPAR;
677 tios.c_oflag = 0;
678 tios.c_lflag = 0;
679 tios.c_cc[VMIN] = 1;
680 tios.c_cc[VTIME] = 0;
682 if (crtscts == -2) {
683 tios.c_iflag |= IXON | IXOFF;
684 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
685 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
688 speed = translate_speed(inspeed);
689 if (speed) {
690 cfsetospeed(&tios, speed);
691 cfsetispeed(&tios, speed);
692 } else {
693 speed = cfgetospeed(&tios);
695 * We can't proceed if the serial port speed is 0,
696 * since that implies that the serial port is disabled.
698 if (speed == B0)
699 fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
702 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0)
703 fatal("tcsetattr: %m");
705 baud_rate = inspeed = baud_rate_of(speed);
706 restore_term = 1;
710 * restore_tty - restore the terminal to the saved settings.
712 void
713 restore_tty(fd)
714 int fd;
716 if (restore_term) {
717 if (!default_device) {
719 * Turn off echoing, because otherwise we can get into
720 * a loop with the tty and the modem echoing to each other.
721 * We presume we are the sole user of this tty device, so
722 * when we close it, it will revert to its defaults anyway.
724 inittermios.c_lflag &= ~(ECHO | ECHONL);
726 if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
727 if (!hungup && errno != ENXIO)
728 warn("tcsetattr: %m");
729 ioctl(fd, TIOCSWINSZ, &wsinfo);
730 restore_term = 0;
735 * setdtr - control the DTR line on the serial port.
736 * This is called from die(), so it shouldn't call die().
738 void
739 setdtr(fd, on)
740 int fd, on;
742 int modembits = TIOCM_DTR;
744 ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
748 * open_loopback - open the device we use for getting packets
749 * in demand mode. Under Digital Unix, we use our existing fd
750 * to the ppp driver.
753 open_ppp_loopback()
755 return pppfd;
759 * output - Output PPP packet.
761 void
762 output(unit, p, len)
763 int unit;
764 u_char *p;
765 int len;
767 struct strbuf data;
768 int retries;
769 struct pollfd pfd;
771 if (debug)
772 dbglog("sent %P", p, len);
774 data.len = len;
775 data.buf = (caddr_t) p;
776 retries = 4;
777 while (putmsg(pppfd, NULL, &data, 0) < 0) {
778 if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) {
779 if (errno != ENXIO)
780 error("Couldn't send packet: %m");
781 break;
783 pfd.fd = pppfd;
784 pfd.events = POLLOUT;
785 poll(&pfd, 1, 250); /* wait for up to 0.25 seconds */
791 * wait_input - wait until there is data available on fd,
792 * for the length of time specified by *timo (indefinite
793 * if timo is NULL).
795 void
796 wait_input(timo)
797 struct timeval *timo;
799 int t;
801 t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000;
802 if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR)
803 fatal("poll: %m");
807 * add_fd - add an fd to the set that wait_input waits for.
809 void add_fd(fd)
810 int fd;
812 int n;
814 for (n = 0; n < n_pollfds; ++n)
815 if (pollfds[n].fd == fd)
816 return;
817 if (n_pollfds < MAX_POLLFDS) {
818 pollfds[n_pollfds].fd = fd;
819 pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP;
820 ++n_pollfds;
821 } else
822 error("Too many inputs!");
826 * remove_fd - remove an fd from the set that wait_input waits for.
828 void remove_fd(fd)
829 int fd;
831 int n;
833 for (n = 0; n < n_pollfds; ++n) {
834 if (pollfds[n].fd == fd) {
835 while (++n < n_pollfds)
836 pollfds[n-1] = pollfds[n];
837 --n_pollfds;
838 break;
843 #if 0
845 * wait_loop_output - wait until there is data available on the
846 * loopback, for the length of time specified by *timo (indefinite
847 * if timo is NULL).
849 void
850 wait_loop_output(timo)
851 struct timeval *timo;
853 wait_input(timo);
856 #endif
859 * wait_time - wait for a given length of time or until a
860 * signal is received. Called by ccp_test
862 static void
863 wait_time(timo)
864 struct timeval *timo;
866 int n;
868 n = select(0, NULL, NULL, NULL, timo);
869 if (n < 0 && errno != EINTR)
870 fatal("select: %m");
874 * read_packet - get a PPP packet from the serial device.
877 read_packet(buf)
878 u_char *buf;
880 struct strbuf ctrl, data;
881 int flags, len;
882 unsigned char ctrlbuf[64];
884 for (;;) {
885 data.maxlen = PPP_MRU + PPP_HDRLEN;
886 data.buf = (caddr_t) buf;
887 ctrl.maxlen = sizeof(ctrlbuf);
888 ctrl.buf = (caddr_t) ctrlbuf;
889 flags = 0;
890 len = getmsg(pppfd, &ctrl, &data, &flags);
891 if (len < 0) {
892 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
893 return -1;
894 fatal("Error reading packet: %m");
897 if (ctrl.len <= 0)
898 return data.len;
901 * Got a M_PROTO or M_PCPROTO message. Huh?
903 if (debug)
904 dbglog("got ctrl msg len=%d", ctrl.len);
910 * get_loop_output - get outgoing packets from the ppp device,
911 * and detect when we want to bring the real link up.
912 * Return value is 1 if we need to bring up the link, 0 otherwise.
915 get_loop_output()
917 int len;
918 int rv = 0;
920 while ((len = read_packet(inpacket_buf)) > 0) {
921 if (loop_frame(inpacket_buf, len))
922 rv = 1;
924 return rv;
928 * ppp_send_config - configure the transmit characteristics of
929 * the ppp interface.
931 void
932 ppp_send_config(unit, mtu, asyncmap, pcomp, accomp)
933 int unit, mtu;
934 u_int32_t asyncmap;
935 int pcomp, accomp;
937 int cf[2];
939 link_mtu = mtu;
940 if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
941 if (hungup && errno == ENXIO)
942 return;
943 error("Couldn't set MTU: %m");
945 if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
946 error("Couldn't set transmit ACCM: %m");
948 cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
949 cf[1] = COMP_PROT | COMP_AC;
950 if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
951 error("Couldn't set prot/AC compression: %m");
956 * ppp_set_xaccm - set the extended transmit ACCM for the interface.
958 void
959 ppp_set_xaccm(unit, accm)
960 int unit;
961 ext_accm accm;
963 if (strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) {
964 if (!hungup || errno != ENXIO)
965 warn("Couldn't set extended ACCM: %m");
970 * ppp_recv_config - configure the receive-side characteristics of
971 * the ppp interface.
973 void
974 ppp_recv_config(unit, mru, asyncmap, pcomp, accomp)
975 int unit, mru;
976 u_int32_t asyncmap;
977 int pcomp, accomp;
979 int cf[2];
981 link_mru = mru;
982 if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
983 if (hungup && errno == ENXIO)
984 return;
985 error("Couldn't set MRU: %m");
987 if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) {
988 error("Couldn't set receive ACCM: %m");
990 cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
991 cf[1] = DECOMP_PROT | DECOMP_AC;
992 if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
993 error("Couldn't set prot/AC decompression: %m");
998 * ccp_test - ask kernel whether a given compression method
999 * is acceptable for use.
1001 * In Digital UNIX the memory buckets for chunks >16K are not
1002 * primed when the system comes up. That means we're not
1003 * likely to get the memory needed for the compressor on
1004 * the first try. The way we work around this is to have
1005 * the driver spin off a thread to go get the memory for us
1006 * (we can't block at that point in a streams context.)
1008 * This code synchronizes with the thread when it has returned
1009 * with the memory we need. The driver will continue to return
1010 * with EAGAIN until the thread comes back. We give up here
1011 * if after 10 attempts in one second we still don't have memory.
1012 * It's up to the driver to not lose track of that memory if
1013 * thread takes too long to return.
1016 ccp_test(unit, opt_ptr, opt_len, for_transmit)
1017 int unit, opt_len, for_transmit;
1018 u_char *opt_ptr;
1020 struct timeval tval;
1021 int i;
1023 tval.tv_sec = 0;
1024 tval.tv_usec = 100000;
1025 for (i = 0; i < 10; ++i) {
1026 if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP),
1027 opt_ptr, opt_len, 0) >= 0) {
1028 return 1;
1030 if (errno != EAGAIN)
1031 break;
1032 wait_time(&tval);
1034 if (errno != 0)
1035 error("hard failure trying to get memory for a compressor: %m");
1036 return (errno == ENOSR)? 0: -1;
1040 * ccp_flags_set - inform kernel about the current state of CCP.
1042 void
1043 ccp_flags_set(unit, isopen, isup)
1044 int unit, isopen, isup;
1046 int cf[2];
1048 cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0);
1049 cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR;
1050 if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
1051 if (!hungup || errno != ENXIO)
1052 error("Couldn't set kernel CCP state: %m");
1057 * get_idle_time - return how long the link has been idle.
1060 get_idle_time(u, ip)
1061 int u;
1062 struct ppp_idle *ip;
1064 return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;
1068 * get_ppp_stats - return statistics for the link.
1071 get_ppp_stats(u, stats)
1072 int u;
1073 struct pppd_stats *stats;
1075 struct ppp_stats s;
1077 if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {
1078 error("Couldn't get link statistics: %m");
1079 return 0;
1081 stats->bytes_in = s.p.ppp_ibytes;
1082 stats->bytes_out = s.p.ppp_obytes;
1083 return 1;
1088 * ccp_fatal_error - returns 1 if decompression was disabled as a
1089 * result of an error detected after decompression of a packet,
1090 * 0 otherwise. This is necessary because of patent nonsense.
1093 ccp_fatal_error(unit)
1094 int unit;
1096 int cf[2];
1098 cf[0] = cf[1] = 0;
1099 if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
1100 if (errno != ENXIO && errno != EINVAL)
1101 error("Couldn't get compression flags: %m");
1102 return 0;
1104 return cf[0] & CCP_FATALERROR;
1108 * sifvjcomp - config tcp header compression
1111 sifvjcomp(u, vjcomp, xcidcomp, xmaxcid)
1112 int u, vjcomp, xcidcomp, xmaxcid;
1114 int cf[2];
1115 char maxcid[2];
1117 if (vjcomp) {
1118 maxcid[0] = xcidcomp;
1119 maxcid[1] = 15; /* XXX should be rmaxcid */
1120 if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) {
1121 error("Couldn't initialize VJ compression: %m");
1125 cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0) /* XXX this is wrong */
1126 + (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0);
1127 cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID;
1128 if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
1129 if (vjcomp)
1130 error("Couldn't enable VJ compression: %m");
1133 return 1;
1137 * sifup - Config the interface up and enable IP packets to pass.
1140 sifup(u)
1141 int u;
1143 struct ifreq ifr;
1145 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1146 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
1147 error("Couldn't mark interface up (get): %m");
1148 return 0;
1150 ifr.ifr_flags |= IFF_UP;
1151 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
1152 error("Couldn't mark interface up (set): %m");
1153 return 0;
1155 if_is_up = 1;
1156 return 1;
1160 * sifdown - Config the interface down and disable IP.
1163 sifdown(u)
1164 int u;
1166 struct ifreq ifr;
1168 bzero(&ifr, sizeof(ifr));
1169 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1170 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
1171 error("Couldn't mark interface down (get): %m");
1172 return 0;
1174 if ((ifr.ifr_flags & IFF_UP) != 0) {
1175 ifr.ifr_flags &= ~IFF_UP;
1176 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
1177 error("Couldn't mark interface down (set): %m");
1178 return 0;
1181 if_is_up = 0;
1182 return 1;
1186 * sifnpmode - Set the mode for handling packets for a given NP.
1189 sifnpmode(u, proto, mode)
1190 int u;
1191 int proto;
1192 enum NPmode mode;
1194 int npi[2];
1196 npi[0] = proto;
1197 npi[1] = (int) mode;
1198 if (strioctl(pppfd, PPPIO_NPMODE, npi, 2 * sizeof(int), 0) < 0) {
1199 error("ioctl(set NP %d mode to %d): %m", proto, mode);
1200 return 0;
1202 return 1;
1205 #define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr)
1208 * SET_SA_FAMILY - initialize a struct sockaddr, setting the sa_family field.
1210 #define SET_SA_FAMILY(addr, family) \
1211 BZERO((char *) &(addr), sizeof(addr)); \
1212 addr.sa_family = (family); \
1213 addr.sa_len = sizeof ((addr))
1216 * sifaddr - Config the interface IP addresses and netmask.
1219 sifaddr(u, o, h, m)
1220 int u;
1221 u_int32_t o, h, m;
1223 struct ifreq ifr;
1224 struct ifaliasreq addreq;
1225 int ret;
1227 ret = 1;
1229 /* flush old address, if any
1231 bzero(&ifr, sizeof (ifr));
1232 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1233 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
1234 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;
1235 if ((ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0)
1236 && errno != EADDRNOTAVAIL) {
1237 error("ioctl(SIOCDIFADDR): %m");
1238 ret = 0;
1241 bzero(&addreq, sizeof (addreq));
1242 strlcpy(addreq.ifra_name, ifname, sizeof (addreq.ifra_name));
1243 SET_SA_FAMILY(addreq.ifra_addr, AF_INET);
1244 SET_SA_FAMILY(addreq.ifra_broadaddr, AF_INET);
1245 ((struct sockaddr_in *)&addreq.ifra_addr)->sin_addr.s_addr = o;
1246 ((struct sockaddr_in *)&addreq.ifra_broadaddr)->sin_addr.s_addr = h;
1248 if (m != 0) {
1249 ((struct sockaddr_in *)&addreq.ifra_mask)->sin_addr.s_addr = m;
1250 addreq.ifra_mask.sa_len = sizeof (struct sockaddr);
1251 info("Setting interface mask to %s\n", ip_ntoa(m));
1254 /* install new src/dst and (possibly) netmask
1256 if (ioctl(sockfd, SIOCPIFADDR, &addreq) < 0) {
1257 error("ioctl(SIOCPIFADDR): %m");
1258 ret = 0;
1261 ifr.ifr_data = (caddr_t)&link_mtu;
1263 if (ioctl(sockfd, SIOCSIPMTU, &ifr) < 0) {
1264 error("Couldn't set IP MTU: %m");
1265 ret = 0;
1268 ifaddrs[0] = o;
1269 ifaddrs[1] = h;
1270 return (ret);
1275 * cifaddr - Clear the interface IP addresses, and delete routes
1276 * through the interface if possible.
1279 cifaddr(u, o, h)
1280 int u;
1281 u_int32_t o, h;
1283 struct ifreq ifr;
1285 ifaddrs[0] = 0;
1286 ifaddrs[1] = 0;
1287 bzero(&ifr, sizeof (ifr));
1288 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
1289 SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
1290 ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o;
1291 if (ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) {
1292 error("ioctl(SIOCDIFADDR): %m");
1293 return 0;
1295 return 1;
1300 * sifdefaultroute - assign a default route through the address given.
1303 sifdefaultroute(u, l, g)
1304 int u;
1305 u_int32_t l, g;
1307 struct ortentry rt;
1309 BZERO(&rt, sizeof(rt));
1310 SET_SA_FAMILY(rt.rt_dst, AF_INET);
1311 SET_SA_FAMILY(rt.rt_gateway, AF_INET);
1312 ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
1313 rt.rt_flags = RTF_GATEWAY;
1314 if (ioctl(sockfd, (int)SIOCADDRT, &rt) < 0) {
1315 error("default route ioctl(SIOCADDRT): %m");
1316 return 0;
1318 default_route_gateway = g;
1319 return 1;
1324 * cifdefaultroute - delete a default route through the address given.
1327 cifdefaultroute(u, l, g)
1328 int u;
1329 u_int32_t l, g;
1331 struct ortentry rt;
1333 BZERO(&rt, sizeof(rt));
1334 SET_SA_FAMILY(rt.rt_dst, AF_INET);
1335 SET_SA_FAMILY(rt.rt_gateway, AF_INET);
1336 ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g;
1337 rt.rt_flags = RTF_GATEWAY;
1338 if (ioctl(sockfd, (int)SIOCDELRT, &rt) < 0) {
1339 error("default route ioctl(SIOCDELRT): %m");
1340 return 0;
1342 default_route_gateway = 0;
1343 return 1;
1347 * sifproxyarp - Make a proxy ARP entry for the peer.
1350 sifproxyarp(unit, hisaddr)
1351 int unit;
1352 u_int32_t hisaddr;
1354 struct arpreq arpreq;
1356 BZERO(&arpreq, sizeof(arpreq));
1359 * Get the hardware address of an interface on the same subnet
1360 * as our local address.
1362 if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) {
1363 warn("Cannot determine ethernet address for proxy ARP");
1364 return 0;
1367 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1368 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
1369 arpreq.arp_flags = ATF_PERM | ATF_PUBL;
1370 if (ioctl(sockfd, (int)SIOCSARP, (caddr_t)&arpreq) < 0) {
1371 error("ioctl(SIOCSARP): %m");
1372 return 0;
1375 proxy_arp_addr = hisaddr;
1376 return 1;
1381 * cifproxyarp - Delete the proxy ARP entry for the peer.
1384 cifproxyarp(unit, hisaddr)
1385 int unit;
1386 u_int32_t hisaddr;
1388 struct arpreq arpreq;
1390 BZERO(&arpreq, sizeof(arpreq));
1391 SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
1392 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;
1393 if (ioctl(sockfd, (int)SIOCDARP, (caddr_t)&arpreq) < 0) {
1394 error("ioctl(SIOCDARP): %m");
1395 return 0;
1397 proxy_arp_addr = 0;
1398 return 1;
1402 * get_ether_addr - get the hardware address of an interface on the
1403 * the same subnet as ipaddr.
1405 #define MAX_IFS 32
1407 static int
1408 get_ether_addr(ipaddr, hwaddr)
1409 u_int32_t ipaddr;
1410 struct sockaddr *hwaddr;
1412 struct ifreq *ifr, *ifend;
1413 u_int32_t ina, mask;
1414 struct ifreq ifreq;
1415 struct ifconf ifc;
1416 struct ifreq ifs[MAX_IFS];
1417 struct ifdevea ifdevreq;
1419 ifc.ifc_len = sizeof(ifs);
1420 ifc.ifc_req = ifs;
1421 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
1422 error("ioctl(SIOCGIFCONF): %m");
1423 return 0;
1427 * Scan through looking for an interface with an Internet
1428 * address on the same subnet as `ipaddr'.
1430 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1431 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1432 if (ifr->ifr_addr.sa_family == AF_INET) {
1435 * Check that the interface is up, and not point-to-point
1436 * or loopback.
1438 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1439 if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
1440 continue;
1441 if ((ifreq.ifr_flags &
1442 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
1443 != (IFF_UP|IFF_BROADCAST))
1444 continue;
1447 * Get its netmask and check that it's on the right subnet.
1449 if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
1450 continue;
1451 ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
1452 mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
1453 if ((ipaddr & mask) != (ina & mask))
1454 continue;
1456 break;
1457 } else {
1458 if (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr))
1459 ifr = (struct ifreq *)((caddr_t)ifr + (ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr)));
1463 if (ifr >= ifend)
1464 return 0;
1465 info("found interface %s for proxy arp", ifr->ifr_name);
1467 strlcpy(ifdevreq.ifr_name, ifr->ifr_name, sizeof(ifdevreq.ifr_name));
1469 if (ioctl(sockfd, (int)SIOCRPHYSADDR, &ifdevreq) < 0) {
1470 perror("ioctl(SIOCRPHYSADDR)");
1471 return(0);
1474 hwaddr->sa_family = AF_UNSPEC;
1475 memcpy(hwaddr->sa_data, ifdevreq.current_pa, sizeof(ifdevreq.current_pa));
1476 return 1;
1479 #define WTMPFILE "/usr/adm/wtmp"
1481 void
1482 logwtmp(line, name, host)
1483 const char *line, *name, *host;
1485 int fd;
1486 struct stat buf;
1487 struct utmp ut;
1489 if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
1490 return;
1491 if (!fstat(fd, &buf)) {
1492 strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1493 strncpy(ut.ut_name, name, sizeof(ut.ut_name));
1494 strncpy(ut.ut_host, host, sizeof(ut.ut_host));
1495 (void)time(&ut.ut_time);
1496 if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp))
1497 (void)ftruncate(fd, buf.st_size);
1499 close(fd);
1503 * Return user specified netmask, modified by any mask we might determine
1504 * for address `addr' (in network byte order).
1505 * Here we scan through the system's list of interfaces, looking for
1506 * any non-point-to-point interfaces which might appear to be on the same
1507 * network as `addr'. If we find any, we OR in their netmask to the
1508 * user-specified netmask.
1510 u_int32_t
1511 GetMask(addr)
1512 u_int32_t addr;
1514 u_int32_t mask, nmask, ina;
1515 struct ifreq *ifr, *ifend, ifreq;
1516 struct ifconf ifc;
1518 addr = ntohl(addr);
1519 if (IN_CLASSA(addr)) /* determine network mask for address class */
1520 nmask = IN_CLASSA_NET;
1521 else if (IN_CLASSB(addr))
1522 nmask = IN_CLASSB_NET;
1523 else
1524 nmask = IN_CLASSC_NET;
1525 /* class D nets are disallowed by bad_ip_adrs */
1526 mask = netmask | htonl(nmask);
1529 * Scan through the system's network interfaces.
1531 ifc.ifc_len = MAX_IFS * sizeof(struct ifreq);
1532 ifc.ifc_req = (struct ifreq *)alloca(ifc.ifc_len);
1533 if (ifc.ifc_req == 0)
1534 return mask;
1535 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
1536 warn("Couldn't get system interface list: %m");
1537 return mask;
1539 ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
1540 for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
1542 * Check the interface's internet address.
1544 if (ifr->ifr_addr.sa_family == AF_INET) {
1545 ina = INET_ADDR(ifr->ifr_addr);
1546 if ((ntohl(ina) & nmask) != (addr & nmask))
1547 continue;
1549 * Check that the interface is up, and not point-to-point or loopback.
1551 strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
1552 if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
1553 continue;
1554 if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
1555 != IFF_UP)
1556 continue;
1558 * Get its netmask and OR it into our mask.
1560 if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
1561 continue;
1562 mask |= INET_ADDR(ifreq.ifr_addr);
1563 break;
1564 } else {
1565 if (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr))
1566 ifr = (struct ifreq *)((caddr_t)ifr + (ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr)));
1570 return mask;
1574 * have_route_to - determine if the system has any route to
1575 * a given IP address. `addr' is in network byte order.
1576 * For demand mode to work properly, we have to ignore routes
1577 * through our own interface.
1579 int have_route_to(u_int32_t addr)
1581 return -1;
1584 static int
1585 strioctl(fd, cmd, ptr, ilen, olen)
1586 int fd, cmd, ilen, olen;
1587 void *ptr;
1589 struct strioctl str;
1591 str.ic_cmd = cmd;
1592 str.ic_timout = 0;
1593 str.ic_len = ilen;
1594 str.ic_dp = ptr;
1595 if (ioctl(fd, I_STR, &str) == -1)
1596 return -1;
1597 if (str.ic_len != olen)
1598 dbglog("strioctl: expected %d bytes, got %d for cmd %x\n",
1599 olen, str.ic_len, cmd);
1600 return 0;
1604 * Use the hostid as part of the random number seed.
1607 get_host_seed()
1609 return gethostid();
1613 * get_pty - get a pty master/slave pair and chown the slave side
1614 * to the uid given. Assumes slave_name points to >= 12 bytes of space.
1617 get_pty(master_fdp, slave_fdp, slave_name, uid)
1618 int *master_fdp;
1619 int *slave_fdp;
1620 char *slave_name;
1621 int uid;
1623 int i, mfd, sfd;
1624 char pty_name[12];
1625 struct termios tios;
1627 sfd = -1;
1628 for (i = 0; i < 64; ++i) {
1629 slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
1630 'p' + i / 16, i % 16);
1631 mfd = open(pty_name, O_RDWR, 0);
1632 if (mfd >= 0) {
1633 pty_name[5] = 't';
1634 sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
1635 if (sfd >= 0)
1636 break;
1637 close(mfd);
1640 if (sfd < 0)
1641 return 0;
1643 strlcpy(slave_name, pty_name, 12);
1644 *master_fdp = mfd;
1645 *slave_fdp = sfd;
1646 fchown(sfd, uid, -1);
1647 fchmod(sfd, S_IRUSR | S_IWUSR);
1648 if (tcgetattr(sfd, &tios) == 0) {
1649 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
1650 tios.c_cflag |= CS8 | CREAD;
1651 tios.c_iflag = IGNPAR | CLOCAL;
1652 tios.c_oflag = 0;
1653 tios.c_lflag = 0;
1654 if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
1655 warn("couldn't set attributes on pty: %m");
1656 } else
1657 warn("couldn't get attributes on pty: %m");
1659 return 1;
1662 #if 0
1664 * Code for locking/unlocking the serial device.
1665 * This code is derived from chat.c.
1668 #if !defined(HDB) && !defined(SUNOS3)
1669 #define HDB 1 /* ascii lock files are the default */
1670 #endif
1672 #ifndef LOCK_DIR
1673 # if HDB
1674 # define PIDSTRING
1675 # define LOCK_PREFIX "/usr/spool/locks/LCK.."
1676 # else /* HDB */
1677 # define LOCK_PREFIX "/usr/spool/uucp/LCK.."
1678 # endif /* HDB */
1679 #endif /* LOCK_DIR */
1681 static char *lock_file; /* name of lock file created */
1684 * lock - create a lock file for the named device.
1687 lock(dev)
1688 char *dev;
1690 char hdb_lock_buffer[12];
1691 int fd, pid, n;
1692 char *p;
1693 size_t l;
1695 if ((p = strrchr(dev, '/')) != NULL)
1696 dev = p + 1;
1697 l = strlen(LOCK_PREFIX) + strlen(dev) + 1;
1698 lock_file = malloc(l);
1699 if (lock_file == NULL)
1700 novm("lock file name");
1701 slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev);
1703 while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
1704 if (errno == EEXIST
1705 && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
1706 /* Read the lock file to find out who has the device locked */
1707 #ifdef PIDSTRING
1708 n = read(fd, hdb_lock_buffer, 11);
1709 if (n > 0) {
1710 hdb_lock_buffer[n] = 0;
1711 pid = atoi(hdb_lock_buffer);
1713 #else
1714 n = read(fd, &pid, sizeof(pid));
1715 #endif
1716 if (n <= 0) {
1717 error("Can't read pid from lock file %s", lock_file);
1718 close(fd);
1719 } else {
1720 if (kill(pid, 0) == -1 && errno == ESRCH) {
1721 /* pid no longer exists - remove the lock file */
1722 if (unlink(lock_file) == 0) {
1723 close(fd);
1724 notice("Removed stale lock on %s (pid %d)",
1725 dev, pid);
1726 continue;
1727 } else
1728 warn("Couldn't remove stale lock on %s",
1729 dev);
1730 } else
1731 notice("Device %s is locked by pid %d",
1732 dev, pid);
1734 close(fd);
1735 } else
1736 error("Can't create lock file %s: %m", lock_file);
1737 free(lock_file);
1738 lock_file = NULL;
1739 return -1;
1742 #ifdef PIDSTRING
1743 slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid());
1744 write(fd, hdb_lock_buffer, 11);
1745 #else
1746 pid = getpid();
1747 write(fd, &pid, sizeof pid);
1748 #endif
1750 close(fd);
1751 return 0;
1755 * unlock - remove our lockfile
1757 void
1758 unlock()
1760 if (lock_file) {
1761 unlink(lock_file);
1762 free(lock_file);
1763 lock_file = NULL;
1766 #endif
1769 set_filters(pass, active)
1770 struct bpf_program *pass, *active;
1772 return 1;
1776 bpf_compile(program, buf, optimize)
1777 struct bpf_program *program;
1778 char *buf;
1779 int optimize;
1781 return 0;
1784 char *
1785 bpf_geterr()
1787 return 0;
1790 u_int
1791 bpf_filter(pc, p, wirelen, buflen)
1792 struct bpf_insn *pc;
1793 u_char *p;
1794 u_int wirelen;
1795 u_int buflen;
1797 return 0;