/src/PcapPlusPlus/Packet++/src/UdpLayer.cpp
Line | Count | Source |
1 | 93.9k | #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 | 383k | { |
41 | 383k | return be16toh(getUdpHeader()->portSrc); |
42 | 383k | } |
43 | | |
44 | | uint16_t UdpLayer::getDstPort() const |
45 | 383k | { |
46 | 383k | return be16toh(getUdpHeader()->portDst); |
47 | 383k | } |
48 | | |
49 | | uint16_t UdpLayer::calculateChecksum(bool writeResultToPacket) |
50 | 46.9k | { |
51 | 46.9k | udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data); |
52 | 46.9k | uint16_t checksumRes = 0; |
53 | 46.9k | uint16_t currChecksumValue = udpHdr->headerChecksum; |
54 | | |
55 | 46.9k | if (m_PrevLayer != nullptr) |
56 | 46.9k | { |
57 | 46.9k | udpHdr->headerChecksum = 0; |
58 | 46.9k | PCPP_LOG_DEBUG("UDP data len = " << m_DataLen); |
59 | | |
60 | 46.9k | if (m_PrevLayer->getProtocol() == IPv4) |
61 | 41.3k | { |
62 | 41.3k | IPv4Address srcIP = static_cast<IPv4Layer*>(m_PrevLayer)->getSrcIPv4Address(); |
63 | 41.3k | IPv4Address dstIP = static_cast<IPv4Layer*>(m_PrevLayer)->getDstIPv4Address(); |
64 | | |
65 | 41.3k | checksumRes = pcpp::computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv4AddressType, |
66 | 41.3k | PACKETPP_IPPROTO_UDP, srcIP, dstIP); |
67 | | |
68 | 41.3k | PCPP_LOG_DEBUG("calculated IPv4 UDP checksum = 0x" << std::uppercase << std::hex << checksumRes); |
69 | 41.3k | } |
70 | 5.69k | else if (m_PrevLayer->getProtocol() == IPv6) |
71 | 5.69k | { |
72 | 5.69k | IPv6Address srcIP = static_cast<IPv6Layer*>(m_PrevLayer)->getSrcIPv6Address(); |
73 | 5.69k | IPv6Address dstIP = static_cast<IPv6Layer*>(m_PrevLayer)->getDstIPv6Address(); |
74 | | |
75 | 5.69k | checksumRes = computePseudoHdrChecksum((uint8_t*)udpHdr, getDataLen(), IPAddress::IPv6AddressType, |
76 | 5.69k | PACKETPP_IPPROTO_UDP, srcIP, dstIP); |
77 | | |
78 | 5.69k | PCPP_LOG_DEBUG("calculated IPv6 UDP checksum = 0xX" << std::uppercase << std::hex << checksumRes); |
79 | 5.69k | } |
80 | 46.9k | } |
81 | | |
82 | 46.9k | if (checksumRes == 0) |
83 | 33 | checksumRes = 0xffff; |
84 | | |
85 | 46.9k | if (writeResultToPacket) |
86 | 46.9k | udpHdr->headerChecksum = htobe16(checksumRes); |
87 | 0 | else |
88 | 0 | udpHdr->headerChecksum = currChecksumValue; |
89 | | |
90 | 46.9k | return checksumRes; |
91 | 46.9k | } |
92 | | |
93 | | void UdpLayer::parseNextLayer() |
94 | 289k | { |
95 | 289k | if (m_DataLen <= sizeof(udphdr)) |
96 | 0 | return; |
97 | | |
98 | 289k | uint16_t portDst = getDstPort(); |
99 | 289k | uint16_t portSrc = getSrcPort(); |
100 | | |
101 | 289k | uint8_t* udpData = m_Data + sizeof(udphdr); |
102 | 289k | size_t udpDataLen = m_DataLen - sizeof(udphdr); |
103 | | |
104 | 289k | if (DhcpLayer::isDhcpPorts(portSrc, portDst)) |
105 | 13.2k | m_NextLayer = new DhcpLayer(udpData, udpDataLen, this, m_Packet); |
106 | 275k | else if (VxlanLayer::isVxlanPort(portDst)) |
107 | 0 | m_NextLayer = new VxlanLayer(udpData, udpDataLen, this, m_Packet); |
108 | 275k | else if (DnsLayer::isDataValid(udpData, udpDataLen) && |
109 | 251k | (DnsLayer::isDnsPort(portDst) || DnsLayer::isDnsPort(portSrc))) |
110 | 53.3k | m_NextLayer = new DnsLayer(udpData, udpDataLen, this, m_Packet); |
111 | 222k | else if (SipLayer::isSipPort(portDst) || SipLayer::isSipPort(portSrc)) |
112 | 59.4k | { |
113 | 59.4k | if (SipRequestFirstLine::parseMethod((char*)udpData, udpDataLen) != SipRequestLayer::SipMethodUnknown) |
114 | 49.8k | m_NextLayer = new SipRequestLayer(udpData, udpDataLen, this, m_Packet); |
115 | 9.55k | else if (SipResponseFirstLine::parseStatusCode((char*)udpData, udpDataLen) != |
116 | 9.55k | SipResponseLayer::SipStatusCodeUnknown && |
117 | 7.73k | SipResponseFirstLine::parseVersion((char*)udpData, udpDataLen) != "") |
118 | 5.76k | m_NextLayer = new SipResponseLayer(udpData, udpDataLen, this, m_Packet); |
119 | 3.79k | else |
120 | 3.79k | m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); |
121 | 59.4k | } |
122 | 163k | else if ((RadiusLayer::isRadiusPort(portDst) || RadiusLayer::isRadiusPort(portSrc)) && |
123 | 10.3k | RadiusLayer::isDataValid(udpData, udpDataLen)) |
124 | 9.59k | m_NextLayer = new RadiusLayer(udpData, udpDataLen, this, m_Packet); |
125 | 153k | else if ((GtpV1Layer::isGTPv1Port(portDst) || GtpV1Layer::isGTPv1Port(portSrc)) && |
126 | 27.7k | GtpV1Layer::isGTPv1(udpData, udpDataLen)) |
127 | 27.4k | m_NextLayer = new GtpV1Layer(udpData, udpDataLen, this, m_Packet); |
128 | 126k | else if ((GtpV2Layer::isGTPv2Port(portDst) || GtpV2Layer::isGTPv2Port(portSrc)) && |
129 | 0 | GtpV2Layer::isDataValid(udpData, udpDataLen)) |
130 | 0 | m_NextLayer = new GtpV2Layer(udpData, udpDataLen, this, m_Packet); |
131 | 126k | else if ((DhcpV6Layer::isDhcpV6Port(portSrc) || DhcpV6Layer::isDhcpV6Port(portDst)) && |
132 | 17.7k | (DhcpV6Layer::isDataValid(udpData, udpDataLen))) |
133 | 17.6k | m_NextLayer = new DhcpV6Layer(udpData, udpDataLen, this, m_Packet); |
134 | 108k | else if ((NtpLayer::isNTPPort(portSrc) || NtpLayer::isNTPPort(portDst)) && |
135 | 14.7k | NtpLayer::isDataValid(udpData, udpDataLen)) |
136 | 14.7k | m_NextLayer = new NtpLayer(udpData, udpDataLen, this, m_Packet); |
137 | 93.6k | else if ((DoIpLayer::isDoIpPort(portSrc) || DoIpLayer::isDoIpPort(portDst)) && |
138 | 30.4k | (DoIpLayer::isDataValid(udpData, udpDataLen))) |
139 | 28.6k | { |
140 | 28.6k | m_NextLayer = DoIpLayer::parseDoIpLayer(udpData, udpDataLen, this, m_Packet); |
141 | 28.6k | if (!m_NextLayer) |
142 | 42 | constructNextLayer<PayloadLayer>(udpData, udpDataLen, m_Packet); |
143 | 28.6k | } |
144 | 65.0k | else if (SomeIpLayer::isSomeIpPort(portSrc) || SomeIpLayer::isSomeIpPort(portDst)) |
145 | 30.1k | m_NextLayer = SomeIpLayer::parseSomeIpLayer(udpData, udpDataLen, this, m_Packet); |
146 | 34.8k | else if ((WakeOnLanLayer::isWakeOnLanPort(portDst) && WakeOnLanLayer::isDataValid(udpData, udpDataLen))) |
147 | 200 | m_NextLayer = new WakeOnLanLayer(udpData, udpDataLen, this, m_Packet); |
148 | 34.6k | else if ((WireGuardLayer::isWireGuardPorts(portDst, portSrc) && |
149 | 2.32k | WireGuardLayer::isDataValid(udpData, udpDataLen))) |
150 | 2.29k | { |
151 | 2.29k | m_NextLayer = WireGuardLayer::parseWireGuardLayer(udpData, udpDataLen, this, m_Packet); |
152 | 2.29k | if (!m_NextLayer) |
153 | 0 | m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); |
154 | 2.29k | } |
155 | 32.3k | else |
156 | 32.3k | m_NextLayer = new PayloadLayer(udpData, udpDataLen, this, m_Packet); |
157 | 289k | } |
158 | | |
159 | | void UdpLayer::computeCalculateFields() |
160 | 46.9k | { |
161 | 46.9k | udphdr* udpHdr = reinterpret_cast<udphdr*>(m_Data); |
162 | 46.9k | udpHdr->length = htobe16(m_DataLen); |
163 | 46.9k | calculateChecksum(true); |
164 | 46.9k | } |
165 | | |
166 | | std::string UdpLayer::toString() const |
167 | 93.9k | { |
168 | 93.9k | std::ostringstream srcPortStream; |
169 | 93.9k | srcPortStream << getSrcPort(); |
170 | 93.9k | std::ostringstream dstPortStream; |
171 | 93.9k | dstPortStream << getDstPort(); |
172 | | |
173 | 93.9k | return "UDP Layer, Src port: " + srcPortStream.str() + ", Dst port: " + dstPortStream.str(); |
174 | 93.9k | } |
175 | | |
176 | | } // namespace pcpp |