Index: trunk/include/VBox/settings.h
===================================================================
--- trunk/include/VBox/settings.h	(revision 46968)
+++ trunk/include/VBox/settings.h	(revision 46969)
@@ -286,27 +286,4 @@
 typedef std::list<MachineRegistryEntry> MachinesRegistry;
 
-typedef std::map<DhcpOpt_T, com::Utf8Str> DhcpOptionMap;
-typedef DhcpOptionMap::value_type DhcpOptValuePair;
-typedef DhcpOptionMap::iterator DhcpOptIterator;
-typedef DhcpOptionMap::const_iterator DhcpOptConstIterator;
-
-typedef struct VmNameSlotKey
-{
-    VmNameSlotKey(const com::Utf8Str& aVmName, LONG aSlot): VmName(aVmName),
-      Slot(aSlot){}
-    const com::Utf8Str VmName;
-    LONG      Slot;
-    bool operator< (const VmNameSlotKey& that) const
-    {
-        if (VmName == that.VmName)
-            return Slot < that.Slot;
-        else return VmName < that.VmName;
-    }
-} VmNameSlotKey;
-typedef std::map<VmNameSlotKey, DhcpOptionMap> VmSlot2OptionsMap;
-typedef VmSlot2OptionsMap::value_type VmSlot2OptionsPair;
-typedef VmSlot2OptionsMap::iterator VmSlot2OptionsIterator;
-typedef VmSlot2OptionsMap::const_iterator VmSlot2OptionsConstIterator;
-
 struct DHCPServer
 {
@@ -317,9 +294,8 @@
     com::Utf8Str    strNetworkName,
                     strIPAddress,
+                    strIPNetworkMask,
                     strIPLower,
                     strIPUpper;
     bool            fEnabled;
-    std::map<DhcpOpt_T, com::Utf8Str>  GlobalDhcpOptions;
-    VmSlot2OptionsMap VmSlot2OptionsM;
 };
 typedef std::list<DHCPServer> DHCPServersList;
@@ -361,5 +337,4 @@
     void readMachineRegistry(const xml::ElementNode &elmMachineRegistry);
     void readDHCPServers(const xml::ElementNode &elmDHCPServers);
-    void readDhcpOptions(DhcpOptionMap& map, const xml::ElementNode& options);
     void readNATNetworks(const xml::ElementNode &elmNATNetworks);
 
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp	(revision 46968)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp	(revision 46969)
@@ -40,8 +40,4 @@
 #include "VBoxManage.h"
 
-#include <string>
-#include <vector>
-#include <map>
-
 #ifndef VBOX_ONLY_DOCS
 using namespace com;
@@ -53,35 +49,4 @@
     OP_MODIFY
 } OPCODE;
-
-typedef std::map<DhcpOpt_T, std::string> DhcpOptMap;
-typedef DhcpOptMap::iterator DhcpOptIterator;
-typedef DhcpOptMap::value_type DhcpOptValuePair;
-
-struct VmNameSlotKey;
-typedef struct VmNameSlotKey VmNameSlotKey;
-
-struct VmNameSlotKey
-{
-    std::string VmName;
-    uint8_t u8Slot;
-
-    VmNameSlotKey(std::string aVmName, uint8_t aSlot) :
-      VmName(aVmName),
-      u8Slot(aSlot) {}
-
-    bool operator< (const VmNameSlotKey& that) const
-    {
-        if (VmName == that.VmName)
-            return u8Slot < that.u8Slot;
-        else
-            return VmName < that.VmName;
-    }
-};
-
-typedef std::map<VmNameSlotKey, DhcpOptMap> VmSlot2OptionsM;
-typedef VmSlot2OptionsM::iterator VmSlot2OptionsIterator;
-typedef VmSlot2OptionsM::value_type VmSlot2OptionsPair;
-
-typedef std::vector<VmNameSlotKey> VmConfigs;
 
 static const RTGETOPTDEF g_aDHCPIPOptions[]
@@ -107,11 +72,5 @@
         { "-enable",            'e', RTGETOPT_REQ_NOTHING },    // deprecated
         { "--disable",          'd', RTGETOPT_REQ_NOTHING },
-        { "-disable",           'd', RTGETOPT_REQ_NOTHING },     // deprecated
-        { "--options",          'o', RTGETOPT_REQ_NOTHING },     
-        {"--vm",                'n', RTGETOPT_REQ_STRING}, /* only with -o */
-        {"--slot",              's', RTGETOPT_REQ_UINT8}, /* only with -o and -n */
-        {"--id",                'i', RTGETOPT_REQ_UINT8}, /* only with -o */
-        {"--value",             'p', RTGETOPT_REQ_STRING} /* only with -i */
-
+        { "-disable",           'd', RTGETOPT_REQ_NOTHING }     // deprecated
       };
 
@@ -123,8 +82,5 @@
     int index = iStart;
     HRESULT rc;
-    bool fOptionsRead = false;
-    bool fVmOptionRead = false;
-
-    const char *pszVmName = NULL;
+
     const char *pNetName = NULL;
     const char *pIfName = NULL;
@@ -133,13 +89,5 @@
     const char * pLowerIp = NULL;
     const char * pUpperIp = NULL;
-
-    uint8_t u8OptId = -1;
-    uint8_t u8Slot = -1;
-
     int enable = -1;
-
-    DhcpOptMap GlobalDhcpOptions;
-    VmSlot2OptionsM VmSlot2Options;
-    VmConfigs       VmConfigs2Delete;
 
     int c;
@@ -228,79 +176,4 @@
                 return errorSyntax(USAGE_DHCPSERVER, "unhandled parameter: %s", ValueUnion.psz);
             break;
-
-            case 'o': // --options
-                {
-        // {"--vm",                'n', RTGETOPT_REQ_STRING}, /* only with -o */
-        // {"--slot",              's', RTGETOPT_REQ_UINT8}, /* only with -o and -n*/
-        // {"--id",                'i', RTGETOPT_REQ_UINT8}, /* only with -o */
-        // {"--value",             'p', RTGETOPT_REQ_STRING} /* only with -i */
-                    if (fOptionsRead)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "previos option edition  wasn't finished");
-                    fOptionsRead = true;
-                    fVmOptionRead = false; /* we want specify new global or vm option*/
-                    u8Slot = (uint8_t)~0;
-                    u8OptId = (uint8_t)~0;
-                    pszVmName = NULL;
-                } /* end of --options  */
-                break;
-
-            case 'n': // --vm-name
-                {
-                    if (fVmOptionRead)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "previous vm option edition wasn't finished");
-                    else
-                        fVmOptionRead = true;
-                    u8Slot = (uint8_t)~0; /* clear slor */
-                    pszVmName = RTStrDup(ValueUnion.psz);
-                }
-                break; /* end of --vm-name */
-
-            case 's': // --slot
-                {
-                    if (!fVmOptionRead)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "vm name wasn't specified");
-                    
-                    u8Slot = ValueUnion.u8;
-                }
-                break; /* end of --slot */
-
-            case 'i': // --id
-                {
-                    if (!fOptionsRead)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "-o wasn't found");
-
-                    u8OptId = ValueUnion.u8;
-                }
-                break; /* end of --id */
-
-            case 'p': // --value
-                {
-                    if (!fOptionsRead)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "-o wasn't found");
-                    
-                    if (u8OptId == (uint8_t)~0)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "--id wasn't found");
-                    if (   fVmOptionRead 
-                        && u8Slot == (uint8_t)~0)
-                        return errorSyntax(USAGE_DHCPSERVER, 
-                                           "--slot wasn't found");
-                    
-                    DhcpOptMap& map = (fVmOptionRead ? 
-                                       VmSlot2Options[
-                                         VmNameSlotKey::VmNameSlotKey(pszVmName, 
-                                                                      u8Slot)] 
-                                       : GlobalDhcpOptions);
-                    std::string strVal = ValueUnion.psz;
-                    map.insert(DhcpOptValuePair((DhcpOpt_T)u8OptId, strVal));
-
-                }
-                break; // --end of value
-
             default:
                 if (c > 0)
@@ -323,7 +196,5 @@
         return errorSyntax(USAGE_DHCPSERVER, "You need to specify either --netname or --ifname to identify the DHCP server");
 
-    if(   enmCode != OP_REMOVE
-       && GlobalDhcpOptions.size() == 0
-       && VmSlot2Options.size() == 0)
+    if(enmCode != OP_REMOVE)
     {
         if(enable < 0 || pIp || pNetmask || pLowerIp || pUpperIp)
@@ -383,9 +254,5 @@
         if (pIp || pNetmask || pLowerIp || pUpperIp)
         {
-            CHECK_ERROR(svr, SetConfiguration (
-                          Bstr(pIp).mutableRaw(), 
-                          Bstr(pNetmask).mutableRaw(), 
-                          Bstr(pLowerIp).mutableRaw(), 
-                          Bstr(pUpperIp).mutableRaw()));
+            CHECK_ERROR(svr, SetConfiguration (Bstr(pIp).mutableRaw(), Bstr(pNetmask).mutableRaw(), Bstr(pLowerIp).mutableRaw(), Bstr(pUpperIp).mutableRaw()));
             if(FAILED(rc))
                 return errorArgument("Failed to set configuration");
@@ -395,37 +262,4 @@
         {
             CHECK_ERROR(svr, COMSETTER(Enabled) ((BOOL)enable));
-        }
-
-        /* option processing */
-        DhcpOptIterator itOpt;
-        VmSlot2OptionsIterator it;
-        
-        /* Global Options */
-        for(itOpt = GlobalDhcpOptions.begin(); 
-            itOpt != GlobalDhcpOptions.end();
-            ++itOpt)
-        {
-            CHECK_ERROR(svr, 
-                        AddGlobalOption(
-                          itOpt->first, 
-                          com::Bstr(itOpt->second.c_str()).raw()));
-        }
-
-        /* heh, vm slot options. */
-
-        for (it = VmSlot2Options.begin();
-             it != VmSlot2Options.end();
-             ++it)
-        {
-            for(itOpt = it->second.begin();
-                itOpt != it->second.end();
-                ++itOpt)
-            {
-                CHECK_ERROR(svr, 
-                            AddVmSlotOption(Bstr(it->first.VmName.c_str()).raw(),
-                                            it->first.u8Slot,
-                                            itOpt->first, 
-                                            com::Bstr(itOpt->second.c_str()).raw()));
-            }
         }
     }
Index: trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- trunk/src/VBox/Main/Makefile.kmk	(revision 46968)
+++ trunk/src/VBox/Main/Makefile.kmk	(revision 46969)
@@ -335,6 +335,7 @@
 	src-server/BIOSSettingsImpl.cpp \
 	src-server/DHCPServerImpl.cpp \
-	src-server/NetworkServiceRunner.cpp \
+	src-server/DHCPServerRunner.cpp \
 	src-server/NATNetworkImpl.cpp \
+	$(if $(VBOX_WITH_NAT_SERVICE),src-server/NATNetworkServiceRunner.cpp,) \
 	src-server/GuestOSTypeImpl.cpp \
 	src-server/HostImpl.cpp \
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 46968)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 46969)
@@ -1466,75 +1466,7 @@
   </interface>
 
-  <enum 
-      name="DhcpOpt"
-      uuid="40d99bd3-3ece-44d2-a07e-1085fe9c4f0b">
-    <const name="SubnetMask" value="1"/>
-    <const name="TimeOffset" value="2"/>
-    <const name="Router" value="3"/>
-    <const name="TimeServer" value="4"/>
-    <const name="NameServer" value="5"/>
-    <const name="DomainNameServer" value="6"/>
-    <const name="LogServer" value="7"/>
-    <const name="Cookie" value="8"/>
-    <const name="LPRServer" value="9"/>
-    <const name="ImpressServer" value="10"/>
-    <const name="ResourseLocationServer" value="11"/>
-    <const name="HostName" value="12"/>
-    <const name="BootFileSize" value="13"/>
-    <const name="MeritDumpFile" value="14"/>    
-    <const name="DomainName" value="15"/>
-    <const name="SwapServer" value="16"/>
-    <const name="RootPath" value="17"/>
-    <const name="ExtensionPath" value="18"/>
-    <const name="IPForwardingEnableDisable" value="19"/>
-    <const name="NonLocalSourceRoutingEnableDisable" value="20"/>
-    <const name="PolicyFilter" value="21"/>
-    <const name="MaximumDatagramReassemblySize" value="22"/>
-    <const name="DefaultIPTime2Live" value="23"/>
-    <const name="PathMTUAgingTimeout" value="24"/>
-    <const name="IPLayerParametersPerInterface" value="25"/>
-    <const name="InterfaceMTU" value="26"/>
-    <const name="AllSubnetsAreLocal" value="27"/>
-    <const name="BroadcastAddress" value="28"/>
-    <const name="PerformMaskDiscovery" value="29"/>
-    <const name="MaskSupplier" value="30"/>
-    <const name="PerformRouteDiscovery" value="31"/>
-    <const name="RouterSolicitationAddress" value="32"/>
-    <const name="StaticRoute" value="33"/>
-    <const name="TrailerEncapsulation" value="34"/>
-    <const name="ARPCacheTimeout" value="35"/>
-    <const name="EthernetEncapsulation" value="36"/>
-    <const name="TCPDefaultTTL" value="37"/>
-    <const name="TCPKeepAliveInterval" value="38"/>
-    <const name="TCPKeepAliveGarbage" value="39"/>
-    <const name="NetworkInformationServiceDomain" value="40"/>
-    <const name="NetworkInformationServiceServers" value="41"/>
-    <const name="NetworkTimeProtocolServers" value="42"/>
-    <const name="VendorSpecificInformation" value="43"/>
-    <const name="Option_44" value="44"/>
-    <const name="Option_45" value="45"/>
-    <const name="Option_46" value="46"/>
-    <const name="Option_47" value="47"/>
-    <const name="Option_48" value="48"/>
-    <const name="Option_49" value="49"/>
-    <const name="IPAddressLeaseTime" value="51"/>
-    <const name="Option_64" value="64"/>
-    <const name="Option_65" value="65"/>
-    <const name="TFTPServerName" value="66"/>
-    <const name="BootfileName" value="67"/>
-    <const name="Option_68" value="68"/>
-    <const name="Option_69" value="69"/>
-    <const name="Option_70" value="70"/>
-    <const name="Option_71" value="71"/>
-    <const name="Option_72" value="72"/>
-    <const name="Option_73" value="73"/>
-    <const name="Option_74" value="74"/>
-    <const name="Option_75" value="75"/>
-    <const name="Option_119" value="119"/>
-  </enum>
-  
   <interface
     name="IDHCPServer" extends="$unknown"
-    uuid="ff0774c5-1f62-4bc3-919c-7fc942bf1d25"
+    uuid="6cfe387c-74fb-4ca7-bff6-973bec8af7a3"
     wsmap="managed"
     >
@@ -1545,6 +1477,5 @@
       <link to="IVirtualBox::DHCPServers"/> attribute.
     </desc>
-    <!-- We want to keep our "real" servers updated about configuration changes -->
-    <attribute name="eventSource" type="IEventSource" readonly="yes"/>
+
     <attribute name="enabled" type="boolean">
       <desc>
@@ -1582,60 +1513,4 @@
       </desc>
     </attribute>
-    
-    <method name="addGlobalOption">
-      <param name="option" type="DhcpOpt" dir="in"/>
-      <param name="value" type="wstring" dir="in" />
-    </method>
-    
-    <!-- string in format: "option_id:value" -->
-    <attribute name="globalOptions" type="wstring" safearray="yes" readonly="yes"/>
-
-    <!-- string in format: "[vm name]:slot" -->
-    <attribute name="vmConfigs" type="wstring" safearray="yes" readonly="yes"/>
-
-    <!-- VM-slot settings 
-	 It's corresponds to dhcpd.conf entries, like:
-
-	 host ncd1 { hardware ethernet 0:c0:c3:11:90:23; }
-
-	 - in Main we can match (vm name, slot) to ethernet address
-	 that why it's easy to configure dhcp server in such way, 
-	 then ask user to to enter valid name, 
-	 
-	 - mac address might change because of adapter type (e1k <-> pcnet) or because
-	 of import/export
-	 
-	 - it's easy to provide vm-name.rom in boot filename VM with network boot.
-	 
-	 XXX: do we need classic getOptionValueByMAC?
-	 
-	 XML: O-o-oh, this settings are per VM, so perhaps they should be stored in
-	      VM configuration files. And we haven't got the attachment type for 
-	      NATNetwork.
-    -->
-    <method name="addVmSlotOption">
-      <param name="vmname" type="wstring" dir="in"/>
-      <param name="slot" type="long" dir="in"/>
-      <param name="option" type="DhcpOpt" dir="in"/>
-      <param name="value" type="wstring" dir="in" />
-    </method>
-
-    <method name="removeVmSlotOptions">
-      <param name="vmname" type="wstring" dir="in"/>
-      <param name="slot" type="long" dir="in"/>
-    </method>
-
-    <!-- returns array of strings in format: "option_id:value" for a given pair (vm, slot) -->
-    <method name="getVmSlotOptions">
-      <param name="vmname" type="wstring" dir="in"/>
-      <param name="slot" type="long" dir="in"/>
-      <param name="option" type="wstring" safearray="yes" dir="return"/>
-    </method>
-    
-    <!-- Returns options by MAC address -->
-    <method name="getMacOptions">
-      <param name="mac" type="wstring" dir="in"/>
-      <param name="option" type="wstring" safearray="yes" dir="return"/>
-    </method>
 
     <method name="setConfiguration">
@@ -8163,5 +8038,5 @@
   <interface
     name="IHost" extends="$unknown"
-    uuid="a6107246-f939-42c4-82b6-8aca40327b6d"
+    uuid="30678943-32df-4830-b413-931b25ac86a0"
     wsmap="managed"
     >
@@ -8224,16 +8099,4 @@
     <attribute name="networkInterfaces" type="IHostNetworkInterface" safearray="yes" readonly="yes">
       <desc>List of host network interfaces currently defined on the host.</desc>
-    </attribute>
-
-    <attribute name="nameServers" type="wstring" safearray="yes" readonly="yes">
-      <desc> The list of nameservers registered in host's name resolving system.</desc>
-    </attribute>
-
-    <attribute name="domainName" type="wstring" readonly="yes">
-      <desc>Domain name used for name resoving.</desc>
-    </attribute>
-
-    <attribute name="searchStrings" type="wstring" safearray="yes" readonly="yes">
-      <desc>Search string registered for name resoving.</desc>
     </attribute>
 
Index: trunk/src/VBox/Main/include/DHCPServerImpl.h
===================================================================
--- trunk/src/VBox/Main/include/DHCPServerImpl.h	(revision 46968)
+++ trunk/src/VBox/Main/include/DHCPServerImpl.h	(revision 46969)
@@ -30,41 +30,5 @@
 {
     struct DHCPServer;
-    struct VmNameSlotKey;
 }
-#ifdef RT_OS_WINDOWS
-# define DHCP_EXECUTABLE_NAME "VBoxNetDHCP.exe"
-#else
-# define DHCP_EXECUTABLE_NAME "VBoxNetDHCP"
-#endif
-
-class DHCPServerRunner: public NetworkServiceRunner
-{
-public:
-    DHCPServerRunner():NetworkServiceRunner(DHCP_EXECUTABLE_NAME){}
-    virtual ~DHCPServerRunner(){};
-};
-
-/**
- *  for server configuration needs, it's perhaps better to use (VM,slot) pair
- *  (vm-name, slot) <----> (MAC)
- *  
- *  but for client configuration, when server will have MACs at hand, it'd be
- *  easier to requiest options by MAC.
- *  (MAC) <----> (option-list)
- *
- *  Doubts: What should be done if MAC changed for (vm-name, slot), when syncing should? 
- *  XML: serialization of dependecy (DHCP options) - (VM,slot) shouldn't be done via MAC in 
- *  the middle.
- */
-
-typedef std::map<DhcpOpt_T, com::Utf8Str> DhcpOptionMap;
-typedef DhcpOptionMap::value_type DhcpOptValuePair;
-typedef DhcpOptionMap::const_iterator DhcpOptConstIterator;
-typedef DhcpOptionMap::iterator DhcpOptIterator;
-
-typedef std::map<settings::VmNameSlotKey, DhcpOptionMap> VmSlot2OptionsMap;
-typedef VmSlot2OptionsMap::value_type VmSlot2OptionsPair;
-typedef VmSlot2OptionsMap::iterator VmSlot2OptionsIterator;
-
 
 class ATL_NO_VTABLE DHCPServer :
@@ -106,14 +70,4 @@
     STDMETHOD(COMGETTER(UpperIP))(BSTR *aIPAddress);
 
-    STDMETHOD(AddGlobalOption)(DhcpOpt_T aOption, IN_BSTR aValue);
-    STDMETHOD(COMGETTER(GlobalOptions))(ComSafeArrayOut(BSTR, aValue));
-    STDMETHOD(COMGETTER(VmConfigs))(ComSafeArrayOut(BSTR, aValue));
-    STDMETHOD(AddVmSlotOption)(IN_BSTR aVmName, LONG aSlot, DhcpOpt_T aOption, IN_BSTR aValue);
-    STDMETHOD(RemoveVmSlotOptions)(IN_BSTR aVmName, LONG aSlot);
-    STDMETHOD(GetVmSlotOptions)(IN_BSTR aVmName, LONG aSlot, ComSafeArrayOut(BSTR, aValues));
-    STDMETHOD(GetMacOptions)(IN_BSTR aMAC, ComSafeArrayOut(BSTR, aValues));
-    STDMETHOD(COMGETTER(EventSource))(IEventSource **aEventSource);
-    
-
     STDMETHOD(SetConfiguration)(IN_BSTR aIPAddress, IN_BSTR aNetworkMask, IN_BSTR aFromIPAddress, IN_BSTR aToIPAddress);
 
