VirtualBox

Changeset 47018 in vbox for trunk


Ignore:
Timestamp:
Jul 6, 2013 5:31:11 PM (12 years ago)
Author:
vboxsync
Message:

Main: re-commit r86967
Main/Network: DHCP server has got the ear in Main, and we able create/describe more complex infrostructures. DHCP server together with Lwip NAT can handle per vm/slot configuration and store them in xml settings.
place-holder: Host interface nameserver list, domain name and search strings, I suppose that this functions should be used on initialization stage and then on host configuration change even or directly from event.

Location:
trunk
Files:
13 edited
2 moved

Legend:

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

    r46969 r47018  
    286286typedef std::list<MachineRegistryEntry> MachinesRegistry;
    287287
     288typedef std::map<DhcpOpt_T, com::Utf8Str> DhcpOptionMap;
     289typedef DhcpOptionMap::value_type DhcpOptValuePair;
     290typedef DhcpOptionMap::iterator DhcpOptIterator;
     291typedef DhcpOptionMap::const_iterator DhcpOptConstIterator;
     292
     293typedef struct VmNameSlotKey
     294{
     295    VmNameSlotKey(const com::Utf8Str& aVmName, LONG aSlot): VmName(aVmName),
     296      Slot(aSlot){}
     297    const com::Utf8Str VmName;
     298    LONG      Slot;
     299    bool operator< (const VmNameSlotKey& that) const
     300    {
     301        if (VmName == that.VmName)
     302            return Slot < that.Slot;
     303        else return VmName < that.VmName;
     304    }
     305} VmNameSlotKey;
     306typedef std::map<VmNameSlotKey, DhcpOptionMap> VmSlot2OptionsMap;
     307typedef VmSlot2OptionsMap::value_type VmSlot2OptionsPair;
     308typedef VmSlot2OptionsMap::iterator VmSlot2OptionsIterator;
     309typedef VmSlot2OptionsMap::const_iterator VmSlot2OptionsConstIterator;
     310
    288311struct DHCPServer
    289312{
     
    294317    com::Utf8Str    strNetworkName,
    295318                    strIPAddress,
    296                     strIPNetworkMask,
    297319                    strIPLower,
    298320                    strIPUpper;
    299321    bool            fEnabled;
     322    std::map<DhcpOpt_T, com::Utf8Str>  GlobalDhcpOptions;
     323    VmSlot2OptionsMap VmSlot2OptionsM;
    300324};
    301325typedef std::list<DHCPServer> DHCPServersList;
     
    337361    void readMachineRegistry(const xml::ElementNode &elmMachineRegistry);
    338362    void readDHCPServers(const xml::ElementNode &elmDHCPServers);
     363    void readDhcpOptions(DhcpOptionMap& map, const xml::ElementNode& options);
    339364    void readNATNetworks(const xml::ElementNode &elmNATNetworks);
    340365
  • trunk/src/VBox/Main/Makefile.kmk

    r46969 r47018  
    335335        src-server/BIOSSettingsImpl.cpp \
    336336        src-server/DHCPServerImpl.cpp \
    337         src-server/DHCPServerRunner.cpp \
     337        src-server/NetworkServiceRunner.cpp \
    338338        src-server/NATNetworkImpl.cpp \
    339         $(if $(VBOX_WITH_NAT_SERVICE),src-server/NATNetworkServiceRunner.cpp,) \
    340339        src-server/GuestOSTypeImpl.cpp \
    341340        src-server/HostImpl.cpp \
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r46969 r47018  
    14661466  </interface>
    14671467
     1468  <enum
     1469      name="DhcpOpt"
     1470      uuid="40d99bd3-3ece-44d2-a07e-1085fe9c4f0b">
     1471    <const name="SubnetMask" value="1"/>
     1472    <const name="TimeOffset" value="2"/>
     1473    <const name="Router" value="3"/>
     1474    <const name="TimeServer" value="4"/>
     1475    <const name="NameServer" value="5"/>
     1476    <const name="DomainNameServer" value="6"/>
     1477    <const name="LogServer" value="7"/>
     1478    <const name="Cookie" value="8"/>
     1479    <const name="LPRServer" value="9"/>
     1480    <const name="ImpressServer" value="10"/>
     1481    <const name="ResourseLocationServer" value="11"/>
     1482    <const name="HostName" value="12"/>
     1483    <const name="BootFileSize" value="13"/>
     1484    <const name="MeritDumpFile" value="14"/>
     1485    <const name="DomainName" value="15"/>
     1486    <const name="SwapServer" value="16"/>
     1487    <const name="RootPath" value="17"/>
     1488    <const name="ExtensionPath" value="18"/>
     1489    <const name="IPForwardingEnableDisable" value="19"/>
     1490    <const name="NonLocalSourceRoutingEnableDisable" value="20"/>
     1491    <const name="PolicyFilter" value="21"/>
     1492    <const name="MaximumDatagramReassemblySize" value="22"/>
     1493    <const name="DefaultIPTime2Live" value="23"/>
     1494    <const name="PathMTUAgingTimeout" value="24"/>
     1495    <const name="IPLayerParametersPerInterface" value="25"/>
     1496    <const name="InterfaceMTU" value="26"/>
     1497    <const name="AllSubnetsAreLocal" value="27"/>
     1498    <const name="BroadcastAddress" value="28"/>
     1499    <const name="PerformMaskDiscovery" value="29"/>
     1500    <const name="MaskSupplier" value="30"/>
     1501    <const name="PerformRouteDiscovery" value="31"/>
     1502    <const name="RouterSolicitationAddress" value="32"/>
     1503    <const name="StaticRoute" value="33"/>
     1504    <const name="TrailerEncapsulation" value="34"/>
     1505    <const name="ARPCacheTimeout" value="35"/>
     1506    <const name="EthernetEncapsulation" value="36"/>
     1507    <const name="TCPDefaultTTL" value="37"/>
     1508    <const name="TCPKeepAliveInterval" value="38"/>
     1509    <const name="TCPKeepAliveGarbage" value="39"/>
     1510    <const name="NetworkInformationServiceDomain" value="40"/>
     1511    <const name="NetworkInformationServiceServers" value="41"/>
     1512    <const name="NetworkTimeProtocolServers" value="42"/>
     1513    <const name="VendorSpecificInformation" value="43"/>
     1514    <const name="Option_44" value="44"/>
     1515    <const name="Option_45" value="45"/>
     1516    <const name="Option_46" value="46"/>
     1517    <const name="Option_47" value="47"/>
     1518    <const name="Option_48" value="48"/>
     1519    <const name="Option_49" value="49"/>
     1520    <const name="IPAddressLeaseTime" value="51"/>
     1521    <const name="Option_64" value="64"/>
     1522    <const name="Option_65" value="65"/>
     1523    <const name="TFTPServerName" value="66"/>
     1524    <const name="BootfileName" value="67"/>
     1525    <const name="Option_68" value="68"/>
     1526    <const name="Option_69" value="69"/>
     1527    <const name="Option_70" value="70"/>
     1528    <const name="Option_71" value="71"/>
     1529    <const name="Option_72" value="72"/>
     1530    <const name="Option_73" value="73"/>
     1531    <const name="Option_74" value="74"/>
     1532    <const name="Option_75" value="75"/>
     1533    <const name="Option_119" value="119"/>
     1534  </enum>
     1535
    14681536  <interface
    14691537    name="IDHCPServer" extends="$unknown"
    1470     uuid="6cfe387c-74fb-4ca7-bff6-973bec8af7a3"
     1538    uuid="ff0774c5-1f62-4bc3-919c-7fc942bf1d25"
    14711539    wsmap="managed"
    14721540    >
     
    14771545      <link to="IVirtualBox::DHCPServers"/> attribute.
    14781546    </desc>
    1479 
     1547    <!-- We want to keep our "real" servers updated about configuration changes -->
     1548    <attribute name="eventSource" type="IEventSource" readonly="yes"/>
    14801549    <attribute name="enabled" type="boolean">
    14811550      <desc>
     
    15131582      </desc>
    15141583    </attribute>
     1584
     1585    <method name="addGlobalOption">
     1586      <param name="option" type="DhcpOpt" dir="in"/>
     1587      <param name="value" type="wstring" dir="in" />
     1588    </method>
     1589
     1590    <!-- string in format: "option_id:value" -->
     1591    <attribute name="globalOptions" type="wstring" safearray="yes" readonly="yes"/>
     1592
     1593    <!-- string in format: "[vm name]:slot" -->
     1594    <attribute name="vmConfigs" type="wstring" safearray="yes" readonly="yes"/>
     1595
     1596    <!-- VM-slot settings
     1597         It's corresponds to dhcpd.conf entries, like:
     1598
     1599         host ncd1 { hardware ethernet 0:c0:c3:11:90:23; }
     1600
     1601         - in Main we can match (vm name, slot) to ethernet address
     1602         that why it's easy to configure dhcp server in such way,
     1603         then ask user to to enter valid name,
     1604       
     1605         - mac address might change because of adapter type (e1k <-> pcnet) or because
     1606         of import/export
     1607       
     1608         - it's easy to provide vm-name.rom in boot filename VM with network boot.
     1609       
     1610         XXX: do we need classic getOptionValueByMAC?
     1611       
     1612         XML: O-o-oh, this settings are per VM, so perhaps they should be stored in
     1613              VM configuration files. And we haven't got the attachment type for
     1614              NATNetwork.
     1615    -->
     1616    <method name="addVmSlotOption">
     1617      <param name="vmname" type="wstring" dir="in"/>
     1618      <param name="slot" type="long" dir="in"/>
     1619      <param name="option" type="DhcpOpt" dir="in"/>
     1620      <param name="value" type="wstring" dir="in" />
     1621    </method>
     1622
     1623    <method name="removeVmSlotOptions">
     1624      <param name="vmname" type="wstring" dir="in"/>
     1625      <param name="slot" type="long" dir="in"/>
     1626    </method>
     1627
     1628    <!-- returns array of strings in format: "option_id:value" for a given pair (vm, slot) -->
     1629    <method name="getVmSlotOptions">
     1630      <param name="vmname" type="wstring" dir="in"/>
     1631      <param name="slot" type="long" dir="in"/>
     1632      <param name="option" type="wstring" safearray="yes" dir="return"/>
     1633    </method>
     1634
     1635    <!-- Returns options by MAC address -->
     1636    <method name="getMacOptions">
     1637      <param name="mac" type="wstring" dir="in"/>
     1638      <param name="option" type="wstring" safearray="yes" dir="return"/>
     1639    </method>
    15151640
    15161641    <method name="setConfiguration">
     
    42644389        This setting determines the filename VirtualBox uses to save
    42654390        the recorded content. This setting cannot be changed while video
    4266         capturing is enabled. 
     4391        capturing is enabled.
    42674392        <note>
    42684393          When setting this attribute, the specified path has to be
     
    80388163  <interface
    80398164    name="IHost" extends="$unknown"
    8040     uuid="30678943-32df-4830-b413-931b25ac86a0"
     8165    uuid="a6107246-f939-42c4-82b6-8aca40327b6d"
    80418166    wsmap="managed"
    80428167    >
     
    80998224    <attribute name="networkInterfaces" type="IHostNetworkInterface" safearray="yes" readonly="yes">
    81008225      <desc>List of host network interfaces currently defined on the host.</desc>
     8226    </attribute>
     8227
     8228    <attribute name="nameServers" type="wstring" safearray="yes" readonly="yes">
     8229      <desc> The list of nameservers registered in host's name resolving system.</desc>
     8230    </attribute>
     8231
     8232    <attribute name="domainName" type="wstring" readonly="yes">
     8233      <desc>Domain name used for name resoving.</desc>
     8234    </attribute>
     8235
     8236    <attribute name="searchStrings" type="wstring" safearray="yes" readonly="yes">
     8237      <desc>Search string registered for name resoving.</desc>
    81018238    </attribute>
    81028239
  • trunk/src/VBox/Main/include/DHCPServerImpl.h

    r46969 r47018  
    3030{
    3131    struct DHCPServer;
     32    struct VmNameSlotKey;
    3233}
     34#ifdef RT_OS_WINDOWS
     35# define DHCP_EXECUTABLE_NAME "VBoxNetDHCP.exe"
     36#else
     37# define DHCP_EXECUTABLE_NAME "VBoxNetDHCP"
     38#endif
     39
     40class DHCPServerRunner: public NetworkServiceRunner
     41{
     42public:
     43    DHCPServerRunner():NetworkServiceRunner(DHCP_EXECUTABLE_NAME){}
     44    virtual ~DHCPServerRunner(){};
     45};
     46
     47/**
     48 *  for server configuration needs, it's perhaps better to use (VM,slot) pair
     49 *  (vm-name, slot) <----> (MAC)
     50 * 
     51 *  but for client configuration, when server will have MACs at hand, it'd be
     52 *  easier to requiest options by MAC.
     53 *  (MAC) <----> (option-list)
     54 *
     55 *  Doubts: What should be done if MAC changed for (vm-name, slot), when syncing should?
     56 *  XML: serialization of dependecy (DHCP options) - (VM,slot) shouldn't be done via MAC in
     57 *  the middle.
     58 */
     59
     60typedef std::map<DhcpOpt_T, com::Utf8Str> DhcpOptionMap;
     61typedef DhcpOptionMap::value_type DhcpOptValuePair;
     62typedef DhcpOptionMap::const_iterator DhcpOptConstIterator;
     63typedef DhcpOptionMap::iterator DhcpOptIterator;
     64
     65typedef std::map<settings::VmNameSlotKey, DhcpOptionMap> VmSlot2OptionsMap;
     66typedef VmSlot2OptionsMap::value_type VmSlot2OptionsPair;
     67typedef VmSlot2OptionsMap::iterator VmSlot2OptionsIterator;
     68
    3369
    3470class ATL_NO_VTABLE DHCPServer :
     
    70106    STDMETHOD(COMGETTER(UpperIP))(BSTR *aIPAddress);
    71107
     108    STDMETHOD(AddGlobalOption)(DhcpOpt_T aOption, IN_BSTR aValue);
     109    STDMETHOD(COMGETTER(GlobalOptions))(ComSafeArrayOut(BSTR, aValue));
     110    STDMETHOD(COMGETTER(VmConfigs))(ComSafeArrayOut(BSTR, aValue));
     111    STDMETHOD(AddVmSlotOption)(IN_BSTR aVmName, LONG aSlot, DhcpOpt_T aOption, IN_BSTR aValue);
     112    STDMETHOD(RemoveVmSlotOptions)(IN_BSTR aVmName, LONG aSlot);
     113    STDMETHOD(GetVmSlotOptions)(IN_BSTR aVmName, LONG aSlot, ComSafeArrayOut(BSTR, aValues));
     114    STDMETHOD(GetMacOptions)(IN_BSTR aMAC, ComSafeArrayOut(BSTR, aValues));
     115    STDMETHOD(COMGETTER(EventSource))(IEventSource **aEventSource);
     116 
    72117    STDMETHOD(SetConfiguration)(IN_BSTR aIPAddress, IN_BSTR aNetworkMask, IN_BSTR aFromIPAddress, IN_BSTR aToIPAddress);
    73118
     
    86131
    87132        Bstr IPAddress;
    88         Bstr networkMask;
    89133        Bstr lowerIP;
    90134        Bstr upperIP;
     135
    91136        BOOL enabled;
     137        DHCPServerRunner dhcp;
    92138
    93         DHCPServerRunner dhcp;
     139        DhcpOptionMap GlobalDhcpOptions;
     140        VmSlot2OptionsMap VmSlot2Options;
    94141    } m;
    95142
     143    DhcpOptionMap& findOptMapByVmNameSlot(const com::Utf8Str& aVmName,
     144                                          LONG Slot);
    96145};
    97146
  • trunk/src/VBox/Main/include/HostImpl.h

    r46969 r47018  
    6262    STDMETHOD(COMGETTER(USBDeviceFilters))(ComSafeArrayOut(IHostUSBDeviceFilter *, aUSBDeviceFilters));
    6363    STDMETHOD(COMGETTER(NetworkInterfaces))(ComSafeArrayOut(IHostNetworkInterface *, aNetworkInterfaces));
     64    STDMETHOD(COMGETTER(NameServers))(ComSafeArrayOut(BSTR, aNameServers));
     65    STDMETHOD(COMGETTER(DomainName))(BSTR *aDomainName);
     66    STDMETHOD(COMGETTER(SearchStrings))(ComSafeArrayOut(BSTR, aSearchStrings));
    6467    STDMETHOD(COMGETTER(ProcessorCount))(ULONG *count);
    6568    STDMETHOD(COMGETTER(ProcessorOnlineCount))(ULONG *count);
     
    147150    HRESULT updateNetIfList();
    148151
     152#ifndef RT_OS_WINDOWS
     153    HRESULT parseResolvConf();
     154#else
     155    HRESULT fetchNameResolvingInformation();
     156#endif
     157
    149158#ifdef VBOX_WITH_RESOURCE_USAGE_API
    150159    void registerMetrics(PerformanceCollector *aCollector);
  • trunk/src/VBox/Main/include/NATNetworkImpl.h

    r46969 r47018  
    3737}
    3838
     39#ifdef RT_OS_WINDOWS
     40# define NATSR_EXECUTABLE_NAME "VBoxNetLwipNAT.exe"
     41#else
     42# define NATSR_EXECUTABLE_NAME "VBoxNetLwipNAT"
     43#endif
     44
     45class NATNetworkServiceRunner: public NetworkServiceRunner
     46{
     47public:
     48    NATNetworkServiceRunner(): NetworkServiceRunner(NATSR_EXECUTABLE_NAME){}
     49    virtual ~NATNetworkServiceRunner(){}
     50};
    3951
    4052class ATL_NO_VTABLE NATNetwork :
     
    8294    STDMETHOD(COMGETTER(Network))(BSTR *aIPNetwork);
    8395    STDMETHOD(COMSETTER(Network))(IN_BSTR aIPNetwork);
    84    
     96
    8597    STDMETHOD(COMGETTER(IPv6Enabled))(BOOL *aEnabled);
    8698    STDMETHOD(COMSETTER(IPv6Enabled))(BOOL aEnabled);
    87    
     99
    88100    STDMETHOD(COMGETTER(IPv6Prefix))(BSTR *aName);
    89101    STDMETHOD(COMSETTER(IPv6Prefix))(IN_BSTR aName);
     
    91103    STDMETHOD(COMGETTER(AdvertiseDefaultIPv6RouteEnabled))(BOOL *aEnabled);
    92104    STDMETHOD(COMSETTER(AdvertiseDefaultIPv6RouteEnabled))(BOOL aEnabled);
    93    
     105
    94106    STDMETHOD(COMGETTER(NeedDhcpServer))(BOOL *aEnabled);
    95107    STDMETHOD(COMSETTER(NeedDhcpServer))(BOOL aEnabled);
    96    
     108
    97109    STDMETHOD(COMGETTER(PortForwardRules4))(ComSafeArrayOut(BSTR, aPortForwardRules4));
    98110    STDMETHOD(COMGETTER(PortForwardRules6))(ComSafeArrayOut(BSTR, aPortForwardRules6));
    99111
    100     STDMETHOD(AddPortForwardRule)(BOOL aIsIpv6, 
    101                                   IN_BSTR aPortForwardRuleName, 
     112    STDMETHOD(AddPortForwardRule)(BOOL aIsIpv6,
     113                                  IN_BSTR aPortForwardRuleName,
    102114                                  NATProtocol_T aProto,
    103115                                  IN_BSTR aHostIp,
  • trunk/src/VBox/Main/include/NetworkServiceRunner.h

    r47017 r47018  
    2323typedef enum
    2424{
    25     DHCPCFG_NAME = 1,
    26     DHCPCFG_NETNAME,
    27     DHCPCFG_TRUNKTYPE,
    28     DHCPCFG_TRUNKNAME,
    29     DHCPCFG_MACADDRESS,
    30     DHCPCFG_IPADDRESS,
    31     DHCPCFG_LEASEDB,
    32     DHCPCFG_VERBOSE,
    33     DHCPCFG_GATEWAY,
    34     DHCPCFG_LOWERIP,
    35     DHCPCFG_UPPERIP,
    36     DHCPCFG_NETMASK,
    37     DHCPCFG_HELP,
    38     DHCPCFG_VERSION,
    39     DHCPCFG_BEGINCONFIG,
    40     DHCPCFG_NOTOPT_MAXVAL
    41 }DHCPCFG;
     25    NETCFG_NAME = 1,
     26    NETCFG_NETNAME,
     27    NETCFG_TRUNKTYPE,
     28    NETCFG_TRUNKNAME,
     29    NETCFG_MACADDRESS,
     30    NETCFG_IPADDRESS,
     31    NETCFG_NETMASK,
     32    NETCFG_VERBOSE,
     33    NETCFG_NOTOPT_MAXVAL
     34}NETCFG;
    4235
    4336#define TRUNKTYPE_WHATEVER "whatever"
     
    4639#define TRUNKTYPE_SRVNAT   "srvnat"
    4740
    48 class DHCPServerRunner
     41class NetworkServiceRunner
    4942{
    5043public:
    51     DHCPServerRunner();
    52     ~DHCPServerRunner() { stop(); /* don't leave abandoned servers */}
     44    NetworkServiceRunner(const char *aProcName):
     45      mProcName(aProcName),
     46      mProcess(NIL_RTPROCESS)
     47    {
     48        memset(mOptionEnabled, 0, sizeof(mOptionEnabled));
     49    };
     50    ~NetworkServiceRunner() { stop(); /* don't leave abandoned servers */}
    5351
    54     int setOption(DHCPCFG opt, const char *val, bool enabled)
     52    int setOption(NETCFG opt, const char *val, bool enabled)
    5553    {
    56         if (opt == 0 || opt >= DHCPCFG_NOTOPT_MAXVAL)
     54        if (opt == 0 || opt >= NETCFG_NOTOPT_MAXVAL)
    5755            return VERR_INVALID_PARAMETER;
    5856        if (isRunning())
     
    6462    }
    6563
    66     int setOption(DHCPCFG opt, const com::Utf8Str &val, bool enabled)
     64    int setOption(NETCFG opt, const com::Utf8Str &val, bool enabled)
    6765    {
    6866        return setOption(opt, val.c_str(), enabled);
     
    7573    void detachFromServer();
    7674private:
    77     com::Utf8Str mOptions[DHCPCFG_NOTOPT_MAXVAL];
    78     bool mOptionEnabled[DHCPCFG_NOTOPT_MAXVAL];
     75    com::Utf8Str mOptions[NETCFG_NOTOPT_MAXVAL];
     76    bool mOptionEnabled[NETCFG_NOTOPT_MAXVAL];
     77    const char *mProcName;
    7978    RTPROCESS mProcess;
    8079};
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r46969 r47018  
    115115#endif /* VBOX_WITH_NETFLT */
    116116
    117 #include "DHCPServerRunner.h"
     117#include "NetworkServiceRunner.h"
    118118#include "BusAssignmentManager.h"
    119119#ifdef VBOX_WITH_EXTPACK
  • trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp

    r46969 r47018  
    1818 */
    1919
    20 #include "DHCPServerRunner.h"
     20#include "NetworkServiceRunner.h"
    2121#include "DHCPServerImpl.h"
    2222#include "AutoCaller.h"
     
    2525#include <iprt/cpp/utils.h>
    2626
     27#include <VBox/com/array.h>
    2728#include <VBox/settings.h>
    2829
     
    3738}
    3839
     40
    3941DHCPServer::~DHCPServer()
    4042{
    4143}
    4244
     45
    4346HRESULT DHCPServer::FinalConstruct()
    4447{
     
    4649}
    4750
     51
    4852void DHCPServer::FinalRelease()
    4953{
     
    5256    BaseFinalRelease();
    5357}
     58
    5459
    5560void DHCPServer::uninit()
     
    6368}
    6469
     70
    6571HRESULT DHCPServer::init(VirtualBox *aVirtualBox, IN_BSTR aName)
    6672{
     
    7581    unconst(mName) = aName;
    7682    m.IPAddress = "0.0.0.0";
    77     m.networkMask = "0.0.0.0";
     83    m.GlobalDhcpOptions.insert(DhcpOptValuePair(DhcpOpt_SubnetMask, Bstr("0.0.0.0")));
    7884    m.enabled = FALSE;
     85
    7986    m.lowerIP = "0.0.0.0";
    8087    m.upperIP = "0.0.0.0";
     
    8592    return S_OK;
    8693}
     94
    8795
    8896HRESULT DHCPServer::init(VirtualBox *aVirtualBox,
     
    98106    unconst(mName) = data.strNetworkName;
    99107    m.IPAddress = data.strIPAddress;
    100     m.networkMask = data.strIPNetworkMask;
    101108    m.enabled = data.fEnabled;
    102109    m.lowerIP = data.strIPLower;
    103110    m.upperIP = data.strIPUpper;
    104111
     112    m.GlobalDhcpOptions.clear();
     113    m.GlobalDhcpOptions.insert(data.GlobalDhcpOptions.begin(),
     114                               data.GlobalDhcpOptions.end());
     115
     116    m.VmSlot2Options.clear();
     117    m.VmSlot2Options.insert(data.VmSlot2OptionsM.begin(),
     118                            data.VmSlot2OptionsM.end());
     119
    105120    autoInitSpan.setSucceeded();
    106121
    107122    return S_OK;
    108123}
     124
    109125
    110126HRESULT DHCPServer::saveSettings(settings::DHCPServer &data)
     
    117133    data.strNetworkName = mName;
    118134    data.strIPAddress = m.IPAddress;
    119     data.strIPNetworkMask = m.networkMask;
     135
    120136    data.fEnabled = !!m.enabled;
    121137    data.strIPLower = m.lowerIP;
    122138    data.strIPUpper = m.upperIP;
    123139
    124     return S_OK;
    125 }
     140    data.GlobalDhcpOptions.clear();
     141    data.GlobalDhcpOptions.insert(m.GlobalDhcpOptions.begin(),
     142                                  m.GlobalDhcpOptions.end());
     143
     144    data.VmSlot2OptionsM.clear();
     145    data.VmSlot2OptionsM.insert(m.VmSlot2Options.begin(),
     146                                m.VmSlot2Options.end());
     147
     148    return S_OK;
     149}
     150
    126151
    127152STDMETHODIMP DHCPServer::COMGETTER(NetworkName) (BSTR *aName)
     
    137162}
    138163
     164
    139165STDMETHODIMP DHCPServer::COMGETTER(Enabled) (BOOL *aEnabled)
    140166{
     
    148174    return S_OK;
    149175}
     176
    150177
    151178STDMETHODIMP DHCPServer::COMSETTER(Enabled) (BOOL aEnabled)
     
    165192}
    166193
     194
    167195STDMETHODIMP DHCPServer::COMGETTER(IPAddress) (BSTR *aIPAddress)
    168196{
     
    177205}
    178206
     207
    179208STDMETHODIMP DHCPServer::COMGETTER(NetworkMask) (BSTR *aNetworkMask)
    180209{
     
    184213    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    185214
    186     m.networkMask.cloneTo(aNetworkMask);
    187 
    188     return S_OK;
    189 }
     215    m.GlobalDhcpOptions[DhcpOpt_SubnetMask].cloneTo(aNetworkMask);
     216
     217    return S_OK;
     218}
     219
    190220
    191221STDMETHODIMP DHCPServer::COMGETTER(LowerIP) (BSTR *aIPAddress)
     
    201231}
    202232
     233
    203234STDMETHODIMP DHCPServer::COMGETTER(UpperIP) (BSTR *aIPAddress)
    204235{
     
    212243    return S_OK;
    213244}
     245
    214246
    215247STDMETHODIMP DHCPServer::SetConfiguration (IN_BSTR aIPAddress, IN_BSTR aNetworkMask, IN_BSTR aLowerIP, IN_BSTR aUpperIP)
     
    225257    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    226258    m.IPAddress = aIPAddress;
    227     m.networkMask = aNetworkMask;
     259    m.GlobalDhcpOptions[DhcpOpt_SubnetMask] = aNetworkMask;
     260
    228261    m.lowerIP = aLowerIP;
    229262    m.upperIP = aUpperIP;
     
    235268}
    236269
     270
     271STDMETHODIMP DHCPServer::AddGlobalOption(DhcpOpt_T aOption, IN_BSTR aValue)
     272{
     273    CheckComArgStr(aValue);
     274    /* store global option */
     275    AutoCaller autoCaller(this);
     276    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     277
     278    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     279
     280    m.GlobalDhcpOptions.insert(
     281      DhcpOptValuePair(aOption, Utf8Str(aValue)));
     282
     283    alock.release();
     284
     285    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     286    return mVirtualBox->saveSettings();
     287}
     288
     289
     290STDMETHODIMP DHCPServer::COMGETTER(GlobalOptions)(ComSafeArrayOut(BSTR, aValue))
     291{
     292    CheckComArgOutSafeArrayPointerValid(aValue);
     293
     294    AutoCaller autoCaller(this);
     295    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     296
     297    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     298
     299    SafeArray<BSTR> sf(m.GlobalDhcpOptions.size());
     300    int i = 0;
     301
     302    for (DhcpOptIterator it = m.GlobalDhcpOptions.begin();
     303         it != m.GlobalDhcpOptions.end(); ++it)
     304    {
     305        Bstr(Utf8StrFmt("%d:%s", (*it).first, (*it).second.c_str())).detachTo(&sf[i]);
     306        i++;
     307    }
     308
     309    sf.detachTo(ComSafeArrayOutArg(aValue));
     310
     311    return S_OK;
     312}
     313
     314
     315STDMETHODIMP DHCPServer::COMGETTER(VmConfigs)(ComSafeArrayOut(BSTR, aValue))
     316{
     317    CheckComArgOutSafeArrayPointerValid(aValue);
     318
     319    AutoCaller autoCaller(this);
     320    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     321
     322    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     323
     324    SafeArray<BSTR> sf(m.VmSlot2Options.size());
     325    VmSlot2OptionsIterator it = m.VmSlot2Options.begin();
     326    int i = 0;
     327    for (;it != m.VmSlot2Options.end(); ++it)
     328    {
     329        Bstr(Utf8StrFmt("[%s]:%d",
     330                        it->first.VmName.c_str(),
     331                        it->first.Slot)).detachTo(&sf[i]);
     332        i++;
     333    }
     334
     335    sf.detachTo(ComSafeArrayOutArg(aValue));
     336
     337    return S_OK;
     338}
     339
     340
     341STDMETHODIMP DHCPServer::AddVmSlotOption(IN_BSTR aVmName, LONG aSlot, DhcpOpt_T aOption, IN_BSTR aValue)
     342{
     343    AutoCaller autoCaller(this);
     344    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     345    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     346
     347    m.VmSlot2Options[settings::VmNameSlotKey(
     348          com::Utf8Str(aVmName),
     349          aSlot)][aOption] = com::Utf8Str(aValue);
     350
     351
     352    alock.release();
     353
     354    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     355    return mVirtualBox->saveSettings();
     356}
     357
     358
     359STDMETHODIMP DHCPServer::RemoveVmSlotOptions(IN_BSTR aVmName, LONG aSlot)
     360{
     361    AutoCaller autoCaller(this);
     362    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     363    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     364
     365    DhcpOptionMap& map = findOptMapByVmNameSlot(com::Utf8Str(aVmName), aSlot);
     366
     367    map.clear();
     368
     369    alock.release();
     370
     371    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
     372    return mVirtualBox->saveSettings();
     373}
     374
     375
     376/**
     377 * this is mapping (vm, slot)
     378 */
     379STDMETHODIMP DHCPServer::GetVmSlotOptions(IN_BSTR aVmName,
     380                                          LONG aSlot,
     381                                          ComSafeArrayOut(BSTR, aValues))
     382{
     383    CheckComArgOutSafeArrayPointerValid(aValues);
     384    AutoCaller autoCaller(this);
     385    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     386
     387    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     388
     389    DhcpOptionMap& map = findOptMapByVmNameSlot(com::Utf8Str(aVmName), aSlot);
     390
     391    SafeArray<BSTR> sf(map.size());
     392    int i = 0;
     393
     394    for (DhcpOptIterator it = map.begin();
     395         it != map.end(); ++it)
     396    {
     397        Bstr(Utf8StrFmt("%d:%s", (*it).first, (*it).second.c_str())).detachTo(&sf[i]);
     398        i++;
     399    }
     400
     401    sf.detachTo(ComSafeArrayOutArg(aValues));
     402
     403    return S_OK;
     404}
     405
     406
     407STDMETHODIMP DHCPServer::GetMacOptions(IN_BSTR aMAC, ComSafeArrayOut(BSTR, aValues))
     408{
     409    CheckComArgOutSafeArrayPointerValid(aValues);
     410
     411    AutoCaller autoCaller(this);
     412    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     413
     414    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     415    HRESULT hrc;
     416
     417    ComPtr<IMachine> machine;
     418    ComPtr<INetworkAdapter> nic;
     419
     420    VmSlot2OptionsIterator it;
     421    for(it = m.VmSlot2Options.begin();
     422        it != m.VmSlot2Options.end();
     423        ++it)
     424    {
     425
     426        alock.release();
     427        hrc = mVirtualBox->FindMachine(Bstr(it->first.VmName).raw(), machine.asOutParam());
     428        alock.acquire();
     429
     430        if (FAILED(hrc))
     431            continue;
     432
     433        alock.release();
     434        hrc = machine->GetNetworkAdapter(it->first.Slot, nic.asOutParam());
     435        alock.acquire();
     436
     437        if (FAILED(hrc))
     438            continue;
     439
     440        com::Bstr mac;
     441
     442        alock.release();
     443        hrc = nic->COMGETTER(MACAddress)(mac.asOutParam());
     444        alock.acquire();
     445
     446        if (FAILED(hrc)) /* no MAC address ??? */
     447            break;
     448
     449        if (!RTStrICmp(com::Utf8Str(mac).c_str(), com::Utf8Str(aMAC).c_str()))
     450            return GetVmSlotOptions(Bstr(it->first.VmName).raw(),
     451                                    it->first.Slot,
     452                                    ComSafeArrayOutArg(aValues));
     453    } /* end of for */
     454
     455    return hrc;
     456}
     457
     458
     459STDMETHODIMP DHCPServer::COMGETTER(EventSource)(IEventSource **aEventSource)
     460{
     461    ReturnComNotImplemented();
     462}
     463
     464
    237465STDMETHODIMP DHCPServer::Start(IN_BSTR aNetworkName, IN_BSTR aTrunkName, IN_BSTR aTrunkType)
    238466{
     
    241469        return S_OK;
    242470
    243     m.dhcp.setOption(DHCPCFG_NETNAME, Utf8Str(aNetworkName), true);
     471    /* Commmon Network Settings */
     472    m.dhcp.setOption(NETCFG_NETNAME, Utf8Str(aNetworkName), true);
     473
    244474    Bstr tmp(aTrunkName);
     475
    245476    if (!tmp.isEmpty())
    246         m.dhcp.setOption(DHCPCFG_TRUNKNAME, Utf8Str(tmp), true);
    247     m.dhcp.setOption(DHCPCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
    248     //temporary hack for testing
    249     //    DHCPCFG_NAME
     477        m.dhcp.setOption(NETCFG_TRUNKNAME, Utf8Str(tmp), true);
     478    m.dhcp.setOption(NETCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
     479
     480    /* XXX: should this MAC default initialization moved to NetworkServiceRunner? */
    250481    char strMAC[32];
    251482    Guid guid;
    252483    guid.create();
    253484    RTStrPrintf (strMAC, sizeof(strMAC), "08:00:27:%02X:%02X:%02X",
    254                  guid.raw()->au8[0], guid.raw()->au8[1], guid.raw()->au8[2]);
    255     m.dhcp.setOption(DHCPCFG_MACADDRESS, strMAC, true);
    256     m.dhcp.setOption(DHCPCFG_IPADDRESS,  Utf8Str(m.IPAddress), true);
    257     //        DHCPCFG_LEASEDB,
    258     //        DHCPCFG_VERBOSE,
    259     //        DHCPCFG_GATEWAY,
    260     m.dhcp.setOption(DHCPCFG_LOWERIP,  Utf8Str(m.lowerIP), true);
    261     m.dhcp.setOption(DHCPCFG_UPPERIP,  Utf8Str(m.upperIP), true);
    262     m.dhcp.setOption(DHCPCFG_NETMASK,  Utf8Str(m.networkMask), true);
    263 
    264     //        DHCPCFG_HELP,
    265     //        DHCPCFG_VERSION,
    266     //        DHCPCFG_NOTOPT_MAXVAL
    267     m.dhcp.setOption(DHCPCFG_BEGINCONFIG,  "", true);
    268 
     485                 guid.raw()->au8[0],
     486                 guid.raw()->au8[1],
     487                 guid.raw()->au8[2]);
     488    m.dhcp.setOption(NETCFG_MACADDRESS, strMAC, true);
     489    m.dhcp.setOption(NETCFG_IPADDRESS,  Utf8Str(m.IPAddress), true);
     490    m.dhcp.setOption(NETCFG_NETMASK, Utf8Str(m.GlobalDhcpOptions[DhcpOpt_SubnetMask]), true);
     491
     492    /* XXX: This parameters Dhcp Server will fetch via API */
    269493    return RT_FAILURE(m.dhcp.start()) ? E_FAIL : S_OK;
    270494    //m.dhcp.detachFromServer(); /* need to do this to avoid server shutdown on runner destruction */
    271495}
    272496
     497
    273498STDMETHODIMP DHCPServer::Stop (void)
    274499{
    275500    return RT_FAILURE(m.dhcp.stop()) ? E_FAIL : S_OK;
    276501}
     502
     503
     504DhcpOptionMap& DHCPServer::findOptMapByVmNameSlot(const com::Utf8Str& aVmName,
     505                                                  LONG aSlot)
     506{
     507    return m.VmSlot2Options[settings::VmNameSlotKey(
     508          com::Utf8Str(aVmName),
     509          aSlot)];
     510}
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r46969 r47018  
    134134#include <iprt/mem.h>
    135135#include <iprt/system.h>
     136#ifndef RT_OS_WINDOWS
     137# include <iprt/path.h>
     138#endif
    136139#ifdef RT_OS_SOLARIS
    137 # include <iprt/path.h>
    138140# include <iprt/ctype.h>
    139141#endif
     
    215217
    216218    HostPowerService        *pHostPowerService;
     219
     220    /* Name resolving */
     221    std::list<com::Bstr>     llNameServers;
     222    std::list<com::Bstr>     llSearchStrings;
     223    Bstr                     DomainName;
     224    /* XXX: we need timestamp when these values were set, on repeate in some
     225     *  (~1h?, 5 min?) period, this values should be refetched from host syetem.
     226     */
    217227};
    218228
     229#ifndef RT_OS_WINDOWS
     230static char g_aszResolvConf[RTPATH_MAX];
     231
     232static inline char *getResolvConfPath()
     233{
     234    int rc = VINF_SUCCESS;
     235    if (!g_aszResolvConf[0]) return g_aszResolvConf;
     236# ifdef RT_OS_OS2
     237    /*
     238     * This was in an old Slirp code:
     239     * IBM's "Technical Document # - 16070238", clearly says \MPTN\ETC\RESOLV2
     240     * no redolv.conf (remark to code in old Slirp code)
     241     */
     242    if (RTEnvExists("ETC"))
     243    {
     244        RTStrmPrintf(g_aszResolvConf, MAX_PATH, "%/RESOLV2", RTEnvGet("ETC"));
     245        rc = RTFileExists(g_aszResolvConf);
     246        if (RT_SUCCESS(rc))
     247            return g_aszResolvConf;
     248    }
     249
     250    RT_ZERO(g_aszResolvConf);
     251    RTStrmPrintf(g_aszResolvConf, MAX_PATH, "%/RESOLV2", _PATH_ETC);
     252# else
     253    strcmp(g_aszResolvConf, "/etc/resolv.conf");
     254# endif   
     255    return g_aszResolvConf;
     256}
     257#endif
    219258
    220259////////////////////////////////////////////////////////////////////////////////
     
    797836#endif
    798837}
     838
     839
     840/**
     841 * This method return the list of registered name servers
     842 */
     843STDMETHODIMP Host::COMGETTER(NameServers)(ComSafeArrayOut(BSTR, aNameServers))
     844{
     845    return E_NOTIMPL;
     846}
     847
     848
     849/**
     850 * This method returns the domain name of the host
     851 */
     852STDMETHODIMP Host::COMGETTER(DomainName)(BSTR *aDomainName)
     853{
     854    return E_NOTIMPL;
     855}
     856
     857
     858/**
     859 * This method returns the search string.
     860 */
     861STDMETHODIMP Host::COMGETTER(SearchStrings)(ComSafeArrayOut(BSTR, aSearchStrings))
     862{
     863    return E_NOTIMPL;
     864}
     865
    799866
    800867STDMETHODIMP Host::COMGETTER(USBDeviceFilters)(ComSafeArrayOut(IHostUSBDeviceFilter*, aUSBDeviceFilters))
  • trunk/src/VBox/Main/src-server/NATNetworkImpl.cpp

    r46969 r47018  
    1818 */
    1919
    20 #include "DHCPServerRunner.h"
     20#include "NetworkServiceRunner.h"
    2121#include "DHCPServerImpl.h"
    2222#include "NATNetworkImpl.h"
     
    3535#include "VBoxEvents.h"
    3636
    37 #include "NATNetworkServiceRunner.h"
    3837#include "VirtualBoxImpl.h"
    3938
     
    4443struct NATNetwork::Data
    4544{
    46     Data() : 
    47      
     45    Data() :
     46
    4847      fEnabled(FALSE),
    4948      fIPv6Enabled(FALSE),
     
    128127    m->fEnabled = FALSE;
    129128
    130    
    131    
     129
     130
    132131    RecalculateIpv4AddressAssignments();
    133132
     
    137136    hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
    138137    if (FAILED(hrc)) throw hrc;
    139        
     138
    140139    /* Confirm a successful initialization */
    141140    autoInitSpan.setSucceeded();
     
    185184    hrc = m->pEventSource->init(static_cast<INATNetwork *>(this));
    186185    if (FAILED(hrc)) throw hrc;
    187    
     186
    188187    autoInitSpan.setSucceeded();
    189188
     
    206205    data.fIPv6 = RT_BOOL(m->fIPv6Enabled);
    207206    data.strIPv6Prefix = m->IPv6Prefix;
    208    
     207
    209208    /* saving ipv4 port-forward Rules*/
    210209    data.llPortForwardRules4.clear();
     
    221220    /* XXX: should we do here a copy of params */
    222221    /* XXX: should we unlock here? */
    223     mVirtualBox->onNATNetworkSetting(mName.raw(), 
     222    mVirtualBox->onNATNetworkSetting(mName.raw(),
    224223                                     data.fEnabled ? TRUE : FALSE,
    225224                                     m->IPv4NetworkCidr.raw(),
    226                                      m->IPv4Gateway.raw(), 
     225                                     m->IPv4Gateway.raw(),
    227226                                     data.fAdvertiseDefaultIPv6Route ? TRUE : FALSE,
    228227                                     data.fNeedDhcpServer ? TRUE : FALSE);
     
    485484
    486485    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    487     GetPortForwardRulesFromMap(ComSafeArrayInArg(aPortForwardRules4), 
     486    GetPortForwardRulesFromMap(ComSafeArrayInArg(aPortForwardRules4),
    488487                               m->mapName2PortForwardRule4);
    489488    alock.release();
     
    491490}
    492491
    493 STDMETHODIMP NATNetwork::COMGETTER(PortForwardRules6)(ComSafeArrayOut(BSTR, 
     492STDMETHODIMP NATNetwork::COMGETTER(PortForwardRules6)(ComSafeArrayOut(BSTR,
    494493                                                                      aPortForwardRules6))
    495494{
     
    504503}
    505504
    506 STDMETHODIMP NATNetwork::AddPortForwardRule(BOOL aIsIpv6, 
    507                                             IN_BSTR aPortForwardRuleName, 
     505STDMETHODIMP NATNetwork::AddPortForwardRule(BOOL aIsIpv6,
     506                                            IN_BSTR aPortForwardRuleName,
    508507                                            NATProtocol_T aProto,
    509508                                            IN_BSTR aHostIp,
     
    533532    }
    534533    if (name.isEmpty())
    535       name = Utf8StrFmt("%s_[%s]%%%d_[%s]%%%d", proto.c_str(), 
     534      name = Utf8StrFmt("%s_[%s]%%%d_[%s]%%%d", proto.c_str(),
    536535                        Utf8Str(aHostIp).c_str(), aHostPort,
    537536                        Utf8Str(aGuestIp).c_str(), aGuestPort);
     
    561560
    562561    alock.release();
    563     mVirtualBox->onNATNetworkPortForward(mName.raw(), TRUE, aIsIpv6, 
    564                                          aPortForwardRuleName, aProto, 
    565                                          aHostIp, aHostPort, 
     562    mVirtualBox->onNATNetworkPortForward(mName.raw(), TRUE, aIsIpv6,
     563                                         aPortForwardRuleName, aProto,
     564                                         aHostIp, aHostPort,
    566565                                         aGuestIp, aGuestPort);
    567566
    568567    /* Notify listerners listening on this network only */
    569     fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), TRUE, 
     568    fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), TRUE,
    570569                                   aIsIpv6, aPortForwardRuleName, aProto,
    571570                                   aHostIp, aHostPort,
     
    592591    NATRuleMap& mapRules = aIsIpv6 ? m->mapName2PortForwardRule6 : m->mapName2PortForwardRule4;
    593592    NATRuleMap::iterator it = mapRules.find(aPortForwardRuleName);
    594    
     593
    595594    if (it == mapRules.end())
    596595        return E_INVALIDARG;
    597    
     596
    598597    strHostIP = it->second.strHostIP;
    599598    strGuestIP = it->second.strGuestIP;
     
    603602
    604603    mapRules.erase(it);
    605    
     604
    606605    alock.release();
    607606
    608     mVirtualBox->onNATNetworkPortForward(mName.raw(), FALSE, aIsIpv6, 
    609                                          aPortForwardRuleName, proto, 
    610                                          Bstr(strHostIP).raw(), u16HostPort, 
     607    mVirtualBox->onNATNetworkPortForward(mName.raw(), FALSE, aIsIpv6,
     608                                         aPortForwardRuleName, proto,
     609                                         Bstr(strHostIP).raw(), u16HostPort,
    611610                                         Bstr(strGuestIP).raw(), u16GuestPort);
    612611
    613612    /* Notify listerners listening on this network only */
    614     fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), FALSE, 
     613    fireNATNetworkPortForwardEvent(m->pEventSource, mName.raw(), FALSE,
    615614                                   aIsIpv6, aPortForwardRuleName, proto,
    616615                                   Bstr(strHostIP).raw(), u16HostPort,
     
    632631
    633632    if (!m->fEnabled) return S_OK;
    634     m->NATRunner.setOption(NATSCCFG_NAME, mName, true);
    635     m->NATRunner.setOption(NATSCCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
    636     m->NATRunner.setOption(NATSCCFG_IPADDRESS, m->IPv4Gateway, true);
    637     m->NATRunner.setOption(NATSCCFG_NETMASK, m->IPv4NetworkMask, true);
    638    
    639     /* port-forwarding */
    640    
    641     for (constNATRuleMapIterator it = m->mapName2PortForwardRule4.begin();
    642          it != m->mapName2PortForwardRule4.end(); ++it)
    643     {
    644         settings::NATRule r = it->second;
    645         m->NATRunner.setOption(NATSCCFG_PORTFORWARD4,
    646                                Bstr(Utf8StrFmt("%s:%d:[%s]:%d:[%s]:%d",
    647                                                r.strName.c_str(),
    648                                                r.proto,
    649                                                r.strHostIP.isEmpty() ?
    650                                                       "0.0.0.0" :
    651                                                        r.strHostIP.c_str(),
    652                                                r.u16HostPort,
    653                                                r.strGuestIP.c_str(),
    654                                                r.u16GuestPort)), true);
    655     }
     633
     634    m->NATRunner.setOption(NETCFG_NETNAME, mName, true);
     635    m->NATRunner.setOption(NETCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
     636    m->NATRunner.setOption(NETCFG_IPADDRESS, m->IPv4Gateway, true);
     637    m->NATRunner.setOption(NETCFG_NETMASK, m->IPv4NetworkMask, true);
     638
     639    /* No portforwarding rules from command-line, all will be fetched via API */
    656640
    657641    if (m->fNeedDhcpServer)
     
    659643        /**
    660644         * Just to as idea... via API (on creation user pass the cidr of network and)
    661          * and we calculate it's addreses (mutable?). 
     645         * and we calculate it's addreses (mutable?).
    662646         */
    663          
    664         /* 
     647
     648        /*
    665649         * Configuration and running DHCP server:
    666650         * 1. find server first createDHCPServer
     
    668652         * 3. if return status neither E_INVALRG nor S_OK => return E_FAIL
    669653         * 4. if return status S_OK proceed to DHCP server configuration
    670          * 5. call setConfiguration() and pass all required parameters 
     654         * 5. call setConfiguration() and pass all required parameters
    671655         * 6. start dhcp server.
    672656         */
    673         int rc = mVirtualBox->FindDHCPServerByNetworkName(mName.raw(), 
     657        int rc = mVirtualBox->FindDHCPServerByNetworkName(mName.raw(),
    674658                                                      m->dhcpServer.asOutParam());
    675         switch (rc) 
     659        switch (rc)
    676660        {
    677661            case E_INVALIDARG:
    678662                /* server haven't beeen found let create it then */
    679                 rc = mVirtualBox->CreateDHCPServer(mName.raw(), 
     663                rc = mVirtualBox->CreateDHCPServer(mName.raw(),
    680664                                                   m->dhcpServer.asOutParam());
    681665                if (FAILED(rc))
    682666                  return E_FAIL;
    683667                /* breakthrough */
    684             case S_OK:
     668
    685669            {
    686                 LogFunc(("gateway: %s, dhcpserver:%s, dhcplowerip:%s, dhcpupperip:%s\n", 
    687                          Utf8Str(m->IPv4Gateway.raw()).c_str(), 
     670                LogFunc(("gateway: %s, dhcpserver:%s, dhcplowerip:%s, dhcpupperip:%s\n",
     671                         Utf8Str(m->IPv4Gateway.raw()).c_str(),
    688672                         Utf8Str(m->IPv4DhcpServer.raw()).c_str(),
    689                          Utf8Str(m->IPv4DhcpServerLowerIp.raw()).c_str(), 
     673                         Utf8Str(m->IPv4DhcpServerLowerIp.raw()).c_str(),
    690674                         Utf8Str(m->IPv4DhcpServerUpperIp.raw()).c_str()));
    691                          
     675
     676                m->dhcpServer->AddGlobalOption(DhcpOpt_Router, m->IPv4Gateway.raw());
    692677
    693678                rc = m->dhcpServer->SetEnabled(true);
     679
    694680                BSTR dhcpip = NULL;
    695681                BSTR netmask = NULL;
    696682                BSTR lowerip = NULL;
    697683                BSTR upperip = NULL;
     684
    698685                m->IPv4DhcpServer.cloneTo(&dhcpip);
    699686                m->IPv4NetworkMask.cloneTo(&netmask);
    700                
    701                 m->IPv4DhcpServerLowerIp.cloneTo(&lowerip);
     687                m->IPv4DhcpServerLowerIp.cloneTo(&lowerip);
    702688                m->IPv4DhcpServerUpperIp.cloneTo(&upperip);
    703                 rc = m->dhcpServer->SetConfiguration(dhcpip, 
     689                rc = m->dhcpServer->SetConfiguration(dhcpip,
    704690                                                     netmask,
    705691                                                     lowerip,
    706692                                                     upperip);
    707             break;
    708693            }
    709            
    710         default:
    711             return E_FAIL;
     694            case S_OK:
     695                break;
     696
     697            default:
     698                return E_FAIL;
    712699        }
    713700
     
    719706        }
    720707    }
    721    
     708
    722709    if (RT_SUCCESS(m->NATRunner.start()))
    723710    {
     
    728715#else
    729716    NOREF(aTrunkType);
    730     return E_NOTIMPL;
     717    ReturnComNotImplemented();
    731718#endif
    732719}
     
    741728    }
    742729    else return E_FAIL;
    743        
    744730#else
    745     return E_NOTIMPL;
     731    ReturnComNotImplemented();
    746732#endif
    747733}
     
    773759    char aszGatewayIp[16], aszNetmask[16];
    774760    RT_ZERO(aszNetmask);
    775     int rc = RTCidrStrToIPv4(Utf8Str(m->IPv4NetworkCidr.raw()).c_str(), 
    776                              &network, 
     761    int rc = RTCidrStrToIPv4(Utf8Str(m->IPv4NetworkCidr.raw()).c_str(),
     762                             &network,
    777763                             &netmask);
    778764    AssertRCReturn(rc, rc);
    779  
     765
    780766    /* I don't remember the reason CIDR calcualted in host */
    781767    gateway.u = network.u;
     
    790776          dhcplowerip,
    791777          dhcpupperip;
    792         char aszNetwork[16], 
     778        char aszNetwork[16],
    793779          aszDhcpIp[16],
    794780          aszDhcpLowerIp[16],
     
    802788        dhcpserver.u = network.u;
    803789        dhcpserver.u += 2;
    804        
    805        
     790
     791
    806792        /* XXX: adding more services should change the math here */
    807793        dhcplowerip.u = RT_H2N_U32(dhcpserver.u + 1);
     
    809795        dhcpserver.u = RT_H2N_U32(dhcpserver.u);
    810796        network.u = RT_H2N_U32(network.u);
    811                
     797
    812798        RTStrPrintf(aszNetwork, 16, "%RTnaipv4", network);
    813799        RTStrPrintf(aszDhcpLowerIp, 16, "%RTnaipv4", dhcplowerip);
     
    818804        m->IPv4DhcpServerLowerIp = aszDhcpLowerIp;
    819805        m->IPv4DhcpServerUpperIp = aszDhcpUpperIp;
    820         LogFunc(("network: %RTnaipv4, dhcpserver:%RTnaipv4, dhcplowerip:%RTnaipv4, dhcpupperip:%RTnaipv4\n", network, dhcpserver, dhcplowerip, dhcpupperip));
     806
     807        LogFunc(("network: %RTnaipv4, dhcpserver:%RTnaipv4, dhcplowerip:%RTnaipv4, dhcpupperip:%RTnaipv4\n",
     808                 network,
     809                 dhcpserver,
     810                 dhcplowerip,
     811                 dhcpupperip));
    821812    }
    822813    /* we need IPv4NetworkMask for NAT's gw service start */
  • trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp

    r47017 r47018  
    1515 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1616 */
    17 #include "DHCPServerRunner.h"
     17#include "NetworkServiceRunner.h"
    1818#include <iprt/process.h>
    1919#include <iprt/param.h>
     
    2222struct ARGDEF
    2323{
    24     DHCPCFG Type;
     24    NETCFG Type;
    2525    const char * Name;
    2626};
    2727
    28 #ifdef RT_OS_WINDOWS
    29 # define DHCP_EXECUTABLE_NAME "VBoxNetDHCP.exe"
    30 #else
    31 # define DHCP_EXECUTABLE_NAME "VBoxNetDHCP"
    32 #endif
    33 
    3428static const ARGDEF g_aArgDefs[] =
    3529{
    36     {DHCPCFG_NAME, "--name"},
    37     {DHCPCFG_NETNAME, "--network"},
    38     {DHCPCFG_TRUNKTYPE, "--trunk-type"},
    39     {DHCPCFG_TRUNKNAME, "--trunk-name"},
    40     {DHCPCFG_MACADDRESS, "--mac-address"},
    41     {DHCPCFG_IPADDRESS, "--ip-address"},
    42     {DHCPCFG_LEASEDB, "--lease-db"},
    43     {DHCPCFG_VERBOSE, "--verbose"},
    44     {DHCPCFG_BEGINCONFIG, "--begin-config"},
    45     {DHCPCFG_GATEWAY, "--gateway"},
    46     {DHCPCFG_LOWERIP, "--lower-ip"},
    47     {DHCPCFG_UPPERIP, "--upper-ip"},
    48     {DHCPCFG_NETMASK, "--netmask"},
    49     {DHCPCFG_HELP, "--help"},
    50     {DHCPCFG_VERSION, "--version"}
     30    {NETCFG_NAME, "--name"},
     31    {NETCFG_NETNAME, "--network"},
     32    {NETCFG_TRUNKTYPE, "--trunk-type"},
     33    {NETCFG_TRUNKNAME, "--trunk-name"},
     34    {NETCFG_MACADDRESS, "--mac-address"},
     35    {NETCFG_IPADDRESS, "--ip-address"},
     36    {NETCFG_VERBOSE, "--verbose"},
     37    {NETCFG_NETMASK, "--netmask"},
    5138};
    5239
    53 static const ARGDEF * getArgDef(DHCPCFG type)
     40static const ARGDEF * getArgDef(NETCFG type)
    5441{
    5542    for (unsigned i = 0; i < RT_ELEMENTS(g_aArgDefs); i++)
     
    6047}
    6148
    62 DHCPServerRunner::DHCPServerRunner()
    63 {
    64     mProcess = NIL_RTPROCESS;
    65     for (unsigned i = 0; i < DHCPCFG_NOTOPT_MAXVAL; i++)
    66     {
    67         mOptionEnabled[i] = false;
    68     }
    69 }
    70 
    71 void DHCPServerRunner::detachFromServer()
     49void NetworkServiceRunner::detachFromServer()
    7250{
    7351    mProcess = NIL_RTPROCESS;
    7452}
    7553
    76 int DHCPServerRunner::start()
     54int NetworkServiceRunner::start()
    7755{
    7856    if (isRunning())
    7957        return VINF_ALREADY_INITIALIZED;
    8058
    81     const char * args[DHCPCFG_NOTOPT_MAXVAL * 2];
     59    const char * args[NETCFG_NOTOPT_MAXVAL * 2];
    8260
    8361    /* get the path to the executable */
     
    9169    {
    9270        suffix++;
    93         strcpy(suffix, DHCP_EXECUTABLE_NAME);
     71        strcpy(suffix, mProcName);
    9472    }
    95     else
    96         exePath = DHCP_EXECUTABLE_NAME;
    9773
    9874    int index = 0;
     
    10076    args[index++] = exePath;
    10177
    102     for (unsigned i = 0; i < DHCPCFG_NOTOPT_MAXVAL; i++)
     78    for (unsigned i = 0; i < NETCFG_NOTOPT_MAXVAL; i++)
    10379    {
    10480        if (mOptionEnabled[i])
    10581        {
    106             const ARGDEF *pArgDef = getArgDef((DHCPCFG)i);
     82            const ARGDEF *pArgDef = getArgDef((NETCFG)i);
    10783            if (!pArgDef)
    10884                continue;
    109             args[index++] = pArgDef->Name;      // e.g. "--network"
     85            args[index++] = pArgDef->Name;
    11086
    111             /* value can be null for e.g. --begin-config has no value
    112              * and thus check the mOptions string length here
    113              */
    11487            if (mOptions[i].length())
    11588                args[index++] = mOptions[i].c_str();  // value
     
    11992    args[index++] = NULL;
    12093
    121     int rc = RTProcCreate(exePath, args, RTENV_DEFAULT, 0, &mProcess);
     94    int rc = RTProcCreate(suffix ? exePath : mProcName, args, RTENV_DEFAULT, 0, &mProcess);
    12295    if (RT_FAILURE(rc))
    12396        mProcess = NIL_RTPROCESS;
     
    12699}
    127100
    128 int DHCPServerRunner::stop()
     101int NetworkServiceRunner::stop()
    129102{
    130103    if (!isRunning())
     
    136109}
    137110
    138 bool DHCPServerRunner::isRunning()
     111bool NetworkServiceRunner::isRunning()
    139112{
    140113    if (mProcess == NIL_RTPROCESS)
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r46969 r47018  
    6161#include "SystemPropertiesImpl.h"
    6262#include "GuestOSTypeImpl.h"
    63 #include "DHCPServerRunner.h"
     63#include "NetworkServiceRunner.h"
    6464#include "DHCPServerImpl.h"
    6565#include "NATNetworkImpl.h"
  • trunk/src/VBox/Main/src-server/xpcom/server.cpp

    r46969 r47018  
    6767#include "BandwidthControlImpl.h"
    6868#include "BandwidthGroupImpl.h"
    69 #include "DHCPServerRunner.h"
     69#include "NetworkServiceRunner.h"
    7070#include "DHCPServerImpl.h"
    7171#include "GuestOSTypeImpl.h"
  • trunk/src/VBox/Main/xml/Settings.cpp

    r46969 r47018  
    13021302            if (    (pelmServer->getAttributeValue("networkName", srv.strNetworkName))
    13031303                 && (pelmServer->getAttributeValue("IPAddress", srv.strIPAddress))
    1304                  && (pelmServer->getAttributeValue("networkMask", srv.strIPNetworkMask))
     1304                    && (pelmServer->getAttributeValue("networkMask", srv.GlobalDhcpOptions[DhcpOpt_SubnetMask]))
    13051305                 && (pelmServer->getAttributeValue("lowerIP", srv.strIPLower))
    13061306                 && (pelmServer->getAttributeValue("upperIP", srv.strIPUpper))
    13071307                 && (pelmServer->getAttributeValue("enabled", srv.fEnabled))
    13081308               )
     1309            {
     1310                xml::NodesLoop nlOptions(*pelmServer, "Options");
     1311                const xml::ElementNode *options;
     1312                /* XXX: Options are in 1:1 relation to DHCPServer */
     1313
     1314                while ((options = nlOptions.forAllNodes()))
     1315                {
     1316                    readDhcpOptions(srv.GlobalDhcpOptions, *options);
     1317                } /* end of forall("Options") */
     1318                xml::NodesLoop nlConfig(*pelmServer, "Config");
     1319                const xml::ElementNode *cfg;
     1320                while ((cfg = nlConfig.forAllNodes()))
     1321                {
     1322                    com::Utf8Str strVmName;
     1323                    uint32_t u32Slot;
     1324                    cfg->getAttributeValue("vm-name", strVmName);
     1325                    cfg->getAttributeValue("slot", (uint32_t&)u32Slot);
     1326                    readDhcpOptions(srv.VmSlot2OptionsM[VmNameSlotKey(strVmName, u32Slot)],
     1327                                   *cfg);
     1328                }
    13091329                llDhcpServers.push_back(srv);
     1330            }
    13101331            else
    13111332                throw ConfigFileError(this, pelmServer, N_("Required DHCPServer/@networkName, @IPAddress, @networkMask, @lowerIP, @upperIP or @enabled attribute is missing"));
    13121333        }
    13131334    }
     1335}
     1336
     1337void MainConfigFile::readDhcpOptions(DhcpOptionMap& map,
     1338                                     const xml::ElementNode& options)
     1339{
     1340    xml::NodesLoop nl2(options, "Option");
     1341    const xml::ElementNode *opt;
     1342    while((opt = nl2.forAllNodes()))
     1343    {
     1344        DhcpOpt_T OptName;
     1345        com::Utf8Str OptValue;
     1346        opt->getAttributeValue("name", (uint32_t&)OptName);
     1347
     1348        if (OptName == DhcpOpt_SubnetMask)
     1349            continue;
     1350
     1351        opt->getAttributeValue("value", OptValue);
     1352
     1353        map.insert(
     1354          std::map<DhcpOpt_T, Utf8Str>::value_type(OptName, OptValue));
     1355    } /* end of forall("Option") */
     1356
    13141357}
    13151358
     
    14461489#endif
    14471490        srv.strIPAddress = "192.168.56.100";
    1448         srv.strIPNetworkMask = "255.255.255.0";
     1491        srv.GlobalDhcpOptions[DhcpOpt_SubnetMask] = "255.255.255.0";
    14491492        srv.strIPLower = "192.168.56.101";
    14501493        srv.strIPUpper = "192.168.56.254";
     
    14891532        const DHCPServer &d = *it;
    14901533        xml::ElementNode *pelmThis = pelmDHCPServers->createChild("DHCPServer");
     1534        DhcpOptConstIterator itOpt;
     1535        itOpt = d.GlobalDhcpOptions.find(DhcpOpt_SubnetMask);
     1536
    14911537        pelmThis->setAttribute("networkName", d.strNetworkName);
    14921538        pelmThis->setAttribute("IPAddress", d.strIPAddress);
    1493         pelmThis->setAttribute("networkMask", d.strIPNetworkMask);
     1539        if (itOpt != d.GlobalDhcpOptions.end())
     1540            pelmThis->setAttribute("networkMask", itOpt->second);
    14941541        pelmThis->setAttribute("lowerIP", d.strIPLower);
    14951542        pelmThis->setAttribute("upperIP", d.strIPUpper);
    14961543        pelmThis->setAttribute("enabled", (d.fEnabled) ? 1 : 0);        // too bad we chose 1 vs. 0 here
    1497     }
     1544        /* We assume that if there're only 1 element it means that */
     1545        int cOpt = d.GlobalDhcpOptions.size();
     1546        /* We don't want duplicate validation check of networkMask here*/
     1547        if (   (   itOpt == d.GlobalDhcpOptions.end()
     1548                && cOpt > 0)
     1549            || cOpt > 1)
     1550        {
     1551            xml::ElementNode *pelmOptions = pelmThis->createChild("Options");
     1552            for (itOpt = d.GlobalDhcpOptions.begin();
     1553                 itOpt != d.GlobalDhcpOptions.end();
     1554                 ++itOpt)
     1555            {
     1556                if (itOpt->first == DhcpOpt_SubnetMask)
     1557                    continue;
     1558
     1559                xml::ElementNode *pelmOpt = pelmOptions->createChild("Option");
     1560
     1561                if (!pelmOpt)
     1562                    break;
     1563
     1564                pelmOpt->setAttribute("name", itOpt->first);
     1565                pelmOpt->setAttribute("value", itOpt->second);
     1566            }
     1567        } /* end of if */
     1568
     1569        if (d.VmSlot2OptionsM.size() > 0)
     1570        {
     1571            VmSlot2OptionsConstIterator itVmSlot;
     1572            DhcpOptConstIterator itOpt1;
     1573            for(itVmSlot = d.VmSlot2OptionsM.begin();
     1574                itVmSlot != d.VmSlot2OptionsM.end();
     1575                ++itVmSlot)
     1576            {
     1577                xml::ElementNode *pelmCfg = pelmThis->createChild("Config");
     1578                pelmCfg->setAttribute("vm-name", itVmSlot->first.VmName);
     1579                pelmCfg->setAttribute("slot", itVmSlot->first.Slot);
     1580
     1581                for (itOpt1 = itVmSlot->second.begin();
     1582                     itOpt1 != itVmSlot->second.end();
     1583                     ++itOpt1)
     1584                {
     1585                    xml::ElementNode *pelmOpt = pelmCfg->createChild("Option");
     1586                    pelmOpt->setAttribute("name", itOpt1->first);
     1587                    pelmOpt->setAttribute("value", itOpt1->second);
     1588                }
     1589            }
     1590        } /* and of if */
     1591
     1592     }
    14981593
    14991594    /* TODO: bump main version ? */
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