VirtualBox

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

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

VUSBSniffer: Add flag to avoid overwriting exitisting captures, compiler warnings

  • 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 59686 2016-02-15 17:01:24Z 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 uint32_t fFileFlags = RTFILE_O_DENY_NONE | RTFILE_O_WRITE | RTFILE_O_READ;
162 if (fFlags & VUSBSNIFFER_F_NO_REPLACE)
163 fFileFlags |= RTFILE_O_CREATE;
164 else
165 fFileFlags |= RTFILE_O_CREATE_REPLACE;
166
167 rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, fFileFlags);
168 if (RT_SUCCESS(rc))
169 {
170 rc = pThis->pFmt->pfnInit((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], &pThis->Strm);
171 if (RT_SUCCESS(rc))
172 {
173 *phSniffer = pThis;
174 return VINF_SUCCESS;
175 }
176
177 RTFileClose(pThis->hFile);
178 pThis->hFile = NIL_RTFILE;
179 RTFileDelete(pszCaptureFilename);
180 }
181 RTSemFastMutexDestroy(pThis->hMtx);
182 pThis->hMtx = NIL_RTSEMFASTMUTEX;
183 }
184
185 RTMemFree(pThis);
186 }
187 else
188 rc = VERR_NO_MEMORY;
189
190 return rc;
191}
192
193/**
194 * Destroys the given VUSB sniffer instance.
195 *
196 * @returns nothing.
197 * @param hSniffer The sniffer instance to destroy.
198 */
199DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer)
200{
201 PVUSBSNIFFERINT pThis = hSniffer;
202
203 int rc = RTSemFastMutexRequest(pThis->hMtx);
204 AssertRC(rc);
205
206 pThis->pFmt->pfnDestroy((PVUSBSNIFFERFMTINT)&pThis->abFmt[0]);
207
208 if (pThis->hFile != NIL_RTFILE)
209 RTFileClose(pThis->hFile);
210
211 RTSemFastMutexRelease(pThis->hMtx);
212 RTSemFastMutexDestroy(pThis->hMtx);
213 RTMemFree(pThis);
214}
215
216/**
217 * Records an VUSB event.
218 *
219 * @returns VBox status code.
220 * @param hSniffer The sniffer instance.
221 * @param pUrb The URB triggering the event.
222 * @param enmEvent The type of event to record.
223 */
224DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
225{
226 int rc = VINF_SUCCESS;
227 PVUSBSNIFFERINT pThis = hSniffer;
228
229 /* Write the packet to the capture file. */
230 rc = RTSemFastMutexRequest(pThis->hMtx);
231 if (RT_SUCCESS(rc))
232 {
233 rc = pThis->pFmt->pfnRecordEvent((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], pUrb, enmEvent);
234 RTSemFastMutexRelease(pThis->hMtx);
235 }
236
237 return rc;
238}
239
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