|
|
|
|
@ -22,14 +22,19 @@
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include "cip.h"
|
|
|
|
|
|
|
|
|
|
CIp::CIp()
|
|
|
|
|
CIp::CIp() : is_set(false)
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CIp::CIp(const char *address, int family, int type, uint16_t port)
|
|
|
|
|
CIp::CIp(const char *address, int family, int type, uint16_t port) : is_set(true)
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
if (0 == strncasecmp(address, "none", 4))
|
|
|
|
|
{
|
|
|
|
|
is_set = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
struct addrinfo hints, *result;
|
|
|
|
|
bzero(&hints, sizeof(struct addrinfo));
|
|
|
|
|
hints.ai_family = family;
|
|
|
|
|
@ -41,7 +46,7 @@ CIp::CIp(const char *address, int family, int type, uint16_t port)
|
|
|
|
|
}
|
|
|
|
|
SetPort(port);
|
|
|
|
|
}
|
|
|
|
|
CIp::CIp(const int family, const uint16_t port, const char *address)
|
|
|
|
|
CIp::CIp(const int family, const uint16_t port, const char *address) : is_set(true)
|
|
|
|
|
{
|
|
|
|
|
Initialize(family, port, address);
|
|
|
|
|
}
|
|
|
|
|
@ -49,50 +54,68 @@ CIp::CIp(const int family, const uint16_t port, const char *address)
|
|
|
|
|
void CIp::Initialize(const int family, const uint16_t port, const char *address)
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
if (0 == strncasecmp(address, "none", 4))
|
|
|
|
|
{
|
|
|
|
|
is_set = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
is_set = true;
|
|
|
|
|
addr.ss_family = family;
|
|
|
|
|
if (AF_INET == family) {
|
|
|
|
|
if (AF_INET == family)
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
addr4->sin_port = htons(port);
|
|
|
|
|
if (address) {
|
|
|
|
|
if (address)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strncasecmp(address, "loc", 3))
|
|
|
|
|
inet_pton(AF_INET, "127.0.0.1", &(addr4->sin_addr));
|
|
|
|
|
else if (0 == strncasecmp(address, "any", 3))
|
|
|
|
|
inet_pton(AF_INET, "0.0.0.0", &(addr4->sin_addr));
|
|
|
|
|
else if (0 == strncasecmp(address, "none", 4))
|
|
|
|
|
addr.ss_family = AF_UNSPEC;
|
|
|
|
|
else {
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (1 > inet_pton(AF_INET, address, &(addr4->sin_addr)))
|
|
|
|
|
std::cerr << "Address Initialization Error: '" << address << "' is not a valdid IPV4 address!" << std::endl;
|
|
|
|
|
is_set = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (AF_INET6 == family) {
|
|
|
|
|
else if (AF_INET6 == family)
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
addr6->sin6_port = htons(port);
|
|
|
|
|
if (address) {
|
|
|
|
|
if (address)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strncasecmp(address, "loc", 3))
|
|
|
|
|
inet_pton(AF_INET6, "::1", &(addr6->sin6_addr));
|
|
|
|
|
else if (0 == strncasecmp(address, "any", 3))
|
|
|
|
|
inet_pton(AF_INET6, "::", &(addr6->sin6_addr));
|
|
|
|
|
else if (0 == strncasecmp(address, "none", 4))
|
|
|
|
|
addr.ss_family = AF_UNSPEC;
|
|
|
|
|
else {
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (1 > inet_pton(AF_INET6, address, &(addr6->sin6_addr)))
|
|
|
|
|
std::cerr << "Address Initialization Error: '" << address << "' is not a valid IPV6 address!" << std::endl;
|
|
|
|
|
is_set = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Error: Wrong address family type:" << family << " for [" << (address ? address : "NULL") << "]:" << port << std::endl;
|
|
|
|
|
is_set = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CIp::operator==(const CIp &rhs) const // doesn't compare ports, only addresses and families
|
|
|
|
|
{
|
|
|
|
|
if (addr.ss_family != rhs.addr.ss_family)
|
|
|
|
|
return false;
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto l = (struct sockaddr_in *)&addr;
|
|
|
|
|
auto r = (struct sockaddr_in *)&rhs.addr;
|
|
|
|
|
return (l->sin_addr.s_addr == r->sin_addr.s_addr);
|
|
|
|
|
} else if (AF_INET6 == addr.ss_family) {
|
|
|
|
|
}
|
|
|
|
|
else if (AF_INET6 == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto l = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
auto r = (struct sockaddr_in6 *)&rhs.addr;
|
|
|
|
|
return (0 == memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_addr)));
|
|
|
|
|
@ -104,11 +127,14 @@ bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addres
|
|
|
|
|
{
|
|
|
|
|
if (addr.ss_family != rhs.addr.ss_family)
|
|
|
|
|
return true;
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto l = (struct sockaddr_in *)&addr;
|
|
|
|
|
auto r = (struct sockaddr_in *)&rhs.addr;
|
|
|
|
|
return (l->sin_addr.s_addr != r->sin_addr.s_addr);
|
|
|
|
|
} else if (AF_INET6 == addr.ss_family) {
|
|
|
|
|
}
|
|
|
|
|
else if (AF_INET6 == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto l = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
auto r = (struct sockaddr_in6 *)&rhs.addr;
|
|
|
|
|
return (0 != memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_addr)));
|
|
|
|
|
@ -118,12 +144,16 @@ bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addres
|
|
|
|
|
|
|
|
|
|
bool CIp::AddressIsZero() const
|
|
|
|
|
{
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
return (addr4->sin_addr.s_addr == 0U);
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
for (unsigned int i=0; i<16; i++) {
|
|
|
|
|
for (unsigned int i=0; i<16; i++)
|
|
|
|
|
{
|
|
|
|
|
if (addr6->sin6_addr.s6_addr[i])
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@ -133,11 +163,14 @@ bool CIp::AddressIsZero() const
|
|
|
|
|
|
|
|
|
|
void CIp::ClearAddress()
|
|
|
|
|
{
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
addr4->sin_addr.s_addr = 0U;
|
|
|
|
|
strcpy(straddr, "0.0.0.0");
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
memset(&(addr6->sin6_addr.s6_addr), 0, 16);
|
|
|
|
|
strcpy(straddr, "::");
|
|
|
|
|
@ -149,13 +182,18 @@ const char *CIp::GetAddress() const
|
|
|
|
|
if (straddr[0])
|
|
|
|
|
return straddr;
|
|
|
|
|
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
inet_ntop(AF_INET, &(addr4->sin_addr), straddr, INET6_ADDRSTRLEN);
|
|
|
|
|
} else if (AF_INET6 == addr.ss_family) {
|
|
|
|
|
}
|
|
|
|
|
else if (AF_INET6 == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, INET6_ADDRSTRLEN);
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "CIp::GetAddress: unknown socket family=" << addr.ss_family << std::endl;
|
|
|
|
|
}
|
|
|
|
|
return straddr;
|
|
|
|
|
@ -176,12 +214,15 @@ std::ostream &operator<<(std::ostream &stream, const CIp &Ip)
|
|
|
|
|
|
|
|
|
|
uint32_t CIp::GetAddr() const
|
|
|
|
|
{
|
|
|
|
|
if (AF_INET6 == addr.ss_family) {
|
|
|
|
|
if (AF_INET6 == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
// hash the results
|
|
|
|
|
auto *a = (const uint32_t *)&(addr6->sin6_addr.s6_addr);
|
|
|
|
|
return a[0] ^ a[1] ^ a[2] ^ a[3];
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
return addr4->sin_addr.s_addr;
|
|
|
|
|
}
|
|
|
|
|
@ -194,10 +235,13 @@ int CIp::GetFamily() const
|
|
|
|
|
|
|
|
|
|
uint16_t CIp::GetPort() const
|
|
|
|
|
{
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
return ntohs(addr4->sin_port);
|
|
|
|
|
} else if (AF_INET6 == addr.ss_family) {
|
|
|
|
|
}
|
|
|
|
|
else if (AF_INET6 == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
return ntohs(addr6->sin6_port);
|
|
|
|
|
} else
|
|
|
|
|
@ -206,10 +250,13 @@ uint16_t CIp::GetPort() const
|
|
|
|
|
|
|
|
|
|
void CIp::SetPort(const uint16_t newport)
|
|
|
|
|
{
|
|
|
|
|
if (AF_INET == addr.ss_family) {
|
|
|
|
|
if (AF_INET == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr4 = (struct sockaddr_in *)&addr;
|
|
|
|
|
addr4->sin_port = htons(newport);
|
|
|
|
|
} else if (AF_INET6 == addr.ss_family) {
|
|
|
|
|
}
|
|
|
|
|
else if (AF_INET6 == addr.ss_family)
|
|
|
|
|
{
|
|
|
|
|
auto addr6 = (struct sockaddr_in6 *)&addr;
|
|
|
|
|
addr6->sin6_port = htons(newport);
|
|
|
|
|
}
|
|
|
|
|
@ -238,4 +285,5 @@ void CIp::Clear()
|
|
|
|
|
{
|
|
|
|
|
memset(&addr, 0, sizeof(struct sockaddr_storage));
|
|
|
|
|
memset(straddr, 0, INET6_ADDRSTRLEN);
|
|
|
|
|
is_set = false;
|
|
|
|
|
}
|
|
|
|
|
|