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