diff -aur VirtualBox-4.2.10-orig/include/iprt/net.h VirtualBox-4.2.10/include/iprt/net.h
--- VirtualBox-4.2.10-orig/include/iprt/net.h	2012-12-19 10:24:40.000000000 -0800
+++ VirtualBox-4.2.10/include/iprt/net.h	2013-02-24 10:54:45.000000000 -0800
@@ -323,14 +323,14 @@
 
 /** The minimum IPv6 header length (in bytes).
  * Up to and including RTNETIPV6::ip6_dst. */
-#define RTNETIPV6_MIN_LEN   (40)
+#define RTNETIPV6_MIN_LEN                           (40)
+#define RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN    (32)
 
 RTDECL(uint32_t) RTNetIPv6PseudoChecksum(PCRTNETIPV6 pIpHdr);
 RTDECL(uint32_t) RTNetIPv6PseudoChecksumEx(PCRTNETIPV6 pIpHdr, uint8_t bProtocol, uint16_t cbPkt);
 RTDECL(uint32_t) RTNetIPv6PseudoChecksumBits(PCRTNETADDRIPV6 pSrcAddr, PCRTNETADDRIPV6 pDstAddr,
                                              uint8_t bProtocol, uint16_t cbPkt);
 
-
 /**
  * UDP header.
  */
@@ -737,6 +737,51 @@
 
 /** @todo add ICMPv6 when needed. */
 
+#define RTNETIPV6_PROT_ICMPV6       (58)
+#define RTNETIPV6_ICMPV6_CODE_0     (0)
+#define RTNETIPV6_ICMP_NS_TYPE      (135)
+#define RTNETIPV6_ICMP_NA_TYPE      (136)
+#define RTNETIPV6_ICMP_ND_SLLA_OPT  (1)
+#define RTNETIPV6_ICMP_ND_TLLA_OPT  (2)
+#define RTNETIPV6_ICMP_ND_LLA_LEN   (1)
+
+/** ICMPv6 ND Source Link Layer Address option */
+#pragma pack(1)
+typedef struct RTNETNDP_SLLA_OPT
+{
+    uint8_t type;
+    uint8_t len;
+    RTMAC slla;
+} RTNETNDP_SLLA_OPT;
+#pragma pack()
+
+AssertCompileSize(RTNETNDP_SLLA_OPT, 1+1+6);
+
+typedef RTNETNDP_SLLA_OPT *PRTNETNDP_SLLA_OPT;
+typedef RTNETNDP_SLLA_OPT const *PCRTNETNDP_SLLA_OPT;
+
+/** ICMPv6 ND Neighbor Sollicitation */
+#pragma pack(1)
+typedef struct RTNETNDP
+{
+    /** ICMPv6 type. **/
+    uint8_t icmp6_type;
+    /** ICMPv6 code. **/
+    uint8_t icmp6_code;
+    /** ICMPv6 checksum **/
+    uint16_t icmp6_cksum;
+    /** reserved **/
+    uint32_t reserved;
+    /** target address **/
+    RTNETADDRIPV6 target_address;
+} RTNETNDP;
+#pragma pack()
+AssertCompileSize(RTNETNDP, 1+1+2+4+16);
+/** Pointer to a NDP ND packet. */
+typedef RTNETNDP *PRTNETNDP;
+/** Pointer to a const NDP NS packet. */
+typedef RTNETNDP const *PCRTNETNDP;
+
 
 /**
  * Ethernet ARP header.
@@ -805,9 +850,6 @@
 typedef RTNETARPIPV4 const *PCRTNETARPIPV4;
 
 
-/** @todo RTNETNDP (IPv6)*/
-
-
 /** @} */
 
 RT_C_DECLS_END
diff -aur VirtualBox-4.2.10-orig/include/iprt/types.h VirtualBox-4.2.10/include/iprt/types.h
--- VirtualBox-4.2.10-orig/include/iprt/types.h	2012-12-19 10:24:40.000000000 -0800
+++ VirtualBox-4.2.10/include/iprt/types.h	2013-02-24 10:54:55.000000000 -0800
@@ -395,6 +395,7 @@
 /**
  * 128-bit unsigned integer union.
  */
+#pragma pack(1)
 typedef union RTUINT128U
 {
     /** Natural view.
@@ -470,6 +471,7 @@
     /** 8-bit view. */
     uint8_t     au8[16];
 } RTUINT128U;
+#pragma pack()
 /** Pointer to a 64-bit unsigned integer union. */
 typedef RTUINT128U *PRTUINT128U;
 /** Pointer to a const 64-bit unsigned integer union. */
diff -aur VirtualBox-4.2.10-orig/src/VBox/Devices/Network/SrvIntNetR0.cpp VirtualBox-4.2.10/src/VBox/Devices/Network/SrvIntNetR0.cpp
--- VirtualBox-4.2.10-orig/src/VBox/Devices/Network/SrvIntNetR0.cpp	2012-12-19 10:26:38.000000000 -0800
+++ VirtualBox-4.2.10/src/VBox/Devices/Network/SrvIntNetR0.cpp	2013-02-24 10:55:01.000000000 -0800
@@ -836,6 +836,23 @@
     return NULL;
 }
 
+/**
+ * Checks if the IPv6 address is a good interface address.
+ * @returns true/false.
+ * @param   addr        The address, network endian.
+ */
+DECLINLINE(bool) intnetR0IPv6AddrIsGood(RTNETADDRIPV6 addr)
+{
+            //check for ::
+    return  !(addr.u == 0 ||
+            //check for multicast
+            (addr.Words.w0 & RT_H2BE_U16(0xff00) == RT_H2BE_U16(0xff00)) ||
+            //check for ::1
+            (addr.Words.w0 == 0 && addr.Words.w1 == 0 && addr.Words.w2 == 0 &&
+                addr.Words.w3 == 0 && addr.Words.w4 ==0 && addr.Words.w5 == 0 &&
+                addr.Words.w6 == 0 && addr.Words.w7 == RT_H2BE_U16(0x0001)) );
+}
+
 
 /**
  * Checks if the IPv4 address is a broadcast address.
@@ -848,7 +865,6 @@
     return Addr.u == UINT32_MAX;
 }
 
-
 /**
  * Checks if the IPv4 address is a good interface address.
  * @returns true/false.
@@ -1070,11 +1086,25 @@
     switch (enmAddrType)
     {
         case kIntNetAddrType_IPv4:
-            Log(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n",
+            LogRel(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv4 deleted #%d %d.%d.%d.%d %s\n",
                  pIf->hIf, &pIf->MacAddr, iEntry, pAddr->au8[0], pAddr->au8[1], pAddr->au8[2], pAddr->au8[3], pszMsg));
             break;
+        case kIntNetAddrType_IPv6:
+            LogRel(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv6 deleted #%d %00x:%00x:%00x:%00x:%00x:%00x:%00x %00x %s\n",
+                pIf->hIf, &pIf->MacAddr, iEntry, 
+                pAddr->IPv6.Words.w0,
+                pAddr->IPv6.Words.w1,
+                pAddr->IPv6.Words.w2,
+                pAddr->IPv6.Words.w3,
+                pAddr->IPv6.Words.w4,
+                pAddr->IPv6.Words.w5,
+                pAddr->IPv6.Words.w6,
+                pAddr->IPv6.Words.w7,
+                pszMsg
+            ));
+            break;
         default:
-            Log(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 MAC=%.6Rhxs type=%d #%d %.*Rhxs %s\n",
+            LogRel(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 MAC=%.6Rhxs type=%d #%d %.*Rhxs %s\n",
                  pIf->hIf, &pIf->MacAddr, enmAddrType, iEntry, pCache->cbAddress, pAddr, pszMsg));
             break;
     }
@@ -1229,7 +1259,7 @@
     /* When the table is full, drop the older entry (FIFO). Do proper ageing? */
     if (pCache->cEntries >= pCache->cEntriesAlloc)
     {
-        Log(("intnetR0IfAddrCacheAddIt: type=%d replacing %.*Rhxs\n",
+        LogRel(("intnetR0IfAddrCacheAddIt: type=%d replacing %.*Rhxs\n",
              (int)(uintptr_t)(pCache - &pIf->aAddrCache[0]), pCache->cbAddress, pCache->pbEntries));
         memmove(pCache->pbEntries, pCache->pbEntries + pCache->cbEntry, pCache->cbEntry * (pCache->cEntries - 1));
         pCache->cEntries--;
@@ -1247,11 +1277,25 @@
     switch (enmAddrType)
     {
         case kIntNetAddrType_IPv4:
-            Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n",
+            LogRel(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n",
                  pIf->hIf, &pIf->MacAddr, pCache->cEntries, pAddr->au8[0], pAddr->au8[1], pAddr->au8[2], pAddr->au8[3], pszMsg));
             break;
+        case kIntNetAddrType_IPv6:
+            LogRel(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv6 added #%d %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x %s\n", 
+                    pIf->hIf, &pIf->MacAddr, pCache->cEntries,
+                    RT_BE2H_U16(pAddr->IPv6.Words.w0),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w1),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w2),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w3),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w4),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w5),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w6),
+                    RT_BE2H_U16(pAddr->IPv6.Words.w7), 
+                    pszMsg
+                ));
+            break;
         default:
