Skip to content

Commit 1c9116f

Browse files
Dimi1010seladb
andauthored
Update parsing procedures to use new "construct" API. (#2046)
* Add construct next layer utilities that automatically infer the packet. * Update IPv6 parsing. * Update VLan layer. * Lint * Update SSLLayer. * Update Sll2 layer. * Update null loopback. * Update nflog layer. * Update Cisco layer. --------- Co-authored-by: seladb <pcapplusplus@gmail.com>
1 parent 33b9be1 commit 1c9116f

File tree

8 files changed

+211
-118
lines changed

8 files changed

+211
-118
lines changed

Packet++/header/Layer.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,22 @@ namespace pcpp
264264
return m_NextLayer != nullptr;
265265
}
266266

267+
/// @brief Construct the next layer in the protocol stack. No validation is performed on the data.
268+
///
269+
/// This overload infers the Packet from the current layer.
270+
///
271+
/// @tparam T The type of the layer to construct
272+
/// @tparam Args The types of the arguments to pass to the layer constructor
273+
/// @param data The data to construct the layer from
274+
/// @param dataLen The length of the data
275+
/// @param extraArgs Extra arguments to be forwarded to the layer constructor
276+
/// @return The constructed layer
277+
template <typename T, typename... Args>
278+
Layer* constructNextLayer(uint8_t* data, size_t dataLen, Args&&... extraArgs)
279+
{
280+
return constructNextLayer<T>(data, dataLen, getAttachedPacket(), std::forward<Args>(extraArgs)...);
281+
}
282+
267283
/// Construct the next layer in the protocol stack. No validation is performed on the data.
268284
/// @tparam T The type of the layer to construct
269285
/// @tparam Args The types of the arguments to pass to the layer constructor
@@ -285,6 +301,27 @@ namespace pcpp
285301
return newLayer;
286302
}
287303

304+
/// @brief Try to construct the next layer in the protocol stack with a fallback option.
305+
///
306+
/// This overload infers the Packet from the current layer.
307+
///
308+
/// The method checks if the data is valid for the layer type T before constructing it by calling
309+
/// T::isDataValid(data, dataLen). If the data is invalid, it constructs the layer of type TFallback.
310+
///
311+
/// @tparam T The type of the layer to construct
312+
/// @tparam TFallback The fallback layer type to construct if T fails
313+
/// @tparam Args The types of the extra arguments to pass to the layer constructor of T
314+
/// @param[in] data The data to construct the layer from
315+
/// @param[in] dataLen The length of the data
316+
/// @param[in] extraArgs Extra arguments to be forwarded to the layer constructor of T
317+
/// @return The constructed layer of type T or TFallback
318+
template <typename T, typename TFallback, typename... Args>
319+
Layer* tryConstructNextLayerWithFallback(uint8_t* data, size_t dataLen, Args&&... extraArgs)
320+
{
321+
return tryConstructNextLayerWithFallback<T, TFallback>(data, dataLen, getAttachedPacket(),
322+
std::forward<Args>(extraArgs)...);
323+
}
324+
288325
/// Try to construct the next layer in the protocol stack with a fallback option.
289326
///
290327
/// The method checks if the data is valid for the layer type T before constructing it by calling

Packet++/src/CiscoHdlcLayer.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,17 @@ namespace pcpp
5454
{
5555
case CISCO_HDLC_TYPE_IP:
5656
{
57-
m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
58-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
59-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
57+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
6058
break;
6159
}
6260
case CISCO_HDLC_TYPE_IPV6:
6361
{
64-
m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
65-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
66-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
62+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
6763
break;
6864
}
6965
default:
7066
{
71-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
67+
constructNextLayer<PayloadLayer>(payload, payloadLen);
7268
break;
7369
}
7470
}

