Coverage Report

Created: 2026-05-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/UdpLayer.cpp
Line
Count
Source
1
114k
#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
474k
  {
41
474k
    return be16toh(getUdpHeader()->portSrc);
42
474k
  }
43
44
  uint16_t UdpLayer::getDstPort() const
45
474k
  {
46
474k
    return be16toh(getUdpHeader()->portDst);
47
474k
  }
48
49
  uint16_t UdpLayer::calculateChecksum(bool writeResultToPacket)
50
57.4k
  {
51
57.4k
    udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data);
52
57.4k
    uint16_t checksumRes = 0;
53
57.4k
    uint16_t currChecksumValue = udpHdr->headerChecksum;
54
55
57.4k
    if (m_PrevLayer != nullptr)
56
57.4k
    {
57
57.4k
      udpHdr->headerChecksum = 0;
58
57.4k
      PCPP_LOG_DEBUG("UDP data len = " << m_DataLen);
59
60
57.4k
      if (m_PrevLayer->getProtocol() == IPv4)
61
50.9k
      {
62
50.9k
        IPv4Address srcIP = static_cast<IPv4Layer*>(m_PrevLayer)->getSrcIPv4Address();
63
50.9k
        IPv4Address dstIP = static_cast<IPv4Layer*>(m_PrevLayer)->getDstIPv4Address();
64
65
50.9k
        checksumRes = pcpp::computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv4AddressType,
66
50.9k
                                                     PACKETPP_IPPROTO_UDP, srcIP, dstIP);
67
68
50.9k
        PCPP_LOG_DEBUG("calculated IPv4 UDP checksum = 0x" << std::uppercase << std::hex << checksumRes);
69
50.9k
      }
70
6.47k
      else if (m_PrevLayer->getProtocol() == IPv6)
71
6.47k
      {
72
6.47k
        IPv6Address srcIP = static_cast<IPv6Layer*>(m_PrevLayer)->getSrcIPv6Address();
73
6.47k
        IPv6Address dstIP = static_cast<IPv6Layer*>(m_PrevLayer)->getDstIPv6Address();
74
75
6.47k
        checksumRes = computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv6AddressType,
76
6.47k
                                               PACKETPP_IPPROTO_UDP, srcIP, dstIP);
77
78
6.47k
        PCPP_LOG_DEBUG("calculated IPv6 UDP checksum = 0xX" << std::uppercase << std::hex << checksumRes);
79
6.47k
      }
80
57.4k
    }
81
82
57.4k
    if (checksumRes == 0)
83
34
      checksumRes = 0xffff;
84
85
57.4k
    if (writeResultToPacket)
86
57.4k
      udpHdr->headerChecksum = htobe16(checksumRes);
87
0
    else
88
0
      udpHdr->headerChecksum = currChecksumValue;
89
90
57.4k
    return checksumRes;
91
57.4k
  }
92
93
  void UdpLayer::parseNextLayer()