-            Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs type=%d added #%d %.*Rhxs %s\n",
+            LogRel(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs type=%d added #%d %.*Rhxs %s\n",
                  pIf->hIf, &pIf->MacAddr, enmAddrType, pCache->cEntries, pCache->cbAddress, pAddr, pszMsg));
             break;
     }
@@ -2251,7 +2295,7 @@
 
 #ifdef INTNET_WITH_DHCP_SNOOPING
 /**
- * Snoop up addresses from ARP and DHCP traffic from frames coming
+ * Snoop up addresses from ND, ARP and DHCP traffic from frames coming
  * over the trunk connection.
  *
  * The caller is responsible for do some basic filtering before calling
@@ -2333,13 +2377,6 @@
             break;
         }
 
-        case RTNET_ETHERTYPE_IPV6:
-        {
-            /** @todo IPv6: Check for ICMPv6. It looks like type 133 (Router solicitation) might
-             * need to be edited. Check out how NDP works...  */
-            break;
-        }
-
         case RTNET_ETHERTYPE_ARP:
             intnetR0TrunkIfSnoopArp(pNetwork, pSG);
             break;
@@ -2347,6 +2384,41 @@
 }
 #endif /* INTNET_WITH_DHCP_SNOOPING */
 
+/**
+ * Deals with an IPv6 packet.
+ *
+ * This will fish out the source IP address and add it to the cache.
+ * Then it will look for DHCPRELEASE requests (?) and anything else
+ * that we might find useful later.
+ *
+ * @param   pIf             The interface that's sending the frame.
+ * @param   pIpHdr          Pointer to the IPv4 header in the frame.
+ * @param   cbPacket        The size of the packet, or more correctly the
+ *                          size of the frame without the ethernet header.
+ * @param   fGso            Set if this is a GSO frame, clear if regular.
+ */
+static void intnetR0IfSnoopIPv6SourceAddr(PINTNETIF pIf, PCRTNETIPV6 pIpHdr, uint32_t cbPacket, bool fGso)
+{
+    /*
+     * Check the header size first to prevent access invalid data.
+     */
+    if (cbPacket < RTNETIPV6_MIN_LEN)
+        return;
+
+    /*
+     * If the source address is good (not multicast) and
+     * not already in the address cache of the sender, add it.
+     */
+    RTNETADDRU Addr;
+    Addr.IPv6 = pIpHdr->ip6_src;
+
+    if (    intnetR0IPv6AddrIsGood(Addr.IPv6) && (pIpHdr->ip6_hlim == 0xff)
+        &&  intnetR0IfAddrCacheLookupLikely(&pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, sizeof(Addr.IPv6)) < 0)
+    {
+        intnetR0IfAddrCacheAddIt(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, "if/ipv6");
+    }
+}
+
 
 /**
  * Deals with an IPv4 packet.
@@ -2497,13 +2569,11 @@
         case RTNET_ETHERTYPE_IPV4:
             intnetR0IfSnoopIPv4SourceAddr(pIf, (PCRTNETIPV4)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, fGso);
             break;
-#if 0 /** @todo IntNet: implement IPv6 for wireless MAC sharing. */
+
         case RTNET_ETHERTYPE_IPV6:
-            /** @todo IPv6: Check for ICMPv6. It looks like type 133 (Router solicitation) might
-             * need to be edited. Check out how NDP works...  */
-            intnetR0IfSnoopIPv6SourceAddr(pIf, (PCINTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, fGso, pfSgFlags);
+            intnetR0IfSnoopIPv6SourceAddr(pIf, (PCRTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, fGso);
             break;
-#endif
+
 #if 0 /** @todo IntNet: implement IPX for wireless MAC sharing? */
         case RTNET_ETHERTYPE_IPX_1:
         case RTNET_ETHERTYPE_IPX_2:
@@ -2685,6 +2755,42 @@
     return !!(pThis->fHostGsoCapabilites & pThis->fWireGsoCapabilites & fMask);
 }
 
+/**
+ * Calculates the checksum of a full ipv6 frame.
+ *
+ * @returns 16-bit hecksum value.
+ * @param   pIpHdr          The IPv6 header (network endian (big)).
+ * @param   bProtocol       The protocol number.  This can be the same as the
+ *                          ip6_nxt field, but doesn't need to be.
+ * @param   cbPkt           The packet size (host endian of course).  This can
+ *                          be the same as the ip6_plen field, but as with @a
+ *                          bProtocol it won't be when extension headers are
+ *                          present.  For UDP this will be uh_ulen converted to
+ *                          host endian.
+ */
+static uint16_t computeIPv6FullChecksum(PCRTNETIPV6 pIpHdr)
+{
+    uint16_t const *data;
+    int len         = RT_BE2H_U16(pIpHdr->ip6_plen);
+    uint32_t sum    = RTNetIPv6PseudoChecksum(pIpHdr);
+
+    //add the payload
+    data = (uint16_t *) (pIpHdr + 1);
+    while(len > 1)
+    {
+        sum += *(data);
+        data++;
+        len -= 2;
+    }
+
+    if(len > 0)
+        sum += *((uint8_t *) data);
+
+    while(sum >> 16)
+        sum = (sum & 0xffff) + (sum >> 16);
+
+    return (uint16_t) ~sum;
+}
 
 /**
  * Sends a frame down the trunk.
@@ -2765,9 +2906,51 @@
                 pArp->ar_tha = pThis->MacAddr;
             }
         }
-        //else if (pSG->fFlags & INTNETSG_FLAGS_ICMPV6_NDP)
-        //{ /// @todo move the editing into a different function
-        //}
+        else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
+        { 
+            /*
+             * IPV6 ICMP Neighbor Discovery : replace 
+             * 1) the advertised source mac address in outgoing neighbor sollicitations
+             *    with the HW MAC address of the trunk interface,
+             * 2) the advertised target mac address in outgoing neighbor advertisements
+             *    with the HW mac address of the trunk interface.
+             *
+             * Note that this only applies to traffic going out on the trunk. Incoming
+             * NS/NA will never advertise any VM mac address, so we do not need to touch
+             * them. Other VMs on this bridge as well as the host will see and use the VM's 
+             * actual mac addresses.
+             *
+             */
+
+            PRTNETIPV6 pIPv6            = (PRTNETIPV6)(pEthHdr + 1);
+            PRTNETNDP pNd               = (PRTNETNDP)(pIPv6 + 1); 
+            PRTNETNDP_SLLA_OPT pLLAOpt  = (PRTNETNDP_SLLA_OPT)(pNd + 1); 
+
+            //make sure we have enough bytes to work with
+            if(pSG->cbTotal >= (RTNETIPV6_MIN_LEN + RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN) &&
+                //ensure the packet came from our LAN (not gone through any router)
+                pIPv6->ip6_hlim == 0xff &&
+                //protocol has to be icmpv6
+                pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 && 
+                //we either have a sollicitation with source link layer addr. opt, or
+                ((pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE &&
+                            pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 &&
+                            pLLAOpt->type == RTNETIPV6_ICMP_ND_SLLA_OPT) ||
+                //an advertisement with target link layer addr. option
+                ((pNd->icmp6_type == RTNETIPV6_ICMP_NA_TYPE &&
+                            pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 &&
+                            pLLAOpt->type == RTNETIPV6_ICMP_ND_TLLA_OPT)) ) &&
+                pLLAOpt->len == RTNETIPV6_ICMP_ND_LLA_LEN)
+            {
+                //swap the advertised VM MAC address with the trunk's
+                pLLAOpt->slla   = pThis->MacAddr;
+
+                //recompute the checksum since we changed the packet
+                pNd->icmp6_cksum = 0;
+                pNd->icmp6_cksum = computeIPv6FullChecksum(pIPv6);
+            }
+            
+        }
     }
 
     /*
@@ -2791,6 +2974,52 @@
 
 
 /**
+ * Snoops a multicast ICMPv6 ND DAD from the wire via the trunk connection.
+ *
+ * @param   pNetwork        The network the frame is being sent to.
+ * @param   pSG             Pointer to the gather list for the frame.
+ * @param   pEthHdr         Pointer to the ethernet header. 
+ */
+static void intnetR0NetworkSnoopNAFromWire(PINTNETNETWORK pNetwork, PINTNETSG pSG, PRTNETETHERHDR pEthHdr)
+{
+    /*
+     * Check the minimum size and get a linear copy of the thing to work on,
+     * using the temporary buffer if necessary.
+     */
+    if (RT_UNLIKELY(pSG->cbTotal < sizeof(RTNETETHERHDR) + sizeof(RTNETIPV6) + 
+                                            sizeof(RTNETNDP)))
+        return;
+    PRTNETIPV6 pIPv6 = (PRTNETIPV6)((uint8_t *)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR));
+    if (    pSG->cSegsUsed != 1
+        &&  pSG->aSegs[0].cb < sizeof(RTNETETHERHDR) + sizeof(RTNETIPV6) +
+                                                        sizeof(RTNETNDP))
+    {
+        Log6(("fw: Copying IPv6 pkt %u\n", sizeof(RTNETIPV6)));
+        if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), sizeof(RTNETIPV6)
+                                               + sizeof(RTNETNDP), pNetwork->pbTmp))
+            return;
+        pSG->fFlags |= INTNETSG_FLAGS_PKT_CP_IN_TMP;
+        pIPv6 = (PRTNETIPV6)pNetwork->pbTmp;
+    }
+
+    PCRTNETNDP pNd  = (PCRTNETNDP) (pIPv6 + 1);
+
+    //a multicast NS with :: as source address means a DAD packet.
+    //if it comes from the wire and we have the DAD'd address in our cache,
+    //flush the entry as the address is being acquired by someone else on
+    //the network.
+    if(     pIPv6->ip6_hlim == 0xff &&
+            pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 && 
+            pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE &&
+            pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 &&
+            pIPv6->ip6_src.u == 0)
+    {
+        
+        intnetR0NetworkAddrCacheDelete(pNetwork, (PCRTNETADDRU) &pNd->target_address, 
+                                        kIntNetAddrType_IPv6, sizeof(RTNETADDRIPV6), "tif/ip6");
+    }
+}
+/**
  * Edits an ARP packet arriving from the wire via the trunk connection.
  *
  * @param   pNetwork        The network the frame is being sent to.
@@ -3097,6 +3326,17 @@
         return INTNETSWDECISION_BAD_CONTEXT;
 
     /*
+     * Check for ICMPv6 Neighbor Advertisements coming from the trunk.
+     * If we see an advertisement for an IP in our cache, we can safely remove
+     * it as the IP has probably moved.
+     */
+    if (    (fSrc & INTNETTRUNKDIR_WIRE)
+        &&  RT_BE2H_U16(pEthHdr->EtherType) == RTNET_ETHERTYPE_IPV6
+        &&  pSG->GsoCtx.u8Type == PDMNETWORKGSOTYPE_INVALID)
+        intnetR0NetworkSnoopNAFromWire(pNetwork, pSG, pEthHdr);
+
+
+    /*
      * Check for ARP packets from the wire since we'll have to make
      * modification to them if we're sharing the MAC address with the host.
      */
