added some socket classification functions

This commit is contained in:
hyung-hwan 2020-09-07 08:05:54 +00:00
parent 664a770a3a
commit bbeec42ad2
3 changed files with 95 additions and 9 deletions

View File

@ -45,8 +45,14 @@ struct qse_ip6ad_t
qse_uint8_t value[16];
};
#define QSE_IP4AD_IS_LOOPBACK(addr) ((((addr)->value) & QSE_CONST_HTON32(0xFF000000)) == QSE_CONST_HTON32(0x7F000000))
/* 127.0.0.0/8 */
#define QSE_IP4AD_IS_LOOPBACK(addr) ((((addr)->value) & QSE_CONST_HTON32(0xFF000000u)) == QSE_CONST_HTON32(0x7F000000u))
/* 169.254.0.0/16 */
#define QSE_IP4AD_IS_LINK_LOCAL(addr) ((((addr)->value) & QSE_CONST_HTON32(0xFFFF0000u)) == QSE_CONST_HTON32(0xA9FE0000u))
/* 224.0.0.0/4 */
#define QSE_IP4AD_IS_MULTICAST(addr) ((((addr)->value) & QSE_CONST_HTON32(0xF0000000u)) == QSE_CONST_HTON32(0xE0000000u))
/* ::1 */
#define QSE_IP6AD_IS_LOOPBACK(addr) \
((addr)->value[0] == 0 && (addr)->value[1] == 0 && \
(addr)->value[2] == 0 && (addr)->value[3] == 0 && \
@ -57,11 +63,13 @@ struct qse_ip6ad_t
(addr)->value[12] == 0 && (addr)->value[13] == 0 && \
(addr)->value[14] == 0 && (addr)->value[15] == 1)
// FE80::/10
/* FE80::/10 */
#define QSE_IP6AD_IS_LINK_LOCAL(addr) (this->value[0] == 0xFE && (this->value[1] & 0xC0) == 0x80)
// FEC0::/10
/* FEC0::/10 */
#define QSE_IP6AD_IS_SITE_LOCAL(addr) (this->value[0] == 0xFE && (this->value[1] & 0xC0) == 0xC0)
/* FF00::/8 */
#define QSE_IP6AD_IS_MULTICAST(addr) ((addr)->value[0] == 0xFF)
#define QSE_IP6AD_IS_MULTICAST_LINK_LOCAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x02)
#define QSE_IP6AD_IS_MULTICAST_SITE_LOCAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x05)

View File

