293 lines
8.1 KiB
Text
293 lines
8.1 KiB
Text
$NetBSD: patch-aj,v 1.1.1.1 1999/10/08 04:34:43 dbj Exp $
|
|
|
|
--- pppd/sys-bsd.c.orig Fri Aug 13 02:46:18 1999
|
|
+++ pppd/sys-bsd.c Sat Sep 18 02:28:45 1999
|
|
@@ -25,4 +25,3 @@
|
|
-#endif
|
|
|
|
/*
|
|
* TODO:
|
|
@@ -42,7 +41,7 @@
|
|
#include <sys/time.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/param.h>
|
|
-#ifdef NetBSD1_2
|
|
+#if defined(NetBSD1_2) || defined(__NetBSD_Version__)
|
|
#include <util.h>
|
|
#endif
|
|
#ifdef PPP_FILTER
|
|
@@ -55,6 +54,10 @@
|
|
#include <net/route.h>
|
|
#include <net/if_dl.h>
|
|
#include <netinet/in.h>
|
|
+#ifdef __KAME__
|
|
+#include <netinet6/in6_var.h>
|
|
+#include <netinet6/nd6.h>
|
|
+#endif
|
|
|
|
#if RTM_VERSION >= 3
|
|
#include <sys/param.h>
|
|
@@ -91,6 +94,9 @@
|
|
static unsigned char inbuf[512]; /* buffer for chars read from loopback */
|
|
|
|
static int sockfd; /* socket for doing interface ioctls */
|
|
+#ifdef INET6
|
|
+static int sock6_fd = -1; /* socket for doing ipv6 interface ioctls */
|
|
+#endif /* INET6 */
|
|
|
|
static fd_set in_fds; /* set of fds that wait_input waits for */
|
|
static int max_in_fd; /* highest fd set in in_fds */
|
|
@@ -115,6 +121,11 @@
|
|
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
|
fatal("Couldn't create IP socket: %m");
|
|
|
|
+#ifdef INET6
|
|
+ if ((sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
|
|
+ fatal("Couldn't create IPv6 socket: %m");
|
|
+#endif
|
|
+
|
|
FD_ZERO(&in_fds);
|
|
max_in_fd = 0;
|
|
}
|
|
@@ -191,10 +202,16 @@
|
|
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
|
|
close(s);
|
|
|
|
+#ifdef __NetBSD__
|
|
+ no_ppp_msg = "\
|
|
+This system lacks kernel support for PPP. To include PPP support\n\
|
|
+in the kernel, please read the ppp(4) manual page.\n";
|
|
+#else
|
|
no_ppp_msg = "\
|
|
This system lacks kernel support for PPP. To include PPP support\n\
|
|
in the kernel, please follow the steps detailed in the README.bsd\n\
|
|
file in the ppp-2.2 distribution.\n";
|
|
+#endif
|
|
return ok;
|
|
}
|
|
|
|
@@ -459,6 +476,176 @@
|
|
ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
|
|
}
|
|
|
|
+#ifdef INET6
|
|
+/*
|
|
+ * sif6addr - Config the interface with an IPv6 link-local address
|
|
+ */
|
|
+int
|
|
+sif6addr(unit, our_eui64, his_eui64)
|
|
+ int unit;
|
|
+ eui64_t our_eui64, his_eui64;
|
|
+{
|
|
+#ifdef __KAME__
|
|
+ int ifindex;
|
|
+ struct in6_aliasreq addreq6;
|
|
+
|
|
+ /* actually, this part is not kame local - RFC2553 conformant */
|
|
+ ifindex = if_nametoindex(ifname);
|
|
+ if (ifindex == 0) {
|
|
+ error("sifaddr6: no interface %s", ifname);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ memset(&addreq6, 0, sizeof(addreq6));
|
|
+ strlcpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name));
|
|
+
|
|
+ /* my addr */
|
|
+ addreq6.ifra_addr.sin6_family = AF_INET6;
|
|
+ addreq6.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
|
|
+ addreq6.ifra_addr.sin6_addr.s6_addr[0] = 0xfe;
|
|
+ addreq6.ifra_addr.sin6_addr.s6_addr[1] = 0x80;
|
|
+ memcpy(&addreq6.ifra_addr.sin6_addr.s6_addr[8], &our_eui64,
|
|
+ sizeof(our_eui64));
|
|
+ /* KAME ifindex hack */
|
|
+ *(u_int16_t *)&addreq6.ifra_addr.sin6_addr.s6_addr[2] = htons(ifindex);
|
|
+
|
|
+ /* his addr */
|
|
+ addreq6.ifra_dstaddr.sin6_family = AF_INET6;
|
|
+ addreq6.ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
|
|
+ addreq6.ifra_dstaddr.sin6_addr.s6_addr[0] = 0xfe;
|
|
+ addreq6.ifra_dstaddr.sin6_addr.s6_addr[1] = 0x80;
|
|
+ memcpy(&addreq6.ifra_dstaddr.sin6_addr.s6_addr[8], &his_eui64,
|
|
+ sizeof(our_eui64));
|
|
+ /* KAME ifindex hack */
|
|
+ *(u_int16_t *)&addreq6.ifra_dstaddr.sin6_addr.s6_addr[2] = htons(ifindex);
|
|
+
|
|
+ /* prefix mask: 128bit (correct?) */
|
|
+ addreq6.ifra_prefixmask.sin6_family = AF_INET6;
|
|
+ addreq6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
|
|
+ memset(&addreq6.ifra_prefixmask.sin6_addr, 0xff,
|
|
+ sizeof(addreq6.ifra_prefixmask.sin6_addr));
|
|
+
|
|
+ /* address lifetime (infty) */
|
|
+ addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
|
|
+ addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
|
|
+
|
|
+ if (ioctl(sock6_fd, SIOCAIFADDR_IN6, &addreq6) < 0) {
|
|
+ error("sif6addr: ioctl(SIOCAIFADDR_IN6): %m");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+#else
|
|
+ struct in6_ifreq ifr6;
|
|
+ struct ifreq ifr;
|
|
+ struct in6_rtmsg rt6;
|
|
+
|
|
+ memset(&ifr, 0, sizeof (ifr));
|
|
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
|
+ if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
|
|
+ error("sif6addr: ioctl(SIOCGIFINDEX): %m");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* Local interface */
|
|
+ memset(&ifr6, 0, sizeof(ifr6));
|
|
+ IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
|
|
+ ifr6.ifr6_ifindex = ifindex;
|
|
+ ifr6.ifr6_prefixlen = 10;
|
|
+
|
|
+ if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
|
|
+ error("sif6addr: ioctl(SIOCSIFADDR): %m");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* Route to remote host */
|
|
+ memset(&rt6, 0, sizeof(rt6));
|
|
+ IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
|
|
+ rt6.rtmsg_flags = RTF_UP | RTF_HOST;
|
|
+ rt6.rtmsg_dst_len = 128;
|
|
+ rt6.rtmsg_ifindex = ifr.ifr_ifindex;
|
|
+ rt6.rtmsg_metric = 1;
|
|
+
|
|
+ if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
|
|
+ error("sif6addr: ioctl(SIOCADDRT): %m");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * cif6addr - Remove IPv6 address from interface
|
|
+ */
|
|
+int
|
|
+cif6addr(unit, our_eui64, his_eui64)
|
|
+ int unit;
|
|
+ eui64_t our_eui64, his_eui64;
|
|
+{
|
|
+#ifdef __KAME__
|
|
+ int ifindex;
|
|
+ struct in6_ifreq delreq6;
|
|
+
|
|
+ /* actually, this part is not kame local - RFC2553 conformant */
|
|
+ ifindex = if_nametoindex(ifname);
|
|
+ if (ifindex == 0) {
|
|
+ error("cifaddr6: no interface %s", ifname);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ memset(&delreq6, 0, sizeof(delreq6));
|
|
+ strlcpy(delreq6.ifr_name, ifname, sizeof(delreq6.ifr_name));
|
|
+
|
|
+ /* my addr */
|
|
+ delreq6.ifr_ifru.ifru_addr.sin6_family = AF_INET6;
|
|
+ delreq6.ifr_ifru.ifru_addr.sin6_len = sizeof(struct sockaddr_in6);
|
|
+ delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[0] = 0xfe;
|
|
+ delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[1] = 0x80;
|
|
+ memcpy(&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[8], &our_eui64,
|
|
+ sizeof(our_eui64));
|
|
+ /* KAME ifindex hack */
|
|
+ *(u_int16_t *)&delreq6.ifr_ifru.ifru_addr.sin6_addr.s6_addr[2] =
|
|
+ htons(ifindex);
|
|
+
|
|
+ if (ioctl(sock6_fd, SIOCDIFADDR_IN6, &delreq6) < 0) {
|
|
+ error("cif6addr: ioctl(SIOCDIFADDR_IN6): %m");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+#else
|
|
+ struct ifreq ifr;
|
|
+ struct in6_ifreq ifr6;
|
|
+
|
|
+ memset(&ifr, 0, sizeof(ifr));
|
|
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
|
|
+ if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
|
|
+ error("cif6addr: ioctl(SIOCGIFINDEX): %m");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ memset(&ifr6, 0, sizeof(ifr6));
|
|
+ IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
|
|
+ ifr6.ifr6_ifindex = ifr.ifr_ifindex;
|
|
+ ifr6.ifr6_prefixlen = 10;
|
|
+
|
|
+ if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
|
|
+ if (errno != EADDRNOTAVAIL) {
|
|
+ if (! ok_error (errno))
|
|
+ error("cif6addr: ioctl(SIOCDIFADDR): %m");
|
|
+ }
|
|
+ else {
|
|
+ warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
|
|
+ }
|
|
+ return (0);
|
|
+ }
|
|
+ return 1;
|
|
+#endif
|
|
+}
|
|
+#endif /* INET6 */
|
|
+
|
|
/*
|
|
* get_pty - get a pty master/slave pair and chown the slave side
|
|
* to the uid given. Assumes slave_name points to >= 12 bytes of space.
|
|
@@ -851,23 +1038,39 @@
|
|
* set_filters - transfer the pass and active filters to the kernel.
|
|
*/
|
|
int
|
|
-set_filters(pass, active)
|
|
- struct bpf_program *pass, *active;
|
|
+set_filters(pass_in, pass_out, active_in, active_out)
|
|
+ struct bpf_program *pass_in, *pass_out, *active_in, *active_out;
|
|
{
|
|
int ret = 1;
|
|
|
|
- if (pass->bf_len > 0) {
|
|
- if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) {
|
|
- error("Couldn't set pass-filter in kernel: %m");
|
|
+ if (pass_in->bf_len > 0) {
|
|
+ if (ioctl(ppp_fd, PPPIOCSIPASS, pass_in) < 0) {
|
|
+ error("Couldn't set pass-filter-in in kernel: %m");
|
|
+ ret = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (pass_out->bf_len > 0) {
|
|
+ if (ioctl(ppp_fd, PPPIOCSOPASS, pass_out) < 0) {
|
|
+ error("Couldn't set pass-filter-out in kernel: %m");
|
|
ret = 0;
|
|
}
|
|
}
|
|
- if (active->bf_len > 0) {
|
|
- if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) {
|
|
- error("Couldn't set active-filter in kernel: %m");
|
|
+
|
|
+ if (active_in->bf_len > 0) {
|
|
+ if (ioctl(ppp_fd, PPPIOCSIACTIVE, active_in) < 0) {
|
|
+ error("Couldn't set active-filter-in in kernel: %m");
|
|
ret = 0;
|
|
}
|
|
}
|
|
+
|
|
+ if (active_out->bf_len > 0) {
|
|
+ if (ioctl(ppp_fd, PPPIOCSOACTIVE, active_out) < 0) {
|
|
+ error("Couldn't set active-filter-out in kernel: %m");
|
|
+ ret = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
#endif
|