On Thu, Aug 04, 2011 at 17:06 +0200, Mike Belopuhov wrote:
> Hi,
>
> Currently it's possible to assign *any* IPv6 source address to
> the datagram sent out by the unprivileged process by supplying
> a IPV6_PKTINFO control message to the sendmsg(2).
>
> I'm not sure it's a desired behavior and afaik it's not possible
> to achieve this with IPv4 sockets without the need to be a root.
> Do we want to change that?
>
> The following change restricts it to the locally configured
> addresses. Is it a way to go?
>
> Cheers!
>
Considering all the pros and cons and what other operating systems
are doing this approach should be good enough for us at least at
this point.
OK? (with a s/IN6_IS_SCOPE_EMBED/IN6_IS_ADDR_LINKLOCAL/ fix)
>
> Index: in6_src.c
> ===================================================================
> RCS file: /home/cvs/src/sys/netinet6/in6_src.c,v
> retrieving revision 1.25
> diff -u -p -u -p -r1.25 in6_src.c
> --- in6_src.c 7 May 2010 13:33:17 -0000 1.25
> +++ in6_src.c 4 Aug 2011 14:19:54 -0000
> @@ -113,8 +113,29 @@ in6_selectsrc(struct sockaddr_in6 *dstso
> * use it.
> */
> if (opts && (pi = opts->ip6po_pktinfo) &&
> - !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr))
> + !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr)) {
> + struct ifnet *ifp;
> +
> + if (IN6_IS_SCOPE_EMBED(&pi->ipi6_addr)) {
This has to be IN6_IS_ADDR_LINKLOCAL because multicast addresses
are prohibited by the RFC.
> + pi->ipi6_addr.s6_addr16[1] = htons(pi->ipi6_ifindex);
> + if (in6ifa_ifpwithaddr(ifindex2ifnet[pi->ipi6_ifindex],
> + &pi->ipi6_addr) == NULL) {
> + *errorp = EADDRNOTAVAIL;
> + return (NULL);
> + }
> + } else {
> + TAILQ_FOREACH(ifp, &ifnet, if_list) {
> + if ((ia6 = in6ifa_ifpwithaddr(ifp,
> + &pi->ipi6_addr)) != NULL)
> + break;
> + }
> + if (!ia6) {
> + *errorp = EADDRNOTAVAIL;
> + return (NULL);
> + }
> + }
> return (&pi->ipi6_addr);
> + }
>
> /*
> * If the source address is not specified but the socket(if any)