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)

Reply via email to