From 767d70c5fbae41c61598a6e7bc5eb23add7bf480 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Tue, 7 Jan 2025 23:58:16 +0200 Subject: [PATCH 01/14] Added additional APR layer constructors that build a specific request / reply. - NB: Removed zeroing of MAC address if the ArpLayer contains a opcode ARP_REQUEST. - Added new structs with only required data to construct a certain packet. --- Common++/header/MacAddress.h | 2 ++ Common++/src/MacAddress.cpp | 2 ++ Packet++/header/ArpLayer.h | 63 ++++++++++++++++++++++++++++++++++++ Packet++/src/ArpLayer.cpp | 22 +++++++++++-- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/Common++/header/MacAddress.h b/Common++/header/MacAddress.h index 6e0834b013..cbd1dd6575 100644 --- a/Common++/header/MacAddress.h +++ b/Common++/header/MacAddress.h @@ -137,6 +137,8 @@ namespace pcpp /// A static value representing a zero value of MAC address, meaning address of value "00:00:00:00:00:00" static MacAddress Zero; + /// A static value representing a broadcast MAC address, meaning address of value "ff:ff:ff:ff:ff:ff" + static MacAddress Broadcast; private: uint8_t m_Address[6] = { 0 }; diff --git a/Common++/src/MacAddress.cpp b/Common++/src/MacAddress.cpp index 47d990a017..284cffbc3f 100644 --- a/Common++/src/MacAddress.cpp +++ b/Common++/src/MacAddress.cpp @@ -5,6 +5,8 @@ namespace pcpp MacAddress MacAddress::Zero(0, 0, 0, 0, 0, 0); + MacAddress MacAddress::Broadcast(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); + std::string MacAddress::toString() const { char str[19]; diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 4fb1b0db4c..f0aed49a35 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -52,6 +52,45 @@ namespace pcpp ARP_REPLY = 0x0002 ///< ARP reply (response) }; + struct ArpRequest + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + IPv4Address targetIpAddr; + + ArpRequest(MacAddress senderMacAddress, IPv4Address senderIPAddress, IPv4Address targetIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetIpAddr(targetIPAddress) {}; + }; + + struct ArpReply + { + MacAddress senderMacAddr; + MacAddress targetMacAddr; + IPv4Address senderIpAddr; + IPv4Address targetIpAddr; + + ArpReply(MacAddress senderMacAddress, MacAddress targetMacAddress, IPv4Address senderIPAddress, + IPv4Address targetIPAddress) + : senderMacAddr(senderMacAddress), targetMacAddr(targetMacAddress), senderIpAddr(senderIPAddress), + targetIpAddr(targetIPAddress) {}; + }; + + struct GratuitousArpRequest + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + GratuitousArpRequest(MacAddress senderMacAddress, IPv4Address senderIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; + }; + + struct GratuitousArpReply + { + MacAddress senderMacAddr; + IPv4Address senderIpAddr; + GratuitousArpReply(MacAddress senderMacAddress, IPv4Address senderIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; + }; + /** * @class ArpLayer * Represents an ARP protocol layer. Currently only IPv4 ARP messages are supported @@ -83,6 +122,30 @@ namespace pcpp ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr); + /** + * @brief A constructor that creates an ARP request header. + * @param arpRequest The ARP request data + */ + ArpLayer(ArpRequest const& arpRequest); + + /** + * @brief A constructor that creates an ARP reply header. + * @param arpReply The ARP reply data + */ + ArpLayer(ArpReply const& arpReply); + + /** + * @brief A constructor that creates a gratuitous ARP request header. + * @param gratuitousArpRequest The gratuitous ARP request data + */ + ArpLayer(GratuitousArpRequest const& gratuitousArpRequest); + + /** + * @brief A constructor that creates a gratuitous ARP reply header. + * @param gratuitousArpReply The gratuitous ARP reply data + */ + ArpLayer(GratuitousArpReply const& gratuitousArpReply); + ~ArpLayer() override = default; /** diff --git a/Packet++/src/ArpLayer.cpp b/Packet++/src/ArpLayer.cpp index 4971addd37..1db42ebc9d 100644 --- a/Packet++/src/ArpLayer.cpp +++ b/Packet++/src/ArpLayer.cpp @@ -24,6 +24,26 @@ namespace pcpp arpHeader->senderIpAddr = senderIpAddr.toInt(); } + ArpLayer::ArpLayer(ArpRequest const& arpRequest) + : ArpLayer(ARP_REQUEST, arpRequest.senderMacAddr, MacAddress::Zero, arpRequest.senderIpAddr, + arpRequest.targetIpAddr) + {} + + ArpLayer::ArpLayer(ArpReply const& arpReply) + : ArpLayer(ARP_REPLY, arpReply.senderMacAddr, arpReply.targetMacAddr, arpReply.senderIpAddr, + arpReply.targetIpAddr) + {} + + ArpLayer::ArpLayer(GratuitousArpRequest const& gratuitousArpRequest) + : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, MacAddress::Broadcast, gratuitousArpRequest.senderIpAddr, + gratuitousArpRequest.senderIpAddr) + {} + + ArpLayer::ArpLayer(GratuitousArpReply const& gratuitousArpReply) + : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, MacAddress::Broadcast, + gratuitousArpReply.senderIpAddr, gratuitousArpReply.senderIpAddr) + {} + void ArpLayer::computeCalculateFields() { arphdr* arpHeader = getArpHeader(); @@ -31,8 +51,6 @@ namespace pcpp arpHeader->hardwareSize = 6; arpHeader->protocolType = htobe16(PCPP_ETHERTYPE_IP); // assume IPv4 over ARP arpHeader->protocolSize = 4; // assume IPv4 over ARP - if (arpHeader->opcode == htobe16(ARP_REQUEST)) - MacAddress::Zero.copyTo(arpHeader->targetMacAddr); } bool ArpLayer::isRequest() const From 1e9f389ce3dadd916b47593d662a520aafcb528c Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Wed, 8 Jan 2025 00:03:45 +0200 Subject: [PATCH 02/14] Added explicit to ctors. --- Packet++/header/ArpLayer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index f0aed49a35..a416d5234b 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -126,25 +126,25 @@ namespace pcpp * @brief A constructor that creates an ARP request header. * @param arpRequest The ARP request data */ - ArpLayer(ArpRequest const& arpRequest); + explicit ArpLayer(ArpRequest const& arpRequest); /** * @brief A constructor that creates an ARP reply header. * @param arpReply The ARP reply data */ - ArpLayer(ArpReply const& arpReply); + explicit ArpLayer(ArpReply const& arpReply); /** * @brief A constructor that creates a gratuitous ARP request header. * @param gratuitousArpRequest The gratuitous ARP request data */ - ArpLayer(GratuitousArpRequest const& gratuitousArpRequest); + explicit ArpLayer(GratuitousArpRequest const& gratuitousArpRequest); /** * @brief A constructor that creates a gratuitous ARP reply header. * @param gratuitousArpReply The gratuitous ARP reply data */ - ArpLayer(GratuitousArpReply const& gratuitousArpReply); + explicit ArpLayer(GratuitousArpReply const& gratuitousArpReply); ~ArpLayer() override = default; From a7b1275b52ef54f82b3a049f4078e04c44ba0746 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Wed, 8 Jan 2025 00:05:10 +0200 Subject: [PATCH 03/14] Added docs --- Packet++/header/ArpLayer.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index a416d5234b..104f78b7f3 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -52,6 +52,9 @@ namespace pcpp ARP_REPLY = 0x0002 ///< ARP reply (response) }; + /** + * @brief A struct representing the build data for an ARP request + */ struct ArpRequest { MacAddress senderMacAddr; @@ -62,6 +65,9 @@ namespace pcpp : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetIpAddr(targetIPAddress) {}; }; + /** + * @brief A struct representing the build data for an ARP reply + */ struct ArpReply { MacAddress senderMacAddr; @@ -75,6 +81,9 @@ namespace pcpp targetIpAddr(targetIPAddress) {}; }; + /** + * @brief A struct representing the build data for a gratuitous ARP request + */ struct GratuitousArpRequest { MacAddress senderMacAddr; @@ -83,6 +92,9 @@ namespace pcpp : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; }; + /** + * @brief A struct representing the build data a gratuitous ARP reply + */ struct GratuitousArpReply { MacAddress senderMacAddr; From 03525c88d82d36e2af813b7bb84ee312a72eb1ef Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Wed, 8 Jan 2025 00:08:05 +0200 Subject: [PATCH 04/14] Lint --- Packet++/src/ArpLayer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Packet++/src/ArpLayer.cpp b/Packet++/src/ArpLayer.cpp index 1db42ebc9d..3963879828 100644 --- a/Packet++/src/ArpLayer.cpp +++ b/Packet++/src/ArpLayer.cpp @@ -35,13 +35,13 @@ namespace pcpp {} ArpLayer::ArpLayer(GratuitousArpRequest const& gratuitousArpRequest) - : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, MacAddress::Broadcast, gratuitousArpRequest.senderIpAddr, - gratuitousArpRequest.senderIpAddr) + : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, MacAddress::Broadcast, + gratuitousArpRequest.senderIpAddr, gratuitousArpRequest.senderIpAddr) {} ArpLayer::ArpLayer(GratuitousArpReply const& gratuitousArpReply) - : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, MacAddress::Broadcast, - gratuitousArpReply.senderIpAddr, gratuitousArpReply.senderIpAddr) + : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, MacAddress::Broadcast, gratuitousArpReply.senderIpAddr, + gratuitousArpReply.senderIpAddr) {} void ArpLayer::computeCalculateFields() From d0a507a664e710d424555ff1d462393dc64b7088 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Wed, 8 Jan 2025 09:15:25 +0200 Subject: [PATCH 05/14] Changed const to constexpr. --- Packet++/src/ArpLayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packet++/src/ArpLayer.cpp b/Packet++/src/ArpLayer.cpp index 3963879828..e3e3ad141d 100644 --- a/Packet++/src/ArpLayer.cpp +++ b/Packet++/src/ArpLayer.cpp @@ -10,7 +10,7 @@ namespace pcpp ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr) { - const size_t headerLen = sizeof(arphdr); + constexpr size_t headerLen = sizeof(arphdr); m_DataLen = headerLen; m_Data = new uint8_t[headerLen]; memset(m_Data, 0, sizeof(headerLen)); From c3112856fec5396d674b64fb551760a491906542 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 10 Jan 2025 01:31:47 +0200 Subject: [PATCH 06/14] Deprecated the old ARPLayer constructor. - Added a new private constructor to handle populating the header. The old constructor is forwarded to this one with the caveat that the target MAC address is ignored and zeroed if a request is to be made. --- Packet++/header/ArpLayer.h | 17 +++++++++++++++++ Packet++/src/ArpLayer.cpp | 29 +++++++++++++++++------------ Pcap++/src/NetworkUtils.cpp | 6 ++---- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 104f78b7f3..2d511ac35d 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -3,6 +3,7 @@ #include "Layer.h" #include "IpAddress.h" #include "MacAddress.h" +#include "DeprecationUtils.h" /// @file @@ -109,6 +110,19 @@ namespace pcpp */ class ArpLayer : public Layer { + private: + /** + * @brief A constructor that creates an ARP header + * @param[in] opCode ARP message type (ARP request or ARP reply) + * @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) + * @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) + * @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) + * @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) + * @remarks This constructor's parameters are reordered to avoid ambiguity with the deprecated constructor. + */ + ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, + const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr); + public: /** * A constructor that creates the layer from an existing packet raw data @@ -130,7 +144,10 @@ namespace pcpp * @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) * @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) * @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) + * @deprecated This constructor has been deprecated. Please use one of the other overloads. + * @remarks This constructor zeroes the target MAC address for ARP requests to keep backward compatibility. */ + PCPP_DEPRECATED("This constructor has been deprecated. Please use one of the other overloads.") ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr); diff --git a/Packet++/src/ArpLayer.cpp b/Packet++/src/ArpLayer.cpp index e3e3ad141d..6be1ae1dda 100644 --- a/Packet++/src/ArpLayer.cpp +++ b/Packet++/src/ArpLayer.cpp @@ -6,41 +6,46 @@ namespace pcpp { - - ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, - const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr) + ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, + const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr) { constexpr size_t headerLen = sizeof(arphdr); m_DataLen = headerLen; - m_Data = new uint8_t[headerLen]; - memset(m_Data, 0, sizeof(headerLen)); + m_Data = new uint8_t[headerLen]{}; // zero-initialized m_Protocol = ARP; arphdr* arpHeader = getArpHeader(); arpHeader->opcode = htobe16(static_cast(opCode)); - targetMacAddr.copyTo(arpHeader->targetMacAddr); senderMacAddr.copyTo(arpHeader->senderMacAddr); - arpHeader->targetIpAddr = targetIpAddr.toInt(); + targetMacAddr.copyTo(arpHeader->targetMacAddr); arpHeader->senderIpAddr = senderIpAddr.toInt(); + arpHeader->targetIpAddr = targetIpAddr.toInt(); } + // This constructor zeroes the target MAC address for ARP requests to keep backward compatibility. + ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, + const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr) + : ArpLayer(opCode, senderMacAddr, senderIpAddr, opCode == ARP_REQUEST ? MacAddress::Zero : targetMacAddr, + targetIpAddr) + {} + ArpLayer::ArpLayer(ArpRequest const& arpRequest) - : ArpLayer(ARP_REQUEST, arpRequest.senderMacAddr, MacAddress::Zero, arpRequest.senderIpAddr, + : ArpLayer(ARP_REQUEST, arpRequest.senderMacAddr, arpRequest.senderIpAddr, MacAddress::Zero, arpRequest.targetIpAddr) {} ArpLayer::ArpLayer(ArpReply const& arpReply) - : ArpLayer(ARP_REPLY, arpReply.senderMacAddr, arpReply.targetMacAddr, arpReply.senderIpAddr, + : ArpLayer(ARP_REPLY, arpReply.senderMacAddr, arpReply.senderIpAddr, arpReply.targetMacAddr, arpReply.targetIpAddr) {} ArpLayer::ArpLayer(GratuitousArpRequest const& gratuitousArpRequest) - : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, MacAddress::Broadcast, - gratuitousArpRequest.senderIpAddr, gratuitousArpRequest.senderIpAddr) + : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, gratuitousArpRequest.senderIpAddr, + MacAddress::Broadcast, gratuitousArpRequest.senderIpAddr) {} ArpLayer::ArpLayer(GratuitousArpReply const& gratuitousArpReply) - : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, MacAddress::Broadcast, gratuitousArpReply.senderIpAddr, + : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, gratuitousArpReply.senderIpAddr, MacAddress::Broadcast, gratuitousArpReply.senderIpAddr) {} diff --git a/Pcap++/src/NetworkUtils.cpp b/Pcap++/src/NetworkUtils.cpp index 6e595adfc8..35c4d29f33 100644 --- a/Pcap++/src/NetworkUtils.cpp +++ b/Pcap++/src/NetworkUtils.cpp @@ -106,10 +106,8 @@ namespace pcpp Packet arpRequest(100); - MacAddress destMac(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); - EthLayer ethLayer(sourceMac, destMac); - - ArpLayer arpLayer(ARP_REQUEST, sourceMac, destMac, sourceIP, ipAddr); + EthLayer ethLayer(sourceMac, MacAddress::Broadcast); + ArpLayer arpLayer(ArpRequest(sourceMac, sourceIP, ipAddr)); if (!arpRequest.addLayer(ðLayer)) { From d5c3fad83cdf0558ff85f75deb9303d5f2ade422 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 10 Jan 2025 01:33:20 +0200 Subject: [PATCH 07/14] Added documentation to the new structured. --- Packet++/header/ArpLayer.h | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 2d511ac35d..2176b2b677 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -55,6 +55,8 @@ namespace pcpp /** * @brief A struct representing the build data for an ARP request + * + * An ARP request is a message sent by a machine to request the MAC address of another machine on the network. */ struct ArpRequest { @@ -62,12 +64,22 @@ namespace pcpp IPv4Address senderIpAddr; IPv4Address targetIpAddr; - ArpRequest(MacAddress senderMacAddress, IPv4Address senderIPAddress, IPv4Address targetIPAddress) + /** + * @brief Construct a new Arp Request object + * @param senderMacAddress The MAC address of the machine sending the query. + * @param senderIPAddress The IP address of the machine sending the query. + * @param targetIPAddress The IP address of the target machine being queried. + */ + ArpRequest(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress, + IPv4Address const& targetIPAddress) : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetIpAddr(targetIPAddress) {}; }; /** * @brief A struct representing the build data for an ARP reply + * + * An ARP reply is a message sent by a machine in response to an ARP request. It contains the MAC address of the + * answering machine, and is sent to the IP/MAC address of the machine that sent the original ARP request. */ struct ArpReply { @@ -76,31 +88,65 @@ namespace pcpp IPv4Address senderIpAddr; IPv4Address targetIpAddr; - ArpReply(MacAddress senderMacAddress, MacAddress targetMacAddress, IPv4Address senderIPAddress, - IPv4Address targetIPAddress) + /** + * @brief Construct a new Arp Reply object + * @param senderMacAddress The MAC address of the machine sending the reply. + * @param targetMacAddress The MAC address of the target machine being replied to. + * @param senderIPAddress The IP address of the machine sending the reply. + * @param targetIPAddress The IP address of the target machine being replied to. + * @remarks The target machine is considered the machine that sent the original ARP request. + */ + ArpReply(MacAddress const& senderMacAddress, MacAddress const& targetMacAddress, + IPv4Address const& senderIPAddress, IPv4Address const& targetIPAddress) : senderMacAddr(senderMacAddress), targetMacAddr(targetMacAddress), senderIpAddr(senderIPAddress), targetIpAddr(targetIPAddress) {}; }; /** * @brief A struct representing the build data for a gratuitous ARP request + * + * A gratuitous ARP request is an ARP request that is sent by a machine to announce its presence on the network. + * It is an ARP request that has both the sender and target IP addresses set to the IP address of the machine + * and the target MAC address set to the broadcast address. Normally such a request will not receive a reply. + * + * These requests can be used to update ARP caches on other machines on the network, or to help in detecting IP + * address conflicts. */ struct GratuitousArpRequest { MacAddress senderMacAddr; IPv4Address senderIpAddr; - GratuitousArpRequest(MacAddress senderMacAddress, IPv4Address senderIPAddress) + + /** + * @brief Construct a new Gratuitous Arp Request object + * @param senderMacAddress The MAC address of the machine sending the gratuitous ARP request. + * @param senderIPAddress The IP address of the machine sending the gratuitous ARP request. + * @remarks The target MAC address is set to the broadcast address and the target IP address is set to the + * sender's. + */ + GratuitousArpRequest(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress) : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; }; /** * @brief A struct representing the build data a gratuitous ARP reply + * + * A gratuitous ARP reply is an ARP reply that is sent by a machine to announce its presence on the network. + * It is gratuitous in the sense that it is not in response to an ARP request, but sent unsolicited to the network. */ struct GratuitousArpReply { MacAddress senderMacAddr; IPv4Address senderIpAddr; - GratuitousArpReply(MacAddress senderMacAddress, IPv4Address senderIPAddress) + + /** + * @brief Construct a new Gratuitous Arp Reply object + * @param senderMacAddress The MAC address of the machine sending the gratuitous ARP reply. + * @param senderIPAddress The IP address of the machine sending the gratuitous ARP reply. + * @remarks The target MAC address is set to the broadcast address and the target IP address is set to the + * sender's. + */ + GratuitousArpReply(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress) : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {}; }; From 948e4aa2f2c05d0671a4a01ca28c3296b30cf1bd Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 10 Jan 2025 11:30:40 +0200 Subject: [PATCH 08/14] Changed visibility of new direct ctor to public. --- Packet++/header/ArpLayer.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 2176b2b677..4efd292c94 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -156,19 +156,6 @@ namespace pcpp */ class ArpLayer : public Layer { - private: - /** - * @brief A constructor that creates an ARP header - * @param[in] opCode ARP message type (ARP request or ARP reply) - * @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) - * @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) - * @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) - * @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) - * @remarks This constructor's parameters are reordered to avoid ambiguity with the deprecated constructor. - */ - ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, - const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr); - public: /** * A constructor that creates the layer from an existing packet raw data @@ -183,6 +170,19 @@ namespace pcpp m_DataLen = sizeof(arphdr); } + /** + * @brief A constructor that creates an ARP header + * @param[in] opCode ARP message type (ARP request or ARP reply) + * @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) + * @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) + * @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) + * @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) + * @remarks No validation is done on the input parameters. The caller must ensure that the input creates a valid + * header. + */ + ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, + const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr); + /** * A constructor that allocates a new ARP header * @param[in] opCode ARP message type (ARP request or ARP reply) From 08b31a0ebf88feabf42829f4a7de8d62e22dbad1 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 10 Jan 2025 13:23:49 +0200 Subject: [PATCH 09/14] Added static assert to ensure the `arphdr` structure is precisely 28 bytes. --- Packet++/header/ArpLayer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 4efd292c94..64b2140ccb 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -43,6 +43,7 @@ namespace pcpp uint32_t targetIpAddr; }; #pragma pack(pop) + static_assert(sizeof(arphdr) == 28, "arphdr size is not 28 bytes"); /** * An enum for ARP message type From da3f639afde97587a162bd56e84535ca256da117 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 10 Jan 2025 16:30:45 +0200 Subject: [PATCH 10/14] Swapped constructor arguments to pair Mac and IP addresses for source and target. --- Packet++/header/ArpLayer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 64b2140ccb..63d9fabbeb 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -85,21 +85,21 @@ namespace pcpp struct ArpReply { MacAddress senderMacAddr; - MacAddress targetMacAddr; IPv4Address senderIpAddr; + MacAddress targetMacAddr; IPv4Address targetIpAddr; /** * @brief Construct a new Arp Reply object * @param senderMacAddress The MAC address of the machine sending the reply. - * @param targetMacAddress The MAC address of the target machine being replied to. * @param senderIPAddress The IP address of the machine sending the reply. + * @param targetMacAddress The MAC address of the target machine being replied to. * @param targetIPAddress The IP address of the target machine being replied to. * @remarks The target machine is considered the machine that sent the original ARP request. */ - ArpReply(MacAddress const& senderMacAddress, MacAddress const& targetMacAddress, - IPv4Address const& senderIPAddress, IPv4Address const& targetIPAddress) - : senderMacAddr(senderMacAddress), targetMacAddr(targetMacAddress), senderIpAddr(senderIPAddress), + ArpReply(MacAddress const& senderMacAddress, IPv4Address const& senderIPAddress, + MacAddress const& targetMacAddress, IPv4Address const& targetIPAddress) + : senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetMacAddr(targetMacAddress), targetIpAddr(targetIPAddress) {}; }; From 85b6c74a9cba8c2df8db0724bfb81bf11c51bf68 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Fri, 10 Jan 2025 16:31:08 +0200 Subject: [PATCH 11/14] Added unit tests for new constructors. --- Tests/Packet++Test/Tests/EthAndArpTests.cpp | 140 ++++++++++++++++---- 1 file changed, 115 insertions(+), 25 deletions(-) diff --git a/Tests/Packet++Test/Tests/EthAndArpTests.cpp b/Tests/Packet++Test/Tests/EthAndArpTests.cpp index b8faea90aa..7b708ebab0 100644 --- a/Tests/Packet++Test/Tests/EthAndArpTests.cpp +++ b/Tests/Packet++Test/Tests/EthAndArpTests.cpp @@ -120,32 +120,122 @@ PTF_TEST_CASE(EthAndArpPacketParsing) PTF_TEST_CASE(ArpPacketCreation) { - pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); - pcpp::MacAddress dstMac("ff:ff:ff:ff:ff:ff"); - pcpp::EthLayer ethLayer(srcMac, dstMac, PCPP_ETHERTYPE_ARP); - - pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, srcMac, srcMac, pcpp::IPv4Address("10.0.0.1"), - pcpp::IPv4Address("10.0.0.138")); - - pcpp::Packet arpRequestPacket(1); - PTF_ASSERT_TRUE(arpRequestPacket.addLayer(ðLayer)); - PTF_ASSERT_TRUE(arpRequestPacket.addLayer(&arpLayer)); - arpRequestPacket.computeCalculateFields(); - PTF_ASSERT_EQUAL(arpRequestPacket.getRawPacket()->getRawDataLen(), 42); - - pcpp::ArpLayer* pArpLayer = arpRequestPacket.getLayerOfType(); - PTF_ASSERT_NOT_NULL(pArpLayer); - - pcpp::arphdr* arpHeader = pArpLayer->getArpHeader(); - PTF_ASSERT_EQUAL(arpHeader->hardwareSize, 6); - PTF_ASSERT_EQUAL(arpHeader->protocolType, htobe16(PCPP_ETHERTYPE_IP)); - READ_FILE_INTO_BUFFER(1, "PacketExamples/ArpRequestPacket.dat"); - - PTF_ASSERT_EQUAL(bufferLength1, arpRequestPacket.getRawPacket()->getRawDataLen()); - PTF_ASSERT_BUF_COMPARE(arpRequestPacket.getRawPacket()->getRawData(), buffer1, bufferLength1); - - delete[] buffer1; + // Stores the buffer in a unique_ptr to ensure it's deleted when the test ends. + std::unique_ptr buffer1Uptr(buffer1); + + { + pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); + pcpp::MacAddress dstMac("ff:ff:ff:ff:ff:ff"); + pcpp::EthLayer ethLayer(srcMac, dstMac, PCPP_ETHERTYPE_ARP); + pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, srcMac, srcMac, pcpp::IPv4Address("10.0.0.1"), + pcpp::IPv4Address("10.0.0.138")); + + pcpp::Packet arpRequestPacket(1); + + PTF_ASSERT_TRUE(arpRequestPacket.addLayer(ðLayer)); + PTF_ASSERT_TRUE(arpRequestPacket.addLayer(&arpLayer)); + arpRequestPacket.computeCalculateFields(); + PTF_ASSERT_EQUAL(arpRequestPacket.getRawPacket()->getRawDataLen(), 42); + + pcpp::ArpLayer* pArpLayer = arpRequestPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(pArpLayer); + + pcpp::arphdr* arpHeader = pArpLayer->getArpHeader(); + PTF_ASSERT_EQUAL(arpHeader->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpHeader->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + + PTF_ASSERT_EQUAL(bufferLength1, arpRequestPacket.getRawPacket()->getRawDataLen()); + PTF_ASSERT_BUF_COMPARE(arpRequestPacket.getRawPacket()->getRawData(), buffer1, bufferLength1); + } + + { + pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); + pcpp::IPv4Address srcIp("10.0.0.1"); + pcpp::IPv4Address dstIp("10.0.0.138"); + + pcpp::EthLayer ethLayer(srcMac, pcpp::MacAddress::Broadcast, PCPP_ETHERTYPE_ARP); + pcpp::ArpLayer arpLayer(pcpp::ArpRequest(srcMac, srcIp, dstIp)); + + pcpp::Packet argRequestPacket(1); + PTF_ASSERT_TRUE(argRequestPacket.addLayer(ðLayer)); + PTF_ASSERT_TRUE(argRequestPacket.addLayer(&arpLayer)); + + argRequestPacket.computeCalculateFields(); + PTF_ASSERT_EQUAL(argRequestPacket.getRawPacket()->getRawDataLen(), 42); + + pcpp::ArpLayer* pArpLayer = argRequestPacket.getLayerOfType(); + PTF_ASSERT_NOT_NULL(pArpLayer); + + pcpp::arphdr* arpHeader = pArpLayer->getArpHeader(); + PTF_ASSERT_EQUAL(arpHeader->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpHeader->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + + PTF_ASSERT_EQUAL(bufferLength1, argRequestPacket.getRawPacket()->getRawDataLen()); + PTF_ASSERT_BUF_COMPARE(argRequestPacket.getRawPacket()->getRawData(), buffer1, bufferLength1); + } + + { + // TODO: Add an actual packet to test against. + pcpp::MacAddress srcMac("02:00:00:00:00:02"); + pcpp::IPv4Address srcIp("10.0.0.138"); + pcpp::MacAddress dstMac("02:00:00:00:00:01"); + pcpp::IPv4Address dstIp("10.0.0.1"); + + pcpp::ArpLayer arpLayer(pcpp::ArpReply(srcMac, srcIp, dstMac, dstIp)); + + arpLayer.computeCalculateFields(); + PTF_ASSERT_EQUAL(arpLayer.getHeaderLen(), 28); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolSize, 4); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REPLY)); + PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); + PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); + PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), dstMac); + PTF_ASSERT_EQUAL(arpLayer.getTargetIpAddr(), dstIp); + } + + { + // TODO: Add an actual packet to test against. + pcpp::MacAddress srcMac("02:00:00:00:00:01"); + pcpp::IPv4Address srcIp("10.0.0.1"); + + pcpp::ArpLayer arpLayer(pcpp::GratuitousArpRequest(srcMac, srcIp)); + arpLayer.computeCalculateFields(); + + PTF_ASSERT_EQUAL(arpLayer.getHeaderLen(), 28); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolSize, 4); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REQUEST)); + PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); + PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); + PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), pcpp::MacAddress::Broadcast); + PTF_ASSERT_EQUAL(arpLayer.getTargetIpAddr(), srcIp); + } + + { + // TODO: Add an actual packet to test against. + pcpp::MacAddress srcMac("02:00:00:00:00:01"); + pcpp::IPv4Address srcIp("10.0.0.1"); + + pcpp::ArpLayer arpLayer(pcpp::GratuitousArpReply(srcMac, srcIp)); + arpLayer.computeCalculateFields(); + + PTF_ASSERT_EQUAL(arpLayer.getHeaderLen(), 28); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareSize, 6); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolSize, 4); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); + PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REPLY)); + PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); + PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); + PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), pcpp::MacAddress::Broadcast); + PTF_ASSERT_EQUAL(arpLayer.getTargetIpAddr(), srcIp); + } } // ArpPacketCreation PTF_TEST_CASE(EthDot3LayerParsingTest) From bbe99043997840f8d8b4e07b42da6ca9f739de73 Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sat, 11 Jan 2025 13:04:43 +0200 Subject: [PATCH 12/14] Added a mechanism to probe for known header signatures to discover the type of ARP message. --- Packet++/header/ArpLayer.h | 26 ++++++++++++- Packet++/src/ArpLayer.cpp | 43 ++++++++++++++++++--- Tests/Packet++Test/Tests/EthAndArpTests.cpp | 7 ++++ 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/Packet++/header/ArpLayer.h b/Packet++/header/ArpLayer.h index 63d9fabbeb..c1a125ce3c 100644 --- a/Packet++/header/ArpLayer.h +++ b/Packet++/header/ArpLayer.h @@ -54,6 +54,18 @@ namespace pcpp ARP_REPLY = 0x0002 ///< ARP reply (response) }; + /** + * @brief An enum representing the ARP message type + */ + enum class ArpMessageType + { + Unknown, ///< Unknown ARP message type + Request, ///< ARP request + Reply, ///< ARP reply + GratuitousRequest, ///< Gratuitous ARP request + GratuitousReply, ///< Gratuitous ARP reply + }; + /** * @brief A struct representing the build data for an ARP request * @@ -234,6 +246,13 @@ namespace pcpp return reinterpret_cast(m_Data); } + /** + * Get the ARP opcode + * @return The ARP opcode + * @remarks The opcode may not be one of the values in @ref ArpOpcode + */ + ArpOpcode getOpcode() const; + /** * Get the sender hardware address (SHA) in the form of MacAddress * @return A MacAddress containing the sender hardware address (SHA) @@ -292,10 +311,15 @@ namespace pcpp * - @ref arphdr#hardwareSize = 6 * - @ref arphdr#protocolType = ETHERTYPE_IP (assume IPv4 over ARP) * - @ref arphdr#protocolSize = 4 (assume IPv4 over ARP) - * - if it's an ARP request: @ref arphdr#targetMacAddr = MacAddress("00:00:00:00:00:00") */ void computeCalculateFields() override; + /** + * @brief Attempts to determine the ARP message type based on the header signature. + * @return An @ref ArpMessageType representing the ARP message type. + */ + ArpMessageType getMessageType() const; + /** * Is this packet an ARP request? */ diff --git a/Packet++/src/ArpLayer.cpp b/Packet++/src/ArpLayer.cpp index 6be1ae1dda..0ae415d27f 100644 --- a/Packet++/src/ArpLayer.cpp +++ b/Packet++/src/ArpLayer.cpp @@ -49,6 +49,11 @@ namespace pcpp gratuitousArpReply.senderIpAddr) {} + ArpOpcode ArpLayer::getOpcode() const + { + return static_cast(be16toh(getArpHeader()->opcode)); + } + void ArpLayer::computeCalculateFields() { arphdr* arpHeader = getArpHeader(); @@ -58,27 +63,53 @@ namespace pcpp arpHeader->protocolSize = 4; // assume IPv4 over ARP } + ArpMessageType ArpLayer::getMessageType() const + { + switch (getOpcode()) + { + case ArpOpcode::ARP_REQUEST: + { + if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr()) + { + return ArpMessageType::GratuitousRequest; + } + return ArpMessageType::Request; + } + case ArpOpcode::ARP_REPLY: + { + if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr()) + { + return ArpMessageType::GratuitousReply; + } + return ArpMessageType::Reply; + } + default: + return ArpMessageType::Unknown; + } + } + bool ArpLayer::isRequest() const { - return be16toh(getArpHeader()->opcode) == pcpp::ArpOpcode::ARP_REQUEST; + return getOpcode() == pcpp::ArpOpcode::ARP_REQUEST; } bool ArpLayer::isReply() const { - return be16toh(getArpHeader()->opcode) == pcpp::ArpOpcode::ARP_REPLY; + return getOpcode() == pcpp::ArpOpcode::ARP_REPLY; } std::string ArpLayer::toString() const { - if (be16toh(getArpHeader()->opcode) == ARP_REQUEST) + switch (getOpcode()) { + case ArpOpcode::ARP_REQUEST: return "ARP Layer, ARP request, who has " + getTargetIpAddr().toString() + " ? Tell " + getSenderIpAddr().toString(); - } - else - { + case ArpOpcode::ARP_REPLY: return "ARP Layer, ARP reply, " + getSenderIpAddr().toString() + " is at " + getSenderMacAddress().toString(); + default: + return "ARP Layer, unknown opcode (" + std::to_string(getOpcode()) + ")"; } } diff --git a/Tests/Packet++Test/Tests/EthAndArpTests.cpp b/Tests/Packet++Test/Tests/EthAndArpTests.cpp index 7b708ebab0..d7abc3f859 100644 --- a/Tests/Packet++Test/Tests/EthAndArpTests.cpp +++ b/Tests/Packet++Test/Tests/EthAndArpTests.cpp @@ -131,6 +131,8 @@ PTF_TEST_CASE(ArpPacketCreation) pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, srcMac, srcMac, pcpp::IPv4Address("10.0.0.1"), pcpp::IPv4Address("10.0.0.138")); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::Request); + pcpp::Packet arpRequestPacket(1); PTF_ASSERT_TRUE(arpRequestPacket.addLayer(ðLayer)); @@ -157,6 +159,8 @@ PTF_TEST_CASE(ArpPacketCreation) pcpp::EthLayer ethLayer(srcMac, pcpp::MacAddress::Broadcast, PCPP_ETHERTYPE_ARP); pcpp::ArpLayer arpLayer(pcpp::ArpRequest(srcMac, srcIp, dstIp)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::Request); + pcpp::Packet argRequestPacket(1); PTF_ASSERT_TRUE(argRequestPacket.addLayer(ðLayer)); PTF_ASSERT_TRUE(argRequestPacket.addLayer(&arpLayer)); @@ -191,6 +195,7 @@ PTF_TEST_CASE(ArpPacketCreation) PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REPLY)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::Reply); PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), dstMac); @@ -211,6 +216,7 @@ PTF_TEST_CASE(ArpPacketCreation) PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REQUEST)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::GratuitousRequest); PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), pcpp::MacAddress::Broadcast); @@ -231,6 +237,7 @@ PTF_TEST_CASE(ArpPacketCreation) PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->hardwareType, htobe16(1)); PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->protocolType, htobe16(PCPP_ETHERTYPE_IP)); PTF_ASSERT_EQUAL(arpLayer.getArpHeader()->opcode, htobe16(pcpp::ARP_REPLY)); + PTF_ASSERT_TRUE(arpLayer.getMessageType() == pcpp::ArpMessageType::GratuitousReply); PTF_ASSERT_EQUAL(arpLayer.getSenderMacAddress(), srcMac); PTF_ASSERT_EQUAL(arpLayer.getSenderIpAddr(), srcIp); PTF_ASSERT_EQUAL(arpLayer.getTargetMacAddress(), pcpp::MacAddress::Broadcast); From d4cc2e55d9c9b556b31e72165e0154eeb3faec4b Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sat, 11 Jan 2025 13:07:10 +0200 Subject: [PATCH 13/14] Lint --- Tests/Packet++Test/Tests/EthAndArpTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Packet++Test/Tests/EthAndArpTests.cpp b/Tests/Packet++Test/Tests/EthAndArpTests.cpp index d7abc3f859..950fdfadcf 100644 --- a/Tests/Packet++Test/Tests/EthAndArpTests.cpp +++ b/Tests/Packet++Test/Tests/EthAndArpTests.cpp @@ -123,7 +123,7 @@ PTF_TEST_CASE(ArpPacketCreation) READ_FILE_INTO_BUFFER(1, "PacketExamples/ArpRequestPacket.dat"); // Stores the buffer in a unique_ptr to ensure it's deleted when the test ends. std::unique_ptr buffer1Uptr(buffer1); - + { pcpp::MacAddress srcMac("6c:f0:49:b2:de:6e"); pcpp::MacAddress dstMac("ff:ff:ff:ff:ff:ff"); From 014c0631aeb89edca28f9fb79199141157a2db4b Mon Sep 17 00:00:00 2001 From: Dimitar Krastev Date: Sat, 18 Jan 2025 12:25:03 +0200 Subject: [PATCH 14/14] Changed ArpLayer constructors in examples and tests to use the new message structure based constructors. --- Examples/ArpSpoofing/main.cpp | 7 +++---- Tests/Packet++Test/Tests/VlanMplsTests.cpp | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Examples/ArpSpoofing/main.cpp b/Examples/ArpSpoofing/main.cpp index 837e2555be..e6d354dc73 100644 --- a/Examples/ArpSpoofing/main.cpp +++ b/Examples/ArpSpoofing/main.cpp @@ -66,8 +66,7 @@ pcpp::MacAddress getMacAddress(const pcpp::IPv4Address& ipAddr, pcpp::PcapLiveDe pcpp::MacAddress macSrc = pDevice->getMacAddress(); pcpp::MacAddress macDst(0xff, 0xff, 0xff, 0xff, 0xff, 0xff); pcpp::EthLayer ethLayer(macSrc, macDst, static_cast(PCPP_ETHERTYPE_ARP)); - pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, pDevice->getMacAddress(), pDevice->getMacAddress(), - pDevice->getIPv4Address(), ipAddr); + pcpp::ArpLayer arpLayer(pcpp::ArpRequest(pDevice->getMacAddress(), pDevice->getIPv4Address(), ipAddr)); arpRequest.addLayer(ðLayer); arpRequest.addLayer(&arpLayer); @@ -137,7 +136,7 @@ void doArpSpoofing(pcpp::PcapLiveDevice* pDevice, const pcpp::IPv4Address& gatew // Create ARP reply for the gateway pcpp::Packet gwArpReply(500); pcpp::EthLayer gwEthLayer(deviceMacAddress, gatewayMacAddr, static_cast(PCPP_ETHERTYPE_ARP)); - pcpp::ArpLayer gwArpLayer(pcpp::ARP_REPLY, pDevice->getMacAddress(), gatewayMacAddr, victimAddr, gatewayAddr); + pcpp::ArpLayer gwArpLayer(pcpp::ArpReply(pDevice->getMacAddress(), victimAddr, gatewayMacAddr, gatewayAddr)); gwArpReply.addLayer(&gwEthLayer); gwArpReply.addLayer(&gwArpLayer); gwArpReply.computeCalculateFields(); @@ -145,7 +144,7 @@ void doArpSpoofing(pcpp::PcapLiveDevice* pDevice, const pcpp::IPv4Address& gatew // Create ARP reply for the victim pcpp::Packet victimArpReply(500); pcpp::EthLayer victimEthLayer(deviceMacAddress, victimMacAddr, static_cast(PCPP_ETHERTYPE_ARP)); - pcpp::ArpLayer victimArpLayer(pcpp::ARP_REPLY, pDevice->getMacAddress(), victimMacAddr, gatewayAddr, victimAddr); + pcpp::ArpLayer victimArpLayer(pcpp::ArpReply(pDevice->getMacAddress(), gatewayAddr, victimMacAddr, victimAddr)); victimArpReply.addLayer(&victimEthLayer); victimArpReply.addLayer(&victimArpLayer); victimArpReply.computeCalculateFields(); diff --git a/Tests/Packet++Test/Tests/VlanMplsTests.cpp b/Tests/Packet++Test/Tests/VlanMplsTests.cpp index 44ab437489..4a1bcc141a 100644 --- a/Tests/Packet++Test/Tests/VlanMplsTests.cpp +++ b/Tests/Packet++Test/Tests/VlanMplsTests.cpp @@ -52,8 +52,8 @@ PTF_TEST_CASE(VlanParseAndCreation) pcpp::EthLayer ethLayer(macSrc, macDest); pcpp::VlanLayer firstVlanLayer(666, 1, 5); pcpp::VlanLayer secondVlanLayer(200, 0, 2, PCPP_ETHERTYPE_ARP); - pcpp::ArpLayer arpLayer(pcpp::ARP_REQUEST, macSrc, pcpp::MacAddress("00:00:00:00:00:00"), - pcpp::IPv4Address("192.168.2.200"), pcpp::IPv4Address("192.168.2.254")); + pcpp::ArpLayer arpLayer( + pcpp::ArpRequest(macSrc, pcpp::IPv4Address("192.168.2.200"), pcpp::IPv4Address("192.168.2.254"))); pcpp::Packet arpWithVlanNew(1); PTF_ASSERT_TRUE(arpWithVlanNew.addLayer(ðLayer)); PTF_ASSERT_TRUE(arpWithVlanNew.addLayer(&firstVlanLayer));