summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Network/Pcap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Network/Pcap.cpp')
-rw-r--r--src/VBox/Devices/Network/Pcap.cpp105
1 files changed, 99 insertions, 6 deletions
diff --git a/src/VBox/Devices/Network/Pcap.cpp b/src/VBox/Devices/Network/Pcap.cpp
index 7f1ecfe49..f6f9a7645 100644
--- a/src/VBox/Devices/Network/Pcap.cpp
+++ b/src/VBox/Devices/Network/Pcap.cpp
@@ -1,10 +1,10 @@
-/* $Id: Pcap.cpp $ */
+/* $Id: Pcap.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
/** @file
* Helpers for writing libpcap files.
*/
/*
- * Copyright (C) 2006-2008 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,10 +13,6 @@
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
*/
/*******************************************************************************
@@ -28,6 +24,7 @@
#include <iprt/stream.h>
#include <iprt/time.h>
#include <iprt/err.h>
+#include <VBox/pdmnetinline.h>
/*******************************************************************************
@@ -92,6 +89,16 @@ static void pcapCalcHeader(struct pcaprec_hdr *pHdr, uint64_t StartNanoTS, size_
/**
+ * Internal helper.
+ */
+static void pcapUpdateHeader(struct pcaprec_hdr *pHdr, size_t cbFrame, size_t cbMax)
+{
+ pHdr->incl_len = (uint32_t)RT_MIN(cbFrame, cbMax);
+ pHdr->orig_len = (uint32_t)cbFrame;
+}
+
+
+/**
* Writes the stream header.
*
* @returns IPRT status code, @see RTStrmWrite.
@@ -129,6 +136,49 @@ int PcapStreamFrame(PRTSTREAM pStream, uint64_t StartNanoTS, const void *pvFrame
/**
+ * Writes a GSO frame to a stream.
+ *
+ * @returns IPRT status code, @see RTStrmWrite.
+ *
+ * @param pStream The stream handle.
+ * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
+ * @param pGso Pointer to the GSO context.
+ * @param pvFrame The start of the GSO frame.
+ * @param cbFrame The size of the GSO frame.
+ * @param cbSegMax The max number of bytes to include in the file for
+ * each segment.
+ */
+int PcapStreamGsoFrame(PRTSTREAM pStream, uint64_t StartNanoTS, PCPDMNETWORKGSO pGso,
+ const void *pvFrame, size_t cbFrame, size_t cbSegMax)
+{
+ struct pcaprec_hdr Hdr;
+ pcapCalcHeader(&Hdr, StartNanoTS, 0, 0);
+
+ uint8_t const *pbFrame = (uint8_t const *)pvFrame;
+ uint8_t abHdrs[256];
+ uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame);
+ for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
+ {
+ uint32_t cbSegPayload;
+ uint32_t offSegPayload = PDMNetGsoCarveSegment(pGso, pbFrame, cbFrame, iSeg, cSegs, abHdrs, &cbSegPayload);
+
+ pcapUpdateHeader(&Hdr, pGso->cbHdrs + cbSegPayload, cbSegMax);
+ int rc = RTStrmWrite(pStream, &Hdr, sizeof(Hdr));
+ if (RT_FAILURE(rc))
+ return rc;
+
+ rc = RTStrmWrite(pStream, abHdrs, RT_MIN(Hdr.incl_len, pGso->cbHdrs));
+ if (RT_SUCCESS(rc) && Hdr.incl_len > pGso->cbHdrs)
+ rc = RTStrmWrite(pStream, pbFrame + offSegPayload, Hdr.incl_len - pGso->cbHdrs);
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
* Writes the file header.
*
* @returns IPRT status code, @see RTFileWrite.
@@ -164,3 +214,46 @@ int PcapFileFrame(RTFILE File, uint64_t StartNanoTS, const void *pvFrame, size_t
return RT_SUCCESS(rc1) ? rc2 : rc1;
}
+
+/**
+ * Writes a GSO frame to a file.
+ *
+ * @returns IPRT status code, @see RTFileWrite.
+ *
+ * @param File The file handle.
+ * @param StartNanoTS What to subtract from the RTTimeNanoTS output.
+ * @param pGso Pointer to the GSO context.
+ * @param pvFrame The start of the GSO frame.
+ * @param cbFrame The size of the GSO frame.
+ * @param cbSegMax The max number of bytes to include in the file for
+ * each segment.
+ */
+int PcapFileGsoFrame(RTFILE File, uint64_t StartNanoTS, PCPDMNETWORKGSO pGso,
+ const void *pvFrame, size_t cbFrame, size_t cbSegMax)
+{
+ struct pcaprec_hdr Hdr;
+ pcapCalcHeader(&Hdr, StartNanoTS, 0, 0);
+
+ uint8_t const *pbFrame = (uint8_t const *)pvFrame;
+ uint8_t abHdrs[256];
+ uint32_t const cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame);
+ for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
+ {
+ uint32_t cbSegPayload;
+ uint32_t offSegPayload = PDMNetGsoCarveSegment(pGso, pbFrame, cbFrame, iSeg, cSegs, abHdrs, &cbSegPayload);
+
+ pcapUpdateHeader(&Hdr, pGso->cbHdrs + cbSegPayload, cbSegMax);
+ int rc = RTFileWrite(File, &Hdr, sizeof(Hdr), NULL);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ rc = RTFileWrite(File, abHdrs, RT_MIN(Hdr.incl_len, pGso->cbHdrs), NULL);
+ if (RT_SUCCESS(rc) && Hdr.incl_len > pGso->cbHdrs)
+ rc = RTFileWrite(File, pbFrame + offSegPayload, Hdr.incl_len - pGso->cbHdrs, NULL);
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+
+ return VINF_SUCCESS;
+}
+