/src/PcapPlusPlus/Packet++/header/ArpLayer.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "Layer.h" |
4 | | #include "IpAddress.h" |
5 | | #include "MacAddress.h" |
6 | | |
7 | | /// @file |
8 | | |
9 | | /** |
10 | | * \namespace pcpp |
11 | | * \brief The main namespace for the PcapPlusPlus lib |
12 | | */ |
13 | | namespace pcpp |
14 | | { |
15 | | |
16 | | /** |
17 | | * @struct arphdr |
18 | | * Represents an ARP protocol header |
19 | | */ |
20 | | #pragma pack(push, 1) |
21 | | struct arphdr |
22 | | { |
23 | | /** Hardware type (HTYPE) */ |
24 | | uint16_t hardwareType; |
25 | | /** Protocol type (PTYPE). The permitted PTYPE values share a numbering space with those for EtherType */ |
26 | | uint16_t protocolType; |
27 | | /** Hardware address length (HLEN). For IPv4, this has the value 0x0800 */ |
28 | | uint8_t hardwareSize; |
29 | | /** Protocol length (PLEN). Length (in octets) of addresses used in the upper layer protocol. (The upper layer protocol specified in PTYPE.) IPv4 address size is 4 */ |
30 | | uint8_t protocolSize; |
31 | | /** Specifies the operation that the sender is performing: 1 (::ARP_REQUEST) for request, 2 (::ARP_REPLY) for reply */ |
32 | | uint16_t opcode; |
33 | | /** Sender hardware address (SHA) */ |
34 | | uint8_t senderMacAddr[6]; |
35 | | /** Sender protocol address (SPA) */ |
36 | | uint32_t senderIpAddr; |
37 | | /** Target hardware address (THA) */ |
38 | | uint8_t targetMacAddr[6]; |
39 | | /** Target protocol address (TPA) */ |
40 | | uint32_t targetIpAddr; |
41 | | }; |
42 | | #pragma pack(pop) |
43 | | |
44 | | /** |
45 | | * An enum for ARP message type |
46 | | */ |
47 | | enum ArpOpcode |
48 | | { |
49 | | ARP_REQUEST = 0x0001, ///< ARP request |
50 | | ARP_REPLY = 0x0002 ///< ARP reply (response) |
51 | | }; |
52 | | |
53 | | /** |
54 | | * @class ArpLayer |
55 | | * Represents an ARP protocol layer. Currently only IPv4 ARP messages are supported |
56 | | */ |
57 | | class ArpLayer : public Layer |
58 | | { |
59 | | public: |
60 | | /** |
61 | | * A constructor that creates the layer from an existing packet raw data |
62 | | * @param[in] data A pointer to the raw data (will be casted to @ref arphdr) |
63 | | * @param[in] dataLen Size of the data in bytes |
64 | | * @param[in] prevLayer A pointer to the previous layer |
65 | | * @param[in] packet A pointer to the Packet instance where layer will be stored in |
66 | | */ |
67 | 24.5k | ArpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = ARP; m_DataLen = sizeof(arphdr); } |
68 | | |
69 | | /** |
70 | | * A constructor that allocates a new ARP header |
71 | | * @param[in] opCode ARP message type (ARP request or ARP reply) |
72 | | * @param[in] senderMacAddr The sender MAC address (will be put in arphdr#senderMacAddr) |
73 | | * @param[in] targetMacAddr The target MAC address (will be put in arphdr#targetMacAddr) |
74 | | * @param[in] senderIpAddr The sender IP address (will be put in arphdr#senderIpAddr) |
75 | | * @param[in] targetIpAddr The target IP address (will be put in arphdr#targetIpAddr) |
76 | | */ |
77 | | ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const MacAddress& targetMacAddr, const IPv4Address& senderIpAddr, const IPv4Address& targetIpAddr); |
78 | | |
79 | 0 | ~ArpLayer() {} |
80 | | |
81 | | /** |
82 | | * Get a pointer to the ARP header. Notice this points directly to the data, so every change will change the actual packet data |
83 | | * @return A pointer to the @ref arphdr |
84 | | */ |
85 | 62.2k | inline arphdr* getArpHeader() const { return (arphdr*)m_Data; } |
86 | | |
87 | | /** |
88 | | * Get the sender hardware address (SHA) in the form of MacAddress |
89 | | * @return A MacAddress containing the sender hardware address (SHA) |
90 | | */ |
91 | 4.41k | inline MacAddress getSenderMacAddress() const { return MacAddress(getArpHeader()->senderMacAddr); } |
92 | | |
93 | | /** |
94 | | * Get the target hardware address (THA) in the form of MacAddress |
95 | | * @return A MacAddress containing the target hardware address (THA) |
96 | | */ |
97 | 0 | inline MacAddress getTargetMacAddress() const { return MacAddress(getArpHeader()->targetMacAddr); } |
98 | | |
99 | | /** |
100 | | * Get the sender protocol address (SPA) in the form of IPv4Address |
101 | | * @return An IPv4Address containing the sender protocol address (SPA) |
102 | | */ |
103 | 13.8k | inline IPv4Address getSenderIpAddr() const { return getArpHeader()->senderIpAddr; } |
104 | | |
105 | | /** |
106 | | * Get the target protocol address (TPA) in the form of IPv4Address |
107 | | * @return An IPv4Address containing the target protocol address (TPA) |
108 | | */ |
109 | 9.41k | inline IPv4Address getTargetIpAddr() const { return getArpHeader()->targetIpAddr; } |
110 | | |
111 | | // implement abstract methods |
112 | | |
113 | | /** |
114 | | * Does nothing for this layer (ArpLayer is always last) |
115 | | */ |
116 | 24.5k | void parseNextLayer() {} |
117 | | |
118 | | /** |
119 | | * @return The size of @ref arphdr |
120 | | */ |
121 | 6.91k | size_t getHeaderLen() const { return sizeof(arphdr); } |
122 | | |
123 | | /** |
124 | | * Calculate the following fields: |
125 | | * - @ref arphdr#hardwareType = Ethernet (1) |
126 | | * - @ref arphdr#hardwareSize = 6 |
127 | | * - @ref arphdr#protocolType = ETHERTYPE_IP (assume IPv4 over ARP) |
128 | | * - @ref arphdr#protocolSize = 4 (assume IPv4 over ARP) |
129 | | * - if it's an ARP request: @ref arphdr#targetMacAddr = MacAddress("00:00:00:00:00:00") |
130 | | */ |
131 | | void computeCalculateFields(); |
132 | | |
133 | | /** |
134 | | * Is this packet an ARP request? |
135 | | */ |
136 | | bool isRequest() const; |
137 | | |
138 | | /** |
139 | | * Is this packet an ARP reply? |
140 | | */ |
141 | | bool isReply() const; |
142 | | |
143 | | std::string toString() const; |
144 | | |
145 | 6.91k | OsiModelLayer getOsiModelLayer() const { return OsiModelNetworkLayer; } |
146 | | }; |
147 | | |
148 | | } // namespace pcpp |