]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Fix non-conformant IPv6 link-local address.
authorVMware, Inc <>
Mon, 26 Sep 2011 18:08:04 +0000 (11:08 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 26 Sep 2011 18:08:04 +0000 (11:08 -0700)
Some TCP stacks stick the scope id in there when they shouldn't. Fix it
in our code so that outside people see the correct address.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/services/plugins/guestInfo/getlib/guestInfo.c

index 8bf69af1a46ed3a8a6a75887a0be7aac6441246e..e359b74d9c11262a13a4d8474b829a7e6d16bddf 100644 (file)
@@ -395,6 +395,34 @@ GuestInfoSockaddrToTypedIpAddress(const struct sockaddr *sa,
       XDRUTIL_SAFESETOPAQUE(&typedIp->ipAddressAddr, InetAddress,
                             &sin6->sin6_addr.s6_addr,
                             sizeof sin6->sin6_addr.s6_addr);
+
+      /*
+       * Some TCP stacks (hello Apple and FreeBSD!) deviate from the RFC and
+       * embed the scope id in link-local IPv6 addresses. This breaks things
+       * since the address with the scope id does not work on the wire. For
+       * example:
+       *
+       *    fe80:4::20c:29ff:fece:3dcf
+       *
+       * Is an invalid IPv6 address because the "4" violates the RFC. But that's
+       * what SIOCGIFCONF returns on these platforms.
+       *
+       * Detect link-local addresses here and make sure they comply with the
+       * RFC. Just for reference, link local addresses start with '1111111010'
+       * and have 54 zero bits after that:
+       *
+       * http://tools.ietf.org/html/rfc4291#section-2.5.6
+       */
+      {
+         uint64  ip6_ll_test = 0x80FE;
+         uint64  ip6_ll_mask = 0xC0FF;
+         uint64 *ip6 = (uint64 *) typedIp->ipAddressAddr.InetAddress_val;
+
+         if ((*ip6 & ip6_ll_mask) == ip6_ll_test) {
+            *ip6 &= ip6_ll_mask;
+         }
+      }
+
       break;
    default:
       NOT_REACHED();