summaryrefslogtreecommitdiff
path: root/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
diff options
context:
space:
mode:
authorFelix Geyer <debfx-pkg@fobos.de>2010-05-02 13:24:51 +0200
committerFelix Geyer <debfx-pkg@fobos.de>2010-05-02 13:24:51 +0200
commit4749e3a0c5d3a159d3ae751e6780b537c860923a (patch)
tree28cd86e0a63ddac4224277df9ce83ef056629917 /src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
parent0429962c55c464036f613d707f26b91f252584e7 (diff)
downloadvirtualbox-4749e3a0c5d3a159d3ae751e6780b537c860923a.tar.gz
Imported Upstream version 3.1.51-dfsgupstream/3.1.51-dfsg
Diffstat (limited to 'src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp')
-rw-r--r--src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
new file mode 100644
index 000000000..40d0d30c6
--- /dev/null
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
@@ -0,0 +1,344 @@
+/* $Id: VBoxNetBaseService.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
+/** @file
+ * VBoxNetDHCP - DHCP Service for connecting to IntNet.
+ */
+/** @todo r=bird: Cut&Past rules... Please fix DHCP refs! */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/** @page pg_net_dhcp VBoxNetDHCP
+ *
+ * Write a few words...
+ *
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_NET_SERVICE
+
+#include <iprt/alloca.h>
+#include <iprt/buildconfig.h>
+#include <iprt/err.h>
+#include <iprt/net.h> /* must come before getopt.h. */
+#include <iprt/getopt.h>
+#include <iprt/initterm.h>
+#include <iprt/param.h>
+#include <iprt/path.h>
+#include <iprt/stream.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+
+#include <VBox/sup.h>
+#include <VBox/intnet.h>
+#include <VBox/vmm.h>
+#include <VBox/version.h>
+
+#include <vector>
+#include <string>
+
+#include <VBox/log.h>
+
+#include "VBoxNetLib.h"
+#include "VBoxNetBaseService.h"
+#include "VBoxNetLib.h"
+#include "VBoxNetBaseService.h"
+
+#ifdef RT_OS_WINDOWS /* WinMain */
+# include <Windows.h>
+# include <stdlib.h>
+#endif
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+VBoxNetBaseService::VBoxNetBaseService()
+{
+ /* numbers from DrvIntNet */
+ m_cbSendBuf = 36 * _1K;
+ m_cbRecvBuf = 218 * _1K;
+ m_hIf = INTNET_HANDLE_INVALID;
+ m_pIfBuf = NULL;
+
+ m_cVerbosity = 0;
+ m_Name = "VBoxNetNAT";
+ m_Network = "intnet";
+}
+VBoxNetBaseService::~VBoxNetBaseService()
+{
+ /*
+ * 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_RTCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
+ AssertRC(rc);
+ }
+
+ if (m_pSession)
+ {
+ SUPR3Term(false /*fForced*/);
+ m_pSession = NIL_RTR0PTR;
+ }
+}
+/**
+ * Parse the arguments.
+ *
+ * @returns 0 on success, fully bitched exit code on failure.
+ *
+ * @param argc Argument count.
+ * @param argv Argument vector.
+ */
+int VBoxNetBaseService::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 },
+ { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
+ };
+
+ RTGETOPTSTATE State;
+ int rc = RTGetOptInit(&State, argc, argv, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0 /*fFlags*/);
+ AssertRCReturn(rc, 49);
+ Log2(("BaseService: parseArgs enter\n"));
+
+ 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 'v':
+ m_cVerbosity++;
+ 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);
+ usage(); /* to print Service Specific usage */
+ return 1;
+
+ default:
+ rc = RTGetOptPrintError(rc, &Val);
+ RTPrintf("Use --help for more information.\n");
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
+int VBoxNetBaseService::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;
+ LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc));
+ return 1;
+ }
+
+ char szPath[RTPATH_MAX];
+ rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
+ if (RT_FAILURE(rc))
+ {
+ LogRel(("VBoxNetBaseService: RTPathExecDir -> %Rrc\n", rc));
+ return 1;
+ }
+
+ rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0"));
+ if (RT_FAILURE(rc))
+ {
+ LogRel(("VBoxNetBaseService: SUPR3LoadVMM(\"%s\") -> %Rrc\n", szPath, rc));
+ return 1;
+ }
+
+ /*
+ * Create the open request.
+ */
+ PINTNETBUF pBuf;
+ 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.
+ */
+ Log2(("attempting to open/create network \"%s\"...\n", OpenReq.szNetwork));
+ rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
+ if (RT_FAILURE(rc))
+ {
+ Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc));
+ goto bad;
+ }
+ m_hIf = OpenReq.hIf;
+ Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m_hIf));
+
+ /*
+ * Get the ring-3 address of the shared interface buffer.
+ */
+ 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 = NULL;
+ rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, 0, &GetBufferPtrsReq.Hdr);
+ if (RT_FAILURE(rc))
+ {
+ Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,) failed, rc=%Rrc\n", rc));
+ goto bad;
+ }
+ pBuf = GetBufferPtrsReq.pRing3Buf;
+ Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
+ 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 */
+ Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc));
+
+ return 0;
+ bad:
+ return 1;
+}
+
+void VBoxNetBaseService::shutdown(void)
+{
+}
+
+/**
+ * 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 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.
+ */
+void VBoxNetBaseService::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
+{
+ if (iMinLevel <= m_cVerbosity)
+ {
+ va_list vaCopy; /* This dude is *very* special, thus the copy. */
+ va_copy(vaCopy, va);
+ RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
+ va_end(vaCopy);
+ }
+
+}
+