VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp@ 27901

Last change on this file since 27901 was 27901, checked in by vboxsync, 15 years ago

OSE header fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* $Id: VBoxNetBaseService.cpp 27901 2010-03-31 14:07:26Z vboxsync $ */
2/** @file
3 * VBoxNetDHCP - DHCP Service for connecting to IntNet.
4 */
5/** @todo r=bird: Cut&Past rules... Please fix DHCP refs! */
6
7/*
8 * Copyright (C) 2009 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23/** @page pg_net_dhcp VBoxNetDHCP
24 *
25 * Write a few words...
26 *
27 */
28
29/*******************************************************************************
30* Header Files *
31*******************************************************************************/
32#define LOG_GROUP LOG_GROUP_NET_SERVICE
33
34#include <iprt/alloca.h>
35#include <iprt/buildconfig.h>
36#include <iprt/err.h>
37#include <iprt/net.h> /* must come before getopt.h. */
38#include <iprt/getopt.h>
39#include <iprt/initterm.h>
40#include <iprt/param.h>
41#include <iprt/path.h>
42#include <iprt/stream.h>
43#include <iprt/string.h>
44#include <iprt/time.h>
45
46#include <VBox/sup.h>
47#include <VBox/intnet.h>
48#include <VBox/vmm.h>
49
50#include <vector>
51#include <string>
52
53#include <VBox/log.h>
54
55#include "VBoxNetLib.h"
56#include "VBoxNetBaseService.h"
57#include "VBoxNetLib.h"
58#include "VBoxNetBaseService.h"
59
60#ifdef RT_OS_WINDOWS /* WinMain */
61# include <Windows.h>
62# include <stdlib.h>
63#endif
64
65
66/*******************************************************************************
67* Structures and Typedefs *
68*******************************************************************************/
69VBoxNetBaseService::VBoxNetBaseService()
70{
71 /* numbers from DrvIntNet */
72 m_cbSendBuf = 36 * _1K;
73 m_cbRecvBuf = 218 * _1K;
74 m_hIf = INTNET_HANDLE_INVALID;
75 m_pIfBuf = NULL;
76
77 m_cVerbosity = 0;
78 m_Name = "VBoxNetNAT";
79 m_Network = "intnet";
80}
81VBoxNetBaseService::~VBoxNetBaseService()
82{
83 /*
84 * Close the interface connection.
85 */
86 if (m_hIf != INTNET_HANDLE_INVALID)
87 {
88 INTNETIFCLOSEREQ CloseReq;
89 CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
90 CloseReq.Hdr.cbReq = sizeof(CloseReq);
91 CloseReq.pSession = m_pSession;
92 CloseReq.hIf = m_hIf;
93 m_hIf = INTNET_HANDLE_INVALID;
94 int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_RTCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
95 AssertRC(rc);
96 }
97
98 if (m_pSession)
99 {
100 SUPR3Term(false /*fForced*/);
101 m_pSession = NIL_RTR0PTR;
102 }
103}
104/**
105 * Parse the arguments.
106 *
107 * @returns 0 on success, fully bitched exit code on failure.
108 *
109 * @param argc Argument count.
110 * @param argv Argument vector.
111 */
112int VBoxNetBaseService::parseArgs(int argc, char **argv)
113{
114 static const RTGETOPTDEF s_aOptionDefs[] =
115 {
116 { "--name", 'N', RTGETOPT_REQ_STRING },
117 { "--network", 'n', RTGETOPT_REQ_STRING },
118 { "--trunk-name", 't', RTGETOPT_REQ_STRING },
119 { "--trunk-type", 'T', RTGETOPT_REQ_STRING },
120 { "--mac-address", 'a', RTGETOPT_REQ_MACADDR },
121 { "--ip-address", 'i', RTGETOPT_REQ_IPV4ADDR },
122 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
123 };
124
125 RTGETOPTSTATE State;
126 int rc = RTGetOptInit(&State, argc, argv, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0 /*fFlags*/);
127 AssertRCReturn(rc, 49);
128 Log2(("BaseService: parseArgs enter\n"));
129
130 for (;;)
131 {
132 RTGETOPTUNION Val;
133 rc = RTGetOpt(&State, &Val);
134 if (!rc)
135 break;
136 switch (rc)
137 {
138 case 'N':
139 m_Name = Val.psz;
140 break;
141 case 'n':
142 m_Network = Val.psz;
143 break;
144 case 't':
145 m_TrunkName = Val.psz;
146 break;
147 case 'T':
148 if (!strcmp(Val.psz, "none"))
149 m_enmTrunkType = kIntNetTrunkType_None;
150 else if (!strcmp(Val.psz, "whatever"))
151 m_enmTrunkType = kIntNetTrunkType_WhateverNone;
152 else if (!strcmp(Val.psz, "netflt"))
153 m_enmTrunkType = kIntNetTrunkType_NetFlt;
154 else if (!strcmp(Val.psz, "netadp"))
155 m_enmTrunkType = kIntNetTrunkType_NetAdp;
156 else if (!strcmp(Val.psz, "srvnat"))
157 m_enmTrunkType = kIntNetTrunkType_SrvNat;
158 else
159 {
160 RTStrmPrintf(g_pStdErr, "Invalid trunk type '%s'\n", Val.psz);
161 return 1;
162 }
163 break;
164 case 'a':
165 m_MacAddress = Val.MacAddr;
166 break;
167 case 'i':
168 m_Ipv4Address = Val.IPv4Addr;
169 break;
170
171 case 'v':
172 m_cVerbosity++;
173 break;
174
175 case 'V':
176 RTPrintf("%sr%u\n", RTBldCfgVersion(), RTBldCfgRevision());
177 return 0;
178
179 case 'h':
180 RTPrintf("VBoxNetDHCP Version %s\n"
181 "(C) 2009 Sun Microsystems, Inc.\n"
182 "All rights reserved\n"
183 "\n"
184 "Usage: VBoxNetDHCP <options>\n"
185 "\n"
186 "Options:\n",
187 RTBldCfgVersion());
188 for (size_t i = 0; i < RT_ELEMENTS(s_aOptionDefs); i++)
189 RTPrintf(" -%c, %s\n", s_aOptionDefs[i].iShort, s_aOptionDefs[i].pszLong);
190 usage(); /* to print Service Specific usage */
191 return 1;
192
193 case VERR_GETOPT_UNKNOWN_OPTION:
194 case VINF_GETOPT_NOT_OPTION:
195 RTPrintf("Unknown option '%s'. Use --help for more information.\n", Val.psz);
196 return 1;
197
198 default:
199 break;
200 }
201 }
202
203 return rc;
204}
205
206int VBoxNetBaseService::tryGoOnline(void)
207{
208 /*
209 * Open the session, load ring-0 and issue the request.
210 */
211 int rc = SUPR3Init(&m_pSession);
212 if (RT_FAILURE(rc))
213 {
214 m_pSession = NIL_RTR0PTR;
215 LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc));
216 return 1;
217 }
218
219 char szPath[RTPATH_MAX];
220 rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
221 if (RT_FAILURE(rc))
222 {
223 LogRel(("VBoxNetBaseService: RTPathExecDir -> %Rrc\n", rc));
224 return 1;
225 }
226
227 rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0"));
228 if (RT_FAILURE(rc))
229 {
230 LogRel(("VBoxNetBaseService: SUPR3LoadVMM(\"%s\") -> %Rrc\n", szPath, rc));
231 return 1;
232 }
233
234 /*
235 * Create the open request.
236 */
237 PINTNETBUF pBuf;
238 INTNETOPENREQ OpenReq;
239 OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
240 OpenReq.Hdr.cbReq = sizeof(OpenReq);
241 OpenReq.pSession = m_pSession;
242 strncpy(OpenReq.szNetwork, m_Network.c_str(), sizeof(OpenReq.szNetwork));
243 OpenReq.szNetwork[sizeof(OpenReq.szNetwork) - 1] = '\0';
244 strncpy(OpenReq.szTrunk, m_TrunkName.c_str(), sizeof(OpenReq.szTrunk));
245 OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0';
246 OpenReq.enmTrunkType = m_enmTrunkType;
247 OpenReq.fFlags = 0; /** @todo check this */
248 OpenReq.cbSend = m_cbSendBuf;
249 OpenReq.cbRecv = m_cbRecvBuf;
250 OpenReq.hIf = INTNET_HANDLE_INVALID;
251
252 /*
253 * Issue the request.
254 */
255 Log2(("attempting to open/create network \"%s\"...\n", OpenReq.szNetwork));
256 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
257 if (RT_FAILURE(rc))
258 {
259 Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc));
260 goto bad;
261 }
262 m_hIf = OpenReq.hIf;
263 Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m_hIf));
264
265 /*
266 * Get the ring-3 address of the shared interface buffer.
267 */
268 INTNETIFGETRING3BUFFERREQ GetRing3BufferReq;
269 GetRing3BufferReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
270 GetRing3BufferReq.Hdr.cbReq = sizeof(GetRing3BufferReq);
271 GetRing3BufferReq.pSession = m_pSession;
272 GetRing3BufferReq.hIf = m_hIf;
273 GetRing3BufferReq.pRing3Buf = NULL;
274 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_GET_RING3_BUFFER, 0, &GetRing3BufferReq.Hdr);
275 if (RT_FAILURE(rc))
276 {
277 Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_RING3_BUFFER,) failed, rc=%Rrc\n", rc));
278 goto bad;
279 }
280 pBuf = GetRing3BufferReq.pRing3Buf;
281 Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
282 pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv));
283 m_pIfBuf = pBuf;
284
285 /*
286 * Activate the interface.
287 */
288 INTNETIFSETACTIVEREQ ActiveReq;
289 ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
290 ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
291 ActiveReq.pSession = m_pSession;
292 ActiveReq.hIf = m_hIf;
293 ActiveReq.fActive = true;
294 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
295 if (RT_SUCCESS(rc))
296 return 0;
297
298 /* bail out */
299 Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc));
300
301 return 0;
302 bad:
303 return 1;
304}
305
306void VBoxNetBaseService::shutdown(void)
307{
308}
309
310/**
311 * Print debug message depending on the m_cVerbosity level.
312 *
313 * @param iMinLevel The minimum m_cVerbosity level for this message.
314 * @param fMsg Whether to dump parts for the current DHCP message.
315 * @param pszFmt The message format string.
316 * @param ... Optional arguments.
317 */
318inline void VBoxNetBaseService::debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
319{
320 if (iMinLevel <= m_cVerbosity)
321 {
322 va_list va;
323 va_start(va, pszFmt);
324 debugPrintV(iMinLevel, fMsg, pszFmt, va);
325 va_end(va);
326 }
327}
328
329
330/**
331 * Print debug message depending on the m_cVerbosity level.
332 *
333 * @param iMinLevel The minimum m_cVerbosity level for this message.
334 * @param fMsg Whether to dump parts for the current DHCP message.
335 * @param pszFmt The message format string.
336 * @param va Optional arguments.
337 */
338void VBoxNetBaseService::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
339{
340 if (iMinLevel <= m_cVerbosity)
341 {
342 va_list vaCopy; /* This dude is *very* special, thus the copy. */
343 va_copy(vaCopy, va);
344 RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: %s: %N\n", iMinLevel >= 2 ? "debug" : "info", pszFmt, &vaCopy);
345 va_end(vaCopy);
346 }
347
348}
349
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette