Skip to content

Commit 077a6cf

Browse files
authored
Update more layers to use "construct" API. (#2047)
* Update parsers to new API. - Change visibility of `tryConstructNextLayer` to protected. * Update more layers. * Lint
1 parent e543792 commit 077a6cf

File tree

9 files changed

+111
-100
lines changed

9 files changed

+111
-100
lines changed

Packet++/header/Layer.h

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,47 @@ namespace pcpp
301301
return newLayer;
302302
}
303303

304+
/// Try to construct the next layer in the protocol stack.
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, no layer is constructed and a nullptr is returned.
310+
///
311+
/// @tparam T The type of the layer to construct
312+
/// @tparam Args The types of the extra arguments to pass to the layer constructor
313+
/// @param[in] data The data to construct the layer from
314+
/// @param[in] dataLen The length of the data
315+
/// @param[in] extraArgs Extra arguments to be forwarded to the layer constructor
316+
/// @return The constructed layer or nullptr if the data is invalid
317+
template <typename T, typename... Args>
318+
Layer* tryConstructNextLayer(uint8_t* data, size_t dataLen, Args&&... extraArgs)
319+
{
320+
return tryConstructNextLayer<T>(data, dataLen, getAttachedPacket(), std::forward<Args>(extraArgs)...);
321+
}
322+
323+
/// Try to construct the next layer in the protocol stack.
324+
///
325+
/// The method checks if the data is valid for the layer type T before constructing it by calling
326+
/// T::isDataValid(data, dataLen). If the data is invalid, no layer is constructed and a nullptr is returned.
327+
///
328+
/// @tparam T The type of the layer to construct
329+
/// @tparam Args The types of the extra arguments to pass to the layer constructor
330+
/// @param[in] data The data to construct the layer from
331+
/// @param[in] dataLen The length of the data
332+
/// @param[in] packet The packet the layer belongs to
333+
/// @param[in] extraArgs Extra arguments to be forwarded to the layer constructor
334+
/// @return The constructed layer or nullptr if the data is invalid
335+
template <typename T, typename... Args>
336+
Layer* tryConstructNextLayer(uint8_t* data, size_t dataLen, Packet* packet, Args&&... extraArgs)
337+
{
338+
if (T::isDataValid(data, dataLen))
339+
{
340+
return constructNextLayer<T>(data, dataLen, packet, std::forward<Args>(extraArgs)...);
341+
}
342+
return nullptr;
343+
}
344+
304345
/// @brief Try to construct the next layer in the protocol stack with a fallback option.
305346
///
306347
/// This overload infers the Packet from the current layer.
@@ -358,29 +399,6 @@ namespace pcpp
358399
{
359400
return data != nullptr && dataLen >= sizeof(T);
360401
}
361-
362-
private:
363-
/// Try to construct the next layer in the protocol stack.
364-
///
365-
/// The method checks if the data is valid for the layer type T before constructing it by calling
366-
/// T::isDataValid(data, dataLen). If the data is invalid, a nullptr is returned.
367-
///
368-
/// @tparam T The type of the layer to construct
369-
/// @tparam Args The types of the extra arguments to pass to the layer constructor
370-
/// @param[in] data The data to construct the layer from
371-
/// @param[in] dataLen The length of the data
372-
/// @param[in] packet The packet the layer belongs to
373-
/// @param[in] extraArgs Extra arguments to be forwarded to the layer constructor
374-
/// @return The constructed layer or nullptr if the data is invalid
375-
template <typename T, typename... Args>
376-
Layer* tryConstructNextLayer(uint8_t* data, size_t dataLen, Packet* packet, Args&&... extraArgs)
377-
{
378-
if (T::isDataValid(data, dataLen))
379-
{
380-
return constructNextLayer<T>(data, dataLen, packet, std::forward<Args>(extraArgs)...);
381-
}
382-
return nullptr;
383-
}
384402
};
385403

386404
inline std::ostream& operator<<(std::ostream& os, const pcpp::Layer& layer)

Packet++/src/BgpLayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace pcpp
8787
uint8_t* payload = m_Data + headerLen;
8888
size_t payloadLen = m_DataLen - headerLen;
8989

90-
m_NextLayer = BgpLayer::parseBgpLayer(payload, payloadLen, this, getAttachedPacket());
90+
setNextLayer(BgpLayer::parseBgpLayer(payload, payloadLen, this, getAttachedPacket()));
9191
}
9292

9393
std::string BgpLayer::toString() const

Packet++/src/CotpLayer.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ namespace pcpp
7272
uint8_t* payload = m_Data + headerLen;
7373
size_t payloadLen = m_DataLen - headerLen;
7474

75-
if (S7CommLayer::isDataValid(payload, payloadLen))
76-
m_NextLayer = new S7CommLayer(payload, payloadLen, this, getAttachedPacket());
77-
else
78-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
75+
tryConstructNextLayerWithFallback<S7CommLayer, PayloadLayer>(payload, payloadLen);
7976
}
8077
} // namespace pcpp

Packet++/src/EthDot3Layer.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ namespace pcpp
2929
uint8_t* payload = m_Data + sizeof(ether_dot3_header);
3030
size_t payloadLen = m_DataLen - sizeof(ether_dot3_header);
3131

32-
if (LLCLayer::isDataValid(payload, payloadLen))
33-
m_NextLayer = new LLCLayer(payload, payloadLen, this, getAttachedPacket());
34-
else
35-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
32+
tryConstructNextLayerWithFallback<LLCLayer, PayloadLayer>(payload, payloadLen);
3633
}
3734

3835
std::string EthDot3Layer::toString() const

Packet++/src/EthLayer.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,35 @@ namespace pcpp
3939
switch (be16toh(hdr->etherType))
4040
{
4141
case PCPP_ETHERTYPE_IP:
42-
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen, getAttachedPacket());
42+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
4343
break;
4444
case PCPP_ETHERTYPE_IPV6:
45-
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen, getAttachedPacket());
45+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
4646
break;
4747
case PCPP_ETHERTYPE_ARP:
48-
tryConstructNextLayerWithFallback<ArpLayer, PayloadLayer>(payload, payloadLen, getAttachedPacket());
48+
tryConstructNextLayerWithFallback<ArpLayer, PayloadLayer>(payload, payloadLen);
4949
break;
5050
case PCPP_ETHERTYPE_VLAN:
5151
case PCPP_ETHERTYPE_IEEE_802_1AD:
52-
tryConstructNextLayerWithFallback<VlanLayer, PayloadLayer>(payload, payloadLen, getAttachedPacket());
52+
tryConstructNextLayerWithFallback<VlanLayer, PayloadLayer>(payload, payloadLen);
5353
break;
5454
case PCPP_ETHERTYPE_PPPOES:
55-
tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen,
56-
getAttachedPacket());
55+
tryConstructNextLayerWithFallback<PPPoESessionLayer, PayloadLayer>(payload, payloadLen);
5756
break;
5857
case PCPP_ETHERTYPE_PPPOED:
59-
tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen,
60-
getAttachedPacket());
58+
tryConstructNextLayerWithFallback<PPPoEDiscoveryLayer, PayloadLayer>(payload, payloadLen);
6159
break;
6260
case PCPP_ETHERTYPE_MPLS:
63-
tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen, getAttachedPacket());
61+
tryConstructNextLayerWithFallback<MplsLayer, PayloadLayer>(payload, payloadLen);
6462
break;
6563
case PCPP_ETHERTYPE_WAKE_ON_LAN:
66-
tryConstructNextLayerWithFallback<WakeOnLanLayer, PayloadLayer>(payload, payloadLen, getAttachedPacket());
64+
tryConstructNextLayerWithFallback<WakeOnLanLayer, PayloadLayer>(payload, payloadLen);
6765
break;
6866
}
6967

7068
// If no next layer was constructed, assume it's a payload layer
7169
if (!hasNextLayer())
72-
constructNextLayer<PayloadLayer>(payload, payloadLen, getAttachedPacket());
70+
constructNextLayer<PayloadLayer>(payload, payloadLen);
7371
}
7472

7573
void EthLayer::computeCalculateFields()