94
360k
  {
95
360k
    if (m_DataLen <= sizeof(udphdr))
96
106
      return;
97
98
360k
    uint16_t portDst = getDstPort();
99
360k
    uint16_t portSrc = getSrcPort();
100
101
360k
    uint8_t* udpData = m_Data + sizeof(udphdr);
102
360k
    size_t udpDataLen = m_DataLen - sizeof(udphdr);
103
104
360k
    if (DhcpLayer::isDhcpPorts(portSrc, portDst))
105
15.9k
    {
106
15.9k
      tryConstructNextLayerWithFallback<DhcpLayer, PayloadLayer>(udpData, udpDataLen);
107
15.9k
    }
108
344k
    else if (VxlanLayer::isVxlanPort(portDst))
109
0
    {
110
0
      tryConstructNextLayerWithFallback<VxlanLayer, PayloadLayer>(udpData, udpDataLen);
111
0
    }
112
344k
    else if (DnsLayer::isDataValid(udpData, udpDataLen) &&
113
303k
             (DnsLayer::isDnsPort(portDst) || DnsLayer::isDnsPort(portSrc)))
114
58.1k
    {
115
58.1k
      constructNextLayer<DnsLayer>(udpData, udpDataLen);
116
58.1k
    }
117
285k
    else if (SipLayer::isSipPort(portDst) || SipLayer::isSipPort(portSrc))
118
74.5k
    {
119
      // Resolves the overload of parseSipLayer, without static_casting a function pointer.
120
74.5k
      auto* (*fac)(uint8_t*, size_t, Layer*, Packet*, uint16_t, uint16_t) = SipLayer::parseSipLayer;
121
74.5k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(fac, udpData, udpDataLen, portSrc, portDst);
122
74.5k
    }
123
211k
    else if ((RadiusLayer::isRadiusPort(portDst) || RadiusLayer::isRadiusPort(portSrc)) &&
124
13.7k
             RadiusLayer::isDataValid(udpData, udpDataLen))
125
12.8k
    {
126
12.8k
      constructNextLayer<RadiusLayer>(udpData, udpDataLen);
127
12.8k
    }
128
198k
    else if ((GtpV1Layer::isGTPv1Port(portDst) || GtpV1Layer::isGTPv1Port(portSrc)) &&
129
34.9k
             GtpV1Layer::isGTPv1(udpData, udpDataLen))
130
34.5k
    {
131
34.5k
      constructNextLayer<GtpV1Layer>(udpData, udpDataLen);
132
34.5k
    }
133
163k
    else if ((GtpV2Layer::isGTPv2Port(portDst) || GtpV2Layer::isGTPv2Port(portSrc)) &&
134
16
             GtpV2Layer::isDataValid(udpData, udpDataLen))
135
6
    {
136
6
      constructNextLayer<GtpV2Layer>(udpData, udpDataLen);
137
6
    }
138
163k
    else if ((DhcpV6Layer::isDhcpV6Port(portSrc) || DhcpV6Layer::isDhcpV6Port(portDst)) &&
139
21.1k
             (DhcpV6Layer::isDataValid(udpData, udpDataLen)))
140
20.8k
    {
141
20.8k
      constructNextLayer<DhcpV6Layer>(udpData, udpDataLen);
142
20.8k
    }
143
143k
    else if ((NtpLayer::isNTPPort(portSrc) || NtpLayer::isNTPPort(portDst)) &&
144
17.2k
             NtpLayer::isDataValid(udpData, udpDataLen))
145
17.1k
    {
146
17.1k
      constructNextLayer<NtpLayer>(udpData, udpDataLen);
147
17.1k
    }
148
125k
    else if ((DoIpLayer::isDoIpPort(portSrc) || DoIpLayer::isDoIpPort(portDst)) &&
149
49.5k
             (DoIpLayer::isDataValid(udpData, udpDataLen)))
150
44.9k
    {
151
44.9k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(DoIpLayer::parseDoIpLayer, udpData, udpDataLen);
152
44.9k
    }
153
80.9k
    else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst))
154
36.1k
    {
155
36.1k
      constructNextLayerFromFactory(SomeIpLayer::parseSomeIpLayer, udpData, udpDataLen);
156
36.1k
    }
157
44.8k
    else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen)))
158
495
    {
159
495
      constructNextLayer<WakeOnLanLayer>(udpData, udpDataLen);
160
495
    }
161
44.3k
    else if ((WireGuardLayer::isWireGuardPorts(portDst, portSrc) &&
162
2.22k
              WireGuardLayer::isDataValid(udpData, udpDataLen)))
163
2.08k
    {
164
2.08k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(WireGuardLayer::parseWireGuardLayer, udpData,
165
2.08k
                                                                 udpDataLen);
166
2.08k
    }
167
168
    // If a valid layer was found, return immediately
169
360k
    if (hasNextLayer())
170
317k
    {
171
317k
      return;
172
317k
    }
173
174
    // Here, heuristics for all protocols should be invoked to determine the correct layer
175
42.2k
    {
176
      // Resolves the overload of parseSipLayer, without static_casting a function pointer.
177
42.2k
      auto* (*fac)(uint8_t*, size_t, Layer*, Packet*) = SipLayer::parseSipLayer;
178
42.2k
      tryConstructNextLayerFromFactoryWithFallback<PayloadLayer>(fac, udpData, udpDataLen);
179
42.2k
    }
180
181
42.2k
    if (!hasNextLayer())
182
0
    {
183
0
      constructNextLayer<PayloadLayer>(udpData, udpDataLen);
184
0
    }
185
42.2k
  }
186
187
  void UdpLayer::computeCalculateFields()
188
57.4k
  {
189
57.4k
    udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data);
190
57.4k
    udpHdr->length = htobe16(m_DataLen);
191
57.4k
    calculateChecksum(true);
192
57.4k
  }
193
194
  std::string UdpLayer::toString() const
195
114k
  {
196
114k
    std::ostringstream srcPortStream;
197
114k
    srcPortStream << getSrcPort();
198
114k
    std::ostringstream dstPortStream;
199
114k
    dstPortStream << getDstPort();
200
201
114k
    return "UDP Layer, Src port: " + srcPortStream.str() + ", Dst port: " + dstPortStream.str();
202
114k
  }
203
204
}  // namespace pcpp