Coverage Report

Created: 2025-07-11 07:47

/src/PcapPlusPlus/Packet++/header/IcmpV6Layer.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include "Layer.h"
4
5
/// @file
6
7
/// @namespace pcpp
8
/// @brief The main namespace for the PcapPlusPlus lib
9
namespace pcpp
10
{
11
  /// An enum representing the available ICMPv6 message types
12
  enum class ICMPv6MessageType : int
13
  {
14
    /// Unknown ICMPv6 message
15
    ICMPv6_UNKNOWN_MESSAGE = 0,
16
    /// Destination Unreachable Message
17
    ICMPv6_DESTINATION_UNREACHABLE = 1,
18
    /// Packet Too Big Message
19
    ICMPv6_PACKET_TOO_BIG = 2,
20
    /// Time Exceeded Message
21
    ICMPv6_TIME_EXCEEDED = 3,
22
    /// Parameter Problem Message
23
    ICMPv6_PARAMETER_PROBLEM = 4,
24
    /// Private Experimentation Message
25
    ICMPv6_PRIVATE_EXPERIMENTATION1 = 100,
26
    /// Private Experimentation Message
27
    ICMPv6_PRIVATE_EXPERIMENTATION2 = 101,
28
    /// Reserved for expansion of ICMPv6 error messages
29
    ICMPv6_RESERVED_EXPANSION_ERROR = 127,
30
    /// Echo Request Message
31
    ICMPv6_ECHO_REQUEST = 128,
32
    /// Echo Reply Message
33
    ICMPv6_ECHO_REPLY = 129,
34
    /// Multicast Listener Query Message
35
    ICMPv6_MULTICAST_LISTENER_QUERY = 130,
36
    /// Multicast Listener Report Message
37
    ICMPv6_MULTICAST_LISTENER_REPORT = 131,
38
    /// Multicast Listener Done Message
39
    ICMPv6_MULTICAST_LISTENER_DONE = 132,
40
    /// Router Solicitation Message
41
    ICMPv6_ROUTER_SOLICITATION = 133,
42
    /// Router Advertisement Message
43
    ICMPv6_ROUTER_ADVERTISEMENT = 134,
44
    /// Neighbor Solicitation Message
45
    ICMPv6_NEIGHBOR_SOLICITATION = 135,
46
    /// Neighbor Advertisement Message
47
    ICMPv6_NEIGHBOR_ADVERTISEMENT = 136,
48
    /// Redirect Message
49
    ICMPv6_REDIRECT_MESSAGE = 137,
50
    /// Router Renumbering Message
51
    ICMPv6_ROUTER_RENUMBERING = 138,
52
    /// Node Information Query Message
53
    ICMPv6_ICMP_NODE_INFORMATION_QUERY = 139,
54
    /// Node Information Reply Message
55
    ICMPv6_ICMP_NODE_INFORMATION_RESPONSE = 140,
56
    /// Inverse Neighbor Discovery Solicitation Message
57
    ICMPv6_INVERSE_NEIGHBOR_DISCOVERY_SOLICITATION_MESSAGE = 141,
58
    /// Inverse Neighbor Discovery Advertisement Message
59
    ICMPv6_INVERSE_NEIGHBOR_DISCOVERY_ADVERTISEMENT_MESSAGE = 142,
60
    /// Multicast Listener Report Message
61
    ICMPv6_MULTICAST_LISTENER_DISCOVERY_REPORTS = 143,
62
    /// Home Agent Address Discovery Request Message
63
    ICMPv6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST_MESSAGE = 144,
64
    /// Home Agent Address Discovery Reply Message
65
    ICMPv6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY_MESSAGE = 145,
66
    /// Mobile Prefix Solicitation Message
67
    ICMPv6_MOBILE_PREFIX_SOLICITATION = 146,
68
    /// Mobile Prefix Advertisement Message
69
    ICMPv6_MOBILE_PREFIX_ADVERTISEMENT = 147,
70
    /// Certification Path Solicitation Message
71
    ICMPv6_CERTIFICATION_PATH_SOLICITATION = 148,
72
    /// Certification Path Advertisement Message
73
    ICMPv6_CERTIFICATION_PATH_ADVERTISEMENT = 149,
74
    /// ICMP Experimental Mobility Subtype Format and Registry Message
75
    ICMPv6_EXPERIMENTAL_MOBILITY = 150,
76
    /// Multicast Router Advertisement Message
77
    ICMPv6_MULTICAST_ROUTER_ADVERTISEMENT = 151,
78
    /// Multicast Router Solicitation Message
79
    ICMPv6_MULTICAST_ROUTER_SOLICITATION = 152,
80
    /// Multicast Router Termination Message
81
    ICMPv6_MULTICAST_ROUTER_TERMINATION = 153,
82
    /// RPL Control Message
83
    ICMPv6_RPL_CONTROL_MESSAGE = 155,
84
    /// Private Experimentation Message
85
    ICMPv6_PRIVATE_EXPERIMENTATION3 = 200,
86
    /// Private Experimentation Message
87
    ICMPv6_PRIVATE_EXPERIMENTATION4 = 201,
88
    /// Reserved for expansion of ICMPv6 informational messages
89
    ICMPv6_RESERVED_EXPANSION_INFORMATIONAL = 255
90
  };
91
92
  /// @struct icmpv6hdr
93
  /// Represents an ICMPv6 protocol header
94
#pragma pack(push, 1)
95
  struct icmpv6hdr
96
  {
97
    /// Type of the message. Values in the range from 0 to 127 (high-order bit is 0) indicate an error message,
98
    /// while values in the range from 128 to 255 (high-order bit is 1) indicate an information message.
99
    uint8_t type;
100
    /// The code field value depends on the message type and provides an additional level of message granularity
101
    uint8_t code;
102
    /// The checksum field provides a minimal level of integrity verification for the ICMP message
103
    uint16_t checksum;
104
  };
105
#pragma pack(pop)
106
  static_assert(sizeof(icmpv6hdr) == 4, "icmpv6hdr size is not 4 bytes");
107
108
  /// @struct icmpv6_echo_hdr
109
  /// ICMP echo request/reply message structure
110
#pragma pack(push, 1)
111
  typedef struct icmpv6_echo_hdr : icmpv6hdr
112
  {
113
    /// the echo request identifier
114
    uint16_t id;
115
    /// the echo request sequence number
116
    uint16_t sequence;
117
  } icmpv6_echo_hdr;
118
#pragma pack(pop)
119
  static_assert(sizeof(icmpv6_echo_hdr) == 8, "icmpv6_echo_hdr size is not 8 bytes");
120
121
  /// @class IcmpV6Layer
122
  /// Base class for ICMPv6 protocol layers which provides common logic for ICMPv6 messages.
123
  class IcmpV6Layer : public Layer
124
  {
125
  public:
126
    /// A constructor that creates the layer from an existing packet raw data
127
    /// @param data A pointer to the raw data
128
    /// @param dataLen Size of the data in bytes
129
    /// @param prevLayer A pointer to the previous layer
130
    /// @param packet A pointer to the Packet instance where layer will be stored in
131
    IcmpV6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
132
403
        : Layer(data, dataLen, prevLayer, packet, ICMPv6)
133
403
    {}
134
135
    /// A constructor that allocates a new ICMPv6 layer with type, code and data
136
    /// @param[in] msgType Message type of the ICMPv6 layer
137
    /// @param[in] code Code field of the ICMPv6 layer
138
    /// @param[in] data A pointer to the payload to set
139
    /// @param[in] dataLen The length of the payload
140
    IcmpV6Layer(ICMPv6MessageType msgType, uint8_t code, const uint8_t* data, size_t dataLen);
141
142
    ~IcmpV6Layer() override = default;
143
144
    /// A static method that creates an ICMPv6 layer from packet raw data
145
    /// @param[in] data A pointer to the raw data
146
    /// @param[in] dataLen Size of the data in bytes
147
    /// @param[in] prevLayer A pointer to the previous layer
148
    /// @param[in] packet A pointer to the Packet instance where layer will be stored
149
    /// @return Layer* A newly allocated ICMPv6 layer
150
    static Layer* parseIcmpV6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
151
152
    /// @param[in] type Type to check
153
    /// @return True if the layer if of the given type, false otherwise
154
    bool isMessageOfType(ICMPv6MessageType type) const
155
0
    {
156
0
      return getMessageType() == type;
157
0
    }
158
159
    /// @return Get the ICMPv6 Message Type
160
    ICMPv6MessageType getMessageType() const;
161
162
    /// @return Get the code header field
163
    uint8_t getCode() const;
164
165
    /// @return Get the checksum header field in host representation
166
    uint16_t getChecksum() const;
167
168
    /// Does nothing for this layer. ICMPv6 is the last layer.
169
    void parseNextLayer() override
170
403
    {}
171
172
    /// @return The size of the ICMPv6 message
173
    size_t getHeaderLen() const override
174
125
    {
175
125
      return m_DataLen;
176
125
    }
177
178
    /// Calculate ICMPv6 checksum field
179
    void computeCalculateFields() override;
180
181
    OsiModelLayer getOsiModelLayer() const override
182
95
    {
183
95
      return OsiModelNetworkLayer;
184
95
    }
185
186
    std::string toString() const override;
187
188
  protected:
189
0
    IcmpV6Layer() = default;
190
191
  private:
192
    void calculateChecksum();
193
    icmpv6hdr* getIcmpv6Header() const
194
350
    {
195
350
      return reinterpret_cast<icmpv6hdr*>(m_Data);
196
350
    }
197
  };
198
199
  /// @class ICMPv6EchoLayer
200
  /// Represents an ICMPv6 echo request/reply protocol layer
201
  class ICMPv6EchoLayer : public IcmpV6Layer
202
  {
203
  public:
204
    /// An enum representing ICMPv6 echo message types
205
    enum ICMPv6EchoType
206
    {
207
      /// Echo Request Type
208
      REQUEST,
209
      /// Echo Reply Type
210
      REPLY
211
    };
212
213
    /// A constructor that creates the layer from an existing packet raw data
214
    /// @param[in] data A pointer to the raw data
215
    /// @param[in] dataLen Size of the data in bytes
216
    /// @param[in] prevLayer A pointer to the previous layer
217
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
218
    ICMPv6EchoLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
219
0
        : IcmpV6Layer(data, dataLen, prevLayer, packet)
220
0
    {}
221
222
    /// A constructor for a new echo request/reply layer
223
    /// @param[in] echoType The type of the echo message
224
    /// @param[in] id Echo request identifier
225
    /// @param[in] sequence Echo request sequence number
226
    /// @param[in] data A pointer to echo request payload to set
227
    /// @param[in] dataLen The length of the echo request payload
228
    ICMPv6EchoLayer(ICMPv6EchoType echoType, uint16_t id, uint16_t sequence, const uint8_t* data, size_t dataLen);
229
230
    ~ICMPv6EchoLayer() override = default;
231
232
    /// @return Identifier in host representation
233
    uint16_t getIdentifier() const;
234
235
    /// @return Sequence number in host representation
236
    uint16_t getSequenceNr() const;
237
238
    /// @return Size of the data in bytes
239
    size_t getEchoDataLen() const
240
0
    {
241
0
      return m_DataLen - sizeof(icmpv6_echo_hdr);
242
0
    }
243
244
    /// @return Pointer to the beginning of the data
245
    uint8_t* getEchoDataPtr() const
246
0
    {
247
0
      return m_Data + sizeof(icmpv6_echo_hdr);
248
0
    }
249
250
    std::string toString() const override;
251
252
  private:
253
    icmpv6_echo_hdr* getEchoHeader() const
254
0
    {
255
0
      return reinterpret_cast<icmpv6_echo_hdr*>(m_Data);
256
0
    }
257
  };
258
259
}  // namespace pcpp