Coverage Report

Created: 2024-02-25 06:29

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