Coverage Report

Created: 2025-07-18 07:14

/src/PcapPlusPlus/Packet++/src/ArpLayer.cpp
Line
Count
Source (jump to first uncovered line)
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
5.41k
  {
54
5.41k
    return static_cast<ArpOpcode>(be16toh(getArpHeader()->opcode));
55
5.41k
  }
56
57
  void ArpLayer::computeCalculateFields()
58
1.00k
  {
59
1.00k
    arphdr* arpHeader = getArpHeader();
60
1.00k
    arpHeader->hardwareType = htobe16(1);  // Ethernet
61
1.00k
    arpHeader->hardwareSize = 6;
62
1.00k
    arpHeader->protocolType = htobe16(PCPP_ETHERTYPE_IP);  // assume IPv4 over ARP
63
1.00k
    arpHeader->protocolSize = 4;                           // assume IPv4 over ARP
64
1.00k
  }
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
1.00k
  {
93
1.00k
    return getOpcode() == pcpp::ArpOpcode::ARP_REQUEST;
94
1.00k
  }
95
96
  bool ArpLayer::isReply() const
97
1.00k
  {
98
1.00k
    return getOpcode() == pcpp::ArpOpcode::ARP_REPLY;
99
1.00k
  }
100
101
  std::string ArpLayer::toString() const
102
2.01k
  {
103
2.01k
    switch (getOpcode())
104
2.01k
    {
105
392
    case ArpOpcode::ARP_REQUEST:
106
392
      return "ARP Layer, ARP request, who has " + getTargetIpAddr().toString() + " ? Tell " +
107
392
             getSenderIpAddr().toString();
108
238
    case ArpOpcode::ARP_REPLY:
109
238
      return "ARP Layer, ARP reply, " + getSenderIpAddr().toString() + " is at " +
110
238
             getSenderMacAddress().toString();
111
1.38k
    default:
112
1.38k
      return "ARP Layer, unknown opcode (" + std::to_string(getOpcode()) + ")";
113
2.01k
    }
114
2.01k
  }
115
116
}  // namespace pcpp