added some socket classification functions
This commit is contained in:
		| @ -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) | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user