File indexing completed on 2024-06-23 05:27:54
0001 /* 0002 SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "Packet.h" 0008 0009 #include <arpa/inet.h> 0010 #include <net/ethernet.h> 0011 #include <netinet/in.h> 0012 #include <netinet/ip.h> 0013 #include <netinet/ip6.h> 0014 #include <netinet/tcp.h> 0015 #include <netinet/udp.h> 0016 #include <sys/types.h> 0017 0018 #include <pcap/pcap.h> 0019 #include <pcap/sll.h> 0020 0021 uint32_t u8Tou32(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth) 0022 { 0023 return uint32_t(first) << 24 | uint32_t(second) << 16 | uint32_t(third) << 8 | uint32_t(fourth); 0024 } 0025 0026 Packet::Packet() 0027 { 0028 } 0029 0030 Packet::Packet(const TimeStamp::MicroSeconds &timeStamp, const uint8_t *data, uint32_t dataLength, uint32_t packetSize) 0031 : m_timeStamp(timeStamp) 0032 { 0033 m_size = packetSize; 0034 0035 const sll_header *header = reinterpret_cast<const sll_header *>(data); 0036 switch (ntohs(header->sll_protocol)) { 0037 case ETHERTYPE_IP: 0038 m_networkProtocol = NetworkProtocolType::IPv4; 0039 if (sizeof(sll_header) <= dataLength) { 0040 parseIPv4(data + sizeof(sll_header), dataLength - sizeof(sll_header)); 0041 } 0042 break; 0043 case ETHERTYPE_IPV6: 0044 m_networkProtocol = NetworkProtocolType::IPv6; 0045 if (sizeof(sll_header) <= dataLength) { 0046 parseIPv6(data + sizeof(sll_header), dataLength - sizeof(sll_header)); 0047 } 0048 break; 0049 default: 0050 m_networkProtocol = NetworkProtocolType::Unknown; 0051 break; 0052 } 0053 } 0054 0055 Packet::~Packet() 0056 { 0057 } 0058 0059 unsigned int Packet::size() const 0060 { 0061 return m_size; 0062 } 0063 0064 TimeStamp::MicroSeconds Packet::timeStamp() const 0065 { 0066 return m_timeStamp; 0067 } 0068 0069 Packet::NetworkProtocolType Packet::networkProtocol() const 0070 { 0071 return m_networkProtocol; 0072 } 0073 0074 Packet::TransportProtocolType Packet::transportProtocol() const 0075 { 0076 return m_transportProtocol; 0077 } 0078 0079 Packet::Address Packet::sourceAddress() const 0080 { 0081 return m_sourceAddress; 0082 } 0083 0084 Packet::Address Packet::destinationAddress() const 0085 { 0086 return m_destinationAddress; 0087 } 0088 0089 void Packet::parseIPv4(const uint8_t *data, int32_t dataLength) 0090 { 0091 if (dataLength < int32_t(sizeof(ip))) { 0092 return; 0093 } 0094 0095 const ip *header = reinterpret_cast<const ip *>(data); 0096 0097 m_sourceAddress.address[3] = header->ip_src.s_addr; 0098 m_destinationAddress.address[3] = header->ip_dst.s_addr; 0099 0100 parseTransport(header->ip_p, data + sizeof(ip), dataLength - sizeof(ip)); 0101 } 0102 0103 void Packet::parseIPv6(const uint8_t *data, int32_t dataLength) 0104 { 0105 if (dataLength < int32_t(sizeof(ip6_hdr))) { 0106 return; 0107 } 0108 0109 const ip6_hdr *header = reinterpret_cast<const ip6_hdr *>(data); 0110 0111 m_sourceAddress.address = { 0112 u8Tou32(header->ip6_src.s6_addr[0], header->ip6_src.s6_addr[1], header->ip6_src.s6_addr[2], header->ip6_src.s6_addr[3]), 0113 u8Tou32(header->ip6_src.s6_addr[4], header->ip6_src.s6_addr[5], header->ip6_src.s6_addr[6], header->ip6_src.s6_addr[7]), 0114 u8Tou32(header->ip6_src.s6_addr[8], header->ip6_src.s6_addr[9], header->ip6_src.s6_addr[10], header->ip6_src.s6_addr[11]), 0115 u8Tou32(header->ip6_src.s6_addr[12], header->ip6_src.s6_addr[13], header->ip6_src.s6_addr[14], header->ip6_src.s6_addr[15]), 0116 }; 0117 m_destinationAddress.address = { 0118 u8Tou32(header->ip6_dst.s6_addr[0], header->ip6_dst.s6_addr[1], header->ip6_dst.s6_addr[2], header->ip6_dst.s6_addr[3]), 0119 u8Tou32(header->ip6_dst.s6_addr[4], header->ip6_dst.s6_addr[5], header->ip6_dst.s6_addr[6], header->ip6_dst.s6_addr[7]), 0120 u8Tou32(header->ip6_dst.s6_addr[8], header->ip6_dst.s6_addr[9], header->ip6_dst.s6_addr[10], header->ip6_dst.s6_addr[11]), 0121 u8Tou32(header->ip6_dst.s6_addr[12], header->ip6_dst.s6_addr[13], header->ip6_dst.s6_addr[14], header->ip6_dst.s6_addr[15]), 0122 }; 0123 0124 parseTransport(header->ip6_nxt, data + sizeof(ip6_hdr), dataLength - sizeof(ip6_hdr)); 0125 } 0126 0127 void Packet::parseTransport(uint8_t type, const uint8_t *data, int32_t dataLength) 0128 { 0129 switch (type) { 0130 case IPPROTO_TCP: { 0131 m_transportProtocol = TransportProtocolType::Tcp; 0132 if (dataLength >= int32_t(sizeof(tcphdr))) { 0133 const tcphdr *tcpHeader = reinterpret_cast<const tcphdr *>(data); 0134 m_sourceAddress.port = ntohs(tcpHeader->th_sport); 0135 m_destinationAddress.port = ntohs(tcpHeader->th_dport); 0136 } 0137 break; 0138 } 0139 case IPPROTO_UDP: { 0140 m_transportProtocol = TransportProtocolType::Udp; 0141 if (dataLength >= int32_t(sizeof(udphdr))) { 0142 const udphdr *udpHeader = reinterpret_cast<const udphdr *>(data); 0143 m_sourceAddress.port = ntohs(udpHeader->uh_sport); 0144 m_destinationAddress.port = ntohs(udpHeader->uh_dport); 0145 } 0146 break; 0147 } 0148 default: 0149 m_transportProtocol = TransportProtocolType::Unknown; 0150 break; 0151 } 0152 }