/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 |