VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/VUSBSniffer.cpp@ 102788

Last change on this file since 102788 was 99739, checked in by vboxsync, 16 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
RevLine 
[53014]1/* $Id: VUSBSniffer.cpp 99739 2023-05-11 01:01:08Z vboxsync $ */
2/** @file
3 * Virtual USB - Sniffer facility.
4 */
5
6/*
[98103]7 * Copyright (C) 2014-2023 Oracle and/or its affiliates.
[53014]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
[53014]26 */
27
[57358]28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
[53014]32#define LOG_GROUP LOG_GROUP_DRV_VUSB
33#include <VBox/log.h>
34#include <iprt/file.h>
[76474]35#include <iprt/errcore.h>
[59615]36#include <iprt/path.h>
[53014]37#include <iprt/mem.h>
38#include <iprt/string.h>
[53071]39#include <iprt/semaphore.h>
[53072]40#include <iprt/time.h>
[53014]41
[59615]42#include "VUSBSnifferInternal.h"
[53014]43
44
[57358]45/*********************************************************************************************************************************
46* Structures and Typedefs *
47*********************************************************************************************************************************/
48
[53014]49/**
50 * The internal VUSB sniffer state.
51 */
52typedef struct VUSBSNIFFERINT
53{
54 /** The file handle to dump to. */
55 RTFILE hFile;
[53071]56 /** Fast Mutex protecting the state against concurrent access. */
57 RTSEMFASTMUTEX hMtx;
[59615]58 /** File stream. */
59 VUSBSNIFFERSTRM Strm;
60 /** Pointer to the used format. */
61 PCVUSBSNIFFERFMT pFmt;
62 /** Format specific state - variable in size. */
63 uint8_t abFmt[1];
[53014]64} VUSBSNIFFERINT;
65/** Pointer to the internal VUSB sniffer state. */
66typedef VUSBSNIFFERINT *PVUSBSNIFFERINT;
67
68
[59615]69/*********************************************************************************************************************************
70* Static Variables *
71*********************************************************************************************************************************/
[53014]72
[59615]73static PCVUSBSNIFFERFMT s_aVUsbSnifferFmts[] =
[53060]74{
[59633]75 &g_VUsbSnifferFmtPcapNg,
76 &g_VUsbSnifferFmtUsbMon,
77 &g_VUsbSnifferFmtVmx,
[59615]78};
[53060]79
80
[59615]81/*********************************************************************************************************************************
82* Internal Functions *
83*********************************************************************************************************************************/
[53060]84
[64294]85/** @interface_method_impl{VUSBSNIFFERSTRM,pfnWrite} */
[59615]86static DECLCALLBACK(int) vusbSnifferStrmWrite(PVUSBSNIFFERSTRM pStrm, const void *pvBuf, size_t cbBuf)
[53014]87{
[59615]88 PVUSBSNIFFERINT pThis = RT_FROM_MEMBER(pStrm, VUSBSNIFFERINT, Strm);
[53014]89
[59615]90 return RTFileWrite(pThis->hFile, pvBuf, cbBuf, NULL);
[53072]91}
92
93/**
[59615]94 * Returns a supporting format writer taken from the given format name.
[53072]95 *
[59615]96 * @returns Pointer to the format structure or NULL if none was found.
97 * @param pszFmt The format to use.
[53072]98 */
[59615]99static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromString(const char *pszFmt)
[53072]100{
[59615]101 for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++)
[53014]102 {
[59615]103 if (!RTStrICmp(pszFmt, s_aVUsbSnifferFmts[i]->szName))
104 return s_aVUsbSnifferFmts[i];
[53014]105 }
106
[59615]107 return NULL;
[53014]108}
109
110/**
[59615]111 * Returns a supporting format writer taken from the file suffix.
[53014]112 *
[59615]113 * @returns Pointer to the format structure or NULL if none was found.
[64294]114 * @param pszFilename The file name to take the suffix from.
[53014]115 */
[59615]116static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromFilename(const char *pszFilename)
[53014]117{
[59615]118 const char *pszFileExt = RTPathSuffix(pszFilename);
119 if (!pszFileExt)
120 return NULL;
[53014]121
[59615]122 pszFileExt++; /* Skip the dot. */
[53014]123
[59615]124 for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++)
125 {
126 unsigned idxFileExt = 0;
[53014]127
[59615]128 while (s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt])
129 {
130 if (!RTStrICmp(pszFileExt, s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt]))
131 return s_aVUsbSnifferFmts[i];
[53014]132
[59615]133 idxFileExt++;
134 }
[53014]135 }
136
[59615]137 return NULL;
[53014]138}
139
[59615]140
[53014]141DECLHIDDEN(int) VUSBSnifferCreate(PVUSBSNIFFER phSniffer, uint32_t fFlags,
[59615]142 const char *pszCaptureFilename, const char *pszFmt,
143 const char *pszDesc)
[53014]144{
[62959]145 RT_NOREF(pszDesc);
[53014]146 int rc = VINF_SUCCESS;
147 PVUSBSNIFFERINT pThis = NULL;
[59615]148 PCVUSBSNIFFERFMT pFmt = NULL;
[53014]149
[59615]150 if (pszFmt)
151 pFmt = vusbSnifferGetFmtFromString(pszFmt);
152 else
153 pFmt = vusbSnifferGetFmtFromFilename(pszCaptureFilename);
154
155 if (!pFmt)
156 return VERR_NOT_FOUND;
157
[73097]158 pThis = (PVUSBSNIFFERINT)RTMemAllocZ(RT_UOFFSETOF_DYN(VUSBSNIFFERINT, abFmt[pFmt->cbFmt]));
[53014]159 if (pThis)
160 {
[59615]161 pThis->hFile = NIL_RTFILE;
162 pThis->hMtx = NIL_RTSEMFASTMUTEX;
163 pThis->pFmt = pFmt;
164 pThis->Strm.pfnWrite = vusbSnifferStrmWrite;
[53014]165
[53071]166 rc = RTSemFastMutexCreate(&pThis->hMtx);
[53014]167 if (RT_SUCCESS(rc))
168 {
[59686]169 uint32_t fFileFlags = RTFILE_O_DENY_NONE | RTFILE_O_WRITE | RTFILE_O_READ;
170 if (fFlags & VUSBSNIFFER_F_NO_REPLACE)
171 fFileFlags |= RTFILE_O_CREATE;
172 else
173 fFileFlags |= RTFILE_O_CREATE_REPLACE;
174
175 rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, fFileFlags);
[53014]176 if (RT_SUCCESS(rc))
177 {
[59615]178 rc = pThis->pFmt->pfnInit((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], &pThis->Strm);
[53071]179 if (RT_SUCCESS(rc))
180 {
181 *phSniffer = pThis;
182 return VINF_SUCCESS;
[53014]183 }
184
[53071]185 RTFileClose(pThis->hFile);
186 pThis->hFile = NIL_RTFILE;
187 RTFileDelete(pszCaptureFilename);
[53014]188 }
[53071]189 RTSemFastMutexDestroy(pThis->hMtx);
[53072]190 pThis->hMtx = NIL_RTSEMFASTMUTEX;
[53014]191 }
[59615]192
[53146]193 RTMemFree(pThis);
[53014]194 }
195 else
196 rc = VERR_NO_MEMORY;
197
198 return rc;
199}
200
201/**
202 * Destroys the given VUSB sniffer instance.
203 *
204 * @param hSniffer The sniffer instance to destroy.
205 */
206DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer)
207{
208 PVUSBSNIFFERINT pThis = hSniffer;
209
[53071]210 int rc = RTSemFastMutexRequest(pThis->hMtx);
211 AssertRC(rc);
212
[59615]213 pThis->pFmt->pfnDestroy((PVUSBSNIFFERFMTINT)&pThis->abFmt[0]);
214
[53014]215 if (pThis->hFile != NIL_RTFILE)
216 RTFileClose(pThis->hFile);
[53071]217
218 RTSemFastMutexRelease(pThis->hMtx);
219 RTSemFastMutexDestroy(pThis->hMtx);
[53014]220 RTMemFree(pThis);
221}
222
223/**
224 * Records an VUSB event.
225 *
226 * @returns VBox status code.
227 * @param hSniffer The sniffer instance.
228 * @param pUrb The URB triggering the event.
229 * @param enmEvent The type of event to record.
230 */
231DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
232{
233 int rc = VINF_SUCCESS;
234 PVUSBSNIFFERINT pThis = hSniffer;
235
[53071]236 /* Write the packet to the capture file. */
237 rc = RTSemFastMutexRequest(pThis->hMtx);
[53014]238 if (RT_SUCCESS(rc))
[53071]239 {
[59615]240 rc = pThis->pFmt->pfnRecordEvent((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], pUrb, enmEvent);
[53071]241 RTSemFastMutexRelease(pThis->hMtx);
242 }
243
[53014]244 return rc;
245}
246
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