VirtualBox

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

Last change on this file since 59633 was 59633, checked in by vboxsync, 9 years ago

USB/Sniffer: Add format writers for Linux usbmon ASCII output and VMware debug logs so analyzing logs with vusb-analyzer is possible

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: VUSBSniffer.cpp 59633 2016-02-10 15:39:58Z vboxsync $ */
2/** @file
3 * Virtual USB - Sniffer facility.
4 */
5
6/*
7 * Copyright (C) 2014-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DRV_VUSB
23#include <VBox/log.h>
24#include <iprt/file.h>
25#include <iprt/path.h>
26#include <iprt/mem.h>
27#include <iprt/string.h>
28#include <iprt/semaphore.h>
29#include <iprt/time.h>
30
31#include "VUSBSnifferInternal.h"
32
33
34/*********************************************************************************************************************************
35* Defined Constants And Macros *
36*********************************************************************************************************************************/
37
38/*********************************************************************************************************************************
39* Structures and Typedefs *
40*********************************************************************************************************************************/
41
42/**
43 * The internal VUSB sniffer state.
44 */
45typedef struct VUSBSNIFFERINT
46{
47 /** The file handle to dump to. */
48 RTFILE hFile;
49 /** Fast Mutex protecting the state against concurrent access. */
50 RTSEMFASTMUTEX hMtx;
51 /** File stream. */
52 VUSBSNIFFERSTRM Strm;
53 /** Pointer to the used format. */
54 PCVUSBSNIFFERFMT pFmt;
55 /** Format specific state - variable in size. */
56 uint8_t abFmt[1];
57} VUSBSNIFFERINT;
58/** Pointer to the internal VUSB sniffer state. */
59typedef VUSBSNIFFERINT *PVUSBSNIFFERINT;
60
61
62/*********************************************************************************************************************************
63* Static Variables *
64*********************************************************************************************************************************/
65
66static PCVUSBSNIFFERFMT s_aVUsbSnifferFmts[] =
67{
68 &g_VUsbSnifferFmtPcapNg,
69 &g_VUsbSnifferFmtUsbMon,
70 &g_VUsbSnifferFmtVmx,
71};
72
73
74/*********************************************************************************************************************************
75* Internal Functions *
76*********************************************************************************************************************************/
77
78/** @copydoc VUSBSNIFFERSTRM::pfnWrite. */
79static DECLCALLBACK(int) vusbSnifferStrmWrite(PVUSBSNIFFERSTRM pStrm, const void *pvBuf, size_t cbBuf)
80{
81 PVUSBSNIFFERINT pThis = RT_FROM_MEMBER(pStrm, VUSBSNIFFERINT, Strm);
82
83 return RTFileWrite(pThis->hFile, pvBuf, cbBuf, NULL);
84}
85
86/**
87 * Returns a supporting format writer taken from the given format name.
88 *
89 * @returns Pointer to the format structure or NULL if none was found.
90 * @param pszFmt The format to use.
91 */
92static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromString(const char *pszFmt)
93{
94 for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++)
95 {
96 if (!RTStrICmp(pszFmt, s_aVUsbSnifferFmts[i]->szName))
97 return s_aVUsbSnifferFmts[i];
98 }
99
100 return NULL;
101}
102
103/**
104 * Returns a supporting format writer taken from the file suffix.
105 *
106 * @returns Pointer to the format structure or NULL if none was found.
107 * @param pFilename The file name to take the suffix from.
108 */
109static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromFilename(const char *pszFilename)
110{
111 const char *pszFileExt = RTPathSuffix(pszFilename);
112 if (!pszFileExt)
113 return NULL;
114
115 pszFileExt++; /* Skip the dot. */
116
117 for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++)
118 {
119 unsigned idxFileExt = 0;
120
121 while (s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt])
122 {
123 if (!RTStrICmp(pszFileExt, s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt]))
124 return s_aVUsbSnifferFmts[i];
125
126 idxFileExt++;
127 }
128 }
129
130 return NULL;
131}
132
133
134DECLHIDDEN(int) VUSBSnifferCreate(PVUSBSNIFFER phSniffer, uint32_t fFlags,
135 const char *pszCaptureFilename, const char *pszFmt,
136 const char *pszDesc)
137{
138 int rc = VINF_SUCCESS;
139 PVUSBSNIFFERINT pThis = NULL;
140 PCVUSBSNIFFERFMT pFmt = NULL;
141
142 if (pszFmt)
143 pFmt = vusbSnifferGetFmtFromString(pszFmt);
144 else
145 pFmt = vusbSnifferGetFmtFromFilename(pszCaptureFilename);
146
147 if (!pFmt)
148 return VERR_NOT_FOUND;
149
150 pThis = (PVUSBSNIFFERINT)RTMemAllocZ(RT_OFFSETOF(VUSBSNIFFERINT, abFmt[pFmt->cbFmt]));
151 if (pThis)
152 {
153 pThis->hFile = NIL_RTFILE;
154 pThis->hMtx = NIL_RTSEMFASTMUTEX;
155 pThis->pFmt = pFmt;
156 pThis->Strm.pfnWrite = vusbSnifferStrmWrite;
157
158 rc = RTSemFastMutexCreate(&pThis->hMtx);
159 if (RT_SUCCESS(rc))
160 {
161 rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, RTFILE_O_DENY_NONE | RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ);
162 if (RT_SUCCESS(rc))
163 {
164 rc = pThis->pFmt->pfnInit((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], &pThis->Strm);
165 if (RT_SUCCESS(rc))
166 {
167 *phSniffer = pThis;
168 return VINF_SUCCESS;
169 }
170
171 RTFileClose(pThis->hFile);
172 pThis->hFile = NIL_RTFILE;
173 RTFileDelete(pszCaptureFilename);
174 }
175 RTSemFastMutexDestroy(pThis->hMtx);
176 pThis->hMtx = NIL_RTSEMFASTMUTEX;
177 }
178
179 RTMemFree(pThis);
180 }
181 else
182 rc = VERR_NO_MEMORY;
183
184 return rc;
185}
186
187/**
188 * Destroys the given VUSB sniffer instance.
189 *
190 * @returns nothing.
191 * @param hSniffer The sniffer instance to destroy.
192 */
193DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer)
194{
195 PVUSBSNIFFERINT pThis = hSniffer;
196
197 int rc = RTSemFastMutexRequest(pThis->hMtx);
198 AssertRC(rc);
199
200 pThis->pFmt->pfnDestroy((PVUSBSNIFFERFMTINT)&pThis->abFmt[0]);
201
202 if (pThis->hFile != NIL_RTFILE)
203 RTFileClose(pThis->hFile);
204
205 RTSemFastMutexRelease(pThis->hMtx);
206 RTSemFastMutexDestroy(pThis->hMtx);
207 RTMemFree(pThis);
208}
209
210/**
211 * Records an VUSB event.
212 *
213 * @returns VBox status code.
214 * @param hSniffer The sniffer instance.
215 * @param pUrb The URB triggering the event.
216 * @param enmEvent The type of event to record.
217 */
218DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
219{
220 int rc = VINF_SUCCESS;
221 PVUSBSNIFFERINT pThis = hSniffer;
222
223 /* Write the packet to the capture file. */
224 rc = RTSemFastMutexRequest(pThis->hMtx);
225 if (RT_SUCCESS(rc))
226 {
227 rc = pThis->pFmt->pfnRecordEvent((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], pUrb, enmEvent);
228 RTSemFastMutexRelease(pThis->hMtx);
229 }
230
231 return rc;
232}
233
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