VirtualBox

Changeset 14695

Show
Ignore:
Timestamp:
11/27/08 11:34:30 (1 month ago)
Author:
vboxsync
Message:

IntNet?: Quick hack to force broadcast flag in DHCP requests on shared MAC.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/iprt/net.h

    r11546 r14695  
    367367/** @} */ 
    368368 
     369/** @name DHCP Flags 
     370 * @{ */ 
     371#define RTNET_DHCP_FLAG_BROADCAST   0x8000 
     372/** @} */ 
     373 
    369374RTDECL(bool) RTNetIPv4IsDHCPValid(PCRTNETUDP pUdpHdr, PCRTNETBOOTP pDhcp, size_t cbDhcp, uint8_t *pMsgType); 
    370375 
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r14609 r14695  
    19571957 
    19581958/** 
     1959 * Detects and edits an DHCP packet arriving from the internal net. 
     1960 * 
     1961 * @param   pNetwork        The network the frame is being sent to. 
     1962 * @param   pSG             Pointer to the gather list for the frame. 
     1963 *                          The flags and data content may be updated. 
     1964 * @param   pEthHdr         Pointer to the ethernet header. This may also be 
     1965 *                          updated if it's a unicast... 
     1966 */ 
     1967static void intnetR0NetworkEditDhcpFromIntNet(PINTNETNETWORK pNetwork, PINTNETSG pSG, PRTNETETHERHDR pEthHdr) 
     1968{ 
     1969    /* 
     1970     * Check the minimum size and get a linear copy of the thing to work on, 
     1971     * using the temporary buffer if necessary. 
     1972     */ 
     1973    if (RT_UNLIKELY(pSG->cbTotal < sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN)) 
     1974        return; 
     1975    /* 
     1976     * Get a pointer to a linear copy of the full packet, using the 
     1977     * temporary buffer if necessary. 
     1978     */ 
     1979    PCRTNETIPV4 pIpHdr = (PCRTNETIPV4)((PCRTNETETHERHDR)pSG->aSegs[0].pv + 1); 
     1980    size_t cbPacket = pSG->cbTotal - sizeof(RTNETETHERHDR); 
     1981    if (pSG->cSegsUsed > 1) 
     1982    { 
     1983        cbPacket = RT_MIN(cbPacket, INTNETNETWORK_TMP_SIZE); 
     1984        Log6(("intnetR0NetworkEditDhcpFromIntNet: Copying IPv4/UDP/DHCP pkt %u\n", cbPacket)); 
     1985        if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp)) 
     1986            return; 
     1987        //pSG->fFlags |= INTNETSG_FLAGS_PKT_CP_IN_TMP; 
     1988        pIpHdr = (PCRTNETIPV4)pNetwork->pbTmp; 
     1989    } 
     1990 
     1991    /* 
     1992     * Validate the IP header and find the UDP packet. 
     1993     */ 
     1994    if (!RTNetIPv4IsHdrValid(pIpHdr, cbPacket, pSG->cbTotal - sizeof(RTNETETHERHDR))) 
     1995    { 
     1996        Log6(("intnetR0NetworkEditDhcpFromIntNet: bad ip header\n")); 
     1997        return; 
     1998    } 
     1999    size_t cbIpHdr = pIpHdr->ip_hl * 4; 
     2000    if (    pIpHdr->ip_p != RTNETIPV4_PROT_UDP                               /* DHCP is UDP. */ 
     2001        ||  cbPacket < cbIpHdr + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN) /* Min DHCP packet len */ 
     2002        return; 
     2003  
     2004    size_t cbUdpPkt = cbPacket - cbIpHdr; 
     2005    PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uintptr_t)pIpHdr + cbIpHdr); 
     2006    /* We are only interested in DHCP packets coming from client to server. */ 
     2007    if (    RT_BE2H_U16(pUdpHdr->uh_dport) != RTNETIPV4_PORT_BOOTPS 
     2008         || RT_BE2H_U16(pUdpHdr->uh_sport) != RTNETIPV4_PORT_BOOTPC) 
     2009        return; 
     2010 
     2011    /* 
     2012     * Check if the DHCP message is valid and get the type. 
     2013     */ 
     2014    if (!RTNetIPv4IsUDPValid(pIpHdr, pUdpHdr, pUdpHdr + 1, cbUdpPkt)) 
     2015    { 
     2016        Log6(("intnetR0NetworkEditDhcpFromIntNet: Bad UDP packet\n")); 
     2017        return; 
     2018    } 
     2019    PCRTNETBOOTP pDhcp = (PCRTNETBOOTP)(pUdpHdr + 1); 
     2020    uint8_t MsgType; 
     2021    if (!RTNetIPv4IsDHCPValid(pUdpHdr, pDhcp, cbUdpPkt - sizeof(*pUdpHdr), &MsgType)) 
     2022    { 
     2023        Log6(("intnetR0NetworkEditDhcpFromIntNet: Bad DHCP packet\n")); 
     2024        return; 
     2025    } 
     2026 
     2027    switch (MsgType) 
     2028    { 
     2029        case RTNET_DHCP_MT_DISCOVER: 
     2030        case RTNET_DHCP_MT_REQUEST: 
     2031            Log6(("intnetR0NetworkEditDhcpFromIntNet: Setting broadcast flag in DHCP %#x, previously %x\n", MsgType, pDhcp->bp_flags)); 
     2032            if (!(pDhcp->bp_flags & RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST))) 
     2033            { 
     2034                /* Patch flags */ 
     2035                uint16_t uFlags = pDhcp->bp_flags | RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST); 
     2036                intnetR0SgWritePart(pSG, (uint8_t*)&pDhcp->bp_flags - (uint8_t*)pIpHdr + sizeof(RTNETETHERHDR), sizeof(uFlags), &uFlags); 
     2037                /* Patch UDP checksum */ 
     2038                uint32_t uChecksum = (uint32_t)~pUdpHdr->uh_sum + RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST); 
     2039                while (uChecksum >> 16) 
     2040                    uChecksum = (uChecksum >> 16) + (uChecksum & 0xFFFF); 
     2041                uChecksum = ~uChecksum; 
     2042                intnetR0SgWritePart(pSG, (uint8_t*)&pUdpHdr->uh_sum - (uint8_t*)pIpHdr + sizeof(RTNETETHERHDR), sizeof(pUdpHdr->uh_sum), &uChecksum); 
     2043            } 
     2044            break; 
     2045    } 
     2046} 
     2047 
     2048 
     2049/** 
    19592050 * Sends a broadcast frame. 
    19602051 * 
     
    19812072        &&  RT_BE2H_U16(pEthHdr->EtherType) == RTNET_ETHERTYPE_ARP) 
    19822073        intnetR0NetworkEditArpFromWire(pNetwork, pSG, pEthHdr); 
     2074 
     2075     /* 
     2076     * Check for DHCP packets from the internal net since we'll have to set 
     2077     * broadcast flag in DHCP requests if we're sharing the MAC address with 
     2078     * the host. 
     2079     */ 
     2080    if (    (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 
     2081        &&  !fSrc 
     2082        &&  RT_BE2H_U16(pEthHdr->EtherType) == RTNET_ETHERTYPE_IPV4) 
     2083        intnetR0NetworkEditDhcpFromIntNet(pNetwork, pSG, pEthHdr); 
    19832084 
    19842085    /* 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy