Coverage Report

Created: 2026-06-30 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/ArpLayer.cpp
Line
Count
Source
1
#define LOG_MODULE PacketLogModuleArpLayer
2
3
#include "ArpLayer.h"
4
#include "EthLayer.h"
5
#include "EndianPortable.h"
6
7
namespace pcpp
8
{
9
  ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr,
10
                     const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr)
11
0
  {
12
0
    constexpr size_t headerLen = sizeof(arphdr);
13
0
    m_DataLen = headerLen;
14
0
    m_Data = new uint8_t[headerLen]{};  // zero-initialized
15
0
    m_Protocol = ARP;
16
17
0
    arphdr* arpHeader = getArpHeader();
18
0
    arpHeader->opcode = htobe16(static_cast<uint16_t>(opCode));
19
0
    senderMacAddr.copyTo(arpHeader->senderMacAddr);
20
0
    targetMacAddr.copyTo(arpHeader->targetMacAddr);
21
0
    arpHeader->senderIpAddr = senderIpAddr.toInt();
22
0
    arpHeader->targetIpAddr = targetIpAddr.toInt();
23
0
  }
24
25
  // This constructor zeroes the target MAC address for ARP requests to keep backward compatibility.
26
  ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr,
27
                     const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr)
28
0
      : ArpLayer(opCode, senderMacAddr, senderIpAddr, opCode == ARP_REQUEST ? MacAddress::Zero : targetMacAddr,
29
0
                 targetIpAddr)
30
0
  {}
31
32
  ArpLayer::ArpLayer(ArpRequest const& arpRequest)
33
0
      : ArpLayer(ARP_REQUEST, arpRequest.senderMacAddr, arpRequest.senderIpAddr, MacAddress::Zero,
34
0
                 arpRequest.targetIpAddr)
35
0
  {}
36
37
  ArpLayer::ArpLayer(ArpReply const& arpReply)
38
0
      : ArpLayer(ARP_REPLY, arpReply.senderMacAddr, arpReply.senderIpAddr, arpReply.targetMacAddr,
39
0
                 arpReply.targetIpAddr)
40
0
  {}
41
42
  ArpLayer::ArpLayer(GratuitousArpRequest const& gratuitousArpRequest)
43
0
      : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, gratuitousArpRequest.senderIpAddr,
44
0
                 MacAddress::Broadcast, gratuitousArpRequest.senderIpAddr)
45
0
  {}
46
47
  ArpLayer::ArpLayer(GratuitousArpReply const& gratuitousArpReply)
48
0
      : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, gratuitousArpReply.senderIpAddr, MacAddress::Broadcast,
49
0
                 gratuitousArpReply.senderIpAddr)
50
0
  {}
51
52
  ArpOpcode ArpLayer::getOpcode() const
53
18.6k
  {
54
18.6k
    return static_cast<ArpOpcode>(be16toh(getArpHeader()->opcode));
55
18.6k
  }
56
57
  void ArpLayer::computeCalculateFields()
58
4.59k
  {
59
4.59k
    arphdr* arpHeader = getArpHeader();
60
4.59k
    arpHeader->hardwareType = htobe16(1);  // Ethernet
61
4.59k
    arpHeader->hardwareSize = 6;
62
4.59k
    arpHeader->protocolType = htobe16(PCPP_ETHERTYPE_IP);  // assume IPv4 over ARP
63
4.59k
    arpHeader->protocolSize = 4;                           // assume IPv4 over ARP
64
4.59k
  }
65
66
  ArpMessageType ArpLayer::getMessageType() const
67
0
  {
68
0
    switch (getOpcode())
69
0
    {
70
0
    case ArpOpcode::ARP_REQUEST:
71
0
    {
72
0
      if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr())
73
0
      {
74
0
        return ArpMessageType::GratuitousRequest;
75
0
      }
76
0
      return ArpMessageType::Request;
77
0
    }
78
0
    case ArpOpcode::ARP_REPLY:
79
0
    {
80
0
      if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr())
81
0
      {
82
0
        return ArpMessageType::GratuitousReply;
83
0
      }
84
0
      return ArpMessageType::Reply;
85
0
    }
86
0
    default:
87
0
      return ArpMessageType::Unknown;
88
0
    }
89
0
  }
90
91
  bool ArpLayer::isRequest() const
92
4.59k
  {
93
4.59k
    return getOpcode() == pcpp::ArpOpcode::ARP_REQUEST;
94
4.59k
  }
95
96
  bool ArpLayer::isReply() const
97
4.59k
  {
98
4.59k
    return getOpcode() == pcpp::ArpOpcode::ARP_REPLY;
99
4.59k
  }
100
101
  std::string ArpLayer::toString() const
102
9.19k
  {
103
9.19k
    switch (getOpcode())
104
9.19k
    {
105
7.30k
    case ArpOpcode::ARP_REQUEST:
106
7.30k
      return "ARP Layer, ARP request, who has " + getTargetIpAddr().toString() + " ? Tell " +
107
7.30k
             getSenderIpAddr().toString();
108
1.64k
    case ArpOpcode::ARP_REPLY:
109
1.64k
      return "ARP Layer, ARP reply, " + getSenderIpAddr().toString() + " is at " +
110
1.64k
             getSenderMacAddress().toString();
111
238
    default:
112
238
      return "ARP Layer, unknown opcode (" + std::to_string(getOpcode()) + ")";
113
9.19k
    }
114
9.19k
  }
115
116
}  // namespace pcpp