diff options
Diffstat (limited to 'src/VBox/Devices/USB/VUSBSnifferVmx.cpp')
-rw-r--r-- | src/VBox/Devices/USB/VUSBSnifferVmx.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/VBox/Devices/USB/VUSBSnifferVmx.cpp b/src/VBox/Devices/USB/VUSBSnifferVmx.cpp new file mode 100644 index 00000000..b69548a4 --- /dev/null +++ b/src/VBox/Devices/USB/VUSBSnifferVmx.cpp @@ -0,0 +1,212 @@ +/* $Id: VUSBSnifferVmx.cpp $ */ +/** @file + * Virtual USB Sniffer facility - VMX USBIO format. + */ + +/* + * Copyright (C) 2016-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#define LOG_GROUP LOG_GROUP_DRV_VUSB +#include <VBox/log.h> +#include <iprt/mem.h> +#include <iprt/buildconfig.h> +#include <iprt/string.h> +#include <iprt/system.h> +#include <iprt/time.h> + +#include "VUSBSnifferInternal.h" + + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ + + +/********************************************************************************************************************************* +* Structures and Typedefs * +*********************************************************************************************************************************/ + +/** + * The internal VUSB sniffer state. + */ +typedef struct VUSBSNIFFERFMTINT +{ + /** Stream handle. */ + PVUSBSNIFFERSTRM pStrm; +} VUSBSNIFFERFMTINT; + + +/********************************************************************************************************************************* +* Static Variables * +*********************************************************************************************************************************/ + +/** + * Supported file extensions. + */ +static const char *s_apszFileExts[] = +{ + "vmx", + "vmware", + "usbio", + NULL +}; + + +/** + * Month strings. + */ +static const char *s_apszMonths[] = +{ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" +}; + + +/********************************************************************************************************************************* +* Internal Functions * +*********************************************************************************************************************************/ + + +static int vusbSnifferFmtVmxLogData(PVUSBSNIFFERFMTINT pThis, PRTTIME pTime, uint8_t *pbBuf, size_t cbBuf) +{ + int rc; + char szLineBuf[256]; + size_t off = 0; + + do + { + size_t cch = RTStrPrintf(&szLineBuf[0], sizeof(szLineBuf), + "%s %02u %02u:%02u:%02u.%3.*u: vmx| USBIO: %03zx: %16.*Rhxs\n", + s_apszMonths[pTime->u8Month - 1], pTime->u8MonthDay, + pTime->u8Hour, pTime->u8Minute, pTime->u8Second, 3, pTime->u32Nanosecond, + off, RT_MIN(cbBuf - off, 16), pbBuf); + rc = pThis->pStrm->pfnWrite(pThis->pStrm, &szLineBuf[0], cch); + off += RT_MIN(cbBuf, 16); + pbBuf += RT_MIN(cbBuf, 16); + } while (RT_SUCCESS(rc) && off < cbBuf); + + return rc; +} + +/** @interface_method_impl{VUSBSNIFFERFMT,pfnInit} */ +static DECLCALLBACK(int) vusbSnifferFmtVmxInit(PVUSBSNIFFERFMTINT pThis, PVUSBSNIFFERSTRM pStrm) +{ + pThis->pStrm = pStrm; + return VINF_SUCCESS; +} + + +/** @interface_method_impl{VUSBSNIFFERFMT,pfnDestroy} */ +static DECLCALLBACK(void) vusbSnifferFmtVmxDestroy(PVUSBSNIFFERFMTINT pThis) +{ + NOREF(pThis); +} + + +/** @interface_method_impl{VUSBSNIFFERFMT,pfnRecordEvent} */ +static DECLCALLBACK(int) vusbSnifferFmtVmxRecordEvent(PVUSBSNIFFERFMTINT pThis, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent) +{ + RTTIMESPEC TimeNow; + RTTIME Time; + char szLineBuf[256]; + const char *pszEvt = enmEvent == VUSBSNIFFEREVENT_SUBMIT ? "Down" : "Up"; + uint8_t cIsocPkts = pUrb->enmType == VUSBXFERTYPE_ISOC ? pUrb->cIsocPkts : 0; + + if (pUrb->enmType == VUSBXFERTYPE_MSG) + return VINF_SUCCESS; + + RT_ZERO(szLineBuf); + + RTTimeNow(&TimeNow); + RTTimeExplode(&Time, &TimeNow); + + size_t cch = RTStrPrintf(&szLineBuf[0], sizeof(szLineBuf), + "%s %02u %02u:%02u:%02u.%3.*u: vmx| USBIO: %s dev=%u endpt=%x datalen=%u numPackets=%u status=%u 0\n", + s_apszMonths[Time.u8Month - 1], Time.u8MonthDay, Time.u8Hour, Time.u8Minute, Time.u8Second, 3, Time.u32Nanosecond, + pszEvt, pUrb->DstAddress, pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0x00), + pUrb->cbData, cIsocPkts, pUrb->enmStatus); + int rc = pThis->pStrm->pfnWrite(pThis->pStrm, &szLineBuf[0], cch); + if (RT_SUCCESS(rc)) + { + /* Log the data in the appropriate stage. */ + if ( pUrb->enmType == VUSBXFERTYPE_CTRL + || pUrb->enmType == VUSBXFERTYPE_MSG) + { + if (enmEvent == VUSBSNIFFEREVENT_SUBMIT) + rc = vusbSnifferFmtVmxLogData(pThis, &Time, &pUrb->abData[0], sizeof(VUSBSETUP)); + else if (enmEvent == VUSBSNIFFEREVENT_COMPLETE) + { + rc = vusbSnifferFmtVmxLogData(pThis, &Time, &pUrb->abData[0], sizeof(VUSBSETUP)); + if ( RT_SUCCESS(rc) + && pUrb->cbData > sizeof(VUSBSETUP)) + rc = vusbSnifferFmtVmxLogData(pThis, &Time, &pUrb->abData[sizeof(VUSBSETUP)], pUrb->cbData - sizeof(VUSBSETUP)); + } + } + else + { + if ( enmEvent == VUSBSNIFFEREVENT_SUBMIT + && pUrb->enmDir == VUSBDIRECTION_OUT) + rc = vusbSnifferFmtVmxLogData(pThis, &Time, &pUrb->abData[0], pUrb->cbData); + else if ( enmEvent == VUSBSNIFFEREVENT_COMPLETE + && pUrb->enmDir == VUSBDIRECTION_IN) + rc = vusbSnifferFmtVmxLogData(pThis, &Time, &pUrb->abData[0], pUrb->cbData); + } + } + + return rc; +} + +/** + * VUSB sniffer format writer. + */ +const VUSBSNIFFERFMT g_VUsbSnifferFmtVmx = +{ + /** szName */ + "VMX", + /** pszDesc */ + "VMX log format writer supported by vusb-analyzer: http://vusb-analyzer.sourceforge.net", + /** papszFileExts */ + &s_apszFileExts[0], + /** cbFmt */ + sizeof(VUSBSNIFFERFMTINT), + /** pfnInit */ + vusbSnifferFmtVmxInit, + /** pfnDestroy */ + vusbSnifferFmtVmxDestroy, + /** pfnRecordEvent */ + vusbSnifferFmtVmxRecordEvent +}; + |