VirtualBox

Changeset 37979 in vbox


Ignore:
Timestamp:
Jul 15, 2011 2:04:24 PM (14 years ago)
Author:
vboxsync
Message:

IntNet: Work around DHCP issue on Mac OS X Lion GM when bridging wireless connections (ip_tos is cleared by someone and the checksum is written as little endian).

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/intnet.h

    r36075 r37979  
    906906#define INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE               RT_BIT_32(26)
    907907
     908/** Used to enable host specific workarounds.
     909 *
     910 * On darwin this will clear ip_tos in DHCP packets when
     911 * INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE is also set. */
     912#define INTNET_OPEN_FLAGS_WORKAROUND_1                          RT_BIT_32(31)
     913
    908914
    909915/** The mask of valid flags. */
    910 #define INTNET_OPEN_FLAGS_MASK                                  UINT32_C(0x03ffffff)
     916#define INTNET_OPEN_FLAGS_MASK                                  UINT32_C(0x83ffffff)
    911917/** The mask of all flags use to fix (lock) settings. */
    912918#define INTNET_OPEN_FLAGS_FIXED_MASK \
  • trunk/src/VBox/Devices/Network/DrvIntNet.cpp

    r36085 r37979  
    4242#include <iprt/thread.h>
    4343#include <iprt/uuid.h>
     44#if defined(RT_OS_DARWIN) && defined(IN_RING3)
     45# include <iprt/system.h>
     46#endif
    4447
    4548#include "VBoxDD.h"
     
    13581361                                  "|TrunkPolicyWire"
    13591362                                  "|IsService"
    1360                                   "|IgnoreConnectFailure",
     1363                                  "|IgnoreConnectFailure"
     1364                                  "|Workaround1",
    13611365                                  "");
    13621366
     
    16001604        return PDMDRV_SET_ERROR(pDrvIns, rc,
    16011605                                N_("Configuration error: Failed to get the \"IgnoreConnectFailure\" value"));
     1606
     1607    /** @cfgm{Workaround1, boolean, depends}
     1608     * Enables host specific workarounds, the default is depends on the whether
     1609     * we think the host requires it or not.
     1610     */
     1611    bool fWorkaround1 = false;
     1612#ifdef RT_OS_DARWIN
     1613    if (OpenReq.fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
     1614    {
     1615        char szKrnlVer[256];
     1616        RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szKrnlVer, sizeof(szKrnlVer));
     1617        if (strcmp(szKrnlVer, "10.7.0") >= 0)
     1618        {
     1619            LogRel(("IntNet#%u: Enables the workaround (ip_tos=0) for the little endian ip header checksum problem\n"));
     1620            fWorkaround1 = true;
     1621        }
     1622    }
     1623#endif
     1624    rc = CFGMR3QueryBoolDef(pCfg, "Workaround1", &fWorkaround1, fWorkaround1);
     1625    if (RT_FAILURE(rc))
     1626        return PDMDRV_SET_ERROR(pDrvIns, rc,
     1627                                N_("Configuration error: Failed to get the \"Workaround1\" value"));
     1628    if (fWorkaround1)
     1629        OpenReq.fFlags |= INTNET_OPEN_FLAGS_WORKAROUND_1;
    16021630
    16031631    LogRel(("IntNet#%u: szNetwork={%s} enmTrunkType=%d szTrunk={%s} fFlags=%#x cbRecv=%u cbSend=%u fIgnoreConnectFailure=%RTbool\n",
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r37909 r37979  
    29492949    }
    29502950    PCRTNETBOOTP pDhcp = (PCRTNETBOOTP)(pUdpHdr + 1);
    2951     uint8_t MsgType;
    2952     if (!RTNetIPv4IsDHCPValid(pUdpHdr, pDhcp, cbUdpPkt - sizeof(*pUdpHdr), &MsgType))
     2951    uint8_t bMsgType;
     2952    if (!RTNetIPv4IsDHCPValid(pUdpHdr, pDhcp, cbUdpPkt - sizeof(*pUdpHdr), &bMsgType))
    29532953    {
    29542954        Log6(("intnetR0NetworkEditDhcpFromIntNet: Bad DHCP packet\n"));
     
    29562956    }
    29572957
    2958     switch (MsgType)
     2958    switch (bMsgType)
    29592959    {
    29602960        case RTNET_DHCP_MT_DISCOVER:
    29612961        case RTNET_DHCP_MT_REQUEST:
    2962             Log6(("intnetR0NetworkEditDhcpFromIntNet: Setting broadcast flag in DHCP %#x, previously %x\n", MsgType, pDhcp->bp_flags));
     2962            /*
     2963             * Must set the broadcast flag or we won't catch the respons.
     2964             */
    29632965            if (!(pDhcp->bp_flags & RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST)))
    29642966            {
     2967                Log6(("intnetR0NetworkEditDhcpFromIntNet: Setting broadcast flag in DHCP %#x, previously %x\n",
     2968                      bMsgType, pDhcp->bp_flags));
     2969
    29652970                /* Patch flags */
    29662971                uint16_t uFlags = pDhcp->bp_flags | RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST);
    29672972                intnetR0SgWritePart(pSG, (uintptr_t)&pDhcp->bp_flags - (uintptr_t)pIpHdr + sizeof(RTNETETHERHDR), sizeof(uFlags), &uFlags);
     2973
    29682974                /* Patch UDP checksum */
    29692975                uint32_t uChecksum = (uint32_t)~pUdpHdr->uh_sum + RT_H2BE_U16_C(RTNET_DHCP_FLAG_BROADCAST);
     
    29732979                intnetR0SgWritePart(pSG, (uintptr_t)&pUdpHdr->uh_sum - (uintptr_t)pIpHdr + sizeof(RTNETETHERHDR), sizeof(pUdpHdr->uh_sum), &uChecksum);
    29742980            }
     2981
     2982#ifdef RT_OS_DARWIN
     2983            /*
     2984             * Work around little endian checksum issue in mac os x 10.7.0 GM.
     2985             */
     2986            if (   pIpHdr->ip_tos
     2987                && (pNetwork->fFlags & INTNET_OPEN_FLAGS_WORKAROUND_1))
     2988            {
     2989                /* Patch it. */
     2990                uint8_t uTos  = pIpHdr->ip_tos;
     2991                uint8_t uZero = 0;
     2992                intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR) + 1, sizeof(uZero), &uZero);
     2993
     2994                /* Patch the IP header checksum. */
     2995                uint32_t uChecksum = (uint32_t)~pIpHdr->ip_sum - (uTos << 8);
     2996                while (uChecksum >> 16)
     2997                    uChecksum = (uChecksum >> 16) + (uChecksum & 0xFFFF);
     2998                uChecksum = ~uChecksum;
     2999
     3000                Log(("intnetR0NetworkEditDhcpFromIntNet: cleared ip_tos (was %#04x); ip_sum=%#06x -> %#06x\n",
     3001                     uTos, RT_BE2H_U16(pIpHdr->ip_sum), RT_BE2H_U16(uChecksum) ));
     3002                intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR) + RT_OFFSETOF(RTNETIPV4, ip_sum),
     3003                                    sizeof(pIpHdr->ip_sum), &uChecksum);
     3004            }
     3005#endif
    29753006            break;
    29763007    }
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