Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow gratuitous ARP requests. #1684

Open
wants to merge 16 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Common++/header/MacAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
2 changes: 2 additions & 0 deletions Common++/src/MacAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
75 changes: 75 additions & 0 deletions Packet++/header/ArpLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,57 @@ namespace pcpp
ARP_REPLY = 0x0002 ///< ARP reply (response)
};

/**
* @brief A struct representing the build data for an ARP request
*/
struct ArpRequest
{
MacAddress senderMacAddr;
IPv4Address senderIpAddr;
IPv4Address targetIpAddr;

ArpRequest(MacAddress senderMacAddress, IPv4Address senderIPAddress, IPv4Address targetIPAddress)
: senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress), targetIpAddr(targetIPAddress) {};
Dimi1010 marked this conversation as resolved.
Show resolved Hide resolved
};

/**
* @brief A struct representing the build data for an ARP reply
*/
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) {};
};

/**
* @brief A struct representing the build data for a gratuitous ARP request
*/
struct GratuitousArpRequest
{
MacAddress senderMacAddr;
IPv4Address senderIpAddr;
GratuitousArpRequest(MacAddress senderMacAddress, IPv4Address senderIPAddress)
: senderMacAddr(senderMacAddress), senderIpAddr(senderIPAddress) {};
};

/**
* @brief A struct representing the build data a gratuitous ARP reply
*/
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
Expand Down Expand Up @@ -83,6 +134,30 @@ namespace pcpp
ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr,
Dimi1010 marked this conversation as resolved.
Show resolved Hide resolved
const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr);

/**
* @brief A constructor that creates an ARP request header.
* @param arpRequest The ARP request data
*/
explicit ArpLayer(ArpRequest const& arpRequest);

/**
* @brief A constructor that creates an ARP reply header.
* @param arpReply The ARP reply data
*/
explicit ArpLayer(ArpReply const& arpReply);

/**
* @brief A constructor that creates a gratuitous ARP request header.
* @param gratuitousArpRequest The gratuitous ARP request data
*/
explicit ArpLayer(GratuitousArpRequest const& gratuitousArpRequest);

/**
* @brief A constructor that creates a gratuitous ARP reply header.
* @param gratuitousArpReply The gratuitous ARP reply data
*/
explicit ArpLayer(GratuitousArpReply const& gratuitousArpReply);

~ArpLayer() override = default;

/**
Expand Down
24 changes: 21 additions & 3 deletions Packet++/src/ArpLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -24,15 +24,33 @@ 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();
arpHeader->hardwareType = htobe16(1); // Ethernet
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
Expand Down
Loading