Coverage Report

Created: 2026-03-07 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/UdpLayer.cpp
Line
Count
Source
1
135k
#define LOG_MODULE PacketLogModuleUdpLayer
2
3
#include "EndianPortable.h"
4
#include "UdpLayer.h"
5
#include "PayloadLayer.h"
6
#include "IPv4Layer.h"
7
#include "IPv6Layer.h"
8
#include "DnsLayer.h"
9
#include "DhcpLayer.h"
10
#include "DhcpV6Layer.h"
11
#include "DoIpLayer.h"
12
#include "VxlanLayer.h"
13
#include "SipLayer.h"
14
#include "RadiusLayer.h"
15
#include "GtpLayer.h"
16
#include "NtpLayer.h"
17
#include "SomeIpLayer.h"
18
#include "WakeOnLanLayer.h"
19
#include "WireGuardLayer.h"
20
#include "PacketUtils.h"
21
#include "Logger.h"
22
#include <sstream>
23
24
namespace pcpp
25
{
26
27
  UdpLayer::UdpLayer(uint16_t portSrc, uint16_t portDst)
28
0
  {
29
0
    const size_t headerLen = sizeof(udphdr);
30
0
    m_DataLen = headerLen;
31
0
    m_Data = new uint8_t[headerLen];
32
0
    memset(m_Data, 0, headerLen);
33
0
    udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data);
34
0
    udpHdr->portDst = htobe16(portDst);
35
0
    udpHdr->portSrc = htobe16(portSrc);
36
0
    m_Protocol = UDP;
37
0
  }
38
39
  uint16_t UdpLayer::getSrcPort() const
40
511k
  {
41
511k
    return be16toh(getUdpHeader()->portSrc);
42
511k
  }
43
44
  uint16_t UdpLayer::getDstPort() const
45
511k
  {
46
511k
    return be16toh(getUdpHeader()->portDst);
47
511k
  }
48
49
  uint16_t UdpLayer::calculateChecksum(bool writeResultToPacket)
50
67.6k
  {
51
67.6k
    udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data);
52
67.6k
    uint16_t checksumRes = 0;
53
67.6k
    uint16_t currChecksumValue = udpHdr->headerChecksum;
54
55
67.6k
    if (m_PrevLayer != nullptr)
56
67.6k
    {
57
67.6k
      udpHdr->headerChecksum = 0;
58
67.6k
      PCPP_LOG_DEBUG("UDP data len = " << m_DataLen);
59
60
67.6k
      if (m_PrevLayer->getProtocol() == IPv4)
61
65.1k
      {
62
65.1k
        IPv4Address srcIP = static_cast<IPv4Layer*>(m_PrevLayer)->getSrcIPv4Address();
63
65.1k
        IPv4Address dstIP = static_cast<IPv4Layer*>(m_PrevLayer)->getDstIPv4Address();
64
65
65.1k
        checksumRes = pcpp::computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv4AddressType,
66
65.1k
                                                     PACKETPP_IPPROTO_UDP, srcIP, dstIP);
67
68
65.1k
        PCPP_LOG_DEBUG("calculated IPv4 UDP checksum = 0x" << std::uppercase << std::hex << checksumRes);
69
65.1k
      }
70
2.46k
      else if (m_PrevLayer->getProtocol() == IPv6)
71
2.41k
      {
72
2.41k
        IPv6Address srcIP = static_cast<IPv6Layer*>(m_PrevLayer)->getSrcIPv6Address();
73
2.41k
        IPv6Address dstIP = static_cast<IPv6Layer*>(m_PrevLayer)->getDstIPv6Address();
74
75
2.41k
        checksumRes = computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv6AddressType,
76
2.41k
                                               PACKETPP_IPPROTO_UDP, srcIP, dstIP);
77
78
2.41k
        PCPP_LOG_DEBUG("calculated IPv6 UDP checksum = 0xX" << std::uppercase << std::hex << checksumRes);
79
2.41k
      }
80
67.6k
    }
81
82
67.6k
    if (checksumRes == 0)
83
209
      checksumRes = 0xffff;
84
85
67.6k
    if (writeResultToPacket)
86
67.6k
      udpHdr->headerChecksum = htobe16(checksumRes);
87
0
    else
88
0
      udpHdr->headerChecksum = currChecksumValue;
89
90
67.6k
    return checksumRes;
91
67.6k
  }
92
93
  void UdpLayer::parseNextLayer()
