40#include <ucommon-config.h>
51#include <sys/socket.h>
52#include <netinet/in.h>
56#if defined(_MSWINDOWS_) && !defined(__BIG_ENDIAN)
57#define __LITTLE_ENDIAN 1234
58#define __BIG_ENDIAN 4321
59#define __PDP_ENDIAN 3412
60#define __BYTE_ORDER __LITTLE_ENDIAN
66#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN
90 if ( (address.s_addr != INADDR_ANY) &&
92 throw "Multicast address not in the valid range: from 224.0.0.1 through 239.255.255.255";
98validator(_validator), ipaddr(NULL), addr_count(0), hostname(NULL)
100 *
this = (in_addr_t)INADDR_ANY;
104validator(_validator), ipaddr(NULL), addr_count(0), hostname(NULL)
106 if(address == 0 || !strcmp(address,
"*"))
113validator(_validator), ipaddr(NULL), hostname(NULL)
119 ipaddr =
new struct in_addr[1];
124validator(rhs.validator), addr_count(rhs.addr_count), hostname(NULL)
149 return (i < addr_count ? ipaddr[i] : ipaddr[0]);
163 if(
str == 0 || !strcmp(
str,
"*"))
178 ipaddr =
new struct in_addr[1];
196 (*validator)(aptr.in4);
202 ipaddr =
new struct in_addr[1];
203 memcpy(
ipaddr, &aptr.in4,
sizeof(
struct in_addr));
212 if(
this == &rhs)
return *
this;
246 memcmp((
char *)&smaller->
ipaddr[s], (
char *)&larger->
ipaddr[l],
sizeof(
struct in_addr)); l++);
255 return (*
this == a ?
false :
true);
262 uint8_t *a = (uint8_t *)&
ipaddr[i];
263 uint8_t *m = (uint8_t *)&mask;
265 for(
size_t j = 0; j <
sizeof(
struct in_addr); ++j)
285 gethostname(namebuf, 256);
298#if defined(_MSWINDOWS_)
299 struct sockaddr_in
addr;
300 addr.sin_addr.s_addr = inet_addr(host);
302 (*validator)(
addr.sin_addr);
303 if(
addr.sin_addr.s_addr == INADDR_NONE)
305 *
this =
addr.sin_addr.s_addr;
307 struct in_addr l_addr;
309 int ok = inet_aton(host, &l_addr);
311 (*validator)(l_addr);
327 *
this = (in_addr_t)htonl(INADDR_ANY);
332 if(!
stricmp(host,
"localhost")) {
333 *
this = (
long unsigned int)inet_addr(
"127.0.0.1");
340 struct in_addr **bptr;
341#if defined(__GLIBC__)
346 if(gethostbyname_r(host, &hb, hbuf,
sizeof(hbuf), &hp, &rtn))
353 hp = gethostbyname_r(host, &hb, hbuf,
sizeof(hbuf), &rtn);
354#elif (defined(__osf__) || defined(_MSWINDOWS_))
355 hp = gethostbyname(host);
358 hp = gethostbyname(host);
364 ipaddr =
new struct in_addr[1];
365 memset(
ipaddr, 0,
sizeof(
struct in_addr));
371 for(bptr = (
struct in_addr **)hp->h_addr_list; *bptr != NULL; bptr++) {
382 bptr = (
struct in_addr **)hp->h_addr_list;
383 for(
unsigned int i = 0; i <
addr_count; i++) {
385 (*validator)(*bptr[i]);
398 unsigned long x = 0xffffffff;
399 int l = 32 - atoi(mask);
404 if(l < 1 || l > 32) {
405#ifdef CCXX_EXCEPTIONS
412 *
this = htonl(x << l);
417 struct hostent *hp = NULL;
418 struct in_addr addr0;
420 memset(&addr0, 0,
sizeof(addr0));
421 if(!memcmp(&addr0, &
ipaddr[0],
sizeof(addr0)))
425 memset(&addr0, 0xff,
sizeof(addr0));
426 if(!memcmp(&addr0, &
ipaddr[0],
sizeof(addr0)))
427 return "255.255.255.255";
428 long a = inet_addr(
"127.0.0.1");
429 if(!memcmp(&a, &
ipaddr[0],
sizeof(a)))
433#if defined(__GLIBC__)
437 if(gethostbyaddr_r((
char *)&
ipaddr[0],
sizeof(addr0), AF_INET, &hb, hbuf,
sizeof(hbuf), &hp, &rtn))
443 hp = gethostbyaddr_r((
char *)&
ipaddr[0], (
int)
sizeof(addr0), (
int)AF_INET, &hb, hbuf, (
int)
sizeof(hbuf), &rtn);
444#elif defined(__osf__) || defined(_MSWINDOWS_)
445 hp = gethostbyaddr((
char *)&
ipaddr[0],
sizeof(addr0), AF_INET);
448 hp = gethostbyaddr((
char *)&
ipaddr[0],
sizeof(addr0), AF_INET);
457 return inet_ntoa(
ipaddr[0]);
483Mutex IPV6Address::mutex;
486const IPV6MulticastValidator IPV6Multicast::validator;
488void IPV6MulticastValidator::operator()(
const in6_addr address)
const
490#ifdef CCXX_EXCEPTIONS
492 if ( (address.s6_addr[0] != 0 || address.s6_addr[1] != 0) &&
493 (address.s6_addr[0] != 0xff || address.s6_addr[1] < 0x1f)) {
494 throw "Multicast address not in the valid prefix ff00-ff1f:";
499IPV6Address::IPV6Address(
const IPV6Validator *_validator) :
500validator(_validator), hostname(NULL)
503 ipaddr =
new struct in6_addr[1];
504 memcpy(
ipaddr, &in6addr_any,
sizeof(
struct in6_addr));
507IPV6Address::IPV6Address(
const char *address,
const IPV6Validator *_validator) :
508validator(_validator), ipaddr(NULL), addr_count(0), hostname(NULL)
510 if(address == 0 || !strcmp(address,
"*"))
516IPV6Address::IPV6Address(
struct in6_addr
addr,
const IPV6Validator *_validator) :
517validator(_validator), ipaddr(NULL), hostname(NULL)
523 ipaddr =
new struct in6_addr[1];
524 memcpy(
ipaddr, &
addr,
sizeof(
struct in6_addr));
527IPV6Address::IPV6Address(
const IPV6Address &rhs) :
528 validator(rhs.validator), addr_count(rhs.addr_count), hostname(NULL) {
533IPV6Address::~IPV6Address()
545struct in6_addr IPV6Address::getAddress(void) const
550struct in6_addr IPV6Address::getAddress(size_t i) const
552 return (i < addr_count ? ipaddr[i] : ipaddr[0]);
555bool IPV6Address::isInetAddress(
void)
const
557 struct in6_addr
addr;
561 if(memcmp(&
addr, &ipaddr[0],
sizeof(
addr)))
566IPV6Address &IPV6Address::operator=(
const char *
str)
568 if(
str == 0 || !strcmp(
str,
"*"))
576IPV6Address &IPV6Address::operator=(
struct in6_addr
addr)
583 ipaddr =
new struct in6_addr[1];
591IPV6Address &IPV6Address::operator=(
const IPV6Address &rhs)
593 if(
this == &rhs)
return *
this;
595 addr_count = rhs.addr_count;
598 ipaddr =
new struct in6_addr[addr_count];
599 memcpy(ipaddr, rhs.ipaddr,
sizeof(
struct in6_addr) * addr_count);
600 validator = rhs.validator;
608bool IPV6Address::operator==(
const IPV6Address &a)
const
610 const IPV6Address *smaller, *larger;
613 if(addr_count > a.addr_count) {
624 for(s = 0; s < smaller->addr_count; s++) {
626 for(l = 0; l < larger->addr_count &&
627 memcmp((
char *)&smaller->ipaddr[s], (
char *)&larger->ipaddr[l],
sizeof(
struct in6_addr)); l++);
628 if(l == larger->addr_count)
return false;
633bool IPV6Address::operator!=(
const IPV6Address &a)
const
636 return (*
this == a ?
false :
true);
639IPV6Host &IPV6Host::operator&=(
const IPV6Mask &ma)
641 for(
size_t i = 0; i < addr_count; i++) {
642 struct in6_addr mask = ma.getAddress();
643 uint8_t *a = (uint8_t *)&ipaddr[i];
644 uint8_t *m = (uint8_t *)&mask;
646 for(
size_t j = 0; j <
sizeof(
struct in6_addr); ++j)
656IPV6Host::IPV6Host(
struct in6_addr
addr) :
659IPV6Host::IPV6Host(
const char *host) :
665 gethostname(namebuf, 256);
670bool IPV6Address::setIPAddress(
const char *host)
675 struct in6_addr l_addr;
678 struct sockaddr saddr;
679 int slen =
sizeof(saddr);
680 struct sockaddr_in6 *paddr = (
struct sockaddr_in6 *)&saddr;
681 int ok = WSAStringToAddress((LPSTR)host, AF_INET6, NULL, &saddr, &slen);
682 l_addr = paddr->sin6_addr;
684 int ok = inet_pton(AF_INET6, host, &l_addr);
687 (*validator)(l_addr);
694#if defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME2)
696void IPV6Address::setAddress(
const char *host)
706 if(!
stricmp(host,
"localhost"))
710 if(!setIPAddress(host)) {
711 struct addrinfo hint, *list = NULL, *first;
712 memset(&hint, 0,
sizeof(hint));
713 hint.ai_family = AF_INET6;
714 struct in6_addr *
addr;
715 struct sockaddr_in6 *ip6addr;
717 if(
getaddrinfo(host, NULL, &hint, &list) || !list) {
720 ipaddr =
new struct in6_addr[1];
721 memset((
void *)&ipaddr[0], 0,
sizeof(
struct in6_addr));
736 ipaddr =
new struct in6_addr[addr_count];
743 ip6addr = (
struct sockaddr_in6 *)list->
ai_addr;
744 addr = &ip6addr->sin6_addr;
756void IPV6Address::setAddress(
const char *host)
766 if(!
stricmp(host,
"localhost"))
770 if(!setIPAddress(host)) {
772 struct in6_addr **bptr;
773#if defined(__GLIBC__)
778 if(gethostbyname2_r(host, AF_INET6, &hb, hbuf,
sizeof(hbuf), &hp, &rtn))
785 hp = gethostbyname2_r(host, AF_INET6, &hb, hbuf,
sizeof(hbuf), &rtn);
786#elif (defined(__osf__) || defined(_OSF_SOURCE) || defined(__hpux))
787 hp = gethostbyname(host);
788#elif defined(_MSWINDOWS_) && (!defined(_MSC_VER) || _MSC_VER < 1300)
789 hp = gethostbyname(host);
790#elif defined(_MSWINDOWS_)
791 hp = gethostbyname2(host, AF_INET6);
794 hp = gethostbyname2(host, AF_INET6);
800 ipaddr =
new struct in6_addr[1];
801 memset((
void *)&ipaddr[0], 0,
sizeof(
struct in6_addr));
807 for(bptr = (
struct in6_addr **)hp->h_addr_list; *bptr != NULL; bptr++) {
814 ipaddr =
new struct in6_addr[addr_count];
818 bptr = (
struct in6_addr **)hp->h_addr_list;
819 for(
unsigned int i = 0; i < addr_count; i++) {
821 (*validator)(*bptr[i]);
822 ipaddr[i] = *bptr[i];
829IPV6Broadcast::IPV6Broadcast(
const char *net) :
834IPV6Mask::IPV6Mask(
const char *mask) :
839const char *IPV6Address::getHostname(
void)
const
841 struct hostent *hp = NULL;
842 struct in6_addr addr0;
843 static char strbuf[64];
845 memset(&addr0, 0,
sizeof(addr0));
846 if(!memcmp(&addr0, &ipaddr[0],
sizeof(addr0)))
849 if(!memcmp(&in6addr_loopback, &ipaddr[0],
sizeof(addr0)))
852#if defined(__GLIBC__)
856 if(gethostbyaddr_r((
char *)&ipaddr[0],
sizeof(addr0), AF_INET6, &hb, hbuf,
sizeof(hbuf), &hp, &rtn))
862 hp = gethostbyaddr_r((
char *)&ipaddr[0],
sizeof(addr0), AF_INET6, &hb, hbuf, (
int)
sizeof(hbuf), &rtn);
863#elif defined(__osf__) || defined(_MSWINDOWS_)
864 hp = gethostbyaddr((
char *)&ipaddr[0],
sizeof(addr0), AF_INET6);
867 hp = gethostbyaddr((
char *)&ipaddr[0],
sizeof(addr0), AF_INET6);
877 struct sockaddr saddr;
878 struct sockaddr_in6 *paddr = (
struct sockaddr_in6 *)&saddr;
879 DWORD slen =
sizeof(strbuf);
880 memset(&saddr, 0,
sizeof(saddr));
881 paddr->sin6_family = AF_INET6;
882 paddr->sin6_addr = ipaddr[0];
883 WSAAddressToString(&saddr,
sizeof(saddr), NULL, strbuf, &slen);
886 return inet_ntop(AF_INET6, &ipaddr[0], strbuf,
sizeof(strbuf));
891IPV6Host
operator&(
const IPV6Host &
addr,
const IPV6Mask &mask)
898IPV6Multicast::IPV6Multicast() :
899IPV6Address(&validator)
902IPV6Multicast::IPV6Multicast(
const char *address) :
903IPV6Address(address,&validator)
919 *(bits++) &= *(mask++);
925 *(bits++) |= ~(*(mask++));
933 mask = (
bit_t)(1 << 7);
934 while(mask && blen) {
949 mask = (
bit_t)(1<<7);
964 memset(&netmask, 0,
sizeof(netmask));
975 memcpy(&netmask, &
cidr.netmask,
sizeof(netmask));
980 struct in_addr host =
addr;
983 if(!memcmp(&host, &
network,
sizeof(host)))
991 struct sockaddr_in *
addr = (
struct sockaddr_in *)saddr;
994 if(saddr->sa_family != AF_INET)
997 memcpy(&host, &
addr->sin_addr.s_addr,
sizeof(host));
999 if(!memcmp(&host, &
network,
sizeof(host)))
1007 struct in_addr bcast;
1008 memcpy(&bcast, &network,
sizeof(network));
1015 unsigned dcount = 0;
1016 const char *gp = cp;
1017 const char *mp = strchr(cp,
'/');
1026 if(!strchr(++mp,
'.'))
1029 mask = inet_addr(mp);
1033 memset(dots, 0,
sizeof(dots));
1035 while(*gp && dcount < 3) {
1037 dots[++dcount] = atoi(gp);
1061 memset(&netmask, 0,
sizeof(netmask));
1065 ep = (
char *)strchr(cp,
'/');
1071 while(NULL != (cp = strchr(cp,
'.'))) {
1095 memset(&network, 0,
sizeof(network));
1096 memset(&netmask, 0,
sizeof(netmask));
1099IPV6Cidr::IPV6Cidr(
const char *cp)
1104IPV6Cidr::IPV6Cidr(IPV6Cidr &cidr)
1106 memcpy(&network, &cidr.network,
sizeof(network));
1107 memcpy(&netmask, &cidr.netmask,
sizeof(netmask));
1110bool IPV6Cidr::isMember(
const struct in6_addr &
addr)
const
1112 struct in6_addr host =
addr;
1115 if(!memcmp(&host, &network,
sizeof(host)))
1121bool IPV6Cidr::isMember(
const struct sockaddr *saddr)
const
1123 struct sockaddr_in6 *
addr = (
struct sockaddr_in6 *)saddr;
1124 struct in6_addr host;
1126 if(saddr->sa_family != AF_INET6)
1129 memcpy(&host, &
addr->sin6_addr,
sizeof(host));
1131 if(!memcmp(&host, &network,
sizeof(host)))
1137struct in6_addr IPV6Cidr::getBroadcast(void) const
1139 struct in6_addr bcast;
1140 memcpy(&bcast, &network,
sizeof(network));
1141 bitimask((bit_t *)&bcast, (bit_t *)&netmask,
sizeof(bcast));
1145unsigned IPV6Cidr::getMask(
const char *cp)
const
1147 unsigned count = 0, rcount = 0;
1148 const char *sp = strchr(cp,
'/');
1154 if(!strncmp(cp,
"ff00:", 5))
1157 if(!strncmp(cp,
"fe80:", 5))
1160 if(!strncmp(cp,
"2002:", 5))
1163 sp = strrchr(cp,
':');
1164 while(*(++sp) ==
'0')
1169 while(*cp && count < 128) {
1170 if(*(cp++) ==
':') {
1186void IPV6Cidr::set(
const char *cp)
1191 memset(&netmask, 0,
sizeof(netmask));
1194 ep = (
char *)strchr(cp,
'/');
1199 int slen =
sizeof(network);
1200 WSAStringToAddressA(
cbuf, AF_INET6, NULL, (
struct sockaddr*)&network, &slen);
1202 inet_pton(AF_INET6,
cbuf, &network);
Network addresses and sockets related classes.
#define INET_IPV6_ADDRESS_SIZE
#define INET_IPV4_ADDRESS_SIZE
The network name and address objects are all derived from a common IPV4Address base class.
IPV4Address(const IPV4Validator *validator=NULL)
Create an Internet Address object with an empty (0.0.0.0) address.
const IPV4Validator * validator
void setAddress(const char *host)
Used to specify a host name or numeric internet address.
const char * getHostname(void) const
Provide a string representation of the value (Internet Address) held in the IPV4Address object.
virtual ~IPV4Address()
Destructor.
bool operator!=(const IPV4Address &a) const
Compare two internet addresses to see if they are not equal (if they each refer to unique and differe...
bool isInetAddress(void) const
May be used to verify if a given IPV4Address returned by another function contains a "valid" address,...
bool setIPAddress(const char *host)
Sets the IP address from a string representation of the numeric address, ie "127.0....
bool operator==(const IPV4Address &a) const
Compare two internet addresses to see if they are equal (if they specify the physical address of the ...
struct in_addr getAddress(void) const
Provide a low level system usable struct in_addr object from the contents of IPV4Address.
IPV4Address & operator=(const char *str)
IPV4Broadcast(const char *net="255.255.255.255")
Specify the physical broadcast address to use and create a new broadcast address object based on a nu...
The CIDR class is used to support routing tables and validate address policies.
struct in_addr netmask network
void set(const char *cidr)
Set the cidr from a full or partial hostname, or from an address/mask, or a host/bits specification.
IPV4Cidr()
Construct an empty cidr.
bool isMember(const struct sockaddr *saddr) const
See if a socket address is a member of this cidr's network.
unsigned getMask(const char *cp) const
This object is used to hold the actual and valid internet address of a specific host machine that wil...
IPV4Host & operator&=(const IPV4Mask &mask)
Mask the internet host address object with a network mask address.
IPV4Host(const char *host=NULL)
Create a new host address for a specific internet host.
Internet addresses used specifically as masking addresses (such as " 255.255.255.0") are held in the ...
IPV4Mask(const char *mask)
Create the mask from a null terminated ASCII string such as "255.255.255.128".
void operator()(const in_addr address) const __OVERRIDE
Application operator.
static const IPV4MulticastValidator validator
Check the address in addr is a valid multicast address.
IPV4Multicast()
Create an Internet Multicast Address object with an empty (0.0.0.0) address.
Classes derived from IPV4Address would require an specific validator to pass to the IPV4Address const...
static Throw getException(void)
Get exception mode of the current thread.
@ throwObject
throw object that cause error (throw this)
A class to hold internet segment routing rules.
Export interfaces for library interfaces.
Common C++ thread class and sychronization objects.
int stricmp(const char *s1, const char *s2)
static void bitimask(bit_t *bits, bit_t *mask, unsigned len)
static void bitmask(bit_t *bits, bit_t *mask, unsigned len)
char * addString(char *target, size_t size, const char *str)
struct in_addr getaddress(const IPV4Address &ia)
char * newString(const char *src, size_t size)
IPV4Host operator&(const IPV4Host &addr, const IPV4Mask &mask)
static void bitset(bit_t *bits, unsigned blen)
ostream & operator<<(ostream &os, const IPV4Address &ia)
void delString(char *str)
static unsigned bitcount(bit_t *bits, unsigned len)
char * setString(char *target, size_t size, const char *str)
static void freeaddrinfo(struct addrinfo *aip)
const struct sockaddr * addr(Socket::address &address)
A convenience function to convert a socket address list into a socket address.
static int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hintsp, struct addrinfo **res)
String str(Socket &so, size_t size)
struct sockaddr * ai_addr
struct addrinfo * ai_next