summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/raw_ipv6.c
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/raw_ipv6.c
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/raw_ipv6.c')
-rw-r--r--sys/netinet6/raw_ipv6.c74
1 files changed, 71 insertions, 3 deletions
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))