Coverage Report

Created: 2026-10-17 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/header/IcmpV6Layer.h
Line
Count
Source
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
0
        : Layer(data, dataLen, prevLayer, packet, ICMPv6)
133
0
    {}
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
0
    {}
171
172
    /// @return The size of the ICMPv6 message
173
    size_t getHeaderLen() const override
174
0
    {
175
0
      return m_DataLen;
176
0
    }
177
178
    /// Calculate ICMPv6 checksum field
179
    void computeCalculateFields() override;
180
181
    OsiModelLayer getOsiModelLayer() const override
182
0
    {
183
0
      return OsiModelNetworkLayer;
184
0
    }
185
186
    std::string toString() const override;
187
188
    /// @struct SerializedFields
189
    /// Fields written by IcmpV6Layer's serializeLayer(), in addition to
190
    /// Layer::SerializedFields.
191
    struct SerializedFields : Layer::SerializedFields
192
    {
193
      /// @brief The highest field ID used by IcmpV6Layer
194
      static constexpr uint16_t MaxID = Layer::SerializedFields::MaxID + 4;
195
196
      /// @return All field descriptors for IcmpV6Layer
197
      static std::vector<FieldDescriptor> all()
198
0
      {
199
0
        auto result = Layer::SerializedFields::all();
200
0
        std::initializer_list<FieldDescriptor> extra{ Type, TypeName, Code, Checksum };
201
0
        std::copy(extra.begin(), extra.end(), std::back_inserter(result));
202
0
        return result;
203
0
      }
204
205
      /// @brief ICMPv6 message type, as an integer
206
      static const FieldDescriptor Type;
207
208
      /// @brief ICMPv6 message type, as a string
209
      static const FieldDescriptor TypeName;
210
211
      /// @brief ICMPv6 message code, as an integer
212
      static const FieldDescriptor Code;
213
214
      /// @brief Checksum, in hexadecimal notation
215
      static const FieldDescriptor Checksum;
216
    };
217
218
  protected:
219
0
    IcmpV6Layer() = default;
220
221
    void serializeLayer(ObjectScope& serializer) const override;
222
223
  private:
224
    void calculateChecksum();
225
    icmpv6hdr* getIcmpv6Header() const
226
0
    {
227
0
      return reinterpret_cast<icmpv6hdr*>(m_Data);
228
0
    }
229
  };
230
231
  /// @class ICMPv6EchoLayer
232
  /// Represents an ICMPv6 echo request/reply protocol layer
233
  class ICMPv6EchoLayer : public IcmpV6Layer
234
  {
235
  public:
236
    /// An enum representing ICMPv6 echo message types
237
    enum ICMPv6EchoType
238
    {
239
      /// Echo Request Type
240
      REQUEST,
241
      /// Echo Reply Type
242
      REPLY
243
    };
244
245
    /// A constructor that creates the layer from an existing packet raw data
246
    /// @param[in] data A pointer to the raw data
247
    /// @param[in] dataLen Size of the data in bytes
248
    /// @param[in] prevLayer A pointer to the previous layer
249
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
250
    ICMPv6EchoLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
251
0
        : IcmpV6Layer(data, dataLen, prevLayer, packet)
252
0
    {}
253
254
    /// A constructor for a new echo request/reply layer
255
    /// @param[in] echoType The type of the echo message
256
    /// @param[in] id Echo request identifier
257
    /// @param[in] sequence Echo request sequence number
258
    /// @param[in] data A pointer to echo request payload to set
259
    /// @param[in] dataLen The length of the echo request payload
260
    ICMPv6EchoLayer(ICMPv6EchoType echoType, uint16_t id, uint16_t sequence, const uint8_t* data, size_t dataLen);
261
262
    ~ICMPv6EchoLayer() override = default;
263
264
    /// @return Identifier in host representation
265
    uint16_t getIdentifier() const;
266
267
    /// @return Sequence number in host representation
268
    uint16_t getSequenceNr() const;
269
270
    /// @return Size of the data in bytes
271
    size_t getEchoDataLen() const
272
0
    {
273
0
      return m_DataLen - sizeof(icmpv6_echo_hdr);
274
0
    }
275
276
    /// @return Pointer to the beginning of the data
277
    uint8_t* getEchoDataPtr() const
278
0
    {
279
0
      return m_Data + sizeof(icmpv6_echo_hdr);
280
0
    }
281
282
    std::string toString() const override;
283
284
    /// @struct SerializedFields
285
    /// Fields written by ICMPv6EchoLayer's serializeLayer(), in addition to
286
    /// IcmpV6Layer::SerializedFields.
287
    struct SerializedFields : IcmpV6Layer::SerializedFields
288
    {
289
      /// @return All field descriptors for ICMPv6EchoLayer
290
      static std::vector<FieldDescriptor> all()
291
0
      {
292
0
        auto result = IcmpV6Layer::SerializedFields::all();
293
0
        std::initializer_list<FieldDescriptor> extra{ Identifier, Sequence };
294
0
        std::copy(extra.begin(), extra.end(), std::back_inserter(result));
295
0
        return result;
296
0
      }
297
298
      /// @brief Echo identifier, in host byte order
299
      static const FieldDescriptor Identifier;
300
301
      /// @brief Echo sequence number, in host byte order
302
      static const FieldDescriptor Sequence;
303
    };
304
305
  protected:
306
    void serializeLayer(ObjectScope& serializer) const override;
307
308
  private:
309
    icmpv6_echo_hdr* getEchoHeader() const
310
0
    {
311
0
      return reinterpret_cast<icmpv6_echo_hdr*>(m_Data);
312
0
    }
313
  };
314
315
}  // namespace pcpp