Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp	(revision 79760)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDHCPServer.cpp	(revision 79761)
@@ -230,6 +230,6 @@
         { "--vm",               'M', RTGETOPT_REQ_STRING  },
         { "--nic",              'n', RTGETOPT_REQ_UINT8   },
-        { "--add-opt",          'A', RTGETOPT_REQ_STRING  },
-        { "--del-opt",          'D', RTGETOPT_REQ_STRING  },
+        { "--add-opt",          'A', RTGETOPT_REQ_UINT8   },
+        { "--del-opt",          'D', RTGETOPT_REQ_UINT8   },
         { "--id",               'i', RTGETOPT_REQ_UINT8   },    // obsolete, backwards compatibility only.
         { "--value",            'p', RTGETOPT_REQ_STRING  },    // obsolete, backwards compatibility only.
@@ -497,5 +497,5 @@
         {
             CHECK_ERROR2_STMT(hrc, svr, AddVmSlotOption(Bstr(it->first.VmName.c_str()).raw(), it->first.u8Slot, itOpt->first,
-                                                        com::Bstr(itOpt->second.c_str()).raw()),
+                                                        com::Bstr(itOpt->second).raw()),
                               rcExit = RTEXITCODE_FAILURE);
         }
Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 79760)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 79761)
@@ -444,4 +444,5 @@
 ##         VBoxC, you shall obviously put them in VBOX_MAIN_DEFS!  So, one way or the other they they disappear from here...
 VBoxSVC_DEFS = \
+       IN_VBOXSVC \
 	VBOX_MAIN_SETTINGS_ADDONS \
 	IN_VMM_STATIC \
@@ -551,4 +552,5 @@
 	src-server/DHCPServerImpl.cpp \
 	src-server/DHCPConfigImpl.cpp \
+	../NetworkServices/Dhcpd/DhcpOptions.cpp \
 	src-server/NetworkServiceRunner.cpp \
 	src-server/NATNetworkImpl.cpp \
Index: /trunk/src/VBox/Main/include/DHCPServerImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/DHCPServerImpl.h	(revision 79760)
+++ /trunk/src/VBox/Main/include/DHCPServerImpl.h	(revision 79761)
@@ -113,5 +113,5 @@
      * @{  */
     HRESULT i_doSaveSettings();
-    HRESULT i_calcLeasesFilename(const com::Utf8Str &aNetwork) RT_NOEXCEPT;
+    HRESULT i_calcLeasesConfigAndLogFilenames(const com::Utf8Str &aNetwork) RT_NOEXCEPT;
     HRESULT i_writeDhcpdConfig(const char *pszFilename, uint32_t uMACAddressVersion) RT_NOEXCEPT;
 
Index: /trunk/src/VBox/Main/include/NetworkServiceRunner.h
===================================================================
--- /trunk/src/VBox/Main/include/NetworkServiceRunner.h	(revision 79760)
+++ /trunk/src/VBox/Main/include/NetworkServiceRunner.h	(revision 79761)
@@ -53,6 +53,8 @@
     int  start(bool aKillProcessOnStop);
     int  stop();
+    void detachFromServer();
     bool isRunning();
-    void detachFromServer();
+
+    RTPROCESS getPid() const;
 
     /** @name Common options
Index: /trunk/src/VBox/Main/src-server/DHCPConfigImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/DHCPConfigImpl.cpp	(revision 79760)
+++ /trunk/src/VBox/Main/src-server/DHCPConfigImpl.cpp	(revision 79761)
@@ -36,4 +36,6 @@
 #include "VirtualBoxImpl.h"
 
+#include "../../NetworkServices/Dhcpd/DhcpOptions.h"
+
 
 
@@ -159,18 +161,49 @@
 HRESULT DHCPConfig::i_setOption(DhcpOpt_T aOption, DHCPOptionEncoding_T aEncoding, const com::Utf8Str &aValue)
 {
-    /** @todo validate option value format. */
-    {
-        AutoWriteLock alock(m_pHack COMMA_LOCKVAL_SRC_POS);
-        try
+    /*
+     * Validate the option as there is no point in allowing the user to set
+     * something that the DHCP server does not grok.  It will only lead to
+     * startup failures an no DHCP.  We share this code with the server.
+     */
+    DhcpOption *pParsed = NULL;
+    int         rc      = VINF_SUCCESS;
+    try
+    {
+        pParsed = DhcpOption::parse((uint8_t)aOption, aEncoding, aValue.c_str(), &rc);
+    }
+    catch (std::bad_alloc &)
+    {
+        return E_OUTOFMEMORY;
+    }
+    if (pParsed)
+    {
+        delete pParsed;
+
+        /*
+         * Add/change it.
+         */
         {
-            m_OptionMap[aOption] = settings::DhcpOptValue(aValue, aEncoding);
+            AutoWriteLock alock(m_pHack COMMA_LOCKVAL_SRC_POS);
+            try
+            {
+                m_OptionMap[aOption] = settings::DhcpOptValue(aValue, aEncoding);
+            }
+            catch (std::bad_alloc &)
+            {
+                return E_OUTOFMEMORY;
+            }
         }
-        catch (std::bad_alloc &)
-        {
-            return E_OUTOFMEMORY;
-        }
-    }
-    i_doWriteConfig();
-    return S_OK;
+        i_doWriteConfig();
+        return S_OK;
+    }
+
+    if (rc == VERR_WRONG_TYPE)
+        return m_pHack->setError(E_INVALIDARG, m_pHack->tr("Unsupported encoding %d (option %d, value %s)"),
+                                 (int)aEncoding, (int)aOption, aValue.c_str());
+    if (rc == VERR_NOT_SUPPORTED)
+        return m_pHack->setError(E_INVALIDARG, m_pHack->tr("Unsupported option %d (encoding %d, value %s)"),
+                                 (int)aOption, (int)aEncoding, aValue.c_str());
+    return m_pHack->setError(E_INVALIDARG, m_pHack->tr("Malformed option %d value '%s' (encoding %d, rc=%Rrc)"),
+                             (int)aOption, aValue.c_str(), (int)aEncoding, rc);
 }
 
Index: /trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp	(revision 79760)
+++ /trunk/src/VBox/Main/src-server/DHCPServerImpl.cpp	(revision 79761)
@@ -65,11 +65,5 @@
     virtual ~DHCPServerRunner()
     {}
-
-    static const char * const kDsrKeyConfig;
-    static const char * const kDsrKeyComment;
 };
-
-/*static*/ const char * const DHCPServerRunner::kDsrKeyConfig  = "--config";
-/*static*/ const char * const DHCPServerRunner::kDsrKeyComment = "--comment";
 
 
@@ -85,5 +79,4 @@
         , uIndividualMACAddressVersion(1)
     {
-        szTempConfigFileName[0] = '\0';
     }
 
@@ -101,6 +94,8 @@
     DHCPServerRunner dhcp;
 
-    char szTempConfigFileName[RTPATH_MAX];
     com::Utf8Str strLeasesFilename;
+    com::Utf8Str strConfigFilename;
+    com::Utf8Str strLogFilename;
+
     com::Utf8Str networkName;
     com::Utf8Str trunkName;
@@ -1079,5 +1074,5 @@
     if (m->dhcp.isRunning())
         return setErrorBoth(VBOX_E_OBJECT_IN_USE, VERR_PROCESS_RUNNING,
-                            tr("Cannot start DHCP server because it is already running"));
+                            tr("Cannot start DHCP server because it is already running (pid %RTproc)"), m->dhcp.getPid());
 
     /*
@@ -1087,5 +1082,5 @@
     m->trunkName   = aTrunkName;
     m->trunkType   = aTrunkType;
-    HRESULT hrc = i_calcLeasesFilename(aNetworkName);
+    HRESULT hrc = i_calcLeasesConfigAndLogFilenames(aNetworkName);
     if (SUCCEEDED(hrc))
     {
@@ -1093,37 +1088,29 @@
          * Create configuration file path and write out the configuration.
          */
