NATNetworkServiceRunner.cpp revision 20fc4a350a4a8e56ffaac6cf57dcd677a7ac36c5
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau/* $Id$ */
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau/** @file
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * VirtualBox Main - interface for VBox NAT Network service
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau */
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau/*
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * Copyright (C) 2009-2012 Oracle Corporation
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau *
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * This file is part of VirtualBox Open Source Edition (OSE), as
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * available from http://www.virtualbox.org. This file is free software;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * you can redistribute it and/or modify it under the terms of the GNU
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * General Public License (GPL) as published by the Free Software
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * Foundation, in version 2 as it comes in the "COPYING" file of the
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau */
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau#include "NATNetworkServiceRunner.h"
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau#include <iprt/process.h>
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau#include <iprt/param.h>
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau#include <iprt/env.h>
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineaustruct ARGDEF
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering{
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau NATSCCFG Type;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering const char * Name;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau};
f4f15635ec05293ffcc83a5b39f624bbabbd8fd0Lennart Poettering
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau#ifdef RT_OS_WINDOWS
ee735086f8670be1591fa9593e80dd60163a7a2fLennart Poettering# define NATSR_EXECUTABLE_NAME "VBoxNetNAT.exe"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#else
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering# define NATSR_EXECUTABLE_NAME "VBoxNetNAT"
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau#endif
ee104e11e303499a637c5cd8157bd12ad5cc116dLennart Poettering
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineaustatic const ARGDEF g_aArgDefs[] =
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau{
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_NAME, "-n"},
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_TRUNKTYPE, "--trunk-type"},
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_MACADDRESS, "--mac-address"},
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_IPADDRESS, "--ip-address"},
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_NETMASK, "--netmask"},
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_PORTFORWARD4, "--pf4"},
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {NATSCCFG_PORTFORWARD6, "--pf6"}
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
ee735086f8670be1591fa9593e80dd60163a7a2fLennart Poettering};
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineaustatic const ARGDEF * getArgDef(NATSCCFG type)
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau{
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau for (unsigned i = 0; i < RT_ELEMENTS(g_aArgDefs); i++)
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau if (g_aArgDefs[i].Type == type)
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau return &g_aArgDefs[i];
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau return NULL;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau}
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael MarineauNATNetworkServiceRunner::NATNetworkServiceRunner()
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau{
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau mProcess = NIL_RTPROCESS;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau for (unsigned i = 0; i < NATSCCFG_NOTOPT_MAXVAL; i++)
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau mOptionEnabled[i] = false;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau }
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau}
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineauvoid NATNetworkServiceRunner::detachFromServer()
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau{
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau mProcess = NIL_RTPROCESS;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering}
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineauint NATNetworkServiceRunner::start()
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau{
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering if (isRunning())
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering return VINF_ALREADY_INITIALIZED;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau const char * args[NATSCCFG_NOTOPT_MAXVAL * 2];
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau /* get the path to the executable */
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau char exePathBuf[RTPATH_MAX];
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX);
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau char *substrSl = strrchr(exePathBuf, '/');
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau char *substrBs = strrchr(exePathBuf, '\\');
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau char *suffix = substrSl ? substrSl : substrBs;
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau if (suffix)
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau {
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau suffix++;
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau strcpy(suffix, NATSR_EXECUTABLE_NAME);
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau }
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau else
09e00c524fd4d21a3508c27d01d265b8a6c9ae30Michael Marineau exePath = NATSR_EXECUTABLE_NAME;
int index = 0;
args[index++] = exePath;
for (unsigned i = 0; i < NATSCCFG_NOTOPT_MAXVAL; i++)
{
if (mOptionEnabled[i])
{
const ARGDEF *pArgDef = getArgDef((NATSCCFG)i);
if (!pArgDef)
continue;
args[index++] = pArgDef->Name; // e.g. "--network"
/* value can be null for e.g. --begin-config has no value
* and thus check the mOptions string length here
*/
if (mOptions[i].length())
args[index++] = mOptions[i].c_str(); // value
}
}
args[index++] = NULL;
RTENV env;
int rc = RTEnvCreate(&env);
AssertRCReturn(rc,rc);
RTEnvPutEx(env, "VBOX_LOG=e.l.f");
rc = RTProcCreate(exePath, args, RTENV_DEFAULT, 0, &mProcess);
if (RT_FAILURE(rc))
mProcess = NIL_RTPROCESS;
RTEnvDestroy(env);
return rc;
}
int NATNetworkServiceRunner::stop()
{
if (!isRunning())
return VINF_OBJECT_DESTROYED;
int rc = RTProcTerminate(mProcess);
mProcess = NIL_RTPROCESS;
return rc;
}
bool NATNetworkServiceRunner::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;
}