/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 |