/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuIPAddress.hpp Date: 2022-8-16 Author: Reece ***/ #include "Networking.hpp" #include "AuIPAddress.hpp" namespace Aurora::IO::Net { IPAddress::IPAddress() { AuMemset(this, 0, sizeof(*this)); this->ip = EIPProtocol::eEnumInvalid; } IPAddress::IPAddress(const AuString &parse) { char buf[64]; static_assert(AuArraySize(buf) >= sizeof(struct in6_addr)); static_assert(AuArraySize(buf) >= sizeof(struct in_addr)); this->ip = EIPProtocol::eEnumInvalid; bool isIPV4 {}; if (parse.size() > 4) { isIPV4 = parse[1] == '.' || parse[2] == '.' || parse[3] == '.'; } // Requires Windows 8.1 or greater to link... if (::inet_pton(isIPV4 ? AF_INET : AF_INET6, parse.c_str(), buf) != 1) { return; } UpdateFromName(!isIPV4, buf); } AuString IPAddress::ToString() const { switch (this->ip) { case EIPProtocol::eIPProtocolV4: return fmt::format("{}.{}.{}.{}", this->v4[0], this->v4[1], this->v4[2], this->v4[3]); case EIPProtocol::eIPProtocolV6: return fmt::format("{:04x}:{:04x}:{:04x}:{:04x}:{:04x}:{:04x}:{:04x}:{:04x}", this->v6[0], this->v6[1], this->v6[2], this->v6[3], this->v6[4], this->v6[5], this->v6[6], this->v6[7]); } return {}; } void IPAddress::UpdateFromName(bool bIPv6, const char *buf) { if (!bIPv6) { AuWriteU32LE(this->v4, 0, AuReadU32LE(buf, 0)); this->ip = EIPProtocol::eIPProtocolV4; } else { auto ipv6 = reinterpret_cast(buf); for (int i = 0; i < AuArraySize(this->v6); i++) { AuWriteU16BE(this->v6, i * sizeof(*this->v6), ipv6[i]);// AuArraySize(this->v6) - 1 - i]); } this->ip = EIPProtocol::eIPProtocolV6; } } bool IPAddress::IsValid() const { return EIPProtocolIsValid(this->ip); } IPAddress::operator bool() const { return IsValid(); } bool IPAddress::operator==(const IPAddress &cmp) const { if (cmp.ip != this->ip) { return false; } switch (this->ip) { case EIPProtocol::eIPProtocolV4: { return AuMemcmp(cmp.v4, this->v4, sizeof(this->v4)) == 0; } case EIPProtocol::eIPProtocolV6: { return AuMemcmp(cmp.v6, this->v6, sizeof(this->v6)) == 0; } case EIPProtocol::kEnumInvalid: { return true; } } return false; } AuUInt IPToDomain(EIPProtocol protocol) { switch (protocol) { case EIPProtocol::eIPProtocolV4: { return AF_INET; } case EIPProtocol::eIPProtocolV6: { return AF_INET6; } } return 0; } }