-        /** @todo put this next to the leases file.   */
-        int vrc = RTPathTemp(m->szTempConfigFileName, sizeof(m->szTempConfigFileName));
-        if (RT_SUCCESS(vrc))
-            vrc = RTPathAppend(m->szTempConfigFileName, sizeof(m->szTempConfigFileName), "dhcp-config-XXXXX.xml");
-        if (RT_SUCCESS(vrc))
-            vrc = RTFileCreateTemp(m->szTempConfigFileName, 0600);
-        if (RT_SUCCESS(vrc))
-        {
-            hrc = i_writeDhcpdConfig(m->szTempConfigFileName, uMACAddressVersion);
-            if (SUCCEEDED(hrc))
+        hrc = i_writeDhcpdConfig(m->strConfigFilename.c_str(), uMACAddressVersion);
+        if (SUCCEEDED(hrc))
+        {
+            /*
+             * Setup the arguments and start the DHCP server.
+             */
+            m->dhcp.resetArguments();
+            int vrc = m->dhcp.addArgPair("--comment", m->networkName.c_str());
+            if (RT_SUCCESS(vrc))
+                vrc = m->dhcp.addArgPair("--config", m->strConfigFilename.c_str());
+            if (RT_SUCCESS(vrc))
+                vrc = m->dhcp.addArgPair("--log", m->networkName.c_str());
+            /** @todo Add --log-flags, --log-group-settings, and --log-destinations with
+             *        associated IDHCPServer attributes.  (Not doing it now because that'll
+             *        exhaust all reserved attribute slot in 6.0.) */
+            if (RT_SUCCESS(vrc))
             {
-                /*
-                 * Setup the arguments and start the DHCP server.
-                 */
-                m->dhcp.resetArguments();
-                vrc = m->dhcp.addArgPair(DHCPServerRunner::kDsrKeyConfig, m->szTempConfigFileName);
-                if (RT_SUCCESS(vrc))
-                    vrc = m->dhcp.addArgPair(DHCPServerRunner::kDsrKeyComment, m->networkName.c_str());
-                if (RT_SUCCESS(vrc))
-                    vrc = m->dhcp.start(true /*aKillProcessOnStop*/);
+                /* Start it: */
+                vrc = m->dhcp.start(true /*aKillProcessOnStop*/);
                 if (RT_FAILURE(vrc))
                     hrc = setErrorVrc(vrc, tr("Failed to start DHCP server for '%s': %Rrc"), m->strName.c_str(), vrc);
             }
-            if (FAILED(hrc))
-            {
-                RTFileDelete(m->szTempConfigFileName);
-                m->szTempConfigFileName[0] = '\0';
-            }
-        }
-        else
-        {
-            m->szTempConfigFileName[0] = '\0';
-            hrc = setErrorVrc(vrc);
+            else
+                hrc = setErrorVrc(vrc, tr("Failed to assemble the command line for DHCP server '%s': %Rrc"),
+                                  m->strName.c_str(), vrc);
         }
     }
@@ -1135,10 +1122,4 @@
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->szTempConfigFileName[0])
-    {
-        RTFileDelete(m->szTempConfigFileName);
-        m->szTempConfigFileName[0] = '\0';
-    }
 
     int vrc = m->dhcp.stop();
@@ -1174,5 +1155,5 @@
     if (m->strLeasesFilename.isEmpty())
     {
-        HRESULT hrc = i_calcLeasesFilename(m->networkName.isEmpty() ? m->strName : m->networkName);
+        HRESULT hrc = i_calcLeasesConfigAndLogFilenames(m->networkName.isEmpty() ? m->strName : m->networkName);
         if (FAILED(hrc))
             return hrc;
@@ -1424,5 +1405,5 @@
  * Calculates and updates the value of strLeasesFilename given @a aNetwork.
  */
-HRESULT DHCPServer::i_calcLeasesFilename(const com::Utf8Str &aNetwork) RT_NOEXCEPT
+HRESULT DHCPServer::i_calcLeasesConfigAndLogFilenames(const com::Utf8Str &aNetwork) RT_NOEXCEPT
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -1433,12 +1414,34 @@
         vrc = RTPathAppendCxx(m->strLeasesFilename, aNetwork);
     if (RT_SUCCESS(vrc))
-        vrc = m->strLeasesFilename.appendNoThrow("-Dhcpd.leases");
-    if (RT_SUCCESS(vrc))
     {
         RTPathPurgeFilename(RTPathFilename(m->strLeasesFilename.mutableRaw()), RTPATH_STR_F_STYLE_HOST);
-        m->strLeasesFilename.jolt();
-        return S_OK;
-    }
-    return setErrorBoth(E_FAIL, vrc, tr("Failed to construct lease filename: %Rrc"), vrc);
-}
-
+
+        /* The configuration file: */
+        vrc = m->strConfigFilename.assignNoThrow(m->strLeasesFilename);
+        if (RT_SUCCESS(vrc))
+            vrc = m->strConfigFilename.appendNoThrow("-Dhcpd.config");
+
+
+        /* The log file: */
+        if (RT_SUCCESS(vrc))
+        {
+            vrc = m->strLogFilename.assignNoThrow(m->strLeasesFilename);
+            if (RT_SUCCESS(vrc))
+                vrc = m->strLogFilename.appendNoThrow("-Dhcpd.log");
+
+            /* Finally, complete the leases file: */
+            if (RT_SUCCESS(vrc))
+            {
+                vrc = m->strLeasesFilename.appendNoThrow("-Dhcpd.leases");
+                if (RT_SUCCESS(vrc))
+                {
+                    RTPathPurgeFilename(RTPathFilename(m->strLeasesFilename.mutableRaw()), RTPATH_STR_F_STYLE_HOST);
+                    m->strLeasesFilename.jolt();
+                    return S_OK;
+                }
+            }
+        }
+    }
+    return setErrorBoth(E_FAIL, vrc, tr("Failed to construct leases, config and log filenames: %Rrc"), vrc);
+}
+
Index: /trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp	(revision 79760)
+++ /trunk/src/VBox/Main/src-server/NetworkServiceRunner.cpp	(revision 79761)
@@ -286,2 +286,12 @@
     return false;
 }
+
+
+/**
+ * Gets the process ID of a running service, NIL_PROCESS if not running.
+ */
+RTPROCESS NetworkServiceRunner::getPid() const
+{
+    return m->Process;
+}
+
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp	(revision 79760)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp	(revision 79761)
@@ -36,4 +36,10 @@
 
 
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/*static*/ bool Config::g_fInitializedLog = false;
+
+
 /**
  * Configuration file exception.
@@ -70,5 +76,4 @@
     : m_strHome()
     , m_strNetwork()
-    , m_strBaseName()
     , m_strTrunk()
     , m_enmTrunkType(kIntNetTrunkType_Invalid)
@@ -140,40 +145,4 @@
 
 /**
- * Internal network name (m_strNetwork) setter.
- *
- * Can only be called once.  Will also invoke i_sanitizeBaseName to update
- * m_strBaseName.
- *
- * @throws std::bad_alloc
- */
-void Config::i_setNetwork(const RTCString &aStrNetwork)
-{
-    AssertReturnVoid(m_strNetwork.isEmpty());
-
-    m_strNetwork = aStrNetwork;
-    i_sanitizeBaseName();
-}
-
-
-/**
- * Interal worker for i_setNetwork() that sets m_strBaseName to sanitized the
- * version of m_strNetwork suitable for use as a path component.
- *
- * @throws std::bad_alloc
- */
-void Config::i_sanitizeBaseName()
-{
-    if (m_strNetwork.isNotEmpty())
-    {
-        m_strBaseName = m_strNetwork;
-        RTPathPurgeFilename(m_strBaseName.mutableRaw(), RTPATH_STR_F_STYLE_HOST);
-        m_strBaseName.jolt();
-    }
-    else
-        m_strBaseName.setNull();
-}
-
-
-/**
  * Worker for i_complete() that initializes the release log of the process.
  *
@@ -182,9 +151,12 @@
  * command line?
  *
- * @todo make the log file directly configurable?
+ * @note This is only used when no --log parameter was given.
  */
 int Config::i_logInit() RT_NOEXCEPT
 {
-    if (m_strHome.isEmpty() || m_strBaseName.isEmpty())
+    if (g_fInitializedLog)
+        return VINF_SUCCESS;
+
+    if (m_strHome.isEmpty() || m_strNetwork.isEmpty())
         return VERR_PATH_ZERO_LENGTH;
 
@@ -193,22 +165,29 @@
     ssize_t cch = RTStrPrintf2(szLogFile, sizeof(szLogFile),
                                "%s%c%s-Dhcpd.log",
-                               m_strHome.c_str(), RTPATH_DELIMITER, m_strBaseName.c_str());
-    if (cch <= 0)
-        return VERR_BUFFER_OVERFLOW;
-
-    /* Sanitize base name some more to be usable in an environment variable name: */
-    char szEnvVarBase[128];
-    cch = RTStrPrintf(szEnvVarBase, sizeof(szEnvVarBase), "VBOXDHCP_%s_RELEASE_LOG", m_strBaseName.c_str());
-    if (cch <= 0)
-        return VERR_BUFFER_OVERFLOW;
-    for (char *p = szEnvVarBase; *p != '\0'; ++p)
-        if (*p != '_' && !RT_C_IS_ALNUM(*p))
-            *p = '_';
+                               m_strHome.c_str(), RTPATH_DELIMITER, m_strNetwork.c_str());
+    if (cch > 0)
+    {
+        RTPathPurgeFilename(RTPathFilename(szLogFile), RTPATH_STR_F_STYLE_HOST);
+        return i_logInitWithFilename(szLogFile);
+    }
+    return VERR_BUFFER_OVERFLOW;
+}
+
+
+/**
+ * Worker for i_logInit and for handling --log on the command line.
+ *
+ * @returns IPRT status code.
+ * @param   pszFilename         The log filename.
+ */
+/*static*/ int Config::i_logInitWithFilename(const char *pszFilename) RT_NOEXCEPT
+{
+    AssertReturn(!g_fInitializedLog, VERR_WRONG_ORDER);
 
     int rc = com::VBoxLogRelCreate("DHCP Server",
-                                   szLogFile,
+                                   pszFilename,
                                    RTLOGFLAGS_PREFIX_TIME_PROG,
-                                   "all all.restrict -default.restrict",
-                                   szEnvVarBase,
+                                   "all net_dhcpd.e.l",
+                                   "VBOXDHCP_RELEASE_LOG",
                                    RTLOGDEST_FILE
 #ifdef DEBUG
@@ -217,10 +196,14 @@
                                    ,
                                    32768 /* cMaxEntriesPerGroup */,
-                                   0 /* cHistory */,
-                                   0 /* uHistoryFileTime */,
-                                   0 /* uHistoryFileSize */,
+                                   5 /* cHistory */,
+                                   RT_SEC_1DAY /* uHistoryFileTime */,
+                                   _32M /* uHistoryFileSize */,
                                    NULL /* pErrInfo */);
-
+    if (RT_SUCCESS(rc))
+        g_fInitializedLog = true;
+    else
+        RTMsgError("Log initialization failed: %Rrc, log file '%s'", rc, pszFilename);
     return rc;
+
 }
 