@ -38,6 +38,14 @@ QSE_BEGIN_NAMESPACE(QSE)
class SocketAddress
{
public:
enum
{
MAX_IP4AD_STR_LEN = 15, // nnn.nnn.nnn.nnn
MAX_IP6AD_STR_LEN = 45, // XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX, XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:nnn.nnn.nnn.nnn
MAX_IP4AD_PORT_STR_LEN = 21, // nnn.nnn.nnn.nnn:AAAAA
MAX_IP6AD_PORT_STR_LEN = 53 // [....]:AAAAA
};
SocketAddress () QSE_CPP_NOEXCEPT;
SocketAddress (int family) QSE_CPP_NOEXCEPT;
SocketAddress (const qse_skad_t* skad) QSE_CPP_NOEXCEPT;
@ -93,10 +101,11 @@ public:
int resolve (const qse_wchar_t* service, const qse_wchar_t* host, int type) QSE_CPP_NOEXCEPT { return this->resolve(service, host, this->getFamily(), type); }
bool isLoopBack () const QSE_CPP_NOEXCEPT;
// TODO: isLinkLocal() const QSE_CPP_NOEXCEPT
// TODO: isSiteLocal() const QSE_CPP_NOEXCEPT
// TODO: isV4Mapped() const QSE_CPP_NOEXCEPT
//
bool isLinkLocal() const QSE_CPP_NOEXCEPT;
bool isSiteLocal() const QSE_CPP_NOEXCEPT;
bool isMulticast() const QSE_CPP_NOEXCEPT;
bool isV4Mapped() const QSE_CPP_NOEXCEPT;
//TODO: bool isInIpSubnet (const qse_ip4ad_t* addr, int prefix) const QSE_CPP_NOEXCEPT;
//TODO: bool isInIpSubnet (const qse_ip6ad_t* addr, int prefix) const QSE_CPP_NOEXCEPT;
bool isInIpSubnet (const qse_nwad_t* addr, int prefix) const QSE_CPP_NOEXCEPT;

View File

@ -378,21 +378,90 @@ bool SocketAddress::isLoopBack () const QSE_CPP_NOEXCEPT
{
case AF_INET:
{
// 127.0.0.0/8
struct sockaddr_in* v4 = (struct sockaddr_in*)&this->skad;
return v4->sin_addr.s_addr == QSE_CONST_HTON32(0x7F000001);
return (v4->sin_addr.s_addr & QSE_CONST_HTON32(0xFF000000u)) == QSE_CONST_HTON32(0x7F000000u);
}
case AF_INET6:
{
struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad;
qse_uint32_t* x = (qse_uint32_t*)v6->sin6_addr.s6_addr; // TODO: is this alignment safe?
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 1;
return (x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == QSE_CONST_HTON32(1)) ||
(this->isV4Mapped() && (x[3] & QSE_CONST_HTON32(0xFF000000u)) == QSE_CONST_HTON32(0x7F000000u));
}
}
return false;
}
bool SocketAddress::isLinkLocal() const QSE_CPP_NOEXCEPT
{
switch (FAMILY(&this->skad))
{
case AF_INET:
{
// 169.254.0.0/16
struct sockaddr_in* v4 = (struct sockaddr_in*)&this->skad;
return (v4->sin_addr.s_addr & QSE_CONST_HTON32(0xFFFF0000u)) == QSE_CONST_HTON32(0xA9FE0000u);
}
case AF_INET6:
{
// FE80::/10
struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad;
return v6->sin6_addr.s6_addr[0] == 0xFE && (v6->sin6_addr.s6_addr[1] & 0xC0) == 0x80;
}
}
return false;
}
bool SocketAddress::isSiteLocal() const QSE_CPP_NOEXCEPT
{
if (FAMILY(&this->skad) != AF_INET6) return false;
// FEC0::/10
struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad;
return v6->sin6_addr.s6_addr[0] == 0xFE && (v6->sin6_addr.s6_addr[1] & 0xC0) == 0xC0;
}
bool SocketAddress::isMulticast() const QSE_CPP_NOEXCEPT
{
switch (FAMILY(&this->skad))
{
case AF_INET:
{
// 224.0.0.0/4
struct sockaddr_in* v4 = (struct sockaddr_in*)&this->skad;
return (v4->sin_addr.s_addr & QSE_CONST_HTON32(0xF0000000u)) == QSE_CONST_HTON32(0xE0000000u);
}
case AF_INET6:
{
// FF00::/8
struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad;
return v6->sin6_addr.s6_addr[0] == 0xFF;
}
}
return false;
}
bool SocketAddress::isV4Mapped() const QSE_CPP_NOEXCEPT
{
if (FAMILY(&this->skad) != AF_INET6) return false;
struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad;
return v6->sin6_addr.s6_addr[0] == 0x00 && v6->sin6_addr.s6_addr[1] == 0x00 &&
v6->sin6_addr.s6_addr[2] == 0x00 && v6->sin6_addr.s6_addr[3] == 0x00 &&
v6->sin6_addr.s6_addr[4] == 0x00 && v6->sin6_addr.s6_addr[5] == 0x00 &&
v6->sin6_addr.s6_addr[6] == 0x00 && v6->sin6_addr.s6_addr[7] == 0x00 &&
v6->sin6_addr.s6_addr[8] == 0x00 && v6->sin6_addr.s6_addr[9] == 0x00 &&
v6->sin6_addr.s6_addr[10] == 0xFF && v6->sin6_addr.s6_addr[11] == 0xFF;
}
bool SocketAddress::isInIpSubnet (const qse_nwad_t* addr, int prefix) const QSE_CPP_NOEXCEPT
{
switch (addr->type)