VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
RevLine 
[25966]1/* $Id: DrvNetSniffer.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
[1]2/** @file
[25966]3 * DrvNetSniffer - Network sniffer filter driver.
[1]4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[1]26 */
27
28
[57358]29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
[1]32#define LOG_GROUP LOG_GROUP_DRV_NAT
[35346]33#include <VBox/vmm/pdmdrv.h>
34#include <VBox/vmm/pdmnetifs.h>
[1]35
36#include <VBox/log.h>
37#include <iprt/assert.h>
[25966]38#include <iprt/critsect.h>
[1]39#include <iprt/file.h>
40#include <iprt/process.h>
41#include <iprt/string.h>
42#include <iprt/time.h>
[25966]43#include <iprt/uuid.h>
[56866]44#include <iprt/path.h>
[1]45#include <VBox/param.h>
46
[10758]47#include "Pcap.h"
[35353]48#include "VBoxDD.h"
[1]49
50
[57358]51/*********************************************************************************************************************************
52* Structures and Typedefs *
53*********************************************************************************************************************************/
[1]54/**
55 * Block driver instance data.
[25966]56 *
[26305]57 * @implements PDMINETWORKUP
58 * @implements PDMINETWORKDOWN
[25966]59 * @implements PDMINETWORKCONFIG
[1]60 */
61typedef struct DRVNETSNIFFER
62{
63 /** The network interface. */
[26305]64 PDMINETWORKUP INetworkUp;
[1]65 /** The network interface. */
[26305]66 PDMINETWORKDOWN INetworkDown;
67 /** The network config interface.
68 * @todo this is a main interface and shouldn't be here... */
[10009]69 PDMINETWORKCONFIG INetworkConfig;
[1]70 /** The port we're attached to. */
[26305]71 PPDMINETWORKDOWN pIAboveNet;
[10009]72 /** The config port interface we're attached to. */
[26305]73 PPDMINETWORKCONFIG pIAboveConfig;
[1]74 /** The connector that's attached to us. */
[26305]75 PPDMINETWORKUP pIBelowNet;
[1]76 /** The filename. */
77 char szFilename[RTPATH_MAX];
78 /** The filehandle. */
[37596]79 RTFILE hFile;
[1]80 /** The lock serializing the file access. */
81 RTCRITSECT Lock;
[10758]82 /** The NanoTS delta we pass to the pcap writers. */
83 uint64_t StartNanoTS;
[1]84 /** Pointer to the driver instance. */
85 PPDMDRVINS pDrvIns;
[28258]86 /** For when we're the leaf driver. */
87 RTCRITSECT XmitLock;
[1]88
89} DRVNETSNIFFER, *PDRVNETSNIFFER;
90
91
92
93/**
[28258]94 * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit}
95 */
[28275]96static DECLCALLBACK(int) drvNetSnifferUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread)
[28258]97{
98 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
99 if (RT_UNLIKELY(!pThis->pIBelowNet))
100 {
101 int rc = RTCritSectTryEnter(&pThis->XmitLock);
102 if (RT_UNLIKELY(rc == VERR_SEM_BUSY))
103 rc = VERR_TRY_AGAIN;
104 return rc;
105 }
[28275]106 return pThis->pIBelowNet->pfnBeginXmit(pThis->pIBelowNet, fOnWorkerThread);
[28258]107}
108
109
110/**
[27843]111 * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf}
112 */
[27973]113static DECLCALLBACK(int) drvNetSnifferUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin,
114 PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf)
[27843]115{
116 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
117 if (RT_UNLIKELY(!pThis->pIBelowNet))
118 return VERR_NET_DOWN;
[27973]119 return pThis->pIBelowNet->pfnAllocBuf(pThis->pIBelowNet, cbMin, pGso, ppSgBuf);
[27843]120}
121
122
123/**
124 * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf}
125 */
126static DECLCALLBACK(int) drvNetSnifferUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf)
127{
128 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
129 if (RT_UNLIKELY(!pThis->pIBelowNet))
130 return VERR_NET_DOWN;
131 return pThis->pIBelowNet->pfnFreeBuf(pThis->pIBelowNet, pSgBuf);
132}
133
134
135/**
136 * @interface_method_impl{PDMINETWORKUP,pfnSendBuf}
137 */
138static DECLCALLBACK(int) drvNetSnifferUp_SendBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread)
139{
140 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
141 if (RT_UNLIKELY(!pThis->pIBelowNet))
142 return VERR_NET_DOWN;
143
144 /* output to sniffer */
145 RTCritSectEnter(&pThis->Lock);
[28056]146 if (!pSgBuf->pvUser)
[37596]147 PcapFileFrame(pThis->hFile, pThis->StartNanoTS,
[28056]148 pSgBuf->aSegs[0].pvSeg,
149 pSgBuf->cbUsed,
150 RT_MIN(pSgBuf->cbUsed, pSgBuf->aSegs[0].cbSeg));
151 else
[37596]152 PcapFileGsoFrame(pThis->hFile, pThis->StartNanoTS, (PCPDMNETWORKGSO)pSgBuf->pvUser,
[28056]153 pSgBuf->aSegs[0].pvSeg,
154 pSgBuf->cbUsed,
155 RT_MIN(pSgBuf->cbUsed, pSgBuf->aSegs[0].cbSeg));
[27843]156 RTCritSectLeave(&pThis->Lock);
157
158 return pThis->pIBelowNet->pfnSendBuf(pThis->pIBelowNet, pSgBuf, fOnWorkerThread);
159}
160
161
162/**
[28258]163 * @interface_method_impl{PDMINETWORKUP,pfnEndXmit}
164 */
165static DECLCALLBACK(void) drvNetSnifferUp_EndXmit(PPDMINETWORKUP pInterface)
166{
167 LogFlow(("drvNetSnifferUp_EndXmit:\n"));
168 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
169 if (RT_LIKELY(pThis->pIBelowNet))
170 pThis->pIBelowNet->pfnEndXmit(pThis->pIBelowNet);
171 else
172 RTCritSectLeave(&pThis->XmitLock);
173}
174
175
176/**
[26305]177 * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode}
[1]178 */
[27843]179static DECLCALLBACK(void) drvNetSnifferUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous)
[1]180{
[27843]181 LogFlow(("drvNetSnifferUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous));
[26305]182 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
183 if (pThis->pIBelowNet)
184 pThis->pIBelowNet->pfnSetPromiscuousMode(pThis->pIBelowNet, fPromiscuous);
[1]185}
186
187
188/**
[26305]189 * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged}
[1]190 */
[27843]191static DECLCALLBACK(void) drvNetSnifferUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState)
[1]192{
[27843]193 LogFlow(("drvNetSnifferUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
[26305]194 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkUp);
195 if (pThis->pIBelowNet)
196 pThis->pIBelowNet->pfnNotifyLinkChanged(pThis->pIBelowNet, enmLinkState);
[1]197}
198
199
200/**
[28258]201 * @interface_method_impl{PDMINETWORKDOWN,pfnWaitReceiveAvail}
[1]202 */
[27843]203static DECLCALLBACK(int) drvNetSnifferDown_WaitReceiveAvail(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies)
[1]204{
[26305]205 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkDown);
206 return pThis->pIAboveNet->pfnWaitReceiveAvail(pThis->pIAboveNet, cMillies);
[1]207}
208
209
210/**
[28258]211 * @interface_method_impl{PDMINETWORKDOWN,pfnReceive}
[1]212 */
[27843]213static DECLCALLBACK(int) drvNetSnifferDown_Receive(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb)
[1]214{
[26305]215 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkDown);
[1]216
217 /* output to sniffer */
[10758]218 RTCritSectEnter(&pThis->Lock);
[37596]219 PcapFileFrame(pThis->hFile, pThis->StartNanoTS, pvBuf, cb, cb);
[10758]220 RTCritSectLeave(&pThis->Lock);
[1]221
222 /* pass up */
[26305]223 int rc = pThis->pIAboveNet->pfnReceive(pThis->pIAboveNet, pvBuf, cb);
[1]224#if 0
[10758]225 RTCritSectEnter(&pThis->Lock);
[1]226 u64TS = RTTimeProgramNanoTS();
227 Hdr.ts_sec = (uint32_t)(u64TS / 1000000000);
228 Hdr.ts_usec = (uint32_t)((u64TS / 1000) % 1000000);
229 Hdr.incl_len = 0;
[37596]230 RTFileWrite(pThis->hFile, &Hdr, sizeof(Hdr), NULL);
[10758]231 RTCritSectLeave(&pThis->Lock);
[1]232#endif
233 return rc;
234}
235
[10009]236
[1]237/**
[28277]238 * @interface_method_impl{PDMINETWORKDOWN,pfnXmitPending}
[27843]239 */
[28277]240static DECLCALLBACK(void) drvNetSnifferDown_XmitPending(PPDMINETWORKDOWN pInterface)
[27843]241{
242 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkDown);
[28277]243 pThis->pIAboveNet->pfnXmitPending(pThis->pIAboveNet);
[27843]244}
245
246
247/**
[10009]248 * Gets the current Media Access Control (MAC) address.
249 *
250 * @returns VBox status code.
251 * @param pInterface Pointer to the interface structure containing the called function pointer.
252 * @param pMac Where to store the MAC address.
253 * @thread EMT
254 */
[27843]255static DECLCALLBACK(int) drvNetSnifferDownCfg_GetMac(PPDMINETWORKCONFIG pInterface, PRTMAC pMac)
[10009]256{
[26305]257 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkConfig);
258 return pThis->pIAboveConfig->pfnGetMac(pThis->pIAboveConfig, pMac);
[10009]259}
260
261/**
262 * Gets the new link state.
263 *
264 * @returns The current link state.
265 * @param pInterface Pointer to the interface structure containing the called function pointer.
266 * @thread EMT
267 */
[27843]268static DECLCALLBACK(PDMNETWORKLINKSTATE) drvNetSnifferDownCfg_GetLinkState(PPDMINETWORKCONFIG pInterface)
[10009]269{
[26305]270 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkConfig);
271 return pThis->pIAboveConfig->pfnGetLinkState(pThis->pIAboveConfig);
[10009]272}
273
274/**
275 * Sets the new link state.
276 *
277 * @returns VBox status code.
278 * @param pInterface Pointer to the interface structure containing the called function pointer.
279 * @param enmState The new link state
280 * @thread EMT
281 */
[27843]282static DECLCALLBACK(int) drvNetSnifferDownCfg_SetLinkState(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState)
[10009]283{
[26305]284 PDRVNETSNIFFER pThis = RT_FROM_MEMBER(pInterface, DRVNETSNIFFER, INetworkConfig);
285 return pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig, enmState);
[10009]286}
287
288
289/**
[25966]290 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
[1]291 */
[25966]292static DECLCALLBACK(void *) drvNetSnifferQueryInterface(PPDMIBASE pInterface, const char *pszIID)
[1]293{
[25966]294 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
295 PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
[25985]296 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
[26305]297 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKUP, &pThis->INetworkUp);
298 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKDOWN, &pThis->INetworkDown);
[25981]299 PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKCONFIG, &pThis->INetworkConfig);
[25966]300 return NULL;
[1]301}
302
303
304/**
[28258]305 * @interface_method_impl{PDMDRVREG,pfnDetach}
[22375]306 */
307static DECLCALLBACK(void) drvNetSnifferDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
308{
[62926]309 RT_NOREF(fFlags);
[22375]310 PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
311
312 LogFlow(("drvNetSnifferDetach: pDrvIns: %p, fFlags: %u\n", pDrvIns, fFlags));
[28258]313 RTCritSectEnter(&pThis->XmitLock);
[26305]314 pThis->pIBelowNet = NULL;
[28258]315 RTCritSectLeave(&pThis->XmitLock);
[22375]316}
317
318
319/**
[28258]320 * @interface_method_impl{PDMDRVREG,pfnAttach}
[22375]321 */
322static DECLCALLBACK(int) drvNetSnifferAttach(PPDMDRVINS pDrvIns, uint32_t fFlags)
323{
324 PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
[28258]325 LogFlow(("drvNetSnifferAttach/#%#x: fFlags=%#x\n", pDrvIns->iInstance, fFlags));
326 RTCritSectEnter(&pThis->XmitLock);
[22375]327
328 /*
329 * Query the network connector interface.
330 */
331 PPDMIBASE pBaseDown;
332 int rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
[28082]333 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
334 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
[28258]335 {
[26305]336 pThis->pIBelowNet = NULL;
[28258]337 rc = VINF_SUCCESS;
338 }
[22375]339 else if (RT_SUCCESS(rc))
340 {
[26305]341 pThis->pIBelowNet = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
[28258]342 if (pThis->pIBelowNet)
343 rc = VINF_SUCCESS;
344 else
[22375]345 {
346 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
[28258]347 rc = VERR_PDM_MISSING_INTERFACE_BELOW;
[22375]348 }
349 }
350 else
351 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
352
[28258]353 RTCritSectLeave(&pThis->XmitLock);
[22375]354 return VINF_SUCCESS;
355}
356
357
358/**
[28258]359 * @interface_method_impl{PDMDRVREG,pfnDestruct}
[1]360 */
361static DECLCALLBACK(void) drvNetSnifferDestruct(PPDMDRVINS pDrvIns)
362{
[11267]363 PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
[26001]364 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
[1]365
[10758]366 if (RTCritSectIsInitialized(&pThis->Lock))
367 RTCritSectDelete(&pThis->Lock);
[1]368
[28258]369 if (RTCritSectIsInitialized(&pThis->XmitLock))
370 RTCritSectDelete(&pThis->XmitLock);
371
[45061]372 if (pThis->hFile != NIL_RTFILE)
373 {
374 RTFileClose(pThis->hFile);
375 pThis->hFile = NIL_RTFILE;
376 }
[1]377}
378
379
380/**
[28258]381 * @interface_method_impl{Construct a NAT network transport driver instance,
382 * PDMDRVREG,pfnDestruct}
[1]383 */
[26173]384static DECLCALLBACK(int) drvNetSnifferConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
[1]385{
[26001]386 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
[91872]387 PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
388 PCPDMDRVHLPR3 pHlp = pDrvIns->pHlpR3;
[1]389
[91872]390 LogFlow(("drvNetSnifferConstruct:\n"));
391
[1]392 /*
393 * Init the static parts.
394 */
[26305]395 pThis->pDrvIns = pDrvIns;
[37596]396 pThis->hFile = NIL_RTFILE;
[14844]397 /* The pcap file *must* start at time offset 0,0. */
[26305]398 pThis->StartNanoTS = RTTimeNanoTS() - RTTimeProgramNanoTS();
[1]399 /* IBase */
[26305]400 pDrvIns->IBase.pfnQueryInterface = drvNetSnifferQueryInterface;
401 /* INetworkUp */
[28258]402 pThis->INetworkUp.pfnBeginXmit = drvNetSnifferUp_BeginXmit;
[27843]403 pThis->INetworkUp.pfnAllocBuf = drvNetSnifferUp_AllocBuf;
404 pThis->INetworkUp.pfnFreeBuf = drvNetSnifferUp_FreeBuf;
405 pThis->INetworkUp.pfnSendBuf = drvNetSnifferUp_SendBuf;
[28258]406 pThis->INetworkUp.pfnEndXmit = drvNetSnifferUp_EndXmit;
[27843]407 pThis->INetworkUp.pfnSetPromiscuousMode = drvNetSnifferUp_SetPromiscuousMode;
408 pThis->INetworkUp.pfnNotifyLinkChanged = drvNetSnifferUp_NotifyLinkChanged;
[26305]409 /* INetworkDown */
[27843]410 pThis->INetworkDown.pfnWaitReceiveAvail = drvNetSnifferDown_WaitReceiveAvail;
411 pThis->INetworkDown.pfnReceive = drvNetSnifferDown_Receive;
[28277]412 pThis->INetworkDown.pfnXmitPending = drvNetSnifferDown_XmitPending;
[10009]413 /* INetworkConfig */
[27843]414 pThis->INetworkConfig.pfnGetMac = drvNetSnifferDownCfg_GetMac;
415 pThis->INetworkConfig.pfnGetLinkState = drvNetSnifferDownCfg_GetLinkState;
416 pThis->INetworkConfig.pfnSetLinkState = drvNetSnifferDownCfg_SetLinkState;
[1]417
418 /*
[28258]419 * Create the locks.
420 */
421 int rc = RTCritSectInit(&pThis->Lock);
422 AssertRCReturn(rc, rc);
423 rc = RTCritSectInit(&pThis->XmitLock);
424 AssertRCReturn(rc, rc);
425
426 /*
427 * Validate the config.
428 */
[91872]429 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "File", "");
[28258]430
[91872]431 if (pHlp->pfnCFGMGetFirstChild(pCfg))
[28258]432 LogRel(("NetSniffer: Found child config entries -- are you trying to redirect ports?\n"));
433
434 /*
[1]435 * Get the filename.
436 */
[91872]437 rc = pHlp->pfnCFGMQueryString(pCfg, "File", pThis->szFilename, sizeof(pThis->szFilename));
[1]438 if (rc == VERR_CFGM_VALUE_NOT_FOUND)
[24285]439 {
440 if (pDrvIns->iInstance > 0)
441 RTStrPrintf(pThis->szFilename, sizeof(pThis->szFilename), "./VBox-%x-%u.pcap", RTProcSelf(), pDrvIns->iInstance);
442 else
443 RTStrPrintf(pThis->szFilename, sizeof(pThis->szFilename), "./VBox-%x.pcap", RTProcSelf());
444 }
445
[11266]446 else if (RT_FAILURE(rc))
[1]447 {
[11284]448 AssertMsgFailed(("Failed to query \"File\", rc=%Rrc.\n", rc));
[1]449 return rc;
450 }
451
452 /*
453 * Query the network port interface.
454 */
[26305]455 pThis->pIAboveNet = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKDOWN);
456 if (!pThis->pIAboveNet)
[1]457 {
458 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network port interface!\n"));
459 return VERR_PDM_MISSING_INTERFACE_ABOVE;
460 }
461
462 /*
[10009]463 * Query the network config interface.
464 */
[26305]465 pThis->pIAboveConfig = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMINETWORKCONFIG);
466 if (!pThis->pIAboveConfig)
[10009]467 {
468 AssertMsgFailed(("Configuration error: the above device/driver didn't export the network config interface!\n"));
469 return VERR_PDM_MISSING_INTERFACE_ABOVE;
470 }
471
472 /*
[1]473 * Query the network connector interface.
474 */
475 PPDMIBASE pBaseDown;
[22277]476 rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBaseDown);
[28082]477 if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
478 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
[26305]479 pThis->pIBelowNet = NULL;
[11266]480 else if (RT_SUCCESS(rc))
[1]481 {
[26305]482 pThis->pIBelowNet = PDMIBASE_QUERY_INTERFACE(pBaseDown, PDMINETWORKUP);
483 if (!pThis->pIBelowNet)
[1]484 {
485 AssertMsgFailed(("Configuration error: the driver below didn't export the network connector interface!\n"));
486 return VERR_PDM_MISSING_INTERFACE_BELOW;
487 }
488 }
489 else
490 {
[11284]491 AssertMsgFailed(("Failed to attach to driver below! rc=%Rrc\n", rc));
[1]492 return rc;
493 }
494
495 /*
496 * Open output file / pipe.
497 */
[37596]498 rc = RTFileOpen(&pThis->hFile, pThis->szFilename,
[1]499 RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE);
[11266]500 if (RT_FAILURE(rc))
[15115]501 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
502 N_("Netsniffer cannot open '%s' for writing. The directory must exist and it must be writable for the current user"), pThis->szFilename);
[1]503
[56866]504 char *pszPathReal = RTPathRealDup(pThis->szFilename);
505 if (pszPathReal)
506 {
[56868]507 LogRel(("NetSniffer: Sniffing to '%s'\n", pszPathReal));
[56866]508 RTStrFree(pszPathReal);
509 }
510 else
[56868]511 LogRel(("NetSniffer: Sniffing to '%s'\n", pThis->szFilename));
[56866]512
[1]513 /*
514 * Write pcap header.
[37461]515 * Some time has gone by since capturing pThis->StartNanoTS so get the
516 * current time again.
[1]517 */
[37596]518 PcapFileHdr(pThis->hFile, RTTimeNanoTS());
[3196]519
[1]520 return VINF_SUCCESS;
521}
522
523
524
525/**
526 * Network sniffer filter driver registration record.
527 */
528const PDMDRVREG g_DrvNetSniffer =
529{
530 /* u32Version */
531 PDM_DRVREG_VERSION,
[26166]532 /* szName */
[1]533 "NetSniffer",
[25893]534 /* szRCMod */
535 "",
536 /* szR0Mod */
537 "",
[1]538 /* pszDescription */
539 "Network Sniffer Filter Driver",
540 /* fFlags */
541 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
542 /* fClass. */
543 PDM_DRVREG_CLASS_NETWORK,
544 /* cMaxInstances */
[24285]545 UINT32_MAX,
[1]546 /* cbInstance */
547 sizeof(DRVNETSNIFFER),
548 /* pfnConstruct */
549 drvNetSnifferConstruct,
550 /* pfnDestruct */
551 drvNetSnifferDestruct,
[25893]552 /* pfnRelocate */
553 NULL,
[1]554 /* pfnIOCtl */
555 NULL,
556 /* pfnPowerOn */
557 NULL,
558 /* pfnReset */
559 NULL,
560 /* pfnSuspend */
561 NULL,
562 /* pfnResume */
563 NULL,
[22277]564 /* pfnAttach */
[22375]565 drvNetSnifferAttach,
[1]566 /* pfnDetach */
[22375]567 drvNetSnifferDetach,
[22277]568 /* pfnPowerOff */
[22375]569 NULL,
[22277]570 /* pfnSoftReset */
[1]571 NULL,
[22277]572 /* u32EndVersion */
573 PDM_DRVREG_VERSION
[1]574};
575
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use