diff options
author | 2000-02-28 16:40:39 +0000 | |
---|---|---|
committer | 2000-02-28 16:40:39 +0000 | |
commit | 763eaa77a0e4ce7af56e41876ff947d8146b705b (patch) | |
tree | 3ae16bf1bb7c8e31b438bb8c21f46573f978278d /sys/netinet6 | |
parent | Sanitize v{,un}mapbuf. (use the sizes we are passed, not the size from b_count); art (diff) | |
download | wireguard-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.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 3 | ||||
-rw-r--r-- | sys/netinet6/raw_ipv6.c | 74 |
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)) |