VirtualBox

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


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

intnet: Implemented ARP snooping on the trunk. Fixed a couple of bugs (DHCP and other ARP snooping).

File:
1 edited

Legend:

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

    r11058 r11061  
    112112    struct INTNETIF        *pNext;
    113113    /** The current MAC address for the interface. */
    114     PDMMAC                  Mac;
     114    RTMAC                   Mac;
    115115    /** Set if the INTNET::Mac member is valid. */
    116116    bool                    fMacSet;
     
    254254    RTNETARPHDR     Hdr;
    255255    /** The sender hardware address. */
    256     PDMMAC          ar_sha;
     256    RTMAC           ar_sha;
    257257    /** The sender protocol address. */
    258258    RTNETADDRIPV6   ar_spa;
    259259    /** The target hardware address. */
    260     PDMMAC          ar_tha;
     260    RTMAC           ar_tha;
    261261    /** The arget protocol address. */
    262262    RTNETADDRIPV6   ar_tpa;
     
    267267/** Pointer to a const ethernet IPv6+MAC ARP request packet. */
    268268typedef INTNETARPIPV6 const *PCINTNETARPIPV6;
     269
     270
     271/*******************************************************************************
     272*   Defined Constants And Macros                                               *
     273*******************************************************************************/
     274/** Minimum length for ARP packets that we snoop. */
     275#define INTNET_ARP_MIN_LEN      sizeof(RTNETARPIPV4)
     276/** Maximum length for ARP packets that we snoop. */
     277#define INTNET_ARP_MAX_LEN      sizeof(INTNETARPIPV6)
    269278
    270279
     
    964973static void intnetR0TrunkIfSnoopDhcp(PINTNETNETWORK pNetwork, PCINTNETSG pSG)
    965974{
    966 
    967 }
    968 
     975}
     976
     977
     978/**
     979 * Snoops up source addresses from ARP requests and purge these
     980 * from the address caches.
     981 *
     982 * The purpose of this purging is to get rid of stale addresses.
     983 *
     984 * @param   pNetwork        The network the this frame was seen on.
     985 * @param   pSG             The gather list for the frame.
     986 */
    969987static void intnetR0TrunkIfSnoopArp(PINTNETNETWORK pNetwork, PCINTNETSG pSG)
    970988{
    971 
     989    /*
     990     * Check the minimum size first.
     991     */
     992    if (RT_UNLIKELY(pSG->cbTotal < INTNET_ARP_MIN_LEN))
     993        return;
     994
     995    /*
     996     * Copy to temporary buffer if necessary.
     997     */
     998    size_t cbPacket = RT_MIN(pSG->cbTotal, INTNET_ARP_MAX_LEN);
     999    PCRTNETARPHDR pHdr = (PCRTNETARPHDR)((uintptr_t)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR));
     1000    if (    pSG->cSegsUsed != 1
     1001        &&  pSG->aSegs[0].cb < cbPacket)
     1002    {
     1003        if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp))
     1004            return;
     1005        pHdr = (PCRTNETARPHDR)pNetwork->pbTmp;
     1006    }
     1007
     1008    /*
     1009     * Ignore malformed packets and packets which doesn't interest us.
     1010     */
     1011    if (RT_UNLIKELY(    pHdr->ar_hlen != sizeof(RTMAC)
     1012                    ||  pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)))
     1013        return;
     1014    uint16_t ar_oper = RT_H2BE_U16(pHdr->ar_oper);
     1015    if (RT_UNLIKELY(    ar_oper != RTNET_ARPOP_REQUEST
     1016                    &&  ar_oper != RTNET_ARPOP_REPLY
     1017                    &&  ar_oper != RTNET_ARPOP_REVREQUEST
     1018                    &&  ar_oper != RTNET_ARPOP_REVREPLY
     1019                    /** @todo Read up on inverse ARP. */
     1020                   ))
     1021        return;
     1022
     1023    /*
     1024     * Deal with the protocols.
     1025     */
     1026    RTNETADDRU Addr;
     1027    uint16_t ar_ptype = RT_H2BE_U16(pHdr->ar_ptype);
     1028    if (ar_ptype == RTNET_ETHERTYPE_IPV4)
     1029    {
     1030        /*
     1031         * IPv4.
     1032         */
     1033        PCRTNETARPIPV4 pReq = (PCRTNETARPIPV4)pHdr;
     1034        if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
     1035                        ||  cbPacket < sizeof(*pReq)
     1036                        ||  !intnetR0IPv4AddrIsGood(pReq->ar_spa)))
     1037            return;
     1038
     1039        Addr.IPv4 = pReq->ar_spa;
     1040        intnetR0NetworkAddrCacheDelete(pNetwork, &Addr, kIntNetAddrType_IPv4, sizeof(pReq->ar_spa));
     1041    }
     1042#if 0 /** @todo IPv6 support */
     1043    else if (ar_ptype == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
     1044    {
     1045        /*
     1046         * IPv6.
     1047         */
     1048        PCINTNETARPIPV6 pReq = (PCINTNETARPIPV6)pHdr;
     1049        if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
     1050                        ||  cbPacket < sizeof(*pReq)
     1051                        ||  !intnetR0IPv6AddrIsGood(&pReq->ar_spa)))
     1052            return;
     1053
     1054        Addr.IPv6 = pReq->ar_spa;
     1055        intnetR0NetworkAddrCacheDelete(pNetwork, &Addr, kIntNetAddrType_IPv6, sizeof(pReq->ar_spa));
     1056    }
     1057#endif
     1058    else
     1059        Log(("intnetR0TrunkIfSnoopArp: unknown ar_ptype=%#x\n", ar_ptype));
    9721060}
    9731061
     
    11071195     * Ignore malformed packets and packets which doesn't interest us.
    11081196     */
    1109     if (RT_UNLIKELY(    cbPacket <= sizeof(*pHdr)
    1110                     ||  pHdr->ar_hlen != sizeof(PDMMAC)
     1197    if (RT_UNLIKELY(    cbPacket <= INTNET_ARP_MIN_LEN
     1198                    ||  pHdr->ar_hlen != sizeof(RTMAC)
    11111199                    ||  pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER)))
    11121200        return;
     
    11311219         */
    11321220        PCRTNETARPIPV4 pReq = (PCRTNETARPIPV4)pHdr;
    1133         if (RT_UNLIKELY(    pHdr->ar_plen == sizeof(pReq->ar_spa)
     1221        if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
    11341222                        ||  cbPacket < sizeof(*pReq)
    11351223                        ||  !intnetR0IPv4AddrIsGood(pReq->ar_spa)))
     
    11521240         */
    11531241        PCINTNETARPIPV6 pReq = (PCINTNETARPIPV6)pHdr;
    1154         if (RT_UNLIKELY(    pHdr->ar_plen == sizeof(pReq->ar_spa)
     1242        if (RT_UNLIKELY(    pHdr->ar_plen != sizeof(pReq->ar_spa)
    11551243                        ||  cbPacket < sizeof(*pReq)
    11561244                        ||  !intnetR0IPv6AddrIsGood(&pReq->ar_spa)))
     
    12651353    AssertPtr(pRingBuf);
    12661354    AssertPtr(pSG);
    1267     Assert(pSG->cbTotal >= sizeof(PDMMAC) * 2);
     1355    Assert(pSG->cbTotal >= sizeof(RTMAC) * 2);
    12681356    uint32_t offWrite = pRingBuf->offWrite;
    12691357    Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR)));
     
    15271615        uint16_t EtherType = RT_BE2H_U16(pEthHdr->EtherType);
    15281616        if (    (   EtherType == RTNET_ETHERTYPE_IPV4       /* for DHCP */
    1529                  && pSG->cbTotal >= RTNETBOOTP_DHCP_MIN_LEN)
     1617                 && pSG->cbTotal >= sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN)
    15301618            ||  EtherType == RTNET_ETHERTYPE_ARP)
    15311619            intnetR0TrunkIfSnoopAddr(pNetwork, pSG, EtherType);
     
    16501738     */
    16511739    if (    enmAddrType == kIntNetAddrType_IPv4
    1652         &&  pSG->cbTotal >= RTNETBOOTP_DHCP_MIN_LEN)
     1740        &&  pSG->cbTotal >= sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN)
    16531741        intnetR0TrunkIfSnoopAddr(pNetwork, pSG, RT_BE2H_U16(pEthHdr->EtherType));
    16541742
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