Packet++/src/GreLayer.cpp

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -205,42 +205,32 @@ namespace pcpp
205205
switch (be16toh(header->protocol))
206206
{
207207
case PCPP_ETHERTYPE_IP:
208-
m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
209-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
210-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
208+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
211209
break;
212210
case PCPP_ETHERTYPE_IPV6:
213-
m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
214-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
215-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
211+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
216212
break;
217213
case PCPP_ETHERTYPE_VLAN:
218-
m_NextLayer = new VlanLayer(payload, payloadLen, this, getAttachedPacket());
214+
constructNextLayer<VlanLayer>(payload, payloadLen);
219215
break;
220216
case PCPP_ETHERTYPE_MPLS:
221-
m_NextLayer = new MplsLayer(payload, payloadLen, this, getAttachedPacket());
217+
constructNextLayer<MplsLayer>(payload, payloadLen);
222218
break;
223219
case PCPP_ETHERTYPE_PPP:
224-
m_NextLayer = PPP_PPTPLayer::isDataValid(payload, payloadLen)
225-
? static_cast<Layer*>(new PPP_PPTPLayer(payload, payloadLen, this, getAttachedPacket()))
226-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
220+
tryConstructNextLayerWithFallback<PPP_PPTPLayer, PayloadLayer>(payload, payloadLen);
227221
break;
228222
case PCPP_ETHERTYPE_ETHBRIDGE:
229-
if (EthLayer::isDataValid(payload, payloadLen))
230-
{
231-
m_NextLayer = new EthLayer(payload, payloadLen, this, getAttachedPacket());
232-
}
233-
else if (EthDot3Layer::isDataValid(payload, payloadLen))
234-
{
235-
m_NextLayer = new EthDot3Layer(payload, payloadLen, this, getAttachedPacket());
236-
}
237-
else
223+
{
224+
if (tryConstructNextLayer<EthLayer>(payload, payloadLen) != nullptr)
238225
{
239-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
226+
break;
240227
}
228+
229+
tryConstructNextLayerWithFallback<EthDot3Layer, PayloadLayer>(payload, payloadLen);
241230
break;
231+
}
242232
default:
243-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
233+
constructNextLayer<PayloadLayer>(payload, payloadLen);
244234
}
245235
}
246236

Packet++/src/GtpLayer.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -589,19 +589,15 @@ namespace pcpp
589589
uint8_t subProto = *payload;
590590
if (subProto >= 0x45 && subProto <= 0x4e)
591591
{
592-
m_NextLayer = IPv4Layer::isDataValid(payload, payloadLen)
593-
? static_cast<Layer*>(new IPv4Layer(payload, payloadLen, this, getAttachedPacket()))
594-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
592+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
595593
}
596594
else if ((subProto & 0xf0) == 0x60)
597595
{
598-
m_NextLayer = IPv6Layer::isDataValid(payload, payloadLen)
599-
? static_cast<Layer*>(new IPv6Layer(payload, payloadLen, this, getAttachedPacket()))
600-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
596+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
601597
}
602598
else
603599
{
604-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
600+
constructNextLayer<PayloadLayer>(payload, payloadLen);
605601
}
606602
}
607603

@@ -1313,13 +1309,13 @@ namespace pcpp
13131309
auto* nextLayerData = m_Data + headerLen;
13141310
auto nextLayerDataLen = m_DataLen - headerLen;
13151311

1316-
if (getHeader()->piggybacking && GtpV2Layer::isDataValid(nextLayerData, nextLayerDataLen))
1312+
if (getHeader()->piggybacking)
13171313
{
1318-
m_NextLayer = new GtpV2Layer(nextLayerData, nextLayerDataLen, this, getAttachedPacket());
1314+
tryConstructNextLayerWithFallback<GtpV2Layer, PayloadLayer>(nextLayerData, nextLayerDataLen);
13191315
}
13201316
else
13211317
{
1322-
m_NextLayer = new PayloadLayer(nextLayerData, nextLayerDataLen, this, getAttachedPacket());
1318+
constructNextLayer<PayloadLayer>(nextLayerData, nextLayerDataLen);
13231319
}
13241320
}
13251321

