VirtualBox

Ignore:
Timestamp:
Nov 19, 2018 11:52:10 AM (6 years ago)
Author:
vboxsync
Message:

Main/DHCPD: bugref:9288 Use new implementation of DHCP server (VCC 10 and older GCC support).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp

    r75513 r75568  
    2525
    2626#include <iprt/asm.h>
     27#include <iprt/file.h>
    2728#include <iprt/net.h>
     29#include <iprt/path.h>
    2830#include <iprt/cpp/utils.h>
     31#include <iprt/cpp/xml.h>
    2932
    3033#include <VBox/com/array.h>
     
    3841const std::string DHCPServerRunner::kDsrKeyLowerIp = "--lower-ip";
    3942const std::string DHCPServerRunner::kDsrKeyUpperIp = "--upper-ip";
     43const std::string DHCPServerRunner::kDsrKeyConfig  = "--config";
    4044
    4145
     
    4549        : enabled(FALSE)
    4650        , router(false)
    47     {}
     51    {
     52        tempConfigFileName[0] = '\0';
     53    }
    4854
    4955    Utf8Str IPAddress;
     
    5763    settings::DhcpOptionMap GlobalDhcpOptions;
    5864    settings::VmSlot2OptionsMap VmSlot2Options;
     65
     66    char tempConfigFileName[RTPATH_MAX];
     67    com::Utf8Str networkName;
     68    com::Utf8Str trunkName;
     69    com::Utf8Str trunkType;
    5970};
    6071
     
    98109    if (autoUninitSpan.uninitDone())
    99110        return;
     111
     112    if (m->dhcp.isRunning())
     113        stop();
    100114
    101115    unconst(mVirtualBox) = NULL;
     
    599613
    600614
     615DECLINLINE(void) addOptionChild(xml::ElementNode *pParent, uint32_t OptCode, const settings::DhcpOptValue &OptValue)
     616{
     617    xml::ElementNode *pOption = pParent->createChild("Option");
     618    pOption->setAttribute("name", OptCode);
     619    pOption->setAttribute("encoding", OptValue.encoding);
     620    pOption->setAttribute("value", OptValue.text.c_str());
     621}
     622
     623
     624HRESULT DHCPServer::restart()
     625{
     626    if (!m->dhcp.isRunning())
     627        return E_FAIL;
     628    /*
     629        * Disabled servers will be brought down, but won't be restarted.
     630        * (see DHCPServer::start)
     631        */
     632    HRESULT hrc = stop();
     633    if (SUCCEEDED(hrc))
     634        hrc = start(m->networkName, m->trunkName, m->trunkType);
     635    return hrc;
     636}
     637
     638
    601639HRESULT DHCPServer::start(const com::Utf8Str &aNetworkName,
    602640                          const com::Utf8Str &aTrunkName,
     
    607645        return S_OK;
    608646
     647    /*
     648     * @todo: the existing code cannot handle concurrent attempts to start DHCP server.
     649     * Note that technically it may receive different parameters from different callers.
     650     */
     651    m->networkName = aNetworkName;
     652    m->trunkName = aTrunkName;
     653    m->trunkType = aTrunkType;
     654
     655    m->dhcp.clearOptions();
     656#ifdef VBOX_WITH_DHCPD
     657    int rc = RTPathTemp(m->tempConfigFileName, sizeof(m->tempConfigFileName));
     658    if (RT_FAILURE(rc))
     659        return E_FAIL;
     660    rc = RTPathAppend(m->tempConfigFileName, sizeof(m->tempConfigFileName), "dhcp-config-XXXXX.xml");
     661    if (RT_FAILURE(rc))
     662    {
     663        m->tempConfigFileName[0] = '\0';
     664        return E_FAIL;
     665    }
     666    rc = RTFileCreateTemp(m->tempConfigFileName, 0600);
     667    if (RT_FAILURE(rc))
     668    {
     669        m->tempConfigFileName[0] = '\0';
     670        return E_FAIL;
     671    }
     672
     673    xml::Document doc;
     674    xml::ElementNode *pElmRoot = doc.createRootElement("DHCPServer");
     675    pElmRoot->setAttribute("networkName", m->networkName.c_str());
     676    if (!m->trunkName.isEmpty())
     677        pElmRoot->setAttribute("trunkName", m->trunkName.c_str());
     678    pElmRoot->setAttribute("trunkType", m->trunkType.c_str());
     679    pElmRoot->setAttribute("IPAddress",  Utf8Str(m->IPAddress).c_str());
     680    pElmRoot->setAttribute("networkMask", Utf8Str(m->GlobalDhcpOptions[DhcpOpt_SubnetMask].text).c_str());
     681    pElmRoot->setAttribute("lowerIP", Utf8Str(m->lowerIP).c_str());
     682    pElmRoot->setAttribute("upperIP", Utf8Str(m->upperIP).c_str());
     683
     684    /* Process global options */
     685    xml::ElementNode *pOptions = pElmRoot->createChild("Options");
     686    // settings::DhcpOptionMap::const_iterator itGlobal;
     687    for (settings::DhcpOptionMap::const_iterator it = m->GlobalDhcpOptions.begin();
     688         it != m->GlobalDhcpOptions.end();
     689         ++it)
     690        addOptionChild(pOptions, (*it).first, (*it).second);
     691
     692    /* Process network-adapter-specific options */
     693    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     694    HRESULT hrc = S_OK;
     695    ComPtr<IMachine> machine;
     696    ComPtr<INetworkAdapter> nic;
     697    settings::VmSlot2OptionsIterator it;
     698    for(it = m->VmSlot2Options.begin(); it != m->VmSlot2Options.end(); ++it)
     699    {
     700        alock.release();
     701        hrc = mVirtualBox->FindMachine(Bstr(it->first.VmName).raw(), machine.asOutParam());
     702        alock.acquire();
     703
     704        if (FAILED(hrc))
     705            continue;
     706
     707        alock.release();
     708        hrc = machine->GetNetworkAdapter(it->first.Slot, nic.asOutParam());
     709        alock.acquire();
     710
     711        if (FAILED(hrc))
     712            continue;
     713
     714        com::Bstr mac;
     715
     716        alock.release();
     717        hrc = nic->COMGETTER(MACAddress)(mac.asOutParam());
     718        alock.acquire();
     719
     720        if (FAILED(hrc)) /* no MAC address ??? */
     721            continue;
     722
     723        /* Convert MAC address from XXXXXXXXXXXX to XX:XX:XX:XX:XX:XX */
     724        Utf8Str strMacWithoutColons(mac);
     725        const char *pszSrc = strMacWithoutColons.c_str();
     726        RTMAC binaryMac;
     727        if (RTStrConvertHexBytes(pszSrc, &binaryMac, sizeof(binaryMac), 0) != VINF_SUCCESS)
     728            continue;
     729        char szMac[18]; /* "XX:XX:XX:XX:XX:XX" */
     730        if (RTStrPrintHexBytes(szMac, sizeof(szMac), &binaryMac, sizeof(binaryMac), RTSTRPRINTHEXBYTES_F_SEP_COLON) != VINF_SUCCESS)
     731            continue;
     732
     733        xml::ElementNode *pMacConfig = pElmRoot->createChild("Config");
     734        pMacConfig->setAttribute("MACAddress", szMac);
     735
     736        com::Utf8Str encodedOption;
     737        settings::DhcpOptionMap &map = i_findOptMapByVmNameSlot(it->first.VmName, it->first.Slot);
     738        settings::DhcpOptionMap::const_iterator itAdapterOption;
     739        for (itAdapterOption = map.begin(); itAdapterOption != map.end(); ++itAdapterOption)
     740            addOptionChild(pMacConfig, (*itAdapterOption).first, (*itAdapterOption).second);
     741    }
     742
     743    xml::XmlFileWriter writer(doc);
     744    writer.write(m->tempConfigFileName, true);
     745
     746    m->dhcp.setOption(DHCPServerRunner::kDsrKeyConfig, m->tempConfigFileName);
     747#else /* !VBOX_WITH_DHCPD */
    609748    /* Commmon Network Settings */
    610749    m->dhcp.setOption(NetworkServiceRunner::kNsrKeyNetwork, aNetworkName.c_str());
     
    628767    m->dhcp.setOption(DHCPServerRunner::kDsrKeyLowerIp, Utf8Str(m->lowerIP).c_str());
    629768    m->dhcp.setOption(DHCPServerRunner::kDsrKeyUpperIp, Utf8Str(m->upperIP).c_str());
     769#endif /* !VBOX_WITH_DHCPD */
    630770
    631771    /* XXX: This parameters Dhcp Server will fetch via API */
     
    637777HRESULT DHCPServer::stop (void)
    638778{
     779#ifdef VBOX_WITH_DHCPD
     780    if (m->tempConfigFileName[0])
     781    {
     782        RTFileDelete(m->tempConfigFileName);
     783        m->tempConfigFileName[0] = 0;
     784    }
     785#endif /* VBOX_WITH_DHCPD */
    639786    return RT_FAILURE(m->dhcp.stop()) ? E_FAIL : S_OK;
    640787}
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