/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 |