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 #ifndef PACKET_H
0008 #define PACKET_H
0009 
0010 #include <array>
0011 #include <chrono>
0012 #include <cstdint>
0013 #include <functional>
0014 #include <iostream>
0015 
0016 #include "TimeStamps.h"
0017 
0018 class Packet
0019 {
0020 public:
0021     enum class NetworkProtocolType {
0022         Unknown,
0023         IPv4,
0024         IPv6,
0025     };
0026 
0027     enum class TransportProtocolType {
0028         Unknown,
0029         Tcp,
0030         Udp,
0031     };
0032 
0033     enum class Direction {
0034         Inbound,
0035         Outbound,
0036     };
0037 
0038     struct Address {
0039         std::array<uint32_t, 4> address = {0};
0040         uint32_t port = 0;
0041 
0042         inline bool operator==(const Address &other) const
0043         {
0044             return address == other.address && port == other.port;
0045         }
0046     };
0047 
0048     Packet();
0049 
0050     Packet(const TimeStamp::MicroSeconds &timeStamp, const uint8_t *data, uint32_t dataLength, uint32_t packetSize);
0051 
0052     ~Packet();
0053 
0054     Packet(const Packet &other) = delete;
0055     Packet(Packet &&other) = default;
0056 
0057     TimeStamp::MicroSeconds timeStamp() const;
0058     unsigned int size() const;
0059     NetworkProtocolType networkProtocol() const;
0060     TransportProtocolType transportProtocol() const;
0061     Address sourceAddress() const;
0062     Address destinationAddress() const;
0063 
0064 private:
0065     void parseIPv4(const uint8_t *data, int32_t dataLength);
0066     void parseIPv6(const uint8_t *data, int32_t dataLength);
0067     void parseTransport(uint8_t type, const uint8_t *data, int32_t dataLength);
0068 
0069     TimeStamp::MicroSeconds m_timeStamp;
0070     unsigned int m_size = 0;
0071 
0072     NetworkProtocolType m_networkProtocol = NetworkProtocolType::Unknown;
0073     TransportProtocolType m_transportProtocol = TransportProtocolType::Unknown;
0074 
0075     Address m_sourceAddress;
0076     Address m_destinationAddress;
0077 };
0078 
0079 inline std::ostream &operator<<(std::ostream &stream, const Packet::Address &address)
0080 {
0081     stream << std::hex << address.address[0] << ":" << address.address[1] << ":" << address.address[2] << ":" << address.address[3];
0082     stream << std::dec << "::" << address.port;
0083     return stream;
0084 }
0085 
0086 namespace std
0087 {
0088 template<>
0089 struct hash<Packet::Address> {
0090     using argument_type = Packet::Address;
0091     using result_type = std::size_t;
0092     inline result_type operator()(argument_type const &address) const noexcept
0093     {
0094         return std::hash<uint32_t>{}(address.address[0]) //
0095             ^ (std::hash<uint32_t>{}(address.address[1]) << 1) //
0096             ^ (std::hash<uint32_t>{}(address.address[2]) << 2) //
0097             ^ (std::hash<uint32_t>{}(address.address[3]) << 3) //
0098             ^ (std::hash<uint32_t>{}(address.port) << 4);
0099     }
0100 };
0101 }
0102 
0103 #endif // PACKET_H