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