/src/PcapPlusPlus/Packet++/header/Packet.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "RawPacket.h" |
4 | | #include "Layer.h" |
5 | | #include <vector> |
6 | | |
7 | | /// @file |
8 | | |
9 | | /** |
10 | | * \namespace pcpp |
11 | | * \brief The main namespace for the PcapPlusPlus lib |
12 | | */ |
13 | | namespace pcpp |
14 | | { |
15 | | |
16 | | /** |
17 | | * @class Packet |
18 | | * This class represents a parsed packet. It contains the raw data (RawPacket instance), and a linked list of layers, each layer is a parsed |
19 | | * protocol that this packet contains. The layers linked list is ordered where the first layer is the lowest in the packet (currently it's always |
20 | | * Ethernet protocol as PcapPlusPlus supports only Ethernet packets), the next layer will be L2.5 or L3 (e.g VLAN, IPv4, IPv6, etc.), and so on. |
21 | | * etc.), etc. The last layer in the linked list will be the highest in the packet. |
22 | | * For example: for a standard HTTP request packet the layer will look like this: EthLayer -> IPv4Layer -> TcpLayer -> HttpRequestLayer <BR> |
23 | | * Packet instance isn't read only. The user can add or remove layers, update current layer, etc. |
24 | | */ |
25 | | class Packet |
26 | | { |
27 | | friend class Layer; |
28 | | private: |
29 | | RawPacket* m_RawPacket; |
30 | | Layer* m_FirstLayer; |
31 | | Layer* m_LastLayer; |
32 | | size_t m_MaxPacketLen; |
33 | | bool m_FreeRawPacket; |
34 | | bool m_CanReallocateData; |
35 | | |
36 | | public: |
37 | | |
38 | | /** |
39 | | * A constructor for creating a new packet (with no layers). |
40 | | * When using this constructor an empty raw buffer is allocated (with the size of maxPacketLen) and a new RawPacket is created |
41 | | * @param[in] maxPacketLen The expected packet length in bytes |
42 | | */ |
43 | | explicit Packet(size_t maxPacketLen = 1); |
44 | | |
45 | | /** |
46 | | * A constructor for creating a new packet with a buffer that is pre-allocated by the user. |
47 | | * The packet is created empty (with no layers), which means the constructor doesn't parse the data in the buffer. |
48 | | * Instead, all of the raw data of this packet it written to this buffer: whenever a layer is added, it's data is written to this buffer. |
49 | | * The buffer isn't freed and it's content isn't erased when the packet object is deleted. |
50 | | * This constructor is useful when you already have a memory buffer and you want to create packet data in it. |
51 | | * @param[in] buffer A pointer to a pre-allocated memory buffer |
52 | | * @param[in] bufferSize The size of the buffer |
53 | | */ |
54 | | Packet(uint8_t* buffer, size_t bufferSize); |
55 | | |
56 | | /** |
57 | | * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network. |
58 | | * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers |
59 | | * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free |
60 | | * the instance of raw packet when the Packet is free or not |
61 | | * @param[in] rawPacket A pointer to the raw packet |
62 | | * @param[in] freeRawPacket Optional parameter. A flag indicating if the destructor should also call the raw packet destructor or not. Default value is false |
63 | | * @param[in] parseUntil Optional parameter. Parse the packet until you reach a certain protocol (inclusive). Can be useful for cases when you need to parse only up to a |
64 | | * certain layer and want to avoid the performance impact and memory consumption of parsing the whole packet. Default value is ::UnknownProtocol which means don't take this |
65 | | * parameter into account |
66 | | * @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI model (inclusive). Can be useful for cases when you need to |
67 | | * parse only up to a certain OSI layer (for example transport layer) and want to avoid the performance impact and memory consumption of parsing the whole packet. |
68 | | * Default value is ::OsiModelLayerUnknown which means don't take this parameter into account |
69 | | */ |
70 | | explicit Packet(RawPacket* rawPacket, bool freeRawPacket = false, ProtocolType parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown); |
71 | | |
72 | | /** |
73 | | * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network. |
74 | | * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers |
75 | | * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free |
76 | | * the instance of raw packet when the Packet is free or not. This constructor should be used to parse the packet up to a certain layer |
77 | | * @param[in] rawPacket A pointer to the raw packet |
78 | | * @param[in] parseUntil Parse the packet until you reach a certain protocol (inclusive). Can be useful for cases when you need to parse only up to a |
79 | | * certain layer and want to avoid the performance impact and memory consumption of parsing the whole packet |
80 | | */ |
81 | | explicit Packet(RawPacket* rawPacket, ProtocolType parseUntil); |
82 | | |
83 | | /** |
84 | | * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network. |
85 | | * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers |
86 | | * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free |
87 | | * the instance of raw packet when the Packet is free or not. This constructor should be used to parse the packet up to a certain layer |
88 | | * @param[in] rawPacket A pointer to the raw packet |
89 | | * @param[in] parseUntilFamily Parse the packet until you reach a certain protocol family (inclusive). Can be useful for cases when you need to parse only up to a |
90 | | * certain layer and want to avoid the performance impact and memory consumption of parsing the whole packet |
91 | | */ |
92 | | explicit Packet(RawPacket* rawPacket, ProtocolTypeFamily parseUntilFamily); |
93 | | |
94 | | /** |
95 | | * A constructor for creating a packet out of already allocated RawPacket. Very useful when parsing packets that came from the network. |
96 | | * When using this constructor a pointer to the RawPacket is saved (data isn't copied) and the RawPacket is parsed, meaning all layers |
97 | | * are created and linked to each other in the right order. In this overload of the constructor the user can specify whether to free |
98 | | * the instance of raw packet when the Packet is free or not. . This constructor should be used to parse the packet up to a certain layer in the OSI model |
99 | | * @param[in] rawPacket A pointer to the raw packet |
100 | | * @param[in] parseUntilLayer Optional parameter. Parse the packet until you reach a certain layer in the OSI model (inclusive). Can be useful for cases when you need to |
101 | | * parse only up to a certain OSI layer (for example transport layer) and want to avoid the performance impact and memory consumption of parsing the whole packet |
102 | | */ |
103 | | explicit Packet(RawPacket* rawPacket, OsiModelLayer parseUntilLayer); |
104 | | |
105 | | /** |
106 | | * A destructor for this class. Frees all layers allocated by this instance (Notice: it doesn't free layers that weren't allocated by this |
107 | | * class, for example layers that were added by addLayer() or insertLayer() ). In addition it frees the raw packet if it was allocated by |
108 | | * this instance (meaning if it was allocated by this instance constructor) |
109 | | */ |
110 | 1.20M | virtual ~Packet() { destructPacketData(); } |
111 | | |
112 | | /** |
113 | | * A copy constructor for this class. This copy constructor copies all the raw data and re-create all layers. So when the original Packet |
114 | | * is being freed, no data will be lost in the copied instance |
115 | | * @param[in] other The instance to copy from |
116 | | */ |
117 | 893k | Packet(const Packet& other) { copyDataFrom(other); } |
118 | | |
119 | | /** |
120 | | * Assignment operator overloading. It first frees all layers allocated by this instance (Notice: it doesn't free layers that weren't allocated by this |
121 | | * class, for example layers that were added by addLayer() or insertLayer() ). In addition it frees the raw packet if it was allocated by |
122 | | * this instance (meaning if it was allocated by this instance constructor). |
123 | | * Afterwards it copies the data from the other packet in the same way used in the copy constructor. |
124 | | * @param[in] other The instance to copy from |
125 | | */ |
126 | | Packet& operator=(const Packet& other); |
127 | | |
128 | | /** |
129 | | * Get a pointer to the Packet's RawPacket |
130 | | * @return A pointer to the Packet's RawPacket |
131 | | */ |
132 | 0 | RawPacket* getRawPacket() const { return m_RawPacket; } |
133 | | |
134 | | /** |
135 | | * Set a RawPacket and re-construct all packet layers |
136 | | * @param[in] rawPacket Raw packet to set |
137 | | * @param[in] freeRawPacket A flag indicating if the destructor should also call the raw packet destructor or not |
138 | | * @param[in] parseUntil Parse the packet until it reaches this protocol. Can be useful for cases when you need to parse only up to a certain layer and want to avoid the |
139 | | * performance impact and memory consumption of parsing the whole packet. Default value is ::UnknownProtocol which means don't take this parameter into account |
140 | | * @param[in] parseUntilLayer Parse the packet until certain layer in OSI model. Can be useful for cases when you need to parse only up to a certain layer and want to avoid the |
141 | | * performance impact and memory consumption of parsing the whole packet. Default value is ::OsiModelLayerUnknown which means don't take this parameter into account |
142 | | */ |
143 | | void setRawPacket(RawPacket* rawPacket, bool freeRawPacket, ProtocolTypeFamily parseUntil = UnknownProtocol, OsiModelLayer parseUntilLayer = OsiModelLayerUnknown); |
144 | | |
145 | | /** |
146 | | * Get a pointer to the Packet's RawPacket in a read-only manner |
147 | | * @return A pointer to the Packet's RawPacket |
148 | | */ |
149 | 0 | RawPacket* getRawPacketReadOnly() const { return m_RawPacket; } |
150 | | |
151 | | /** |
152 | | * Get a pointer to the first (lowest) layer in the packet |
153 | | * @return A pointer to the first (lowest) layer in the packet |
154 | | */ |
155 | 19.0M | Layer* getFirstLayer() const { return m_FirstLayer; } |
156 | | |
157 | | /** |
158 | | * Get a pointer to the last (highest) layer in the packet |
159 | | * @return A pointer to the last (highest) layer in the packet |
160 | | */ |
161 | 0 | Layer* getLastLayer() const { return m_LastLayer; } |
162 | | |
163 | | /** |
164 | | * Add a new layer as the last layer in the packet. This method gets a pointer to the new layer as a parameter |
165 | | * and attaches it to the packet. Notice after calling this method the input layer is attached to the packet so |
166 | | * every change you make in it affect the packet; Also it cannot be attached to other packets |
167 | | * @param[in] newLayer A pointer to the new layer to be added to the packet |
168 | | * @param[in] ownInPacket If true, Packet fully owns newLayer, including memory deletion upon destruct. Default is false. |
169 | | * @return True if everything went well or false otherwise (an appropriate error log message will be printed in |
170 | | * such cases) |
171 | | */ |
172 | 0 | bool addLayer(Layer* newLayer, bool ownInPacket = false) { return insertLayer(m_LastLayer, newLayer, ownInPacket); } |
173 | | |
174 | | /** |
175 | | * Insert a new layer after an existing layer in the packet. This method gets a pointer to the new layer as a |
176 | | * parameter and attaches it to the packet. Notice after calling this method the input layer is attached to the |
177 | | * packet so every change you make in it affect the packet; Also it cannot be attached to other packets |
178 | | * @param[in] prevLayer A pointer to an existing layer in the packet which the new layer should followed by. If |
179 | | * this layer isn't attached to a packet and error will be printed to log and false will be returned |
180 | | * @param[in] newLayer A pointer to the new layer to be added to the packet |
181 | | * @param[in] ownInPacket If true, Packet fully owns newLayer, including memory deletion upon destruct. Default is false. |
182 | | * @return True if everything went well or false otherwise (an appropriate error log message will be printed in |
183 | | * such cases) |
184 | | */ |
185 | | bool insertLayer(Layer* prevLayer, Layer* newLayer, bool ownInPacket = false); |
186 | | |
187 | | |
188 | | /** |
189 | | * Remove an existing layer from the packet. The layer to removed is identified by its type (protocol). If the |
190 | | * packet has multiple layers of the same type in the packet the user may specify the index of the layer to remove |
191 | | * (the default index is 0 - remove the first layer of this type). If the layer was allocated during packet creation |
192 | | * it will be deleted and any pointer to it will get invalid. However if the layer was allocated by the user and |
193 | | * manually added to the packet it will simply get detached from the packet, meaning the pointer to it will stay |
194 | | * valid and its data (that was removed from the packet) will be copied back to the layer. In that case it's |
195 | | * the user's responsibility to delete the layer instance |
196 | | * @param[in] layerType The layer type (protocol) to remove |
197 | | * @param[in] index If there are multiple layers of the same type, indicate which instance to remove. The default |
198 | | * value is 0, meaning remove the first layer of this type |
199 | | * @return True if everything went well or false otherwise (an appropriate error log message will be printed in |
200 | | * such cases) |
201 | | */ |
202 | | bool removeLayer(ProtocolType layerType, int index = 0); |
203 | | |
204 | | /** |
205 | | * Remove the first layer in the packet. The layer will be deleted if it was allocated during packet creation, or detached |
206 | | * if was allocated outside of the packet. Please refer to removeLayer() to get more info |
207 | | * @return True if layer removed successfully, or false if removing the layer failed or if there are no layers in the |
208 | | * packet. In any case of failure an appropriate error log message will be printed |
209 | | */ |
210 | | bool removeFirstLayer(); |
211 | | |
212 | | /** |
213 | | * Remove the last layer in the packet. The layer will be deleted if it was allocated during packet creation, or detached |
214 | | * if was allocated outside of the packet. Please refer to removeLayer() to get more info |
215 | | * @return True if layer removed successfully, or false if removing the layer failed or if there are no layers in the |
216 | | * packet. In any case of failure an appropriate error log message will be printed |
217 | | */ |
218 | | bool removeLastLayer(); |
219 | | |
220 | | /** |
221 | | * Remove all layers that come after a certain layer. All layers removed will be deleted if they were allocated during |
222 | | * packet creation or detached if were allocated outside of the packet, please refer to removeLayer() to get more info |
223 | | * @param[in] layer A pointer to the layer to begin removing from. Please note this layer will not be removed, only the |
224 | | * layers that come after it will be removed. Also, if removal of one layer failed, the method will return immediately and |
225 | | * the following layers won't be deleted |
226 | | * @return True if all layers were removed successfully, or false if failed to remove at least one layer. In any case of |
227 | | * failure an appropriate error log message will be printed |
228 | | */ |
229 | | bool removeAllLayersAfter(Layer* layer); |
230 | | |
231 | | /** |
232 | | * Detach a layer from the packet. Detaching means the layer instance will not be deleted, but rather separated from the |
233 | | * packet - e.g it will be removed from the layer chain of the packet and its data will be copied from the packet buffer |
234 | | * into an internal layer buffer. After a layer is detached, it can be added into another packet (but it's impossible to |
235 | | * attach a layer to multiple packets in the same time). After layer is detached, it's the user's responsibility to |
236 | | * delete it when it's not needed anymore |
237 | | * @param[in] layerType The layer type (protocol) to detach from the packet |
238 | | * @param[in] index If there are multiple layers of the same type, indicate which instance to detach. The default |
239 | | * value is 0, meaning detach the first layer of this type |
240 | | * @return A pointer to the detached layer or NULL if detaching process failed. In any case of failure an |
241 | | * appropriate error log message will be printed |
242 | | */ |
243 | | Layer* detachLayer(ProtocolType layerType, int index = 0); |
244 | | |
245 | | /** |
246 | | * Detach a layer from the packet. Detaching means the layer instance will not be deleted, but rather separated from the |
247 | | * packet - e.g it will be removed from the layer chain of the packet and its data will be copied from the packet buffer |
248 | | * into an internal layer buffer. After a layer is detached, it can be added into another packet (but it's impossible to |
249 | | * attach a layer to multiple packets at the same time). After layer is detached, it's the user's responsibility to |
250 | | * delete it when it's not needed anymore |
251 | | * @param[in] layer A pointer to the layer to detach |
252 | | * @return True if the layer was detached successfully, or false if something went wrong. In any case of failure an |
253 | | * appropriate error log message will be printed |
254 | | */ |
255 | 0 | bool detachLayer(Layer* layer) { return removeLayer(layer, false); } |
256 | | |
257 | | /** |
258 | | * Get a pointer to the layer of a certain type (protocol). This method goes through the layers and returns a layer |
259 | | * that matches the give protocol type |
260 | | * @param[in] layerType The layer type (protocol) to fetch |
261 | | * @param[in] index If there are multiple layers of the same type, indicate which instance to fetch. The default |
262 | | * value is 0, meaning fetch the first layer of this type |
263 | | * @return A pointer to the layer or NULL if no such layer was found |
264 | | */ |
265 | | Layer* getLayerOfType(ProtocolType layerType, int index = 0) const; |
266 | | |
267 | | /** |
268 | | * A templated method to get a layer of a certain type (protocol). If no layer of such type is found, NULL is returned |
269 | | * @param[in] reverseOrder The optional parameter that indicates that the lookup should run in reverse order, the default value is false |
270 | | * @return A pointer to the layer of the requested type, NULL if not found |
271 | | */ |
272 | | template<class TLayer> |
273 | | TLayer* getLayerOfType(bool reverseOrder = false) const; |
274 | | |
275 | | /** |
276 | | * A templated method to get the first layer of a certain type (protocol), start searching from a certain layer. |
277 | | * For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> IPv4Layer |
278 | | * and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(3) will be returned |
279 | | * If no layer of such type is found, NULL is returned |
280 | | * @param[in] startLayer A pointer to the layer to start search from |
281 | | * @return A pointer to the layer of the requested type, NULL if not found |
282 | | */ |
283 | | template<class TLayer> |
284 | | TLayer* getNextLayerOfType(Layer* startLayer) const; |
285 | | |
286 | | /** |
287 | | * A templated method to get the first layer of a certain type (protocol), start searching from a certain layer. |
288 | | * For example: if a packet looks like: EthLayer -> VlanLayer(1) -> VlanLayer(2) -> VlanLayer(3) -> IPv4Layer |
289 | | * and the user put VlanLayer(2) as a parameter and wishes to search for a VlanLayer, VlanLayer(1) will be returned |
290 | | * If no layer of such type is found, NULL is returned |
291 | | * @param[in] startLayer A pointer to the layer to start search from |
292 | | * @return A pointer to the layer of the requested type, NULL if not found |
293 | | */ |
294 | | template<class TLayer> |
295 | | TLayer* getPrevLayerOfType(Layer* startLayer) const; |
296 | | |
297 | | /** |
298 | | * Check whether the packet contains a layer of a certain protocol |
299 | | * @param[in] protocolType The protocol type to search |
300 | | * @return True if the packet contains a layer of a certain protocol, false otherwise |
301 | | */ |
302 | | bool isPacketOfType(ProtocolType protocolType) const; |
303 | | |
304 | | /** |
305 | | * Check whether the packet contains a layer of a certain protocol family |
306 | | * @param[in] protocolTypeFamily The protocol type family to search |
307 | | * @return True if the packet contains a layer of a certain protocol family, false otherwise |
308 | | */ |
309 | | bool isPacketOfType(ProtocolTypeFamily protocolTypeFamily) const; |
310 | | |
311 | | /** |
312 | | * Each layer can have fields that can be calculate automatically from other fields using Layer#computeCalculateFields(). This method forces all layers to calculate these |
313 | | * fields values |
314 | | */ |
315 | | void computeCalculateFields(); |
316 | | |
317 | | /** |
318 | | * Each layer can print a string representation of the layer most important data using Layer#toString(). This method aggregates this string from all layers and |
319 | | * print it to a complete string containing all packet's relevant data |
320 | | * @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set to false |
321 | | * @return A string containing most relevant data from all layers (looks like the packet description in Wireshark) |
322 | | */ |
323 | | std::string toString(bool timeAsLocalTime = true) const; |
324 | | |
325 | | /** |
326 | | * Similar to toString(), but instead of one string it outputs a list of strings, one string for every layer |
327 | | * @param[out] result A string vector that will contain all strings |
328 | | * @param[in] timeAsLocalTime Print time as local time or GMT. Default (true value) is local time, for GMT set to false |
329 | | */ |
330 | | void toStringList(std::vector<std::string>& result, bool timeAsLocalTime = true) const; |
331 | | |
332 | | private: |
333 | | void copyDataFrom(const Packet& other); |
334 | | |
335 | | void destructPacketData(); |
336 | | |
337 | | bool extendLayer(Layer* layer, int offsetInLayer, size_t numOfBytesToExtend); |
338 | | bool shortenLayer(Layer* layer, int offsetInLayer, size_t numOfBytesToShorten); |
339 | | |
340 | | void reallocateRawData(size_t newSize); |
341 | | |
342 | | bool removeLayer(Layer* layer, bool tryToDelete); |
343 | | |
344 | | std::string printPacketInfo(bool timeAsLocalTime) const; |
345 | | |
346 | | Layer* createFirstLayer(LinkLayerType linkType); |
347 | | }; // class Packet |
348 | | |
349 | | |
350 | | // implementation of inline methods |
351 | | |
352 | | template<class TLayer> |
353 | | TLayer* Packet::getLayerOfType(bool reverse) const |
354 | 4.55k | { |
355 | 4.55k | if (!reverse) |
356 | 4.55k | { |
357 | 4.55k | if (dynamic_cast<TLayer*>(getFirstLayer()) != NULL) |
358 | 0 | return dynamic_cast<TLayer*>(getFirstLayer()); |
359 | | |
360 | 4.55k | return getNextLayerOfType<TLayer>(getFirstLayer()); |
361 | 4.55k | } |
362 | | |
363 | | // lookup in reverse order |
364 | 0 | if (dynamic_cast<TLayer*>(getLastLayer()) != NULL) |
365 | 0 | return dynamic_cast<TLayer*>(getLastLayer()); |
366 | | |
367 | 0 | return getPrevLayerOfType<TLayer>(getLastLayer()); |
368 | 0 | } Unexecuted instantiation: pcpp::TcpLayer* pcpp::Packet::getLayerOfType<pcpp::TcpLayer>(bool) const Unexecuted instantiation: pcpp::UdpLayer* pcpp::Packet::getLayerOfType<pcpp::UdpLayer>(bool) const Unexecuted instantiation: pcpp::IPv4Layer* pcpp::Packet::getLayerOfType<pcpp::IPv4Layer>(bool) const Unexecuted instantiation: pcpp::IPv6Layer* pcpp::Packet::getLayerOfType<pcpp::IPv6Layer>(bool) const pcpp::IPLayer* pcpp::Packet::getLayerOfType<pcpp::IPLayer>(bool) const Line | Count | Source | 354 | 4.55k | { | 355 | 4.55k | if (!reverse) | 356 | 4.55k | { | 357 | 4.55k | if (dynamic_cast<TLayer*>(getFirstLayer()) != NULL) | 358 | 0 | return dynamic_cast<TLayer*>(getFirstLayer()); | 359 | | | 360 | 4.55k | return getNextLayerOfType<TLayer>(getFirstLayer()); | 361 | 4.55k | } | 362 | | | 363 | | // lookup in reverse order | 364 | 0 | if (dynamic_cast<TLayer*>(getLastLayer()) != NULL) | 365 | 0 | return dynamic_cast<TLayer*>(getLastLayer()); | 366 | | | 367 | 0 | return getPrevLayerOfType<TLayer>(getLastLayer()); | 368 | 0 | } |
|
369 | | |
370 | | template<class TLayer> |
371 | | TLayer* Packet::getNextLayerOfType(Layer* curLayer) const |
372 | 4.55k | { |
373 | 4.55k | if (curLayer == NULL) |
374 | 0 | return NULL; |
375 | | |
376 | 4.55k | curLayer = curLayer->getNextLayer(); |
377 | 4.55k | while ((curLayer != NULL) && (dynamic_cast<TLayer*>(curLayer) == NULL)) |
378 | 0 | { |
379 | 0 | curLayer = curLayer->getNextLayer(); |
380 | 0 | } |
381 | | |
382 | 4.55k | return dynamic_cast<TLayer*>(curLayer); |
383 | 4.55k | } Unexecuted instantiation: pcpp::TcpLayer* pcpp::Packet::getNextLayerOfType<pcpp::TcpLayer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::UdpLayer* pcpp::Packet::getNextLayerOfType<pcpp::UdpLayer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::IPv4Layer* pcpp::Packet::getNextLayerOfType<pcpp::IPv4Layer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::IPv6Layer* pcpp::Packet::getNextLayerOfType<pcpp::IPv6Layer>(pcpp::Layer*) const pcpp::IPLayer* pcpp::Packet::getNextLayerOfType<pcpp::IPLayer>(pcpp::Layer*) const Line | Count | Source | 372 | 4.55k | { | 373 | 4.55k | if (curLayer == NULL) | 374 | 0 | return NULL; | 375 | | | 376 | 4.55k | curLayer = curLayer->getNextLayer(); | 377 | 4.55k | while ((curLayer != NULL) && (dynamic_cast<TLayer*>(curLayer) == NULL)) | 378 | 0 | { | 379 | 0 | curLayer = curLayer->getNextLayer(); | 380 | 0 | } | 381 | | | 382 | 4.55k | return dynamic_cast<TLayer*>(curLayer); | 383 | 4.55k | } |
|
384 | | |
385 | | template<class TLayer> |
386 | | TLayer* Packet::getPrevLayerOfType(Layer* curLayer) const |
387 | 0 | { |
388 | 0 | if (curLayer == NULL) |
389 | 0 | return NULL; |
390 | | |
391 | 0 | curLayer = curLayer->getPrevLayer(); |
392 | 0 | while (curLayer != NULL && dynamic_cast<TLayer*>(curLayer) == NULL) |
393 | 0 | { |
394 | 0 | curLayer = curLayer->getPrevLayer(); |
395 | 0 | } |
396 | |
|
397 | 0 | return dynamic_cast<TLayer*>(curLayer); |
398 | 0 | } Unexecuted instantiation: pcpp::TcpLayer* pcpp::Packet::getPrevLayerOfType<pcpp::TcpLayer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::UdpLayer* pcpp::Packet::getPrevLayerOfType<pcpp::UdpLayer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::IPv4Layer* pcpp::Packet::getPrevLayerOfType<pcpp::IPv4Layer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::IPv6Layer* pcpp::Packet::getPrevLayerOfType<pcpp::IPv6Layer>(pcpp::Layer*) const Unexecuted instantiation: pcpp::IPLayer* pcpp::Packet::getPrevLayerOfType<pcpp::IPLayer>(pcpp::Layer*) const |
399 | | |
400 | | } // namespace pcpp |
401 | | |
402 | | inline std::ostream& operator<<(std::ostream& os, const pcpp::Packet& packet) |
403 | 0 | { |
404 | 0 | os << packet.toString(); |
405 | 0 | return os; |
406 | 0 | } |