diff options
author | ume <ume@FreeBSD.org> | 2005-07-25 12:31:43 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2005-07-25 12:31:43 +0000 |
commit | da2cf62b280b8450d5f8e0d810e810cdcc59a8c0 (patch) | |
tree | 5a678f63b25976c30f74f3bad9edb6f708c52930 /sys/netinet | |
parent | 59bc7b0da19f008a39ee92249e92f8246f04394e (diff) | |
download | FreeBSD-src-da2cf62b280b8450d5f8e0d810e810cdcc59a8c0.zip FreeBSD-src-da2cf62b280b8450d5f8e0d810e810cdcc59a8c0.tar.gz |
scope cleanup. with this change
- most of the kernel code will not care about the actual encoding of
scope zone IDs and won't touch "s6_addr16[1]" directly.
- similarly, most of the kernel code will not care about link-local
scoped addresses as a special case.
- scope boundary check will be stricter. For example, the current
*BSD code allows a packet with src=::1 and dst=(some global IPv6
address) to be sent outside of the node, if the application do:
s = socket(AF_INET6);
bind(s, "::1");
sendto(s, some_global_IPv6_addr);
This is clearly wrong, since ::1 is only meaningful within a single
node, but the current implementation of the *BSD kernel cannot
reject this attempt.
Submitted by: JINMEI Tatuya <jinmei__at__isl.rdc.toshiba.co.jp>
Obtained from: KAME
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/icmp6.h | 1 | ||||
-rw-r--r-- | sys/netinet/ip_carp.c | 35 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 22 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 22 | ||||
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 2 |
5 files changed, 40 insertions, 42 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index 4dee079..b35ec09 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -632,6 +632,7 @@ struct in6_multi; void icmp6_init(void); void icmp6_paramerror(struct mbuf *, int); void icmp6_error(struct mbuf *, int, int, int); +void icmp6_error2(struct mbuf *, int, int, int, struct ifnet *); int icmp6_input(struct mbuf **, int *, int); void icmp6_fasttimo(void); void icmp6_reflect(struct mbuf *, size_t); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 83fb9b9..812caf3 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -268,8 +268,7 @@ carp_hmac_prepare(struct carp_softc *sc) TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) { if (ifa->ifa_addr->sa_family == AF_INET6) { in6 = ifatoia6(ifa)->ia_addr.sin6_addr; - if (IN6_IS_ADDR_LINKLOCAL(&in6)) - in6.s6_addr16[1] = 0; + in6_clearscope(&in6); SHA1Update(&sc->sc_sha1, (void *)&in6, sizeof(in6)); } } @@ -1537,7 +1536,7 @@ carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) struct in6_ifaddr *ia, *ia_if; struct ip6_moptions *im6o = &sc->sc_im6o; struct in6_multi_mship *imm; - struct sockaddr_in6 addr; + struct in6_addr in6; int own, error; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { @@ -1586,25 +1585,25 @@ carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6) im6o->im6o_multicast_ifp = ifp; /* join CARP multicast address */ - bzero(&addr, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_len = sizeof(addr); - addr.sin6_addr.s6_addr16[0] = htons(0xff02); - addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); - addr.sin6_addr.s6_addr8[15] = 0x12; - if ((imm = in6_joingroup(ifp, &addr.sin6_addr, &error)) == NULL) + bzero(&in6, sizeof(in6)); + in6.s6_addr16[0] = htons(0xff02); + in6.s6_addr8[15] = 0x12; + if (in6_setscope(&in6, ifp, NULL) != 0) + goto cleanup; + if ((imm = in6_joingroup(ifp, &in6, &error)) == NULL) goto cleanup; LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain); /* join solicited multicast address */ - bzero(&addr.sin6_addr, sizeof(addr.sin6_addr)); - addr.sin6_addr.s6_addr16[0] = htons(0xff02); - addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); - addr.sin6_addr.s6_addr32[1] = 0; - addr.sin6_addr.s6_addr32[2] = htonl(1); - addr.sin6_addr.s6_addr32[3] = sin6->sin6_addr.s6_addr32[3]; - addr.sin6_addr.s6_addr8[12] = 0xff; - if ((imm = in6_joingroup(ifp, &addr.sin6_addr, &error)) == NULL) + bzero(&in6, sizeof(in6)); + in6.s6_addr16[0] = htons(0xff02); + in6.s6_addr32[1] = 0; + in6.s6_addr32[2] = htonl(1); + in6.s6_addr32[3] = sin6->sin6_addr.s6_addr32[3]; + in6.s6_addr8[12] = 0xff; + if (in6_setscope(&in6, ifp, NULL) != 0) + goto cleanup; + if ((imm = in6_joingroup(ifp, &in6, &error)) == NULL) goto cleanup; LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain); } diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 11d51e2..750c3b9 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -74,6 +74,7 @@ #include <netinet/ip_var.h> #ifdef INET6 #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #include <netinet6/nd6.h> #endif #include <netinet/ip_icmp.h> @@ -1044,19 +1045,17 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS) error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) return (error); + if ((error = sa6_embedscope(&addrs[0], ip6_use_defzone)) != 0 || + (error = sa6_embedscope(&addrs[1], ip6_use_defzone)) != 0) { + return (error); + } if (IN6_IS_ADDR_V4MAPPED(&addrs[0].sin6_addr)) { if (IN6_IS_ADDR_V4MAPPED(&addrs[1].sin6_addr)) mapped = 1; else return (EINVAL); - } else { - error = in6_embedscope(&a6[0], &addrs[0], NULL, NULL); - if (error) - return (EINVAL); - error = in6_embedscope(&a6[1], &addrs[1], NULL, NULL); - if (error) - return (EINVAL); } + INP_INFO_RLOCK(&tcbinfo); if (mapped == 1) inp = in_pcblookup_hash(&tcbinfo, @@ -2191,12 +2190,11 @@ sysctl_drop(SYSCTL_HANDLER_ARGS) lin = (struct sockaddr_in *)&addrs[1]; break; } - error = in6_embedscope(&f6, fin6, NULL, NULL); + error = sa6_embedscope(fin6, ip6_use_defzone); if (error) - return (EINVAL); - error = in6_embedscope(&l6, lin6, NULL, NULL); - if (error) - return (EINVAL); + return (error); + error = sa6_embedscope(lin6, ip6_use_defzone); + return (error); break; #endif case AF_INET: diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index 11d51e2..750c3b9 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -74,6 +74,7 @@ #include <netinet/ip_var.h> #ifdef INET6 #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #include <netinet6/nd6.h> #endif #include <netinet/ip_icmp.h> @@ -1044,19 +1045,17 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS) error = SYSCTL_IN(req, addrs, sizeof(addrs)); if (error) return (error); + if ((error = sa6_embedscope(&addrs[0], ip6_use_defzone)) != 0 || + (error = sa6_embedscope(&addrs[1], ip6_use_defzone)) != 0) { + return (error); + } if (IN6_IS_ADDR_V4MAPPED(&addrs[0].sin6_addr)) { if (IN6_IS_ADDR_V4MAPPED(&addrs[1].sin6_addr)) mapped = 1; else return (EINVAL); - } else { - error = in6_embedscope(&a6[0], &addrs[0], NULL, NULL); - if (error) - return (EINVAL); - error = in6_embedscope(&a6[1], &addrs[1], NULL, NULL); - if (error) - return (EINVAL); } + INP_INFO_RLOCK(&tcbinfo); if (mapped == 1) inp = in_pcblookup_hash(&tcbinfo, @@ -2191,12 +2190,11 @@ sysctl_drop(SYSCTL_HANDLER_ARGS) lin = (struct sockaddr_in *)&addrs[1]; break; } - error = in6_embedscope(&f6, fin6, NULL, NULL); + error = sa6_embedscope(fin6, ip6_use_defzone); if (error) - return (EINVAL); - error = in6_embedscope(&l6, lin6, NULL, NULL); - if (error) - return (EINVAL); + return (error); + error = sa6_embedscope(lin6, ip6_use_defzone); + return (error); break; #endif case AF_INET: diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 653ab6c..0ed4495 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -66,6 +66,7 @@ #include <netinet/ip_var.h> #ifdef INET6 #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #endif #include <netinet/tcp.h> #include <netinet/tcp_fsm.h> @@ -925,6 +926,7 @@ tcp6_connect(tp, nam, td) * Cannot simply call in_pcbconnect, because there might be an * earlier incarnation of this same connection still in * TIME_WAIT state, creating an ADDRINUSE error. + * in6_pcbladdr() also handles scope zone IDs. */ error = in6_pcbladdr(inp, nam, &addr6); if (error) |