Coverage Report

Created: 2023-01-17 06:15

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