diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 03:01:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 03:01:46 +0000 |
commit | f8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch) | |
tree | 26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/Devices/USB/VUSBSniffer.cpp | |
parent | Initial commit. (diff) | |
download | virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip |
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/USB/VUSBSniffer.cpp')
-rw-r--r-- | src/VBox/Devices/USB/VUSBSniffer.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/src/VBox/Devices/USB/VUSBSniffer.cpp b/src/VBox/Devices/USB/VUSBSniffer.cpp new file mode 100644 index 00000000..2661f9d6 --- /dev/null +++ b/src/VBox/Devices/USB/VUSBSniffer.cpp @@ -0,0 +1,237 @@ +/* $Id: VUSBSniffer.cpp $ */ +/** @file + * Virtual USB - Sniffer facility. + */ + +/* + * Copyright (C) 2014-2019 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. + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#define LOG_GROUP LOG_GROUP_DRV_VUSB +#include <VBox/log.h> +#include <iprt/file.h> +#include <iprt/errcore.h> +#include <iprt/path.h> +#include <iprt/mem.h> +#include <iprt/string.h> +#include <iprt/semaphore.h> +#include <iprt/time.h> + +#include "VUSBSnifferInternal.h" + + +/********************************************************************************************************************************* +* Structures and Typedefs * +*********************************************************************************************************************************/ + +/** + * The internal VUSB sniffer state. + */ +typedef struct VUSBSNIFFERINT +{ + /** The file handle to dump to. */ + RTFILE hFile; + /** Fast Mutex protecting the state against concurrent access. */ + RTSEMFASTMUTEX hMtx; + /** File stream. */ + VUSBSNIFFERSTRM Strm; + /** Pointer to the used format. */ + PCVUSBSNIFFERFMT pFmt; + /** Format specific state - variable in size. */ + uint8_t abFmt[1]; +} VUSBSNIFFERINT; +/** Pointer to the internal VUSB sniffer state. */ +typedef VUSBSNIFFERINT *PVUSBSNIFFERINT; + + +/********************************************************************************************************************************* +* Static Variables * +*********************************************************************************************************************************/ + +static PCVUSBSNIFFERFMT s_aVUsbSnifferFmts[] = +{ + &g_VUsbSnifferFmtPcapNg, + &g_VUsbSnifferFmtUsbMon, + &g_VUsbSnifferFmtVmx, +}; + + +/********************************************************************************************************************************* +* Internal Functions * +*********************************************************************************************************************************/ + +/** @interface_method_impl{VUSBSNIFFERSTRM,pfnWrite} */ +static DECLCALLBACK(int) vusbSnifferStrmWrite(PVUSBSNIFFERSTRM pStrm, const void *pvBuf, size_t cbBuf) +{ + PVUSBSNIFFERINT pThis = RT_FROM_MEMBER(pStrm, VUSBSNIFFERINT, Strm); + + return RTFileWrite(pThis->hFile, pvBuf, cbBuf, NULL); +} + +/** + * Returns a supporting format writer taken from the given format name. + * + * @returns Pointer to the format structure or NULL if none was found. + * @param pszFmt The format to use. + */ +static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromString(const char *pszFmt) +{ + for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++) + { + if (!RTStrICmp(pszFmt, s_aVUsbSnifferFmts[i]->szName)) + return s_aVUsbSnifferFmts[i]; + } + + return NULL; +} + +/** + * Returns a supporting format writer taken from the file suffix. + * + * @returns Pointer to the format structure or NULL if none was found. + * @param pszFilename The file name to take the suffix from. + */ +static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromFilename(const char *pszFilename) +{ + const char *pszFileExt = RTPathSuffix(pszFilename); + if (!pszFileExt) + return NULL; + + pszFileExt++; /* Skip the dot. */ + + for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++) + { + unsigned idxFileExt = 0; + + while (s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt]) + { + if (!RTStrICmp(pszFileExt, s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt])) + return s_aVUsbSnifferFmts[i]; + + idxFileExt++; + } + } + + return NULL; +} + + +DECLHIDDEN(int) VUSBSnifferCreate(PVUSBSNIFFER phSniffer, uint32_t fFlags, + const char *pszCaptureFilename, const char *pszFmt, + const char *pszDesc) +{ + RT_NOREF(pszDesc); + int rc = VINF_SUCCESS; + PVUSBSNIFFERINT pThis = NULL; + PCVUSBSNIFFERFMT pFmt = NULL; + + if (pszFmt) + pFmt = vusbSnifferGetFmtFromString(pszFmt); + else + pFmt = vusbSnifferGetFmtFromFilename(pszCaptureFilename); + + if (!pFmt) + return VERR_NOT_FOUND; + + pThis = (PVUSBSNIFFERINT)RTMemAllocZ(RT_UOFFSETOF_DYN(VUSBSNIFFERINT, abFmt[pFmt->cbFmt])); + if (pThis) + { + pThis->hFile = NIL_RTFILE; + pThis->hMtx = NIL_RTSEMFASTMUTEX; + pThis->pFmt = pFmt; + pThis->Strm.pfnWrite = vusbSnifferStrmWrite; + + rc = RTSemFastMutexCreate(&pThis->hMtx); + if (RT_SUCCESS(rc)) + { + uint32_t fFileFlags = RTFILE_O_DENY_NONE | RTFILE_O_WRITE | RTFILE_O_READ; + if (fFlags & VUSBSNIFFER_F_NO_REPLACE) + fFileFlags |= RTFILE_O_CREATE; + else + fFileFlags |= RTFILE_O_CREATE_REPLACE; + + rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, fFileFlags); + if (RT_SUCCESS(rc)) + { + rc = pThis->pFmt->pfnInit((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], &pThis->Strm); + if (RT_SUCCESS(rc)) + { + *phSniffer = pThis; + return VINF_SUCCESS; + } + + RTFileClose(pThis->hFile); + pThis->hFile = NIL_RTFILE; + RTFileDelete(pszCaptureFilename); + } + RTSemFastMutexDestroy(pThis->hMtx); + pThis->hMtx = NIL_RTSEMFASTMUTEX; + } + + RTMemFree(pThis); + } + else + rc = VERR_NO_MEMORY; + + return rc; +} + +/** + * Destroys the given VUSB sniffer instance. + * + * @returns nothing. + * @param hSniffer The sniffer instance to destroy. + */ +DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer) +{ + PVUSBSNIFFERINT pThis = hSniffer; + + int rc = RTSemFastMutexRequest(pThis->hMtx); + AssertRC(rc); + + pThis->pFmt->pfnDestroy((PVUSBSNIFFERFMTINT)&pThis->abFmt[0]); + + if (pThis->hFile != NIL_RTFILE) + RTFileClose(pThis->hFile); + + RTSemFastMutexRelease(pThis->hMtx); + RTSemFastMutexDestroy(pThis->hMtx); + RTMemFree(pThis); +} + +/** + * Records an VUSB event. + * + * @returns VBox status code. + * @param hSniffer The sniffer instance. + * @param pUrb The URB triggering the event. + * @param enmEvent The type of event to record. + */ +DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent) +{ + int rc = VINF_SUCCESS; + PVUSBSNIFFERINT pThis = hSniffer; + + /* Write the packet to the capture file. */ + rc = RTSemFastMutexRequest(pThis->hMtx); + if (RT_SUCCESS(rc)) + { + rc = pThis->pFmt->pfnRecordEvent((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], pUrb, enmEvent); + RTSemFastMutexRelease(pThis->hMtx); + } + + return rc; +} + |