added some socket classification functions
This commit is contained in:
		| @ -45,8 +45,14 @@ struct qse_ip6ad_t | |||||||
| 	qse_uint8_t value[16]; | 	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) \ | #define QSE_IP6AD_IS_LOOPBACK(addr) \ | ||||||
| 		((addr)->value[0] == 0 && (addr)->value[1] == 0 && \ | 		((addr)->value[0] == 0 && (addr)->value[1] == 0 && \ | ||||||
| 		 (addr)->value[2] == 0 && (addr)->value[3] == 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[12] == 0 && (addr)->value[13] == 0 && \ | ||||||
| 		 (addr)->value[14] == 0 && (addr)->value[15] == 1) | 		 (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) | #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) | #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(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_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) | #define QSE_IP6AD_IS_MULTICAST_SITE_LOCAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x05) | ||||||
|  | |||||||
| @ -38,6 +38,14 @@ QSE_BEGIN_NAMESPACE(QSE) | |||||||
| class SocketAddress | class SocketAddress | ||||||
| { | { | ||||||
| public: | 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 () QSE_CPP_NOEXCEPT; | ||||||
| 	SocketAddress (int family) QSE_CPP_NOEXCEPT; | 	SocketAddress (int family) QSE_CPP_NOEXCEPT; | ||||||
| 	SocketAddress (const qse_skad_t* skad) 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); } | 	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; | 	bool isLoopBack () const QSE_CPP_NOEXCEPT; | ||||||
| 	// TODO: isLinkLocal() const QSE_CPP_NOEXCEPT | 	bool isLinkLocal() const QSE_CPP_NOEXCEPT; | ||||||
| 	// TODO: isSiteLocal() const QSE_CPP_NOEXCEPT | 	bool isSiteLocal() const QSE_CPP_NOEXCEPT; | ||||||
| 	// TODO: isV4Mapped() 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_ip4ad_t* addr, int prefix) const  QSE_CPP_NOEXCEPT; | ||||||
| 	//TODO: bool isInIpSubnet (const qse_ip6ad_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; | 	bool isInIpSubnet (const qse_nwad_t* addr, int prefix) const  QSE_CPP_NOEXCEPT; | ||||||
|  | |||||||
| @ -378,21 +378,90 @@ bool SocketAddress::isLoopBack () const QSE_CPP_NOEXCEPT | |||||||
| 	{ | 	{ | ||||||
| 		case AF_INET: | 		case AF_INET: | ||||||
| 		{ | 		{ | ||||||
|  | 			// 127.0.0.0/8 | ||||||
| 			struct sockaddr_in* v4 = (struct sockaddr_in*)&this->skad; | 			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: | 		case AF_INET6: | ||||||
| 		{ | 		{ | ||||||
| 			struct sockaddr_in6* v6 = (struct sockaddr_in6*)&this->skad; | 			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?  | 			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; | 	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 | bool SocketAddress::isInIpSubnet (const qse_nwad_t* addr, int prefix) const QSE_CPP_NOEXCEPT | ||||||
| { | { | ||||||
| 	switch (addr->type) | 	switch (addr->type) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user