⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipaddress.cpp

📁 C++ class libraries for network-centric, portable applications, integrated perfectly with the C++ St
💻 CPP
字号:
//// IPAddress.cpp//// $Id: //poco/1.2/Net/src/IPAddress.cpp#2 $//// Library: Net// Package: NetCore// Module:  IPAddress//// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/Net/IPAddress.h"#include "Poco/Net/NetException.h"#include "Poco/RefCountedObject.h"#include "Poco/NumberFormatter.h"#include "Poco/Types.h"#include <algorithm>#include <string.h>using Poco::RefCountedObject;using Poco::NumberFormatter;using Poco::UInt8;using Poco::UInt16;using Poco::UInt32;namespace Poco {namespace Net {//// IPAddressImpl//class IPAddressImpl: public RefCountedObject{public:	virtual std::string toString() const = 0;	virtual poco_socklen_t length() const = 0;	virtual const void* addr() const = 0;	virtual IPAddress::Family family() const = 0;	virtual int af() const = 0;	virtual bool isWildcard() const	= 0;	virtual bool isBroadcast() const = 0;	virtual bool isLoopback() const = 0;	virtual bool isMulticast() const = 0;	virtual bool isLinkLocal() const = 0;	virtual bool isSiteLocal() const = 0;	virtual bool isIPv4Mapped() const = 0;	virtual bool isIPv4Compatible() const = 0;	virtual bool isWellKnownMC() const = 0;	virtual bool isNodeLocalMC() const = 0;	virtual bool isLinkLocalMC() const = 0;	virtual bool isSiteLocalMC() const = 0;	virtual bool isOrgLocalMC() const = 0;	virtual bool isGlobalMC() const = 0;protected:	IPAddressImpl()	{	}		virtual ~IPAddressImpl()	{	}private:	IPAddressImpl(const IPAddressImpl&);	IPAddressImpl& operator = (const IPAddressImpl&);};class IPv4AddressImpl: public IPAddressImpl{public:	IPv4AddressImpl()	{		memset(&_addr, 0, sizeof(_addr));	}		IPv4AddressImpl(const void* addr)	{		memcpy(&_addr, addr, sizeof(_addr));	}		std::string toString() const	{		const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);		std::string result;		result.reserve(16);		result.append(NumberFormatter::format(bytes[0]));		result.append(".");		result.append(NumberFormatter::format(bytes[1]));		result.append(".");		result.append(NumberFormatter::format(bytes[2]));		result.append(".");		result.append(NumberFormatter::format(bytes[3]));		return result;	}	poco_socklen_t length() const	{		return sizeof(_addr);	}		const void* addr() const	{		return &_addr;	}		IPAddress::Family family() const	{		return IPAddress::IPv4;	}		int af() const	{		return AF_INET;	}		bool isWildcard() const	{		return _addr.s_addr == INADDR_ANY;	}		bool isBroadcast() const	{		return _addr.s_addr == INADDR_NONE;	}		bool isLoopback() const	{		return ntohl(_addr.s_addr) == 0x7F000001; // 127.0.0.1	}		bool isMulticast() const	{		return (ntohl(_addr.s_addr) & 0xF0000000) == 0xE0000000; // 224.0.0.0/24 to 239.0.0.0/24	}			bool isLinkLocal() const	{		return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xA9FE0000; // 169.254.0.0/16	}		bool isSiteLocal() const	{		UInt32 addr = ntohl(_addr.s_addr);		return (addr & 0xFF000000) == 0x0A000000 ||      // 10.0.0.0/24		       (addr & 0xFFFF0000) == 0xC0A80000 ||      // 192.68.0.0/16		       addr >= 0xAC100000 && addr <= 0xAC1FFFFF; // 172.16.0.0 to 172.31.255.255	}		bool isIPv4Compatible() const	{		return true;	}	bool isIPv4Mapped() const	{		return true;	}	bool isWellKnownMC() const	{		return (ntohl(_addr.s_addr) & 0xFFFFFF00) == 0xE0000000; // 224.0.0.0/8	}		bool isNodeLocalMC() const	{		return false;	}		bool isLinkLocalMC() const	{		return (ntohl(_addr.s_addr) & 0xFF000000) == 0xE0000000; // 244.0.0.0/24	}		bool isSiteLocalMC() const	{		return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFFF0000; // 239.255.0.0/16	}		bool isOrgLocalMC() const	{		return (ntohl(_addr.s_addr) & 0xFFFF0000) == 0xEFC00000; // 239.192.0.0/16	}		bool isGlobalMC() const	{		UInt32 addr = ntohl(_addr.s_addr);		return addr >= 0xE0000100 && addr <= 0xEE000000; // 224.0.1.0 to 238.255.255.255	}	static IPv4AddressImpl* parse(const std::string& addr)	{		if (addr.empty()) return 0;		#if defined(_WIN32)		struct in_addr ia;		ia.s_addr = inet_addr(addr.c_str());		if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")			return 0;		else			return new IPv4AddressImpl(&ia);#else		struct in_addr ia;		if (inet_aton(addr.c_str(), &ia))			return new IPv4AddressImpl(&ia);		else			return 0;#endif	}		private:	struct in_addr _addr;	};#if defined(POCO_HAVE_IPv6)class IPv6AddressImpl: public IPAddressImpl{public:	IPv6AddressImpl()	{		memset(&_addr, 0, sizeof(_addr));	}	IPv6AddressImpl(const void* addr)	{		memcpy(&_addr, addr, sizeof(_addr));	}	std::string toString() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		if (isIPv4Compatible() || isIPv4Mapped())		{			std::string result;			result.reserve(24);			if (words[5] == 0)				result.append("::");			else				result.append("::FFFF:");			const UInt8* bytes = reinterpret_cast<const UInt8*>(&_addr);			result.append(NumberFormatter::format(bytes[12]));			result.append(".");			result.append(NumberFormatter::format(bytes[13]));			result.append(".");			result.append(NumberFormatter::format(bytes[14]));			result.append(".");			result.append(NumberFormatter::format(bytes[15]));			return result;		}		else		{			std::string result;			result.reserve(46);			bool zeroSequence = false;			int i = 0;			while (i < 8)			{				if (!zeroSequence && words[i] == 0)				{					int zi = i;					while (zi < 8 && words[zi] == 0) ++zi;					if (zi > i + 1)					{						i = zi;						result.append(":");						zeroSequence = true;					}				}				if (i > 0) result.append(":");				if (i < 8) result.append(NumberFormatter::formatHex(words[i++]));			}			return result;		}	}		poco_socklen_t length() const	{		return sizeof(_addr);	}	const void* addr() const	{		return &_addr;	}	IPAddress::Family family() const	{		return IPAddress::IPv6;	}	int af() const	{		return AF_INET6;	}	bool isWildcard() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && 		       words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 0;	}		bool isBroadcast() const	{		return false;	}		bool isLoopback() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && 		       words[4] == 0 && words[5] == 0 && words[6] == 0 && words[7] == 1;	}		bool isMulticast() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFE0) == 0xFF00;	}			bool isLinkLocal() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFE0) == 0xFE80;	}		bool isSiteLocal() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFE0) == 0xFEC0;	}		bool isIPv4Compatible() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0;	}	bool isIPv4Mapped() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 && words[4] == 0 && words[5] == 0xFFFF;	}	bool isWellKnownMC() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFF0) == 0xFF00;	}		bool isNodeLocalMC() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFEF) == 0xFF01;	}		bool isLinkLocalMC() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFEF) == 0xFF02;	}		bool isSiteLocalMC() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFEF) == 0xFF05;	}		bool isOrgLocalMC() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFEF) == 0xFF08;	}		bool isGlobalMC() const	{		const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);		return (words[0] & 0xFFEF) == 0xFF0F;	}	static IPv6AddressImpl* parse(const std::string& addr)	{		if (addr.empty()) return 0;#if defined(_WIN32)		struct addrinfo* pAI;		struct addrinfo hints;		memset(&hints, 0, sizeof(hints));		hints.ai_flags = AI_NUMERICHOST;		int rc = getaddrinfo(addr.c_str(), NULL, &hints, &pAI);		if (rc == 0)		{			IPv6AddressImpl* pResult = new IPv6AddressImpl(&reinterpret_cast<struct sockaddr_in6*>(pAI->ai_addr)->sin6_addr);			freeaddrinfo(pAI);			return pResult;		}		else return 0;#else		struct in6_addr ia;		if (inet_pton(AF_INET6, addr.c_str(), &ia) == 1)			return new IPv6AddressImpl(&ia);		else			return 0;#endif	}private:	struct in6_addr _addr;	};#endif // POCO_HAVE_IPv6//// IPAddress//IPAddress::IPAddress(): _pImpl(new IPv4AddressImpl){}IPAddress::IPAddress(const IPAddress& addr): _pImpl(addr._pImpl){	_pImpl->duplicate();}IPAddress::IPAddress(Family family): _pImpl(0){	if (family == IPv4)		_pImpl = new IPv4AddressImpl();#if defined(POCO_HAVE_IPv6)	else if (family == IPv6)		_pImpl = new IPv6AddressImpl();#endif	else Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");}IPAddress::IPAddress(const std::string& addr){	_pImpl = IPv4AddressImpl::parse(addr);#if defined(POCO_HAVE_IPv6)	if (!_pImpl)		_pImpl = IPv6AddressImpl::parse(addr);#endif	if (!_pImpl) throw InvalidAddressException(addr);}IPAddress::IPAddress(const std::string& addr, Family family): _pImpl(0){	if (family == IPv4)		_pImpl = IPv4AddressImpl::parse(addr);#if defined(POCO_HAVE_IPv6)	else if (family == IPv6)		_pImpl = IPv6AddressImpl::parse(addr);#endif	else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");}IPAddress::IPAddress(const void* addr, poco_socklen_t length){	if (length == sizeof(struct in_addr))		_pImpl = new IPv4AddressImpl(addr);#if defined(POCO_HAVE_IPv6)	else if (length == sizeof(struct in6_addr))		_pImpl = new IPv6AddressImpl(addr);#endif	else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");}IPAddress::~IPAddress(){	_pImpl->release();}IPAddress& IPAddress::operator = (const IPAddress& addr){	if (&addr != this)	{		_pImpl->release();		_pImpl = addr._pImpl;		_pImpl->duplicate();	}	return *this;}void IPAddress::swap(IPAddress& address){	std::swap(_pImpl, address._pImpl);}	IPAddress::Family IPAddress::family() const{	return _pImpl->family();}	std::string IPAddress::toString() const{	return _pImpl->toString();}bool IPAddress::isWildcard() const{	return _pImpl->isWildcard();}	bool IPAddress::isBroadcast() const{	return _pImpl->isBroadcast();}bool IPAddress::isLoopback() const{	return _pImpl->isLoopback();}bool IPAddress::isMulticast() const{	return _pImpl->isMulticast();}	bool IPAddress::isUnicast() const{	return !isWildcard() && !isBroadcast() && !isMulticast();}	bool IPAddress::isLinkLocal() const{	return _pImpl->isLinkLocal();}bool IPAddress::isSiteLocal() const{	return _pImpl->isSiteLocal();}bool IPAddress::isIPv4Compatible() const{	return _pImpl->isIPv4Compatible();}bool IPAddress::isIPv4Mapped() const{	return _pImpl->isIPv4Mapped();}bool IPAddress::isWellKnownMC() const{	return _pImpl->isWellKnownMC();}bool IPAddress::isNodeLocalMC() const{	return _pImpl->isNodeLocalMC();}bool IPAddress::isLinkLocalMC() const{	return _pImpl->isLinkLocalMC();}bool IPAddress::isSiteLocalMC() const{	return _pImpl->isSiteLocalMC();}bool IPAddress::isOrgLocalMC() const{	return _pImpl->isOrgLocalMC();}bool IPAddress::isGlobalMC() const{	return _pImpl->isGlobalMC();}bool IPAddress::operator == (const IPAddress& a) const{	poco_socklen_t l1 = length();	poco_socklen_t l2 = a.length();	if (l1 == l2)		return memcmp(addr(), a.addr(), l1) == 0;	else		return false;}bool IPAddress::operator != (const IPAddress& a) const{	poco_socklen_t l1 = length();	poco_socklen_t l2 = a.length();	if (l1 == l2)		return memcmp(addr(), a.addr(), l1) != 0;	else		return true;}bool IPAddress::operator < (const IPAddress& a) const{	poco_socklen_t l1 = length();	poco_socklen_t l2 = a.length();	if (l1 == l2)		return memcmp(addr(), a.addr(), l1) < 0;	else		return l1 < l2;}bool IPAddress::operator <= (const IPAddress& a) const{	poco_socklen_t l1 = length();	poco_socklen_t l2 = a.length();	if (l1 == l2)		return memcmp(addr(), a.addr(), l1) <= 0;	else		return l1 < l2;}bool IPAddress::operator > (const IPAddress& a) const{	poco_socklen_t l1 = length();	poco_socklen_t l2 = a.length();	if (l1 == l2)		return memcmp(addr(), a.addr(), l1) > 0;	else		return l1 > l2;}bool IPAddress::operator >= (const IPAddress& a) const{	poco_socklen_t l1 = length();	poco_socklen_t l2 = a.length();	if (l1 == l2)		return memcmp(addr(), a.addr(), l1) >= 0;	else		return l1 > l2;}poco_socklen_t IPAddress::length() const{	return _pImpl->length();}	const void* IPAddress::addr() const{	return _pImpl->addr();}int IPAddress::af() const{	return _pImpl->af();}void IPAddress::init(IPAddressImpl* pImpl){	_pImpl->release();	_pImpl = pImpl;}IPAddress IPAddress::parse(const std::string& addr){	return IPAddress(addr);}bool IPAddress::tryParse(const std::string& addr, IPAddress& result){	IPAddressImpl* pImpl = IPv4AddressImpl::parse(addr);#if defined(POCO_HAVE_IPv6)	if (!pImpl) pImpl = IPv6AddressImpl::parse(addr);#endif	if (pImpl)	{		result.init(pImpl);		return true;	}	else return false;}} } // namespace Poco::Net

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -