Coverage Report

Created: 2026-08-15 08:03

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
    allocData(headerLen);
14
0
    m_Protocol = ARP;
15
16
0
    arphdr* arpHeader = getArpHeader();
17
0
    arpHeader->opcode = htobe16(static_cast<uint16_t>(opCode));
18
0
    senderMacAddr.copyTo(arpHeader->senderMacAddr);
19
0
    targetMacAddr.copyTo(arpHeader->targetMacAddr);
20
0
    arpHeader->senderIpAddr = senderIpAddr.toInt();
21
0
    arpHeader->targetIpAddr = targetIpAddr.toInt();
22
0
  }
23
24
  // This constructor zeroes the target MAC address for ARP requests to keep backward compatibility.
25
  ArpLayer::ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr,
26
                     const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr)
27
0
      : ArpLayer(opCode, senderMacAddr, senderIpAddr, opCode == ARP_REQUEST ? MacAddress::Zero : targetMacAddr,
28
0
                 targetIpAddr)
29
0
  {}
30
31
  ArpLayer::ArpLayer(ArpRequest const& arpRequest)
32
0
      : ArpLayer(ARP_REQUEST, arpRequest.senderMacAddr, arpRequest.senderIpAddr, MacAddress::Zero,
33
0
                 arpRequest.targetIpAddr)
34
0
  {}
35
36
  ArpLayer::ArpLayer(ArpReply const& arpReply)
37
0
      : ArpLayer(ARP_REPLY, arpReply.senderMacAddr, arpReply.senderIpAddr, arpReply.targetMacAddr,
38
0
                 arpReply.targetIpAddr)
39
0
  {}
40
41
  ArpLayer::ArpLayer(GratuitousArpRequest const& gratuitousArpRequest)
42
0
      : ArpLayer(ARP_REQUEST, gratuitousArpRequest.senderMacAddr, gratuitousArpRequest.senderIpAddr,
43
0
                 MacAddress::Broadcast, gratuitousArpRequest.senderIpAddr)
44
0
  {}
45
46
  ArpLayer::ArpLayer(GratuitousArpReply const& gratuitousArpReply)
47
0
      : ArpLayer(ARP_REPLY, gratuitousArpReply.senderMacAddr, gratuitousArpReply.senderIpAddr, MacAddress::Broadcast,
48
0
                 gratuitousArpReply.senderIpAddr)
49
0
  {}
50
51
  ArpOpcode ArpLayer::getOpcode() const
52
7.63k
  {
53
7.63k
    return static_cast<ArpOpcode>(be16toh(getArpHeader()->opcode));
54
7.63k
  }
55
56
  void ArpLayer::computeCalculateFields()
57
1.43k
  {
58
1.43k
    arphdr* arpHeader = getArpHeader();
59
1.43k
    arpHeader->hardwareType = htobe16(1);  // Ethernet
60
1.43k
    arpHeader->hardwareSize = 6;
61
1.43k
    arpHeader->protocolType = htobe16(PCPP_ETHERTYPE_IP);  // assume IPv4 over ARP
62
1.43k
    arpHeader->protocolSize = 4;                           // assume IPv4 over ARP
63
1.43k
  }
64
65
  ArpMessageType ArpLayer::getMessageType() const
66
0
  {
67
0
    switch (getOpcode())
68
0
    {
69
0
    case ArpOpcode::ARP_REQUEST:
70
0
    {
71
0
      if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr())
72
0
      {
73
0
        return ArpMessageType::GratuitousRequest;
74
0
      }
75
0
      return ArpMessageType::Request;
76
0
    }
77
0
    case ArpOpcode::ARP_REPLY:
78
0
    {
79
0
      if (getTargetMacAddress() == MacAddress::Broadcast && getSenderIpAddr() == getTargetIpAddr())
80
0
      {
81
0
        return ArpMessageType::GratuitousReply;
82
0
      }
83
0
      return ArpMessageType::Reply;
84
0
    }
85
0
    default:
86
0
      return ArpMessageType::Unknown;
87
0
    }
88
0
  }
89
90
  bool ArpLayer::isRequest() const
91
1.43k
  {
92
1.43k
    return getOpcode() == pcpp::ArpOpcode::ARP_REQUEST;
93
1.43k
  }
94
95
  bool ArpLayer::isReply() const
96
1.43k
  {
97
1.43k
    return getOpcode() == pcpp::ArpOpcode::ARP_REPLY;
98
1.43k
  }
99
100
  std::string ArpLayer::toString() const
101
2.86k
  {
102
2.86k
    switch (getOpcode())
103
2.86k
    {
104
820
    case ArpOpcode::ARP_REQUEST:
105
820
      return "ARP Layer, ARP request, who has " + getTargetIpAddr().toString() + " ? Tell " +
106
820
             getSenderIpAddr().toString();
107
138
    case ArpOpcode::ARP_REPLY:
108
138
      return "ARP Layer, ARP reply, " + getSenderIpAddr().toString() + " is at " +
109
138
             getSenderMacAddress().toString();
110
1.90k
    default:
111
1.90k
      return "ARP Layer, unknown opcode (" + std::to_string(getOpcode()) + ")";
112
2.86k
    }
113
2.86k
  }
114
115
}  // namespace pcpp