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