@@ -132,16 +86,12 @@
 
         Bstr IPAddress;
+        Bstr networkMask;
         Bstr lowerIP;
         Bstr upperIP;
+        BOOL enabled;
 
-        BOOL enabled;
         DHCPServerRunner dhcp;
-        
-        DhcpOptionMap GlobalDhcpOptions;
-        VmSlot2OptionsMap VmSlot2Options;
     } m;
-    
-    DhcpOptionMap& findOptMapByVmNameSlot(const com::Utf8Str& aVmName, 
-                                   LONG Slot);
+
 };
 
Index: trunk/src/VBox/Main/include/HostImpl.h
===================================================================
--- trunk/src/VBox/Main/include/HostImpl.h	(revision 46968)
+++ trunk/src/VBox/Main/include/HostImpl.h	(revision 46969)
@@ -62,8 +62,4 @@
     STDMETHOD(COMGETTER(USBDeviceFilters))(ComSafeArrayOut(IHostUSBDeviceFilter *, aUSBDeviceFilters));
     STDMETHOD(COMGETTER(NetworkInterfaces))(ComSafeArrayOut(IHostNetworkInterface *, aNetworkInterfaces));
-    STDMETHOD(COMGETTER(NameServers))(ComSafeArrayOut(BSTR, aNameServers));
-    STDMETHOD(COMGETTER(DomainName))(BSTR *aDomainName);
-    STDMETHOD(COMGETTER(SearchStrings))(ComSafeArrayOut(BSTR, aSearchStrings));
-
     STDMETHOD(COMGETTER(ProcessorCount))(ULONG *count);
     STDMETHOD(COMGETTER(ProcessorOnlineCount))(ULONG *count);
@@ -151,10 +147,4 @@
     HRESULT updateNetIfList();
 
-#ifndef RT_OS_WINDOWS
-    HRESULT parseResolvConf();
-#else
-    HRESULT fetchNameResolvingInformation();
-#endif
-
 #ifdef VBOX_WITH_RESOURCE_USAGE_API
     void registerMetrics(PerformanceCollector *aCollector);
Index: trunk/src/VBox/Main/include/NATNetworkImpl.h
===================================================================
--- trunk/src/VBox/Main/include/NATNetworkImpl.h	(revision 46968)
+++ trunk/src/VBox/Main/include/NATNetworkImpl.h	(revision 46969)
@@ -37,16 +37,4 @@
 }
 
-#ifdef RT_OS_WINDOWS
-# define NATSR_EXECUTABLE_NAME "VBoxNetLwipNAT.exe"
-#else
-# define NATSR_EXECUTABLE_NAME "VBoxNetLwipNAT"
-#endif
-
-class NATNetworkServiceRunner: public NetworkServiceRunner
-{
-public: 
-    NATNetworkServiceRunner(): NetworkServiceRunner(NATSR_EXECUTABLE_NAME){}
-    virtual ~NATNetworkServiceRunner(){}
-};
 
 class ATL_NO_VTABLE NATNetwork :
Index: trunk/src/VBox/Main/include/NetworkServiceRunner.h
===================================================================
--- trunk/src/VBox/Main/include/NetworkServiceRunner.h	(revision 46968)
+++ 	(revision )
@@ -1,79 +1,0 @@
-/* $Id$ */
-/** @file
- * VirtualBox Main - interface for VBox DHCP server
- */
-
-/*
- * Copyright (C) 2009-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-#include <iprt/err.h>
-#include <iprt/types.h>
-#include <iprt/string.h>
-#include <iprt/mem.h>
-#include <VBox/com/string.h>
-
-typedef enum
-{
-    NETCFG_NAME = 1,
-    NETCFG_NETNAME,
-    NETCFG_TRUNKTYPE,
-    NETCFG_TRUNKNAME,
-    NETCFG_MACADDRESS,
-    NETCFG_IPADDRESS,
-    NETCFG_NETMASK,
-    NETCFG_VERBOSE,
-    NETCFG_NOTOPT_MAXVAL
-}NETCFG;
-
-#define TRUNKTYPE_WHATEVER "whatever"
-#define TRUNKTYPE_NETFLT   "netflt"
-#define TRUNKTYPE_NETADP   "netadp"
-#define TRUNKTYPE_SRVNAT   "srvnat"
-
-class NetworkServiceRunner
-{
-public:
-    NetworkServiceRunner(const char *aProcName):
-      mProcName(aProcName),
-      mProcess(NIL_RTPROCESS)
-    {
-        memset(mOptionEnabled, 0, sizeof(mOptionEnabled));
-    };
-    ~NetworkServiceRunner() { stop(); /* don't leave abandoned servers */}
-
-    int setOption(NETCFG opt, const char *val, bool enabled)
-    {
-        if (opt == 0 || opt >= NETCFG_NOTOPT_MAXVAL)
-            return VERR_INVALID_PARAMETER;
-        if (isRunning())
-            return VERR_INVALID_STATE;
-
-        mOptions[opt] = val;
-        mOptionEnabled[opt] = enabled;
-        return VINF_SUCCESS;
-    }
-
-    int setOption(NETCFG opt, const com::Utf8Str &val, bool enabled)
-    {
-        return setOption(opt, val.c_str(), enabled);
-    }
-
-    int start();
-    int stop();
-    bool isRunning();
-
-    void detachFromServer();
-private:
-    com::Utf8Str mOptions[NETCFG_NOTOPT_MAXVAL];
-    bool mOptionEnabled[NETCFG_NOTOPT_MAXVAL];
-    const char *mProcName;
-    RTPROCESS mProcess;
-};
Index: trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 46968)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 46969)
@@ -115,5 +115,5 @@
 #endif /* VBOX_WITH_NETFLT */
 
-#include "NetworkServiceRunner.h"
+#include "DHCPServerRunner.h"
 #include "BusAssignmentManager.h"
 #ifdef VBOX_WITH_EXTPACK
Index: trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp	(revision 46968)
+++ trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp	(revision 46969)
@@ -18,5 +18,5 @@
  */
 
-#include "NetworkServiceRunner.h"
+#include "DHCPServerRunner.h"
 #include "DHCPServerImpl.h"
 #include "AutoCaller.h"
@@ -25,5 +25,4 @@
 #include <iprt/cpp/utils.h>
 
-#include <VBox/com/array.h>
 #include <VBox/settings.h>
 
@@ -38,10 +37,8 @@
 }
 
-
 DHCPServer::~DHCPServer()
 {
 }
 
-
 HRESULT DHCPServer::FinalConstruct()
 {
@@ -49,5 +46,4 @@
 }
 
-
 void DHCPServer::FinalRelease()
 {
@@ -56,5 +52,4 @@
     BaseFinalRelease();
 }
-
 
 void DHCPServer::uninit()
@@ -68,5 +63,4 @@
 }
 
-
 HRESULT DHCPServer::init(VirtualBox *aVirtualBox, IN_BSTR aName)
 {
@@ -81,7 +75,6 @@
     unconst(mName) = aName;
     m.IPAddress = "0.0.0.0";
-    m.GlobalDhcpOptions.insert(DhcpOptValuePair(DhcpOpt_SubnetMask, Bstr("0.0.0.0")));
+    m.networkMask = "0.0.0.0";
     m.enabled = FALSE;
-    
     m.lowerIP = "0.0.0.0";
     m.upperIP = "0.0.0.0";
@@ -92,5 +85,4 @@
     return S_OK;
 }
-
 
 HRESULT DHCPServer::init(VirtualBox *aVirtualBox,
@@ -106,22 +98,13 @@
     unconst(mName) = data.strNetworkName;
     m.IPAddress = data.strIPAddress;
+    m.networkMask = data.strIPNetworkMask;
     m.enabled = data.fEnabled;
     m.lowerIP = data.strIPLower;
     m.upperIP = data.strIPUpper;
 
-    
-    m.GlobalDhcpOptions.clear();
-    m.GlobalDhcpOptions.insert(data.GlobalDhcpOptions.begin(), 
-                               data.GlobalDhcpOptions.end());
-
-    m.VmSlot2Options.clear();
-    m.VmSlot2Options.insert(data.VmSlot2OptionsM.begin(),
-                            data.VmSlot2OptionsM.end());
-
     autoInitSpan.setSucceeded();
 
     return S_OK;
 }
-
 
 HRESULT DHCPServer::saveSettings(settings::DHCPServer &data)
@@ -134,20 +117,11 @@
     data.strNetworkName = mName;
     data.strIPAddress = m.IPAddress;
-
+    data.strIPNetworkMask = m.networkMask;
     data.fEnabled = !!m.enabled;
     data.strIPLower = m.lowerIP;
     data.strIPUpper = m.upperIP;
 
-    data.GlobalDhcpOptions.clear();
-    data.GlobalDhcpOptions.insert(m.GlobalDhcpOptions.begin(), 
-                                  m.GlobalDhcpOptions.end());
-    
-    data.VmSlot2OptionsM.clear();
-    data.VmSlot2OptionsM.insert(m.VmSlot2Options.begin(),
-                                m.VmSlot2Options.end());
-    
-    return S_OK;
-}
-
+    return S_OK;
+}
 
 STDMETHODIMP DHCPServer::COMGETTER(NetworkName) (BSTR *aName)
@@ -163,5 +137,4 @@
 }
 
-
 STDMETHODIMP DHCPServer::COMGETTER(Enabled) (BOOL *aEnabled)
 {
@@ -175,5 +148,4 @@
     return S_OK;
 }
-
 
 STDMETHODIMP DHCPServer::COMSETTER(Enabled) (BOOL aEnabled)
@@ -193,5 +165,4 @@
 }
 
-
 STDMETHODIMP DHCPServer::COMGETTER(IPAddress) (BSTR *aIPAddress)
 {
@@ -206,5 +177,4 @@
 }
 
-
 STDMETHODIMP DHCPServer::COMGETTER(NetworkMask) (BSTR *aNetworkMask)
 {
@@ -214,9 +184,8 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    m.GlobalDhcpOptions[DhcpOpt_SubnetMask].cloneTo(aNetworkMask);
-
-    return S_OK;
-}
-
+    m.networkMask.cloneTo(aNetworkMask);
+
+    return S_OK;
+}
 
 STDMETHODIMP DHCPServer::COMGETTER(LowerIP) (BSTR *aIPAddress)
@@ -226,5 +195,5 @@
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
-    
+
     m.lowerIP.cloneTo(aIPAddress);
 
@@ -232,5 +201,4 @@
 }
 
-
 STDMETHODIMP DHCPServer::COMGETTER(UpperIP) (BSTR *aIPAddress)
 {
@@ -244,5 +212,4 @@
     return S_OK;
 }
-
 
 STDMETHODIMP DHCPServer::SetConfiguration (IN_BSTR aIPAddress, IN_BSTR aNetworkMask, IN_BSTR aLowerIP, IN_BSTR aUpperIP)
@@ -258,6 +225,5 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     m.IPAddress = aIPAddress;
-    m.GlobalDhcpOptions[DhcpOpt_SubnetMask] = aNetworkMask;
-
+    m.networkMask = aNetworkMask;
     m.lowerIP = aLowerIP;
     m.upperIP = aUpperIP;
@@ -269,197 +235,4 @@
 }
 
-
-STDMETHODIMP DHCPServer::AddGlobalOption(DhcpOpt_T aOption, IN_BSTR aValue)
-{
-    CheckComArgStr(aValue);
-    /* store global option */
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-    
-    m.GlobalDhcpOptions.insert(
-      DhcpOptValuePair(aOption, Utf8Str(aValue)));
-
-    alock.release();
-
-    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
-    return mVirtualBox->saveSettings();
-}
-
-
-STDMETHODIMP DHCPServer::COMGETTER(GlobalOptions)(ComSafeArrayOut(BSTR, aValue))
-{
-    CheckComArgOutSafeArrayPointerValid(aValue);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    SafeArray<BSTR> sf(m.GlobalDhcpOptions.size());
-    int i = 0;
-    
-    for (DhcpOptIterator it = m.GlobalDhcpOptions.begin(); 
-         it != m.GlobalDhcpOptions.end(); ++it)
-    {
-        Bstr(Utf8StrFmt("%d:%s", (*it).first, (*it).second.c_str())).detachTo(&sf[i]);
-        i++;
-    }
-
-    sf.detachTo(ComSafeArrayOutArg(aValue));
-
-    return S_OK;
-}
-
-
-STDMETHODIMP DHCPServer::COMGETTER(VmConfigs)(ComSafeArrayOut(BSTR, aValue))
-{
-    CheckComArgOutSafeArrayPointerValid(aValue);
-    
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    SafeArray<BSTR> sf(m.VmSlot2Options.size());
-    VmSlot2OptionsIterator it = m.VmSlot2Options.begin();
-    int i = 0;
-    for (;it != m.VmSlot2Options.end(); ++it)
-    {
-        Bstr(Utf8StrFmt("[%s]:%d", 
-                        it->first.VmName.c_str(), 
-                        it->first.Slot)).detachTo(&sf[i]);
-        i++;
-    }
-
-    sf.detachTo(ComSafeArrayOutArg(aValue));
-
-    return S_OK;
-}
-
-
-STDMETHODIMP DHCPServer::AddVmSlotOption(IN_BSTR aVmName, LONG aSlot, DhcpOpt_T aOption, IN_BSTR aValue)
-{
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    m.VmSlot2Options[settings::VmNameSlotKey(
-          com::Utf8Str(aVmName), 
-          aSlot)][aOption] = com::Utf8Str(aValue);
-
-
-    alock.release();
-
-    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);    
-    return mVirtualBox->saveSettings();
-}
-
-
-STDMETHODIMP DHCPServer::RemoveVmSlotOptions(IN_BSTR aVmName, LONG aSlot)
-{
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    DhcpOptionMap& map = findOptMapByVmNameSlot(com::Utf8Str(aVmName), aSlot);
-
-    map.clear();
-    
-    alock.release();    
-
-    AutoWriteLock vboxLock(mVirtualBox COMMA_LOCKVAL_SRC_POS);
-    return mVirtualBox->saveSettings();
-}
-
-
-/**
- * this is mapping (vm, slot) 
- */
-STDMETHODIMP DHCPServer::GetVmSlotOptions(IN_BSTR aVmName, LONG aSlot, ComSafeArrayOut(BSTR, aValues))
-{
-    CheckComArgOutSafeArrayPointerValid(aValues);
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    DhcpOptionMap& map = findOptMapByVmNameSlot(com::Utf8Str(aVmName), aSlot);
-
-    SafeArray<BSTR> sf(map.size());
-    int i = 0;
-    
-    for (DhcpOptIterator it = map.begin(); 
-         it != map.end(); ++it)
-    {
-        Bstr(Utf8StrFmt("%d:%s", (*it).first, (*it).second.c_str())).detachTo(&sf[i]);
-        i++;
-    }
-
-    sf.detachTo(ComSafeArrayOutArg(aValues));
-
-    return S_OK;
-}
-
-
-STDMETHODIMP DHCPServer::GetMacOptions(IN_BSTR aMAC, ComSafeArrayOut(BSTR, aValues))
-{
-    CheckComArgOutSafeArrayPointerValid(aValues);
-    
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-    HRESULT hrc;
-
-    ComPtr<IMachine> machine;
-    ComPtr<INetworkAdapter> nic;
-    
-    VmSlot2OptionsIterator it;
-    for(it = m.VmSlot2Options.begin();
-        it != m.VmSlot2Options.end();
-        ++it)
-    {
-
-        alock.release();
-        hrc = mVirtualBox->FindMachine(Bstr(it->first.VmName).raw(), machine.asOutParam());
-        alock.acquire();    
-
-        if (FAILED(hrc))
-            continue;
-
-        alock.release();
-        hrc = machine->GetNetworkAdapter(it->first.Slot, nic.asOutParam());
-        alock.acquire();
-
-        if (FAILED(hrc))
-            continue;
-    
-        com::Bstr mac;
-
-        alock.release();
-        hrc = nic->COMGETTER(MACAddress)(mac.asOutParam());
-        alock.acquire();
-
-        if (FAILED(hrc)) /* no MAC address ??? */
-            break;
-    
-        if (!RTStrICmp(com::Utf8Str(mac).c_str(), com::Utf8Str(aMAC).c_str()))
-            return GetVmSlotOptions(Bstr(it->first.VmName).raw(), 
-                                    it->first.Slot, 
-                                    ComSafeArrayOutArg(aValues));
-    } /* end of for */
-    
-    return hrc;
-}
-
-
-STDMETHODIMP DHCPServer::COMGETTER(EventSource)(IEventSource **aEventSource)
-{
-    ReturnComNotImplemented();
-}
-
-
 STDMETHODIMP DHCPServer::Start(IN_BSTR aNetworkName, IN_BSTR aTrunkName, IN_BSTR aTrunkType)
 {
@@ -467,42 +240,37 @@
     if (!m.enabled)
         return S_OK;
-    
-    /* Commmon Network Settings */
-    m.dhcp.setOption(NETCFG_NETNAME, Utf8Str(aNetworkName), true);
-
+
+    m.dhcp.setOption(DHCPCFG_NETNAME, Utf8Str(aNetworkName), true);
     Bstr tmp(aTrunkName);
-
     if (!tmp.isEmpty())
-        m.dhcp.setOption(NETCFG_TRUNKNAME, Utf8Str(tmp), true);
-    m.dhcp.setOption(NETCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
-
-    /* XXX: should this MAC default initialization moved to NetworkServiceRunner? */
+        m.dhcp.setOption(DHCPCFG_TRUNKNAME, Utf8Str(tmp), true);
+    m.dhcp.setOption(DHCPCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
+    //temporary hack for testing
+    //    DHCPCFG_NAME
     char strMAC[32];
     Guid guid;
     guid.create();
     RTStrPrintf (strMAC, sizeof(strMAC), "08:00:27:%02X:%02X:%02X",
-                 guid.raw()->au8[0],
-                 guid.raw()->au8[1],
-                 guid.raw()->au8[2]);
-    m.dhcp.setOption(NETCFG_MACADDRESS, strMAC, true);
-    m.dhcp.setOption(NETCFG_IPADDRESS,  Utf8Str(m.IPAddress), true);
-    m.dhcp.setOption(NETCFG_NETMASK, Utf8Str(m.GlobalDhcpOptions[DhcpOpt_SubnetMask]), true);
-    
-    /* XXX: This parameters Dhcp Server will fetch via API */
+                 guid.raw()->au8[0], guid.raw()->au8[1], guid.raw()->au8[2]);
+    m.dhcp.setOption(DHCPCFG_MACADDRESS, strMAC, true);
+    m.dhcp.setOption(DHCPCFG_IPADDRESS,  Utf8Str(m.IPAddress), true);
+    //        DHCPCFG_LEASEDB,
+    //        DHCPCFG_VERBOSE,
+    //        DHCPCFG_GATEWAY,
+    m.dhcp.setOption(DHCPCFG_LOWERIP,  Utf8Str(m.lowerIP), true);
+    m.dhcp.setOption(DHCPCFG_UPPERIP,  Utf8Str(m.upperIP), true);
+    m.dhcp.setOption(DHCPCFG_NETMASK,  Utf8Str(m.networkMask), true);
+
+    //        DHCPCFG_HELP,
+    //        DHCPCFG_VERSION,
+    //        DHCPCFG_NOTOPT_MAXVAL
+    m.dhcp.setOption(DHCPCFG_BEGINCONFIG,  "", true);
+
     return RT_FAILURE(m.dhcp.start()) ? E_FAIL : S_OK;
     //m.dhcp.detachFromServer(); /* need to do this to avoid server shutdown on runner destruction */
 }
 
-
 STDMETHODIMP DHCPServer::Stop (void)
 {
     return RT_FAILURE(m.dhcp.stop()) ? E_FAIL : S_OK;
 }
-
-DhcpOptionMap& DHCPServer::findOptMapByVmNameSlot(const com::Utf8Str& aVmName, 
-                                           LONG aSlot)
-{
-    return m.VmSlot2Options[settings::VmNameSlotKey(
-          com::Utf8Str(aVmName),
-          aSlot)];
-}
Index: trunk/src/VBox/Main/src-server/HostImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/HostImpl.cpp	(revision 46968)
+++ trunk/src/VBox/Main/src-server/HostImpl.cpp	(revision 46969)
@@ -134,8 +134,6 @@
 #include <iprt/mem.h>
 #include <iprt/system.h>
-#ifndef RT_OS_WINDOWS
+#ifdef RT_OS_SOLARIS
 # include <iprt/path.h>
-#endif
-#ifdef RT_OS_SOLARIS
 # include <iprt/ctype.h>
 #endif
@@ -217,43 +215,6 @@
 
     HostPowerService        *pHostPowerService;
-
-    /* Name resolving */
-    std::list<com::Bstr>     llNameServers;
-    std::list<com::Bstr>     llSearchStrings;
-    Bstr                     DomainName;
-    /* XXX: we need timestamp when these values were set, on repeate in some 
-     *  (~1h?, 5 min?) period, this values should be refetched from host syetem.
-     */
 };
 
-#ifndef RT_OS_WINDOWS
-static char g_aszResolvConf[RTPATH_MAX];
-
-static inline char *getResolvConfPath()
-{
-    int rc = VINF_SUCCESS;
-    if (!g_aszResolvConf[0]) return g_aszResolvConf;
-# ifdef RT_OS_OS2
-    /*
-     * This was in an old Slirp code:
-     * IBM's "Technical Document # - 16070238", clearly says \MPTN\ETC\RESOLV2 
-     * no redolv.conf (remark to code in old Slirp code)
-     */
-    if (RTEnvExists("ETC"))
-    {
-        RTStrmPrintf(g_aszResolvConf, MAX_PATH, "%/RESOLV2", RTEnvGet("ETC"));
-        rc = RTFileExists(g_aszResolvConf);
-        if (RT_SUCCESS(rc))
-            return g_aszResolvConf;
-    }
-
-    RT_ZERO(g_aszResolvConf);
-    RTStrmPrintf(g_aszResolvConf, MAX_PATH, "%/RESOLV2", _PATH_ETC);
-# else
-    strcmp(g_aszResolvConf, "/etc/resolv.conf");
-# endif    
-    return g_aszResolvConf;
-}
-#endif
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -836,32 +797,4 @@
 #endif
 }
-
-
-/**
- * This method return the list of registered name servers 
- */
-STDMETHODIMP Host::COMGETTER(NameServers)(ComSafeArrayOut(BSTR, aNameServers))
-{
-    return E_NOTIMPL;
-}
-
-
-/**
- * This method returns the domain name of the host
- */
-STDMETHODIMP Host::COMGETTER(DomainName)(BSTR *aDomainName)
-{
-    return E_NOTIMPL;
-}
-
-
-/**
- * This method returns the search string.
- */
-STDMETHODIMP Host::COMGETTER(SearchStrings)(ComSafeArrayOut(BSTR, aSearchStrings))
-{
-    return E_NOTIMPL;
-}
-
 
 STDMETHODIMP Host::COMGETTER(USBDeviceFilters)(ComSafeArrayOut(IHostUSBDeviceFilter*, aUSBDeviceFilters))
Index: trunk/src/VBox/Main/src-server/NATNetworkImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/NATNetworkImpl.cpp	(revision 46968)
+++ trunk/src/VBox/Main/src-server/NATNetworkImpl.cpp	(revision 46969)
@@ -18,5 +18,5 @@
  */
 
-#include "NetworkServiceRunner.h"
+#include "DHCPServerRunner.h"
 #include "DHCPServerImpl.h"
 #include "NATNetworkImpl.h"
@@ -35,4 +35,5 @@
 #include "VBoxEvents.h"
 
+#include "NATNetworkServiceRunner.h"
 #include "VirtualBoxImpl.h"
 
@@ -631,11 +632,26 @@
 
     if (!m->fEnabled) return S_OK;
-
-    m->NATRunner.setOption(NETCFG_NETNAME, mName, true);
-    m->NATRunner.setOption(NETCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
-    m->NATRunner.setOption(NETCFG_IPADDRESS, m->IPv4Gateway, true);
-    m->NATRunner.setOption(NETCFG_NETMASK, m->IPv4NetworkMask, true);
-
-    /* No portforwarding rules from command-line, all will be fetched via API */
+    m->NATRunner.setOption(NATSCCFG_NAME, mName, true);
+    m->NATRunner.setOption(NATSCCFG_TRUNKTYPE, Utf8Str(aTrunkType), true);
+    m->NATRunner.setOption(NATSCCFG_IPADDRESS, m->IPv4Gateway, true);
+    m->NATRunner.setOption(NATSCCFG_NETMASK, m->IPv4NetworkMask, true);
+    
+    /* port-forwarding */
+    
+    for (constNATRuleMapIterator it = m->mapName2PortForwardRule4.begin();
+	 it != m->mapName2PortForwardRule4.end(); ++it)
+    {
+	settings::NATRule r = it->second;
+	m->NATRunner.setOption(NATSCCFG_PORTFORWARD4, 
+			       Bstr(Utf8StrFmt("%s:%d:[%s]:%d:[%s]:%d",
+					       r.strName.c_str(),
+					       r.proto,
+					       r.strHostIP.isEmpty() ? 
+					              "0.0.0.0" :
+					               r.strHostIP.c_str(),
+					       r.u16HostPort,
+					       r.strGuestIP.c_str(),
+					       r.u16GuestPort)), true);
+    }
 
     if (m->fNeedDhcpServer)
@@ -666,5 +682,5 @@
                   return E_FAIL;
                 /* breakthrough */
-
+            case S_OK:
             {
                 LogFunc(("gateway: %s, dhcpserver:%s, dhcplowerip:%s, dhcpupperip:%s\n", 
@@ -673,16 +689,14 @@
                          Utf8Str(m->IPv4DhcpServerLowerIp.raw()).c_str(), 
                          Utf8Str(m->IPv4DhcpServerUpperIp.raw()).c_str()));
-
-                m->dhcpServer->AddGlobalOption(DhcpOpt_Router, m->IPv4Gateway.raw());
+                         
 
                 rc = m->dhcpServer->SetEnabled(true);
-
                 BSTR dhcpip = NULL;
                 BSTR netmask = NULL;
                 BSTR lowerip = NULL;
                 BSTR upperip = NULL;
-
                 m->IPv4DhcpServer.cloneTo(&dhcpip);
                 m->IPv4NetworkMask.cloneTo(&netmask);
+                
                 m->IPv4DhcpServerLowerIp.cloneTo(&lowerip); 
                 m->IPv4DhcpServerUpperIp.cloneTo(&upperip);
@@ -691,10 +705,9 @@
                                                      lowerip,
                                                      upperip);
+            break;
             }
-            case S_OK:
-                break;
-                
-            default:
-                return E_FAIL;
+            
+        default:
+            return E_FAIL;
         }
 
@@ -715,5 +728,5 @@
 #else
     NOREF(aTrunkType);
-    ReturnComNotImplemented();
+    return E_NOTIMPL;
 #endif
 }
@@ -728,6 +741,7 @@
     }
     else return E_FAIL;
+        
 #else
-    ReturnComNotImplemented();
+    return E_NOTIMPL;
 #endif
 }
@@ -804,10 +818,5 @@
         m->IPv4DhcpServerLowerIp = aszDhcpLowerIp;
         m->IPv4DhcpServerUpperIp = aszDhcpUpperIp;
-
-        LogFunc(("network: %RTnaipv4, dhcpserver:%RTnaipv4, dhcplowerip:%RTnaipv4, dhcpupperip:%RTnaipv4\n", 
-                 network, 
-                 dhcpserver, 
-                 dhcplowerip, 
-                 dhcpupperip));
+        LogFunc(("network: %RTnaipv4, dhcpserver:%RTnaipv4, dhcplowerip:%RTnaipv4, dhcpupperip:%RTnaipv4\n", network, dhcpserver, dhcplowerip, dhcpupperip));
     }
     /* we need IPv4NetworkMask for NAT's gw service start */
Index: trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp	(revision 46968)
+++ 	(revision )
@@ -1,124 +1,0 @@
-/* $Id$ */
-/** @file
- * VirtualBox Main - interface for VBox DHCP server
- */
-
-/*
- * Copyright (C) 2009-2012 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-#include "NetworkServiceRunner.h"
-#include <iprt/process.h>
-#include <iprt/param.h>
-#include <iprt/env.h>
-
-struct ARGDEF
-{
-    NETCFG Type;
-    const char * Name;
-};
-
-static const ARGDEF g_aArgDefs[] =
-{
-    {NETCFG_NAME, "--name"},
-    {NETCFG_NETNAME, "--network"},
-    {NETCFG_TRUNKTYPE, "--trunk-type"},
-    {NETCFG_TRUNKNAME, "--trunk-name"},
-    {NETCFG_MACADDRESS, "--mac-address"},
-    {NETCFG_IPADDRESS, "--ip-address"},
-    {NETCFG_VERBOSE, "--verbose"},
-    {NETCFG_NETMASK, "--netmask"},
-};
-
-static const ARGDEF * getArgDef(NETCFG type)
-{
-    for (unsigned i = 0; i < RT_ELEMENTS(g_aArgDefs); i++)
-        if (g_aArgDefs[i].Type == type)
-            return &g_aArgDefs[i];
-
-    return NULL;
-}
-
-void NetworkServiceRunner::detachFromServer()
-{
-    mProcess = NIL_RTPROCESS;
-}
-
-int NetworkServiceRunner::start()
-{
-    if (isRunning())
-        return VINF_ALREADY_INITIALIZED;
-
-    const char * args[NETCFG_NOTOPT_MAXVAL * 2];
-
-    /* get the path to the executable */
-    char exePathBuf[RTPATH_MAX];
-    const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX);
-    char *substrSl = strrchr(exePathBuf, '/');
-    char *substrBs = strrchr(exePathBuf, '\\');
-    char *suffix = substrSl ? substrSl : substrBs;
-
-    if (suffix)
-    {
-        suffix++;
-        strcpy(suffix, mProcName);
-    }
-
-    int index = 0;
-
-    args[index++] = exePath;
-
-    for (unsigned i = 0; i < NETCFG_NOTOPT_MAXVAL; i++)
-    {
-        if (mOptionEnabled[i])
-        {
-            const ARGDEF *pArgDef = getArgDef((NETCFG)i);
-            if (!pArgDef)
-                continue;
-            args[index++] = pArgDef->Name;
-
-            if (mOptions[i].length())
-                args[index++] = mOptions[i].c_str();  // value
-        }
-    }
-
-    args[index++] = NULL;
-
-    int rc = RTProcCreate(suffix ? exePath : mProcName, args, RTENV_DEFAULT, 0, &mProcess);
-    if (RT_FAILURE(rc))
-        mProcess = NIL_RTPROCESS;
-
-    return rc;
-}
-
-int NetworkServiceRunner::stop()
-{
-    if (!isRunning())
-        return VINF_OBJECT_DESTROYED;
-
-    int rc = RTProcTerminate(mProcess);
-    mProcess = NIL_RTPROCESS;
-    return rc;
-}
-
-bool NetworkServiceRunner::isRunning()
-{
-    if (mProcess == NIL_RTPROCESS)
-        return false;
-
-    RTPROCSTATUS status;
-    int rc = RTProcWait(mProcess, RTPROCWAIT_FLAGS_NOBLOCK, &status);
-
-    if (rc == VERR_PROCESS_RUNNING)
-        return true;
-
-    mProcess = NIL_RTPROCESS;
-    return false;
-}
Index: trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 46968)
+++ trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 46969)
@@ -61,5 +61,5 @@
 #include "SystemPropertiesImpl.h"
 #include "GuestOSTypeImpl.h"
-#include "NetworkServiceRunner.h"
+#include "DHCPServerRunner.h"
 #include "DHCPServerImpl.h"
 #include "NATNetworkImpl.h"
Index: trunk/src/VBox/Main/src-server/xpcom/server.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 46968)
+++ trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 46969)
@@ -67,5 +67,5 @@
 #include "BandwidthControlImpl.h"
 #include "BandwidthGroupImpl.h"
-#include "NetworkServiceRunner.h"
+#include "DHCPServerRunner.h"
 #include "DHCPServerImpl.h"
 #include "GuestOSTypeImpl.h"
Index: trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- trunk/src/VBox/Main/xml/Settings.cpp	(revision 46968)
+++ trunk/src/VBox/Main/xml/Settings.cpp	(revision 46969)
@@ -1302,57 +1302,14 @@
             if (    (pelmServer->getAttributeValue("networkName", srv.strNetworkName))
                  && (pelmServer->getAttributeValue("IPAddress", srv.strIPAddress))
-                    && (pelmServer->getAttributeValue("networkMask", srv.GlobalDhcpOptions[DhcpOpt_SubnetMask]))
+                 && (pelmServer->getAttributeValue("networkMask", srv.strIPNetworkMask))
                  && (pelmServer->getAttributeValue("lowerIP", srv.strIPLower))
                  && (pelmServer->getAttributeValue("upperIP", srv.strIPUpper))
                  && (pelmServer->getAttributeValue("enabled", srv.fEnabled))
                )
-            {
-                xml::NodesLoop nlOptions(*pelmServer, "Options");
-                const xml::ElementNode *options;
-                /* XXX: Options are in 1:1 relation to DHCPServer */
-
-                while ((options = nlOptions.forAllNodes()))
-                {
-                    readDhcpOptions(srv.GlobalDhcpOptions, *options);
-                } /* end of forall("Options") */
-                xml::NodesLoop nlConfig(*pelmServer, "Config");
-                const xml::ElementNode *cfg;
-                while ((cfg = nlConfig.forAllNodes()))
-                {
-                    com::Utf8Str strVmName;
-                    uint32_t u32Slot;
-                    cfg->getAttributeValue("vm-name", strVmName);
-                    cfg->getAttributeValue("slot", (uint32_t&)u32Slot);
-                    readDhcpOptions(srv.VmSlot2OptionsM[VmNameSlotKey(strVmName, u32Slot)],
-                                   *cfg);
-                }
                 llDhcpServers.push_back(srv);
-            }
             else
                 throw ConfigFileError(this, pelmServer, N_("Required DHCPServer/@networkName, @IPAddress, @networkMask, @lowerIP, @upperIP or @enabled attribute is missing"));
         }
     }
-}
-
-void MainConfigFile::readDhcpOptions(DhcpOptionMap& map, 
-                                     const xml::ElementNode& options)
-{
-    xml::NodesLoop nl2(options, "Option");
-    const xml::ElementNode *opt;
-    while((opt = nl2.forAllNodes()))
-    {
-        DhcpOpt_T OptName; 
-        com::Utf8Str OptValue;
-        opt->getAttributeValue("name", (uint32_t&)OptName);
-
-        if (OptName == DhcpOpt_SubnetMask)
-            continue;
-
-        opt->getAttributeValue("value", OptValue);
-                    
-        map.insert(
-          std::map<DhcpOpt_T, Utf8Str>::value_type(OptName, OptValue));
-    } /* end of forall("Option") */
-
 }
 
@@ -1489,5 +1446,5 @@
 #endif
         srv.strIPAddress = "192.168.56.100";
-        srv.GlobalDhcpOptions[DhcpOpt_SubnetMask] = "255.255.255.0";
+        srv.strIPNetworkMask = "255.255.255.0";
         srv.strIPLower = "192.168.56.101";
         srv.strIPUpper = "192.168.56.254";
@@ -1532,63 +1489,11 @@
         const DHCPServer &d = *it;
         xml::ElementNode *pelmThis = pelmDHCPServers->createChild("DHCPServer");
-        DhcpOptConstIterator itOpt;
-        itOpt = d.GlobalDhcpOptions.find(DhcpOpt_SubnetMask);
-
         pelmThis->setAttribute("networkName", d.strNetworkName);
         pelmThis->setAttribute("IPAddress", d.strIPAddress);
-        if (itOpt != d.GlobalDhcpOptions.end())
-            pelmThis->setAttribute("networkMask", itOpt->second);
+        pelmThis->setAttribute("networkMask", d.strIPNetworkMask);
         pelmThis->setAttribute("lowerIP", d.strIPLower);
         pelmThis->setAttribute("upperIP", d.strIPUpper);
         pelmThis->setAttribute("enabled", (d.fEnabled) ? 1 : 0);        // too bad we chose 1 vs. 0 here
-        /* We assume that if there're only 1 element it means that */
-        int cOpt = d.GlobalDhcpOptions.size(); 
-        /* We don't want duplicate validation check of networkMask here*/
-        if (   (   itOpt == d.GlobalDhcpOptions.end()
-                && cOpt > 0)
-            || cOpt > 1)
-        {
-            xml::ElementNode *pelmOptions = pelmThis->createChild("Options");
-            for (itOpt = d.GlobalDhcpOptions.begin();
-                 itOpt != d.GlobalDhcpOptions.end();
-                 ++itOpt)
-            {
-                if (itOpt->first == DhcpOpt_SubnetMask)
-                    continue;
-                
-                xml::ElementNode *pelmOpt = pelmOptions->createChild("Option");
-                
-                if (!pelmOpt)
-                    break;
-                
-                pelmOpt->setAttribute("name", itOpt->first);
-                pelmOpt->setAttribute("value", itOpt->second);
-            }
-        } /* end of if */
-        
-        if (d.VmSlot2OptionsM.size() > 0)
-        {
-            VmSlot2OptionsConstIterator itVmSlot;
-            DhcpOptConstIterator itOpt1;
-            for(itVmSlot = d.VmSlot2OptionsM.begin();
-                itVmSlot != d.VmSlot2OptionsM.end();
-                ++itVmSlot)
-            {
-                xml::ElementNode *pelmCfg = pelmThis->createChild("Config");
-                pelmCfg->setAttribute("vm-name", itVmSlot->first.VmName);
-                pelmCfg->setAttribute("slot", itVmSlot->first.Slot);
-                
-                for (itOpt1 = itVmSlot->second.begin();
-                     itOpt1 != itVmSlot->second.end();
-                     ++itOpt1)
-                {
-                    xml::ElementNode *pelmOpt = pelmCfg->createChild("Option");
-                    pelmOpt->setAttribute("name", itOpt1->first);
-                    pelmOpt->setAttribute("value", itOpt1->second);
-                }
-            }
-        } /* and of if */
-
-     }
+    }
 
     /* TODO: bump main version ? */
