VirtualBox

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


Ignore:
Timestamp:
Nov 27, 2008 10:34:30 AM (16 years ago)
Author:
vboxsync
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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    /*
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