94
377k
  {
95
377k
    if (m_DataLen <= sizeof(udphdr))
96
732
      return;
97
98
376k
    uint16_t portDst = getDstPort();
99
376k
    uint16_t portSrc = getSrcPort();
100
101
376k
    uint8_t* udpData = m_Data + sizeof(udphdr);
102
376k
    size_t udpDataLen = m_DataLen - sizeof(udphdr);
103
104
376k
    if (DhcpLayer::isDhcpPorts(portSrc, portDst))
105
18.5k
    {
106
18.5k
      constructNextLayer<DhcpLayer>(udpData, udpDataLen);
107
18.5k
    }
108
357k
    else if (VxlanLayer::isVxlanPort(portDst))
109
9.90k
    {
110
9.90k
      constructNextLayer<VxlanLayer>(udpData, udpDataLen);
111
9.90k
    }
112
347k
    else if (DnsLayer::isDataValid(udpData, udpDataLen) &&
113
339k
             (DnsLayer::isDnsPort(portDst) || DnsLayer::isDnsPort(portSrc)))
114
86.1k
    {
115
86.1k
      constructNextLayer<DnsLayer>(udpData, udpDataLen);
116
86.1k
    }
117
261k
    else if (SipLayer::isSipPort(portDst) || SipLayer::isSipPort(portSrc))
118
36.5k
    {
119
      // Resolves the overload of parseSipLayer, without static_casting a function pointer.
120
36.5k
      auto* (*fac)(uint8_t*, size_t, Layer*, Packet*, uint16_t, uint16_t) = SipLayer::parseSipLayer;
121
36.5k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(fac, udpData, udpDataLen, portSrc, portDst);
122
36.5k
    }
123
225k
    else if ((RadiusLayer::isRadiusPort(portDst) || RadiusLayer::isRadiusPort(portSrc)) &&
124
25.7k
             RadiusLayer::isDataValid(udpData, udpDataLen))
125
22.4k
    {
126
22.4k
      constructNextLayer<RadiusLayer>(udpData, udpDataLen);
127
22.4k
    }
128
202k
    else if ((GtpV1Layer::isGTPv1Port(portDst) || GtpV1Layer::isGTPv1Port(portSrc)) &&
129
23.2k
             GtpV1Layer::isGTPv1(udpData, udpDataLen))
130
13.8k
    {
131
13.8k
      constructNextLayer<GtpV1Layer>(udpData, udpDataLen);
132
13.8k
    }
133
188k
    else if ((GtpV2Layer::isGTPv2Port(portDst) || GtpV2Layer::isGTPv2Port(portSrc)) &&
134
1.18k
             GtpV2Layer::isDataValid(udpData, udpDataLen))
135
1.06k
    {
136
1.06k
      constructNextLayer<GtpV2Layer>(udpData, udpDataLen);
137
1.06k
    }
138
187k
    else if ((DhcpV6Layer::isDhcpV6Port(portSrc) || DhcpV6Layer::isDhcpV6Port(portDst)) &&
139
5.65k
             (DhcpV6Layer::isDataValid(udpData, udpDataLen)))
140
5.65k
    {
141
5.65k
      constructNextLayer<DhcpV6Layer>(udpData, udpDataLen);
142
5.65k
    }
143
182k
    else if ((NtpLayer::isNTPPort(portSrc) || NtpLayer::isNTPPort(portDst)) &&
144
13.3k
             NtpLayer::isDataValid(udpData, udpDataLen))
145
13.0k
    {
146
13.0k
      constructNextLayer<NtpLayer>(udpData, udpDataLen);
147
13.0k
    }
148
169k
    else if ((DoIpLayer::isDoIpPort(portSrc) || DoIpLayer::isDoIpPort(portDst)) &&
149
237
             (DoIpLayer::isDataValid(udpData, udpDataLen)))
150
0
    {
151
0
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(DoIpLayer::parseDoIpLayer, udpData, udpDataLen);
152
0
    }
153
169k
    else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst))
154
61.2k
    {
155
61.2k
      constructNextLayerFromFactory(SomeIpLayer::parseSomeIpLayer, udpData, udpDataLen);
156
61.2k
    }
157
107k
    else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen)))
158
873
    {
159
873
      constructNextLayer<WakeOnLanLayer>(udpData, udpDataLen);
160
873
    }
161
106k
    else if ((WireGuardLayer::isWireGuardPorts(portDst, portSrc) &&
162
2.61k
              WireGuardLayer::isDataValid(udpData, udpDataLen)))
163
2.39k
    {
164
2.39k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(WireGuardLayer::parseWireGuardLayer, udpData,
165
2.39k
                                                                 udpDataLen);
166
2.39k
    }
167
168
    // If a valid layer was found, return immediately
169
376k
    if (hasNextLayer())
170
271k
    {
171
271k
      return;
172
271k
    }
173
174
    // Here, heuristics for all protocols should be invoked to determine the correct layer
175
104k
    {
176
      // Resolves the overload of parseSipLayer, without static_casting a function pointer.
177
104k
      auto* (*fac)(uint8_t*, size_t, Layer*, Packet*) = SipLayer::parseSipLayer;
178
104k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(fac, udpData, udpDataLen);
179
104k
    }
180
181
104k
    if (!hasNextLayer())
182
0
    {
183
0
      constructNextLayer<PayloadLayer>(udpData, udpDataLen);
184
0
    }
185
104k
  }
186
187
  void UdpLayer::computeCalculateFields()
188
67.6k
  {
189
67.6k
    udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data);
190
67.6k
    udpHdr->length = htobe16(m_DataLen);
191
67.6k
    calculateChecksum(true);
192
67.6k
  }
193
194
  std::string UdpLayer::toString() const
195
135k
  {
196
135k
    std::ostringstream srcPortStream;
197
135k
    srcPortStream << getSrcPort();
198
135k
    std::ostringstream dstPortStream;
199
135k
    dstPortStream << getDstPort();
200
201
135k
    return "UDP Layer, Src port: " + srcPortStream.str() + ", Dst port: " + dstPortStream.str();
202
135k
  }
203
204
}  // namespace pcpp