Packet++/src/IPSecLayer.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,33 +63,45 @@ namespace pcpp
6363
switch (getAHHeader()->nextHeader)
6464
{
6565
case PACKETPP_IPPROTO_UDP:
66-
m_NextLayer = UdpLayer::isDataValid(payload, payloadLen)
67-
? static_cast<Layer*>(new UdpLayer(payload, payloadLen, this, getAttachedPacket()))
68-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
66+
{
67+
tryConstructNextLayerWithFallback<UdpLayer, PayloadLayer>(payload, payloadLen);
6968
break;
69+
}
7070
case PACKETPP_IPPROTO_TCP:
71-
m_NextLayer = TcpLayer::isDataValid(payload, payloadLen)
72-
? static_cast<Layer*>(new TcpLayer(payload, payloadLen, this, getAttachedPacket()))
73-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
71+
{
72+
tryConstructNextLayerWithFallback<TcpLayer, PayloadLayer>(payload, payloadLen);
7473
break;
74+
}
7575
case PACKETPP_IPPROTO_IPIP:
7676
{
7777
uint8_t ipVersion = *payload >> 4;
78-
if (ipVersion == 4 && IPv4Layer::isDataValid(payload, payloadLen))
79-
m_NextLayer = new IPv4Layer(payload, payloadLen, this, getAttachedPacket());
80-
else if (ipVersion == 6 && IPv6Layer::isDataValid(payload, payloadLen))
81-
m_NextLayer = new IPv6Layer(payload, payloadLen, this, getAttachedPacket());
82-
else
83-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
78+
switch (ipVersion)
79+
{
80+
case 4:
81+
{
82+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payload, payloadLen);
83+
break;
84+
}
85+
case 6:
86+
{
87+
tryConstructNextLayerWithFallback<IPv6Layer, PayloadLayer>(payload, payloadLen);
88+
break;
89+
}
90+
default:
91+
{
92+
constructNextLayer<PayloadLayer>(payload, payloadLen);
93+
break;
94+
}
95+
}
8496
break;
8597
}
8698
case PACKETPP_IPPROTO_ESP:
87-
m_NextLayer = ESPLayer::isDataValid(payload, payloadLen)
88-
? static_cast<Layer*>(new ESPLayer(payload, payloadLen, this, getAttachedPacket()))
89-
: static_cast<Layer*>(new PayloadLayer(payload, payloadLen, this, getAttachedPacket()));
99+
{
100+
tryConstructNextLayerWithFallback<ESPLayer, PayloadLayer>(payload, payloadLen);
90101
break;
102+
}
91103
default:
92-
m_NextLayer = new PayloadLayer(payload, payloadLen, this, getAttachedPacket());
104+
constructNextLayer<PayloadLayer>(payload, payloadLen);
93105
}
94106
}
95107

@@ -118,7 +130,7 @@ namespace pcpp
118130
if (m_DataLen <= headerLen)
119131
return;
120132

121-
m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket());
133+
constructNextLayer<PayloadLayer>(m_Data + headerLen, m_DataLen - headerLen);
122134
}
123135

124136
std::string ESPLayer::toString() const

Packet++/src/IcmpLayer.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -565,23 +565,26 @@ namespace pcpp
565565
{
566566
size_t headerLen = getHeaderLen();
567567

568+
auto payloadPtr = m_Data + headerLen;
569+
auto payloadLen = m_DataLen - headerLen;
570+
568571
switch (getMessageType())
569572
{
570573
case ICMP_DEST_UNREACHABLE:
571574
case ICMP_SOURCE_QUENCH:
572575
case ICMP_TIME_EXCEEDED:
573576
case ICMP_REDIRECT:
574577
case ICMP_PARAM_PROBLEM:
575-
// clang-format off
576-
m_NextLayer = IPv4Layer::isDataValid(m_Data + headerLen, m_DataLen - headerLen)
577-
? static_cast<Layer*>(new IPv4Layer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()))
578-
: static_cast<Layer*>(new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket()));
579-
// clang-format on
580-
return;
578+
{
579+
tryConstructNextLayerWithFallback<IPv4Layer, PayloadLayer>(payloadPtr, payloadLen);
580+
break;
581+
}
581582
default:
582583
if (m_DataLen > headerLen)
583-
m_NextLayer = new PayloadLayer(m_Data + headerLen, m_DataLen - headerLen, this, getAttachedPacket());
584-
return;
584+
{
585+
constructNextLayer<PayloadLayer>(payloadPtr, payloadLen);
586+
}
587+
break;
585588
}
586589
}
587590

0 commit comments

Comments
 (0)