From d542106f1a917ccbe53f47da1458901a75f1a03d Mon Sep 17 00:00:00 2001 From: Levente Meszaros Date: Fri, 3 May 2024 12:49:12 +0200 Subject: [PATCH] queueing: Added new PacketFlowPcapFileRecorder module. --- .../flow/PacketFlowPcapFileRecorder.cc | 66 +++++++++++++++++++ .../flow/PacketFlowPcapFileRecorder.h | 39 +++++++++++ .../flow/PacketFlowPcapFileRecorder.ned | 25 +++++++ 3 files changed, 130 insertions(+) create mode 100644 src/inet/queueing/flow/PacketFlowPcapFileRecorder.cc create mode 100644 src/inet/queueing/flow/PacketFlowPcapFileRecorder.h create mode 100644 src/inet/queueing/flow/PacketFlowPcapFileRecorder.ned diff --git a/src/inet/queueing/flow/PacketFlowPcapFileRecorder.cc b/src/inet/queueing/flow/PacketFlowPcapFileRecorder.cc new file mode 100644 index 00000000000..cf76b49d84b --- /dev/null +++ b/src/inet/queueing/flow/PacketFlowPcapFileRecorder.cc @@ -0,0 +1,66 @@ +// +// Copyright (C) 2024 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +#include "inet/queueing/flow/PacketFlowPcapFileRecorder.h" + +#include "inet/common/packet/recorder/PcapWriter.h" +#include "inet/common/packet/recorder/PcapngWriter.h" + +namespace inet { +namespace queueing { + +Define_Module(PacketFlowPcapFileRecorder); + +void PacketFlowPcapFileRecorder::initialize(int stage) +{ + PacketFlowBase::initialize(stage); + if (stage == INITSTAGE_LOCAL) { + const char *fileFormat = par("fileFormat"); + if (!strcmp(fileFormat, "pcap")) + pcapWriter = new PcapWriter(); + else if (!strcmp(fileFormat, "pcapng")) + pcapWriter = new PcapngWriter(); + else + throw cRuntimeError("Unknown fileFormat parameter"); + pcapWriter->setFlush(par("alwaysFlush")); + pcapWriter->open(par("filename"), par("snaplen"), par("timePrecision")); + networkType = static_cast(par("networkType").intValue()); + const char *dirString = par("direction"); + if (*dirString == 0) + direction = DIRECTION_UNDEFINED; + else if (!strcmp(dirString, "outbound")) + direction = DIRECTION_OUTBOUND; + else if (!strcmp(dirString, "inbound")) + direction = DIRECTION_INBOUND; + else + throw cRuntimeError("invalid direction parameter value: %s", dirString); + } +} + +cGate *PacketFlowPcapFileRecorder::getRegistrationForwardingGate(cGate *gate) +{ + if (gate == outputGate) + return inputGate; + else if (gate == inputGate) + return outputGate; + else + throw cRuntimeError("Unknown gate"); +} + +void PacketFlowPcapFileRecorder::finish() +{ + pcapWriter->close(); +} + +void PacketFlowPcapFileRecorder::processPacket(Packet *packet) +{ + pcapWriter->writePacket(simTime(), packet, direction, findContainingNicModule(this), networkType); +} + +} // namespace queueing +} // namespace inet + diff --git a/src/inet/queueing/flow/PacketFlowPcapFileRecorder.h b/src/inet/queueing/flow/PacketFlowPcapFileRecorder.h new file mode 100644 index 00000000000..466ae62bac6 --- /dev/null +++ b/src/inet/queueing/flow/PacketFlowPcapFileRecorder.h @@ -0,0 +1,39 @@ +// +// Copyright (C) 2024 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +#ifndef __INET_PACKETFLOWPCAPFILERECORDER_H +#define __INET_PACKETFLOWPCAPFILERECORDER_H + +#include "inet/common/IProtocolRegistrationListener.h" +#include "inet/common/packet/recorder/IPcapWriter.h" +#include "inet/queueing/base/PacketFlowBase.h" + +namespace inet { +namespace queueing { + +class INET_API PacketFlowPcapFileRecorder : public PacketFlowBase, public TransparentProtocolRegistrationListener +{ + protected: + IPcapWriter *pcapWriter = nullptr; + Direction direction = DIRECTION_UNDEFINED; + PcapLinkType networkType = LINKTYPE_INVALID; + + protected: + virtual void initialize(int stage) override; + virtual void finish() override; + + virtual cGate *getRegistrationForwardingGate(cGate *gate) override; + + public: + virtual void processPacket(Packet *packet) override; +}; + +} // namespace queueing +} // namespace inet + +#endif + diff --git a/src/inet/queueing/flow/PacketFlowPcapFileRecorder.ned b/src/inet/queueing/flow/PacketFlowPcapFileRecorder.ned new file mode 100644 index 00000000000..3cfc94d79d2 --- /dev/null +++ b/src/inet/queueing/flow/PacketFlowPcapFileRecorder.ned @@ -0,0 +1,25 @@ +// +// Copyright (C) 2024 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + + +package inet.queueing.flow; + +import inet.queueing.base.PacketFlowBase; +import inet.queueing.contract.IPacketFlow; + +simple PacketFlowPcapFileRecorder extends PacketFlowBase like IPacketFlow +{ + parameters: + string fileFormat @enum("pcap","pcapng") = default("pcap"); + string filename; // the PCAP file to be written + int networkType; // the network type header field in the PCAP file, see http://www.tcpdump.org/linktypes.html (1=ethernet, 204=ppp, 105=IEEE 802.11, ...) + int snaplen = default(65535); // maximum number of bytes to record per packet + int timePrecision = default(6); // Time precison in recorded file. pcap supports only 6 (usec) or 9 (nanosec), pcapng supports more values (see 'if_tsresol' option in pcapng file format). + string direction @enum(inbound, outbound); // direction flag + bool alwaysFlush = default(false); // flush the PCAP file after each write to ensure that all packets are captured in case of a crash + @class(PacketFlowPcapFileRecorder); +} +