diff options
-rw-r--r-- | sys/netinet6/icmp6.c | 105 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 32 |
2 files changed, 25 insertions, 112 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index a71156371f0..2464db14bf8 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.206 2017/04/19 15:21:54 bluhm Exp $ */ +/* $OpenBSD: icmp6.c,v 1.207 2017/04/19 15:44:45 bluhm Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -135,7 +135,6 @@ static struct rttimer_queue *icmp6_redirect_timeout_q = NULL; static int icmp6_redirect_lowat = -1; void icmp6_errcount(int, int); -int icmp6_rip6_input(struct mbuf **, int); int icmp6_ratelimit(const struct in6_addr *, const int, const int); const char *icmp6_redirect_diag(struct in6_addr *, struct in6_addr *, struct in6_addr *); @@ -761,9 +760,7 @@ badlen: raw: #endif /* deliver the packet to appropriate sockets */ - icmp6_rip6_input(&m, *offp); - - return IPPROTO_DONE; + return rip6_input(mp, offp, proto, af); freeit: m_freem(m); @@ -1042,104 +1039,6 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated) } /* - * XXX almost dup'ed code with rip6_input. - */ -int -icmp6_rip6_input(struct mbuf **mp, int off) -{ - struct mbuf *m = *mp; - struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); - struct inpcb *in6p; - struct inpcb *last = NULL; - struct sockaddr_in6 rip6src; - struct icmp6_hdr *icmp6; - struct mbuf *opts = NULL; - - IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); - if (icmp6 == NULL) { - /* m is already reclaimed */ - return IPPROTO_DONE; - } - - bzero(&rip6src, sizeof(rip6src)); - rip6src.sin6_len = sizeof(struct sockaddr_in6); - rip6src.sin6_family = AF_INET6; - /* KAME hack: recover scopeid */ - in6_recoverscope(&rip6src, &ip6->ip6_src); - - TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) { - if (!(in6p->inp_flags & INP_IPV6)) - continue; - if (in6p->inp_ipv6.ip6_nxt != IPPROTO_ICMPV6) - continue; -#if NPF > 0 - if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) { - struct pf_divert *divert; - - /* XXX rdomain support */ - if ((divert = pf_find_divert(m)) == NULL) - continue; - if (IN6_IS_ADDR_UNSPECIFIED(&divert->addr.v6)) - goto divert_reply; - if (!IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, - &divert->addr.v6)) - continue; - } else - divert_reply: -#endif - if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_laddr6) && - !IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, &ip6->ip6_dst)) - continue; - if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6) && - !IN6_ARE_ADDR_EQUAL(&in6p->inp_faddr6, &ip6->ip6_src)) - continue; - if (in6p->inp_icmp6filt - && ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, - in6p->inp_icmp6filt)) - continue; - if (last) { - struct mbuf *n; - if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) != NULL) { - if (last->inp_flags & IN6P_CONTROLOPTS) - ip6_savecontrol(last, n, &opts); - /* strip intermediate headers */ - m_adj(n, off); - if (sbappendaddr(&last->inp_socket->so_rcv, - sin6tosa(&rip6src), n, opts) == 0) { - /* should notify about lost packet */ - m_freem(n); - m_freem(opts); - } else - sorwakeup(last->inp_socket); - opts = NULL; - } - } - last = in6p; - } - if (last) { - if (last->inp_flags & IN6P_CONTROLOPTS) - ip6_savecontrol(last, m, &opts); - /* strip intermediate headers */ - m_adj(m, off); - if (sbappendaddr(&last->inp_socket->so_rcv, - sin6tosa(&rip6src), m, opts) == 0) { - m_freem(m); - m_freem(opts); - } else - sorwakeup(last->inp_socket); - } else { - struct counters_ref ref; - uint64_t *counters; - - m_freem(m); - counters = counters_enter(&ref, ip6counters); - counters[ip6s_delivered]--; - counters_leave(&ref, ip6counters); - } - return IPPROTO_DONE; -} - -/* * Reflect the ip6 packet back to the source. * OFF points to the icmp6 header, counted from the top of the mbuf. * diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index d3a8265c21e..e5217b2791b 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.110 2017/04/17 21:10:03 bluhm Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.111 2017/04/19 15:44:45 bluhm Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -127,7 +127,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) KASSERT(af == AF_INET6); - rip6stat_inc(rip6s_ipackets); + if (proto != IPPROTO_ICMPV6) + rip6stat_inc(rip6s_ipackets); /* Be proactive about malicious use of IPv4 mapped address */ if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || @@ -148,7 +149,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) continue; if (!(in6p->inp_flags & INP_IPV6)) continue; - if (in6p->inp_ipv6.ip6_nxt && + if ((in6p->inp_ipv6.ip6_nxt || proto == IPPROTO_ICMPV6) && in6p->inp_ipv6.ip6_nxt != proto) continue; #if NPF > 0 @@ -172,7 +173,18 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6) && !IN6_ARE_ADDR_EQUAL(&in6p->inp_faddr6, &ip6->ip6_src)) continue; - if (in6p->inp_cksum6 != -1) { + if (proto == IPPROTO_ICMPV6 && in6p->inp_icmp6filt) { + struct icmp6_hdr *icmp6; + + IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, *offp, + sizeof(*icmp6)); + if (icmp6 == NULL) + return IPPROTO_DONE; + if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, + in6p->inp_icmp6filt)) + continue; + } + if (proto != IPPROTO_ICMPV6 && in6p->inp_cksum6 != -1) { rip6stat_inc(rip6s_isum); if (in6_cksum(m, proto, *offp, m->m_pkthdr.len - *offp)) { @@ -216,12 +228,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) struct counters_ref ref; uint64_t *counters; - rip6stat_inc(rip6s_nosock); - if (m->m_flags & M_MCAST) - rip6stat_inc(rip6s_nosockmcast); - if (proto == IPPROTO_NONE) + if (proto != IPPROTO_ICMPV6) { + rip6stat_inc(rip6s_nosock); + if (m->m_flags & M_MCAST) + rip6stat_inc(rip6s_nosockmcast); + } + if (proto == IPPROTO_NONE || proto == IPPROTO_ICMPV6) { m_freem(m); - else { + } else { u_int8_t *prvnxtp = ip6_get_prevhdr(m, *offp); /* XXX */ icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, |