mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-23 16:48:06 +02:00
Net: near complete merge to 1.4.2
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
// Package: NetCore
|
||||
// Module: IPAddress
|
||||
//
|
||||
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
|
||||
// Copyright (c) 2005-2011, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
@@ -64,12 +64,13 @@ 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 const void* addr() const = 0;
|
||||
virtual IPAddress::Family family() const = 0;
|
||||
virtual int af() const = 0;
|
||||
virtual Poco::UInt32 scope() 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;
|
||||
@@ -85,13 +86,19 @@ public:
|
||||
virtual IPAddressImpl* clone() const = 0;
|
||||
|
||||
protected:
|
||||
IPAddressImpl()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~IPAddressImpl()
|
||||
{
|
||||
}
|
||||
IPAddressImpl()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
Poco::Net::initializeNetwork();
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~IPAddressImpl()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
Poco::Net::uninitializeNetwork();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
IPAddressImpl(const IPAddressImpl&);
|
||||
@@ -144,12 +151,17 @@ public:
|
||||
|
||||
int af() const
|
||||
{
|
||||
return AF_INET;
|
||||
}
|
||||
|
||||
bool isWildcard() const
|
||||
{
|
||||
return _addr.s_addr == INADDR_ANY;
|
||||
return AF_INET;
|
||||
}
|
||||
|
||||
Poco::UInt32 scope() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isWildcard() const
|
||||
{
|
||||
return _addr.s_addr == INADDR_ANY;
|
||||
}
|
||||
|
||||
bool isBroadcast() const
|
||||
@@ -159,7 +171,7 @@ public:
|
||||
|
||||
bool isLoopback() const
|
||||
{
|
||||
return ntohl(_addr.s_addr) == 0x7F000001; // 127.0.0.1
|
||||
return (ntohl(_addr.s_addr) & 0xFF000000) == 0x7F000000; // 127.0.0.1 to 127.255.255.255
|
||||
}
|
||||
|
||||
bool isMulticast() const
|
||||
@@ -232,9 +244,9 @@ public:
|
||||
else
|
||||
return new IPv4AddressImpl(&ia);
|
||||
#else
|
||||
#if __GNUC__ < 3
|
||||
#if __GNUC__ < 3 || defined(POCO_VXWORKS)
|
||||
struct in_addr ia;
|
||||
ia.s_addr = inet_addr(addr.c_str());
|
||||
ia.s_addr = inet_addr(const_cast<char*>(addr.c_str()));
|
||||
if (ia.s_addr == INADDR_NONE && addr != "255.255.255.255")
|
||||
return 0;
|
||||
else
|
||||
@@ -273,15 +285,23 @@ private:
|
||||
class IPv6AddressImpl: public IPAddressImpl
|
||||
{
|
||||
public:
|
||||
IPv6AddressImpl()
|
||||
{
|
||||
std::memset(&_addr, 0, sizeof(_addr));
|
||||
}
|
||||
IPv6AddressImpl():
|
||||
_scope(0)
|
||||
{
|
||||
std::memset(&_addr, 0, sizeof(_addr));
|
||||
}
|
||||
|
||||
IPv6AddressImpl(const void* addr)
|
||||
{
|
||||
std::memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
IPv6AddressImpl(const void* addr):
|
||||
_scope(0)
|
||||
{
|
||||
std::memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
|
||||
IPv6AddressImpl(const void* addr, Poco::UInt32 scope):
|
||||
_scope(scope)
|
||||
{
|
||||
std::memcpy(&_addr, addr, sizeof(_addr));
|
||||
}
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
@@ -304,13 +324,13 @@ public:
|
||||
NumberFormatter::append(result, bytes[15]);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(46);
|
||||
bool zeroSequence = false;
|
||||
int i = 0;
|
||||
while (i < 8)
|
||||
else
|
||||
{
|
||||
std::string result;
|
||||
result.reserve(64);
|
||||
bool zeroSequence = false;
|
||||
int i = 0;
|
||||
while (i < 8)
|
||||
{
|
||||
if (!zeroSequence && words[i] == 0)
|
||||
{
|
||||
@@ -323,12 +343,29 @@ public:
|
||||
zeroSequence = true;
|
||||
}
|
||||
}
|
||||
if (i > 0) result.append(":");
|
||||
if (i < 8) NumberFormatter::appendHex(result, ntohs(words[i++]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (i > 0) result.append(":");
|
||||
if (i < 8) NumberFormatter::appendHex(result, ntohs(words[i++]));
|
||||
}
|
||||
if (_scope > 0)
|
||||
{
|
||||
result.append("%");
|
||||
#if defined(_WIN32)
|
||||
NumberFormatter::append(result, _scope);
|
||||
#else
|
||||
char buffer[IFNAMSIZ];
|
||||
if (if_indextoname(_scope, buffer))
|
||||
{
|
||||
result.append(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
NumberFormatter::append(result, _scope);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
poco_socklen_t length() const
|
||||
{
|
||||
@@ -347,12 +384,17 @@ public:
|
||||
|
||||
int af() const
|
||||
{
|
||||
return AF_INET6;
|
||||
}
|
||||
return AF_INET6;
|
||||
}
|
||||
|
||||
Poco::UInt32 scope() const
|
||||
{
|
||||
return _scope;
|
||||
}
|
||||
|
||||
bool isWildcard() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
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;
|
||||
}
|
||||
@@ -363,79 +405,79 @@ public:
|
||||
}
|
||||
|
||||
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 && words[6] == 0 && ntohs(words[7]) == 0x0001;
|
||||
}
|
||||
|
||||
bool isMulticast() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFE0) == 0xFF00;
|
||||
}
|
||||
|
||||
bool isLinkLocal() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFE0) == 0xFE80;
|
||||
}
|
||||
|
||||
bool isSiteLocal() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(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 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 && ntohs(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;
|
||||
}
|
||||
bool isWellKnownMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFF0) == 0xFF00;
|
||||
}
|
||||
|
||||
bool isNodeLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFEF) == 0xFF01;
|
||||
}
|
||||
|
||||
bool isLinkLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFEF) == 0xFF02;
|
||||
}
|
||||
|
||||
bool isSiteLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFEF) == 0xFF05;
|
||||
}
|
||||
|
||||
bool isOrgLocalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFEF) == 0xFF08;
|
||||
}
|
||||
|
||||
bool isGlobalMC() const
|
||||
{
|
||||
const UInt16* words = reinterpret_cast<const UInt16*>(&_addr);
|
||||
return (ntohs(words[0]) & 0xFFEF) == 0xFF0F;
|
||||
}
|
||||
|
||||
static IPv6AddressImpl* parse(const std::string& addr)
|
||||
static IPv6AddressImpl* parse(const std::string& addr)
|
||||
{
|
||||
if (addr.empty()) return 0;
|
||||
#if defined(_WIN32)
|
||||
@@ -443,20 +485,37 @@ public:
|
||||
struct addrinfo hints;
|
||||
std::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;
|
||||
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, static_cast<int>(reinterpret_cast<struct sockaddr_in6*>(pAI->ai_addr)->sin6_scope_id));
|
||||
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);
|
||||
struct in6_addr ia;
|
||||
std::string::size_type pos = addr.find('%');
|
||||
if (std::string::npos != pos)
|
||||
{
|
||||
std::string::size_type start = ('[' == addr[0]) ? 1 : 0;
|
||||
std::string unscopedAddr(addr, start, pos - start);
|
||||
std::string scope(addr, pos + 1, addr.size() - start - pos);
|
||||
Poco::UInt32 scopeId(0);
|
||||
if (!(scopeId = if_nametoindex(scope.c_str())))
|
||||
return 0;
|
||||
if (inet_pton(AF_INET6, unscopedAddr.c_str(), &ia) == 1)
|
||||
return new IPv6AddressImpl(&ia, scopeId);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
{
|
||||
if (inet_pton(AF_INET6, addr.c_str(), &ia) == 1)
|
||||
return new IPv6AddressImpl(&ia);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -465,13 +524,14 @@ public:
|
||||
throw Poco::NotImplementedException("mask() is only supported for IPv4 addresses");
|
||||
}
|
||||
|
||||
IPAddressImpl* clone() const
|
||||
{
|
||||
return new IPv6AddressImpl(&_addr);
|
||||
}
|
||||
IPAddressImpl* clone() const
|
||||
{
|
||||
return new IPv6AddressImpl(&_addr, _scope);
|
||||
}
|
||||
|
||||
private:
|
||||
struct in6_addr _addr;
|
||||
struct in6_addr _addr;
|
||||
Poco::UInt32 _scope;
|
||||
};
|
||||
|
||||
|
||||
@@ -543,9 +603,21 @@ IPAddress::IPAddress(const void* addr, poco_socklen_t length)
|
||||
}
|
||||
|
||||
|
||||
IPAddress::IPAddress(const void* addr, poco_socklen_t length, Poco::UInt32 scope)
|
||||
{
|
||||
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, scope);
|
||||
#endif
|
||||
else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
|
||||
}
|
||||
|
||||
|
||||
IPAddress::~IPAddress()
|
||||
{
|
||||
_pImpl->release();
|
||||
_pImpl->release();
|
||||
}
|
||||
|
||||
|
||||
@@ -572,10 +644,16 @@ IPAddress::Family IPAddress::family() const
|
||||
return _pImpl->family();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Poco::UInt32 IPAddress::scope() const
|
||||
{
|
||||
return _pImpl->scope();
|
||||
}
|
||||
|
||||
|
||||
std::string IPAddress::toString() const
|
||||
{
|
||||
return _pImpl->toString();
|
||||
return _pImpl->toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -799,4 +877,18 @@ void IPAddress::mask(const IPAddress& mask, const IPAddress& set)
|
||||
}
|
||||
|
||||
|
||||
IPAddress IPAddress::wildcard(Family family)
|
||||
{
|
||||
return IPAddress(family);
|
||||
}
|
||||
|
||||
|
||||
IPAddress IPAddress::broadcast()
|
||||
{
|
||||
struct in_addr ia;
|
||||
ia.s_addr = INADDR_NONE;
|
||||
return IPAddress(&ia, sizeof(ia));
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Net
|
||||
|
Reference in New Issue
Block a user