diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet6/frag6.c | 25 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 68 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 42 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 4 | ||||
-rw-r--r-- | sys/netinet6/route6.c | 7 |
5 files changed, 69 insertions, 77 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 121307d..3bb425f 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -144,14 +144,13 @@ frag6_input(mp, offp, proto) struct ip6_frag *ip6f; struct ip6q *q6; struct ip6asfrag *af6, *ip6af, *af6dwn; +#ifdef IN6_IFSTAT_STRICT + struct in6_ifaddr *ia; +#endif int offset = *offp, nxt, i, next; int first_frag = 0; int fragoff, frgpartlen; /* must be larger than u_int16_t */ struct ifnet *dstifp; -#ifdef IN6_IFSTAT_STRICT - static struct route_in6 ro; - struct sockaddr_in6 *dst; -#endif ip6 = mtod(m, struct ip6_hdr *); #ifndef PULLDOWN_TEST @@ -166,22 +165,8 @@ frag6_input(mp, offp, proto) dstifp = NULL; #ifdef IN6_IFSTAT_STRICT /* find the destination interface of the packet. */ - dst = (struct sockaddr_in6 *)&ro.ro_dst; - if (ro.ro_rt - && ((ro.ro_rt->rt_flags & RTF_UP) == 0 - || !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))) { - RTFREE(ro.ro_rt); - ro.ro_rt = (struct rtentry *)0; - } - if (ro.ro_rt == NULL) { - bzero(dst, sizeof(*dst)); - dst->sin6_family = AF_INET6; - dst->sin6_len = sizeof(struct sockaddr_in6); - dst->sin6_addr = ip6->ip6_dst; - } - rtalloc((struct route *)&ro); - if (ro.ro_rt != NULL && ro.ro_rt->rt_ifa != NULL) - dstifp = ((struct in6_ifaddr *)ro.ro_rt->rt_ifa)->ia_ifp; + if ((ia = ip6_getdstifaddr(m)) != NULL) + dstifp = ia->ia_ifp; #else /* we are violating the spec, this is not the destination interface */ if ((m->m_flags & M_PKTHDR) != 0) diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 30e534f..91ae896 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1185,8 +1185,8 @@ ni6_input(m, off) struct ni_reply_fqdn *fqdn; int addrs; /* for NI_QTYPE_NODEADDR */ struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */ - struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */ - struct sockaddr_in6 sin6_d; /* XXX: we should retrieve this from m_aux */ + struct sockaddr_in6 sin6_sbj; /* subject address */ + struct sockaddr_in6 sin6_d; struct ip6_hdr *ip6; int oldfqdn = 0; /* if 1, return pascal string (03 draft) */ char *subj = NULL; @@ -1203,32 +1203,41 @@ ni6_input(m, off) } #endif + 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; + if (in6_addr2zoneid(m->m_pkthdr.rcvif, &ip6->ip6_dst, + &sin6_d.sin6_scope_id)) { + goto bad; + } + if (in6_embedscope(&sin6_d.sin6_addr, &sin6_d, NULL, NULL)) + goto bad; /* XXX should not happen */ + /* * Validate IPv6 destination address. * * The Responder must discard the Query without further processing * unless it is one of the Responder's unicast or anycast addresses, or * a link-local scope multicast address which the Responder has joined. - * [icmp-name-lookups-07, Section 4.] + * [icmp-name-lookups-08, Section 4.] */ - bzero(&sin6, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_len = sizeof(struct sockaddr_in6); - bcopy(&ip6->ip6_dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); - /* XXX scopeid */ - if ((ia6 = (struct in6_ifaddr *)ifa_ifwithaddr((struct sockaddr *)&sin6)) != NULL) { - /* unicast/anycast, fine */ - if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 && - (icmp6_nodeinfo & 4) == 0) { + if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { + if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) + goto bad; + /* else it's a link-local multicast, fine */ + } else { /* unicast or anycast */ + if ((ia6 = ip6_getdstifaddr(m)) == NULL) + goto bad; /* XXX impossible */ + + if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) && + !(icmp6_nodeinfo & 4)) { nd6log((LOG_DEBUG, "ni6_input: ignore node info to " "a temporary address in %s:%d", __FILE__, __LINE__)); goto bad; } - } else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) - ; /* link-local multicast, fine */ - else - goto bad; + } /* validate query Subject field. */ qtype = ntohs(ni6->ni_qtype); @@ -1261,7 +1270,7 @@ ni6_input(m, off) goto bad; #endif - if (subjlen != sizeof(sin6.sin6_addr)) + if (subjlen != sizeof(struct in6_addr)) goto bad; /* @@ -1279,24 +1288,21 @@ ni6_input(m, off) * We do not do proxy at this moment. */ /* m_pulldown instead of copy? */ + bzero(&sin6_sbj, sizeof(sin6_sbj)); + sin6_sbj.sin6_family = AF_INET6; + sin6_sbj.sin6_len = sizeof(sin6_sbj); m_copydata(m, off + sizeof(struct icmp6_nodeinfo), - subjlen, (caddr_t)&sin6.sin6_addr); + subjlen, (caddr_t)&sin6_sbj.sin6_addr); if (in6_addr2zoneid(m->m_pkthdr.rcvif, - &sin6.sin6_addr, &sin6.sin6_scope_id)) { + &sin6_sbj.sin6_addr, &sin6_sbj.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; - 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)) + if (in6_embedscope(&sin6_sbj.sin6_addr, &sin6_sbj, + NULL, NULL)) + goto bad; /* XXX should not happen */ + + subj = (char *)&sin6_sbj; + if (SA6_ARE_ADDR_EQUAL(&sin6_sbj, &sin6_d)) break; /* diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index b823097..fdeebf7 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -157,7 +157,7 @@ int ip6_fw_enable = 1; struct ip6stat ip6stat; static void ip6_init2 __P((void *)); -static struct ip6aux *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *)); +static struct m_tag *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *)); static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *)); #ifdef PULLDOWN_TEST static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int)); @@ -259,7 +259,7 @@ ip6_input(m) #endif /* - * make sure we don't have onion peering information into m_aux. + * make sure we don't have onion peering information into m_tag. */ ip6_delaux(m); @@ -544,7 +544,7 @@ ip6_input(m) (struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa; /* - * record address information into m_aux. + * record address information into m_tag. */ (void)ip6_setdstifaddr(m, ia6); @@ -596,7 +596,7 @@ ip6_input(m) hbhcheck: /* - * record address information into m_aux, if we don't have one yet. + * record address information into m_tag, if we don't have one yet. * note that we are unable to record it, if the address is not listed * as our interface address (e.g. multicast addresses, addresses * within FAITH prefixes and such). @@ -801,28 +801,28 @@ ip6_input(m) * set/grab in6_ifaddr correspond to IPv6 destination address. * XXX backward compatibility wrapper */ -static struct ip6aux * +static struct m_tag * ip6_setdstifaddr(m, ia6) struct mbuf *m; struct in6_ifaddr *ia6; { - struct ip6aux *n; + struct m_tag *mtag; - n = ip6_addaux(m); - if (n) - n->ip6a_dstia6 = ia6; - return n; /* NULL if failed to set */ + mtag = ip6_addaux(m); + if (mtag) + ((struct ip6aux *)(mtag + 1))->ip6a_dstia6 = ia6; + return mtag; /* NULL if failed to set */ } struct in6_ifaddr * ip6_getdstifaddr(m) struct mbuf *m; { - struct ip6aux *n; + struct m_tag *mtag; - n = ip6_findaux(m); - if (n) - return n->ip6a_dstia6; + mtag = ip6_findaux(m); + if (mtag) + return ((struct ip6aux *)(mtag + 1))->ip6a_dstia6; else return NULL; } @@ -1534,7 +1534,7 @@ ip6_lasthdr(m, off, proto, nxtp) } } -struct ip6aux * +struct m_tag * ip6_addaux(m) struct mbuf *m; { @@ -1544,22 +1544,22 @@ ip6_addaux(m) if (!mtag) { mtag = m_tag_get(PACKET_TAG_IPV6_INPUT, sizeof(struct ip6aux), M_NOWAIT); - if (mtag) + if (mtag) { m_tag_prepend(m, mtag); + bzero(mtag + 1, sizeof(struct ip6aux)); + } } - if (mtag) - bzero(mtag+1, sizeof (struct ip6aux)); - return mtag ? (struct ip6aux*)(mtag+1) : NULL; + return mtag; } -struct ip6aux * +struct m_tag * ip6_findaux(m) struct mbuf *m; { struct m_tag *mtag; mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); - return mtag ? (struct ip6aux*)(mtag+1) : NULL; + return mtag; } void diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 6edaa1c..8206755 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -345,8 +345,8 @@ char * ip6_get_prevhdr __P((struct mbuf *, int)); int ip6_nexthdr __P((struct mbuf *, int, int, int *)); int ip6_lasthdr __P((struct mbuf *, int, int, int *)); -struct ip6aux *ip6_addaux __P((struct mbuf *)); -struct ip6aux *ip6_findaux __P((struct mbuf *)); +struct m_tag *ip6_addaux __P((struct mbuf *)); +struct m_tag *ip6_findaux __P((struct mbuf *)); void ip6_delaux __P((struct mbuf *)); int ip6_mforward __P((struct ip6_hdr *, struct ifnet *, struct mbuf *)); diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c index c4b0f61..567d0ba 100644 --- a/sys/netinet6/route6.c +++ b/sys/netinet6/route6.c @@ -60,10 +60,11 @@ route6_input(mp, offp, proto) struct mbuf *m = *mp; struct ip6_rthdr *rh; int off = *offp, rhlen; - struct ip6aux *ip6a; + struct m_tag *mtag; - ip6a = ip6_findaux(m); - if (ip6a) { + mtag = ip6_findaux(m); + if (mtag) { + struct ip6aux *ip6a = (struct ip6aux *)(mtag + 1); /* XXX reject home-address option before rthdr */ if (ip6a->ip6a_flags & IP6A_SWAP) { ip6stat.ip6s_badoptions++; |