Coverage Report

Created: 2025-07-18 07:14

/src/PcapPlusPlus/Packet++/src/UdpLayer.cpp
Line
Count
Source (jump to first uncovered line)
1
69.8k
#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 "VxlanLayer.h"
12
#include "SipLayer.h"
13
#include "RadiusLayer.h"
14
#include "GtpLayer.h"
15
#include "NtpLayer.h"
16
#include "SomeIpLayer.h"
17
#include "WakeOnLanLayer.h"
18
#include "WireGuardLayer.h"
19
#include "PacketUtils.h"
20
#include "Logger.h"
21
#include <sstream>
22
23
namespace pcpp
24
{
25
26
  UdpLayer::UdpLayer(uint16_t portSrc, uint16_t portDst)
27
0
  {
28
0
    const size_t headerLen = sizeof(udphdr);
29
0
    m_DataLen = headerLen;
30
0
    m_Data = new uint8_t[headerLen];
31
0
    memset(m_Data, 0, headerLen);
32
0
    udphdr* udpHdr = (udphdr*)m_Data;
33
0
    udpHdr->portDst = htobe16(portDst);
34
0
    udpHdr->portSrc = htobe16(portSrc);
35
0
    m_Protocol = UDP;
36
0
  }
37
38
  uint16_t UdpLayer::getSrcPort() const
39
286k
  {
40
286k
    return be16toh(getUdpHeader()->portSrc);
41
286k
  }
42
43
  uint16_t UdpLayer::getDstPort() const
44
286k
  {
45
286k
    return be16toh(getUdpHeader()->portDst);
46
286k
  }
47
48
  uint16_t UdpLayer::calculateChecksum(bool writeResultToPacket)
49
34.9k
  {
50
34.9k
    udphdr* udpHdr = (udphdr*)m_Data;
51
34.9k
    uint16_t checksumRes = 0;
52
34.9k
    uint16_t currChecksumValue = udpHdr->headerChecksum;
53
54
34.9k
    if (m_PrevLayer != nullptr)
55
34.9k
    {
56
34.9k
      udpHdr->headerChecksum = 0;
57
34.9k
      PCPP_LOG_DEBUG("UDP data len = " << m_DataLen);
58
59
34.9k
      if (m_PrevLayer->getProtocol() == IPv4)
60
28.9k
      {
61
28.9k
        IPv4Address srcIP = ((IPv4Layer*)m_PrevLayer)->getSrcIPv4Address();
62
28.9k
        IPv4Address dstIP = ((IPv4Layer*)m_PrevLayer)->getDstIPv4Address();
63
64
28.9k
        checksumRes = pcpp::computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv4AddressType,
65
28.9k
                                                     PACKETPP_IPPROTO_UDP, srcIP, dstIP);
66
67
28.9k
        PCPP_LOG_DEBUG("calculated IPv4 UDP checksum = 0x" << std::uppercase << std::hex << checksumRes);
68
28.9k
      }
69
5.98k
      else if (m_PrevLayer->getProtocol() == IPv6)
70
5.98k
      {
71
5.98k
        IPv6Address srcIP = ((IPv6Layer*)m_PrevLayer)->getSrcIPv6Address();
72
5.98k
        IPv6Address dstIP = ((IPv6Layer*)m_PrevLayer)->getDstIPv6Address();
73
74
5.98k
        checksumRes = computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv6AddressType,
75
5.98k
                                               PACKETPP_IPPROTO_UDP, srcIP, dstIP);
76
77
5.98k
        PCPP_LOG_DEBUG("calculated IPv6 UDP checksum = 0xX" << std::uppercase << std::hex << checksumRes);
78
5.98k
      }
79
34.9k
    }
80
81
34.9k
    if (checksumRes == 0)
82
35
      checksumRes = 0xffff;
83
84
34.9k
    if (writeResultToPacket)
85
34.9k
      udpHdr->headerChecksum = htobe16(checksumRes);
86
0
    else
87
0
      udpHdr->headerChecksum = currChecksumValue;
88
89
34.9k
    return checksumRes;
90
34.9k
  }
91
92
  void UdpLayer::parseNextLayer()