Index: trunk/src/VBox/NetworkServices/DHCP/Config.h
===================================================================
--- trunk/src/VBox/NetworkServices/DHCP/Config.h	(revision 46968)
+++ 	(revision )
@@ -1,1000 +1,0 @@
-/* $Id$ */
-/**
- * This file contains declarations of DHCP config.
- */
-
-#ifndef _CONFIG_H_
-# define _CONFIG_H_
-
-#include <iprt/cpp/utils.h>
-
-typedef std::vector<RTMAC> MacAddressContainer;
-typedef MacAddressContainer::iterator MacAddressIterator;
-
-typedef std::vector<RTNETADDRIPV4> Ipv4AddressContainer;
-typedef Ipv4AddressContainer::iterator Ipv4AddressIterator;
-typedef Ipv4AddressContainer::const_iterator Ipv4AddressConstIterator;
-
-static bool operator <(const RTNETADDRIPV4& a, const RTNETADDRIPV4& b)
-{
-    return (RT_N2H_U32(a.u) < RT_N2H_U32(b.u));
-}
-
-static bool operator > (const RTNETADDRIPV4& a, const RTNETADDRIPV4& b)
-{
-    return (b < a);
-}
-
-
-typedef enum CLIENTSESSIONSTATE
-{
-  /**
-   * defult state, session isn't operable, not initialized an so on.
-   */
-  DHCPNONSENSE,
-  /** We've received dhcp discover => 
-   * we're starting new client and/or session.
-   * Using XID (we record session)
-   * and response with DHCPOFFER
-   */
-  DHCPDISCOVERRECEIEVED,
-  /**
-   * We're ready to send DHCPOFFER
-   */
-  DHCPOFFERPREPARED,
-  /**
-   * This more, session state, we responsed, to 
-   * client with DHCPOFFER using session's XID
-   */
-  DHCPOFFERSENT,
-  /**
-   * this is session's state, client's done DHCPREQUEST with (XID)
-   */
-  DHCPREQUESTRECEIVED,
-  /**
-   * We're ready to send DHCPACK or DHCPNAK
-   */
-  DHCPACKNAKPREPARED,
-  /**
-   * We've been able to furfill client's request for (XID) session, erased others Client
-   * 's sessions ... and send DHCPACK (should be Lease bind at this point?) 
-   */
-  DHCPACKSENT,
-  /**
-   * We couldn't furfill client's request -> destroy session.
-   */
-  DHCPNACKSENT,
-  /**
-   * real client, don't want our DHCPOFFER, we're delating our client representation,
-   * and sessions objects.
-   */
-  DHCPDECLINERECEIVED,
-  /**
-   * nice to have, but not mandatory.
-   */
-  DHCPINFORMRECEIVED
-} CLIENTSESSIONSTATE;
-
-
-class RawOption
-{
-public:
-    uint8_t u8OptId;
-    uint8_t cbRawOpt;
-    uint8_t au8RawOpt[255];
-};
-
-
-class Client;
-class BaseConfigEntity;
-
-/**
- * This class joins client and the lease ... 
- * at the begining client might request several address assignments...
- * 
- * So session here is descriptor joining client to each of it's requests.
- * When client finalizes its selection ... only single assignment is chosen,
- * others are released.
- */
-class Session
-{
-public:
-    Session(const Client *client = NULL,  
-            uint32_t xid = 0, 
-            CLIENTSESSIONSTATE enmState = DHCPNONSENSE): 
-      m_pClient(client),
-      m_state(enmState),
-      m_u32Xid(xid),
-      m_pCfg(NULL)
-    {
-        /* XXX: state ? Which is acceptable on initialization ?! */
-        addressHint.u = 0;
-        RT_ZERO(reqParamList);
-    }
-    
-    bool operator < (const Session& s) const;
-    
-    int switchTo(CLIENTSESSIONSTATE);
-    /* XXX private: */
-
-    /**/
-    const Client* m_pClient;
-    /* We don't store the state in the client, because client might initiate several 
-     * sessions.
-     */
-    CLIENTSESSIONSTATE m_state;
-    /** 
-     * uniq identificator of session 
-     */
-    uint32_t m_u32Xid;
-    
-    /* dhcp-opts: request address */
-    RTNETADDRIPV4 addressHint;
-
-    /* dhcp-opts: request parameter list */
-    RawOption reqParamList;
-    /* Config for this session */
-    const BaseConfigEntity *m_pCfg;
-};
-
-typedef std::map<uint32_t, Session>   Map2ClientSession;
-typedef Map2ClientSession::value_type Map2ClientSessionType;
-typedef Map2ClientSession::iterator   Map2ClientSessionIterator;
-
-
-/* 
- * it's a basic representation of 
- * of out undestanding what client is
- * XXX: Client might sends Option 61 (RFC2132 9.14 "Client-identifier") signalling 
- * that we may identify it in special way
- * 
- * XXX: Client might send Option 60 (RFC2132 9.13 "Vendor class undentifier")
- * in response it's expected server sends Option 43 (RFC2132 8.4. "Vendor Specific Information") 
- */
-class Client 
-{
-    public:
-
-    /* XXX: Option 60 and 61 */
-    Client(const RTMAC& mac, uint32_t xid = 0);
-    
-    bool operator== (const RTMAC& mac) const 
-    {
-        return (  m_mac.au16[0] == mac.au16[0] 
-                && m_mac.au16[1] == mac.au16[1] 
-                && m_mac.au16[2] == mac.au16[2]);
-    }
-    /** Dumps client query */
-    void dump();
-    
-    /* XXX! private: */
-    
-    RTMAC m_mac;
-    Map2ClientSession m_sessions;
-    /* XXX: it's logically per session object, but some client broke XIDness */
-    /* XXX: we're using it as stack */
-    std::vector<RawOption> rawOptions;
-};
-
-
-typedef std::vector<Client> VecClient;
-typedef VecClient::iterator VecClientIterator;
-typedef VecClient::const_iterator VecClientConstIterator;
-
-
-class SessionManager
-{
-    public:
-
-    static SessionManager* getSessionManager();
-    
-    /**
-     * This method we call on every DHCP packet we've received.
-     * 1. it finds/creates Client/and Session Object.
-     */
-    Session& getClientSessionByDhcpPacket(const RTNETBOOTP* pDhcpMsg, size_t cbPacket);
-    
-    /* XXX: DHCPDECLINE */
-    void releaseClientSession(Session& session);
-    /* XXX: DHCPRELEASE */
-    void releaseClient(Client& client);
-
-    private:
-    
-    VecClient m_clients;
-
-    SessionManager(){}
-    virtual ~SessionManager(){}
-};
-
-
-typedef std::map<Session, RTNETADDRIPV4> MapSession2Ip4Address;
-typedef MapSession2Ip4Address::iterator MapSession2Ip4AddressIterator;
-typedef MapSession2Ip4Address::value_type MapSession2Ip4AddressPair;
-
-class NetworkConfigEntity;
-class HostConfigEntity;
-class ClientMatchCriteria;
-
-class ConfigurationManager
-{
-    public:
-    static ConfigurationManager* getConfigurationManager();
-
-    /**
-     * We call this on DHCPDISCOVER
-     */
-    int findConfiguration4Session(Session& session);
-    
-    /**
-     * XXX: it's could be done on DHCPOFFER or on DHCPACK (rfc2131 gives freedom here
-     * 3.1.2, what is strict that allocation should do address check before real 
-     * allocation)... 
-     */
-    int allocateConfiguration4Session(Session& session);
-        
-    /*
-     * We call this before DHCPACK sent and after DHCPREQUEST received ...
-     * when requested configuration is acceptable.
-     */
-    int commitConfiguration4ClientSession(Session& sesion);
-
-    static int findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cbDhcpMsg, RawOption& opt);
-    
-    NetworkConfigEntity *addNetwork(NetworkConfigEntity *pCfg, 
-                                    const RTNETADDRIPV4& networkId,
-                                    const RTNETADDRIPV4& netmask,
-                                    RTNETADDRIPV4& UpperAddress, 
-                                    RTNETADDRIPV4& LowerAddress);
-
-    HostConfigEntity *addHost(NetworkConfigEntity*, const RTNETADDRIPV4&, ClientMatchCriteria*);
-    
-    RTNETADDRIPV4  getSessionAddress(const Session& session);
-
-    /* XXX: from config */
-    uint32_t getLeaseTime() {return 600;}
-
-    int addToAddressList(uint8_t u8OptId, RTNETADDRIPV4& address)
-    {
-        switch(u8OptId)
-        {
-            case RTNET_DHCP_OPT_DNS:
-                m_nameservers.push_back(address);
-                break;
-            case RTNET_DHCP_OPT_ROUTERS:
-                m_routers.push_back(address);
-                break;
-            default:
-                Log(("dhcp-opt: list (%d) unsupported\n", u8OptId));
-        }
-        return VINF_SUCCESS;
-    }
-
-    int flushAddressList(uint8_t u8OptId)
-    {
-       switch(u8OptId)
-       {
-           case RTNET_DHCP_OPT_DNS:
-                m_nameservers.clear();
-                break;
-           case RTNET_DHCP_OPT_ROUTERS:
-               m_routers.clear();
-               break;
-           default:
-               Log(("dhcp-opt: list (%d) unsupported\n", u8OptId));
-       }
-       return VINF_SUCCESS;
-    }
-
-    const Ipv4AddressContainer& getAddressList(uint8_t u8OptId)
-    {
-       switch(u8OptId)
-       {
-           case RTNET_DHCP_OPT_DNS:
-               return m_nameservers;
-
-           case RTNET_DHCP_OPT_ROUTERS:
-               return m_routers;
-               
-       }
-       /* XXX: Grrr !!! */
-       return m_empty;
-    }
-
-    private:
-    ConfigurationManager(){}
-    virtual ~ConfigurationManager(){}
-    MapSession2Ip4Address m_allocations;
-    /*
-     *
-     */
-    Ipv4AddressContainer m_nameservers;
-    Ipv4AddressContainer m_routers;
-    Ipv4AddressContainer m_empty;
-
-};
-
-
-class NetworkManager
-{
-    public:
-    static NetworkManager *getNetworkManager();
-    
-    int offer4Session(Session& ses);
-    int ack(Session& ses);
-    int nak(Session& ses);
-
-    const RTNETADDRIPV4& getOurAddress(){ return m_OurAddress;}
-    const RTNETADDRIPV4& getOurNetmask(){ return m_OurNetmask;}
-    const RTMAC& getOurMac() {return m_OurMac;} 
-
-    void setOurAddress(const RTNETADDRIPV4& aAddress){ m_OurAddress = aAddress;}
-    void setOurNetmask(const RTNETADDRIPV4& aNetmask){ m_OurNetmask = aNetmask;}
-    void setOurMac(const RTMAC& aMac) {m_OurMac = aMac;} 
-
-    /* XXX: artifacts should be hidden or removed from here. */
-    PSUPDRVSESSION m_pSession;
-    INTNETIFHANDLE m_hIf;
-    PINTNETBUF m_pIfBuf;
-
-    private:
-    int prepareReplyPacket4Session(const Session& session);
-    int doReply(const Session& session);
-    int processParameterReqList(Session& session);
-
-    union {
-        RTNETBOOTP BootPHeader;
-        uint8_t au8Storage[1024];
-    } BootPReplyMsg;
-    int cbBooPReplyMsg;
-
-    RTNETADDRIPV4 m_OurAddress;
-    RTNETADDRIPV4 m_OurNetmask;
-    RTMAC m_OurMac;
-    
-    NetworkManager(){}
-    virtual ~NetworkManager(){}
-};
-
-/**
- *
- */
-class ClientMatchCriteria
-{
-    public:
-    virtual bool check(const Client& client) const {return false;};
-};
-
-
-class ORClientMatchCriteria: ClientMatchCriteria
-{
-    ClientMatchCriteria* m_left;
-    ClientMatchCriteria* m_right;
-    ORClientMatchCriteria(ClientMatchCriteria *left, ClientMatchCriteria *right)
-    {
-        m_left = left;
-        m_right = right;
-    }
-    
-    virtual bool check(const Client& client) const
-    {
-        return (m_left->check(client) || m_right->check(client));
-    }
-};
-
-
-class ANDClientMatchCriteria: ClientMatchCriteria
-{
-    ClientMatchCriteria* m_left;
-    ClientMatchCriteria* m_right;
-    ANDClientMatchCriteria(ClientMatchCriteria *left, ClientMatchCriteria *right)
-    {
-        m_left = left;
-        m_right = right;
-    }
-    
-    virtual bool check(const Client& client) const
-    {
-        return (m_left->check(client) && m_right->check(client));
-    }
-};
-
-
-class AnyClientMatchCriteria: public ClientMatchCriteria
-{
-    virtual bool check(const Client& client) const
-    {
-        return true;
-    }
-};
-
-
-class MACClientMatchCriteria: public ClientMatchCriteria
-{
-
-    public:
-    MACClientMatchCriteria(const RTMAC& mac):m_mac(mac){}
-    
-    virtual bool check(const Client& client) const
-    {
-        return (client == m_mac);
-    }
-    private:
-    RTMAC m_mac;
-};
-
-
-#if 0
-/* XXX: Later */
-class VmSlotClientMatchCriteria: public ClientMatchCriteria
-{
-    str::string VmName;
-    uint8_t u8Slot;
-    virtual bool check(const Client& client)
-    {
-        return (   client.VmName == VmName
-                   && (   u8Slot == (uint8_t)~0 /* any */
-                       || client.u8Slot == u8Slot));
-    }
-};
-#endif
-
-
-/* Option 60 */
-class ClassClientMatchCriteria: ClientMatchCriteria{};
-/* Option 61 */
-class ClientIdentifierMatchCriteria: ClientMatchCriteria{};
-
-
-/**
- * This is basic representation of leased address. we map it in 1:1 relation to 
- * Client
- */
-class Lease 
-{
-    
-};
-
-
-/**
- * It's representation of our lease db.
- */
-typedef std::map<Client, Lease*> MapClient2Lease;
-
-
-class BaseConfigEntity
-{
-public:
-    BaseConfigEntity(const ClientMatchCriteria *criteria = NULL, 
-                     int matchingLevel = 0)
-      : m_criteria(criteria),
-      m_MatchLevel(matchingLevel){};
-    virtual ~BaseConfigEntity(){};
-    /* XXX */
-    int add(BaseConfigEntity *cfg)
-    {
-        m_children.push_back(cfg);
-        return 0;
-    }
-    
-    /* Should return how strong matching */
-    virtual int match(const Client& client, const BaseConfigEntity **cfg) const 
-    {
-        int iMatch = (m_criteria && m_criteria->check(client)? m_MatchLevel: 0);
-        if (m_children.empty())
-        {
-            if (iMatch > 0)
-            {
-                *cfg = this;
-                return iMatch;
-            }
-        }
-        else
-        {
-            *cfg = this;
-            /* XXX: hack */
-            BaseConfigEntity const *matching = this;
-            int matchingLevel = m_MatchLevel;
-
-            for (std::vector<const BaseConfigEntity *>::const_iterator it = m_children.begin();
-                 it != m_children.end();
-                 ++it)
-            {
-                iMatch = (*it)->match(client, &matching);
-                if (iMatch > matchingLevel)
-                {
-                    *cfg = matching;
-                    matchingLevel = iMatch;
-                }
-            }
-            return matchingLevel;
-        }
-        return iMatch;
-    }
-
-    protected:
-    const ClientMatchCriteria *m_criteria;
-    int m_MatchLevel;
-    std::vector<const BaseConfigEntity *> m_children;
-};
-
-
-class NullConfigEntity: public BaseConfigEntity
-{
-public:
-    NullConfigEntity(){}
-    virtual ~NullConfigEntity(){}
-    int add(BaseConfigEntity *cfg) const
-    {
-        return 0;
-    }
-};
-
-
-class ConfigEntity: public BaseConfigEntity
-{
-    public:
-
-    /* range */
-    /* match conditions */
-    ConfigEntity(std::string& name,
-                 const BaseConfigEntity *cfg,
-                 const ClientMatchCriteria *criteria,
-                 int matchingLevel = 0):
-      BaseConfigEntity(criteria, matchingLevel),
-      m_name(name),
-      m_parentCfg(cfg)
-    {
-        unconst(m_parentCfg)->add(this);
-    }
-      
-    std::string m_name;
-    const BaseConfigEntity *m_parentCfg;
-};
-
-
-/**
- * Network specific entries 
- */
-class NetworkConfigEntity:public ConfigEntity
-{
-    public:
-    /* Address Pool matching with network declaration */
-    NetworkConfigEntity(std::string name,
-                        const BaseConfigEntity *cfg,
-                        const ClientMatchCriteria *criteria,
-                        int matchlvl,
-                        const RTNETADDRIPV4& networkID, 
-                        const RTNETADDRIPV4& networkMask,
-                        const RTNETADDRIPV4& lowerIP,
-                        const RTNETADDRIPV4& upperIP):
-      ConfigEntity(name, cfg, criteria, matchlvl),
-      m_NetworkID(networkID),
-      m_NetworkMask(networkMask),
-      m_UpperIP(upperIP),
-      m_LowerIP(lowerIP)
-    {
-    };
-    
-    NetworkConfigEntity(std::string name,
-                        const BaseConfigEntity *cfg,
-                        const ClientMatchCriteria *criteria,
-                        const RTNETADDRIPV4& networkID, 
-                        const RTNETADDRIPV4& networkMask):
-      ConfigEntity(name, cfg, criteria, 5),
-      m_NetworkID(networkID),
-      m_NetworkMask(networkMask)
-    {
-        m_UpperIP.u = m_NetworkID.u | (~m_NetworkMask.u);
-        m_LowerIP.u = m_NetworkID.u;
-    };
-
-    const RTNETADDRIPV4& upperIp() const {return m_UpperIP;}
-    const RTNETADDRIPV4& lowerIp() const {return m_LowerIP;}
-    const RTNETADDRIPV4& networkId() const {return m_NetworkID;}
-    const RTNETADDRIPV4& netmask() const {return m_NetworkMask;}
-
-    private:
-    RTNETADDRIPV4 m_NetworkID;
-    RTNETADDRIPV4 m_NetworkMask;
-    RTNETADDRIPV4 m_UpperIP;
-    RTNETADDRIPV4 m_LowerIP;
-};
-
-
-/** 
- * Host specific entry
- * Address pool is contains one element
- */
-class HostConfigEntity: public NetworkConfigEntity
-{
-
-    public:
-    HostConfigEntity(const RTNETADDRIPV4& addr,
-                     std::string name,
-                     const NetworkConfigEntity *cfg, 
-                     const ClientMatchCriteria *criteria):
-      NetworkConfigEntity(name, 
-                          static_cast<const ConfigEntity*>(cfg), 
-                          criteria, 
-                          10, 
-                          cfg->networkId(), 
-                          cfg->netmask(), 
-                          addr, 
-                          addr)
-    {
-        /* upper addr == lower addr */
-    }
-
-    virtual int match(const Client& client) const 
-    { 
-        return (m_criteria->check(client) ? 10 : 0);
-    }
-
-};
-
-class RootConfigEntity: public NetworkConfigEntity
-{
-    public:
-    RootConfigEntity(std::string name);
-    virtual ~RootConfigEntity(){};
-};
-
-
-#if 0
-/**
- * Shared regions e.g. some of configured networks declarations 
- * are cover each other.
- * XXX: Shared Network is join on Network config entities with possible 
- * overlaps in address pools. for a moment we won't configure and use them them  
- */
-class SharedNetworkConfigEntity: public NetworkEntity
-{
-    public:
-    SharedNetworkConfigEntity(){}
-    int match(const Client& client) const { return m_criteria.match(client)? 3 : 0;}
-    
-    SharedNetworkConfigEntity(NetworkEntity& network)
-    {
-        Networks.push_back(network);
-    }
-    virtual ~SharedNetworkConfigEntity(){}
-        
-    std::vector<NetworkConfigEntity> Networks;
-    
-};
-#endif
-
-
-class LeaseGenerator
-{
-public:
-    static const  LeaseGenerator *getGenerator();
-    static Lease *generateLease(const Client& client);
-protected:
-    /** returns already allocated lease or NULL */
-    Lease *getLease(const Client& client) const;
-    /** generates new lease by client query and configuration rules */
-    Lease *createLease(const Client& client, const BaseConfigEntity *cfg) const;
-private:
-    LeaseGenerator(){}
-    virtual ~LeaseGenerator(){}
-    std::map<Client, Lease*> m_leases;
-};
-
-
-extern const ClientMatchCriteria *g_AnyClient;
-extern const RootConfigEntity *g_RootConfig;
-extern const NullConfigEntity *g_NullConfig;
-
-/**
- * Helper class for stuffing DHCP options into a reply packet.
- */
-class VBoxNetDhcpWriteCursor
-{
-private:
-    uint8_t        *m_pbCur;       /**< The current cursor position. */
-    uint8_t        *m_pbEnd;       /**< The end the current option space. */
-    uint8_t        *m_pfOverload;  /**< Pointer to the flags of the overload option. */
-    uint8_t         m_fUsed;       /**< Overload fields that have been used. */
-    PRTNETDHCPOPT   m_pOpt;        /**< The current option. */
-    PRTNETBOOTP     m_pDhcp;       /**< The DHCP packet. */
-    bool            m_fOverflowed; /**< Set if we've overflowed, otherwise false. */
-
-public:
-    /** Instantiate an option cursor for the specified DHCP message. */
-    VBoxNetDhcpWriteCursor(PRTNETBOOTP pDhcp, size_t cbDhcp) :
-        m_pbCur(&pDhcp->bp_vend.Dhcp.dhcp_opts[0]),
-        m_pbEnd((uint8_t *)pDhcp + cbDhcp),
-        m_pfOverload(NULL),
-        m_fUsed(0),
-        m_pOpt(NULL),
-        m_pDhcp(pDhcp),
-        m_fOverflowed(false)
-    {
-        AssertPtr(pDhcp);
-        Assert(cbDhcp > RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts[10]));
-    }
-
-    /** Destructor.  */
-    ~VBoxNetDhcpWriteCursor()
-    {
-        m_pbCur = m_pbEnd = m_pfOverload = NULL;
-        m_pOpt = NULL;
-        m_pDhcp = NULL;
-    }
-
-    /**
-     * Try use the bp_file field.
-     * @returns true if not overloaded, false otherwise.
-     */
-    bool useBpFile(void)
-    {
-        if (    m_pfOverload
-            &&  (*m_pfOverload & 1))
-            return false;
-        m_fUsed |= 1 /* bp_file flag*/;
-        return true;
-    }
-
-
-    /**
-     * Try overload more BOOTP fields
-     */
-    bool overloadMore(void)
-    {
-        /* switch option area. */
-        uint8_t    *pbNew;
-        uint8_t    *pbNewEnd;
-        uint8_t     fField;
-        if (!(m_fUsed & 1))
-        {
-            fField     = 1;
-            pbNew      = &m_pDhcp->bp_file[0];
-            pbNewEnd   = &m_pDhcp->bp_file[sizeof(m_pDhcp->bp_file)];
-        }
-        else if (!(m_fUsed & 2))
-        {
-            fField     = 2;
-            pbNew      = &m_pDhcp->bp_sname[0];
-            pbNewEnd   = &m_pDhcp->bp_sname[sizeof(m_pDhcp->bp_sname)];
-        }
-        else
-            return false;
-
-        if (!m_pfOverload)
-        {
-            /* Add an overload option. */
-            *m_pbCur++ = RTNET_DHCP_OPT_OPTION_OVERLOAD;
-            *m_pbCur++ = fField;
-            m_pfOverload = m_pbCur;
-            *m_pbCur++ = 1;     /* bp_file flag */
-        }
-        else
-            *m_pfOverload |= fField;
-
-        /* pad current option field */
-        while (m_pbCur != m_pbEnd)
-            *m_pbCur++ = RTNET_DHCP_OPT_PAD; /** @todo not sure if this stuff is at all correct... */
-
-        /* switch */
-        m_pbCur = pbNew;
-        m_pbEnd = pbNewEnd;
-        return true;
-    }
-
-    /**
-     * Begin an option.
-     *
-     * @returns true on success, false if we're out of space.
-     *
-     * @param   uOption     The option number.
-     * @param   cb          The amount of data.
-     */
-    bool begin(uint8_t uOption, size_t cb)
-    {
-        /* Check that the data of the previous option has all been written. */
-        Assert(   !m_pOpt
-               || (m_pbCur - m_pOpt->dhcp_len == (uint8_t *)(m_pOpt + 1)));
-        AssertMsg(cb <= 255, ("%#x\n", cb));
-
-        /* Check if we need to overload more stuff. */
-        if ((uintptr_t)(m_pbEnd - m_pbCur) < cb + 2 + (m_pfOverload ? 1 : 3))
-        {
-            m_pOpt = NULL;
-            if (!overloadMore())
-            {
-                m_fOverflowed = true;
-                AssertMsgFailedReturn(("%u %#x\n", uOption, cb), false);
-            }
-            if ((uintptr_t)(m_pbEnd - m_pbCur) < cb + 2 + 1)
-            {
-                m_fOverflowed = true;
-                AssertMsgFailedReturn(("%u %#x\n", uOption, cb), false);
-            }
-        }
-
-        /* Emit the option header. */
-        m_pOpt = (PRTNETDHCPOPT)m_pbCur;
-        m_pOpt->dhcp_opt = uOption;
-        m_pOpt->dhcp_len = (uint8_t)cb;
-        m_pbCur += 2;
-        return true;
-    }
-
-    /**
-     * Puts option data.
-     *
-     * @param   pvData      The data.
-     * @param   cb          The amount to put.
-     */
-    void put(void const *pvData, size_t cb)
-    {
-        Assert(m_pOpt || m_fOverflowed);
-        if (RT_LIKELY(m_pOpt))
-        {
-            Assert((uintptr_t)m_pbCur - (uintptr_t)(m_pOpt + 1) + cb  <= (size_t)m_pOpt->dhcp_len);
-            memcpy(m_pbCur, pvData, cb);
-            m_pbCur += cb;
-        }
-    }
-
-    /**
-     * Puts an IPv4 Address.
-     *
-     * @param   IPv4Addr    The address.
-     */
-    void putIPv4Addr(RTNETADDRIPV4 IPv4Addr)
-    {
-        put(&IPv4Addr, 4);
-    }
-
-    /**
-     * Adds an IPv4 address option.
-     *
-     * @returns true/false just like begin().
-     *
-     * @param   uOption     The option number.
-     * @param   IPv4Addr    The address.
-     */
-    bool optIPv4Addr(uint8_t uOption, RTNETADDRIPV4 IPv4Addr)
-    {
-        if (!begin(uOption, 4))
-            return false;
-        putIPv4Addr(IPv4Addr);
-        return true;
-    }
-
-    /**
-     * Adds an option taking 1 or more IPv4 address.
-     *
-     * If the vector contains no addresses, the option will not be added.
-     *
-     * @returns true/false just like begin().
-     *
-     * @param   uOption     The option number.
-     * @param   rIPv4Addrs  Reference to the address vector.
-     */
-    bool optIPv4Addrs(uint8_t uOption, std::vector<RTNETADDRIPV4> const &rIPv4Addrs)
-    {
-        size_t const c = rIPv4Addrs.size();
-        if (!c)
-            return true;
-
-        if (!begin(uOption, 4*c))
-            return false;
-        for (size_t i = 0; i < c; i++)
-            putIPv4Addr(rIPv4Addrs[i]);
-        return true;
-    }
-
-    /**
-     * Puts an 8-bit integer.
-     *
-     * @param   u8          The integer.
-     */
-    void putU8(uint8_t u8)
-    {
-        put(&u8, 1);
-    }
-
-    /**
-     * Adds an 8-bit integer option.
-     *
-     * @returns true/false just like begin().
-     *
-     * @param   uOption     The option number.
-     * @param   u8          The integer
-     */
-    bool optU8(uint8_t uOption, uint8_t u8)
-    {
-        if (!begin(uOption, 1))
-            return false;
-        putU8(u8);
-        return true;
-    }
-
-    /**
-     * Puts an 32-bit integer (network endian).
-     *
-     * @param   u32Network  The integer.
-     */
-    void putU32(uint32_t u32)
-    {
-        put(&u32, 4);
-    }
-
-    /**
-     * Adds an 32-bit integer (network endian) option.
-     *
-     * @returns true/false just like begin().
-     *
-     * @param   uOption     The option number.
-     * @param   u32Network  The integer.
-     */
-    bool optU32(uint8_t uOption, uint32_t u32)
-    {
-        if (!begin(uOption, 4))
-            return false;
-        putU32(u32);
-        return true;
-    }
-
-    /**
-     * Puts a std::string.
-     *
-     * @param   rStr        Reference to the string.
-     */
-    void putStr(std::string const &rStr)
-    {
-        put(rStr.c_str(), rStr.size());
-    }
-
-    /**
-     * Adds an std::string option if the string isn't empty.
-     *
-     * @returns true/false just like begin().
-     *
-     * @param   uOption     The option number.
-     * @param   rStr        Reference to the string.
-     */
-    bool optStr(uint8_t uOption, std::string const &rStr)
-    {
-        const size_t cch = rStr.size();
-        if (!cch)
-            return true;
-
-        if (!begin(uOption, cch))
-            return false;
-        put(rStr.c_str(), cch);
-        return true;
-    }
-
-    /**
-     * Whether we've overflowed.
-     *
-     * @returns true on overflow, false otherwise.
-     */
-    bool hasOverflowed(void) const
-    {
-        return m_fOverflowed;
-    }
-
-    /**
-     * Adds the terminating END option.
-     *
-     * The END will always be added as we're reserving room for it, however, we
-     * might have dropped previous options due to overflows and that is what the
-     * return status indicates.
-     *
-     * @returns true on success, false on a (previous) overflow.
-     */
-    bool optEnd(void)
-    {
-        Assert((uintptr_t)(m_pbEnd - m_pbCur) < 4096);
-        *m_pbCur++ = RTNET_DHCP_OPT_END;
-        return !hasOverflowed();
-    }
-};
-
-#endif
Index: trunk/src/VBox/NetworkServices/DHCP/Makefile.kmk
===================================================================
--- trunk/src/VBox/NetworkServices/DHCP/Makefile.kmk	(revision 46968)
+++ trunk/src/VBox/NetworkServices/DHCP/Makefile.kmk	(revision 46969)
@@ -33,5 +33,5 @@
 # Hardened VBoxNetDHCP.
 #
