From d0b42cd75662d68d721c188f9f1ad5cab2014716 Mon Sep 17 00:00:00 2001 From: "mert.ozer" Date: Sun, 14 Apr 2024 16:23:25 +0300 Subject: [PATCH] Port tutorial codes to C++11, fixing issue #977 partially --- .../Tutorials/Tutorial-DpdkL2Fwd/main.cpp | 66 +++------- .../Tutorials/Tutorial-HelloWorld/main.cpp | 11 +- .../Tutorials/Tutorial-LiveTraffic/main.cpp | 120 +++++++++--------- .../Tutorial-PacketCraftAndEdit/main.cpp | 31 +++-- .../Tutorials/Tutorial-PacketParsing/main.cpp | 107 +++++++--------- .../Tutorials/Tutorial-PcapFiles/main.cpp | 29 +++-- 6 files changed, 162 insertions(+), 202 deletions(-) diff --git a/Examples/Tutorials/Tutorial-DpdkL2Fwd/main.cpp b/Examples/Tutorials/Tutorial-DpdkL2Fwd/main.cpp index 4f9ceecc2c..20b0d3b1c1 100644 --- a/Examples/Tutorials/Tutorial-DpdkL2Fwd/main.cpp +++ b/Examples/Tutorials/Tutorial-DpdkL2Fwd/main.cpp @@ -4,47 +4,31 @@ #include "SystemUtils.h" #include "DpdkDeviceList.h" #include "TablePrinter.h" - #include "WorkerThread.h" - #define MBUF_POOL_SIZE 16*1024-1 #define DEVICE_ID_1 0 #define DEVICE_ID_2 1 - #define COLLECT_STATS_EVERY_SEC 2 - // Keep running flag bool keepRunning = true; void onApplicationInterrupted(void* cookie) { keepRunning = false; - std::cout << std::endl << "Shutting down..." << std::endl; + std::cout << "\nShutting down...\n"; } void printStats(pcpp::DpdkDevice* rxDevice, pcpp::DpdkDevice* txDevice) { - pcpp::DpdkDevice::DpdkDeviceStats rxStats; - pcpp::DpdkDevice::DpdkDeviceStats txStats; + pcpp::DpdkDevice::DpdkDeviceStats rxStats, txStats; rxDevice->getStatistics(rxStats); txDevice->getStatistics(txStats); - std::vector columnNames; - columnNames.push_back(" "); - columnNames.push_back("Total Packets"); - columnNames.push_back("Packets/sec"); - columnNames.push_back("Bytes"); - columnNames.push_back("Bits/sec"); - - std::vector columnLengths; - columnLengths.push_back(10); - columnLengths.push_back(15); - columnLengths.push_back(15); - columnLengths.push_back(15); - columnLengths.push_back(15); + std::vector columnNames = {" ", "Total Packets", "Packets/sec", "Bytes", "Bits/sec"}; + std::vector columnLengths = {10, 15, 15, 15, 15}; pcpp::TablePrinter printer(columnNames, columnLengths); @@ -68,49 +52,46 @@ int main(int argc, char* argv[]) pcpp::DpdkDeviceList::initDpdk(coreMaskToUse, MBUF_POOL_SIZE); // Find DPDK devices - pcpp::DpdkDevice* device1 = pcpp::DpdkDeviceList::getInstance().getDeviceByPort(DEVICE_ID_1); - if (device1 == NULL) + auto* device1 = pcpp::DpdkDeviceList::getInstance().getDeviceByPort(DEVICE_ID_1); + if (device1 == nullptr) { - std::cerr << "Cannot find device1 with port '" << DEVICE_ID_1 << "'" << std::endl; + std::cerr << "Cannot find device1 with port '" << DEVICE_ID_1 << "'\n"; return 1; } - pcpp::DpdkDevice* device2 = pcpp::DpdkDeviceList::getInstance().getDeviceByPort(DEVICE_ID_2); - if (device2 == NULL) + auto* device2 = pcpp::DpdkDeviceList::getInstance().getDeviceByPort(DEVICE_ID_2); + if (device2 == nullptr) { - std::cerr << "Cannot find device2 with port '" << DEVICE_ID_2 << "'" << std::endl; + std::cerr << "Cannot find device2 with port '" << DEVICE_ID_2 << "'\n"; return 1; } // Open DPDK devices if (!device1->openMultiQueues(1, 1)) { - std::cerr << "Couldn't open device1 #" << device1->getDeviceId() << ", PMD '" << device1->getPMDName() << "'" << std::endl; + std::cerr << "Couldn't open device1 #" << device1->getDeviceId() << ", PMD '" << device1->getPMDName() << "'\n"; return 1; } if (!device2->openMultiQueues(1, 1)) { - std::cerr << "Couldn't open device2 #" << device2->getDeviceId() << ", PMD '" << device2->getPMDName() << "'" << std::endl; + std::cerr << "Couldn't open device2 #" << device2->getDeviceId() << ", PMD '" << device2->getPMDName() << "'\n"; return 1; } // Create worker threads std::vector workers; - workers.push_back(new L2FwdWorkerThread(device1, device2)); - workers.push_back(new L2FwdWorkerThread(device2, device1)); + // Constructs a DpdkWorkerThread* directly within the vector's storage + workers.emplace_back(new L2FwdWorkerThread(device1, device2)); + workers.emplace_back(new L2FwdWorkerThread(device2, device1)); // Create core mask - use core 1 and 2 for the two threads - int workersCoreMask = 0; - for (int i = 1; i <= 2; i++) - { - workersCoreMask = workersCoreMask | (1 << i); - } + int workersCoreMask = 0x06; // Binary 110, using cores 1 and 2 // Start capture in async mode if (!pcpp::DpdkDeviceList::getInstance().startDpdkWorkerThreads(workersCoreMask, workers)) { - std::cerr << "Couldn't start worker threads" << std::endl; + std::cerr << "Couldn't start worker threads\n"; return 1; } @@ -129,21 +110,14 @@ int main(int argc, char* argv[]) // Clear screen and move to top left std::cout << "\033[2J\033[1;1H"; - std::cout - << "Stats #" << statsCounter++ << std::endl - << "==========" << std::endl - << std::endl; + std::cout << "Stats #" << statsCounter++ << "\n==========\n\n"; // Print stats of traffic going from Device1 to Device2 - std::cout << std::endl - << "Device1->Device2 stats:" << std::endl - << std::endl; + std::cout << "\nDevice1->Device2 stats:\n\n"; printStats(device1, device2); // Print stats of traffic going from Device2 to Device1 - std::cout << std::endl - << "Device2->Device1 stats:" << std::endl - << std::endl; + std::cout << "\nDevice2->Device1 stats:\n\n"; printStats(device2, device1); } counter++; diff --git a/Examples/Tutorials/Tutorial-HelloWorld/main.cpp b/Examples/Tutorials/Tutorial-HelloWorld/main.cpp index fcad0e09fb..168f2d74a0 100644 --- a/Examples/Tutorials/Tutorial-HelloWorld/main.cpp +++ b/Examples/Tutorials/Tutorial-HelloWorld/main.cpp @@ -9,7 +9,7 @@ int main(int argc, char* argv[]) pcpp::PcapFileReaderDevice reader("1_packet.pcap"); if (!reader.open()) { - std::cerr << "Error opening the pcap file" << std::endl; + std::cerr << "Error opening the pcap file\n"; return 1; } @@ -17,7 +17,7 @@ int main(int argc, char* argv[]) pcpp::RawPacket rawPacket; if (!reader.getNextPacket(rawPacket)) { - std::cerr << "Couldn't read the first packet in the file" << std::endl; + std::cerr << "Couldn't read the first packet in the file\n"; return 1; } @@ -28,14 +28,13 @@ int main(int argc, char* argv[]) if (parsedPacket.isPacketOfType(pcpp::IPv4)) { // extract source and dest IPs - pcpp::IPv4Address srcIP = parsedPacket.getLayerOfType()->getSrcIPv4Address(); - pcpp::IPv4Address destIP = parsedPacket.getLayerOfType()->getDstIPv4Address(); + auto srcIP = parsedPacket.getLayerOfType()->getSrcIPv4Address(); + auto destIP = parsedPacket.getLayerOfType()->getDstIPv4Address(); // print source and dest IPs std::cout << "Source IP is '" << srcIP << "'; " - << "Dest IP is '" << destIP << "'" - << std::endl; + << "Dest IP is '" << destIP << "'\n"; } // close the file diff --git a/Examples/Tutorials/Tutorial-LiveTraffic/main.cpp b/Examples/Tutorials/Tutorial-LiveTraffic/main.cpp index 834a397872..28a8599770 100644 --- a/Examples/Tutorials/Tutorial-LiveTraffic/main.cpp +++ b/Examples/Tutorials/Tutorial-LiveTraffic/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "stdlib.h" #include "PcapLiveDeviceList.h" #include "SystemUtils.h" @@ -7,25 +8,23 @@ */ struct PacketStats { - int ethPacketCount; - int ipv4PacketCount; - int ipv6PacketCount; - int tcpPacketCount; - int udpPacketCount; - int dnsPacketCount; - int httpPacketCount; - int sslPacketCount; + int ethPacketCount = 0; + int ipv4PacketCount = 0; + int ipv6PacketCount = 0; + int tcpPacketCount = 0; + int udpPacketCount = 0; + int dnsPacketCount = 0; + int httpPacketCount = 0; + int sslPacketCount = 0; /** * Clear all stats */ - void clear() { ethPacketCount = 0; ipv4PacketCount = 0; ipv6PacketCount = 0; tcpPacketCount = 0; udpPacketCount = 0; tcpPacketCount = 0; dnsPacketCount = 0; httpPacketCount = 0; sslPacketCount = 0; } + void clear() { ethPacketCount = ipv4PacketCount = ipv6PacketCount = tcpPacketCount = udpPacketCount = dnsPacketCount = httpPacketCount = sslPacketCount = 0; } - /** - * C'tor - */ - PacketStats() { clear(); } + // Constructor is optional here since the members are already initialized + PacketStats() = default; /** * Collect stats from a packet @@ -55,15 +54,14 @@ struct PacketStats */ void printToConsole() { - std::cout - << "Ethernet packet count: " << ethPacketCount << std::endl - << "IPv4 packet count: " << ipv4PacketCount << std::endl - << "IPv6 packet count: " << ipv6PacketCount << std::endl - << "TCP packet count: " << tcpPacketCount << std::endl - << "UDP packet count: " << udpPacketCount << std::endl - << "DNS packet count: " << dnsPacketCount << std::endl - << "HTTP packet count: " << httpPacketCount << std::endl - << "SSL packet count: " << sslPacketCount << std::endl; + std::cout << "Ethernet packet count: " << ethPacketCount << "\n" + << "IPv4 packet count: " << ipv4PacketCount << "\n" + << "IPv6 packet count: " << ipv6PacketCount << "\n" + << "TCP packet count: " << tcpPacketCount << "\n" + << "UDP packet count: " << udpPacketCount << "\n" + << "DNS packet count: " << dnsPacketCount << "\n" + << "HTTP packet count: " << httpPacketCount << "\n" + << "SSL packet count: " << sslPacketCount << "\n"; } }; @@ -74,7 +72,7 @@ struct PacketStats static void onPacketArrives(pcpp::RawPacket* packet, pcpp::PcapLiveDevice* dev, void* cookie) { // extract the stats object form the cookie - PacketStats* stats = (PacketStats*)cookie; + auto* stats = static_cast(cookie); // parsed the raw packet pcpp::Packet parsedPacket(packet); @@ -90,7 +88,7 @@ static void onPacketArrives(pcpp::RawPacket* packet, pcpp::PcapLiveDevice* dev, static bool onPacketArrivesBlockingMode(pcpp::RawPacket* packet, pcpp::PcapLiveDevice* dev, void* cookie) { // extract the stats object form the cookie - PacketStats* stats = (PacketStats*)cookie; + auto* stats = static_cast(cookie); // parsed the raw packet pcpp::Packet parsedPacket(packet); @@ -112,10 +110,10 @@ int main(int argc, char* argv[]) std::string interfaceIPAddr = "10.0.0.1"; // find the interface by IP address - pcpp::PcapLiveDevice* dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(interfaceIPAddr); + auto* dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(interfaceIPAddr); if (dev == nullptr) { - std::cerr << "Cannot find interface with IPv4 address of '" << interfaceIPAddr << "'" << std::endl; + std::cerr << "Cannot find interface with IPv4 address of '" << interfaceIPAddr << "'\n"; return 1; } @@ -124,20 +122,20 @@ int main(int argc, char* argv[]) // before capturing packets let's print some info about this interface std::cout - << "Interface info:" << std::endl - << " Interface name: " << dev->getName() << std::endl // get interface name - << " Interface description: " << dev->getDesc() << std::endl // get interface description - << " MAC address: " << dev->getMacAddress() << std::endl // get interface MAC address - << " Default gateway: " << dev->getDefaultGateway() << std::endl // get default gateway - << " Interface MTU: " << dev->getMtu() << std::endl; // get interface MTU + << "Interface info:\n" + << " Interface name: " << dev->getName() << "\n" // get interface name + << " Interface description: " << dev->getDesc() << "\n" // get interface description + << " MAC address: " << dev->getMacAddress() << "\n" // get interface MAC address + << " Default gateway: " << dev->getDefaultGateway() << "\n" // get default gateway + << " Interface MTU: " << dev->getMtu() << "\n"; // get interface MTU - if (dev->getDnsServers().size() > 0) - std::cout << " DNS server: " << dev->getDnsServers().at(0) << std::endl; + if (!dev->getDnsServers().empty()) + std::cout << " DNS server: " << dev->getDnsServers().front() << "\n"; // open the device before start capturing/sending packets if (!dev->open()) { - std::cerr << "Cannot open device" << std::endl; + std::cerr << "Cannot open device\n"; return 1; } @@ -148,7 +146,7 @@ int main(int argc, char* argv[]) // Async packet capture with a callback function // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - std::cout << std::endl << "Starting async capture..." << std::endl; + std::cout << "\nStarting async capture...\n"; // start capture in async mode. Give a callback function to call to whenever a packet is captured and the stats object as the cookie dev->startCapture(onPacketArrives, &stats); @@ -160,7 +158,7 @@ int main(int argc, char* argv[]) dev->stopCapture(); // print results - std::cout << "Results:" << std::endl; + std::cout << "Results:\n"; stats.printToConsole(); // clear stats @@ -170,7 +168,7 @@ int main(int argc, char* argv[]) // Capturing packets in a packet vector // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - std::cout << std::endl << "Starting capture with packet vector..." << std::endl; + std::cout << "\nStarting capture with packet vector...\n"; // create an empty packet vector object pcpp::RawPacketVector packetVec; @@ -185,17 +183,13 @@ int main(int argc, char* argv[]) dev->stopCapture(); // go over the packet vector and feed all packets to the stats object - for (pcpp::RawPacketVector::ConstVectorIterator iter = packetVec.begin(); iter != packetVec.end(); iter++) - { - // parse raw packet - pcpp::Packet parsedPacket(*iter); - - // feed packet to the stats object - stats.consumePacket(parsedPacket); - } + for (const auto& packet : packetVec) { + pcpp::Packet parsedPacket(packet); + stats.consumePacket(parsedPacket); + } // print results - std::cout << "Results:" << std::endl; + std::cout << "Results:\n"; stats.printToConsole(); // clear stats @@ -205,7 +199,7 @@ int main(int argc, char* argv[]) // Capturing packets in blocking mode // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - std::cout << std::endl << "Starting capture in blocking mode..." << std::endl; + std::cout << "\nStarting capture in blocking mode...\n"; // start capturing in blocking mode. Give a callback function to call to whenever a packet is captured, the stats object as the cookie and a 10 seconds timeout dev->startCaptureBlockingMode(onPacketArrivesBlockingMode, &stats, 10); @@ -213,7 +207,7 @@ int main(int argc, char* argv[]) // thread is blocked until capture is finished // capture is finished, print results - std::cout << "Results:" << std::endl; + std::cout << "Results:\n"; stats.printToConsole(); stats.clear(); @@ -222,30 +216,30 @@ int main(int argc, char* argv[]) // Sending single packets // ~~~~~~~~~~~~~~~~~~~~~~ - std::cout << std::endl << "Sending " << packetVec.size() << " packets one by one..." << std::endl; + std::cout << "\nSending " << packetVec.size() << " packets one by one...\n"; // go over the vector of packets and send them one by one - for (pcpp::RawPacketVector::ConstVectorIterator iter = packetVec.begin(); iter != packetVec.end(); iter++) - { - // send the packet. If fails exit the application - if (!dev->sendPacket(**iter)) - { - std::cerr << "Couldn't send packet" << std::endl; - return 1; - } + bool allSent = std::all_of(packetVec.begin(), packetVec.end(), [dev](const auto& packet) { + return dev->sendPacket(*packet); + }); + + if (!allSent) { + std::cerr << "Couldn't send packet\n"; + return 1; } - std::cout << packetVec.size() << " packets sent" << std::endl; + + std::cout << packetVec.size() << " packets sent\n"; // Sending batch of packets // ~~~~~~~~~~~~~~~~~~~~~~~~ - std::cout << std::endl << "Sending " << packetVec.size() << " packets..." << std::endl; + std::cout << "\nSending " << packetVec.size() << " packets...\n"; // send all packets in the vector. The returned number shows how many packets were actually sent (expected to be equal to vector size) int packetsSent = dev->sendPackets(packetVec); - std::cout << packetsSent << " packets sent" << std::endl; + std::cout << packetsSent << " packets sent\n"; // Using filters @@ -265,7 +259,7 @@ int main(int argc, char* argv[]) // set the filter on the device dev->setFilter(andFilter); - std::cout << std::endl << "Starting packet capture with a filter in place..." << std::endl; + std::cout << "\nStarting packet capture with a filter in place...\n"; // start capture in async mode. Give a callback function to call to whenever a packet is captured and the stats object as the cookie dev->startCapture(onPacketArrives, &stats); @@ -277,7 +271,7 @@ int main(int argc, char* argv[]) dev->stopCapture(); // print results - should capture only packets which match the filter (which is TCP port 80) - std::cout << "Results:" << std::endl; + std::cout << "Results:\n"; stats.printToConsole(); diff --git a/Examples/Tutorials/Tutorial-PacketCraftAndEdit/main.cpp b/Examples/Tutorials/Tutorial-PacketCraftAndEdit/main.cpp index 54d71ffb34..6a8591bad5 100644 --- a/Examples/Tutorials/Tutorial-PacketCraftAndEdit/main.cpp +++ b/Examples/Tutorials/Tutorial-PacketCraftAndEdit/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "stdlib.h" #include "SystemUtils.h" #include "Packet.h" @@ -18,19 +19,19 @@ int main(int argc, char* argv[]) // use the IFileReaderDevice interface to automatically identify file type (pcap/pcap-ng) // and create an interface instance that both readers implement - pcpp::IFileReaderDevice* reader = pcpp::IFileReaderDevice::getReader("1_http_packet.pcap"); + std::unique_ptr reader(pcpp::IFileReaderDevice::getReader("1_http_packet.pcap")); // verify that a reader interface was indeed created if (reader == nullptr) { - std::cerr << "Cannot determine reader for file type" << std::endl; + std::cerr << "Cannot determine reader for file type\n"; return 1; } // open the reader for reading if (!reader->open()) { - std::cerr << "Cannot open input.pcap for reading" << std::endl; + std::cerr << "Cannot open input.pcap for reading\n"; return 1; } @@ -38,7 +39,7 @@ int main(int argc, char* argv[]) pcpp::RawPacket rawPacket; if (!reader->getNextPacket(rawPacket)) { - std::cerr << "Couldn't read the first packet in the file" << std::endl; + std::cerr << "Couldn't read the first packet in the file\n"; return 1; } @@ -49,12 +50,12 @@ int main(int argc, char* argv[]) pcpp::Packet parsedPacket(&rawPacket); // now let's get the Ethernet layer - pcpp::EthLayer* ethernetLayer = parsedPacket.getLayerOfType(); + auto* ethernetLayer = parsedPacket.getLayerOfType(); // change the source dest MAC address ethernetLayer->setDestMac(pcpp::MacAddress("aa:bb:cc:dd:ee:ff")); // let's get the IPv4 layer - pcpp::IPv4Layer* ipLayer = parsedPacket.getLayerOfType(); + auto* ipLayer = parsedPacket.getLayerOfType(); // change source IP address ipLayer->setSrcIPv4Address(pcpp::IPv4Address("1.1.1.1")); // change IP ID @@ -63,7 +64,7 @@ int main(int argc, char* argv[]) ipLayer->getIPv4Header()->timeToLive = 12; // let's get the TCP layer - pcpp::TcpLayer* tcpLayer = parsedPacket.getLayerOfType(); + auto* tcpLayer = parsedPacket.getLayerOfType(); // change source port tcpLayer->getTcpHeader()->portSrc = pcpp::hostToNet16(12345); // add URG flag @@ -72,7 +73,7 @@ int main(int argc, char* argv[]) tcpLayer->addTcpOptionAfter(pcpp::TcpOptionBuilder(pcpp::TCPOPT_MSS, (uint16_t)1460)); // let's get the HTTP layer - pcpp::HttpRequestLayer* httpRequestLayer = parsedPacket.getLayerOfType(); + auto* httpRequestLayer = parsedPacket.getLayerOfType(); // change the request method from GET to TRACE httpRequestLayer->getFirstLine()->setMethod(pcpp::HttpRequestLayer::HttpTRACE); // change host to www.google.com @@ -97,9 +98,10 @@ int main(int argc, char* argv[]) // write the modified packet to a pcap file pcpp::PcapFileWriterDevice writer("1_modified_packet.pcap"); - writer.open(); - writer.writePacket(*(parsedPacket.getRawPacket())); - writer.close(); + if (writer.open()) { + writer.writePacket(*(parsedPacket.getRawPacket())); + writer.close(); + } // Packet Creation @@ -134,7 +136,8 @@ int main(int argc, char* argv[]) // write the new packet to a pcap file pcpp::PcapFileWriterDevice writer2("1_new_packet.pcap"); - writer2.open(); - writer2.writePacket(*(newPacket.getRawPacket())); - writer2.close(); + if (writer2.open()) { + writer2.writePacket(*(newPacket.getRawPacket())); + writer2.close(); + } } diff --git a/Examples/Tutorials/Tutorial-PacketParsing/main.cpp b/Examples/Tutorials/Tutorial-PacketParsing/main.cpp index 15280ffef0..07487bd094 100644 --- a/Examples/Tutorials/Tutorial-PacketParsing/main.cpp +++ b/Examples/Tutorials/Tutorial-PacketParsing/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "stdlib.h" #include "SystemUtils.h" #include "Packet.h" @@ -28,25 +29,17 @@ std::string getProtocolTypeAsString(pcpp::ProtocolType protocolType) std::string printTcpFlags(pcpp::TcpLayer* tcpLayer) { - std::string result = ""; - if (tcpLayer->getTcpHeader()->synFlag == 1) - result += "SYN "; - if (tcpLayer->getTcpHeader()->ackFlag == 1) - result += "ACK "; - if (tcpLayer->getTcpHeader()->pshFlag == 1) - result += "PSH "; - if (tcpLayer->getTcpHeader()->cwrFlag == 1) - result += "CWR "; - if (tcpLayer->getTcpHeader()->urgFlag == 1) - result += "URG "; - if (tcpLayer->getTcpHeader()->eceFlag == 1) - result += "ECE "; - if (tcpLayer->getTcpHeader()->rstFlag == 1) - result += "RST "; - if (tcpLayer->getTcpHeader()->finFlag == 1) - result += "FIN "; - - return result; + std::string result; + auto* tcpHeader = tcpLayer->getTcpHeader(); + if (tcpHeader->synFlag) result += "SYN "; + if (tcpHeader->ackFlag) result += "ACK "; + if (tcpHeader->pshFlag) result += "PSH "; + if (tcpHeader->cwrFlag) result += "CWR "; + if (tcpHeader->urgFlag) result += "URG "; + if (tcpHeader->eceFlag) result += "ECE "; + if (tcpHeader->rstFlag) result += "RST "; + if (tcpHeader->finFlag) result += "FIN "; + return result; } std::string printTcpOptionType(pcpp::TcpOptionType optionType) @@ -79,19 +72,19 @@ int main(int argc, char* argv[]) { // use the IFileReaderDevice interface to automatically identify file type (pcap/pcap-ng) // and create an interface instance that both readers implement - pcpp::IFileReaderDevice* reader = pcpp::IFileReaderDevice::getReader("1_http_packet.pcap"); + std::unique_ptr reader(pcpp::IFileReaderDevice::getReader("1_http_packet.pcap")); // verify that a reader interface was indeed created if (reader == nullptr) { - std::cerr << "Cannot determine reader for file type" << std::endl; + std::cerr << "Cannot determine reader for file type\n"; return 1; } // open the reader for reading if (!reader->open()) { - std::cerr << "Cannot open input.pcap for reading" << std::endl; + std::cerr << "Cannot open input.pcap for reading\n"; return 1; } @@ -99,7 +92,7 @@ int main(int argc, char* argv[]) pcpp::RawPacket rawPacket; if (!reader->getNextPacket(rawPacket)) { - std::cerr << "Couldn't read the first packet in the file" << std::endl; + std::cerr << "Couldn't read the first packet in the file\n"; return 1; } @@ -110,86 +103,76 @@ int main(int argc, char* argv[]) pcpp::Packet parsedPacket(&rawPacket); // first let's go over the layers one by one and find out its type, its total length, its header length and its payload length - for (pcpp::Layer* curLayer = parsedPacket.getFirstLayer(); curLayer != nullptr; curLayer = curLayer->getNextLayer()) + for (auto* curLayer = parsedPacket.getFirstLayer(); curLayer != nullptr; curLayer = curLayer->getNextLayer()) { std::cout << "Layer type: " << getProtocolTypeAsString(curLayer->getProtocol()) << "; " // get layer type << "Total data: " << curLayer->getDataLen() << " [bytes]; " // get total length of the layer << "Layer data: " << curLayer->getHeaderLen() << " [bytes]; " // get the header length of the layer - << "Layer payload: " << curLayer->getLayerPayloadSize() << " [bytes]" // get the payload length of the layer (equals total length minus header length) - << std::endl; + << "Layer payload: " << curLayer->getLayerPayloadSize() << " [bytes]\n"; // get the payload length of the layer (equals total length minus header length) } // now let's get the Ethernet layer - pcpp::EthLayer* ethernetLayer = parsedPacket.getLayerOfType(); + auto* ethernetLayer = parsedPacket.getLayerOfType(); if (ethernetLayer == nullptr) { - std::cerr << "Something went wrong, couldn't find Ethernet layer" << std::endl; + std::cerr << "Something went wrong, couldn't find Ethernet layer\n"; return 1; } // print the source and dest MAC addresses and the Ether type - std::cout << std::endl - << "Source MAC address: " << ethernetLayer->getSourceMac() << std::endl - << "Destination MAC address: " << ethernetLayer->getDestMac() << std::endl - << "Ether type = 0x" << std::hex << pcpp::netToHost16(ethernetLayer->getEthHeader()->etherType) << std::endl; + std::cout << "\nSource MAC address: " << ethernetLayer->getSourceMac() << "\n" + << "Destination MAC address: " << ethernetLayer->getDestMac() << "\n" + << "Ether type = 0x" << std::hex << pcpp::netToHost16(ethernetLayer->getEthHeader()->etherType) << std::dec << "\n"; // let's get the IPv4 layer - pcpp::IPv4Layer* ipLayer = parsedPacket.getLayerOfType(); + auto* ipLayer = parsedPacket.getLayerOfType(); if (ipLayer == nullptr) { - std::cerr << "Something went wrong, couldn't find IPv4 layer" << std::endl; + std::cerr << "Something went wrong, couldn't find IPv4 layer\n"; return 1; } // print source and dest IP addresses, IP ID and TTL - std::cout << std::endl - << "Source IP address: " << ipLayer->getSrcIPAddress() << std::endl - << "Destination IP address: " << ipLayer->getDstIPAddress() << std::endl - << "IP ID: 0x" << std::hex << pcpp::netToHost16(ipLayer->getIPv4Header()->ipId) << std::endl - << "TTL: " << std::dec << (int)ipLayer->getIPv4Header()->timeToLive << std::endl; + std::cout << "\nSource IP address: " << ipLayer->getSrcIPAddress() << "\n" + << "Destination IP address: " << ipLayer->getDstIPAddress() << "\n" + << "IP ID: 0x" << std::hex << pcpp::netToHost16(ipLayer->getIPv4Header()->ipId) << std::dec << "\n" + << "TTL: " << static_cast(ipLayer->getIPv4Header()->timeToLive) << "\n"; // let's get the TCP layer - pcpp::TcpLayer* tcpLayer = parsedPacket.getLayerOfType(); + auto* tcpLayer = parsedPacket.getLayerOfType(); if (tcpLayer == nullptr) { - std::cerr << "Something went wrong, couldn't find TCP layer" << std::endl; + std::cerr << "Something went wrong, couldn't find TCP layer\n"; return 1; } // print TCP source and dest ports, window size, and the TCP flags that are set in this layer - std::cout << std::endl - << "Source TCP port: " << tcpLayer->getSrcPort() << std::endl - << "Destination TCP port: " << tcpLayer->getDstPort() << std::endl - << "Window size: " << pcpp::netToHost16(tcpLayer->getTcpHeader()->windowSize) << std::endl - << "TCP flags: " << printTcpFlags(tcpLayer) << std::endl; + std::cout << "\nSource TCP port: " << tcpLayer->getSrcPort() << "\n" + << "Destination TCP port: " << tcpLayer->getDstPort() << "\n" + << "Window size: " << pcpp::netToHost16(tcpLayer->getTcpHeader()->windowSize) << "\n" + << "TCP flags: " << printTcpFlags(tcpLayer) << "\n"; std::cout << "TCP options: "; for (pcpp::TcpOption tcpOption = tcpLayer->getFirstTcpOption(); tcpOption.isNotNull(); tcpOption = tcpLayer->getNextTcpOption(tcpOption)) { std::cout << printTcpOptionType(tcpOption.getTcpOptionType()) << " "; } - std::cout << std::endl; + std::cout << "\n"; // let's get the HTTP request layer - pcpp::HttpRequestLayer* httpRequestLayer = parsedPacket.getLayerOfType(); + auto* httpRequestLayer = parsedPacket.getLayerOfType(); if (httpRequestLayer == nullptr) { - std::cerr << "Something went wrong, couldn't find HTTP request layer" << std::endl; + std::cerr << "Something went wrong, couldn't find HTTP request layer\n"; return 1; } - // print HTTP method and URI. Both appear in the first line of the HTTP request - std::cout << std::endl - << "HTTP method: " << printHttpMethod(httpRequestLayer->getFirstLine()->getMethod()) << std::endl - << "HTTP URI: " << httpRequestLayer->getFirstLine()->getUri() << std::endl; - - // print values of the following HTTP field: Host, User-Agent and Cookie - std::cout - << "HTTP host: " << httpRequestLayer->getFieldByName(PCPP_HTTP_HOST_FIELD)->getFieldValue() << std::endl - << "HTTP user-agent: " << httpRequestLayer->getFieldByName(PCPP_HTTP_USER_AGENT_FIELD)->getFieldValue() << std::endl - << "HTTP cookie: " << httpRequestLayer->getFieldByName(PCPP_HTTP_COOKIE_FIELD)->getFieldValue() << std::endl; - - // print the full URL of this request - std::cout << "HTTP full URL: " << httpRequestLayer->getUrl() << std::endl; + // print HTTP method, URI, Host, User-Agent, Cookie and full URL of this request + std::cout << "\nHTTP method: " << printHttpMethod(httpRequestLayer->getFirstLine()->getMethod()) << "\n" + << "HTTP URI: " << httpRequestLayer->getFirstLine()->getUri() << "\n" + << "HTTP host: " << httpRequestLayer->getFieldByName(PCPP_HTTP_HOST_FIELD)->getFieldValue() << "\n" + << "HTTP user-agent: " << httpRequestLayer->getFieldByName(PCPP_HTTP_USER_AGENT_FIELD)->getFieldValue() << "\n" + << "HTTP cookie: " << httpRequestLayer->getFieldByName(PCPP_HTTP_COOKIE_FIELD)->getFieldValue() << "\n" + << "HTTP full URL: " << httpRequestLayer->getUrl() << std::endl; } diff --git a/Examples/Tutorials/Tutorial-PcapFiles/main.cpp b/Examples/Tutorials/Tutorial-PcapFiles/main.cpp index 89bff2f3d7..2d9aef64c5 100644 --- a/Examples/Tutorials/Tutorial-PcapFiles/main.cpp +++ b/Examples/Tutorials/Tutorial-PcapFiles/main.cpp @@ -1,3 +1,4 @@ +#include #include #include "stdlib.h" #include "PcapFileDevice.h" @@ -9,19 +10,19 @@ int main(int argc, char* argv[]) { // use the IFileReaderDevice interface to automatically identify file type (pcap/pcap-ng) // and create an interface instance that both readers implement - pcpp::IFileReaderDevice* reader = pcpp::IFileReaderDevice::getReader("input.pcap"); + std::unique_ptr reader(pcpp::IFileReaderDevice::getReader("input.pcap")); // verify that a reader interface was indeed created if (reader == nullptr) { - std::cerr << "Cannot determine reader for file type" << std::endl; + std::cerr << "Cannot determine reader for file type\n"; return 1; } // open the reader for reading if (!reader->open()) { - std::cerr << "Cannot open input.pcap for reading" << std::endl; + std::cerr << "Cannot open input.pcap for reading\n"; return 1; } @@ -32,7 +33,7 @@ int main(int argc, char* argv[]) // try to open the file for writing if (!pcapWriter.open()) { - std::cerr << "Cannot open output.pcap for writing" << std::endl; + std::cerr << "Cannot open output.pcap for writing\n"; return 1; } @@ -43,14 +44,14 @@ int main(int argc, char* argv[]) // try to open the file for writing if (!pcapNgWriter.open()) { - std::cerr << "Cannot open output.pcapng for writing" << std::endl; + std::cerr << "Cannot open output.pcapng for writing\n"; return 1; } // set a BPF filter for the reader - only packets that match the filter will be read if (!reader->setFilter("net 98.138.19.88")) { - std::cerr << "Cannot set filter for file reader" << std::endl; + std::cerr << "Cannot set filter for file reader\n"; return 1; } @@ -66,20 +67,26 @@ int main(int argc, char* argv[]) pcapNgWriter.writePacket(rawPacket); } + // Use lambda to simplify statistics output + auto printStats = [](const std::string& writerName, const pcpp::IPcapDevice::PcapStats& stats) { + std::cout << "Written " << stats.packetsRecv << " packets successfully to " << writerName + << " and " << stats.packetsDrop << " packets could not be written\n"; + }; + // create the stats object pcpp::IPcapDevice::PcapStats stats; // read stats from reader and print them reader->getStatistics(stats); - std::cout << "Read " << stats.packetsRecv << " packets successfully and " << stats.packetsDrop << " packets could not be read" << std::endl; + std::cout << "Read " << stats.packetsRecv << " packets successfully and " << stats.packetsDrop << " packets could not be read\n"; // read stats from pcap writer and print them pcapWriter.getStatistics(stats); - std::cout << "Written " << stats.packetsRecv << " packets successfully to pcap writer and " << stats.packetsDrop << " packets could not be written" << std::endl; + printStats("pcap writer", stats); // read stats from pcap-ng writer and print them pcapNgWriter.getStatistics(stats); - std::cout << "Written " << stats.packetsRecv << " packets successfully to pcap-ng writer and " << stats.packetsDrop << " packets could not be written" << std::endl; + printStats("pcap-ng writer", stats); // close reader reader->close(); @@ -88,6 +95,6 @@ int main(int argc, char* argv[]) pcapWriter.close(); pcapNgWriter.close(); - // free reader memory because it was created by pcpp::IFileReaderDevice::getReader() - delete reader; + // No need to delete reader, unique_ptr will handle that + return 0; }