summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authoritojun <itojun@openbsd.org>2000-02-28 16:40:39 +0000
committeritojun <itojun@openbsd.org>2000-02-28 16:40:39 +0000
commit763eaa77a0e4ce7af56e41876ff947d8146b705b (patch)
tree3ae16bf1bb7c8e31b438bb8c21f46573f978278d /sys/netinet6
parentSanitize v{,un}mapbuf. (use the sizes we are passed, not the size from b_count); art (diff)
downloadwireguard-openbsd-763eaa77a0e4ce7af56e41876ff947d8146b705b.tar.xz
wireguard-openbsd-763eaa77a0e4ce7af56e41876ff947d8146b705b.zip
- check raw socket icmp6 filter only if the packet is icmp6.
- allow setting raw socket icmp6 filter only if it is IPPROTO_ICMPV6 socket. (cmetz may object about above two items...) - add rip6_ctlinput, to flush cached router properly on redirects.
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6_proto.c4
-rw-r--r--sys/netinet6/ip6_var.h3
-rw-r--r--sys/netinet6/raw_ipv6.c74
3 files changed, 75 insertions, 6 deletions
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 85128e8563e..e519519c260 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_proto.c,v 1.18 2000/02/28 11:55:22 itojun Exp $ */
+/* $OpenBSD: in6_proto.c,v 1.19 2000/02/28 16:40:39 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -149,7 +149,7 @@ struct ip6protosw inet6sw[] = {
},
#endif /*TCP6*/
{ SOCK_RAW, &inet6domain, IPPROTO_RAW, PR_ATOMIC | PR_ADDR,
- rip6_input, rip6_output, 0, rip6_ctloutput,
+ rip6_input, rip6_output, rip6_ctlinput, rip6_ctloutput,
rip6_usrreq,
0, 0, 0, 0,
},
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index b9293940211..1a77cd643b4 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_var.h,v 1.5 2000/02/28 11:55:22 itojun Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.6 2000/02/28 16:40:39 itojun Exp $ */
/* $KAME: ip6_var.h,v 1.27 2000/02/22 14:04:22 itojun Exp $ */
/*
@@ -279,6 +279,7 @@ void frag6_drain __P((void));
void rip6_init __P((void));
int rip6_input __P((struct mbuf **mp, int *offp, int proto));
+void rip6_ctlinput __P((int, struct sockaddr *, void *));
int rip6_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
int rip6_output __P((struct mbuf *, ...));
int rip6_usrreq __P((struct socket *,
diff --git a/sys/netinet6/raw_ipv6.c b/sys/netinet6/raw_ipv6.c
index 2ab3fbd543d..593ebcb517d 100644
--- a/sys/netinet6/raw_ipv6.c
+++ b/sys/netinet6/raw_ipv6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ipv6.c,v 1.14 2000/02/28 11:55:23 itojun Exp $ */
+/* $OpenBSD: raw_ipv6.c,v 1.15 2000/02/28 16:40:39 itojun Exp $ */
/*
%%% copyright-nrl-95
@@ -44,7 +44,7 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.7 (Berkeley) 5/15/95
- * $Id: raw_ipv6.c,v 1.14 2000/02/28 11:55:23 itojun Exp $
+ * $Id: raw_ipv6.c,v 1.15 2000/02/28 16:40:39 itojun Exp $
*/
#include <sys/param.h>
@@ -71,6 +71,7 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet/icmp6.h>
+#include <netinet6/ip6protosw.h>
#undef IPSEC
@@ -282,7 +283,7 @@ rip6_input(mp, offp, proto)
if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6) &&
!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, &ip6->ip6_src))
continue;
- if (inp->inp_icmp6filt &&
+ if (icmp6type >= 0 && inp->inp_icmp6filt &&
ICMP6_FILTER_WILLBLOCK(icmp6type, inp->inp_icmp6filt))
continue;
@@ -336,6 +337,67 @@ ret:
return IPPROTO_DONE;
}
+void
+rip6_ctlinput(cmd, sa, d)
+ int cmd;
+ struct sockaddr *sa;
+ void *d;
+{
+ struct sockaddr_in6 sa6;
+ register struct ip6_hdr *ip6;
+ struct mbuf *m;
+ int off;
+ void (*notify) __P((struct inpcb *, int)) = in_rtchange;
+
+ if (sa->sa_family != AF_INET6 ||
+ sa->sa_len != sizeof(struct sockaddr_in6))
+ return;
+
+ if ((unsigned)cmd >= PRC_NCMDS)
+ return;
+ if (PRC_IS_REDIRECT(cmd))
+ notify = in_rtchange, d = NULL;
+ else if (cmd == PRC_HOSTDEAD)
+ d = NULL;
+ else if (inet6ctlerrmap[cmd] == 0)
+ return;
+
+ /* if the parameter is from icmp6, decode it. */
+ if (d != NULL) {
+ struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
+ m = ip6cp->ip6c_m;
+ ip6 = ip6cp->ip6c_ip6;
+ off = ip6cp->ip6c_off;
+ } else {
+ m = NULL;
+ ip6 = NULL;
+ }
+
+ /* translate addresses into internal form */
+ sa6 = *(struct sockaddr_in6 *)sa;
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr) && m && m->m_pkthdr.rcvif)
+ sa6.sin6_addr.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
+
+ if (ip6) {
+ /*
+ * XXX: We assume that when IPV6 is non NULL,
+ * M and OFF are valid.
+ */
+ struct in6_addr s;
+
+ /* translate addresses into internal form */
+ memcpy(&s, &ip6->ip6_src, sizeof(s));
+ if (IN6_IS_ADDR_LINKLOCAL(&s))
+ s.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
+
+ (void) in6_pcbnotify(&rawin6pcbtable, (struct sockaddr *)&sa6,
+ 0, &s, 0, cmd, notify);
+ } else {
+ (void) in6_pcbnotify(&rawin6pcbtable, (struct sockaddr *)&sa6,
+ 0, &zeroin6_addr, 0, cmd, notify);
+ }
+}
+
/*----------------------------------------------------------------------
* Output function for raw IPv6. Called from rip6_usrreq(), and
* ipv6_icmp_usrreq().
@@ -514,6 +576,12 @@ rip6_ctloutput (op, so, level, optname, m)
};
break;
case ICMP6_FILTER:
+ if (level != IPPROTO_ICMPV6) {
+ if (op == PRCO_SETOPT && *m)
+ (void)m_free(*m);
+ return EINVAL;
+ }
+
if (op == PRCO_SETOPT || op == PRCO_GETOPT) {
if (op == PRCO_SETOPT) {
if (!m || !*m || (*m)->m_len != sizeof(struct icmp6_filter))