DHCPServerRunner.cpp revision e48239695d41f806ff02d8a60b97dc20d4822d7a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* $Id$ */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox Main - interface for VBox DHCP server
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2009 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "DHCPServerRunner.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <iprt/process.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <iprt/param.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <iprt/env.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstruct ARGDEF
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DHCPCFG Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync const char * Name;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#ifdef RT_OS_WINDOWS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# define DHCP_EXECUTABLE_NAME "VBoxNetDHCP.exe"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# define DHCP_EXECUTABLE_NAME "VBoxNetDHCP"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic const ARGDEF g_aArgDefs[] =
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_NAME, "--name"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_NETNAME, "--network"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_TRUNKTYPE, "--trunk-type"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_TRUNKNAME, "--trunk-name"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_MACADDRESS, "--mac-address"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_IPADDRESS, "--ip-address"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_LEASEDB, "--lease-db"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_VERBOSE, "--verbose"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_BEGINCONFIG, "--begin-config"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_GATEWAY, "--gateway"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_LOWERIP, "--lower-ip"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_UPPERIP, "--upper-ip"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_NETMASK, "--netmask"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_HELP, "--help"},
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {DHCPCFG_VERSION, "--version"}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic const ARGDEF * getArgDef(DHCPCFG type)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (unsigned i = 0; i < RT_ELEMENTS(g_aArgDefs); i++)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (g_aArgDefs[i].Type == type)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return &g_aArgDefs[i];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncDHCPServerRunner::DHCPServerRunner()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mProcess = NIL_RTPROCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (unsigned i = 0; i < DHCPCFG_NOTOPT_MAXVAL; i++)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mOptionEnabled[i] = false;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncvoid DHCPServerRunner::detachFromServer()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mProcess = NIL_RTPROCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint DHCPServerRunner::start()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (isRunning())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return VINF_ALREADY_INITIALIZED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync const char * args[DHCPCFG_NOTOPT_MAXVAL * 2];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* get the path to the executable */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char exePathBuf[RTPATH_MAX];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync const char *exePath = RTProcGetExecutableName(exePathBuf, RTPATH_MAX);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *substrSl = strrchr(exePathBuf, '/');
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *substrBs = strrchr(exePathBuf, '\\');
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync char *suffix = substrSl ? substrSl : substrBs;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (suffix)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync suffix++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync strcpy(suffix, DHCP_EXECUTABLE_NAME);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync exePath = DHCP_EXECUTABLE_NAME;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int index = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync args[index++] = exePath;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (unsigned i = 0; i < DHCPCFG_NOTOPT_MAXVAL; i++)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mOptionEnabled[i])
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync const ARGDEF * pArgDef = getArgDef((DHCPCFG)i);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync args[index++] = pArgDef->Name; // e.g. "--network"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /* value can be null for e.g. --begin-config has no value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * and thus check the mOptions string length here
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mOptions[i].length())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync args[index++] = mOptions[i].c_str(); // value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync args[index++] = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int rc = RTProcCreate(exePath, args, RTENV_DEFAULT, 0, &mProcess);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (RT_FAILURE(rc))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mProcess = NIL_RTPROCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return rc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncint DHCPServerRunner::stop()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!isRunning())
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return VINF_OBJECT_DESTROYED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int rc = RTProcTerminate(mProcess);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mProcess = NIL_RTPROCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return rc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncbool DHCPServerRunner::isRunning()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mProcess == NIL_RTPROCESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return false;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RTPROCSTATUS status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync int rc = RTProcWait(mProcess, RTPROCWAIT_FLAGS_NOBLOCK, &status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (rc == VERR_PROCESS_RUNNING)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return true;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mProcess = NIL_RTPROCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return false;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync