#ifndef PCAPPP_IPADDRESS #define PCAPPP_IPADDRESS #include #include #include #define MAX_ADDR_STRING_LEN 40 //xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx\0 #define MAX_IPV4_STRING_LEN 16 //xxx.xxx.xxx.xxx\0 /// @file struct in_addr; struct in6_addr; /** * \namespace pcpp * \brief The main namespace for the PcapPlusPlus lib */ namespace pcpp { /** * @class IPAddress * Base class for IPv4Address and IPv6Address. It's an abstract class and cannot be used as is. * The only useful method in this class are the 2 static methods that constructs an IP address class from string */ class IPAddress { protected: bool m_IsValid; char m_AddressAsString[MAX_ADDR_STRING_LEN]; // protected c'tor IPAddress() : m_IsValid(false) { m_AddressAsString[0] = '\0'; } public: //Visual studio has always been stupid about returning something useful for __cplusplus //Only recently was this fixed - and even then it requires a specific hack to the command line during build //Its easier/more consistent to test _MSC_VER in VS //https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017 #if __cplusplus > 199711L || _MSC_VER >= 1800 //Maybe this can be 1600 for VS2010 typedef std::unique_ptr Ptr_t; #else typedef std::auto_ptr Ptr_t; #endif /** * An enum representing the address type: IPv4 or IPv6 */ enum AddressType { /** * IPv4 address type */ IPv4AddressType, /** * IPv6 address type */ IPv6AddressType }; virtual ~IPAddress() {} /** * Gets the address type: IPv4 or IPv6 * @return The address type */ virtual AddressType getType() const = 0; /** * Returns a std::string representation of the address * @return A string representation of the address */ std::string toString() const { return std::string(m_AddressAsString); } /** * Get an indication if the address is valid. An address can be invalid if it was constructed from illegal input, for example: * An IPv4 address that was constructed form the string "999.999.999.999" * @return True if the address is valid, false otherwise */ bool isValid() const { return m_IsValid; } /** * Clone the object * @return A newly allocated instance which is a clone of the current instance */ virtual IPAddress* clone() const = 0; /** * Compare between this IP address and another IP address. This method is different than operator==() implemented in IPv4Address * and IPv6Address in the sense that you can compare any IP type: IPv6 to IPv6, IPv4 to IPv4 or IPv4 to IPv6. * It fits cases when you're not sure which type you currently have * @return True if addresses match or false otherwise */ bool equals(const IPAddress* other) const; /** * Constructs an IP address of type IPv4 or IPv6 from a string (char*) representation * @param[in] addressAsString The address in string (char*) representation * @return an auto-pointer to IPv4Address or IPv6Address instance that the string address represents, or an auto-pointer to NULL if * the string doesn't represent either of types */ static Ptr_t fromString(char* addressAsString); /** * Constructs an IP address of type IPv4 or IPv6 from a std::string representation * @param[in] addressAsString The address in std::string representation * @return an auto-pointer to IPv4Address or IPv6Address instance that the string address represents, or an auto-pointer to NULL if * the string doesn't represent either of types */ static Ptr_t fromString(std::string addressAsString); }; /** * @class IPv4Address * Represents an IPv4 address (of type XXX.XXX.XXX.XXX). An instance of this class can be constructed from string, * 4-byte integer or from the in_addr struct. It can be converted to each of these types */ class IPv4Address : public IPAddress { private: in_addr* m_pInAddr; void init(const char* addressAsString); public: /** * A constructor that creates an instance of the class out of 4-byte integer value * @todo consider endianess in this method * @param[in] addressAsInt The address as 4-byte integer */ IPv4Address(uint32_t addressAsInt); /** * A constructor that creates an instance of the class out of string (char*) value * If the string doesn't represent a valid IPv4 address, instance will be invalid, meaning isValid() will return false * @param[in] addressAsString The string (char*) representation of the address */ IPv4Address(const char* addressAsString); /** * A constructor that creates an instance of the class out of std::string value * If the string doesn't represent a valid IPv4 address, instance will be invalid, meaning isValid() will return false * @param[in] addressAsString The std::string representation of the address */ IPv4Address(std::string addressAsString); /** * A constructor that creates an instance of the class out of in_addr struct pointer * @param[in] inAddr The in_addr struct representation of the address */ IPv4Address(in_addr* inAddr); ~IPv4Address(); /** * A copy constructor for this class */ IPv4Address(const IPv4Address& other); /** * @return IPv4AddressType */ AddressType getType() const { return IPv4AddressType; } IPAddress* clone() const; /** * Converts the IPv4 address into a 4B integer * @return a 4B integer representing the IPv4 address */ uint32_t toInt() const; /** * Returns a in_addr struct pointer representing the IPv4 address * @return a in_addr struct pointer representing the IPv4 address */ in_addr* toInAddr() const { return m_pInAddr; } /** * Overload of the comparison operator * @return true if 2 addresses are equal. False otherwise */ bool operator==(const IPv4Address& other) const { return toInt() == other.toInt(); } /** * Overload of the non-equal operator * @return true if 2 addresses are not equal. False otherwise */ bool operator!=(const IPv4Address& other) const { return toInt() != other.toInt(); } /** * Overload of the assignment operator */ IPv4Address& operator=(const IPv4Address& other); /** * Checks whether the address matches a subnet. * For example: if subnet is 10.1.1.X, subnet mask is 255.255.255.0 and address is 10.1.1.9 then the method will return true * Another example: if subnet is 10.1.X.X, subnet mask is 255.0.0.0 and address is 11.1.1.9 then the method will return false * @param[in] subnet The subnet to be verified. Notice it's an IPv4Address type, so subnets with don't-cares (like 10.0.0.X) must have some number * (it'll be ignored if subnet mask is correct) * @param[in] subnetMask A string representing the subnet mask to compare the address with the subnet * */ bool matchSubnet(const IPv4Address& subnet, const std::string& subnetMask) const; /** * Checks whether the address matches a subnet. * For example: if subnet is 10.1.1.X, subnet mask is 255.255.255.0 and address is 10.1.1.9 then the method will return true * Another example: if subnet is 10.1.X.X, subnet mask is 255.0.0.0 and address is 11.1.1.9 then the method will return false * @param[in] subnet The subnet to be verified. Notice it's an IPv4Address type, so subnets with don't-cares (like 10.0.0.X) must have some number * (it'll be ignored if subnet mask is correct) * @param[in] subnetMask The subnet mask to compare the address with the subnet * */ bool matchSubnet(const IPv4Address& subnet, const IPv4Address& subnetMask) const; /** * A static value representing a zero value of IPv4 address, meaning address of value "0.0.0.0" */ static IPv4Address Zero; }; /** * @class IPv6Address * Represents an IPv6 address (of type xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx). An instance of this class can be constructed from string, * 16-byte array or from the in6_addr struct. It can be converted or copied to each of these types */ class IPv6Address : public IPAddress { private: in6_addr* m_pInAddr; void init(char* addressAsString); public: ~IPv6Address(); /** * A constructor that creates an instance of the class out of a 16-Byte long byte array. * Array size must be 16 bytes, otherwise instance will be invalid, meaning isValid() will return false * @param addressAsUintArr A 16-byte array containing address value */ IPv6Address(uint8_t* addressAsUintArr); /** * A constructor that creates an instance of the class out of string (char*) value. * If the string doesn't represent a valid IPv6 address, instance will be invalid, meaning isValid() will return false * @param[in] addressAsString The string (char*) representation of the address */ IPv6Address(char* addressAsString); /** * A constructor that creates an instance of the class out of string std::string value * If the string doesn't represent a valid IPv6 address, instance will be invalid, meaning isValid() will return false * @param[in] addressAsString The string std::string representation of the address */ IPv6Address(std::string addressAsString); /** * A copy constructor for this class */ IPv6Address(const IPv6Address& other); /** * @return IPv6AddressType */ AddressType getType() const { return IPv6AddressType; } IPAddress* clone() const; /** * Returns a in6_addr struct pointer representing the IPv6 address * @return a in6_addr struct pointer representing the IPv6 address */ in6_addr* toIn6Addr() const { return m_pInAddr; } /** * Allocates a byte array and copies address value into it. Array deallocation is user responsibility * @param[in] arr A pointer to where array will be allocated * @param[out] length Returns the length in bytes of the array that was allocated */ void copyTo(uint8_t** arr, size_t& length) const; /** * Gets a pointer to an already allocated byte array and copies the address value to it. * This method assumes array allocated size is at least 16 (the size of an IPv6 address) * @param[in] arr A pointer to the array which address will be copied to */ void copyTo(uint8_t* arr) const; /** * Overload of the comparison operator * @return true if 2 addresses are equal. False otherwise */ bool operator==(const IPv6Address& other) const; /** * Overload of the non-equal operator * @return true if 2 addresses are not equal. False otherwise */ bool operator!=(const IPv6Address& other) const; /** * Overload of the assignment operator */ IPv6Address& operator=(const IPv6Address& other); /** * A static value representing a zero value of IPv6 address, meaning address of value * "0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0" */ static IPv6Address Zero; }; } // namespace pcpp #endif /* PCAPPP_IPADDRESS */