VirtualBox

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

Last change on this file since 62564 was 62463, checked in by vboxsync, 8 years ago

Devices: scm

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