Changeset 14695 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Nov 27, 2008 10:34:30 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r14609 r14695 1957 1957 1958 1958 /** 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 */ 1967 static 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 /** 1959 2050 * Sends a broadcast frame. 1960 2051 * … … 1981 2072 && RT_BE2H_U16(pEthHdr->EtherType) == RTNET_ETHERTYPE_ARP) 1982 2073 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); 1983 2084 1984 2085 /*
Note:
See TracChangeset
for help on using the changeset viewer.