-VBoxNetDHCPHardened_TEMPLATE = VBOXMAINCLIENTEXE
+VBoxNetDHCPHardened_TEMPLATE = VBOXR3HARDENEDEXE
 VBoxNetDHCPHardened_SOURCES = VBoxNetDHCPHardened.cpp
 VBoxNetDHCPHardened_NAME = VBoxNetDHCP
@@ -41,28 +41,15 @@
 # VBoxNetDHCP
 #
-VBoxNetDHCP_TEMPLATE = VBOXMAINCLIENTEXE
-#VBoxNetDHCP_TEMPLATE := VBOXR3$(if-expr defined(VBOX_WITH_HARDENING),,EXE)
+VBoxNetDHCP_TEMPLATE =
+VBoxNetDHCP_TEMPLATE := VBOXR3$(if-expr defined(VBOX_WITH_HARDENING),,EXE)
 VBoxNetDHCP_SOURCES = \
 	VBoxNetDHCP.cpp \
-	Config.cpp \
 	../NetLib/VBoxNetIntIf.cpp \
 	../NetLib/VBoxNetUDP.cpp \
-	../NetLib/VBoxNetARP.cpp \
-	../NetLib/VBoxNetBaseService.cpp
+	../NetLib/VBoxNetARP.cpp
 VBoxNetDHCP_LIBS = \
 	$(LIB_RUNTIME)
 VBoxNetDHCP_LDFLAGS.win = /SUBSYSTEM:windows
 
-ifeq ($(USERNAME),vvl)
-PROGRAMS += tstDhcpConfig
-
-#
-# VBOXMAINCLIENT here only to use DhcpOpt_T type. 
-tstDhcpConfig_TEMPLATE = VBOXMAINCLIENTEXE
-#XXX: enable condtionally if user is vvl
-#tstDhcpConfig_INSTTYPE = none
-tstDhcpConfig_SOURCES = test/tstDhcpConfig.cpp
-endif
-
 
 include $(FILE_KBUILD_SUB_FOOTER)
Index: trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
===================================================================
--- trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp	(revision 46968)
+++ trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp	(revision 46969)
@@ -25,14 +25,4 @@
 *   Header Files                                                               *
 *******************************************************************************/
-#include <VBox/com/com.h>
-#include <VBox/com/listeners.h>
-#include <VBox/com/string.h>
-#include <VBox/com/Guid.h>
-#include <VBox/com/array.h>
-#include <VBox/com/ErrorInfo.h>
-#include <VBox/com/errorprint.h>
-#include <VBox/com/EventQueue.h>
-#include <VBox/com/VirtualBox.h>
-
 #include <iprt/alloca.h>
 #include <iprt/buildconfig.h>
@@ -54,13 +44,8 @@
 #include <VBox/version.h>
 
-
 #include "../NetLib/VBoxNetLib.h"
 
 #include <vector>
-#include <list>
 #include <string>
-#include <map>
-
-#include "../NetLib/VBoxNetBaseService.h"
 
 #ifdef RT_OS_WINDOWS /* WinMain */
@@ -69,16 +54,314 @@
 #endif
 
-#ifndef INET4_ADDRLEN
-# define INET4_ADDRLEN 17
-#endif
-
-#include "Config.h"
+
 /*******************************************************************************
 *   Structures and Typedefs                                                    *
 *******************************************************************************/
+
+/**
+ * DHCP configuration item.
+ *
+ * This is all public data because I'm too lazy to do it properly right now.
+ */
+class VBoxNetDhcpCfg
+{
+public:
+    /** The etheret addresses this matches config applies to.
+     * An empty vector means 'ANY'. */
+    std::vector<RTMAC>          m_MacAddresses;
+    /** The upper address in the range. */
+    RTNETADDRIPV4               m_UpperAddr;
+    /** The lower address in the range. */
+    RTNETADDRIPV4               m_LowerAddr;
+
+    /** Option 1: The net mask. */
+    RTNETADDRIPV4               m_SubnetMask;
+    /* * Option 2: The time offset. */
+    /** Option 3: Routers for the subnet. */
+    std::vector<RTNETADDRIPV4>  m_Routers;
+    /* * Option 4: Time server. */
+    /* * Option 5: Name server. */
+    /** Option 6: Domain Name Server (DNS) */
+    std::vector<RTNETADDRIPV4>  m_DNSes;
+    /* * Option 7: Log server. */
+    /* * Option 8: Cookie server. */
+    /* * Option 9: LPR server. */
+    /* * Option 10: Impress server. */
+    /* * Option 11: Resource location server. */
+    /* * Option 12: Host name. */
+    std::string                 m_HostName;
+    /* * Option 13: Boot file size option. */
+    /* * Option 14: Merit dump file. */
+    /** Option 15: Domain name. */
+    std::string                 m_DomainName;
+    /* * Option 16: Swap server. */
+    /* * Option 17: Root path. */
+    /* * Option 18: Extension path. */
+    /* * Option 19: IP forwarding enable/disable. */
+    /* * Option 20: Non-local routing enable/disable. */
+    /* * Option 21: Policy filter. */
+    /* * Option 22: Maximum datagram reassembly size (MRS). */
+    /* * Option 23: Default IP time-to-live. */
+    /* * Option 24: Path MTU aging timeout. */
+    /* * Option 25: Path MTU plateau table. */
+    /* * Option 26: Interface MTU. */
+    /* * Option 27: All subnets are local. */
+    /* * Option 28: Broadcast address. */
+    /* * Option 29: Perform maximum discovery. */
+    /* * Option 30: Mask supplier. */
+    /* * Option 31: Perform route discovery. */
+    /* * Option 32: Router solicitation address. */
+    /* * Option 33: Static route. */
+    /* * Option 34: Trailer encapsulation. */
+    /* * Option 35: ARP cache timeout. */
+    /* * Option 36: Ethernet encapsulation. */
+    /* * Option 37: TCP Default TTL. */
+    /* * Option 38: TCP Keepalive Interval. */
+    /* * Option 39: TCP Keepalive Garbage. */
+    /* * Option 40: Network Information Service (NIS) Domain. */
+    /* * Option 41: Network Information Servers. */
+    /* * Option 42: Network Time Protocol Servers. */
+    /* * Option 43: Vendor Specific Information. */
+    /* * Option 44: NetBIOS over TCP/IP Name Server (NBNS). */
+    /* * Option 45: NetBIOS over TCP/IP Datagram distribution Server (NBDD). */
+    /* * Option 46: NetBIOS over TCP/IP Node Type. */
+    /* * Option 47: NetBIOS over TCP/IP Scope. */
+    /* * Option 48: X Window System Font Server. */
+    /* * Option 49: X Window System Display Manager. */
+
+    /** Option 51: IP Address Lease Time. */
+    uint32_t                    m_cSecLease;
+
+    /* * Option 64: Network Information Service+ Domain. */
+    /* * Option 65: Network Information Service+ Servers. */
+    /** Option 66: TFTP server name. */
+    std::string                 m_TftpServer;
+    /** Address for the bp_siaddr field corresponding to m_TftpServer. */
+    RTNETADDRIPV4               m_TftpServerAddr;
+    /** Option 67: Bootfile name. */
+    std::string                 m_BootfileName;
+
+    /* * Option 68: Mobile IP Home Agent. */
+    /* * Option 69: Simple Mail Transport Protocol (SMPT) Server. */
+    /* * Option 70: Post Office Protocol (POP3) Server. */
+    /* * Option 71: Network News Transport Protocol (NNTP) Server. */
+    /* * Option 72: Default World Wide Web (WWW) Server. */
+    /* * Option 73: Default Finger Server. */
+    /* * Option 74: Default Internet Relay Chat (IRC) Server. */
+    /* * Option 75: StreetTalk Server. */
+
+    /* * Option 119: Domain Search. */
+
+
+    VBoxNetDhcpCfg()
+    {
+        m_UpperAddr.u = UINT32_MAX;
+        m_LowerAddr.u = UINT32_MAX;
+        m_SubnetMask.u = UINT32_MAX;
+        m_cSecLease = 60*60; /* 1 hour */
+    }
+
+    /** Validates the configuration.
+     * @returns 0 on success, exit code + error message to stderr on failure. */
+    int validate(void)
+    {
+        if (    m_UpperAddr.u == UINT32_MAX
+            ||  m_LowerAddr.u == UINT32_MAX
+            ||  m_SubnetMask.u == UINT32_MAX)
+        {
+            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: Config is missing:");
+            if (m_UpperAddr.u == UINT32_MAX)
+                RTStrmPrintf(g_pStdErr, " --upper-ip");
+            if (m_LowerAddr.u == UINT32_MAX)
+                RTStrmPrintf(g_pStdErr, " --lower-ip");
+            if (m_SubnetMask.u == UINT32_MAX)
+                RTStrmPrintf(g_pStdErr, " --netmask");
+            return 2;
+        }
+
+        if (RT_N2H_U32(m_UpperAddr.u) < RT_N2H_U32(m_LowerAddr.u))
+        {
+            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: The --upper-ip value is lower than the --lower-ip one!\n"
+                                    "             %d.%d.%d.%d < %d.%d.%d.%d\n",
+                         m_UpperAddr.au8[0], m_UpperAddr.au8[1], m_UpperAddr.au8[2], m_UpperAddr.au8[3],
+                         m_LowerAddr.au8[0], m_LowerAddr.au8[1], m_LowerAddr.au8[2], m_LowerAddr.au8[3]);
+            return 3;
+        }
+
+        /* the code goes insane if we have too many atm. lazy bird */
+        uint32_t cIPs = RT_N2H_U32(m_UpperAddr.u) - RT_N2H_U32(m_LowerAddr.u);
+        if (cIPs > 1024)
+        {
+            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: Too many IPs between --upper-ip and --lower-ip! %d (max 1024)\n"
+                                    "             %d.%d.%d.%d < %d.%d.%d.%d\n",
+                         cIPs,
+                         m_UpperAddr.au8[0], m_UpperAddr.au8[1], m_UpperAddr.au8[2], m_UpperAddr.au8[3],
+                         m_LowerAddr.au8[0], m_LowerAddr.au8[1], m_LowerAddr.au8[2], m_LowerAddr.au8[3]);
+            return 3;
+        }
+        return 0;
+    }
+
+    /**
+     * Is this config for one specific client?
+     *
+     * @return  true / false.
+     */
+    bool            isOneSpecificClient(void) const
+    {
+        return m_LowerAddr.u == m_UpperAddr.u
+            && m_MacAddresses.size() > 0;
+    }
+
+    /**
+     * Checks if this config matches the specified MAC address.
+     *
+     * @returns true / false.
+     *
+     * @param   pMac    The MAC address to match.
+     */
+    bool            matchesMacAddress(PCRTMAC pMac) const
+    {
+        size_t i = m_MacAddresses.size();
+        if (RT_LIKELY(i < 1))
+            return true; /* no entries == ALL wildcard match */
+
+        while (i--)
+        {
+            PCRTMAC pCur = &m_MacAddresses[i];
+            if (    pCur->au16[0] == pMac->au16[0]
+                &&  pCur->au16[1] == pMac->au16[1]
+                &&  pCur->au16[2] == pMac->au16[2])
+                return true;
+        }
+        return false;
+    }
+
+};
+
+/**
+ * DHCP lease.
+ */
+class VBoxNetDhcpLease
+{
+public:
+    typedef enum State
+    {
+        /** Invalid. */
+        kState_Invalid = 0,
+        /** The lease is free / released. */
+        kState_Free,
+        /** An offer has been made.
+         * Expire time indicates when the offer expires. */
+        kState_Offer,
+        /** The lease is active.
+         * Expire time indicates when the lease expires. */
+        kState_Active
+    } State;
+
+    /** The client MAC address. */
+    RTMAC           m_MacAddress;
+    /** The IPv4 address. */
+    RTNETADDRIPV4   m_IPv4Address;
+
+    /** The current lease state. */
+    State           m_enmState;
+    /** The lease expiration time. */
+    RTTIMESPEC      m_ExpireTime;
+    /** Transaction ID. */
+    uint32_t        m_xid;
+    /** The configuration for this lease. */
+    VBoxNetDhcpCfg *m_pCfg;
+
+public:
+    /** Constructor taking an IPv4 address and a Config. */
+    VBoxNetDhcpLease(RTNETADDRIPV4 IPv4Addr, VBoxNetDhcpCfg *pCfg)
+    {
+        m_pCfg          = pCfg;
+        m_IPv4Address   = IPv4Addr;
+
+        m_MacAddress.au16[0] = m_MacAddress.au16[1] =  m_MacAddress.au16[2] = 0xff;
+        m_enmState      = kState_Free;
+        RTTimeSpecSetSeconds(&m_ExpireTime, 0);
+        m_xid           = UINT32_MAX;
+    }
+
+    /** Destructor.  */
+    ~VBoxNetDhcpLease()
+    {
+        m_IPv4Address.u = UINT32_MAX;
+        m_pCfg          = NULL;
+        m_MacAddress.au16[0] = m_MacAddress.au16[1] =  m_MacAddress.au16[2] = 0xff;
+        m_enmState      = kState_Free;
+        m_xid           = UINT32_MAX;
+    }
+
+    void            offer(uint32_t xid);
+    void            activate(void);
+    void            activate(uint32_t xid);
+    void            release(void);
+    bool            hasExpired(void) const;
+
+    /**
+     * Checks if the lease is in use or not.
+     *
+     * @returns true if active, false if free or expired.
+     *
+     * @param   pNow        The current time to use. Optional.
+     */
+    bool            isInUse(PCRTTIMESPEC pNow = NULL) const
+    {
+        if  (   m_enmState == kState_Offer
+             || m_enmState == kState_Active)
+        {
+            RTTIMESPEC Now;
+            if (!pNow)
+                pNow = RTTimeNow(&Now);
+            return RTTimeSpecGetSeconds(&m_ExpireTime) > RTTimeSpecGetSeconds(pNow);
+        }
+        return false;
+    }
+
+    /**
+     * Is this lease for one specific client?
+     *
+     * @return  true/false.
+     */
+    bool            isOneSpecificClient(void) const
+    {
+        return m_pCfg
+            && m_pCfg->isOneSpecificClient();
+    }
+
+    /**
+     * Is this lease currently being offered to a client.
+     *
+     * @returns true / false.
+     */
+    bool            isBeingOffered(void) const
+    {
+        return m_enmState == kState_Offer
+            && isInUse();
+    }
+
+    /**
+     * Is the lease in the current config or not.
+     *
+     * When updating the config we might leave active leases behind which aren't
+     * included in the new config. These will have m_pCfg set to NULL and should be
+     * freed up when they expired.
+     *
+     * @returns true / false.
+     */
+    bool            isInCurrentConfig(void) const
+    {
+        return m_pCfg != NULL;
+    }
+};
+
 /**
  * DHCP server instance.
  */
-class VBoxNetDhcp: public VBoxNetBaseService 
+class VBoxNetDhcp
 {
 public:
@@ -86,10 +369,12 @@
     virtual ~VBoxNetDhcp();
 
-    int                 init();
+    int                 parseArgs(int argc, char **argv);
+    int                 tryGoOnline(void);
     int                 run(void);
-    void                usage(void) { /* XXX: document options */ };
-    int                 parseOpt(int rc, const RTGETOPTUNION& getOptVal);
 
 protected:
+    int                 addConfig(VBoxNetDhcpCfg *pCfg);
+    void                explodeConfig(void);
+
     bool                handleDhcpMsg(uint8_t uMsgType, PCRTNETBOOTP pDhcpMsg, size_t cb);
     bool                handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb);
@@ -97,41 +382,43 @@
     bool                handleDhcpReqDecline(PCRTNETBOOTP pDhcpMsg, size_t cb);
     bool                handleDhcpReqRelease(PCRTNETBOOTP pDhcpMsg, size_t cb);
-
+    void                makeDhcpReply(uint8_t uMsgType, VBoxNetDhcpLease *pLease, PCRTNETBOOTP pDhcpMsg, size_t cb);
+
+    VBoxNetDhcpLease   *findLeaseByMacAddress(PCRTMAC pMacAddress, bool fAnyState);
+    VBoxNetDhcpLease   *findLeaseByIpv4AndMacAddresses(RTNETADDRIPV4 IPv4Addr, PCRTMAC pMacAddress, bool fAnyState);
+    VBoxNetDhcpLease   *newLease(PCRTNETBOOTP pDhcpMsg, size_t cb);
+
+    static uint8_t const *findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cb, size_t *pcbMaxOpt);
+    static bool         findOptionIPv4Addr(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cb, PRTNETADDRIPV4 pIPv4Addr);
+
+    inline void         debugPrint( int32_t iMinLevel, bool fMsg,  const char *pszFmt, ...) const;
     void                debugPrintV(int32_t iMinLevel, bool fMsg,  const char *pszFmt, va_list va) const;
     static const char  *debugDhcpName(uint8_t uMsgType);
 
 protected:
-    /** @name The DHCP server specific configuration data members.
+    /** @name The server configuration data members.
      * @{ */
-    /* 
-     * XXX: what was the plan? SQL3 or plain text file?
-     * How it will coexists with managment from VBoxManagement, who should manage db 
-     * in that case (VBoxManage, VBoxSVC ???)
-     */
+    std::string         m_Name;
+    std::string         m_Network;
+    std::string         m_TrunkName;
+    INTNETTRUNKTYPE     m_enmTrunkType;
+    RTMAC               m_MacAddress;
+    RTNETADDRIPV4       m_Ipv4Address;
     std::string         m_LeaseDBName;
-
     /** @} */
 
-    /* corresponding dhcp server description in Main */
-    ComPtr<IDHCPServer> m_DhcpServer;
-
-    ComPtr<INATNetwork> m_NATNetwork;
-    
-    /*
-     * We will ignore cmd line parameters IFF there will be some DHCP specific arguments
-     * otherwise all paramters will come from Main.
-     */
-    bool m_fIgnoreCmdLineParameters;
-
-    /*
-     * -b -n 10.0.1.2 -m 255.255.255.0 -> to the list processing in 
-     */
-    typedef struct 
-    {
-        char Key;
-        std::string strValue;
-    } CMDLNPRM;
-    std::list<CMDLNPRM> CmdParameterll;
-    typedef std::list<CMDLNPRM>::iterator CmdParameterIterator;
+    /** The current configs. */
+    std::vector<VBoxNetDhcpCfg *> m_Cfgs;
+
+    /** The current leases. */
+    std::vector<VBoxNetDhcpLease> m_Leases;
+
+    /** @name The network interface
+     * @{ */
+    PSUPDRVSESSION      m_pSession;
+    uint32_t            m_cbSendBuf;
+    uint32_t            m_cbRecvBuf;
+    INTNETIFHANDLE      m_hIf;          /**< The handle to the network interface. */
+    PINTNETBUF          m_pIfBuf;       /**< Interface buffer. */
+    /** @} */
 
     /** @name Debug stuff
@@ -144,11 +431,5 @@
     /** @} */
 };
-#if 0
-/* XXX: clean up it. */
-typedef std::vector<VBoxNetDhcpLease> DhcpLeaseContainer;
-typedef DhcpLeaseContainer::iterator DhcpLeaseIterator;
-typedef DhcpLeaseContainer::reverse_iterator DhcpLeaseRIterator;
-typedef DhcpLeaseContainer::const_iterator DhcpLeaseCIterator;
-#endif
+
 
 /*******************************************************************************
@@ -158,16 +439,5 @@
 static VBoxNetDhcp *g_pDhcp;
 
-/* DHCP server specific options */
-static const RTGETOPTDEF g_aOptionDefs[] =
-{
-  { "--lease-db",       'D',   RTGETOPT_REQ_STRING },
-  { "--begin-config",   'b',   RTGETOPT_REQ_NOTHING },
-  { "--gateway",        'g',   RTGETOPT_REQ_IPV4ADDR },
-  { "--lower-ip",       'l',   RTGETOPT_REQ_IPV4ADDR },
-  { "--upper-ip",       'u',   RTGETOPT_REQ_IPV4ADDR },
-};
-
-#if 0
-/* XXX this will gone */
+
 /**
  * Offer this lease to a client.
@@ -235,5 +505,7 @@
     return RTTimeSpecGetSeconds(&m_ExpireTime) > RTTimeSpecGetSeconds(RTTimeNow(&Now));
 }
-#endif
+
+
+
 
 /**
@@ -266,6 +538,4 @@
     memset(&m_CurHdrs, '\0', sizeof(m_CurHdrs));
 
-    m_fIgnoreCmdLineParameters = true;
-
 #if 0 /* enable to hack the code without a mile long argument list. */
     VBoxNetDhcpCfg *pDefCfg = new VBoxNetDhcpCfg();
@@ -279,9 +549,9 @@
     pDefCfg->m_DNSes.push_back(Addr);
     pDefCfg->m_DomainName     = "vboxnetdhcp.org";
-# if 0
+#if 0
     pDefCfg->m_cSecLease      = 60*60; /* 1 hour */
-# else
+#else
     pDefCfg->m_cSecLease      = 30; /* sec */
-# endif
+#endif
     pDefCfg->m_TftpServer     = "10.0.2.3"; //??
     this->addConfig(pDefCfg);
@@ -295,191 +565,388 @@
 VBoxNetDhcp::~VBoxNetDhcp()
 {
-}
-
-
-
-
-/**
- * Parse the DHCP specific arguments.
- * 
- * This callback caled for each paramenter so
- * ....
- * we nee post analisys of the parameters, at least 
- *    for -b, -g, -l, -u, -m  
- */
-int VBoxNetDhcp::parseOpt(int rc, const RTGETOPTUNION& Val)
-{
-    CMDLNPRM prm;
-
-    /* Ok, we've entered here, thus we can't ignore cmd line parameters anymore */
-    m_fIgnoreCmdLineParameters = false;
-
-    prm.Key = rc;
-
-    switch (rc)
-    {
+    /*
+     * Close the interface connection.
+     */
+    if (m_hIf != INTNET_HANDLE_INVALID)
+    {
+        INTNETIFCLOSEREQ CloseReq;
+        CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+        CloseReq.Hdr.cbReq = sizeof(CloseReq);
+        CloseReq.pSession = m_pSession;
+        CloseReq.hIf = m_hIf;
+        m_hIf = INTNET_HANDLE_INVALID;
+        int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
+        AssertRC(rc);
+    }
+
+    if (m_pSession)
+    {
+        SUPR3Term(false /*fForced*/);
+        m_pSession = NIL_RTR0PTR;
+    }
+}
+
+
+/**
+ * Adds a config to the tail.
+ *
+ * @returns See VBoxNetDHCP::validate().
+ * @param   pCfg        The config too add.
+ *                      This object will be consumed by this call!
+ */
+int VBoxNetDhcp::addConfig(VBoxNetDhcpCfg *pCfg)
+{
+    int rc = 0;
+    if (pCfg)
+    {
+        rc = pCfg->validate();
+        if (!rc)
+            m_Cfgs.push_back(pCfg);
+        else
+            delete pCfg;
+    }
+    return rc;
+}
+
+
+/**
+ * Explodes the config into leases.
+ *
+ * @remarks     This code is brute force and not very fast nor memory efficient.
+ *              We will have to revisit this later.
+ *
+ * @remarks     If an IP has been reconfigured for a fixed mac address and it's
+ *              already leased to a client, we it won't be available until the
+ *              client releases its lease or it expires.
+ */
+void VBoxNetDhcp::explodeConfig(void)
+{
+    RTTIMESPEC  Now;
+    RTTimeNow(&Now);
+
+    /*
+     * Remove all non-active leases from the vector and zapping the
+     * config pointers of the once left behind.
+     */
+    std::vector<VBoxNetDhcpLease>::iterator Itr = m_Leases.begin();
+    while (Itr != m_Leases.end())
+    {
+        if (!Itr->isInUse(&Now))
+            Itr = m_Leases.erase(Itr);
+        else
+        {
+            Itr->m_pCfg = NULL;
+            Itr++;
+        }
+    }
+
+    /*
+     * Loop thru the configurations in reverse order, giving the last
+     * configs priority of the newer ones.
+     */
+    size_t iCfg = m_Cfgs.size();
+    while (iCfg-- > 0)
+    {
+        VBoxNetDhcpCfg *pCfg = m_Cfgs[iCfg];
+
+        /* Expand the IP lease range. */
+        uint32_t const uLast = RT_N2H_U32(pCfg->m_UpperAddr.u);
+        for (uint32_t i = RT_N2H_U32(pCfg->m_LowerAddr.u); i <= uLast; i++)
+        {
+            RTNETADDRIPV4 IPv4Addr;
+            IPv4Addr.u = RT_H2N_U32(i);
+
+            /* Check if it exists and is configured. */
+            VBoxNetDhcpLease *pLease = NULL;
+            for (size_t j = 0; j < m_Leases.size(); j++)
+                if (m_Leases[j].m_IPv4Address.u == IPv4Addr.u)
+                {
+                    pLease = &m_Leases[j];
+                    break;
+                }
+            if (pLease)
+            {
+                if (!pLease->m_pCfg)
+                    pLease->m_pCfg = pCfg;
+            }
+            else
+            {
+                /* add it. */
+                VBoxNetDhcpLease NewLease(IPv4Addr, pCfg);
+                m_Leases.push_back(NewLease);
+                debugPrint(10, false, "exploseConfig: new lease %d.%d.%d.%d",
+                           IPv4Addr.au8[0], IPv4Addr.au8[1], IPv4Addr.au8[2], IPv4Addr.au8[3]);
+            }
+        }
+    }
+}
+
+
+/**
+ * Parse the arguments.
+ *
+ * @returns 0 on success, fully bitched exit code on failure.
+ *
+ * @param   argc    Argument count.
+ * @param   argv    Argument vector.
+ */
+int VBoxNetDhcp::parseArgs(int argc, char **argv)
+{
+    static const RTGETOPTDEF s_aOptionDefs[] =
+    {
+        { "--name",           'N',   RTGETOPT_REQ_STRING },
+        { "--network",        'n',   RTGETOPT_REQ_STRING },
+        { "--trunk-name",     't',   RTGETOPT_REQ_STRING },
+        { "--trunk-type",     'T',   RTGETOPT_REQ_STRING },
+        { "--mac-address",    'a',   RTGETOPT_REQ_MACADDR },
+        { "--ip-address",     'i',   RTGETOPT_REQ_IPV4ADDR },
+        { "--lease-db",       'D',   RTGETOPT_REQ_STRING },
+        { "--verbose",        'v',   RTGETOPT_REQ_NOTHING },
+
+        { "--begin-config",   'b',   RTGETOPT_REQ_NOTHING },
+        { "--gateway",        'g',   RTGETOPT_REQ_IPV4ADDR },
+        { "--lower-ip",       'l',   RTGETOPT_REQ_IPV4ADDR },
+        { "--upper-ip",       'u',   RTGETOPT_REQ_IPV4ADDR },
+        { "--netmask",        'm',   RTGETOPT_REQ_IPV4ADDR },
+    };
+
+    RTGETOPTSTATE State;
+    int rc = RTGetOptInit(&State, argc, argv, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0 /*fFlags*/);
+    AssertRCReturn(rc, 49);
+
+    VBoxNetDhcpCfg *pCurCfg = NULL;
+    for (;;)
+    {
+        RTGETOPTUNION Val;
+        rc = RTGetOpt(&State, &Val);
+        if (!rc)
+            break;
+        switch (rc)
+        {
+            case 'N':
+                m_Name = Val.psz;
+                break;
+            case 'n':
+                m_Network = Val.psz;
+                break;
+            case 't':
+                m_TrunkName = Val.psz;
+                break;
+            case 'T':
+                if (!strcmp(Val.psz, "none"))
+                    m_enmTrunkType = kIntNetTrunkType_None;
+                else if (!strcmp(Val.psz, "whatever"))
+                    m_enmTrunkType = kIntNetTrunkType_WhateverNone;
+                else if (!strcmp(Val.psz, "netflt"))
+                    m_enmTrunkType = kIntNetTrunkType_NetFlt;
+                else if (!strcmp(Val.psz, "netadp"))
+                    m_enmTrunkType = kIntNetTrunkType_NetAdp;
+                else if (!strcmp(Val.psz, "srvnat"))
+                    m_enmTrunkType = kIntNetTrunkType_SrvNat;
+                else
+                {
+                    RTStrmPrintf(g_pStdErr, "Invalid trunk type '%s'\n", Val.psz);
+                    return 1;
+                }
+                break;
+            case 'a':
+                m_MacAddress = Val.MacAddr;
+                break;
+            case 'i':
+                m_Ipv4Address = Val.IPv4Addr;
+                break;
+            case 'd':
+                m_LeaseDBName = Val.psz;
+                break;
+
+            case 'v':
+                m_cVerbosity++;
+                break;
+
             /* Begin config. */
-        case 'b': 
-            CmdParameterll.push_back(prm);
-            break;
-
-        case 'l':
-        case 'u':
-        case 'm':
-        case 'g':
-            prm.strValue = std::string(Val.psz);
-            CmdParameterll.push_back(prm);
-            break;
-
-        case 'D':
-            break;
-
-        default:
-            rc = RTGetOptPrintError(rc, &Val);
-            RTPrintf("Use --help for more information.\n");
-            return rc;
-    }
+            case 'b':
+                rc = addConfig(pCurCfg);
+                if (rc)
+                    break;
+                pCurCfg = NULL;
+                /* fall thru */
+
+            /* config specific ones. */
+            case 'g':
+            case 'l':
+            case 'u':
+            case 'm':
+                if (!pCurCfg)
+                {
+                    pCurCfg = new VBoxNetDhcpCfg();
+                    if (!pCurCfg)
+                    {
+                        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: new VBoxDhcpCfg failed\n");
+                        return 1;
+                    }
+                }
+
+                switch (rc)
+                {
+                    case 'g':
+                        pCurCfg->m_Routers.push_back(Val.IPv4Addr);
+                        break;
+
+                    case 'l':
+                        pCurCfg->m_LowerAddr = Val.IPv4Addr;
+                        break;
+
+                    case 'u':
+                        pCurCfg->m_UpperAddr = Val.IPv4Addr;
+                        break;
+
+                    case 'm':
+                        pCurCfg->m_SubnetMask = Val.IPv4Addr;
+                        break;
+
+                    case 0: /* ignore */ break;
+                    default:
+                        AssertMsgFailed(("%d", rc));
+                        return 1;
+                }
+                break;
+
+            case 'V':
+                RTPrintf("%sr%u\n", RTBldCfgVersion(), RTBldCfgRevision());
+                return 1;
+
+            case 'h':
+                RTPrintf("VBoxNetDHCP Version %s\n"
+                         "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
+                         "All rights reserved.\n"
+                         "\n"
+                         "Usage: VBoxNetDHCP <options>\n"
+                         "\n"
+                         "Options:\n",
+                         RTBldCfgVersion());
+                for (size_t i = 0; i < RT_ELEMENTS(s_aOptionDefs); i++)
+                    RTPrintf("    -%c, %s\n", s_aOptionDefs[i].iShort, s_aOptionDefs[i].pszLong);
+                return 1;
+
+            default:
+                rc = RTGetOptPrintError(rc, &Val);
+                RTPrintf("Use --help for more information.\n");
+                return rc;
+        }
+    }
+
+    /*
+     * Do the reconfig. (move this later)
+     */
+    if (!rc)
+        explodeConfig();
 
     return rc;
 }
 
-int VBoxNetDhcp::init()
-{
-    HRESULT hrc = S_OK;
-    /* ok, here we should initiate instance of dhcp server 
-     * and listener for Dhcp configuration events 
-     */
-    AssertRCReturn(virtualbox.isNull(), VERR_INTERNAL_ERROR);
-
-    hrc = virtualbox->FindDHCPServerByNetworkName(com::Bstr(m_Network.c_str()).raw(), 
-                                                  m_DhcpServer.asOutParam());
-    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
-
-    hrc = virtualbox->FindNATNetworkByName(com::Bstr(m_Network.c_str()).raw(), 
-                                           m_NATNetwork.asOutParam());
-
-    /* This isn't fatal in general case.
-     * AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
-     */
-
-    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
-    AssertPtrReturn(confManager, VERR_INTERNAL_ERROR);
-
-    /**
-     * if we have nat netework of the same name 
-     * this is good chance that we are assigned to this network.
-     */
-    BOOL fNeedDhcpServer = false;
-    if (   !m_NATNetwork.isNull()
-        && SUCCEEDED(m_NATNetwork->COMGETTER(NeedDhcpServer)(&fNeedDhcpServer))
-        && fNeedDhcpServer)
-    {
-        /* 90% we are servicing NAT network */
-        RTNETADDRIPV4 gateway;
-        com::Bstr strGateway;
-        hrc = m_NATNetwork->GetGateway(strGateway.asOutParam());
-        AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
-        RTNetStrToIPv4Addr(com::Utf8Str(strGateway).c_str(), &gateway);
-
-        confManager->addToAddressList(RTNET_DHCP_OPT_ROUTERS, gateway);
-    }
-
-    NetworkManager *netManager = NetworkManager::getNetworkManager();
-
-    netManager->setOurAddress(m_Ipv4Address);
-    netManager->setOurNetmask(m_Ipv4Netmask);
-    netManager->setOurMac(m_MacAddress);
-
-    /* Configuration fetching */
-    if (m_fIgnoreCmdLineParameters)
-    {
-        /* just fetch option array and add options to config */
-        /* per VM-settings ??? 
-         * 
-         * - we have vms with attached adapters with known mac-addresses 
-         * - mac-addresses might be changed as well as names, how keep our config cleaned ????
+
+/**
+ * Tries to connect to the internal network.
+ *
+ * @returns 0 on success, exit code + error message to stderr on failure.
+ */
+int VBoxNetDhcp::tryGoOnline(void)
+{
+    /*
+     * Open the session, load ring-0 and issue the request.
+     */
+    int rc = SUPR3Init(&m_pSession);
+    if (RT_FAILURE(rc))
+    {
+        m_pSession = NIL_RTR0PTR;
+        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3Init -> %Rrc", rc);
+        return 1;
+    }
+
+    char szPath[RTPATH_MAX];
+    rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
+    if (RT_FAILURE(rc))
+    {
+        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: RTPathProgram -> %Rrc", rc);
+        return 1;
+    }
+
+    rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0"));
+    if (RT_FAILURE(rc))
+    {
+        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3LoadVMM(\"%s\") -> %Rrc", szPath, rc);
+        return 1;
+    }
+
+    /*
+     * Create the open request.
+     */
+    INTNETOPENREQ OpenReq;
+    OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+    OpenReq.Hdr.cbReq = sizeof(OpenReq);
+    OpenReq.pSession = m_pSession;
+    strncpy(OpenReq.szNetwork, m_Network.c_str(), sizeof(OpenReq.szNetwork));
+    OpenReq.szNetwork[sizeof(OpenReq.szNetwork) - 1] = '\0';
+    strncpy(OpenReq.szTrunk, m_TrunkName.c_str(), sizeof(OpenReq.szTrunk));
+    OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0';
+    OpenReq.enmTrunkType = m_enmTrunkType;
+    OpenReq.fFlags = 0; /** @todo check this */
+    OpenReq.cbSend = m_cbSendBuf;
+    OpenReq.cbRecv = m_cbRecvBuf;
+    OpenReq.hIf = INTNET_HANDLE_INVALID;
+
+    /*
+     * Issue the request.
+     */
+    debugPrint(2, false, "attempting to open/create network \"%s\"...", OpenReq.szNetwork);
+    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
+    if (RT_SUCCESS(rc))
+    {
+        m_hIf = OpenReq.hIf;
+        debugPrint(1, false, "successfully opened/created \"%s\" - hIf=%#x", OpenReq.szNetwork, m_hIf);
+
+        /*
+         * Get the ring-3 address of the shared interface buffer.
          */
-        com::SafeArray<BSTR> sf;
-        hrc = m_DhcpServer->GetGlobalOptions(ComSafeArrayAsOutParam(sf));
-        AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
-
-#if 0        
-        for (int i = 0; i < sf.size(); ++i)
-        {
-            RTPrintf("%d: %s\n", i, com::Utf8Str(sf[i]).c_str());
-        }
-     
-#endif   
-        com::Bstr strUpperIp, strLowerIp;
-        
-        RTNETADDRIPV4 LowerAddress;
-        RTNETADDRIPV4 UpperAddress;
-
-        hrc = m_DhcpServer->GetUpperIP(strUpperIp.asOutParam());
-        AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
-        RTNetStrToIPv4Addr(com::Utf8Str(strUpperIp).c_str(), &UpperAddress);
-        
-
-        hrc = m_DhcpServer->GetLowerIP(strLowerIp.asOutParam());
-        AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
-        RTNetStrToIPv4Addr(com::Utf8Str(strLowerIp).c_str(), &LowerAddress);
-
-        RTNETADDRIPV4 networkId;
-        networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
-        std::string name = std::string("default");
-        
-        NetworkConfigEntity *pCfg = confManager->addNetwork(unconst(g_RootConfig), 
-                                                            networkId,
-                                                            m_Ipv4Netmask,
-                                                            LowerAddress, 
-                                                            UpperAddress);
-
-    } /* if(m_fIgnoreCmdLineParameters) */
+        INTNETIFGETBUFFERPTRSREQ GetBufferPtrsReq;
+        GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+        GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq);
+        GetBufferPtrsReq.pSession = m_pSession;
+        GetBufferPtrsReq.hIf = m_hIf;
+        GetBufferPtrsReq.pRing3Buf = NULL;
+        GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR;
+        rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, 0, &GetBufferPtrsReq.Hdr);
+        if (RT_SUCCESS(rc))
+        {
+            PINTNETBUF pBuf = GetBufferPtrsReq.pRing3Buf;
+            debugPrint(1, false, "pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d",
+                       pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv);
+            m_pIfBuf = pBuf;
+
+            /*
+             * Activate the interface.
+             */
+            INTNETIFSETACTIVEREQ ActiveReq;
+            ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+            ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
+            ActiveReq.pSession = m_pSession;
+            ActiveReq.hIf = m_hIf;
+            ActiveReq.fActive = true;
+            rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
+            if (RT_SUCCESS(rc))
+                return 0;
+
+            /* bail out */
+            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc);
+        }
+        else
+            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,) failed, rc=%Rrc\n", rc);
+    }
     else
-    {
-        CmdParameterIterator it;
-        
-        RTNETADDRIPV4 networkId;
-        networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
-        RTNETADDRIPV4 netmask = m_Ipv4Netmask;
-        RTNETADDRIPV4 LowerAddress;
-        RTNETADDRIPV4 UpperAddress;
-        
-        LowerAddress = networkId;
-        UpperAddress.u = RT_H2N_U32(RT_N2H_U32(LowerAddress.u) | RT_N2H_U32(netmask.u));
-
-        int idx = 0;
-        char name[64];
-
-
-        for (it = CmdParameterll.begin(); it != CmdParameterll.end(); ++it)
-        {
-            idx++;
-            RTStrPrintf(name, RT_ELEMENTS(name), "network-%d", idx);
-            std::string strname(name);
-
-            switch(it->Key)
-            {
-                case 'b':
-                    /* config */
-                    NetworkConfigEntity(strname, 
-                                        g_RootConfig,
-                                        g_AnyClient,
-                                        5,
-                                        networkId,
-                                        netmask,
-                                        LowerAddress,
-                                        UpperAddress);
-                case 'l':
-                case 'u':
-                case 'm':
-                case 'g':
-                    /* XXX: TBD */
-                    break;
-            }
-        }
-    }
-    return VINF_SUCCESS;
-}
+        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc);
+
+    return RT_SUCCESS(rc) ? 0 : 1;
+}
+
 
 /**
@@ -491,11 +958,4 @@
 int VBoxNetDhcp::run(void)
 {
-
-    /* XXX: shortcut should be hidden from network manager */
-    NetworkManager *netManager = NetworkManager::getNetworkManager();
-    netManager->m_pSession = m_pSession;
-    netManager->m_hIf = m_hIf;
-    netManager->m_pIfBuf = m_pIfBuf;
-
     /*
      * The loop.
@@ -614,44 +1074,22 @@
 bool VBoxNetDhcp::handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb)
 {
-
-    /* let's main first */
-    if (!m_DhcpServer.isNull())
-    {
-        HRESULT hrc;
-        com::SafeArray<BSTR> sf;
-        hrc = m_DhcpServer->GetMacOptions(com::BstrFmt("%02X%02X%02X%02X%02X%02X",
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[0],
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[1],
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[2],
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[3],
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[4],
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[5],
-                                                  pDhcpMsg->bp_chaddr.Mac.au8[6]).raw(),
-                                          ComSafeArrayAsOutParam(sf));
-        if (SUCCEEDED(hrc))
-        {
-            /* XXX: per-host configuration */
-        }
-        
-        SessionManager *sesionManager = SessionManager::getSessionManager();
-        Session& session = sesionManager->getClientSessionByDhcpPacket(pDhcpMsg, cb);
-        /* XXX: switch -> private */
-        session.switchTo(DHCPDISCOVERRECEIEVED);
-        
-        ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
-        int rc = confManager->findConfiguration4Session(session);
-        AssertRCReturn(rc, rc);
-
-        rc = confManager->allocateConfiguration4Session(session);
-        AssertRCReturn(rc, rc);
-
-        NetworkManager *netManager = NetworkManager::getNetworkManager();
-        rc = netManager->offer4Session(session);
-        AssertRCReturn(rc, rc);
-
-
-    } /* end of if(!m_DhcpServer.isNull()) */
-
-    return VINF_SUCCESS;
+    /*
+     * The newLease() method contains logic for finding current leases
+     * and reusing them in case the client is forgetful.
+     */
+    VBoxNetDhcpLease *pLease = newLease(pDhcpMsg, cb);
+    if (!pLease)
+        return false;
+    debugPrint(1, true, "Offering %d.%d.%d.%d to %.6Rhxs xid=%#x",
+               pLease->m_IPv4Address.au8[0],
+               pLease->m_IPv4Address.au8[1],
+               pLease->m_IPv4Address.au8[2],
+               pLease->m_IPv4Address.au8[3],
+               &pDhcpMsg->bp_chaddr.Mac,
+               pDhcpMsg->bp_xid);
+    pLease->offer(pDhcpMsg->bp_xid);
+
+    makeDhcpReply(RTNET_DHCP_MT_OFFER, pLease, pDhcpMsg, cb);
+    return true;
 }
 
@@ -667,22 +1105,95 @@
 bool VBoxNetDhcp::handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb)
 {
-    SessionManager *sesionManager = SessionManager::getSessionManager();
-    Session& session = sesionManager->getClientSessionByDhcpPacket(pDhcpMsg, cb);
-    /* XXX: switch -> private */
-    session.switchTo(DHCPREQUESTRECEIVED);
-        
-    ConfigurationManager *confManager = ConfigurationManager::getConfigurationManager();
-    int rc = confManager->findConfiguration4Session(session);
-    AssertRCReturn(rc, false);
-
-    rc = confManager->commitConfiguration4ClientSession(session);
-
-    NetworkManager *netManager = NetworkManager::getNetworkManager();
-    if (RT_SUCCESS(rc))
-        rc = netManager->ack(session);
+    /** @todo Probably need to match the server IP here to work correctly with
+     *        other servers. */
+    /** @todo This code isn't entirely correct and quite a bit of a hack, but it
+     *        will have to do for now as the right thing (tm) is very complex.
+     *        Part of the fun is verifying that the request is something we can
+     *        and should handle. */
+
+    /*
+     * Try find the lease by the requested address + client MAC address.
+     */
+    VBoxNetDhcpLease   *pLease = NULL;
+    RTNETADDRIPV4       IPv4Addr;
+    bool                fReqAddr = findOptionIPv4Addr(RTNET_DHCP_OPT_REQ_ADDR, pDhcpMsg, cb, &IPv4Addr);
+    if (fReqAddr)
+    {
+        fReqAddr = true;
+        pLease = findLeaseByIpv4AndMacAddresses(IPv4Addr, &pDhcpMsg->bp_chaddr.Mac, true /* fAnyState */);
+    }
+
+    /*
+     * Try find the lease by the client IP address + client MAC address.
+     */
+    if (    !pLease
+        &&  pDhcpMsg->bp_ciaddr.u)
+        pLease = findLeaseByIpv4AndMacAddresses(pDhcpMsg->bp_ciaddr, &pDhcpMsg->bp_chaddr.Mac, true /* fAnyState */);
+
+#if 0 /** @todo client id stuff - it doesn't make sense here imho, we need IP + MAC. What would make sense
+                though is to compare the client id with what we've got in the lease and use it to root out
+                bad requests. */
+    /*
+     * Try find the lease by using the client id.
+     */
+    if (!pLease)
+    {
+        size_t          cbClientID = 0;
+        uint8_t const  *pbClientID  = findOption(RTNET_DHCP_OPT_CLIENT_ID, pDhcpMsg, cb, &cbClientID);
+        if (    pbClientID
+            &&  cbClientID == sizeof(RTMAC) + 1
+            &&  pbClientID[0] == RTNET_ARP_ETHER
+            &&
+                )
+        {
+            pLease = findLeaseByIpv4AndMacAddresses(pDhcpMsg->bp_ciaddr, &pDhcpMsg->bp_chaddr.Mac, true /* fAnyState */);
+        }
+    }
+#endif
+
+    /*
+     * Validate the lease that's requested.
+     * We've already check the MAC and IP addresses.
+     */
+    bool fAckIt = false;
+    if (pLease)
+    {
+        if (pLease->isBeingOffered())
+        {
+            if (pLease->m_xid == pDhcpMsg->bp_xid)
+                debugPrint(2, true, "REQUEST for offered lease.");
+            else
+                debugPrint(2, true, "REQUEST for offered lease, xid mismatch. Expected %#x, got %#x.",
+                           pLease->m_xid, pDhcpMsg->bp_xid);
+            pLease->activate(pDhcpMsg->bp_xid);
+            fAckIt = true;
+        }
+        else if (!pLease->isInCurrentConfig())
+            debugPrint(1, true, "REQUEST for obsolete lease -> NAK");
+        else if (fReqAddr != (pDhcpMsg->bp_ciaddr.u != 0)) // ???
+        {
+            /** @todo this ain't safe. */
+            debugPrint(1, true, "REQUEST for lease not on offer, assuming renewal. lease_xid=%#x bp_xid=%#x",
+                       pLease->m_xid, pDhcpMsg->bp_xid);
+            fAckIt = true;
+            pLease->activate(pDhcpMsg->bp_xid);
+        }
+        else
+            debugPrint(1, true, "REQUEST for lease not on offer, NAK it.");
+    }
+
+    /*
+     * NAK if if no lease was found.
+     */
+    if (fAckIt)
+    {
+        debugPrint(1, false, "ACK'ing DHCP_REQUEST");
+        makeDhcpReply(RTNET_DHCP_MT_ACK, pLease, pDhcpMsg, cb);
+    }
     else
-        rc = netManager->nak(session);
-    
-    AssertRCReturn(rc, false);
+    {
+        debugPrint(1, false, "NAK'ing DHCP_REQUEST");
+        makeDhcpReply(RTNET_DHCP_MT_NAC, NULL, pDhcpMsg, cb);
+    }
 
     return true;
@@ -749,4 +1260,665 @@
     debugPrint(1, true, "RELEASE is not implemented");
     return true;
+}
+
+
+/**
+ * Helper class for stuffing DHCP options into a reply packet.
+ */
+class VBoxNetDhcpWriteCursor
+{
+private:
+    uint8_t        *m_pbCur;       /**< The current cursor position. */
+    uint8_t        *m_pbEnd;       /**< The end the current option space. */
+    uint8_t        *m_pfOverload;  /**< Pointer to the flags of the overload option. */
+    uint8_t         m_fUsed;       /**< Overload fields that have been used. */
+    PRTNETDHCPOPT   m_pOpt;        /**< The current option. */
+    PRTNETBOOTP     m_pDhcp;       /**< The DHCP packet. */
+    bool            m_fOverflowed; /**< Set if we've overflowed, otherwise false. */
+
+public:
+    /** Instantiate an option cursor for the specified DHCP message. */
+    VBoxNetDhcpWriteCursor(PRTNETBOOTP pDhcp, size_t cbDhcp) :
+        m_pbCur(&pDhcp->bp_vend.Dhcp.dhcp_opts[0]),
+        m_pbEnd((uint8_t *)pDhcp + cbDhcp),
+        m_pfOverload(NULL),
+        m_fUsed(0),
+        m_pOpt(NULL),
+        m_pDhcp(pDhcp),
+        m_fOverflowed(false)
+    {
+        AssertPtr(pDhcp);
+        Assert(cbDhcp > RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts[10]));
+    }
+
+    /** Destructor.  */
+    ~VBoxNetDhcpWriteCursor()
+    {
+        m_pbCur = m_pbEnd = m_pfOverload = NULL;
+        m_pOpt = NULL;
+        m_pDhcp = NULL;
+    }
+
+    /**
+     * Try use the bp_file field.
+     * @returns true if not overloaded, false otherwise.
+     */
+    bool useBpFile(void)
+    {
+        if (    m_pfOverload
+            &&  (*m_pfOverload & 1))
+            return false;
+        m_fUsed |= 1 /* bp_file flag*/;
+        return true;
+    }
+
+
+    /**
+     * Try overload more BOOTP fields
+     */
+    bool overloadMore(void)
+    {
+        /* switch option area. */
+        uint8_t    *pbNew;
+        uint8_t    *pbNewEnd;
+        uint8_t     fField;
+        if (!(m_fUsed & 1))
+        {
+            fField     = 1;
+            pbNew      = &m_pDhcp->bp_file[0];
+            pbNewEnd   = &m_pDhcp->bp_file[sizeof(m_pDhcp->bp_file)];
+        }
+        else if (!(m_fUsed & 2))
+        {
+            fField     = 2;
+            pbNew      = &m_pDhcp->bp_sname[0];
+            pbNewEnd   = &m_pDhcp->bp_sname[sizeof(m_pDhcp->bp_sname)];
+        }
+        else
+            return false;
+
+        if (!m_pfOverload)
+        {
+            /* Add an overload option. */
+            *m_pbCur++ = RTNET_DHCP_OPT_OPTION_OVERLOAD;
+            *m_pbCur++ = fField;
+            m_pfOverload = m_pbCur;
+            *m_pbCur++ = 1;     /* bp_file flag */
+        }
+        else
+            *m_pfOverload |= fField;
+
+        /* pad current option field */
+        while (m_pbCur != m_pbEnd)
+            *m_pbCur++ = RTNET_DHCP_OPT_PAD; /** @todo not sure if this stuff is at all correct... */
+
+        /* switch */
+        m_pbCur = pbNew;
+        m_pbEnd = pbNewEnd;
+        return true;
+    }
+
+    /**
+     * Begin an option.
+     *
+     * @returns true on success, false if we're out of space.
+     *
+     * @param   uOption     The option number.
+     * @param   cb          The amount of data.
+     */
+    bool begin(uint8_t uOption, size_t cb)
+    {
+        /* Check that the data of the previous option has all been written. */
+        Assert(   !m_pOpt
+               || (m_pbCur - m_pOpt->dhcp_len == (uint8_t *)(m_pOpt + 1)));
+        AssertMsg(cb <= 255, ("%#x\n", cb));
+
+        /* Check if we need to overload more stuff. */
+        if ((uintptr_t)(m_pbEnd - m_pbCur) < cb + 2 + (m_pfOverload ? 1 : 3))
+        {
+            m_pOpt = NULL;
+            if (!overloadMore())
+            {
+                m_fOverflowed = true;
+                AssertMsgFailedReturn(("%u %#x\n", uOption, cb), false);
+            }
+            if ((uintptr_t)(m_pbEnd - m_pbCur) < cb + 2 + 1)
+            {
+                m_fOverflowed = true;
+                AssertMsgFailedReturn(("%u %#x\n", uOption, cb), false);
+            }
+        }
+
+        /* Emit the option header. */
+        m_pOpt = (PRTNETDHCPOPT)m_pbCur;
+        m_pOpt->dhcp_opt = uOption;
+        m_pOpt->dhcp_len = (uint8_t)cb;
+        m_pbCur += 2;
+        return true;
+    }
+
+    /**
+     * Puts option data.
+     *
+     * @param   pvData      The data.
+     * @param   cb          The amount to put.
+     */
+    void put(void const *pvData, size_t cb)
+    {
+        Assert(m_pOpt || m_fOverflowed);
+        if (RT_LIKELY(m_pOpt))
+        {
+            Assert((uintptr_t)m_pbCur - (uintptr_t)(m_pOpt + 1) + cb  <= (size_t)m_pOpt->dhcp_len);
+            memcpy(m_pbCur, pvData, cb);
+            m_pbCur += cb;
+        }
+    }
+
+    /**
+     * Puts an IPv4 Address.
+     *
+     * @param   IPv4Addr    The address.
+     */
+    void putIPv4Addr(RTNETADDRIPV4 IPv4Addr)
+    {
+        put(&IPv4Addr, 4);
+    }
+
+    /**
+     * Adds an IPv4 address option.
+     *
+     * @returns true/false just like begin().
+     *
+     * @param   uOption     The option number.
+     * @param   IPv4Addr    The address.
+     */
+    bool optIPv4Addr(uint8_t uOption, RTNETADDRIPV4 IPv4Addr)
+    {
+        if (!begin(uOption, 4))
+            return false;
+        putIPv4Addr(IPv4Addr);
+        return true;
+    }
+
+    /**
+     * Adds an option taking 1 or more IPv4 address.
+     *
+     * If the vector contains no addresses, the option will not be added.
+     *
+     * @returns true/false just like begin().
+     *
+     * @param   uOption     The option number.
+     * @param   rIPv4Addrs  Reference to the address vector.
+     */
+    bool optIPv4Addrs(uint8_t uOption, std::vector<RTNETADDRIPV4> const &rIPv4Addrs)
+    {
+        size_t const c = rIPv4Addrs.size();
+        if (!c)
+            return true;
+
+        if (!begin(uOption, 4*c))
+            return false;
+        for (size_t i = 0; i < c; i++)
+            putIPv4Addr(rIPv4Addrs[i]);
+        return true;
+    }
+
+    /**
+     * Puts an 8-bit integer.
+     *
+     * @param   u8          The integer.
+     */
+    void putU8(uint8_t u8)
+    {
+        put(&u8, 1);
+    }
+
+    /**
+     * Adds an 8-bit integer option.
+     *
+     * @returns true/false just like begin().
+     *
+     * @param   uOption     The option number.
+     * @param   u8          The integer
+     */
+    bool optU8(uint8_t uOption, uint8_t u8)
+    {
+        if (!begin(uOption, 1))
+            return false;
+        putU8(u8);
+        return true;
+    }
+
+    /**
+     * Puts an 32-bit integer (network endian).
+     *
+     * @param   u32Network  The integer.
+     */
+    void putU32(uint32_t u32)
+    {
+        put(&u32, 4);
+    }
+
+    /**
+     * Adds an 32-bit integer (network endian) option.
+     *
+     * @returns true/false just like begin().
+     *
+     * @param   uOption     The option number.
+     * @param   u32Network  The integer.
+     */
+    bool optU32(uint8_t uOption, uint32_t u32)
+    {
+        if (!begin(uOption, 4))
+            return false;
+        putU32(u32);
+        return true;
+    }
+
+    /**
+     * Puts a std::string.
+     *
+     * @param   rStr        Reference to the string.
+     */
+    void putStr(std::string const &rStr)
+    {
+        put(rStr.c_str(), rStr.size());
+    }
+
+    /**
+     * Adds an std::string option if the string isn't empty.
+     *
+     * @returns true/false just like begin().
+     *
+     * @param   uOption     The option number.
+     * @param   rStr        Reference to the string.
+     */
+    bool optStr(uint8_t uOption, std::string const &rStr)
+    {
+        const size_t cch = rStr.size();
+        if (!cch)
+            return true;
+
+        if (!begin(uOption, cch))
+            return false;
+        put(rStr.c_str(), cch);
+        return true;
+    }
+
+    /**
+     * Whether we've overflowed.
+     *
+     * @returns true on overflow, false otherwise.
+     */
+    bool hasOverflowed(void) const
+    {
+        return m_fOverflowed;
+    }
+
+    /**
+     * Adds the terminating END option.
+     *
+     * The END will always be added as we're reserving room for it, however, we
+     * might have dropped previous options due to overflows and that is what the
+     * return status indicates.
+     *
+     * @returns true on success, false on a (previous) overflow.
+     */
+    bool optEnd(void)
+    {
+        Assert((uintptr_t)(m_pbEnd - m_pbCur) < 4096);
+        *m_pbCur++ = RTNET_DHCP_OPT_END;
+        return !hasOverflowed();
+    }
+};
+
+
+/**
+ * Constructs and sends a reply to a client.
+ *
+ * @returns
+ * @param   uMsgType        The DHCP message type.
+ * @param   pLease          The lease. This can be NULL for some replies.
+ * @param   pDhcpMsg        The client message. We will dig out the MAC address,
+ *                          transaction ID, and requested options from this.
+ * @param   cb              The size of the client message.
+ */
+void VBoxNetDhcp::makeDhcpReply(uint8_t uMsgType, VBoxNetDhcpLease *pLease, PCRTNETBOOTP pDhcpMsg, size_t cb)
+{
+    size_t      cbReply = RTNET_DHCP_NORMAL_SIZE; /** @todo respect the RTNET_DHCP_OPT_MAX_DHCP_MSG_SIZE option */
+    PRTNETBOOTP pReply = (PRTNETBOOTP)alloca(cbReply);
+
+    /*
+     * The fixed bits stuff.
+     */
+    pReply->bp_op     = RTNETBOOTP_OP_REPLY;
+    pReply->bp_htype  = RTNET_ARP_ETHER;
+    pReply->bp_hlen   = sizeof(RTMAC);
+    pReply->bp_hops   = 0;
+    pReply->bp_xid    = pDhcpMsg->bp_xid;
+    pReply->bp_secs   = 0;
+    pReply->bp_flags  = 0; // (pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST); ??
+    pReply->bp_ciaddr.u = 0;
+    pReply->bp_yiaddr.u = pLease ? pLease->m_IPv4Address.u : 0xffffffff;
+    pReply->bp_siaddr.u = pLease && pLease->m_pCfg ? pLease->m_pCfg->m_TftpServerAddr.u : 0; /* (next server == TFTP)*/
+    pReply->bp_giaddr.u = 0;
+    memset(&pReply->bp_chaddr, '\0', sizeof(pReply->bp_chaddr));
+    pReply->bp_chaddr.Mac = pDhcpMsg->bp_chaddr.Mac;
+    memset(&pReply->bp_sname[0], '\0', sizeof(pReply->bp_sname));
+    memset(&pReply->bp_file[0],  '\0', sizeof(pReply->bp_file));
+    pReply->bp_vend.Dhcp.dhcp_cookie = RT_H2N_U32_C(RTNET_DHCP_COOKIE);
+    memset(&pReply->bp_vend.Dhcp.dhcp_opts[0], '\0', RTNET_DHCP_OPT_SIZE);
+
+    /*
+     * The options - use a cursor class for dealing with the ugly stuff.
+     */
+    VBoxNetDhcpWriteCursor Cursor(pReply, cbReply);
+
+    /* The basics */
+    Cursor.optU8(RTNET_DHCP_OPT_MSG_TYPE, uMsgType);
+    Cursor.optIPv4Addr(RTNET_DHCP_OPT_SERVER_ID, m_Ipv4Address);
+
+    if (uMsgType != RTNET_DHCP_MT_NAC)
+    {
+        AssertReturnVoid(pLease && pLease->m_pCfg);
+        const VBoxNetDhcpCfg *pCfg = pLease->m_pCfg; /* no need to retain it. */
+
+        /* The IP config. */
+        Cursor.optU32(RTNET_DHCP_OPT_LEASE_TIME, RT_H2N_U32(pCfg->m_cSecLease));
+        Cursor.optIPv4Addr(RTNET_DHCP_OPT_SUBNET_MASK, pCfg->m_SubnetMask);
+        Cursor.optIPv4Addrs(RTNET_DHCP_OPT_ROUTERS, pCfg->m_Routers);
+        Cursor.optIPv4Addrs(RTNET_DHCP_OPT_ROUTERS, pCfg->m_DNSes);
+        Cursor.optStr(RTNET_DHCP_OPT_HOST_NAME, pCfg->m_HostName);
+        Cursor.optStr(RTNET_DHCP_OPT_DOMAIN_NAME, pCfg->m_DomainName);
+
+        /* The PXE config. */
+        if (pCfg->m_BootfileName.size())
+        {
+            if (Cursor.useBpFile())
+                RTStrPrintf((char *)&pReply->bp_file[0], sizeof(pReply->bp_file), "%s", pCfg->m_BootfileName.c_str());
+            else
+                Cursor.optStr(RTNET_DHCP_OPT_BOOTFILE_NAME, pCfg->m_BootfileName);
+        }
+    }
+
+    /* Terminate the options. */
+    if (!Cursor.optEnd())
+        debugPrint(0, true, "option overflow\n");
+
+    /*
+     * Send it.
+     */
+    int rc;
+#if 0
+    if (!(pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST)) /** @todo need to see someone set this flag to check that it's correct. */
+    {
+        RTNETADDRIPV4 IPv4AddrBrdCast;
+        IPv4AddrBrdCast.u = UINT32_C(0xffffffff); /* broadcast IP */
+        rc = VBoxNetUDPUnicast(m_pSession, m_hIf, m_pIfBuf,
+                               m_Ipv4Address, &m_MacAddress, RTNETIPV4_PORT_BOOTPS,                 /* sender */
+                               IPv4AddrBrdCast, &pDhcpMsg->bp_chaddr.Mac, RTNETIPV4_PORT_BOOTPC,    /* receiver */
+                               pReply, cbReply);
+    }
+    else
+#endif
+        rc = VBoxNetUDPBroadcast(m_pSession, m_hIf, m_pIfBuf,
+                                 m_Ipv4Address, &m_MacAddress, RTNETIPV4_PORT_BOOTPS,               /* sender */
+                                 RTNETIPV4_PORT_BOOTPC,                                             /* receiver port */
+                                 pReply, cbReply);
+    if (RT_FAILURE(rc))
+        debugPrint(0, true, "error %Rrc when sending the reply", rc);
+}
+
+
+/**
+ * Look up a lease by MAC address.
+ *
+ * @returns Pointer to the lease if found, NULL if not found.
+ * @param   pMacAddress             The mac address.
+ * @param   fAnyState       Any state.
+ */
+VBoxNetDhcpLease *VBoxNetDhcp::findLeaseByMacAddress(PCRTMAC pMacAddress, bool fAnyState)
+{
+    size_t iLease = m_Leases.size();
+    while (iLease-- > 0)
+    {
+        VBoxNetDhcpLease *pLease = &m_Leases[iLease];
+        if (    pLease
+            &&  pLease->m_MacAddress.au16[0] == pMacAddress->au16[0]
+            &&  pLease->m_MacAddress.au16[1] == pMacAddress->au16[1]
+            &&  pLease->m_MacAddress.au16[2] == pMacAddress->au16[2]
+            &&  (   fAnyState
+                 || (pLease->m_enmState != VBoxNetDhcpLease::kState_Free)) )
+            return pLease;
+    }
+
+    return NULL;
+}
+
+
+/**
+ * Look up a lease by IPv4 and MAC addresses.
+ *
+ * @returns Pointer to the lease if found, NULL if not found.
+ * @param   IPv4Addr        The IPv4 address.
+ * @param   pMacAddress     The mac address.
+ * @param   fAnyState       Any state.
+ */
+VBoxNetDhcpLease *VBoxNetDhcp::findLeaseByIpv4AndMacAddresses(RTNETADDRIPV4 IPv4Addr, PCRTMAC pMacAddress, bool fAnyState)
+{
+    size_t iLease = m_Leases.size();
+    while (iLease-- > 0)
+    {
+        VBoxNetDhcpLease *pLease = &m_Leases[iLease];
+        if (    pLease
+            &&  pLease->m_IPv4Address.u      == IPv4Addr.u
+            &&  pLease->m_MacAddress.au16[0] == pMacAddress->au16[0]
+            &&  pLease->m_MacAddress.au16[1] == pMacAddress->au16[1]
+            &&  pLease->m_MacAddress.au16[2] == pMacAddress->au16[2]
+            &&  (   fAnyState
+                 || (pLease->m_enmState != VBoxNetDhcpLease::kState_Free)) )
+            return pLease;
+    }
+
+    return NULL;
+}
+
+
+/**
+ * Creates a new lease for the client specified in the DHCP message.
+ *
+ * The caller has already made sure it doesn't already have a lease.
+ *
+ * @returns Pointer to the lease if found, NULL+log if not found.
+ * @param   IPv4Addr        The IPv4 address.
+ * @param   pMacAddress     The MAC address.
+ */
+VBoxNetDhcpLease *VBoxNetDhcp::newLease(PCRTNETBOOTP pDhcpMsg, size_t cb)
+{
+    RTMAC const MacAddr = pDhcpMsg->bp_chaddr.Mac;
+    RTTIMESPEC  Now;
+    RTTimeNow(&Now);
+
+    /*
+     * Search the possible leases.
+     *
+     * We'll try do all the searches in one pass, that is to say, perfect
+     * match, old lease, and next free/expired lease.
+     */
+    VBoxNetDhcpLease *pBest = NULL;
+    VBoxNetDhcpLease *pOld  = NULL;
+    VBoxNetDhcpLease *pFree = NULL;
+
+    size_t cLeases = m_Leases.size();
+    for (size_t i = 0; i < cLeases; i++)
+    {
+        VBoxNetDhcpLease *pCur = &m_Leases[i];
+
+        /* Skip it if no configuration, that means its not in the current config. */
+        if (!pCur->m_pCfg)
+            continue;
+
+        /* best */
+        if (    pCur->isOneSpecificClient()
+            &&  pCur->m_pCfg->matchesMacAddress(&MacAddr))
+        {
+            if (    !pBest
+                ||  pBest->m_pCfg->m_MacAddresses.size() < pCur->m_pCfg->m_MacAddresses.size())
+                pBest = pCur;
+        }
+
+        /* old lease */
+        if (    pCur->m_MacAddress.au16[0] == MacAddr.au16[0]
+            &&  pCur->m_MacAddress.au16[1] == MacAddr.au16[1]
+            &&  pCur->m_MacAddress.au16[2] == MacAddr.au16[2])
+        {
+            if (    !pOld
+                ||  RTTimeSpecGetSeconds(&pCur->m_ExpireTime) > RTTimeSpecGetSeconds(&pFree->m_ExpireTime))
+                pOld = pCur;
+        }
+
+        /* expired lease */
+        if (!pCur->isInUse(&Now))
+        {
+            if (    !pFree
+                ||  RTTimeSpecGetSeconds(&pCur->m_ExpireTime) < RTTimeSpecGetSeconds(&pFree->m_ExpireTime))
+                pFree = pCur;
+        }
+    }
+
+    VBoxNetDhcpLease *pNew = pBest;
+    if (!pNew)
+        pNew = pOld;
+    if (!pNew)
+        pNew = pFree;
+    if (!pNew)
+    {
+        debugPrint(0, true, "No more leases.");
+        return NULL;
+    }
+
+    /*
+     * Init the lease.
+     */
+    pNew->m_MacAddress = MacAddr;
+    pNew->m_xid        = pDhcpMsg->bp_xid;
+    /** @todo extract the client id. */
+
+    return pNew;
+}
+
+
+/**
+ * Finds an option.
+ *
+ * @returns On success, a pointer to the first byte in the option data (no none
+ *          then it'll be the byte following the 0 size field) and *pcbOpt set
+ *          to the option length.
+ *          On failure, NULL is returned and *pcbOpt unchanged.
+ *
+ * @param   uOption         The option to search for.
+ * @param   pDhcpMsg        The DHCP message.
+ * @param   cb              The size of the message.
+ * @param   pcbOpt          Where to store the option size size. Optional. Note
+ *                          that this is adjusted if the option length is larger
+ *                          than the message buffer.
+ */
+/* static */ const uint8_t *
+VBoxNetDhcp::findOption(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cb, size_t *pcbOpt)
+{
+    Assert(uOption != RTNET_DHCP_OPT_PAD);
+
+    /*
+     * Validate the DHCP bits and figure the max size of the options in the vendor field.
+     */
+    if (cb <= RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts))
+        return NULL;
+    if (pDhcpMsg->bp_vend.Dhcp.dhcp_cookie != RT_H2N_U32_C(RTNET_DHCP_COOKIE))
+        return NULL;
+    size_t cbLeft = cb - RT_UOFFSETOF(RTNETBOOTP, bp_vend.Dhcp.dhcp_opts);
+    if (cbLeft > RTNET_DHCP_OPT_SIZE)
+        cbLeft = RTNET_DHCP_OPT_SIZE;
+
+    /*
+     * Search the vendor field.
+     */
+    bool            fExtended = false;
+    uint8_t const  *pb = &pDhcpMsg->bp_vend.Dhcp.dhcp_opts[0];
+    while (pb && cbLeft > 0)
+    {
+        uint8_t uCur  = *pb;
+        if (uCur == RTNET_DHCP_OPT_PAD)
+        {
+            cbLeft--;
+            pb++;
+        }
+        else if (cbLeft <= 1)
+            break;
+        else
+        {
+            size_t  cbCur = pb[1];
+            if (cbCur > cbLeft - 2)
+                cbCur = cbLeft - 2;
+            if (uCur == uOption)
+            {
+                if (pcbOpt)
+                    *pcbOpt = cbCur;
+                return pb+2;
+            }
+            pb     += cbCur + 2;
+            cbLeft -= cbCur - 2;
+        }
+    }
+
+    /** @todo search extended dhcp option field(s) when present */
+
+    return NULL;
+}
+
+
+/**
+ * Locates an option with an IPv4 address in the DHCP message.
+ *
+ * @returns true and *pIpv4Addr if found, false if not.
+ *
+ * @param   uOption         The option to find.
+ * @param   pDhcpMsg        The DHCP message.
+ * @param   cb              The size of the message.
+ * @param   pIPv4Addr       Where to put the address.
+ */
+/* static */ bool
+VBoxNetDhcp::findOptionIPv4Addr(uint8_t uOption, PCRTNETBOOTP pDhcpMsg, size_t cb, PRTNETADDRIPV4 pIPv4Addr)
+{
+    size_t          cbOpt;
+    uint8_t const  *pbOpt = findOption(uOption, pDhcpMsg, cb, &cbOpt);
+    if (pbOpt)
+    {
+        if (cbOpt >= sizeof(RTNETADDRIPV4))
+        {
+            *pIPv4Addr = *(PCRTNETADDRIPV4)pbOpt;
+            return true;
+        }
+    }
+    return false;
+}
+
+
+/**
+ * Print debug message depending on the m_cVerbosity level.
+ *
+ * @param   iMinLevel       The minimum m_cVerbosity level for this message.
+ * @param   fMsg            Whether to dump parts for the current DHCP message.
+ * @param   pszFmt          The message format string.
+ * @param   ...             Optional arguments.
+ */
+inline void VBoxNetDhcp::debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
+{
+    if (iMinLevel <= m_cVerbosity)
+    {
+        va_list va;
+        va_start(va, pszFmt);
+        debugPrintV(iMinLevel, fMsg, pszFmt, va);
+        va_end(va);
+    }
 }
 
