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!
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)) {
+ 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)