@@ -324,73 +307,36 @@
 
 
-/*static*/ Config *Config::hardcoded() RT_NOEXCEPT
-{
-    std::unique_ptr<Config> config(i_createInstanceAndCallInit());
-    AssertReturn(config.get() != NULL, NULL);
-    try
-    {
-        config->i_setNetwork("HostInterfaceNetworking-vboxnet0");
-        config->m_strTrunk.assign("vboxnet0");
-    }
-    catch (std::bad_alloc &)
-    {
-        return NULL;
-    }
-    config->m_enmTrunkType = kIntNetTrunkType_NetFlt;
-
-    config->m_MacAddress.au8[0] = 0x08;
-    config->m_MacAddress.au8[1] = 0x00;
-    config->m_MacAddress.au8[2] = 0x27;
-    config->m_MacAddress.au8[3] = 0xa9;
-    config->m_MacAddress.au8[4] = 0xcf;
-    config->m_MacAddress.au8[5] = 0xef;
-
-
-    config->m_IPv4Address.u     = RT_H2N_U32_C(0xc0a838fe); /* 192.168.56.254 */
-    config->m_IPv4Netmask.u     = RT_H2N_U32_C(0xffffff00); /* 255.255.255.0 */
-
-    /* flip to test naks */
-#if 1
-    config->m_IPv4PoolFirst.u   = RT_H2N_U32_C(0xc0a8385a); /* 192.168.56.90 */
-    config->m_IPv4PoolLast.u    = RT_H2N_U32_C(0xc0a83863); /* 192.168.56.99 */
-#else
-    config->m_IPv4PoolFirst.u   = RT_H2N_U32_C(0xc0a838c9); /* 192.168.56.201 */
-    config->m_IPv4PoolLast.u    = RT_H2N_U32_C(0xc0a838dc); /* 192.168.56.220 */
-#endif
-
-    int rc = config->i_complete();
+/**
+ * Parses the command line and loads the configuration.
+ *
+ * @returns The configuration, NULL if we ran into some fatal problem.
+ * @param   argc    The argc from main().
+ * @param   argv    The argv from main().
+ */
+Config *Config::create(int argc, char **argv) RT_NOEXCEPT
+{
+    /*
+     * Parse the command line.
+     */
+    static const RTGETOPTDEF s_aOptions[] =
+    {
+        { "--comment",              '#', RTGETOPT_REQ_STRING },
+        { "--config",               'c', RTGETOPT_REQ_STRING },
+        { "--log",                  'l', RTGETOPT_REQ_STRING },
+        { "--log-destinations",     'd', RTGETOPT_REQ_STRING },
+        { "--log-flags",            'f', RTGETOPT_REQ_STRING },
+        { "--log-group-settings",   'g', RTGETOPT_REQ_STRING },
+    };
+
+    RTGETOPTSTATE State;
+    int rc = RTGetOptInit(&State, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
     AssertRCReturn(rc, NULL);
 
-    return config.release();
-}
-
-
-/**
- * Old VBoxNetDHCP style command line parsing.
- *
- * @throws std::bad_alloc
- */
-/*static*/ Config *Config::compat(int argc, char **argv)
-{
-    /* compatibility with old VBoxNetDHCP */
-    static const RTGETOPTDEF s_aCompatOptions[] =
-    {
-        { "--ip-address",     'i',   RTGETOPT_REQ_IPV4ADDR },
-        { "--lower-ip",       'l',   RTGETOPT_REQ_IPV4ADDR },
-        { "--mac-address",    'a',   RTGETOPT_REQ_MACADDR },
-        { "--need-main",      'M',   RTGETOPT_REQ_BOOL },
-        { "--netmask",        'm',   RTGETOPT_REQ_IPV4ADDR },
-        { "--network",        'n',   RTGETOPT_REQ_STRING },
-        { "--trunk-name",     't',   RTGETOPT_REQ_STRING },
-        { "--trunk-type",     'T',   RTGETOPT_REQ_STRING },
-        { "--upper-ip",       'u',   RTGETOPT_REQ_IPV4ADDR },
-    };
-
-    RTGETOPTSTATE State;
-    int rc = RTGetOptInit(&State, argc, argv, s_aCompatOptions, RT_ELEMENTS(s_aCompatOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
-    AssertRCReturn(rc, NULL);
-
-    std::unique_ptr<Config> config(i_createInstanceAndCallInit());
-    AssertReturn(config.get() != NULL, NULL);
+    const char *pszLogFile          = NULL;
+    const char *pszLogGroupSettings = NULL;
+    const char *pszLogDestinations  = NULL;
+    const char *pszLogFlags         = NULL;
+    const char *pszConfig           = NULL;
+    const char *pszComment          = NULL;
 
     for (;;)
@@ -403,96 +349,33 @@
         switch (rc)
         {
-            case 'a': /* --mac-address */
-                if (   config->m_MacAddress.au16[0] != 0
-                    || config->m_MacAddress.au16[1] != 0
-                    || config->m_MacAddress.au16[2] != 0)
-                {
-                    RTMsgError("Duplicate --mac-address option");
-                    return NULL;
-                }
-                config->m_MacAddress = ValueUnion.MacAddr;
+            case 'c': /* --config */
+                pszConfig = ValueUnion.psz;
                 break;
 
-            case 'i': /* --ip-address */
-                if (config->m_IPv4Address.u != 0)
-                {
-                    RTMsgError("Duplicate --ip-address option");
-                    return NULL;
-                }
-                config->m_IPv4Address = ValueUnion.IPv4Addr;
+            case 'l':
+                pszLogFile = ValueUnion.psz;
                 break;
 
-            case 'l': /* --lower-ip */
-                if (config->m_IPv4PoolFirst.u != 0)
-                {
-                    RTMsgError("Duplicate --lower-ip option");
-                    return NULL;
-                }
-                config->m_IPv4PoolFirst = ValueUnion.IPv4Addr;
+            case 'd':
+                pszLogDestinations = ValueUnion.psz;
                 break;
 
-            case 'M': /* --need-main */
-                /* for backward compatibility, ignored */
+            case 'f':
+                pszLogFlags = ValueUnion.psz;
                 break;
 
-            case 'm': /* --netmask */
-                if (config->m_IPv4Netmask.u != 0)
-                {
-                    RTMsgError("Duplicate --netmask option");
-                    return NULL;
-                }
-                config->m_IPv4Netmask = ValueUnion.IPv4Addr;
+            case 'g':
+                pszLogGroupSettings = ValueUnion.psz;
                 break;
 
-            case 'n': /* --network */
-                if (!config->m_strNetwork.isEmpty())
-                {
-                    RTMsgError("Duplicate --network option");
-                    return NULL;
-                }
-                config->i_setNetwork(ValueUnion.psz);
+            case '#': /* --comment */
+                /* The sole purpose of this option is to allow identification of DHCP
+                 * server instances in the process list. We ignore the required string
+                 * argument of this option. */
+                pszComment = ValueUnion.psz;
                 break;
 
-            case 't': /* --trunk-name */
-                if (!config->m_strTrunk.isEmpty())
-                {
-                    RTMsgError("Duplicate --trunk-name option");
-                    return NULL;
-                }
-                config->m_strTrunk.assign(ValueUnion.psz);
-                break;
-
-            case 'T': /* --trunk-type */
-                if (config->m_enmTrunkType != kIntNetTrunkType_Invalid)
-                {
-                    RTMsgError("Duplicate --trunk-type option");
-                    return NULL;
-                }
-                else if (strcmp(ValueUnion.psz, "none") == 0)
-                    config->m_enmTrunkType = kIntNetTrunkType_None;
-                else if (strcmp(ValueUnion.psz, "whatever") == 0)
-                    config->m_enmTrunkType = kIntNetTrunkType_WhateverNone;
-                else if (strcmp(ValueUnion.psz, "netflt") == 0)
-                    config->m_enmTrunkType = kIntNetTrunkType_NetFlt;
-                else if (strcmp(ValueUnion.psz, "netadp") == 0)
-                    config->m_enmTrunkType = kIntNetTrunkType_NetAdp;
-                else
-                {
-                    RTMsgError("Unknown trunk type '%s'", ValueUnion.psz);
-                    return NULL;
-                }
-                break;
-
-            case 'u': /* --upper-ip */
-                if (config->m_IPv4PoolLast.u != 0)
-                {
-                    RTMsgError("Duplicate --upper-ip option");
-                    return NULL;
-                }
-                config->m_IPv4PoolLast = ValueUnion.IPv4Addr;
-                break;
-
             case VINF_GETOPT_NOT_OPTION:
-                RTMsgError("%s: Unexpected command line argument", ValueUnion.psz);
+                RTMsgError("Unexpected command line argument: '%s'", ValueUnion.psz);
                 return NULL;
 
@@ -503,73 +386,43 @@
     }
 
-    rc = config->i_complete();
-    if (RT_FAILURE(rc))
+    if (!pszConfig)
+    {
+        RTMsgError("No configuration file specified (--config file)!\n");
         return NULL;
-
-    return config.release();
-}
-
-
-Config *Config::create(int argc, char **argv) RT_NOEXCEPT
-{
-    static const RTGETOPTDEF s_aOptions[] =
-    {
-        { "--config",       'c', RTGETOPT_REQ_STRING },
-        { "--comment",      '#', RTGETOPT_REQ_STRING }
-    };
-
-    RTGETOPTSTATE State;
-    int rc = RTGetOptInit(&State, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
-    AssertRCReturn(rc, NULL);
-
-    std::unique_ptr<Config> config;
-
-    for (;;)
-    {
-        RTGETOPTUNION ValueUnion;
-        rc = RTGetOpt(&State, &ValueUnion);
-        if (rc == 0)            /* done */
-            break;
-
-        switch (rc)
-        {
-            case 'c': /* --config */
-                if (config.get() != NULL)
-                {
-                    RTMsgError("Duplicate option: --config '%s'\n", ValueUnion.psz);
-                    return NULL;
-                }
-
-                RTMsgInfo("reading config from '%s'...\n", ValueUnion.psz);
-                config.reset(Config::i_read(ValueUnion.psz));
-                if (config.get() == NULL)
-                    return NULL;
-                break;
-
-            case '#': /* --comment */
-                /* The sole purpose of this option is to allow identification of DHCP
-                 * server instances in the process list. We ignore the required string
-                 * argument of this option.
-                 */
-                continue;
-
-            case VINF_GETOPT_NOT_OPTION:
-                RTMsgError("Unexpected command line argument: '%s'", ValueUnion.psz);
-                return NULL;
-
-            default:
-                RTGetOptPrintError(rc, &ValueUnion);
-                return NULL;
-        }
-    }
-
-    if (config.get() != NULL)
-    {
-        rc = config->i_complete();
+    }
+
+    /*
+     * Init the log if a log file was specified.
+     */
+    if (pszLogFile)
+    {
+        rc = i_logInitWithFilename(pszLogFile);
+        if (RT_FAILURE(rc))
+            RTMsgError("Failed to initialize log file '%s': %Rrc", pszLogFile, rc);
+
+        if (pszLogDestinations)
+            RTLogDestinations(RTLogRelGetDefaultInstance(), pszLogDestinations);
+        if (pszLogFlags)
+            RTLogFlags(RTLogRelGetDefaultInstance(), pszLogFlags);
+        if (pszLogGroupSettings)
+            RTLogGroupSettings(RTLogRelGetDefaultInstance(), pszLogGroupSettings);
+
+        LogRel(("--config:  %s\n", pszComment));
+        if (pszComment)
+            LogRel(("--comment: %s\n", pszComment));
+    }
+
+    /*
+     * Read the log file.
+     */
+    RTMsgInfo("reading config from '%s'...\n", pszConfig);
+    std::unique_ptr<Config> ptrConfig;
+    ptrConfig.reset(Config::i_read(pszConfig));
+    if (ptrConfig.get() != NULL)
+    {
+        rc = ptrConfig->i_complete();
         if (RT_SUCCESS(rc))
-            return config.release();
-    }
-    else
-        RTMsgError("No configuration file specified (--config file)!\n");
+            return ptrConfig.release();
+    }
     return NULL;
 }
@@ -693,14 +546,8 @@
      * <DHCPServer> attributes
      */
-    const char *pszNetworkName;
-    if (pElmServer->getAttributeValue("networkName", &pszNetworkName))
-        i_setNetwork(pszNetworkName);
-    else
+    if (!pElmServer->getAttributeValue("networkName", m_strNetwork))
         throw ConfigFileError("DHCPServer/@networkName missing");
-    /** @todo log file override.  */
-    /** @todo log level (dhcpd group flags).  */
-    /** @todo log flags.  */
-    /** @todo control logging to stderr/out.  */
-    /** @todo if we like we could open the release log now.   */
+    if (m_strNetwork.isEmpty())
+        throw ConfigFileError("DHCPServer/@networkName is empty");
 
     const char *pszTrunkType;
@@ -732,9 +579,11 @@
         int rc = m_strLeasesFilename.assignNoThrow(getHome());
         if (RT_SUCCESS(rc))
-            rc = RTPathAppendCxx(m_strLeasesFilename, getBaseName());
+            rc = RTPathAppendCxx(m_strLeasesFilename, m_strNetwork);
         if (RT_SUCCESS(rc))
             rc = m_strLeasesFilename.appendNoThrow("-Dhcpd.leases");
         if (RT_FAILURE(rc))
             throw ConfigFileError("Unexpected error constructing default m_strLeasesFilename value: %Rrc", rc);
+        RTPathPurgeFilename(RTPathFilename(m_strLeasesFilename.mutableRaw()), RTPATH_STR_F_STYLE_HOST);
+        m_strLeasesFilename.jolt();
     }
 
@@ -857,8 +706,8 @@
     int rc = RTStrToUInt8Full(pszName, 10, &u8Opt);
     if (rc != VINF_SUCCESS) /* no warnings either */
-        throw ConfigFileError("Bad option name '%s'", pszName);
+        throw ConfigFileError("Bad option name '%s': %Rrc", pszName, rc);
 
     /* The opional 'encoding' attribute: */
-    uint32_t u32Enc = 0;        /* XXX: DhcpOptEncoding_Legacy */
+    uint32_t u32Enc = 0;            /* XXX: DhcpOptEncoding_Legacy */
     const char *pszEncoding;
     if (pElmOption->getAttributeValue("encoding", &pszEncoding))
@@ -866,5 +715,5 @@
         rc = RTStrToUInt32Full(pszEncoding, 10, &u32Enc);
         if (rc != VINF_SUCCESS) /* no warnings either */
-            throw ConfigFileError("Bad option encoding '%s'", pszEncoding);
+            throw ConfigFileError("Bad option encoding '%s': %Rrc", pszEncoding, rc);
 
         switch (u32Enc)
Index: /trunk/src/VBox/NetworkServices/Dhcpd/Config.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/Config.h	(revision 79760)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/Config.h	(revision 79761)
@@ -45,5 +45,4 @@
 
     RTCString       m_strNetwork;       /**< The name of the internal network the DHCP server is connected to. */
-    RTCString       m_strBaseName;      /**< m_strNetwork sanitized to be usable in a path component. */
     RTCString       m_strLeasesFilename;/**< The lease DB filename. */
 
@@ -70,4 +69,7 @@
      *        vendor class and user class, including simple lists of these. */
 
+    /** Set if we've initialized the log already (via command line). */
+    static bool     g_fInitializedLog;
+
 private:
     Config();
@@ -77,4 +79,5 @@
     static Config      *i_createInstanceAndCallInit() RT_NOEXCEPT;
     int                 i_logInit() RT_NOEXCEPT;
+    static int          i_logInitWithFilename(const char *pszFilename) RT_NOEXCEPT;
     int                 i_complete() RT_NOEXCEPT;
 
@@ -92,5 +95,4 @@
 
     const RTCString    &getNetwork() const RT_NOEXCEPT          { return m_strNetwork; }
-    const RTCString    &getBaseName() const RT_NOEXCEPT         { return m_strBaseName; }
     const RTCString    &getLeasesFilename() const RT_NOEXCEPT   { return m_strLeasesFilename; }
 
@@ -124,7 +126,4 @@
     static void         i_getMacAddressAttribute(const xml::ElementNode *pElm, const char *pszAttrName, PRTMAC pMacAddr);
     /** @} */
-
-    void                i_setNetwork(const RTCString &aStrNetwork);
-    void                i_sanitizeBaseName();
 };
 
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.cpp	(revision 79760)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.cpp	(revision 79761)
@@ -16,7 +16,13 @@
  */
 
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
 #include "DhcpdInternal.h"
 #include "DhcpOptions.h"
 #include "DhcpMessage.h"
+
+#include <iprt/cidr.h>
 
 
@@ -102,8 +108,39 @@
 
 
+int DhcpOption::parse1(bool &aValue, const char *pcszValue)
+{
+    pcszValue = RTStrStripL(pcszValue);
+    if (   strcmp(pcszValue, "true") == 0
+        || strcmp(pcszValue, "1")    == 0
+        || strcmp(pcszValue, "yes")  == 0
+        || strcmp(pcszValue, "on")   == 0 )
+    {
+        aValue = true;
+        return VINF_SUCCESS;
+    }
+
+    if (   strcmp(pcszValue, "false") == 0
+        || strcmp(pcszValue, "0")     == 0
+        || strcmp(pcszValue, "no")    == 0
+        || strcmp(pcszValue, "off")   == 0 )
+    {
+        aValue = false;
+        return VINF_SUCCESS;
+    }
+
+    uint8_t bTmp;
+    int rc = RTStrToUInt8Full(RTStrStripL(pcszValue), 10, &bTmp);
+    if (rc == VERR_TRAILING_SPACES)
+        rc = VINF_SUCCESS;
+    if (RT_SUCCESS(rc))
+        aValue = bTmp != 0;
+
+    return rc;
+}
+
+
 int DhcpOption::parse1(uint8_t &aValue, const char *pcszValue)
 {
     int rc = RTStrToUInt8Full(RTStrStripL(pcszValue), 10, &aValue);
-
     if (rc == VERR_TRAILING_SPACES)
         rc = VINF_SUCCESS;
@@ -138,36 +175,82 @@
 
 
-int DhcpOption::parseList(std::vector<RTNETADDRIPV4> &aList, const char *pcszValue)
-{
-    std::vector<RTNETADDRIPV4> l;
-    int rc;
+int DhcpOption::parse1(DhcpIpv4AddrAndMask &aValue, const char *pcszValue)
+{
+    return RTCidrStrToIPv4(pcszValue, &aValue.Ipv4, &aValue.Mask);
+}
+
+
+template <typename a_Type>
+static int DhcpOption::parseList(std::vector<a_Type> &aList, const char *pcszValue)
+{
+    std::vector<a_Type> vecTmp;
 
     pcszValue = RTStrStripL(pcszValue);
-    do {
-        RTNETADDRIPV4 Addr;
-        char *pszNext;
-
-        rc = RTNetStrToIPv4AddrEx(pcszValue, &Addr, &pszNext);
-        if (RT_FAILURE(rc))
+    for (;;)
+    {
+        /* Assume space, tab, comma or semicolon is used as separator (superset of RTStrStrip): */
+        const char *pszNext = strpbrk(pcszValue, " ,;:\t\n\r");
+        char szTmp[256];
+        if (pszNext)
+        {
+            size_t cchToCopy = pszNext - pcszValue;
+            if (cchToCopy >= sizeof(szTmp))
+                return VERR_INVALID_PARAMETER;
+            memcpy(szTmp, pcszValue, cchToCopy);
+            szTmp[cchToCopy] = '\0';
+            pcszValue = szTmp;
+
+            /* Advance pszNext past the separator character and fluff: */
+            char ch;
+            do
+                pszNext++;
+            while ((ch = *pszNext) == ' ' || ch == ':' || ch == ';' || ch == '\t' || ch == '\n' || ch == '\r');
+            if (ch == '\0')
+                pszNext = NULL;
+        }
+
+        /* Try convert it: */
+        a_Type Value;
+        int rc = DhcpOption::parse1(Value, pcszValue);
+        if (RT_SUCCESS(rc))
+            vecTmp.push_back(Value);
+        else
             return VERR_INVALID_PARAMETER;
 
-        if (rc == VWRN_TRAILING_CHARS)
+        if (pszNext)
+            pcszValue = pszNext;
+        else
+            break;
+    }
+
+    aList.swap(vecTmp);
+    return VINF_SUCCESS;
+
+}
+
+/** ASSUME that uint8_t means hex byte strings. */
+template <>
+static int DhcpOption::parseList(std::vector<uint8_t> &aList, const char *pcszValue)
+{
+    uint8_t     abBuf[256];
+    const char *pszNext = NULL;
+    size_t      cbReturned = 0;
+    int rc = RTStrConvertHexBytesEx(RTStrStripL(pcszValue), abBuf, sizeof(abBuf), RTSTRCONVERTHEXBYTES_F_SEP_COLON,
+                                    &pszNext, &cbReturned);
+    if (RT_SUCCESS(rc))
+    {
+        if (pszNext)
+            pszNext = RTStrStripL(pszNext);
+        if (*pszNext)
         {
-            pcszValue = RTStrStripL(pszNext);
-            if (pcszValue == pszNext) /* garbage after address */
-                return VERR_INVALID_PARAMETER;
+            for (size_t i = 0; i < cbReturned; i++)
+                aList.push_back(abBuf[i]);
+            return VINF_SUCCESS;
         }
-
-        l.push_back(Addr);
-
-        /*
-         * If we got VINF_SUCCESS or VWRN_TRAILING_SPACES then this
-         * was the last address and we are done.
-         */
-    } while (rc == VWRN_TRAILING_CHARS);
-
-    aList.swap(l);
-    return VINF_SUCCESS;
-}
+        rc = VERR_TRAILING_CHARS;
+    }
+    return rc;
+}
+
 
 
@@ -208,36 +291,117 @@
 
 
-DhcpOption *DhcpOption::parse(uint8_t aOptCode, int aEnc, const char *pcszValue)
-{
+DhcpOption *DhcpOption::parse(uint8_t aOptCode, int aEnc, const char *pcszValue, int *prc /*= NULL*/)
+{
+    int rcIgn;
+    if (!prc)
+        prc = &rcIgn;
+
     switch (aEnc)
     {
-    case 0: /* DhcpOptEncoding_Legacy */
-        switch (aOptCode)
-        {
-#define HANDLE(_OptClass)                               \
-            case _OptClass::optcode:                    \
-                return _OptClass::parse(pcszValue);
-
-        HANDLE(OptSubnetMask);
-        HANDLE(OptRouter);
-        HANDLE(OptDNS);
-        HANDLE(OptHostName);
-        HANDLE(OptDomainName);
-        HANDLE(OptRootPath);
-        HANDLE(OptLeaseTime);
-        HANDLE(OptRenewalTime);
-        HANDLE(OptRebindingTime);
+        case 0: /* DhcpOptEncoding_Legacy */
+            switch (aOptCode)
+            {
+#define HANDLE(a_OptClass)  \
+                case a_OptClass::optcode: \
+                    return a_OptClass::parse(pcszValue, prc)
+
+                HANDLE(OptSubnetMask);                  // 1
+                HANDLE(OptTimeOffset);                  // 2
+                HANDLE(OptRouters);                     // 3
+                HANDLE(OptTimeServers);                 // 4
+                HANDLE(OptNameServers);                 // 5
+                HANDLE(OptDNSes);                       // 6
+                HANDLE(OptLogServers);                  // 7
+                HANDLE(OptCookieServers);               // 8
+                HANDLE(OptLPRServers);                  // 9
+                HANDLE(OptImpressServers);              // 10
+                HANDLE(OptResourceLocationServers);     // 11
+                HANDLE(OptHostName);                    // 12
+                HANDLE(OptBootFileSize);                // 13
+                HANDLE(OptMeritDumpFile);               // 14
+                HANDLE(OptDomainName);                  // 15
+                HANDLE(OptSwapServer);                  // 16
+                HANDLE(OptRootPath);                    // 17
+                HANDLE(OptExtensionPath);               // 18
+                HANDLE(OptIPForwarding);                // 19
+                HANDLE(OptNonLocalSourceRouting);       // 20
+                HANDLE(OptPolicyFilter);                // 21
+                HANDLE(OptMaxDatagramReassemblySize);   // 22
+                HANDLE(OptDefaultIPTTL);                // 23
+                HANDLE(OptDefaultPathMTUAgingTimeout);  // 24
+                HANDLE(OptPathMTUPlateauTable);         // 25
+                HANDLE(OptInterfaceMTU);                // 26
+                HANDLE(OptAllSubnetsAreLocal);          // 27
+                HANDLE(OptBroadcastAddress);            // 28
+                HANDLE(OptPerformMaskDiscovery);        // 29
+                HANDLE(OptMaskSupplier);                // 30
+                HANDLE(OptPerformRouterDiscovery);      // 31
+                HANDLE(OptRouterSolicitationAddress);   // 32
+                HANDLE(OptStaticRoute);                 // 33
+                HANDLE(OptTrailerEncapsulation);        // 34
+                HANDLE(OptARPCacheTimeout);             // 35
+                HANDLE(OptEthernetEncapsulation);       // 36
+                HANDLE(OptTCPDefaultTTL);               // 37
+                HANDLE(OptTCPKeepaliveInterval);        // 38
+                HANDLE(OptTCPKeepaliveGarbage);         // 39
+                HANDLE(OptNISDomain);                   // 40
+                HANDLE(OptNISServers);                  // 41
+                HANDLE(OptNTPServers);                  // 42
+                HANDLE(OptVendorSpecificInfo);          // 43
+                HANDLE(OptNetBIOSNameServers);          // 44
+                HANDLE(OptNetBIOSDatagramServers);      // 45
+                HANDLE(OptNetBIOSNodeType);             // 46
+                HANDLE(OptNetBIOSScope);                // 47
+                HANDLE(OptXWindowsFontServers);         // 48
+                HANDLE(OptXWindowsDisplayManager);      // 49
+#ifndef IN_VBOXSVC /* Don't allow these in new configs */
+                // OptRequestedAddress (50) is client only and not configurable.
+                HANDLE(OptLeaseTime);                   // 51 - for historical reasons?  Configuable elsewhere now.
+                // OptOptionOverload (52) is part of the protocol and not configurable.
+                // OptMessageType (53) is part of the protocol and not configurable.
+                // OptServerId (54) is the IP address of the server and configurable elsewhere.
+                // OptParameterRequest (55) is client only and not configurable.
+                // OptMessage (56) is server failure message and not configurable.
+                // OptMaxDHCPMessageSize (57) is client only (?) and not configurable.
+                HANDLE(OptRenewalTime);                 // 58 - for historical reasons?
+                HANDLE(OptRebindingTime);               // 59 - for historical reasons?
+                // OptVendorClassId (60) is client only and not configurable.
+                // OptClientId (61) is client only and not configurable.
+#endif
+                HANDLE(OptNetWareIPDomainName);         // 62
+                HANDLE(OptNetWareIPInformation);        // 63
+                HANDLE(OptNISPlusDomain);               // 64
+                HANDLE(OptNISPlusServers);              // 65
+                HANDLE(OptTFTPServer);                  // 66 - perhaps we should use an alternative way to configure these.
+                HANDLE(OptBootFileName);                // 67 - perhaps we should use an alternative way to configure these.
+                HANDLE(OptMobileIPHomeAgents);          // 68
+                HANDLE(OptSMTPServers);                 // 69
+                HANDLE(OptPOP3Servers);                 // 70
+                HANDLE(OptNNTPServers);                 // 71
+                HANDLE(OptWWWServers);                  // 72
+                HANDLE(OptFingerServers);               // 73
+                HANDLE(OptIRCServers);                  // 74
+                HANDLE(OptStreetTalkServers);           // 75
+                HANDLE(OptSTDAServers);                 // 76
+                // OptUserClassId (77) is client only and not configurable.
+                HANDLE(OptSLPDirectoryAgent);           // 78
+                HANDLE(OptSLPServiceScope);             // 79
+                // OptRapidCommit (80) is not configurable.
 
 #undef HANDLE
+                default:
+                    if (prc)
+                        *prc = VERR_NOT_IMPLEMENTED;
+                    return NULL;
+            }
+            break;
+
+        case 1:
+            return RawOption::parse(aOptCode, pcszValue, prc);
+
         default:
+            if (prc)
+                *prc = VERR_WRONG_TYPE;
             return NULL;
-        }
-        break;
-
-    case 1:
-        return RawOption::parse(aOptCode, pcszValue);
-
-    default:
-        return NULL;
-    }
-}
+    }
+}
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h	(revision 79760)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DhcpOptions.h	(revision 79761)
@@ -33,30 +33,39 @@
 class DhcpClientMessage;
 
+typedef struct DhcpIpv4AddrAndMask
+{
+    RTNETADDRIPV4   Ipv4;
+    RTNETADDRIPV4   Mask;
+} DhcpIpv4AddrAndMask;
+
 
 class DhcpOption
 {
-  protected:
+protected:
     uint8_t m_OptCode;
-    bool m_fPresent;
-
-  public:
+    bool    m_fPresent;
+
+public:
     explicit DhcpOption(uint8_t aOptCode)
-      : m_OptCode(aOptCode), m_fPresent(true) {}
+        : m_OptCode(aOptCode), m_fPresent(true)
+    {}
 
     DhcpOption(uint8_t aOptCode, bool fPresent)
-      : m_OptCode(aOptCode), m_fPresent(fPresent) {}
+        : m_OptCode(aOptCode), m_fPresent(fPresent)
+    {}
 
     virtual DhcpOption *clone() const = 0;
 
-    virtual ~DhcpOption() {}
-
-  public:
-    static DhcpOption *parse(uint8_t aOptCode, int aEnc, const char *pcszValue);
-
-  public:
+    virtual ~DhcpOption()
+    {}
+
+public:
+    static DhcpOption *parse(uint8_t aOptCode, int aEnc, const char *pcszValue, int *prc = NULL);
+
+public:
     uint8_t optcode() const RT_NOEXCEPT { return m_OptCode; }
     bool    present() const RT_NOEXCEPT { return m_fPresent; }
 
-  public:
+public:
     int encode(octets_t &dst) const;
 
@@ -64,15 +73,20 @@
     int decode(const DhcpClientMessage &req);
 
-  protected:
+protected:
     virtual ssize_t encodeValue(octets_t &dst) const = 0;
     virtual int decodeValue(const octets_t &src, size_t cb) = 0;
 
-  protected:
+protected:
     static const octets_t *findOption(const rawopts_t &aOptMap, uint8_t aOptCode);
 
-  protected:
-    /*
-     * Serialization
-     */
+protected:
+    /** @name Serialization
+     * @{ */
+    static void append(octets_t &aDst, bool aValue)
+    {
+        uint8_t b = aValue ? 1 : 0;
+        aDst.push_back(b);
+    }
+
     static void append(octets_t &aDst, uint8_t aValue)
     {
@@ -97,4 +111,9 @@
     }
 
+    static void append(octets_t &aDst, DhcpIpv4AddrAndMask aIPv4)
+    {
+        aDst.insert(aDst.end(), (uint8_t *)&aIPv4, (uint8_t *)&aIPv4 + sizeof(aIPv4));
+    }
+
     static void append(octets_t &aDst, const char *pszString, size_t cb)
     {
@@ -113,8 +132,15 @@
     }
 
-
-    /*
-     * Deserialization
-     */
+    /** @} */
+
+
+    /** @name Deserialization
+     * @{  */
+    static void extract(bool &aValue, octets_t::const_iterator &pos)
+    {
+        aValue = *pos != 0;
+        pos += sizeof(uint8_t);
+    }
+
     static void extract(uint8_t &aValue, octets_t::const_iterator &pos)
     {
@@ -145,4 +171,10 @@
     }
 
+    static void extract(DhcpIpv4AddrAndMask &aValue, octets_t::const_iterator &pos)
+    {
+        memcpy(&aValue, &pos[0], sizeof(aValue));
+        pos += sizeof(aValue);
+    }
+
 #if 0 /** @todo fix me */
     static void extract(RTCString &aString, octets_t::const_iterator &pos, size_t cb)
@@ -153,16 +185,20 @@
 #endif
 
-
-    /*
-     * Parse textual representation (e.g. in config file)
-     */
+    /** @} */
+
+    /** @name Parse textual representation (e.g. in config file)
+     * @{  */
+    static int parse1(bool &aValue, const char *pcszValue);
     static int parse1(uint8_t &aValue, const char *pcszValue);
     static int parse1(uint16_t &aValue, const char *pcszValue);
     static int parse1(uint32_t &aValue, const char *pcszValue);
     static int parse1(RTNETADDRIPV4 &aValue, const char *pcszValue);
-
-    static int parseList(std::vector<RTNETADDRIPV4> &aList, const char *pcszValue);
+    static int parse1(DhcpIpv4AddrAndMask &aValue, const char *pcszValue);
+
+    template <typename a_Type> static int parseList(std::vector<a_Type> &aList, const char *pcszValue);
 
     static int parseHex(octets_t &aRawValue, const char *pcszValue);
+
+    /** @} */
 };
 
@@ -180,5 +216,5 @@
 
 
-/*
+/**
  * Only for << OptEnd() syntactic sugar...
  */
@@ -194,19 +230,21 @@
 
 
-/*
+/**
  * Option that has no value
  */
 class OptNoValueBase
-  : public DhcpOption
-{
-  public:
+    : public DhcpOption
+{
+public:
     explicit OptNoValueBase(uint8_t aOptCode)
-      : DhcpOption(aOptCode, false) {}
+        : DhcpOption(aOptCode, false)
+    {}
 
     OptNoValueBase(uint8_t aOptCode, bool fPresent)
-      : DhcpOption(aOptCode, fPresent) {}
+        : DhcpOption(aOptCode, fPresent)
+    {}
 
     OptNoValueBase(uint8_t aOptCode, const DhcpClientMessage &req)
-      : DhcpOption(aOptCode, false)
+        : DhcpOption(aOptCode, false)
     {
         decode(req);
@@ -218,5 +256,5 @@
     }
 
-  protected:
+protected:
     virtual ssize_t encodeValue(octets_t &dst) const
     {
@@ -225,5 +263,5 @@
     }
 
-  public:
+public:
     static bool isLengthValid(size_t cb)
     {
@@ -245,17 +283,20 @@
 template <uint8_t _OptCode>
 class OptNoValue
-  : public OptNoValueBase
-{
-  public:
+    : public OptNoValueBase
+{
+public:
     static const uint8_t optcode = _OptCode;
 
     OptNoValue()
-      : OptNoValueBase(optcode) {}
+        : OptNoValueBase(optcode)
+    {}
 
     explicit OptNoValue(bool fPresent) /* there's no overloaded ctor with value */
-      : OptNoValueBase(optcode, fPresent) {}
+        : OptNoValueBase(optcode, fPresent)
+    {}
 
     explicit OptNoValue(const DhcpClientMessage &req)
-      : OptNoValueBase(optcode, req) {}
+        : OptNoValueBase(optcode, req)
+    {}
 };
 
@@ -267,25 +308,27 @@
 template <typename T>
 class OptValueBase
-  : public DhcpOption
-{
-  public:
+    : public DhcpOption
+{
+public:
     typedef T value_t;
 
-  protected:
+protected:
     T m_Value;
 
     explicit OptValueBase(uint8_t aOptCode)
-      : DhcpOption(aOptCode, false), m_Value() {}
+        : DhcpOption(aOptCode, false), m_Value()
+    {}
 
     OptValueBase(uint8_t aOptCode, const T &aOptValue)
-      : DhcpOption(aOptCode), m_Value(aOptValue) {}
+        : DhcpOption(aOptCode), m_Value(aOptValue)
+    {}
 
     OptValueBase(uint8_t aOptCode, const DhcpClientMessage &req)
-      : DhcpOption(aOptCode, false), m_Value()
+        : DhcpOption(aOptCode, false), m_Value()
     {
         decode(req);
     }
 
-  public:
+public:
     virtual OptValueBase *clone() const
     {
@@ -293,9 +336,9 @@
     }
 
-  public:
-    T &value() { return m_Value; }
-    const T &value() const { return m_Value; }
-
-  protected:
+public:
+    T &value()              { return m_Value; }
+    const T &value() const  { return m_Value; }
+
+protected:
     virtual ssize_t encodeValue(octets_t &dst) const
     {
@@ -304,5 +347,5 @@
     }
 
-  public:
+public:
     static bool isLengthValid(size_t cb)
     {
@@ -325,58 +368,64 @@
 template<uint8_t _OptCode, typename T>
 class OptValue
-  : public OptValueBase<T>
-{
-  public:
+    : public OptValueBase<T>
+{
+public:
     using typename OptValueBase<T>::value_t;
 
-  public:
+public:
     static const uint8_t optcode = _OptCode;
 
     OptValue()
-      : OptValueBase<T>(optcode) {}
+        : OptValueBase<T>(optcode)
+    {}
 
     explicit OptValue(const T &aOptValue)
-      : OptValueBase<T>(optcode, aOptValue) {}
+        : OptValueBase<T>(optcode, aOptValue)
+    {}
 
     explicit OptValue(const DhcpClientMessage &req)
-      : OptValueBase<T>(optcode, req) {}
-
-    static OptValue *parse(const char *pcszValue)
+        : OptValueBase<T>(optcode, req)
+    {}
+
+    static OptValue *parse(const char *pcszValue, int *prc)
     {
         typename OptValueBase<T>::value_t v;
         int rc = DhcpOption::parse1(v, pcszValue);
-        if (RT_FAILURE(rc))
-            return NULL;
-        return new OptValue(v);
-    }
-};
-
-
-
-/*
+        *prc = rc;
+        if (RT_SUCCESS(rc))
+            return new OptValue(v);
+        return NULL;
+    }
+};
+
+
+
+/**
  * Option that contains a string.
  */
 class OptStringBase
-  : public DhcpOption
-{
-  public:
+    : public DhcpOption
+{
+public:
     typedef RTCString value_t;
 
-  protected:
+protected:
     RTCString m_String;
 
     explicit OptStringBase(uint8_t aOptCode)
-      : DhcpOption(aOptCode, false), m_String() {}
+        : DhcpOption(aOptCode, false), m_String()
+    {}
 
     OptStringBase(uint8_t aOptCode, const RTCString &aOptString)
-      : DhcpOption(aOptCode), m_String(aOptString) {}
+        : DhcpOption(aOptCode), m_String(aOptString)
+    {}
 
     OptStringBase(uint8_t aOptCode, const DhcpClientMessage &req)
-      : DhcpOption(aOptCode, false), m_String()
+        : DhcpOption(aOptCode, false), m_String()
     {
         decode(req);
     }
 
-  public:
+public:
     virtual OptStringBase *clone() const
     {
@@ -384,9 +433,9 @@
     }
 
-  public:
-    RTCString &value() { return m_String; }
-    const RTCString &value() const { return m_String; }
-
-  protected:
+public:
+    RTCString &value()              { return m_String; }
+    const RTCString &value() const  { return m_String; }
+
+protected:
     virtual ssize_t encodeValue(octets_t &dst) const
     {
@@ -398,5 +447,5 @@
     }
 
-  public:
+public:
     static bool isLengthValid(size_t cb)
     {
@@ -417,20 +466,24 @@
 template<uint8_t _OptCode>
 class OptString
-  : public OptStringBase
-{
-  public:
+    : public OptStringBase
+{
+public:
     static const uint8_t optcode = _OptCode;
 
     OptString()
-      : OptStringBase(optcode) {}
+        : OptStringBase(optcode)
+    {}
 
     explicit OptString(const RTCString &aOptString)
-      : OptStringBase(optcode, aOptString) {}
+        : OptStringBase(optcode, aOptString)
+    {}
 
     explicit OptString(const DhcpClientMessage &req)
-      : OptStringBase(optcode, req) {}
-
-    static OptString *parse(const char *pcszValue)
-    {
+        : OptStringBase(optcode, req)
+    {}
+
+    static OptString *parse(const char *pcszValue, int *prc)
+    {
+        *prc = VINF_SUCCESS;
         return new OptString(pcszValue);
     }
@@ -444,28 +497,31 @@
 template <typename T>
 class OptListBase
-  : public DhcpOption
-{
-  public:
+    : public DhcpOption
+{
+public:
     typedef std::vector<T> value_t;
 
-  protected:
+protected:
     std::vector<T> m_List;
 
     explicit OptListBase(uint8_t aOptCode)
-      : DhcpOption(aOptCode, false), m_List() {}
+        : DhcpOption(aOptCode, false), m_List()
+    {}
 
     OptListBase(uint8_t aOptCode, const T &aOptSingle)
-      : DhcpOption(aOptCode), m_List(1, aOptSingle) {}
+        : DhcpOption(aOptCode), m_List(1, aOptSingle)
+    {}
 
     OptListBase(uint8_t aOptCode, const std::vector<T> &aOptList)
-      : DhcpOption(aOptCode), m_List(aOptList) {}
+        : DhcpOption(aOptCode), m_List(aOptList)
+    {}
 
     OptListBase(uint8_t aOptCode, const DhcpClientMessage &req)
-      : DhcpOption(aOptCode, false), m_List()
+        : DhcpOption(aOptCode, false), m_List()
     {
         decode(req);
     }
 
-  public:
+public:
     virtual OptListBase *clone() const
     {
@@ -473,9 +529,9 @@
     }
 
-  public:
-    std::vector<T> &value() { return m_List; }
+public:
+    std::vector<T> &value()             { return m_List; }
     const std::vector<T> &value() const { return m_List; }
 
-  protected:
+protected:
     virtual ssize_t encodeValue(octets_t &dst) const
     {
@@ -495,5 +551,5 @@
     }
 
-  public:
+public:
     static bool isLengthValid(size_t cb)
     {
@@ -522,32 +578,95 @@
 template<uint8_t _OptCode, typename T>
 class OptList
-  : public OptListBase<T>
-
-{
-  public:
+    : public OptListBase<T>
+
+{
+public:
     using typename OptListBase<T>::value_t;
 
-  public:
+public:
     static const uint8_t optcode = _OptCode;
 
     OptList()
-      : OptListBase<T>(optcode) {}
+        : OptListBase<T>(optcode)
+    {}
 
     explicit OptList(const T &aOptSingle)
-      : OptListBase<T>(optcode, aOptSingle) {}
+        : OptListBase<T>(optcode, aOptSingle)
+    {}
 
     explicit OptList(const std::vector<T> &aOptList)
-      : OptListBase<T>(optcode, aOptList) {}
+        : OptListBase<T>(optcode, aOptList)
+    {}
 
     explicit OptList(const DhcpClientMessage &req)
-      : OptListBase<T>(optcode, req) {}
-
-    static OptList *parse(const char *pcszValue)
+        : OptListBase<T>(optcode, req)
+    {}
+
+    static OptList *parse(const char *pcszValue, int *prc)
     {
         typename OptListBase<T>::value_t v;
-        int rc = DhcpOption::parseList(v, pcszValue);
-        if (RT_FAILURE(rc) || v.empty())
-            return NULL;
-        return new OptList(v);
+        int rc = DhcpOption::parseList<T>(v, pcszValue);
+        if (RT_SUCCESS(rc))
+        {
+            if (!v.empty())
+            {
+                *prc = rc;
+                return new OptList(v);
+            }
+            rc = VERR_NO_DATA;
+        }
+        *prc = rc;
+        return NULL;
+    }
+};
+
+
+template<uint8_t _OptCode, typename T>
+class OptPairList
+    : public OptListBase<T>
+
+{
+public:
+    using typename OptListBase<T>::value_t;
+
+public:
+    static const uint8_t optcode = _OptCode;
+
+    OptPairList()
+        : OptListBase<T>(optcode)
+    {}
+
+    explicit OptPairList(const T &aOptSingle)
+        : OptListBase<T>(optcode, aOptSingle)
+    {}
+
+    explicit OptPairList(const std::vector<T> &aOptList)
+        : OptListBase<T>(optcode, aOptList)
+    {}
+
+    explicit OptPairList(const DhcpClientMessage &req)
+        : OptListBase<T>(optcode, req)
+    {}
+
+    static OptPairList *parse(const char *pcszValue, int *prc)
+    {
+        typename OptListBase<T>::value_t v;
+        int rc = DhcpOption::parseList<T>(v, pcszValue);
+        if (RT_SUCCESS(rc))
+        {
+            if (!v.empty())
+            {
+                if ((v.size() & 1) == 0)
+                {
+                    *prc = rc;
+                    return new OptPairList(v);
+                }
+                rc = VERR_UNEVEN_INPUT;
+            }
+            else
+                rc = VERR_NO_DATA;
+        }
+        *prc = rc;
+        return NULL;
     }
 };
@@ -559,17 +678,19 @@
  */
 class RawOption
-  : public DhcpOption
-{
-  protected:
+    : public DhcpOption
+{
+protected:
     octets_t m_Data;
 
-  public:
+public:
     explicit RawOption(uint8_t aOptCode)
-      : DhcpOption(aOptCode, false), m_Data() {}
+        : DhcpOption(aOptCode, false), m_Data()
+    {}
 
     RawOption(uint8_t aOptCode, const octets_t &aSrc)
-      : DhcpOption(aOptCode), m_Data(aSrc) {}
-
-  public:
+        : DhcpOption(aOptCode), m_Data(aSrc)
+    {}
+
+public:
     virtual RawOption *clone() const
     {
@@ -578,5 +699,5 @@
 
 
-  protected:
+protected:
     virtual ssize_t encodeValue(octets_t &dst) const
     {
@@ -595,12 +716,13 @@
     }
 
-  public:
-    static RawOption *parse(uint8_t aOptCode, const char *pcszValue)
+public:
+    static RawOption *parse(uint8_t aOptCode, const char *pcszValue, int *prc)
     {
         octets_t data;
         int rc = DhcpOption::parseHex(data, pcszValue);
-        if (RT_FAILURE(rc))
-            return NULL;
-        return new RawOption(aOptCode, data);
+        *prc = rc;
+        if (RT_SUCCESS(rc))
+            return new RawOption(aOptCode, data);
+        return NULL;
     }
 };
@@ -613,13 +735,52 @@
 typedef OptValue<1, RTNETADDRIPV4>      OptSubnetMask;
 typedef OptValue<2, uint32_t>           OptTimeOffset;
-typedef OptList<3, RTNETADDRIPV4>       OptRouter;
-typedef OptList<4, RTNETADDRIPV4>       OptTimeServer;
-typedef OptList<6, RTNETADDRIPV4>       OptDNS;
+typedef OptList<3, RTNETADDRIPV4>       OptRouters;
+typedef OptList<4, RTNETADDRIPV4>       OptTimeServers;
+typedef OptList<5, RTNETADDRIPV4>       OptNameServers;
+typedef OptList<6, RTNETADDRIPV4>       OptDNSes;
+typedef OptList<7, RTNETADDRIPV4>       OptLogServers;
+typedef OptList<8, RTNETADDRIPV4>       OptCookieServers;
+typedef OptList<9, RTNETADDRIPV4>       OptLPRServers;
+typedef OptList<10, RTNETADDRIPV4>      OptImpressServers;
+typedef OptList<11, RTNETADDRIPV4>      OptResourceLocationServers;
 typedef OptString<12>                   OptHostName;
+typedef OptValue<13, uint16_t>          OptBootFileSize;
+typedef OptString<14>                   OptMeritDumpFile;
 typedef OptString<15>                   OptDomainName;
+typedef OptValue<16, RTNETADDRIPV4>     OptSwapServer;
 typedef OptString<17>                   OptRootPath;
-
-/* DHCP related options */
+typedef OptString<18>                   OptExtensionPath;
+typedef OptValue<19, bool>              OptIPForwarding;
+typedef OptValue<20, bool>              OptNonLocalSourceRouting;
+typedef OptList<21, DhcpIpv4AddrAndMask> OptPolicyFilter;
+typedef OptValue<22, uint16_t>          OptMaxDatagramReassemblySize;
+typedef OptValue<23, uint16_t>          OptDefaultIPTTL;
+typedef OptValue<24, uint32_t>          OptDefaultPathMTUAgingTimeout;
+typedef OptList<25, uint16_t>           OptPathMTUPlateauTable;
+typedef OptValue<26, uint16_t>          OptInterfaceMTU;
+typedef OptValue<27, bool>              OptAllSubnetsAreLocal;
+typedef OptValue<28, RTNETADDRIPV4>     OptBroadcastAddress;
+typedef OptValue<29, bool>              OptPerformMaskDiscovery;
+typedef OptValue<30, bool>              OptMaskSupplier;
+typedef OptValue<31, bool>              OptPerformRouterDiscovery;
+typedef OptValue<32, RTNETADDRIPV4>     OptRouterSolicitationAddress;
+typedef OptPairList<33, RTNETADDRIPV4>  OptStaticRoute;
+typedef OptValue<34, bool>              OptTrailerEncapsulation;
+typedef OptValue<35, uint32_t>          OptARPCacheTimeout;
+typedef OptValue<36, bool>              OptEthernetEncapsulation;
+typedef OptValue<37, uint8_t>           OptTCPDefaultTTL;
+typedef OptValue<38, uint32_t>          OptTCPKeepaliveInterval;
+typedef OptValue<39, bool>              OptTCPKeepaliveGarbage;
+typedef OptString<40>                   OptNISDomain;
+typedef OptList<41, RTNETADDRIPV4>      OptNISServers;
+typedef OptList<42, RTNETADDRIPV4>      OptNTPServers;
+/* DHCP related options: */
 typedef OptList<43, uint8_t>            OptVendorSpecificInfo;
+typedef OptList<44, RTNETADDRIPV4>      OptNetBIOSNameServers;
+typedef OptList<45, RTNETADDRIPV4>      OptNetBIOSDatagramServers;
+typedef OptValue<46, uint8_t>           OptNetBIOSNodeType;
+typedef OptList<47, uint8_t>            OptNetBIOSScope;            /**< uint8_t or string? */
+typedef OptList<48, RTNETADDRIPV4>      OptXWindowsFontServers;
+typedef OptList<49, RTNETADDRIPV4>      OptXWindowsDisplayManager;
 typedef OptValue<50, RTNETADDRIPV4>     OptRequestedAddress;
 typedef OptValue<51, uint32_t>          OptLeaseTime;
@@ -634,8 +795,23 @@
 typedef OptList<60, uint8_t>            OptVendorClassId;
 typedef OptList<61, uint8_t>            OptClientId;
-typedef OptString<66>                   OptTFTPServer;   /* when overloaded */
-typedef OptString<67>                   OptBootFileName; /* when overloaded */
+typedef OptString<62>                   OptNetWareIPDomainName;     /**< RFC2242 */
+typedef OptList<63, uint8_t>            OptNetWareIPInformation;    /**< complicated, so just byte list for now. RFC2242 */
+typedef OptString<64>                   OptNISPlusDomain;
+typedef OptString<65>                   OptNISPlusServers;
+typedef OptString<66>                   OptTFTPServer;              /**< when overloaded */
+typedef OptString<67>                   OptBootFileName;            /**< when overloaded */
+typedef OptList<68, RTNETADDRIPV4>      OptMobileIPHomeAgents;
+typedef OptList<69, RTNETADDRIPV4>      OptSMTPServers;
+typedef OptList<70, RTNETADDRIPV4>      OptPOP3Servers;
+typedef OptList<71, RTNETADDRIPV4>      OptNNTPServers;
+typedef OptList<72, RTNETADDRIPV4>      OptWWWServers;
+typedef OptList<73, RTNETADDRIPV4>      OptFingerServers;
+typedef OptList<74, RTNETADDRIPV4>      OptIRCServers;
+typedef OptList<75, RTNETADDRIPV4>      OptStreetTalkServers;
+typedef OptList<76, RTNETADDRIPV4>      OptSTDAServers;
 typedef OptList<77, uint8_t>            OptUserClassId;
-typedef OptNoValue<80>                  OptRapidCommit;  /* RFC4039 */
+typedef OptList<78, uint8_t>            OptSLPDirectoryAgent;       /**< complicated, so just byte list for now. RFC2610 */
+typedef OptList<79, uint8_t>            OptSLPServiceScope;         /**< complicated, so just byte list for now. RFC2610 */
+typedef OptNoValue<80>                  OptRapidCommit;             /**< RFC4039 */
 /** @} */
 
Index: /trunk/src/VBox/NetworkServices/Dhcpd/DhcpdInternal.h
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/DhcpdInternal.h	(revision 79760)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/DhcpdInternal.h	(revision 79761)
@@ -22,5 +22,9 @@
 #endif
 
-#define LOG_GROUP LOG_GROUP_NET_DHCPD
+#ifndef IN_VBOXSVC
+# define LOG_GROUP LOG_GROUP_NET_DHCPD
+#elif !defined(LOG_GROUP)
+# define LOG_GROUP LOG_GROUP_MAIN_DHCPCONFIG
+#endif
 #include <iprt/stdint.h>
 #include <iprt/string.h>
Index: /trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp
===================================================================
--- /trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp	(revision 79760)
+++ /trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp	(revision 79761)
@@ -620,23 +620,5 @@
      * Parse the command line into a configuration object.
      */
-    /** @todo XXX: We no longer need hardcoded and compat methods. We should remove them soon. */
-    if (argc < 2)
-        m_Config = Config::hardcoded();
-    else if (   strcmp(argv[1], "--config") == 0
-             || strcmp(argv[1], "--comment") == 0)
-        m_Config = Config::create(argc, argv);
-    else
-    {
-        try
-        {
-            m_Config = Config::compat(argc, argv);
-        }
-        catch (std::bad_alloc &)
-        {
-            m_Config = NULL;
-            RTMsgError("Out of memory");
-            return VERR_NO_MEMORY;
-        }
-    }
+    m_Config = Config::create(argc, argv);
     if (m_Config == NULL)
         return VERR_GENERAL_FAILURE;