@@ -773,7 +1945,4 @@
             &&  m_pCurMsg)
         {
-            /* XXX: export this to debugPrinfDhcpMsg or variant and other method export 
-             *  to base class
-             */
             const char *pszMsg = m_uCurMsgType != UINT8_MAX ? debugDhcpName(m_uCurMsgType) : "";
             RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: debug: %8s chaddr=%.6Rhxs ciaddr=%d.%d.%d.%d yiaddr=%d.%d.%d.%d siaddr=%d.%d.%d.%d xid=%#x\n",
@@ -834,7 +2003,4 @@
      * Instantiate the DHCP server and hand it the options.
      */
-    HRESULT hrc = com::Initialize();
-    Assert(!FAILED(hrc));
-
     VBoxNetDhcp *pDhcp = new VBoxNetDhcp();
     if (!pDhcp)
@@ -846,6 +2012,4 @@
     if (rc)
         return rc;
-
-    pDhcp->init();
 
     /*
Index: trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
===================================================================
--- trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp	(revision 46968)
+++ trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp	(revision 46969)
@@ -1,6 +1,7 @@
 /* $Id$ */
 /** @file
- * VBoxNetBaseService - Base Service class for connecting to IntNet.
- */
+ * VBoxNetDHCP - DHCP Service for connecting to IntNet.
+ */
+/** @todo r=bird: Cut&Past rules... Please fix DHCP refs! */
 
 /*
@@ -21,14 +22,4 @@
 #define LOG_GROUP LOG_GROUP_NET_SERVICE
 
-#include <VBox/com/com.h>
-#include <VBox/com/listeners.h>
-#include <VBox/com/string.h>
-#include <VBox/com/Guid.h>
-#include <VBox/com/array.h>
-#include <VBox/com/ErrorInfo.h>
-#include <VBox/com/errorprint.h>
-#include <VBox/com/EventQueue.h>
-#include <VBox/com/VirtualBox.h>
-
 #include <iprt/alloca.h>
 #include <iprt/buildconfig.h>
@@ -39,10 +30,8 @@
 #include <iprt/param.h>
 #include <iprt/path.h>
-#include <iprt/process.h>
 #include <iprt/stream.h>
 #include <iprt/string.h>
 #include <iprt/time.h>
 #include <iprt/mem.h>
-#include <iprt/message.h>
 
 #include <VBox/sup.h>
@@ -55,5 +44,4 @@
 #include <string>
 
-#include <VBox/err.h>
 #include <VBox/log.h>
 
@@ -70,9 +58,4 @@
 *   Structures and Typedefs                                                    *
 *******************************************************************************/
-
-/*******************************************************************************
-*   Global Variables                                                           *
-*******************************************************************************/
-/* Commonly used options for network configuration */
 static RTGETOPTDEF g_aGetOptDef[] =
 {
@@ -86,29 +69,9 @@
     { "--verbose",        'v',   RTGETOPT_REQ_NOTHING },
 };
-
-
 VBoxNetBaseService::VBoxNetBaseService()
 {
-    int rc = RTCritSectInit(&m_csThis);
-    AssertRC(rc);
-    /* numbers from DrvIntNet */
-    m_cbSendBuf             = 128 * _1K;
-    m_cbRecvBuf             = 256 * _1K;
-    m_hIf                   = INTNET_HANDLE_INVALID;
-    m_pIfBuf                = NULL;
-
-    m_cVerbosity            = 0;
-    m_Name                  = "VBoxNetNAT";
-    m_Network               = "intnet";
-   
-    for(unsigned int i = 0; i < RT_ELEMENTS(g_aGetOptDef); ++i)
-        m_vecOptionDefs.push_back(&g_aGetOptDef[i]);
-
-    HRESULT hrc = virtualbox.createLocalObject(CLSID_VirtualBox);
-    if (FAILED(hrc))
-        RTMsgError("Failed to create the VirtualBox object!");
-}
-
-
+  int rc = RTCritSectInit(&m_csThis);
+  AssertRC(rc);
+}
 VBoxNetBaseService::~VBoxNetBaseService()
 {
@@ -136,11 +99,19 @@
 }
 
-
 int VBoxNetBaseService::init()
 {
+    /* numbers from DrvIntNet */
+    m_cbSendBuf             = 128 * _1K;
+    m_cbRecvBuf             = 256 * _1K;
+    m_hIf                   = INTNET_HANDLE_INVALID;
+    m_pIfBuf                = NULL;
+
+    m_cVerbosity            = 0;
+    m_Name                  = "VBoxNetNAT";
+    m_Network               = "intnet";
+    for(unsigned int i = 0; i < RT_ELEMENTS(g_aGetOptDef); ++i)
+        m_vecOptionDefs.push_back(&g_aGetOptDef[i]);
     return VINF_SUCCESS;
 }
-
-
 /**
  * Parse the arguments.
@@ -217,14 +188,11 @@
 
             case 'h':
-                RTPrintf("%s Version %s\n"
+                RTPrintf("VBoxNetDHCP Version %s\n"
                          "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
                          "All rights reserved.\n"
                          "\n"
-                         "Usage: %s <options>\n"
+                         "Usage: VBoxNetDHCP <options>\n"
                          "\n"
                          "Options:\n",
-                         RTProcShortName(),
-                         RTProcShortName(),
-                         RTProcShortName(),
                          RTBldCfgVersion());
                 for (unsigned int i = 0; i < m_vecOptionDefs.size(); i++)
@@ -247,5 +215,4 @@
     return rc;
 }
-
 
 int VBoxNetBaseService::tryGoOnline(void)
@@ -350,9 +317,7 @@
 }
 
-
 void VBoxNetBaseService::shutdown(void)
 {
 }
-
 
 int VBoxNetBaseService::waitForIntNetEvent(int cMillis)
@@ -412,10 +377,29 @@
 }
 
-
 /**
  * Print debug message depending on the m_cVerbosity level.
  *
  * @param   iMinLevel       The minimum m_cVerbosity level for this message.
- * @param   fMsg            Whether to dump parts for the current service message.
+ * @param   fMsg            Whether to dump parts for the current DHCP message.
+ * @param   pszFmt          The message format string.
+ * @param   ...             Optional arguments.
+ */
+inline void VBoxNetBaseService::debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
+{
+    if (iMinLevel <= m_cVerbosity)
+    {
+        va_list va;
+        va_start(va, pszFmt);
+        debugPrintV(iMinLevel, fMsg, pszFmt, va);
+        va_end(va);
+    }
+}
+
+
+/**
+ * Print debug message depending on the m_cVerbosity level.
+ *
+ * @param   iMinLevel       The minimum m_cVerbosity level for this message.
+ * @param   fMsg            Whether to dump parts for the current DHCP message.
  * @param   pszFmt          The message format string.
  * @param   va              Optional arguments.
@@ -427,14 +411,9 @@
         va_list vaCopy;                 /* This dude is *very* special, thus the copy. */
         va_copy(vaCopy, va);
-        RTStrmPrintf(g_pStdErr, "%s: %s: %N\n", 
-                     RTProcShortName(),
-                     iMinLevel >= 2 ? "debug" : "info",
-                     pszFmt,
-                     &vaCopy);
+        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
         va_end(vaCopy);
     }
 
 }
-
 
 PRTGETOPTDEF VBoxNetBaseService::getOptionsPtr()
Index: trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
===================================================================
--- trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h	(revision 46968)
+++ trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h	(revision 46969)
@@ -18,5 +18,4 @@
 #ifndef ___VBoxNetBaseService_h___
 #define ___VBoxNetBaseService_h___
-
 #include <iprt/critsect.h>
 class VBoxNetBaseService
@@ -33,36 +32,12 @@
     int                 sendBufferOnWire(PCINTNETSEG pSg, int cSg, size_t cbBuffer);
     void                flushWire();
-
     virtual void        usage(void) = 0;
-    virtual int         run(void) = 0;
+    virtual void        run(void) = 0;
+    virtual int         init(void);
     virtual int         parseOpt(int rc, const RTGETOPTUNION& getOptVal) = 0;
 
-    virtual int         init(void);
-
-    /* VirtualBox instance */
-    ComPtr<IVirtualBox> virtualbox;
-
-protected:
-    /**
-     * Print debug message depending on the m_cVerbosity level.
-     *
-     * @param   iMinLevel       The minimum m_cVerbosity level for this message.
-     * @param   fMsg            Whether to dump parts for the current DHCP message.
-     * @param   pszFmt          The message format string.
-     * @param   ...             Optional arguments.
-     */
-    void debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
-    {
-        if (iMinLevel <= m_cVerbosity)
-        {
-            va_list va;
-            va_start(va, pszFmt);
-            debugPrintV(iMinLevel, fMsg, pszFmt, va);
-            va_end(va);
-        }
-    }
-
-    virtual void debugPrintV(int32_t iMinLevel, bool fMsg, const char *pszFmt, va_list va) const;
-
+    inline void         debugPrint( int32_t iMinLevel, bool fMsg,  const char *pszFmt, ...) const;
+    void                debugPrintV(int32_t iMinLevel, bool fMsg,  const char *pszFmt, va_list va) const;
+public:
     /** @name The server configuration data members.
      * @{ */
@@ -74,4 +49,6 @@
     RTNETADDRIPV4       m_Ipv4Address;
     RTNETADDRIPV4       m_Ipv4Netmask;
+    /* cs for syncing */
+    RTCRITSECT          m_csThis;
     /** @} */
     /** @name The network interface
@@ -89,8 +66,4 @@
 private:
     PRTGETOPTDEF getOptionsPtr();
-
-    /* cs for syncing */
-    RTCRITSECT          m_csThis;
-
     /** @} */
 };
