Coverage Report

Created: 2024-02-25 06:29

/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