VirtualBox

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

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

USB/VUSBSniffer: Separate API from format to make it possible to introduce other formats to capture the traffic in (will come next)

  • 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 59615 2016-02-09 13:08:14Z 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};
70
71
72/*********************************************************************************************************************************
73* Internal Functions *
74*********************************************************************************************************************************/
75
76/** @copydoc VUSBSNIFFERSTRM::pfnWrite. */
77static DECLCALLBACK(int) vusbSnifferStrmWrite(PVUSBSNIFFERSTRM pStrm, const void *pvBuf, size_t cbBuf)
78{
79 PVUSBSNIFFERINT pThis = RT_FROM_MEMBER(pStrm, VUSBSNIFFERINT, Strm);
80
81 return RTFileWrite(pThis->hFile, pvBuf, cbBuf, NULL);
82}
83
84/**
85 * Returns a supporting format writer taken from the given format name.
86 *
87 * @returns Pointer to the format structure or NULL if none was found.
88 * @param pszFmt The format to use.
89 */
90static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromString(const char *pszFmt)
91{
92 for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++)
93 {
94 if (!RTStrICmp(pszFmt, s_aVUsbSnifferFmts[i]->szName))
95 return s_aVUsbSnifferFmts[i];
96 }
97
98 return NULL;
99}
100
101/**
102 * Returns a supporting format writer taken from the file suffix.
103 *
104 * @returns Pointer to the format structure or NULL if none was found.
105 * @param pFilename The file name to take the suffix from.
106 */
107static PCVUSBSNIFFERFMT vusbSnifferGetFmtFromFilename(const char *pszFilename)
108{
109 const char *pszFileExt = RTPathSuffix(pszFilename);
110 if (!pszFileExt)
111 return NULL;
112
113 pszFileExt++; /* Skip the dot. */
114
115 for (unsigned i = 0; i < RT_ELEMENTS(s_aVUsbSnifferFmts); i++)
116 {
117 unsigned idxFileExt = 0;
118
119 while (s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt])
120 {
121 if (!RTStrICmp(pszFileExt, s_aVUsbSnifferFmts[i]->papszFileExts[idxFileExt]))
122 return s_aVUsbSnifferFmts[i];
123
124 idxFileExt++;
125 }
126 }
127
128 return NULL;
129}
130
131
132DECLHIDDEN(int) VUSBSnifferCreate(PVUSBSNIFFER phSniffer, uint32_t fFlags,
133 const char *pszCaptureFilename, const char *pszFmt,
134 const char *pszDesc)
135{
136 int rc = VINF_SUCCESS;
137 PVUSBSNIFFERINT pThis = NULL;
138 PCVUSBSNIFFERFMT pFmt = NULL;
139
140 if (pszFmt)
141 pFmt = vusbSnifferGetFmtFromString(pszFmt);
142 else
143 pFmt = vusbSnifferGetFmtFromFilename(pszCaptureFilename);
144
145 if (!pFmt)
146 return VERR_NOT_FOUND;
147
148 pThis = (PVUSBSNIFFERINT)RTMemAllocZ(RT_OFFSETOF(VUSBSNIFFERINT, abFmt[pFmt->cbFmt]));
149 if (pThis)
150 {
151 pThis->hFile = NIL_RTFILE;
152 pThis->hMtx = NIL_RTSEMFASTMUTEX;
153 pThis->pFmt = pFmt;
154 pThis->Strm.pfnWrite = vusbSnifferStrmWrite;
155
156 rc = RTSemFastMutexCreate(&pThis->hMtx);
157 if (RT_SUCCESS(rc))
158 {
159 rc = RTFileOpen(&pThis->hFile, pszCaptureFilename, RTFILE_O_DENY_NONE | RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_READ);
160 if (RT_SUCCESS(rc))
161 {
162 rc = pThis->pFmt->pfnInit((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], &pThis->Strm);
163 if (RT_SUCCESS(rc))
164 {
165 *phSniffer = pThis;
166 return VINF_SUCCESS;
167 }
168
169 RTFileClose(pThis->hFile);
170 pThis->hFile = NIL_RTFILE;
171 RTFileDelete(pszCaptureFilename);
172 }
173 RTSemFastMutexDestroy(pThis->hMtx);
174 pThis->hMtx = NIL_RTSEMFASTMUTEX;
175 }
176
177 RTMemFree(pThis);
178 }
179 else
180 rc = VERR_NO_MEMORY;
181
182 return rc;
183}
184
185/**
186 * Destroys the given VUSB sniffer instance.
187 *
188 * @returns nothing.
189 * @param hSniffer The sniffer instance to destroy.
190 */
191DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer)
192{
193 PVUSBSNIFFERINT pThis = hSniffer;
194
195 int rc = RTSemFastMutexRequest(pThis->hMtx);
196 AssertRC(rc);
197
198 pThis->pFmt->pfnDestroy((PVUSBSNIFFERFMTINT)&pThis->abFmt[0]);
199
200 if (pThis->hFile != NIL_RTFILE)
201 RTFileClose(pThis->hFile);
202
203 RTSemFastMutexRelease(pThis->hMtx);
204 RTSemFastMutexDestroy(pThis->hMtx);
205 RTMemFree(pThis);
206}
207
208/**
209 * Records an VUSB event.
210 *
211 * @returns VBox status code.
212 * @param hSniffer The sniffer instance.
213 * @param pUrb The URB triggering the event.
214 * @param enmEvent The type of event to record.
215 */
216DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
217{
218 int rc = VINF_SUCCESS;
219 PVUSBSNIFFERINT pThis = hSniffer;
220
221 /* Write the packet to the capture file. */
222 rc = RTSemFastMutexRequest(pThis->hMtx);
223 if (RT_SUCCESS(rc))
224 {
225 rc = pThis->pFmt->pfnRecordEvent((PVUSBSNIFFERFMTINT)&pThis->abFmt[0], pUrb, enmEvent);
226 RTSemFastMutexRelease(pThis->hMtx);
227 }
228
229 return rc;
230}
231
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