diff options
Diffstat (limited to 'sys/netinet6/icmp6.c')
-rw-r--r-- | sys/netinet6/icmp6.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 642b7bd..389d7a2 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -358,10 +358,8 @@ icmp6_error(m, type, code, param) nip6->ip6_src = oip6->ip6_src; nip6->ip6_dst = oip6->ip6_dst; - if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_src)) - oip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_SCOPE_LINKLOCAL(&oip6->ip6_dst)) - oip6->ip6_dst.s6_addr16[1] = 0; + in6_clearscope(&oip6->ip6_src); + in6_clearscope(&oip6->ip6_dst); icmp6 = (struct icmp6_hdr *)(nip6 + 1); icmp6->icmp6_type = type; @@ -1061,8 +1059,9 @@ icmp6_notify_error(m, off, icmp6len, code) icmp6dst.sin6_addr = eip6->ip6_dst; else icmp6dst.sin6_addr = *finaldst; - icmp6dst.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, - &icmp6dst.sin6_addr); + if (in6_addr2zoneid(m->m_pkthdr.rcvif, &icmp6dst.sin6_addr, + &icmp6dst.sin6_scope_id)) + goto freeit; if (in6_embedscope(&icmp6dst.sin6_addr, &icmp6dst, NULL, NULL)) { /* should be impossbile */ @@ -1079,8 +1078,10 @@ icmp6_notify_error(m, off, icmp6len, code) icmp6src.sin6_len = sizeof(struct sockaddr_in6); icmp6src.sin6_family = AF_INET6; icmp6src.sin6_addr = eip6->ip6_src; - icmp6src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, - &icmp6src.sin6_addr); + if (in6_addr2zoneid(m->m_pkthdr.rcvif, &icmp6src.sin6_addr, + &icmp6src.sin6_scope_id)) { + goto freeit; + } if (in6_embedscope(&icmp6src.sin6_addr, &icmp6src, NULL, NULL)) { /* should be impossbile */ @@ -1284,15 +1285,19 @@ ni6_input(m, off) /* m_pulldown instead of copy? */ m_copydata(m, off + sizeof(struct icmp6_nodeinfo), subjlen, (caddr_t)&sin6.sin6_addr); - sin6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, - &sin6.sin6_addr); + if (in6_addr2zoneid(m->m_pkthdr.rcvif, + &sin6.sin6_addr, &sin6.sin6_scope_id)) { + goto bad; + } in6_embedscope(&sin6.sin6_addr, &sin6, NULL, NULL); bzero(&sin6_d, sizeof(sin6_d)); sin6_d.sin6_family = AF_INET6; /* not used, actually */ sin6_d.sin6_len = sizeof(sin6_d); /* ditto */ sin6_d.sin6_addr = ip6->ip6_dst; - sin6_d.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.rcvif, - &ip6->ip6_dst); + if (in6_addr2zoneid(m->m_pkthdr.rcvif, + &ip6->ip6_dst, &sin6_d.sin6_scope_id)) { + goto bad; + } in6_embedscope(&sin6_d.sin6_addr, &sin6_d, NULL, NULL); subj = (char *)&sin6; if (SA6_ARE_ADDR_EQUAL(&sin6, &sin6_d)) @@ -1863,9 +1868,7 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) /* copy the address itself */ bcopy(&ifa6->ia_addr.sin6_addr, cp, sizeof(struct in6_addr)); - /* XXX: KAME link-local hack; remove ifindex */ - if (IN6_IS_ADDR_LINKLOCAL(&ifa6->ia_addr.sin6_addr)) - ((struct in6_addr *)cp)->s6_addr16[1] = 0; + in6_clearscope((struct in6_addr *)cp); /* XXX */ cp += sizeof(struct in6_addr); resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t)); @@ -1899,7 +1902,7 @@ icmp6_rip6_input(mp, off) struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); struct in6pcb *in6p; struct in6pcb *last = NULL; - struct sockaddr_in6 rip6src; + struct sockaddr_in6 fromsa; struct icmp6_hdr *icmp6; struct mbuf *opts = NULL; @@ -1914,11 +1917,11 @@ icmp6_rip6_input(mp, off) } #endif - bzero(&rip6src, sizeof(rip6src)); - rip6src.sin6_len = sizeof(struct sockaddr_in6); - rip6src.sin6_family = AF_INET6; + bzero(&fromsa, sizeof(fromsa)); + fromsa.sin6_len = sizeof(struct sockaddr_in6); + fromsa.sin6_family = AF_INET6; /* KAME hack: recover scopeid */ - (void)in6_recoverscope(&rip6src, &ip6->ip6_src, m->m_pkthdr.rcvif); + (void)in6_recoverscope(&fromsa, &ip6->ip6_src, m->m_pkthdr.rcvif); LIST_FOREACH(in6p, &ripcb, inp_list) { if ((in6p->inp_vflag & INP_IPV6) == 0) @@ -1947,7 +1950,7 @@ icmp6_rip6_input(mp, off) /* strip intermediate headers */ m_adj(n, off); if (sbappendaddr(&last->in6p_socket->so_rcv, - (struct sockaddr *)&rip6src, n, opts) + (struct sockaddr *)&fromsa, n, opts) == 0) { /* should notify about lost packet */ m_freem(n); @@ -1967,7 +1970,7 @@ icmp6_rip6_input(mp, off) /* strip intermediate headers */ m_adj(m, off); if (sbappendaddr(&last->in6p_socket->so_rcv, - (struct sockaddr *)&rip6src, m, opts) == 0) { + (struct sockaddr *)&fromsa, m, opts) == 0) { m_freem(m); if (opts) m_freem(opts); @@ -2447,7 +2450,8 @@ icmp6_redirect_output(m0, rt) src_sa.sin6_len = sizeof(src_sa); src_sa.sin6_addr = sip6->ip6_src; /* we don't currently use sin6_scope_id, but eventually use it */ - src_sa.sin6_scope_id = in6_addr2scopeid(ifp, &sip6->ip6_src); + if (in6_addr2zoneid(ifp, &sip6->ip6_src, &src_sa.sin6_scope_id)) + goto fail; if (nd6_is_addr_neighbor(&src_sa, ifp) == 0) goto fail; if (IN6_IS_ADDR_MULTICAST(&sip6->ip6_dst)) @@ -2664,14 +2668,11 @@ noredhdropt:; m0 = NULL; } - if (IN6_IS_ADDR_LINKLOCAL(&sip6->ip6_src)) - sip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_ADDR_LINKLOCAL(&sip6->ip6_dst)) - sip6->ip6_dst.s6_addr16[1] = 0; - if (IN6_IS_ADDR_LINKLOCAL(&nd_rd->nd_rd_target)) - nd_rd->nd_rd_target.s6_addr16[1] = 0; - if (IN6_IS_ADDR_LINKLOCAL(&nd_rd->nd_rd_dst)) - nd_rd->nd_rd_dst.s6_addr16[1] = 0; + /* XXX: clear embedded link IDs in the inner header */ + in6_clearscope(&sip6->ip6_src); + in6_clearscope(&sip6->ip6_dst); + in6_clearscope(&nd_rd->nd_rd_target); + in6_clearscope(&nd_rd->nd_rd_dst); ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); |