Packet++/src/IPv6Layer.cpp

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ namespace pcpp
208208
{
209209
if (m_LastExtension->getExtensionType() == IPv6Extension::IPv6Fragmentation)
210210
{
211-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
211+
constructNextLayer<PayloadLayer>(payload, payloadLen);
212212
return;
213213
}
214214

@@ -222,66 +222,94 @@ namespace pcpp
222222
switch (nextHdr)
223223
{
224224
case PACKETPP_IPPROTO_UDP:
225-
m_NextLayer = UdpLayer::isDataValid(payload, payloadLen)
226-
? static_cast<Layer*>(new UdpLayer(payload, payloadLen, this, getAttachedPacket()))
227-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
225+
{
226+
tryConstructNextLayerWithFallback<UdpLayer, PayloadLayer>(payload, payloadLen);
228227
break;
228+
}
229229
case PACKETPP_IPPROTO_TCP:
230-
m_NextLayer = TcpLayer::isDataValid(payload, payloadLen)
231-
? static_cast<Layer*>(new TcpLayer(payload, payloadLen, this, getAttachedPacket()))
232-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
230+
{
231+
tryConstructNextLayerWithFallback<TcpLayer, PayloadLayer>(payload, payloadLen);
233232
break;
233+
}
234234
case PACKETPP_IPPROTO_IPIP:
235235
{
236236
uint8_t ipVersion = *payload >> 4;
237-
if (ipVersion == 4 && IPv4Layer::isDataValid(payload, payloadLen))
238-
m_NextLayer = new IPv4Layer(payload, payloadLen, this, getAttachedPacket());
239-
else if (ipVersion == 6 && IPv6Layer::isDataValid(payload, payloadLen))
240-
m_NextLayer = new IPv6Layer(payload, payloadLen, this, getAttachedPacket());
241-
else
242-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
237+
switch (ipVersion)
238+
{
239+
case 4:
240+
{
241+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
242+
break;
243+
}
244+
case 6:
245+
{
246+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
247+
break;
248+
}
249+
default:
250+
{
251+
constructNextLayer<PayloadLayer>(payload, payloadLen);
252+
break;
253+
}
254+
}
243255
break;
244256
}
245257
case PACKETPP_IPPROTO_GRE:
246258
{
247259
ProtocolType greVer = GreLayer::getGREVersion(payload, payloadLen);
248-
if (greVer == GREv0 && GREv0Layer::isDataValid(payload, payloadLen))
249-
m_NextLayer = new GREv0Layer(payload, payloadLen, this, getAttachedPacket());
250-
else if (greVer == GREv1 && GREv1Layer::isDataValid(payload, payloadLen))
251-
m_NextLayer = new GREv1Layer(payload, payloadLen, this, getAttachedPacket());
252-
else
253-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
260+
261+
switch (greVer)
262+
{
263+
case GREv0:
264+
{
265+
tryConstructNextLayerWithFallback<GREv0Layer, PayloadLayer>(payload, payloadLen);
266+
break;
267+
}
268+
case GREv1:
269+
{
270+
tryConstructNextLayerWithFallback<GREv1Layer, PayloadLayer>(payload, payloadLen);
271+
break;
272+
}
273+
default:
274+
constructNextLayer<PayloadLayer>(payload, payloadLen);
275+
break;
276+
}
254277
break;
255278
}
256279
case PACKETPP_IPPROTO_AH:
257-
m_NextLayer =
258-
AuthenticationHeaderLayer::isDataValid(payload, payloadLen)
259-
? static_cast<Layer*>(new AuthenticationHeaderLayer(payload, payloadLen, this, getAttachedPacket()))
260-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
280+
{
281+
tryConstructNextLayerWithFallback<AuthenticationHeaderLayer, PayloadLayer>(payload, payloadLen);
261282
break;
283+
}
262284
case PACKETPP_IPPROTO_ESP:
263-
m_NextLayer = ESPLayer::isDataValid(payload, payloadLen)
264-
? static_cast<Layer*>(new ESPLayer(payload, payloadLen, this, getAttachedPacket()))
265-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
285+
{
286+
tryConstructNextLayerWithFallback<ESPLayer, PayloadLayer>(payload, payloadLen);
266287
break;
288+
}
267289
case PACKETPP_IPPROTO_ICMPV6:
268290
{
269-
m_NextLayer = IcmpV6Layer::parseIcmpV6Layer(payload, payloadLen, this, getAttachedPacket());
291+
setNextLayer(IcmpV6Layer::parseIcmpV6Layer(payload, payloadLen, this, getAttachedPacket()));
270292
break;
271293
}
272294
case PACKETPP_IPPROTO_VRRP:
273295
{
274296
auto vrrpVer = VrrpLayer::getVersionFromData(payload, payloadLen);
297+
275298
if (vrrpVer == VRRPv3)
276-
m_NextLayer =
277-
new VrrpV3Layer(payload, payloadLen, this, getAttachedPacket(), IPAddress::IPv6AddressType);
299+
{
300+
constructNextLayer<VrrpV3Layer>(payload, payloadLen, IPAddress::IPv6AddressType);
301+
}
278302
else
279-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
303+
{
304+
constructNextLayer<PayloadLayer>(payload, payloadLen);
305+
}
280306
break;
281307
}
282308
default:
283-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
284-
return;
309+
{
310+
constructNextLayer<PayloadLayer>(payload, payloadLen);
311+
break;
312+
}
285313
}
286314
}
287315

Packet++/src/NflogLayer.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,20 @@ namespace pcpp
5757
switch (family)
5858
{
5959
case PCPP_WS_NFPROTO_IPV4:
60-
m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
61-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
62-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
60+
{
61+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
6362
break;
63+
}
6464
case PCPP_WS_NFPROTO_IPV6:
65-
m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
66-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
67-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
65+
{
66+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
6867
break;
68+
}
6969
default:
70-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
70+
{
71+
constructNextLayer<PayloadLayer>(payload, payloadLen);
72+
break;
73+
}
7174
}
7275
}
7376

Packet++/src/NullLoopbackLayer.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,39 +62,42 @@ namespace pcpp
6262
switch (ethType)
6363
{
6464
case PCPP_ETHERTYPE_IP:
65-
m_NextLayer =
66-
IPv4Layer::isDataValid(payload, payloadLen)
67-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
68-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
65+
{
66+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
6967
return;
68+
}
7069
case PCPP_ETHERTYPE_IPV6:
71-
m_NextLayer =
72-
IPv6Layer::isDataValid(payload, payloadLen)
73-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
74-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
70+
{
71+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
7572
return;
73+
}
7674
default:
77-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
75+
{
76+
constructNextLayer<PayloadLayer>(payload, payloadLen);
7877
return;
7978
}
79+
}
8080
}
8181

8282
switch (family)
8383
{
8484
case PCPP_BSD_AF_INET:
85-
m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
86-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
87-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
85+
{
86+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
8887
break;
88+
}
8989
case PCPP_BSD_AF_INET6_BSD:
9090
case PCPP_BSD_AF_INET6_FREEBSD:
9191
case PCPP_BSD_AF_INET6_DARWIN:
92-
m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
93-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
94-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
92+
{
93+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
9594
break;
95+
}
9696
default:
97-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
97+
{
98+
constructNextLayer<PayloadLayer>(payload, payloadLen);
99+
break;
100+
}
98101
}
99102
}
100103

Packet++/src/Sll2Layer.cpp

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,39 +68,46 @@ namespace pcpp
6868
switch (be16toh(hdr->protocol_type))
6969
{
7070
case PCPP_ETHERTYPE_IP:
71-
m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
72-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
73-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
71+
{
72+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
7473
break;
74+
}
7575
case PCPP_ETHERTYPE_IPV6:
76-
m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
77-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
78-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
76+
{
77+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
7978
break;
79+
}
8080
case PCPP_ETHERTYPE_ARP:
81-
m_NextLayer = new ArpLayer(payload, payloadLen, this, getAttachedPacket());
81+
{
82+
constructNextLayer<ArpLayer>(payload, payloadLen);
8283
break;
84+
}
8385
case PCPP_ETHERTYPE_VLAN:
8486
case PCPP_ETHERTYPE_IEEE_802_1AD:
85-
m_NextLayer = new VlanLayer(payload, payloadLen, this, getAttachedPacket());
87+
{
88+
constructNextLayer<VlanLayer>(payload, payloadLen);
8689
break;
90+
}
8791
case PCPP_ETHERTYPE_PPPOES:
88-
m_NextLayer =
89-
PPPoESessionLayer::isDataValid(payload, payloadLen)
90-
? static_cast<Layer*>(new PPPoESessionLayer(payload, payloadLen, this, getAttachedPacket()))
91-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
92+
{
93+
tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen);
9294
break;
95+
}
9396
case PCPP_ETHERTYPE_PPPOED:
94-
m_NextLayer =
95-
PPPoEDiscoveryLayer::isDataValid(payload, payloadLen)
96-
? static_cast<Layer*>(new PPPoEDiscoveryLayer(payload, payloadLen, this, getAttachedPacket()))
97-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
97+
{
98+
tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen);
9899
break;
100+
}
99101
case PCPP_ETHERTYPE_MPLS:
100-
m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket());
102+
{
103+
constructNextLayer<MplsLayer>(payload, payloadLen);
101104
break;
105+
}
102106
default:
103-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
107+
{
108+
constructNextLayer<PayloadLayer>(payload, payloadLen);
109+
break;
110+
}
104111
}
105112
}
106113

0 commit comments

Comments
 (0)