diff --git a/qse/include/qse/si/SocketAddress.hpp b/qse/include/qse/si/SocketAddress.hpp index aced48bb..5ee16e30 100644 --- a/qse/include/qse/si/SocketAddress.hpp +++ b/qse/include/qse/si/SocketAddress.hpp @@ -96,6 +96,11 @@ public: // TODO: isLinkLocal() const QSE_CPP_NOEXCEPT // TODO: isSiteLocal() const QSE_CPP_NOEXCEPT // TODO: 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; + //TODO: bool isInIpSubnet (const qse_skad_t* addr, int prefix) const QSE_CPP_NOEXCEPT; qse_mchar_t* toStrBuf (qse_mchar_t* buf, qse_size_t len) const QSE_CPP_NOEXCEPT; qse_wchar_t* toStrBuf (qse_wchar_t* buf, qse_size_t len) const QSE_CPP_NOEXCEPT; diff --git a/qse/include/qse/si/nwad.h b/qse/include/qse/si/nwad.h index 349452ba..2f0af6e8 100644 --- a/qse/include/qse/si/nwad.h +++ b/qse/include/qse/si/nwad.h @@ -248,6 +248,15 @@ QSE_EXPORT qse_uint16_t qse_getnwadport ( qse_nwad_t* nwad ); +/** + * The qse_getnwadipsize() function returns the size of the contained + * IP address. If the given \a nwad doesn't represent an IP address, + * it returns 0. + */ +QSE_EXPORT int qse_getnwadipsize ( + qse_nwad_t* nwad +); + /** * The qse_mbstonwad() function converts a multi-byte string \a mbs to a * network address and stores it to memory pointed to by \a nwad. diff --git a/qse/lib/si/SocketAddress.cpp b/qse/lib/si/SocketAddress.cpp index d00c0f0f..7fcb743b 100644 --- a/qse/lib/si/SocketAddress.cpp +++ b/qse/lib/si/SocketAddress.cpp @@ -393,6 +393,49 @@ bool SocketAddress::isLoopBack () const QSE_CPP_NOEXCEPT return false; } +bool SocketAddress::isInIpSubnet (const qse_nwad_t* addr, int prefix) const QSE_CPP_NOEXCEPT +{ + switch (addr->type) + { + case QSE_NWAD_IN4: + if (prefix >= 1 && prefix <= 32) + { + const qse_ip4ad_t* me = this->getIp4addr(); + if (me) + { + qse_ip4ad_t mask; + qse_prefixtoip4ad (prefix, &mask); + return (me->value & mask.value) == (addr->u.in4.addr.value & mask.value); + } + } + break; + + case QSE_NWAD_IN6: + if (prefix >= 1 && prefix <= 128) + { + const qse_ip6ad_t* me = this->getIp6addr(); + if (me) + { + qse_ip6ad_t mask; + qse_prefixtoip6ad (prefix, &mask); + const qse_uint32_t* x = (const qse_uint32_t*)me->value; + const qse_uint32_t* y = (const qse_uint32_t*)addr->u.in6.addr.value; + const qse_uint32_t* z = (const qse_uint32_t*)mask.value; + return (x[0] & z[0]) == (y[0] & z[0]) && + (x[1] & z[1]) == (y[1] & z[1]) && + (x[2] & z[2]) == (y[2] & z[2]) && + (x[3] & z[3]) == (y[3] & z[3]); + } + } + break; + + default: + break; + } + + return false; +} + qse_wchar_t* SocketAddress::toStrBuf (qse_wchar_t* buf, qse_size_t len) const QSE_CPP_NOEXCEPT { qse_nwad_t nwad; diff --git a/qse/lib/si/nwad.c b/qse/lib/si/nwad.c index a670a8fb..0f5a14a5 100644 --- a/qse/lib/si/nwad.c +++ b/qse/lib/si/nwad.c @@ -35,7 +35,7 @@ #include "../cmn/mem-prv.h" -void qse_initnwadwithip4ad (qse_nwad_t* nwad, qse_uint16_t port, const qse_ip4ad_t* ipad) +void qse_initnwadwithip4ad (qse_nwad_t* nwad, qse_uint16_t port, const qse_ip4ad_t* ipad) { QSE_MEMSET (nwad, 0, QSE_SIZEOF(*nwad)); nwad->type = QSE_NWAD_IN4; @@ -116,6 +116,22 @@ qse_uint16_t qse_getnwadport (qse_nwad_t* nwad) } } +int qse_getnwadipsize (qse_nwad_t* nwad) +{ + switch (nwad->type) + { + case QSE_NWAD_IN4: + return QSE_SIZEOF(qse_ip4ad_t); + + case QSE_NWAD_IN6: + return QSE_SIZEOF(qse_ip6ad_t); + + case QSE_NWAD_LOCAL: + default: + return 0; + } +} + int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad) { return qse_mbsntonwad (str, qse_mbslen(str), nwad); diff --git a/qse/lib/si/sck.c b/qse/lib/si/sck.c index 104f6296..22a490c8 100644 --- a/qse/lib/si/sck.c +++ b/qse/lib/si/sck.c @@ -294,6 +294,7 @@ int qse_fini_sck_conn (qse_sck_hnd_t handle) } else if (ret != 0) { + errno = ret; return -1; /* failure */ }