93
217k
  {
94
217k
    if (m_DataLen <= sizeof(udphdr))
95
65
      return;
96
97
217k
    uint16_t portDst = getDstPort();
98
217k
    uint16_t portSrc = getSrcPort();
99
100
217k
    uint8_t* udpData = m_Data + sizeof(udphdr);
101
217k
    size_t udpDataLen = m_DataLen - sizeof(udphdr);
102
103
217k
    if (DhcpLayer::isDhcpPorts(portSrc, portDst))
104
12.7k
      m_NextLayer = new DhcpLayer(udpData, udpDataLen, this, m_Packet);
105
204k
    else if (VxlanLayer::isVxlanPort(portDst))
106
0
      m_NextLayer = new VxlanLayer(udpData, udpDataLen, this, m_Packet);
107
204k
    else if (DnsLayer::isDataValid(udpData, udpDataLen) &&
108
204k
             (DnsLayer::isDnsPort(portDst) || DnsLayer::isDnsPort(portSrc)))
109
46.5k
      m_NextLayer = new DnsLayer(udpData, udpDataLen, this, m_Packet);
110
157k
    else if (SipLayer::isSipPort(portDst) || SipLayer::isSipPort(portSrc))
111
52.0k
    {
112
52.0k
      if (SipRequestFirstLine::parseMethod((char*)udpData, udpDataLen) != SipRequestLayer::SipMethodUnknown)
113
41.3k
        m_NextLayer = new SipRequestLayer(udpData, udpDataLen, this, m_Packet);
114
10.7k
      else if (SipResponseFirstLine::parseStatusCode((char*)udpData, udpDataLen) !=
115
10.7k
                   SipResponseLayer::SipStatusCodeUnknown &&
116
10.7k
               SipResponseFirstLine::parseVersion((char*)udpData, udpDataLen) != "")
117
7.49k
        m_NextLayer = new SipResponseLayer(udpData, udpDataLen, this, m_Packet);
118
3.23k
      else
119
3.23k
        m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet);
120
52.0k
    }
121
105k
    else if ((RadiusLayer::isRadiusPort(portDst) || RadiusLayer::isRadiusPort(portSrc)) &&
122
105k
             RadiusLayer::isDataValid(udpData, udpDataLen))
123
7.48k
      m_NextLayer = new RadiusLayer(udpData, udpDataLen, this, m_Packet);
124
98.1k
    else if ((GtpV1Layer::isGTPv1Port(portDst) || GtpV1Layer::isGTPv1Port(portSrc)) &&
125
98.1k
             GtpV1Layer::isGTPv1(udpData, udpDataLen))
126
18.0k
      m_NextLayer = new GtpV1Layer(udpData, udpDataLen, this, m_Packet);
127
80.0k
    else if ((GtpV2Layer::isGTPv2Port(portDst) || GtpV2Layer::isGTPv2Port(portSrc)) &&
128
80.0k
             GtpV2Layer::isDataValid(udpData, udpDataLen))
129
0
      m_NextLayer = new GtpV2Layer(udpData, udpDataLen, this, m_Packet);
130
80.0k
    else if ((DhcpV6Layer::isDhcpV6Port(portSrc) || DhcpV6Layer::isDhcpV6Port(portDst)) &&
131
80.0k
             (DhcpV6Layer::isDataValid(udpData, udpDataLen)))
132
19.8k
      m_NextLayer = new DhcpV6Layer(udpData, udpDataLen, this, m_Packet);
133
60.2k
    else if ((NtpLayer::isNTPPort(portSrc) || NtpLayer::isNTPPort(portDst)) &&
134
60.2k
             NtpLayer::isDataValid(udpData, udpDataLen))
135
7.29k
      m_NextLayer = new NtpLayer(udpData, udpDataLen, this, m_Packet);
136
52.9k
    else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst))
137
27.8k
      m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, m_Packet);
138
25.1k
    else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen)))
139
130
      m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet);
140
24.9k
    else if ((WireGuardLayer::isWireGuardPorts(portDst, portSrc) &&
141
24.9k
              WireGuardLayer::isDataValid(udpData, udpDataLen)))
142
2.52k
    {
143
2.52k
      m_NextLayer = WireGuardLayer::parseWireGuardLayer(udpData, udpDataLen, this, m_Packet);
144
2.52k
      if (!m_NextLayer)
145
0
        m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet);
146
2.52k
    }
147
22.4k
    else
148
22.4k
      m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet);
149
217k
  }
150
151
  void UdpLayer::computeCalculateFields()
152
34.9k
  {
153
34.9k
    udphdr* udpHdr = (udphdr*)m_Data;
154
34.9k
    udpHdr->length = htobe16(m_DataLen);
155
34.9k
    calculateChecksum(true);
156
34.9k
  }
157
158
  std::string UdpLayer::toString() const
159
69.8k
  {
160
69.8k
    std::ostringstream srcPortStream;
161
69.8k
    srcPortStream << getSrcPort();
162
69.8k
    std::ostringstream dstPortStream;
163
69.8k
    dstPortStream << getDstPort();
164
165
69.8k
    return "UDP Layer, Src port: " + srcPortStream.str() + ", Dst port: " + dstPortStream.str();
166
69.8k
  }
167
168
}  // namespace pcpp