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
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
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
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
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
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
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 $"
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>
94 #include <sys/ioctl.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>
106 static const char rcsid
[] = RCSID
;
109 static int fdmuxid
= -1;
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
;
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.
154 openlog("pppd", LOG_PID
| LOG_NDELAY
, LOG_PPP
);
155 setlogmask(LOG_UPTO(LOG_INFO
));
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");
164 tty_sid
= getsid((pid_t
)0);
167 * Open the ppp device.
169 pppfd
= open("/dev/streams/ppp", O_RDWR
| O_NONBLOCK
, 0);
171 fatal("Can't open /dev/streams/ppp: %m");
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);
186 fatal("Can't open /dev/streams/ppp (2): %m");
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");
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");
202 if (strioctl(iffd
, PPPIO_BIND
, &x
, sizeof(int), 0) < 0)
203 fatal("Couldn't bind ppp interface to IP SAP: %m");
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().
219 cifaddr(0, ifaddrs
[0], ifaddrs
[1]);
220 if (default_route_gateway
)
221 cifdefaultroute(0, 0, default_route_gateway
);
223 cifproxyarp(0, proxy_arp_addr
);
227 * sys_close - Clean up in a child process before execing.
239 * sys_check_options - check the options that the user specified
249 * daemon - Detach us from controlling terminal session.
252 daemon(nochdir
, noclose
)
253 int nochdir
, noclose
;
257 if ((pid
= fork()) < 0)
260 exit(0); /* parent dies */
265 fclose(stdin
); /* don't need stdin, stdout, stderr */
274 * ppp_available - check whether the system has any ppp interfaces
281 return stat("/dev/streams/ppp", &buf
) >= 0;
284 char pipename
[] = "/dev/streams/pipe";
287 * streampipe -- Opens a STREAMS based pipe. Used by streamify().
291 streampipe(int fd
[2])
293 if ((fd
[0]=open(pipename
, O_RDWR
)) == -1)
295 else if ((fd
[1]=open(pipename
, O_RDWR
)) == -1) {
298 } else if (ioctl(fd
[0], I_PIPE
, fd
[1]) != 0) {
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() */
319 int ret
, fret
, rret
, maxfd
;
320 static char buffer
[BUFFSIZE
];
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
;
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
);
341 maxfd
= (fdes
[1]>fd
)?fdes
[1]:fd
;
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
);
350 SYSDEBUG(("slave died: EOF on tty."));
353 write(fdes
[1], buffer
, rret
);
356 if (FD_ISSET(fdes
[1], &readfds
)) {
357 rret
= read(fdes
[1], buffer
, BUFFSIZE
);
359 SYSDEBUG(("slave died: EOF on pipe."));
362 write(fd
, buffer
, rret
);
377 * establish_ppp - Turn the serial port into a ppp interface.
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. */
392 if (ioctl(fd
, I_LOOK
, tty_modules
[i
]) < 0
393 || ioctl(fd
, I_POP
, 0) < 0)
395 error("popping module %s\n", tty_modules
[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
) {
418 for (i
= 0; i
<= 2; ++i
)
419 if (i
!= fd
&& i
!= sockfd
)
422 /* make sure 0, 1, 2 are open to /dev/null */
423 while ((i
= open("/dev/null", O_RDWR
)) >= 0) {
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");
444 * restore_loop - reattach the ppp unit to the loopback.
445 * This doesn't need to do anything because disestablish_ppp does it.
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().
464 if (ioctl(pppfd
, I_UNLINK
, fdmuxid
) < 0) {
466 error("Can't unlink tty from PPP mux: %m");
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");
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",
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) {
498 (void)wait((void *)0);
506 * Check whether the link seems not to be 8-bit clean.
514 if (strioctl(pppfd
, PPPIO_GCLEAN
, &x
, 0, sizeof(x
)) < 0)
519 s
= "bit 7 set to 1";
522 s
= "bit 7 set to 0";
532 warn("Serial link is not 8-bit clean:");
533 warn("All received characters had %s", s
);
538 * List of valid speeds.
541 int speed_int
, speed_val
;
613 * Translate from bits/second to a speed_t.
619 struct speed
*speedp
;
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
);
631 * Translate from a speed_t to bits/second.
637 struct speed
*speedp
;
641 for (speedp
= speeds
; speedp
->speed_int
; speedp
++)
642 if (speed
== speedp
->speed_val
)
643 return speedp
->speed_int
;
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.
653 set_up_tty(fd
, local
)
659 if (tcgetattr(fd
, &tios
) < 0)
660 fatal("tcgetattr: %m");
664 ioctl(fd
, TIOCGWINSZ
, &wsinfo
);
667 tios
.c_cflag
&= ~(CSIZE
| CSTOPB
| PARENB
| CLOCAL
);
669 tios
.c_cflag
|= CRTSCTS
;
670 else if (crtscts
< 0)
671 tios
.c_cflag
&= ~CRTSCTS
;
673 tios
.c_cflag
|= CS8
| CREAD
| HUPCL
;
675 tios
.c_cflag
|= CLOCAL
;
676 tios
.c_iflag
= IGNBRK
| IGNPAR
;
680 tios
.c_cc
[VTIME
] = 0;
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
);
690 cfsetospeed(&tios
, speed
);
691 cfsetispeed(&tios
, speed
);
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.
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
);
710 * restore_tty - restore the terminal to the saved settings.
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
);
735 * setdtr - control the DTR line on the serial port.
736 * This is called from die(), so it shouldn't call die().
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
759 * output - Output PPP packet.
772 dbglog("sent %P", p
, len
);
775 data
.buf
= (caddr_t
) p
;
777 while (putmsg(pppfd
, NULL
, &data
, 0) < 0) {
778 if (--retries
< 0 || (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
)) {
780 error("Couldn't send packet: %m");
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
797 struct timeval
*timo
;
801 t
= timo
== NULL
? -1: timo
->tv_sec
* 1000 + timo
->tv_usec
/ 1000;
802 if (poll(pollfds
, n_pollfds
, t
) < 0 && errno
!= EINTR
)
807 * add_fd - add an fd to the set that wait_input waits for.
814 for (n
= 0; n
< n_pollfds
; ++n
)
815 if (pollfds
[n
].fd
== fd
)
817 if (n_pollfds
< MAX_POLLFDS
) {
818 pollfds
[n_pollfds
].fd
= fd
;
819 pollfds
[n_pollfds
].events
= POLLIN
| POLLPRI
| POLLHUP
;
822 error("Too many inputs!");
826 * remove_fd - remove an fd from the set that wait_input waits for.
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
];
845 * wait_loop_output - wait until there is data available on the
846 * loopback, for the length of time specified by *timo (indefinite
850 wait_loop_output(timo
)
851 struct timeval
*timo
;
859 * wait_time - wait for a given length of time or until a
860 * signal is received. Called by ccp_test
864 struct timeval
*timo
;
868 n
= select(0, NULL
, NULL
, NULL
, timo
);
869 if (n
< 0 && errno
!= EINTR
)
874 * read_packet - get a PPP packet from the serial device.
880 struct strbuf ctrl
, data
;
882 unsigned char ctrlbuf
[64];
885 data
.maxlen
= PPP_MRU
+ PPP_HDRLEN
;
886 data
.buf
= (caddr_t
) buf
;
887 ctrl
.maxlen
= sizeof(ctrlbuf
);
888 ctrl
.buf
= (caddr_t
) ctrlbuf
;
890 len
= getmsg(pppfd
, &ctrl
, &data
, &flags
);
892 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EINTR
)
894 fatal("Error reading packet: %m");
901 * Got a M_PROTO or M_PCPROTO message. Huh?
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.
920 while ((len
= read_packet(inpacket_buf
)) > 0) {
921 if (loop_frame(inpacket_buf
, len
))
928 * ppp_send_config - configure the transmit characteristics of
932 ppp_send_config(unit
, mtu
, asyncmap
, pcomp
, accomp
)
940 if (strioctl(pppfd
, PPPIO_MTU
, &mtu
, sizeof(mtu
), 0) < 0) {
941 if (hungup
&& errno
== ENXIO
)
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.
959 ppp_set_xaccm(unit
, 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
974 ppp_recv_config(unit
, mru
, asyncmap
, pcomp
, accomp
)
982 if (strioctl(pppfd
, PPPIO_MRU
, &mru
, sizeof(mru
), 0) < 0) {
983 if (hungup
&& errno
== ENXIO
)
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
;
1020 struct timeval tval
;
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) {
1030 if (errno
!= EAGAIN
)
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.
1043 ccp_flags_set(unit
, isopen
, isup
)
1044 int unit
, isopen
, isup
;
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
)
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
)
1073 struct pppd_stats
*stats
;
1077 if (strioctl(pppfd
, PPPIO_GETSTAT
, &s
, 0, sizeof(s
)) < 0) {
1078 error("Couldn't get link statistics: %m");
1081 stats
->bytes_in
= s
.p
.ppp_ibytes
;
1082 stats
->bytes_out
= s
.p
.ppp_obytes
;
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
)
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");
1104 return cf
[0] & CCP_FATALERROR
;
1108 * sifvjcomp - config tcp header compression
1111 sifvjcomp(u
, vjcomp
, xcidcomp
, xmaxcid
)
1112 int u
, vjcomp
, xcidcomp
, xmaxcid
;
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) {
1130 error("Couldn't enable VJ compression: %m");
1137 * sifup - Config the interface up and enable IP packets to pass.
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");
1150 ifr
.ifr_flags
|= IFF_UP
;
1151 if (ioctl(sockfd
, SIOCSIFFLAGS
, &ifr
) < 0) {
1152 error("Couldn't mark interface up (set): %m");
1160 * sifdown - Config the interface down and disable IP.
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");
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");
1186 * sifnpmode - Set the mode for handling packets for a given NP.
1189 sifnpmode(u
, proto
, mode
)
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
);
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.
1224 struct ifaliasreq addreq
;
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");
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
;
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");
1261 ifr
.ifr_data
= (caddr_t
)&link_mtu
;
1263 if (ioctl(sockfd
, SIOCSIPMTU
, &ifr
) < 0) {
1264 error("Couldn't set IP MTU: %m");
1275 * cifaddr - Clear the interface IP addresses, and delete routes
1276 * through the interface if possible.
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");
1300 * sifdefaultroute - assign a default route through the address given.
1303 sifdefaultroute(u
, l
, g
)
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");
1318 default_route_gateway
= g
;
1324 * cifdefaultroute - delete a default route through the address given.
1327 cifdefaultroute(u
, l
, g
)
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");
1342 default_route_gateway
= 0;
1347 * sifproxyarp - Make a proxy ARP entry for the peer.
1350 sifproxyarp(unit
, 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");
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");
1375 proxy_arp_addr
= hisaddr
;
1381 * cifproxyarp - Delete the proxy ARP entry for the peer.
1384 cifproxyarp(unit
, 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");
1402 * get_ether_addr - get the hardware address of an interface on the
1403 * the same subnet as ipaddr.
1408 get_ether_addr(ipaddr
, hwaddr
)
1410 struct sockaddr
*hwaddr
;
1412 struct ifreq
*ifr
, *ifend
;
1413 u_int32_t ina
, mask
;
1416 struct ifreq ifs
[MAX_IFS
];
1417 struct ifdevea ifdevreq
;
1419 ifc
.ifc_len
= sizeof(ifs
);
1421 if (ioctl(sockfd
, SIOCGIFCONF
, &ifc
) < 0) {
1422 error("ioctl(SIOCGIFCONF): %m");
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
1438 strlcpy(ifreq
.ifr_name
, ifr
->ifr_name
, sizeof(ifreq
.ifr_name
));
1439 if (ioctl(sockfd
, SIOCGIFFLAGS
, &ifreq
) < 0)
1441 if ((ifreq
.ifr_flags
&
1442 (IFF_UP
|IFF_BROADCAST
|IFF_POINTOPOINT
|IFF_LOOPBACK
|IFF_NOARP
))
1443 != (IFF_UP
|IFF_BROADCAST
))
1447 * Get its netmask and check that it's on the right subnet.
1449 if (ioctl(sockfd
, SIOCGIFNETMASK
, &ifreq
) < 0)
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
))
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
)));
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)");
1474 hwaddr
->sa_family
= AF_UNSPEC
;
1475 memcpy(hwaddr
->sa_data
, ifdevreq
.current_pa
, sizeof(ifdevreq
.current_pa
));
1479 #define WTMPFILE "/usr/adm/wtmp"
1482 logwtmp(line
, name
, host
)
1483 const char *line
, *name
, *host
;
1489 if ((fd
= open(WTMPFILE
, O_WRONLY
|O_APPEND
, 0)) < 0)
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
);
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.
1514 u_int32_t mask
, nmask
, ina
;
1515 struct ifreq
*ifr
, *ifend
, ifreq
;
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
;
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)
1535 if (ioctl(sockfd
, SIOCGIFCONF
, &ifc
) < 0) {
1536 warn("Couldn't get system interface list: %m");
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
))
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)
1554 if ((ifreq
.ifr_flags
& (IFF_UP
|IFF_POINTOPOINT
|IFF_LOOPBACK
))
1558 * Get its netmask and OR it into our mask.
1560 if (ioctl(sockfd
, SIOCGIFNETMASK
, &ifreq
) < 0)
1562 mask
|= INET_ADDR(ifreq
.ifr_addr
);
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
)));
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
)
1585 strioctl(fd
, cmd
, ptr
, ilen
, olen
)
1586 int fd
, cmd
, ilen
, olen
;
1589 struct strioctl str
;
1595 if (ioctl(fd
, I_STR
, &str
) == -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
);
1604 * Use the hostid as part of the random number seed.
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
)
1625 struct termios tios
;
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);
1634 sfd
= open(pty_name
, O_RDWR
| O_NOCTTY
, 0);
1643 strlcpy(slave_name
, pty_name
, 12);
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
;
1654 if (tcsetattr(sfd
, TCSAFLUSH
, &tios
) < 0)
1655 warn("couldn't set attributes on pty: %m");
1657 warn("couldn't get attributes on pty: %m");
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 */
1675 # define LOCK_PREFIX "/usr/spool/locks/LCK.."
1677 # define LOCK_PREFIX "/usr/spool/uucp/LCK.."
1679 #endif /* LOCK_DIR */
1681 static char *lock_file
; /* name of lock file created */
1684 * lock - create a lock file for the named device.
1690 char hdb_lock_buffer
[12];
1695 if ((p
= strrchr(dev
, '/')) != NULL
)
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) {
1705 && (fd
= open(lock_file
, O_RDONLY
, 0)) >= 0) {
1706 /* Read the lock file to find out who has the device locked */
1708 n
= read(fd
, hdb_lock_buffer
, 11);
1710 hdb_lock_buffer
[n
] = 0;
1711 pid
= atoi(hdb_lock_buffer
);
1714 n
= read(fd
, &pid
, sizeof(pid
));
1717 error("Can't read pid from lock file %s", lock_file
);
1720 if (kill(pid
, 0) == -1 && errno
== ESRCH
) {
1721 /* pid no longer exists - remove the lock file */
1722 if (unlink(lock_file
) == 0) {
1724 notice("Removed stale lock on %s (pid %d)",
1728 warn("Couldn't remove stale lock on %s",
1731 notice("Device %s is locked by pid %d",
1736 error("Can't create lock file %s: %m", lock_file
);
1743 slprintf(hdb_lock_buffer
, sizeof(hdb_lock_buffer
), "%10d\n", getpid());
1744 write(fd
, hdb_lock_buffer
, 11);
1747 write(fd
, &pid
, sizeof pid
);
1755 * unlock - remove our lockfile
1769 set_filters(pass
, active
)
1770 struct bpf_program
*pass
, *active
;
1776 bpf_compile(program
, buf
, optimize
)
1777 struct bpf_program
*program
;
1791 bpf_filter(pc
, p
, wirelen
, buflen
)
1792 struct bpf_insn
*pc
;