VirtualBox

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

Last change on this file since 66058 was 64294, checked in by vboxsync, 8 years ago

VUSB: Doxygen fixes

  • 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 64294 2016-10-17 11:34:36Z 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/** @interface_method_impl{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 pszFilename 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 RT_NOREF(pszDesc);
140 int rc = VINF_SUCCESS;
141 PVUSBSNIFFERINT pThis = NULL;
142 PCVUSBSNIFFERFMT pFmt = NULL;
143
144 if (pszFmt)
145 pFmt = vusbSnifferGetFmtFromString(pszFmt);
146 else
147 pFmt = vusbSnifferGetFmtFromFilename(pszCaptureFilename);
148
149 if (!pFmt)
150 return VERR_NOT_FOUND;
151
152 pThis = (PVUSBSNIFFERINT)RTMemAllocZ(RT_OFFSETOF(VUSBSNIFFERINT, abFmt[pFmt->cbFmt]));
153 if (pThis)
154 {
155 pThis->hFile = NIL_RTFILE;
156 pThis->hMtx = NIL_RTSEMFASTMUTEX;
157 pThis->pFmt = pFmt;
158 pThis->Strm.pfnWrite = vusbSnifferStrmWrite;
159
160 rc = RTSemFastMutexCreate(&pThis->hMtx);
161 if (RT_SUCCESS(rc))
162 {
163 uint32_t fFileFlags = RTFILE_O_DENY_NONE | RTFILE_O_WRITE | RTFILE_O_READ;
164 if (fFlags & VUSBSNIFFER_F_NO_REPLACE)
165 fFileFlags |= RTFILE_O_CREATE;
166 else
167 fFileFlags |= RTFILE_O_CREATE_REPLACE;
168
169 rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, fFileFlags);
170 if (RT_SUCCESS(rc))
171 {
172 rc = pThis->pFmt->pfnInit((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], &pThis->Strm);
173 if (RT_SUCCESS(rc))
174 {
175 *phSniffer = pThis;
176 return VINF_SUCCESS;
177 }
178
179 RTFileClose(pThis->hFile);
180 pThis->hFile = NIL_RTFILE;
181 RTFileDelete(pszCaptureFilename);
182 }
183 RTSemFastMutexDestroy(pThis->hMtx);
184 pThis->hMtx = NIL_RTSEMFASTMUTEX;
185 }
186
187 RTMemFree(pThis);
188 }
189 else
190 rc = VERR_NO_MEMORY;
191
192 return rc;
193}
194
195/**
196 * Destroys the given VUSB sniffer instance.
197 *
198 * @returns nothing.
199 * @param hSniffer The sniffer instance to destroy.
200 */
201DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer)
202{
203 PVUSBSNIFFERINT pThis = hSniffer;
204
205 int rc = RTSemFastMutexRequest(pThis->hMtx);
206 AssertRC(rc);
207
208 pThis->pFmt->pfnDestroy((PVUSBSNIFFERFMTINT)&pThis->abFmt[0]);
209
210 if (pThis->hFile != NIL_RTFILE)
211 RTFileClose(pThis->hFile);
212
213 RTSemFastMutexRelease(pThis->hMtx);
214 RTSemFastMutexDestroy(pThis->hMtx);
215 RTMemFree(pThis);
216}
217
218/**
219 * Records an VUSB event.
220 *
221 * @returns VBox status code.
222 * @param hSniffer The sniffer instance.
223 * @param pUrb The URB triggering the event.
224 * @param enmEvent The type of event to record.
225 */
226DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
227{
228 int rc = VINF_SUCCESS;
229 PVUSBSNIFFERINT pThis = hSniffer;
230
231 /* Write the packet to the capture file. */
232 rc = RTSemFastMutexRequest(pThis->hMtx);
233 if (RT_SUCCESS(rc))
234 {
235 rc = pThis->pFmt->pfnRecordEvent((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], pUrb, enmEvent);
236 RTSemFastMutexRelease(pThis->hMtx);
237 }
238
239 return rc;
240}
241
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