VirtualBox

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

Last change on this file since 49819 was 49735, checked in by vboxsync, 11 years ago

VBoxNetBaseService hides all details of internal network implementation and become responsible for supporting receiving loop. Notification of children are done via introduced interface:

virtual int processFrame(void *, size_t) = 0;
virtual int processGSO(PCPDMNETWORKGSO, size_t) = 0;
virtual int processUDP(void *, size_t) = 0;

processFrame() and processGSO() might return VERR_IGNORED, to inform base service switch to processUDP() (e.g. for DHCP needs)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.7 KB
Line 
1/* $Id: VBoxNetBaseService.cpp 49735 2013-11-30 02:08:42Z 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-2011 Oracle Corporation
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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_NET_SERVICE
23
24#include <VBox/com/com.h>
25#include <VBox/com/listeners.h>
26#include <VBox/com/string.h>
27#include <VBox/com/Guid.h>
28#include <VBox/com/array.h>
29#include <VBox/com/ErrorInfo.h>
30#include <VBox/com/errorprint.h>
31#include <VBox/com/EventQueue.h>
32#include <VBox/com/VirtualBox.h>
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/process.h>
43#include <iprt/stream.h>
44#include <iprt/string.h>
45#include <iprt/time.h>
46#include <iprt/mem.h>
47#include <iprt/message.h>
48
49#include <VBox/sup.h>
50#include <VBox/intnet.h>
51#include <VBox/intnetinline.h>
52#include <VBox/vmm/vmm.h>
53#include <VBox/version.h>
54
55#include <vector>
56#include <string>
57
58#include <VBox/err.h>
59#include <VBox/log.h>
60
61#include "VBoxNetLib.h"
62#include "VBoxNetBaseService.h"
63
64#ifdef RT_OS_WINDOWS /* WinMain */
65# include <Windows.h>
66# include <stdlib.h>
67#endif
68
69
70/*******************************************************************************
71* Structures and Typedefs *
72*******************************************************************************/
73struct VBoxNetBaseService::Data
74{
75 Data(const std::string& aName, const std::string& aNetworkName):
76 m_Name(aName),
77 m_Network(aNetworkName),
78 m_enmTrunkType(kIntNetTrunkType_WhateverNone),
79 m_pSession(NIL_RTR0PTR),
80 m_cbSendBuf(128 * _1K),
81 m_cbRecvBuf(256 * _1K),
82 m_hIf(INTNET_HANDLE_INVALID),
83 m_pIfBuf(NULL),
84 m_cVerbosity(0),
85 m_fNeedMain(false)
86 {
87 int rc = RTCritSectInit(&m_csThis);
88 AssertRC(rc);
89 };
90
91 std::string m_Name;
92 std::string m_Network;
93 std::string m_TrunkName;
94 INTNETTRUNKTYPE m_enmTrunkType;
95
96 RTMAC m_MacAddress;
97 RTNETADDRIPV4 m_Ipv4Address;
98 RTNETADDRIPV4 m_Ipv4Netmask;
99
100 PSUPDRVSESSION m_pSession;
101 uint32_t m_cbSendBuf;
102 uint32_t m_cbRecvBuf;
103 INTNETIFHANDLE m_hIf; /**< The handle to the network interface. */
104 PINTNETBUF m_pIfBuf; /**< Interface buffer. */
105
106 std::vector<PRTGETOPTDEF> m_vecOptionDefs;
107
108 int32_t m_cVerbosity;
109
110 /* cs for syncing */
111 RTCRITSECT m_csThis;
112
113 /* Controls whether service will connect SVC for runtime needs */
114 bool m_fNeedMain;
115};
116
117/*******************************************************************************
118* Global Variables *
119*******************************************************************************/
120/* Commonly used options for network configuration */
121static RTGETOPTDEF g_aGetOptDef[] =
122{
123 { "--name", 'N', RTGETOPT_REQ_STRING },
124 { "--network", 'n', RTGETOPT_REQ_STRING },
125 { "--trunk-name", 't', RTGETOPT_REQ_STRING },
126 { "--trunk-type", 'T', RTGETOPT_REQ_STRING },
127 { "--mac-address", 'a', RTGETOPT_REQ_MACADDR },
128 { "--ip-address", 'i', RTGETOPT_REQ_IPV4ADDR },
129 { "--netmask", 'm', RTGETOPT_REQ_IPV4ADDR },
130 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
131 { "--need-main", 'M', RTGETOPT_REQ_BOOL },
132};
133
134
135VBoxNetBaseService::VBoxNetBaseService(const std::string& aName, const std::string& aNetworkName):m(NULL)
136{
137 m = new VBoxNetBaseService::Data(aName, aNetworkName);
138
139 for(unsigned int i = 0; i < RT_ELEMENTS(g_aGetOptDef); ++i)
140 m->m_vecOptionDefs.push_back(&g_aGetOptDef[i]);
141}
142
143
144VBoxNetBaseService::~VBoxNetBaseService()
145{
146 /*
147 * Close the interface connection.
148 */
149 if (m != NULL)
150 {
151 if (m->m_hIf != INTNET_HANDLE_INVALID)
152 {
153 INTNETIFCLOSEREQ CloseReq;
154 CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
155 CloseReq.Hdr.cbReq = sizeof(CloseReq);
156 CloseReq.pSession = m->m_pSession;
157 CloseReq.hIf = m->m_hIf;
158 m->m_hIf = INTNET_HANDLE_INVALID;
159 int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_RTCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
160 AssertRC(rc);
161 }
162
163 if (m->m_pSession != NIL_RTR0PTR)
164 {
165 SUPR3Term(false /*fForced*/);
166 m->m_pSession = NIL_RTR0PTR;
167 }
168
169 RTCritSectDelete(&m->m_csThis);
170
171 delete m;
172 m = NULL;
173 }
174}
175
176
177int VBoxNetBaseService::init()
178{
179 if (isMainNeeded())
180 {
181 HRESULT hrc = com::Initialize();
182 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
183
184 hrc = virtualbox.createLocalObject(CLSID_VirtualBox);
185 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
186 }
187
188 return VINF_SUCCESS;
189}
190
191
192bool VBoxNetBaseService::isMainNeeded() const
193{
194 return m->m_fNeedMain;
195}
196
197/**
198 * Parse the arguments.
199 *
200 * @returns 0 on success, fully bitched exit code on failure.
201 *
202 * @param argc Argument count.
203 * @param argv Argument vector.
204 */
205int VBoxNetBaseService::parseArgs(int argc, char **argv)
206{
207
208 RTGETOPTSTATE State;
209 PRTGETOPTDEF paOptionArray = getOptionsPtr();
210 int rc = RTGetOptInit(&State, argc, argv, paOptionArray, m->m_vecOptionDefs.size(), 0, 0 /*fFlags*/);
211 AssertRCReturn(rc, 49);
212#if 0
213 /* default initialization */
214 m_enmTrunkType = kIntNetTrunkType_WhateverNone;
215#endif
216 Log2(("BaseService: parseArgs enter\n"));
217
218 for (;;)
219 {
220 RTGETOPTUNION Val;
221 rc = RTGetOpt(&State, &Val);
222 if (!rc)
223 break;
224 switch (rc)
225 {
226 case 'N': // --name
227 m->m_Name = Val.psz;
228 break;
229
230 case 'n': // --network
231 m->m_Network = Val.psz;
232 break;
233
234 case 't': //--trunk-name
235 m->m_TrunkName = Val.psz;
236 break;
237
238 case 'T': //--trunk-type
239 if (!strcmp(Val.psz, "none"))
240 m->m_enmTrunkType = kIntNetTrunkType_None;
241 else if (!strcmp(Val.psz, "whatever"))
242 m->m_enmTrunkType = kIntNetTrunkType_WhateverNone;
243 else if (!strcmp(Val.psz, "netflt"))
244 m->m_enmTrunkType = kIntNetTrunkType_NetFlt;
245 else if (!strcmp(Val.psz, "netadp"))
246 m->m_enmTrunkType = kIntNetTrunkType_NetAdp;
247 else if (!strcmp(Val.psz, "srvnat"))
248 m->m_enmTrunkType = kIntNetTrunkType_SrvNat;
249 else
250 {
251 RTStrmPrintf(g_pStdErr, "Invalid trunk type '%s'\n", Val.psz);
252 return 1;
253 }
254 break;
255
256 case 'a': // --mac-address
257 m->m_MacAddress = Val.MacAddr;
258 break;
259
260 case 'i': // --ip-address
261 m->m_Ipv4Address = Val.IPv4Addr;
262 break;
263
264 case 'm': // --netmask
265 m->m_Ipv4Netmask = Val.IPv4Addr;
266 break;
267
268 case 'v': // --verbose
269 m->m_cVerbosity++;
270 break;
271
272 case 'V': // --version (missed)
273 RTPrintf("%sr%u\n", RTBldCfgVersion(), RTBldCfgRevision());
274 return 1;
275
276 case 'M': // --need-main
277 m->m_fNeedMain = true;
278 break;
279
280 case 'h': // --help (missed)
281 RTPrintf("%s Version %sr%u\n"
282 "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
283 "All rights reserved.\n"
284 "\n"
285 "Usage: %s <options>\n"
286 "\n"
287 "Options:\n",
288 RTProcShortName(),
289 RTBldCfgVersion(),
290 RTBldCfgRevision(),
291 RTProcShortName());
292 for (unsigned int i = 0; i < m->m_vecOptionDefs.size(); i++)
293 RTPrintf(" -%c, %s\n", m->m_vecOptionDefs[i]->iShort, m->m_vecOptionDefs[i]->pszLong);
294 usage(); /* to print Service Specific usage */
295 return 1;
296
297 default:
298 int rc1 = parseOpt(rc, Val);
299 if (RT_FAILURE(rc1))
300 {
301 rc = RTGetOptPrintError(rc, &Val);
302 RTPrintf("Use --help for more information.\n");
303 return rc;
304 }
305 }
306 }
307
308 RTMemFree(paOptionArray);
309 return rc;
310}
311
312
313int VBoxNetBaseService::tryGoOnline(void)
314{
315 /*
316 * Open the session, load ring-0 and issue the request.
317 */
318 int rc = SUPR3Init(&m->m_pSession);
319 if (RT_FAILURE(rc))
320 {
321 m->m_pSession = NIL_RTR0PTR;
322 LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc));
323 return rc;
324 }
325
326 char szPath[RTPATH_MAX];
327 rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
328 if (RT_FAILURE(rc))
329 {
330 LogRel(("VBoxNetBaseService: RTPathExecDir -> %Rrc\n", rc));
331 return rc;
332 }
333
334 rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0"));
335 if (RT_FAILURE(rc))
336 {
337 LogRel(("VBoxNetBaseService: SUPR3LoadVMM(\"%s\") -> %Rrc\n", szPath, rc));
338 return rc;
339 }
340
341 /*
342 * Create the open request.
343 */
344 PINTNETBUF pBuf;
345 INTNETOPENREQ OpenReq;
346 OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
347 OpenReq.Hdr.cbReq = sizeof(OpenReq);
348 OpenReq.pSession = m->m_pSession;
349 strncpy(OpenReq.szNetwork, m->m_Network.c_str(), sizeof(OpenReq.szNetwork));
350 OpenReq.szNetwork[sizeof(OpenReq.szNetwork) - 1] = '\0';
351 strncpy(OpenReq.szTrunk, m->m_TrunkName.c_str(), sizeof(OpenReq.szTrunk));
352 OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0';
353 OpenReq.enmTrunkType = m->m_enmTrunkType;
354 OpenReq.fFlags = 0; /** @todo check this */
355 OpenReq.cbSend = m->m_cbSendBuf;
356 OpenReq.cbRecv = m->m_cbRecvBuf;
357 OpenReq.hIf = INTNET_HANDLE_INVALID;
358
359 /*
360 * Issue the request.
361 */
362 Log2(("attempting to open/create network \"%s\"...\n", OpenReq.szNetwork));
363 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
364 if (RT_FAILURE(rc))
365 {
366 Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc));
367 return rc;
368 }
369 m->m_hIf = OpenReq.hIf;
370 Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m->m_hIf));
371
372 /*
373 * Get the ring-3 address of the shared interface buffer.
374 */
375 INTNETIFGETBUFFERPTRSREQ GetBufferPtrsReq;
376 GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
377 GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq);
378 GetBufferPtrsReq.pSession = m->m_pSession;
379 GetBufferPtrsReq.hIf = m->m_hIf;
380 GetBufferPtrsReq.pRing3Buf = NULL;
381 GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR;
382 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, 0, &GetBufferPtrsReq.Hdr);
383 if (RT_FAILURE(rc))
384 {
385 Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,) failed, rc=%Rrc\n", rc));
386 return rc;
387 }
388 pBuf = GetBufferPtrsReq.pRing3Buf;
389 Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
390 pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv));
391 m->m_pIfBuf = pBuf;
392
393 /*
394 * Activate the interface.
395 */
396 INTNETIFSETACTIVEREQ ActiveReq;
397 ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
398 ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
399 ActiveReq.pSession = m->m_pSession;
400 ActiveReq.hIf = m->m_hIf;
401 ActiveReq.fActive = true;
402 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
403 if (RT_SUCCESS(rc))
404 return 0;
405
406 /* bail out */
407 Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc));
408
409 /* ignore this error */
410 return VINF_SUCCESS;
411}
412
413
414void VBoxNetBaseService::shutdown(void)
415{
416}
417
418
419int VBoxNetBaseService::syncEnter()
420{
421 return RTCritSectEnter(&m->m_csThis);
422}
423
424
425int VBoxNetBaseService::syncLeave()
426{
427 return RTCritSectLeave(&m->m_csThis);
428}
429
430
431int VBoxNetBaseService::waitForIntNetEvent(int cMillis)
432{
433 int rc = VINF_SUCCESS;
434 INTNETIFWAITREQ WaitReq;
435 LogFlowFunc(("ENTER:cMillis: %d\n", cMillis));
436 WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
437 WaitReq.Hdr.cbReq = sizeof(WaitReq);
438 WaitReq.pSession = m->m_pSession;
439 WaitReq.hIf = m->m_hIf;
440 WaitReq.cMillies = cMillis;
441
442 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
443 LogFlowFuncLeaveRC(rc);
444 return rc;
445}
446
447/* S/G API */
448int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG pcSg, int cSg, size_t cbFrame)
449{
450 PINTNETHDR pHdr = NULL;
451 uint8_t *pu8Frame = NULL;
452
453 /* Allocate frame */
454 int rc = IntNetRingAllocateFrame(&m->m_pIfBuf->Send, cbFrame, &pHdr, (void **)&pu8Frame);
455 AssertRCReturn(rc, rc);
456
457 /* Now we fill pvFrame with S/G above */
458 int offFrame = 0;
459 for (int idxSg = 0; idxSg < cSg; ++idxSg)
460 {
461 memcpy(&pu8Frame[offFrame], pcSg[idxSg].pv, pcSg[idxSg].cb);
462 offFrame+=pcSg[idxSg].cb;
463 }
464
465 /* Commit */
466 IntNetRingCommitFrameEx(&m->m_pIfBuf->Send, pHdr, cbFrame);
467
468 LogFlowFuncLeaveRC(rc);
469 return rc;
470}
471
472/**
473 * forcible ask for send packet on the "wire"
474 */
475void VBoxNetBaseService::flushWire()
476{
477 int rc = VINF_SUCCESS;
478 INTNETIFSENDREQ SendReq;
479 SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
480 SendReq.Hdr.cbReq = sizeof(SendReq);
481 SendReq.pSession = m->m_pSession;
482 SendReq.hIf = m->m_hIf;
483 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
484 AssertRCReturnVoid(rc);
485 LogFlowFuncLeave();
486
487}
488
489
490int VBoxNetBaseService::hlpUDPBroadcast(unsigned uSrcPort, unsigned uDstPort,
491 void const *pvData, size_t cbData) const
492{
493 return VBoxNetUDPBroadcast(m->m_pSession, m->m_hIf, m->m_pIfBuf,
494 m->m_Ipv4Address, &m->m_MacAddress, uSrcPort,
495 uDstPort, pvData, cbData);
496
497}
498
499
500const std::string VBoxNetBaseService::getName() const
501{
502 return m->m_Name;
503}
504
505
506void VBoxNetBaseService::setName(const std::string& aName)
507{
508 m->m_Name = aName;
509}
510
511
512const std::string VBoxNetBaseService::getNetwork() const
513{
514 return m->m_Network;
515}
516
517
518void VBoxNetBaseService::setNetwork(const std::string& aNetwork)
519{
520 m->m_Network = aNetwork;
521}
522
523
524const RTMAC VBoxNetBaseService::getMacAddress() const
525{
526 return m->m_MacAddress;
527}
528
529
530void VBoxNetBaseService::setMacAddress(const RTMAC& aMac)
531{
532 m->m_MacAddress = aMac;
533}
534
535
536const RTNETADDRIPV4 VBoxNetBaseService::getIpv4Address() const
537{
538 return m->m_Ipv4Address;
539}
540
541
542void VBoxNetBaseService::setIpv4Address(const RTNETADDRIPV4& aAddress)
543{
544 m->m_Ipv4Address = aAddress;
545}
546
547
548const RTNETADDRIPV4 VBoxNetBaseService::getIpv4Netmask() const
549{
550 return m->m_Ipv4Netmask;
551}
552
553
554void VBoxNetBaseService::setIpv4Netmask(const RTNETADDRIPV4& aNetmask)
555{
556 m->m_Ipv4Netmask = aNetmask;
557}
558
559
560uint32_t VBoxNetBaseService::getSendBufSize() const
561{
562 return m->m_cbSendBuf;
563}
564
565
566void VBoxNetBaseService::setSendBufSize(uint32_t cbBuf)
567{
568 m->m_cbSendBuf = cbBuf;
569}
570
571
572uint32_t VBoxNetBaseService::getRecvBufSize() const
573{
574 return m->m_cbRecvBuf;
575}
576
577
578void VBoxNetBaseService::setRecvBufSize(uint32_t cbBuf)
579{
580 m->m_cbRecvBuf = cbBuf;
581}
582
583
584int32_t VBoxNetBaseService::getVerbosityLevel() const
585{
586 return m->m_cVerbosity;
587}
588
589
590void VBoxNetBaseService::setVerbosityLevel(int32_t aVerbosity)
591{
592 m->m_cVerbosity = aVerbosity;
593}
594
595
596void VBoxNetBaseService::addCommandLineOption(const PRTGETOPTDEF optDef)
597{
598 m->m_vecOptionDefs.push_back(optDef);
599}
600
601
602void VBoxNetBaseService::doReceiveLoop()
603{
604 int rc;
605 /* Well we're ready */
606 PINTNETRINGBUF pRingBuf = &m->m_pIfBuf->Recv;
607
608 for (;;)
609 {
610 /*
611 * Wait for a packet to become available.
612 */
613 /* 2. waiting for request for */
614 rc = waitForIntNetEvent(2000);
615 if (RT_FAILURE(rc))
616 {
617 if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
618 {
619 /* do we want interrupt anyone ??? */
620 continue;
621 }
622 LogRel(("VBoxNetNAT: waitForIntNetEvent returned %Rrc\n", rc));
623 AssertRCReturnVoid(rc);
624 }
625
626 /*
627 * Process the receive buffer.
628 */
629 PCINTNETHDR pHdr;
630
631 while ((pHdr = IntNetRingGetNextFrameToRead(pRingBuf)) != NULL)
632 {
633 uint8_t const u8Type = pHdr->u8Type;
634 size_t cbFrame = pHdr->cbFrame;
635 switch (u8Type)
636 {
637
638 case INTNETHDR_TYPE_FRAME:
639 {
640 void *pvFrame = IntNetHdrGetFramePtr(pHdr, m->m_pIfBuf);
641 rc = processFrame(pvFrame, cbFrame);
642 if (RT_FAILURE(rc) && rc == VERR_IGNORED)
643 {
644 /* XXX: UDP + ARP for DHCP */
645 VBOXNETUDPHDRS Hdrs;
646 size_t cb;
647 void *pv = VBoxNetUDPMatch(m->m_pIfBuf, RTNETIPV4_PORT_BOOTPS, &m->m_MacAddress,
648 VBOXNETUDP_MATCH_UNICAST | VBOXNETUDP_MATCH_BROADCAST
649 | VBOXNETUDP_MATCH_CHECKSUM
650 | (m->m_cVerbosity > 2 ? VBOXNETUDP_MATCH_PRINT_STDERR : 0),
651 &Hdrs, &cb);
652 if (pv && cb)
653 processUDP(pv, cb);
654 else
655 VBoxNetArpHandleIt(m->m_pSession, m->m_hIf, m->m_pIfBuf, &m->m_MacAddress, m->m_Ipv4Address);
656 }
657 }
658 break;
659 case INTNETHDR_TYPE_GSO:
660 {
661 PCPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr, m->m_pIfBuf);
662 rc = processGSO(pGso, cbFrame);
663 if (RT_FAILURE(rc) && rc == VERR_IGNORED)
664 break;
665 }
666 break;
667 case INTNETHDR_TYPE_PADDING:
668 break;
669 default:
670 break;
671 }
672 IntNetRingSkipFrame(&m->m_pIfBuf->Recv);
673
674 } /* loop */
675 }
676
677}
678
679
680void VBoxNetBaseService::debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
681{
682 if (iMinLevel <= m->m_cVerbosity)
683 {
684 va_list va;
685 va_start(va, pszFmt);
686 debugPrintV(iMinLevel, fMsg, pszFmt, va);
687 va_end(va);
688 }
689}
690
691
692/**
693 * Print debug message depending on the m_cVerbosity level.
694 *
695 * @param iMinLevel The minimum m_cVerbosity level for this message.
696 * @param fMsg Whether to dump parts for the current service message.
697 * @param pszFmt The message format string.
698 * @param va Optional arguments.
699 */
700void VBoxNetBaseService::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
701{
702 if (iMinLevel <= m->m_cVerbosity)
703 {
704 va_list vaCopy; /* This dude is *very* special, thus the copy. */
705 va_copy(vaCopy, va);
706 RTStrmPrintf(g_pStdErr, "%s: %s: %N\n",
707 RTProcShortName(),
708 iMinLevel >= 2 ? "debug" : "info",
709 pszFmt,
710 &vaCopy);
711 va_end(vaCopy);
712 }
713
714}
715
716
717PRTGETOPTDEF VBoxNetBaseService::getOptionsPtr()
718{
719 PRTGETOPTDEF pOptArray = NULL;
720 pOptArray = (PRTGETOPTDEF)RTMemAlloc(sizeof(RTGETOPTDEF) * m->m_vecOptionDefs.size());
721 if (!pOptArray)
722 return NULL;
723 for (unsigned int i = 0; i < m->m_vecOptionDefs.size(); ++i)
724 {
725 PRTGETOPTDEF pOpt = m->m_vecOptionDefs[i];
726 memcpy(&pOptArray[i], m->m_vecOptionDefs[i], sizeof(RTGETOPTDEF));
727 }
728 return pOptArray;
729}
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