VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/Pcap.cpp@ 28025

Last change on this file since 28025 was 28025, checked in by vboxsync, 15 years ago

intnet, VBoxNet*, network device & drivers: GSO preps.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: Pcap.cpp 28025 2010-04-07 06:37:43Z vboxsync $ */
2/** @file
3 * Helpers for writing libpcap files.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#include "Pcap.h"
26
27#include <iprt/file.h>
28#include <iprt/stream.h>
29#include <iprt/time.h>
30#include <iprt/err.h>
31#include <VBox/pdmnetinline.h>
32
33
34/*******************************************************************************
35* Structures and Typedefs *
36*******************************************************************************/
37
38/* "libpcap" magic */
39#define PCAP_MAGIC 0xa1b2c3d4
40
41/* "libpcap" file header (minus magic number). */
42struct pcap_hdr
43{
44 uint16_t version_major; /* major version number = 2 */
45 uint16_t version_minor; /* minor version number = 4 */
46 int32_t thiszone; /* GMT to local correction = 0 */
47 uint32_t sigfigs; /* accuracy of timestamps = 0 */
48 uint32_t snaplen; /* max length of captured packets, in octets = 0xffff */
49 uint32_t network; /* data link type = 01 */
50};
51
52/* "libpcap" record header. */
53struct pcaprec_hdr
54{
55 uint32_t ts_sec; /* timestamp seconds */
56 uint32_t ts_usec; /* timestamp microseconds */
57 uint32_t incl_len; /* number of octets of packet saved in file */
58 uint32_t orig_len; /* actual length of packet */
59};
60
61struct pcaprec_hdr_init
62{
63 uint32_t u32Magic;
64 struct pcap_hdr pcap;
65 struct pcaprec_hdr rec0;
66};
67
68
69/*******************************************************************************
70* Global Variables *
71*******************************************************************************/
72static pcaprec_hdr_init const s_Hdr =
73{
74 PCAP_MAGIC,
75 { 2, 4, 0, 0, 0xffff, 1 },
76 /* force ethereal to start at 0.000000. */
77 { 0, 1, 0, 60 }
78
79};
80
81
82/**
83 * Internal helper.
84 */
85static void pcapCalcHeader(struct pcaprec_hdr *pHdr, uint64_t StartNanoTS, size_t cbFrame, size_t cbMax)
86{
87 uint64_t u64TS = RTTimeNanoTS() - StartNanoTS;
88 pHdr->ts_sec = (uint32_t)(u64TS / 1000000000);
89 pHdr->ts_usec = (uint32_t)((u64TS / 1000) % 1000000);
90 pHdr->incl_len = (uint32_t)RT_MIN(cbFrame, cbMax);
91 pHdr->orig_len = (uint32_t)cbFrame;
92}
93
94
95/**
96 * Writes the stream header.
97 *
98 * @returns IPRT status code, @see RTStrmWrite.
99 *
100 * @param pStream The stream handle.
101 * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
102 */
103int PcapStreamHdr(PRTSTREAM pStream, uint64_t StartNanoTS)
104{
105 pcaprec_hdr_init Hdr = s_Hdr;
106 pcapCalcHeader(&Hdr.rec0, StartNanoTS, 60, 0);
107 return RTStrmWrite(pStream, &Hdr, sizeof(Hdr));
108}
109
110
111/**
112 * Writes a frame to a stream.
113 *
114 * @returns IPRT status code, @see RTStrmWrite.
115 *
116 * @param pStream The stream handle.
117 * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
118 * @param pvFrame The start of the frame.
119 * @param cbFrame The size of the frame.
120 * @param cbMax The max number of bytes to include in the file.
121 */
122int PcapStreamFrame(PRTSTREAM pStream, uint64_t StartNanoTS, const void *pvFrame, size_t cbFrame, size_t cbMax)
123{
124 struct pcaprec_hdr Hdr;
125 pcapCalcHeader(&Hdr, StartNanoTS, cbFrame, cbMax);
126 int rc1 = RTStrmWrite(pStream, &Hdr, sizeof(Hdr));
127 int rc2 = RTStrmWrite(pStream, pvFrame, Hdr.incl_len);
128 return RT_SUCCESS(rc1) ? rc2 : rc1;
129}
130
131
132/**
133 * Writes a GSO frame to a stream.
134 *
135 * @returns IPRT status code, @see RTStrmWrite.
136 *
137 * @param pStream The stream handle.
138 * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
139 * @param pGso Pointer to the GSO context.
140 * @param pvFrame The start of the GSO frame.
141 * @param cbFrame The size of the GSO frame.
142 * @param cbSegMax The max number of bytes to include in the file for
143 * each segment.
144 */
145int PcapStreamGsoFrame(PRTSTREAM pStream, uint64_t StartNanoTS, PCPDMNETWORKGSO pGso,
146 const void *pvFrame, size_t cbFrame, size_t cbSegMax)
147{
148 uint8_t const *pbFrame = (uint8_t const *)pvFrame;
149 uint8_t abHdrs[256];
150 uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame);
151 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
152 {
153 uint32_t cbSegPayload;
154 uint32_t offSegPayload = PDMNetGsoCarveSegment(pGso, pbFrame, cbFrame, iSeg, cSegs, abHdrs, &cbSegPayload);
155
156 struct pcaprec_hdr Hdr;
157 pcapCalcHeader(&Hdr, StartNanoTS, pGso->cbHdrs + cbSegPayload, cbSegMax);
158 int rc = RTStrmWrite(pStream, &Hdr, sizeof(Hdr));
159 if (RT_FAILURE(rc))
160 return rc;
161
162 rc = RTStrmWrite(pStream, abHdrs, RT_MIN(Hdr.incl_len, pGso->cbHdrs));
163 if (RT_SUCCESS(rc) && Hdr.incl_len > pGso->cbHdrs)
164 rc = RTStrmWrite(pStream, pbFrame + offSegPayload, Hdr.incl_len - pGso->cbHdrs);
165 if (RT_FAILURE(rc))
166 return rc;
167 }
168
169 return VINF_SUCCESS;
170}
171
172
173/**
174 * Writes the file header.
175 *
176 * @returns IPRT status code, @see RTFileWrite.
177 *
178 * @param File The file handle.
179 * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
180 */
181int PcapFileHdr(RTFILE File, uint64_t StartNanoTS)
182{
183 pcaprec_hdr_init Hdr = s_Hdr;
184 pcapCalcHeader(&Hdr.rec0, StartNanoTS, 60, 0);
185 return RTFileWrite(File, &Hdr, sizeof(Hdr), NULL);
186}
187
188
189/**
190 * Writes a frame to a file.
191 *
192 * @returns IPRT status code, @see RTFileWrite.
193 *
194 * @param File The file handle.
195 * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
196 * @param pvFrame The start of the frame.
197 * @param cbFrame The size of the frame.
198 * @param cbMax The max number of bytes to include in the file.
199 */
200int PcapFileFrame(RTFILE File, uint64_t StartNanoTS, const void *pvFrame, size_t cbFrame, size_t cbMax)
201{
202 struct pcaprec_hdr Hdr;
203 pcapCalcHeader(&Hdr, StartNanoTS, cbFrame, cbMax);
204 int rc1 = RTFileWrite(File, &Hdr, sizeof(Hdr), NULL);
205 int rc2 = RTFileWrite(File, pvFrame, Hdr.incl_len, NULL);
206 return RT_SUCCESS(rc1) ? rc2 : rc1;
207}
208
209
210/**
211 * Writes a GSO frame to a file.
212 *
213 * @returns IPRT status code, @see RTFileWrite.
214 *
215 * @param File The file handle.
216 * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
217 * @param pGso Pointer to the GSO context.
218 * @param pvFrame The start of the GSO frame.
219 * @param cbFrame The size of the GSO frame.
220 * @param cbSegMax The max number of bytes to include in the file for
221 * each segment.
222 */
223int PcapFileGsoFrame(RTFILE File, uint64_t StartNanoTS, PCPDMNETWORKGSO pGso,
224 const void *pvFrame, size_t cbFrame, size_t cbSegMax)
225{
226 uint8_t const *pbFrame = (uint8_t const *)pvFrame;
227 uint8_t abHdrs[256];
228 uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame);
229 for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
230 {
231 uint32_t cbSegPayload;
232 uint32_t offSegPayload = PDMNetGsoCarveSegment(pGso, pbFrame, cbFrame, iSeg, cSegs, abHdrs, &cbSegPayload);
233
234 struct pcaprec_hdr Hdr;
235 pcapCalcHeader(&Hdr, StartNanoTS, pGso->cbHdrs + cbSegPayload, cbSegMax);
236 int rc = RTFileWrite(File, &Hdr, sizeof(Hdr), NULL);
237 if (RT_FAILURE(rc))
238 return rc;
239
240 rc = RTFileWrite(File, abHdrs, RT_MIN(Hdr.incl_len, pGso->cbHdrs), NULL);
241 if (RT_SUCCESS(rc) && Hdr.incl_len > pGso->cbHdrs)
242 rc = RTFileWrite(File, pbFrame + offSegPayload, Hdr.incl_len - pGso->cbHdrs, NULL);
243 if (RT_FAILURE(rc))
244 return rc;
245 }
246
247 return VINF_SUCCESS;
248}
249
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