@@ -3174,8 +3414,7 @@
             Log6(("intnetshareduni: IPv4 %d.%d.%d.%d\n", Addr.au8[0], Addr.au8[1], Addr.au8[2], Addr.au8[3]));
             break;
 
-#if 0 /** @todo IntNet: implement IPv6 for wireless MAC sharing. */
-        case RTNET_ETHERTYPE_IPV6
+        case RTNET_ETHERTYPE_IPV6:
             if (RT_UNLIKELY(!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR) + RT_OFFSETOF(RTNETIPV6, ip6_dst), sizeof(Addr.IPv6), &Addr)))
             {
                 Log(("intnetshareduni: failed to read ip6_dst! cbTotal=%#x\n", pSG->cbTotal));
@@ -3184,7 +3423,6 @@
             enmAddrType = kIntNetAddrType_IPv6;
             cbAddr = sizeof(Addr.IPv6);
             break;
-#endif
 #if 0 /** @todo IntNet: implement IPX for wireless MAC sharing? */
         case RTNET_ETHERTYPE_IPX_1:
         case RTNET_ETHERTYPE_IPX_2:
@@ -3379,7 +3617,7 @@
                     &&  !intnetR0IsMacAddrMulticast(&EthHdr.SrcMac)
                     ))
     {
-        Log2(("IF MAC: %.6Rhxs -> %.6Rhxs\n", &pIfSender->MacAddr, &EthHdr.SrcMac));
+        LogRel(("IF MAC: %.6Rhxs -> %.6Rhxs\n", &pIfSender->MacAddr, &EthHdr.SrcMac));
         RTSpinlockAcquire(pNetwork->hAddrSpinlock);
 
         PINTNETMACTABENTRY pIfEntry = intnetR0NetworkFindMacAddrEntry(pNetwork, pIfSender);
