VirtualBox

Changeset 11073 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Aug 2, 2008 1:34:26 AM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
33979
Message:

intnet: Cleaned up ARP snooping and editing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r11072 r11073  
    248248
    249249
    250 #pragma pack(1)
    251 /**
    252  * Ethernet IPv6 + 6-byte MAC ARP request packet.
    253  *
    254  * @todo check if this exists and is actually used.
    255  */
    256 typedef struct INTNETARPIPV6
    257 {
    258     RTNETARPHDR     Hdr;
    259     /** The sender hardware address. */
    260     RTMAC           ar_sha;
    261     /** The sender protocol address. */
    262     RTNETADDRIPV6   ar_spa;
    263     /** The target hardware address. */
    264     RTMAC           ar_tha;
    265     /** The arget protocol address. */
    266     RTNETADDRIPV6   ar_tpa;
    267 } INTNETARPIPV6;
    268 #pragma pack(0)
    269 /** Pointer to an ethernet IPv6+MAC ARP request packet. */
    270 typedef INTNETARPIPV6 *PINTNETARPIPV6;
    271 /** Pointer to a const ethernet IPv6+MAC ARP request packet. */
    272 typedef INTNETARPIPV6 const *PCINTNETARPIPV6;
    273 
    274 
    275 /*******************************************************************************
    276 *   Defined Constants And Macros                                               *
    277 *******************************************************************************/
    278 /** Minimum length for ARP packets that we snoop. */
    279 #define INTNET_ARP_MIN_LEN      sizeof(RTNETARPIPV4)
    280 /** Maximum length for ARP packets that we snoop. */
    281 #define INTNET_ARP_MAX_LEN      sizeof(INTNETARPIPV6)
    282 
    283250
    284251/*******************************************************************************
     
    834801static void intnetR0IfAddrCacheDeleteIt(PINTNETIF pIf, PINTNETADDRCACHE pCache, int iEntry, const char *pszMsg)
    835802{
    836 #if 0 /** @todo the inbound ARP snooping is busted. */
    837803    Log(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 type=%d #%d %.*Rhxs %s\n", pIf->hIf,
    838804         (int)(intptr_t)(pCache - &pIf->aAddrCache[0]), iEntry, pCache->cbAddress,
    839805         pCache->pbEntries + iEntry * pCache->cbEntry, pszMsg));
    840     Assert(iEntry < pCache->cEntries);
     806    AssertReturnVoid(iEntry < pCache->cEntries);
    841807    pCache->cEntries--;
    842808    if (iEntry < pCache->cEntries)
     
    844810                pCache->pbEntries + (iEntry + 1) * pCache->cbEntry,
    845811                (pCache->cEntries - iEntry)      * pCache->cbEntry);
    846 #endif
    847812}
    848813
     
    11051070static void intnetR0TrunkIfSnoopArp(PINTNETNETWORK pNetwork, PCINTNETSG pSG)
    11061071{
     1072Log6(("ts-ar: %#d\n", pSG->cbTotal));
     1073
    11071074    /*
    11081075     * Check the minimum size first.
    11091076     */
    1110     if (RT_UNLIKELY(pSG->cbTotal < INTNET_ARP_MIN_LEN))
     1077    if (RT_UNLIKELY(pSG->cbTotal < sizeof(RTNETETHERHDR) + sizeof(RTNETARPIPV4)))
    11111078        return;
    11121079
     
    11141081     * Copy to temporary buffer if necessary.
    11151082     */
    1116     size_t cbPacket = RT_MIN(pSG->cbTotal, INTNET_ARP_MAX_LEN);
    1117     PCRTNETARPHDR pHdr = (PCRTNETARPHDR)((uintptr_t)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR));
     1083    size_t cbPacket = RT_MIN(pSG->cbTotal, sizeof(RTNETARPIPV4));
     1084    PCRTNETARPIPV4 pArpIPv4 = (PCRTNETARPIPV4)((uintptr_t)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR));
    11181085    if (    pSG->cSegsUsed != 1
    11191086        &&  pSG->aSegs[0].cb < cbPacket)
    11201087    {
    1121         if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp))
    1122             return;
    1123         pHdr = (PCRTNETARPHDR)pNetwork->pbTmp;
    1124     }
    1125 
    1126     /*
    1127      * Ignore malformed packets and packets which doesn't interest us.
    1128      */
    1129     if (RT_UNLIKELY(    pHdr->ar_hlen != sizeof(RTMAC)
    1130                     ||  pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)))
     1088        if (        (pSG->fFlags & (INTNETSG_FLAGS_ARP_IPV4 | INTNETSG_FLAGS_PKT_CP_IN_TMP))
     1089                !=  (INTNETSG_FLAGS_ARP_IPV4 | INTNETSG_FLAGS_PKT_CP_IN_TMP)
     1090            && !intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp))
     1091                return;
     1092        pArpIPv4 = (PCRTNETARPIPV4)pNetwork->pbTmp;
     1093    }
     1094
     1095    /*
     1096     * Ignore packets which doesn't interest us or we perceive as malformed.
     1097     */
     1098    if (RT_UNLIKELY(    pArpIPv4->Hdr.ar_hlen  != sizeof(RTMAC)
     1099                    ||  pArpIPv4->Hdr.ar_plen  != sizeof(RTNETADDRIPV4)
     1100                    ||  pArpIPv4->Hdr.ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)
     1101                    ||  pArpIPv4->Hdr.ar_ptype != RT_H2BE_U16(RTNET_ETHERTYPE_IPV4)))
    11311102        return;
    1132     uint16_t ar_oper = RT_H2BE_U16(pHdr->ar_oper);
     1103    uint16_t ar_oper = RT_H2BE_U16(pArpIPv4->Hdr.ar_oper);
    11331104    if (RT_UNLIKELY(    ar_oper != RTNET_ARPOP_REQUEST
    1134                     &&  ar_oper != RTNET_ARPOP_REPLY
    1135                  /* These doesn't interest us at the moment since they are rarely used on ethernet:
    1136                     &&  ar_oper != RTNET_ARPOP_REVREQUEST
    1137                     &&  ar_oper != RTNET_ARPOP_REVREPLY
    1138                     &&  ar_oper != RTNET_ARPOP_INVREQUEST
    1139                     &&  ar_oper != RTNET_ARPOP_INVREPLY */
    1140                    ))
     1105                    &&  ar_oper != RTNET_ARPOP_REPLY))
     1106    {
     1107        Log6(("ts-ar: op=%#x\n", ar_oper));
    11411108        return;
    1142 
    1143     /*
    1144      * Deal with the protocols.
    1145      */
    1146     RTNETADDRU Addr;
    1147     uint16_t ar_ptype = RT_H2BE_U16(pHdr->ar_ptype);
    1148     if (ar_ptype == RTNET_ETHERTYPE_IPV4)
    1149     {
    1150         /*
    1151          * IPv4.
    1152          */
    1153         PCRTNETARPIPV4 pReq = (PCRTNETARPIPV4)pHdr;
    1154         if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
    1155                         ||  cbPacket < sizeof(*pReq)
    1156                         ||  !intnetR0IPv4AddrIsGood(pReq->ar_spa)))
    1157             return;
    1158 
    1159         Addr.IPv4 = pReq->ar_spa;
    1160         intnetR0NetworkAddrCacheDelete(pNetwork, &Addr, kIntNetAddrType_IPv4, sizeof(pReq->ar_spa), "tif/arp");
    1161     }
    1162 #if 0 /** @todo IPv6 ARP support? Is it used at all? */
    1163 #endif
    1164     else
    1165         Log(("intnetR0TrunkIfSnoopArp: unknown ar_ptype=%#x\n", ar_ptype));
     1109    }
     1110
     1111    /*
     1112     * Delete the source address if it's OK.
     1113     */
     1114    if (    !(pArpIPv4->ar_sha.au8[0] & 1)
     1115        &&  (   pArpIPv4->ar_sha.au16[0]
     1116             || pArpIPv4->ar_sha.au16[1]
     1117             || pArpIPv4->ar_sha.au16[2])
     1118        &&  intnetR0IPv4AddrIsGood(pArpIPv4->ar_spa))
     1119    {
     1120        Log6(("ts-ar: %d.%d.%d.%d / %.6Rhxs\n", pArpIPv4->ar_spa.au8[0], pArpIPv4->ar_spa.au8[1],
     1121              pArpIPv4->ar_spa.au8[2], pArpIPv4->ar_spa.au8[3], &pArpIPv4->ar_sha));
     1122        intnetR0NetworkAddrCacheDelete(pNetwork, (PCRTNETADDRU)&pArpIPv4->ar_spa,
     1123                                       kIntNetAddrType_IPv4, sizeof(pArpIPv4->ar_spa), "tif/arp");
     1124    }
    11661125}
    11671126
     
    12111170        }
    12121171
     1172        case RTNET_ETHERTYPE_IPV6:
     1173        {
     1174            /** @todo IPv6: Check for ICMPv6. It looks like type 133 (Router solicitation) might
     1175             * need to be edited. Check out how NDP works...  */
     1176            break;
     1177        }
     1178
    12131179        case RTNET_ETHERTYPE_ARP:
    12141180            intnetR0TrunkIfSnoopArp(pNetwork, pSG);
    12151181            break;
    12161182    }
    1217     /** @todo soon */
    12181183}
    12191184
     
    12981263 *                          don't have to repeat the frame parsing in intnetR0TrunkIfSend.
    12991264 */
    1300 static void intnetR0IfSnoopArpAddr(PINTNETIF pIf, PCRTNETARPHDR pHdr, uint32_t cbPacket, uint16_t *pfSgFlags)
    1301 {
    1302     /*
    1303      * Ignore malformed packets and packets which doesn't interest us.
    1304      */
    1305     if (RT_UNLIKELY(    cbPacket <= INTNET_ARP_MIN_LEN
    1306                     ||  pHdr->ar_hlen != sizeof(RTMAC)
    1307                     ||  pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)))
     1265static void intnetR0IfSnoopArpAddr(PINTNETIF pIf, PCRTNETARPIPV4 pArpIPv4, uint32_t cbPacket, uint16_t *pfSgFlags)
     1266{
     1267    /*
     1268     * Ignore packets which doesn't interest us or we perceive as malformed.
     1269     */
     1270    if (RT_UNLIKELY(cbPacket < sizeof(RTNETARPIPV4)))
    13081271        return;
    1309     uint16_t ar_oper = RT_H2BE_U16(pHdr->ar_oper);
     1272    if (RT_UNLIKELY(    pArpIPv4->Hdr.ar_hlen  != sizeof(RTMAC)
     1273                    ||  pArpIPv4->Hdr.ar_plen  != sizeof(RTNETADDRIPV4)
     1274                    ||  pArpIPv4->Hdr.ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)
     1275                    ||  pArpIPv4->Hdr.ar_ptype != RT_H2BE_U16(RTNET_ETHERTYPE_IPV4)))
     1276        return;
     1277    uint16_t ar_oper = RT_H2BE_U16(pArpIPv4->Hdr.ar_oper);
    13101278    if (RT_UNLIKELY(    ar_oper != RTNET_ARPOP_REQUEST
    1311                     &&  ar_oper != RTNET_ARPOP_REPLY
    1312                  /* These doesn't interest us at the moment since they are rarely used on ethernet:
    1313                     &&  ar_oper != RTNET_ARPOP_REVREQUEST
    1314                     &&  ar_oper != RTNET_ARPOP_REVREPLY
    1315                     &&  ar_oper != RTNET_ARPOP_INVREQUEST
    1316                     &&  ar_oper != RTNET_ARPOP_INVREPLY */
    1317                    ))
     1279                    &&  ar_oper != RTNET_ARPOP_REPLY))
     1280    {
     1281        Log6(("ar_oper=%#x\n", ar_oper));
    13181282        return;
    1319 
    1320     /*
    1321      * Deal with the protocols.
    1322      */
    1323     RTNETADDRU Addr;
    1324     uint16_t ar_ptype = RT_H2BE_U16(pHdr->ar_ptype);
    1325     if (ar_ptype == RTNET_ETHERTYPE_IPV4)
    1326     {
    1327         /*
    1328          * IPv4.
    1329          */
    1330         PCRTNETARPIPV4 pReq = (PCRTNETARPIPV4)pHdr;
    1331         if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
    1332                         ||  cbPacket < sizeof(*pReq)))
    1333             return;
    1334         *pfSgFlags |= INTNETSG_FLAGS_ARP_IPV4;
    1335 /** @todo should check the MAC addresses here. */
    1336         if (    RTNET_ARPOP_IS_REPLY(ar_oper)
    1337             &&  intnetR0IPv4AddrIsGood(pReq->ar_tpa))
    1338         {
    1339             Addr.IPv4 = pReq->ar_tpa;
    1340             intnetR0IfAddrCacheDelete(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_tpa), "if/arp");
    1341         }
    1342         if (intnetR0IPv4AddrIsGood(pReq->ar_spa))
    1343         {
    1344             Addr.IPv4 = pReq->ar_spa;
    1345             intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_spa), "if/arp");
    1346         }
    1347     }
    1348 #if 0 /** @todo IPv6 ARP support? Is it used at all? */
    1349 #endif
    1350     else
    1351         Log(("intnetR0IfSnoopArpSourceAddr: unknown ar_ptype=%#x\n", ar_ptype));
     1283    }
     1284
     1285    /*
     1286     * Tag the SG as ARP IPv4 for later editing, then check for addresses
     1287     * which can be removed or added to the address cache of the sender.
     1288     */
     1289    *pfSgFlags |= INTNETSG_FLAGS_ARP_IPV4;
     1290
     1291    if (    ar_oper == RTNET_ARPOP_REPLY
     1292        &&  !(pArpIPv4->ar_tha.au8[0] & 1)
     1293        &&  (   pArpIPv4->ar_tha.au16[0]
     1294             || pArpIPv4->ar_tha.au16[1]
     1295             || pArpIPv4->ar_tha.au16[2])
     1296        &&  intnetR0IPv4AddrIsGood(pArpIPv4->ar_tpa))
     1297        intnetR0IfAddrCacheDelete(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4],
     1298                                  (PCRTNETADDRU)&pArpIPv4->ar_tpa, sizeof(RTNETADDRIPV4), "if/arp");
     1299
     1300    if (    !memcmp(&pArpIPv4->ar_sha, &pIf->Mac, sizeof(RTMAC))
     1301        &&  intnetR0IPv4AddrIsGood(pArpIPv4->ar_spa))
     1302        intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4],
     1303                               (PCRTNETADDRU)&pArpIPv4->ar_spa, sizeof(RTNETADDRIPV4), "if/arp");
    13521304}
    13531305
     
    13811333#if 0 /** @todo IntNet: implement IPv6 for wireless MAC sharing. */
    13821334        case RTNET_ETHERTYPE_IPV6:
    1383             intnetR0IfSnoopIPv6SourceAddr(pIf, (PCINTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame);
     1335            /** @todo IPv6: Check for ICMPv6. It looks like type 133 (Router solicitation) might
     1336             * need to be edited. Check out how NDP works...  */
     1337            intnetR0IfSnoopIPv6SourceAddr(pIf, (PCINTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, pfSgFlags);
    13841338            break;
    13851339#endif
     
    13881342        case RTNET_ETHERTYPE_IPX_2:
    13891343        case RTNET_ETHERTYPE_IPX_3:
    1390             intnetR0IfSnoopIpxSourceAddr(pIf, (PCINTNETIPX)((PCRTNETETHERHDR)pbFrame + 1), cbFrame);
     1344            intnetR0IfSnoopIpxSourceAddr(pIf, (PCINTNETIPX)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, pfSgFlags);
    13911345            break;
    13921346#endif
    13931347        case RTNET_ETHERTYPE_ARP:
    1394             intnetR0IfSnoopArpAddr(pIf, (PCRTNETARPHDR)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, pfSgFlags);
     1348            intnetR0IfSnoopArpAddr(pIf, (PCRTNETARPIPV4)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, pfSgFlags);
    13951349            break;
    13961350    }
     
    16251579
    16261580    /*
    1627      * Do frame modifications when sharing MAC address on the wire.
     1581     * Edit the frame if we're sharing the MAC address with the host on the wire.
    16281582     *
    1629      * If the frame is headed for both the host and the wire, we'll
    1630      * have to send it to the host before making any modifications,
    1631      * and force a copy of the frame.
     1583     * If the frame is headed for both the host and the wire, we'll have to send
     1584     * it to the host before making any modifications, and force the OS specific
     1585     * backend to copy it. We do this by marking it as TEMP (which is always the
     1586     * case right now).
    16321587     */
    16331588    if (    (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
     
    16531608         *
    16541609         * The reason for caching it in the trunk structure is because
    1655          * we cannot take the trunk out-bound semaphore when we handle
    1656          * stuff like ARP replies from the wire.
     1610         * we cannot take the trunk out-bound semaphore when we make
     1611         * edits in the intnetR0TrunkIfPortRecv path.
    16571612         */
    16581613        pThis->pIfPort->pfnGetMacAddress(pThis->pIfPort, &pThis->CachedMac);
     
    16651620        if (pSG->fFlags & INTNETSG_FLAGS_ARP_IPV4)
    16661621        {
     1622            /*
     1623             * APR IPv4: replace hardware (MAC) addresses because these end up
     1624             *           in ARP caches. So, if we don't the other machiens will
     1625             *           send the packets to the MAC address of the guest
     1626             *           instead of the one of the host, which won't work on
     1627             *           wireless of course...
     1628             */
    16671629            PRTNETARPIPV4 pArp = (PRTNETARPIPV4)(pEthHdr + 1);
    16681630            if (!memcmp(&pArp->ar_sha, &pIfSender->Mac, sizeof(RTMAC)))
     
    16771639            }
    16781640        }
     1641        //else if (pSG->fFlags & INTNETSG_FLAGS_ICMPV6_NDP)
     1642        //{ /// @todo move the editing into a different function
     1643        //}
    16791644    }
    16801645
     
    17441709{
    17451710    /*
    1746      * Check the minimum size first.
    1747      */
    1748     if (RT_UNLIKELY(pSG->cbTotal < INTNET_ARP_MIN_LEN))
     1711     * Check the minimum size and get a linear copy of the thing to work on,
     1712     * using the temporary buffer if necessary.
     1713     */
     1714    if (RT_UNLIKELY(pSG->cbTotal < sizeof(RTNETETHERHDR) + sizeof(RTNETARPIPV4)))
    17491715        return;
    1750 
    1751     /*
    1752      * Copy to temporary buffer if necessary.
    1753      */
    1754     size_t  cbPacket = RT_MIN(pSG->cbTotal, INTNET_ARP_MAX_LEN);
    1755     PCRTNETARPHDR pHdr = (PCRTNETARPHDR)((uintptr_t)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR));
     1716    PRTNETARPIPV4 pArpIPv4 = (PRTNETARPIPV4)((uint8_t *)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR));
    17561717    if (    pSG->cSegsUsed != 1
    1757         &&  pSG->aSegs[0].cb < cbPacket)
    1758     {
    1759         Log6(("fw: Copying ARP pkt %u\n", cbPacket));
    1760         if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp))
     1718        &&  pSG->aSegs[0].cb < sizeof(RTNETETHERHDR) + sizeof(RTNETARPIPV4))
     1719    {
     1720        Log6(("fw: Copying ARP pkt %u\n", sizeof(RTNETARPIPV4)));
     1721        if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), sizeof(RTNETARPIPV4), pNetwork->pbTmp))
    17611722            return;
    1762         pHdr = (PCRTNETARPHDR)pNetwork->pbTmp;
    17631723        pSG->fFlags |= INTNETSG_FLAGS_PKT_CP_IN_TMP;
    1764     }
    1765 
    1766     /*
    1767      * Ignore malformed packets and packets which doesn't interest us.
    1768      */
    1769     if (RT_UNLIKELY(    pHdr->ar_hlen != sizeof(RTMAC)
    1770                     ||  pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)))
     1724        pArpIPv4 = (PRTNETARPIPV4)pNetwork->pbTmp;
     1725    }
     1726
     1727    /*
     1728     * Ignore packets which doesn't interest us or we perceive as malformed.
     1729     */
     1730    if (RT_UNLIKELY(    pArpIPv4->Hdr.ar_hlen  != sizeof(RTMAC)
     1731                    ||  pArpIPv4->Hdr.ar_plen  != sizeof(RTNETADDRIPV4)
     1732                    ||  pArpIPv4->Hdr.ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)
     1733                    ||  pArpIPv4->Hdr.ar_ptype != RT_H2BE_U16(RTNET_ETHERTYPE_IPV4)))
    17711734        return;
    1772     uint16_t ar_oper = RT_H2BE_U16(pHdr->ar_oper);
     1735    uint16_t ar_oper = RT_H2BE_U16(pArpIPv4->Hdr.ar_oper);
    17731736    if (RT_UNLIKELY(    ar_oper != RTNET_ARPOP_REQUEST
    1774                     &&  ar_oper != RTNET_ARPOP_REPLY
    1775                  /* These doesn't interest us at the moment since they are rarely used on ethernet:
    1776                     &&  ar_oper != RTNET_ARPOP_REVREQUEST
    1777                     &&  ar_oper != RTNET_ARPOP_REVREPLY
    1778                     &&  ar_oper != RTNET_ARPOP_INVREQUEST
    1779                     &&  ar_oper != RTNET_ARPOP_INVREPLY */
    1780                    ))
     1737                    &&  ar_oper != RTNET_ARPOP_REPLY))
     1738    {
     1739        Log6(("ar_oper=%#x\n", ar_oper));
    17811740        return;
    1782 
    1783     /*
    1784      * Deal with the protocols.
    1785      *
    1786      * The thing we're interested in here is a reply to a query
    1787      * made by a guest since we've modified the MAC in the initial
    1788      * request the guest made.
    1789      */
    1790     bool fModified = false;
    1791     uint16_t ar_ptype = RT_H2BE_U16(pHdr->ar_ptype);
    1792     if (ar_ptype == RTNET_ETHERTYPE_IPV4)
    1793     {
    1794         /*
    1795          * IPv4.
    1796          */
    1797         PRTNETARPIPV4 pReq = (PRTNETARPIPV4)pHdr;
    1798         if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
    1799                         ||  cbPacket < sizeof(*pReq)))
    1800             return;
    1801         pSG->fFlags |= INTNETSG_FLAGS_ARP_IPV4;
    1802         if (    ar_oper == RTNET_ARPOP_REPLY
    1803             &&  !memcmp(&pReq->ar_tha, &pNetwork->pTrunkIF->CachedMac, sizeof(RTMAC)))
     1741    }
     1742
     1743    /* Tag it as ARP IPv4. */
     1744    pSG->fFlags |= INTNETSG_FLAGS_ARP_IPV4;
     1745
     1746    /*
     1747     * The thing we're interested in here is a reply to a query made by a guest
     1748     * since we modified the MAC in the initial request the guest made.
     1749     */
     1750    if (    ar_oper == RTNET_ARPOP_REPLY
     1751        &&  !memcmp(&pArpIPv4->ar_tha, &pNetwork->pTrunkIF->CachedMac, sizeof(RTMAC)))
     1752    {
     1753        PINTNETIF pIf = intnetR0NetworkAddrCacheLookupIf(pNetwork, (PCRTNETADDRU)&pArpIPv4->ar_tpa,
     1754                                                         kIntNetAddrType_IPv4, sizeof(pArpIPv4->ar_tpa));
     1755        if (pIf)
    18041756        {
    1805             PINTNETIF pIf = intnetR0NetworkAddrCacheLookupIf(pNetwork, (PCRTNETADDRU)&pReq->ar_tpa,
    1806                                                              kIntNetAddrType_IPv4, sizeof(pReq->ar_tpa));
    1807             if (pIf)
     1757            Log6(("fw: ar_tha %.6Rhxs -> %.6Rhxs\n", &pArpIPv4->ar_tha, &pIf->Mac));
     1758            pArpIPv4->ar_tha = pIf->Mac;
     1759            if (!memcmp(&pEthHdr->DstMac, &pNetwork->pTrunkIF->CachedMac, sizeof(RTMAC)))
    18081760            {
    1809                 Log6(("fw: ar_tha %.6Rhxs -> %.6Rhxs\n", &pReq->ar_tha, &pIf->Mac));
    1810                 pReq->ar_tha = pIf->Mac;
    1811                 if (!memcmp(&pEthHdr->DstMac, &pNetwork->pTrunkIF->CachedMac, sizeof(RTMAC)))
    1812                 {
    1813                     Log6(("fw: DstMac %.6Rhxs -> %.6Rhxs\n", &pEthHdr->DstMac, &pIf->Mac));
    1814                     pEthHdr->DstMac = pIf->Mac;
    1815                     if ((void *)pEthHdr != pSG->aSegs[0].pv)
    1816                         intnetR0SgWritePart(pSG, RT_OFFSETOF(RTNETETHERHDR, DstMac), sizeof(RTMAC), &pIf->Mac);
    1817                 }
    1818 
    1819                 fModified = true;
     1761                Log6(("fw: DstMac %.6Rhxs -> %.6Rhxs\n", &pEthHdr->DstMac, &pIf->Mac));
     1762                pEthHdr->DstMac = pIf->Mac;
     1763                if ((void *)pEthHdr != pSG->aSegs[0].pv)
     1764                    intnetR0SgWritePart(pSG, RT_OFFSETOF(RTNETETHERHDR, DstMac), sizeof(RTMAC), &pIf->Mac);
    18201765            }
     1766
     1767            /* Write back the packet if we've been making changes to a buffered copy. */
     1768            if (pSG->fFlags & INTNETSG_FLAGS_PKT_CP_IN_TMP)
     1769                intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR), sizeof(PRTNETARPIPV4), pArpIPv4);
    18211770        }
    18221771    }
    1823 #if 0 /** @todo IPv6 support, does it use ARP at all? */
    1824 #endif
    1825     else
    1826         Log(("intnetR0TrunkIfSnoopArp: unknown ar_ptype=%#x\n", ar_ptype));
    1827 
    1828     /*
    1829      * Write back the packet if we've been making changes
    1830      * to a buffered copy.
    1831      */
    1832     if (    (pSG->fFlags & INTNETSG_FLAGS_PKT_CP_IN_TMP)
    1833         && fModified)
    1834         intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR), cbPacket, pHdr);
    18351772}
    18361773
     
    19821919        case RTNET_ETHERTYPE_ARP:
    19831920            Log6(("intnetshareduni: ARP\n"));
     1921            /** @todo revisit this broadcasting of unicast ARP frames! */
    19841922            return intnetR0NetworkSendBroadcast(pNetwork, NULL, INTNETTRUNKDIR_WIRE, pSG, fTrunkLocked, pEthHdr);
    19851923
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette