29#if !defined(IN6_ARE_ADDR_EQUAL) && _SQUID_WINDOWS_
30#define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL
35 if(!(b)){ printf("assert \"%s\" at line %d\n", a, __LINE__); \
36 printf("Ip::Address invalid? with isIPv4()=%c, isIPv6()=%c\n",(isIPv4()?'T':'F'),(isIPv6()?'T':'F')); \
38 for(unsigned int i = 0; i < sizeof(mSocketAddr_.sin6_addr); ++i) { \
39 printf(" %x", mSocketAddr_.sin6_addr.s6_addr[i]); \
40 } printf("\n"); assert(b); \
70 for (caught = 0, bit= 7 ; !caught && (bit <= 7); --bit) {
71 caught = ((ipbyte & 0x80) == 0x00);
89 uint32_t *p1 = (uint32_t*)(&mSocketAddr_.sin6_addr);
90 uint32_t
const *p2 = (uint32_t
const *)(&mask_addr.
mSocketAddr_.sin6_addr);
91 unsigned int blen =
sizeof(mSocketAddr_.sin6_addr)/
sizeof(uint32_t);
92 unsigned int changes = 0;
94 for (
unsigned int i = 0; i < blen; ++i) {
95 if ((p1[i] & p2[i]) != p1[i])
107 if (!isLocalhost() && isIPv4())
108 (void)applyMask(mask);
114 uint8_t clearbits = 0;
115 uint8_t* p =
nullptr;
121 if (cidrMask > 32 && mtype == AF_INET)
130 clearbits = (uint8_t)( (mtype==AF_INET6?128:32) - cidrMask);
136 p = (uint8_t*)(&mSocketAddr_.sin6_addr) + 15;
138 for (; clearbits>0 && p >= (uint8_t*)&mSocketAddr_.sin6_addr ; --p ) {
140 *p &= ((0xFF << clearbits) & 0xFF);
154 return (mSocketAddr_.sin6_port != 0);
160 return IN6_IS_ADDR_V4MAPPED( &mSocketAddr_.sin6_addr );
172 return IN6_IS_ADDR_UNSPECIFIED(&mSocketAddr_.sin6_addr) || IN6_ARE_ADDR_EQUAL(&mSocketAddr_.sin6_addr, &v4_anyaddr);
179 memset(&mSocketAddr_.sin6_addr, 0,
sizeof(
struct in6_addr) );
186 memset(&mSocketAddr_, 0,
sizeof(mSocketAddr_) );
193const struct in6_addr
Ip::
Address::v4_anyaddr = {{{ 0x00000000, 0x00000000, 0x0000ffff, 0x00000000 }}};
194const struct in6_addr
Ip::
Address::v4_noaddr = {{{ 0x00000000, 0x00000000, 0x0000ffff, 0xffffffff }}};
195const struct in6_addr
Ip::
Address::v6_noaddr = {{{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }}};
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
216 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
217 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
226 if ( isLocalhost() ) {
227 mSocketAddr_.sin6_addr = v4_localhost;
232 mSocketAddr_.sin6_addr = v4_anyaddr;
237 mSocketAddr_.sin6_addr = v4_noaddr;
251 return IN6_IS_ADDR_LOOPBACK( &mSocketAddr_.sin6_addr ) || IN6_ARE_ADDR_EQUAL( &mSocketAddr_.sin6_addr, &v4_localhost );
258 mSocketAddr_.sin6_addr = in6addr_loopback;
259 mSocketAddr_.sin6_family = AF_INET6;
261 mSocketAddr_.sin6_addr = v4_localhost;
262 mSocketAddr_.sin6_family = AF_INET;
272 return mSocketAddr_.sin6_addr.s6_addr[0] ==
static_cast<uint8_t
>(0xfd) ||
273 mSocketAddr_.sin6_addr.s6_addr[0] ==
static_cast<uint8_t
>(0xfc);
279 return mSocketAddr_.sin6_addr.s6_addr[11] ==
static_cast<uint8_t
>(0xff) &&
280 mSocketAddr_.sin6_addr.s6_addr[12] ==
static_cast<uint8_t
>(0xfe);
287 return IN6_ARE_ADDR_EQUAL( &mSocketAddr_.sin6_addr, &v6_noaddr )
288 || IN6_ARE_ADDR_EQUAL( &mSocketAddr_.sin6_addr, &v4_noaddr );
294 memset(&mSocketAddr_.sin6_addr, 0xFF,
sizeof(
struct in6_addr) );
295 mSocketAddr_.sin6_family = AF_INET6;
302 unsigned char const *r = dat.s6_addr;
314 for (
int i = 15; i >= 0; --i, p+=4) {
315 snprintf(p, 5,
"%x.%x.", ((r[i])&0xf), (((r[i])>>4)&0xf) );
320 snprintf(p,10,
"ip6.arpa.");
328 unsigned int i = (
unsigned int) ntohl(dat.s_addr);
329 snprintf(buf, 32,
"%u.%u.%u.%u.in-addr.arpa.",
341 if (show_type == AF_UNSPEC) {
342 show_type = isIPv6() ? AF_INET6 : AF_INET ;
345 if (show_type == AF_INET && isIPv4()) {
346 struct in_addr* tmp = (
struct in_addr*)&mSocketAddr_.sin6_addr.s6_addr[12];
347 return getReverseString4(buf, *tmp);
348 }
else if ( show_type == AF_INET6 && isIPv6() ) {
349 return getReverseString6(buf, mSocketAddr_.sin6_addr);
362 lookupHostIP(s,
true);
368 return lookupHostIP(s,
true);
374 return lookupHostIP(s,
false);
380 struct addrinfo want;
381 memset(&want, 0,
sizeof(
struct addrinfo));
383 want.ai_flags = AI_NUMERICHOST;
387 struct addrinfo *res =
nullptr;
388 if ( (err = getaddrinfo(s,
nullptr, &want, &res)) != 0) {
389 debugs(14,3,
"Given Non-IP '" << s <<
"': " << gai_strerror(err) );
396 struct addrinfo *resHead = res;
399 struct addrinfo *maybeIpv4 = res;
401 if (maybeIpv4->ai_family == AF_INET)
403 maybeIpv4 = maybeIpv4->ai_next;
405 if (maybeIpv4 !=
nullptr)
414 short portSaved =
port();
419 freeaddrinfo(resHead);
432 map4to6((
const in_addr)s.sin_addr, mSocketAddr_.sin6_addr);
433 mSocketAddr_.sin6_port = s.sin_port;
434 mSocketAddr_.sin6_family = AF_INET6;
442 if (s.ss_family == AF_INET6) {
443 memmove(&mSocketAddr_, &s,
sizeof(
struct sockaddr_in6));
445 struct sockaddr_in *sin = (
struct sockaddr_in*)&s;
446 mSocketAddr_.sin6_port = sin->sin_port;
447 map4to6( sin->sin_addr, mSocketAddr_.sin6_addr);
461 memmove(&mSocketAddr_, &s,
sizeof(
struct sockaddr_in6));
474 map4to6((
const in_addr)s, mSocketAddr_.sin6_addr);
475 mSocketAddr_.sin6_family = AF_INET6;
488 memmove(&mSocketAddr_.sin6_addr, &s,
sizeof(
struct in6_addr));
489 mSocketAddr_.sin6_family = AF_INET6;
504 struct in_addr* ipv4 =
nullptr;
506 struct in6_addr* ipv6 =
nullptr;
516 switch (s.h_addrtype) {
519 ipv4 = (in_addr*)(s.h_addr_list[0]);
525 ipv6 = (in6_addr*)(s.h_addr_list[0]);
548 struct sockaddr_in* ipv4 =
nullptr;
550 struct sockaddr_in6* ipv6 =
nullptr;
563 switch (s.ai_family) {
566 ipv4 = (sockaddr_in*)(s.ai_addr);
573 ipv6 = (sockaddr_in6*)(s.ai_addr);
583 if (s.ai_addr !=
nullptr) {
584 if (s.ai_addrlen ==
sizeof(
struct sockaddr_in6)) {
585 operator=(*((
struct sockaddr_in6*)s.ai_addr));
587 }
else if (s.ai_addrlen ==
sizeof(
struct sockaddr_in)) {
588 operator=(*((
struct sockaddr_in*)s.ai_addr));
601 if (dst ==
nullptr) {
605 memset(dst, 0,
sizeof(
struct addrinfo));
612 dst->ai_flags = AI_NUMERICHOST;
615 if (dst->ai_socktype == 0)
616 dst->ai_socktype = SOCK_STREAM;
618 if (dst->ai_socktype == SOCK_STREAM
619 && dst->ai_protocol == 0)
620 dst->ai_protocol = IPPROTO_TCP;
622 if (dst->ai_socktype == SOCK_DGRAM
623 && dst->ai_protocol == 0)
624 dst->ai_protocol = IPPROTO_UDP;
626 if (force == AF_INET6 || (force == AF_UNSPEC &&
Ip::EnableIpv6 && isIPv6()) ) {
627 dst->ai_addr = (
struct sockaddr*)
new sockaddr_in6;
629 memset(dst->ai_addr,0,
sizeof(
struct sockaddr_in6));
631 getSockAddr(*((
struct sockaddr_in6*)dst->ai_addr));
633 dst->ai_addrlen =
sizeof(
struct sockaddr_in6);
635 dst->ai_family = ((
struct sockaddr_in6*)dst->ai_addr)->sin6_family;
648 dst->ai_protocol = IPPROTO_IPV6;
651 }
else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
653 dst->ai_addr = (
struct sockaddr*)
new sockaddr_in;
655 memset(dst->ai_addr,0,
sizeof(
struct sockaddr_in));
657 getSockAddr(*((
struct sockaddr_in*)dst->ai_addr));
659 dst->ai_addrlen =
sizeof(
struct sockaddr_in);
661 dst->ai_family = ((
struct sockaddr_in*)dst->ai_addr)->sin_family;
672 memset(ai,0,
sizeof(
struct addrinfo));
676 if (ai->ai_addr)
delete ai->ai_addr;
678 ai->ai_addr = (
struct sockaddr*)
new sockaddr_in6;
679 memset(ai->ai_addr, 0,
sizeof(
struct sockaddr_in6));
681 ai->ai_addrlen =
sizeof(
struct sockaddr_in6);
688 if (ai ==
nullptr)
return;
690 if (ai->ai_addr)
delete ai->ai_addr;
692 ai->ai_addr =
nullptr;
705 uint8_t *l = (uint8_t*)mSocketAddr_.sin6_addr.s6_addr;
706 uint8_t *r = (uint8_t*)rhs.
mSocketAddr_.sin6_addr.s6_addr;
711 for (
unsigned int i = 0 ; i <
sizeof(mSocketAddr_.sin6_addr) ; ++i) {
726 return memcmp(
this, &rhs,
sizeof(*
this));
732 return (0 == matchIPAddr(s));
747 return (matchIPAddr(rhs) <= 0);
756 return ( matchIPAddr(rhs) >= 0);
765 return ( matchIPAddr(rhs) > 0);
774 return ( matchIPAddr(rhs) < 0);
780 return ntohs( mSocketAddr_.sin6_port );
786 mSocketAddr_.sin6_port = htons(prt);
795 if (buf ==
nullptr) {
803 memcpy(buf,
"::\0",
min(
static_cast<unsigned int>(3),blen));
805 memcpy(buf,
"0.0.0.0\0",
min(
static_cast<unsigned int>(8),blen));
813 if ( force == AF_INET && !isIPv4() ) {
815 memcpy(buf,
"{!IPv4}\0",
min(
static_cast<unsigned int>(8),blen));
820 if ( force == AF_INET6 || (force == AF_UNSPEC && isIPv6()) ) {
822 inet_ntop(AF_INET6, &mSocketAddr_.sin6_addr, buf, blen);
824 }
else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
828 inet_ntop(AF_INET, &tmp, buf, blen);
830 debugs(14,
DBG_CRITICAL,
"WARNING: Corrupt IP Address details OR required to display in unknown format (" <<
831 force <<
"). accepted={" << AF_UNSPEC <<
"," << AF_INET <<
"," << AF_INET6 <<
"}");
832 fprintf(stderr,
"WARNING: Corrupt IP Address details OR required to display in unknown format (%d). accepted={%d,%d,%d} ",
833 force, AF_UNSPEC, AF_INET, AF_INET6);
834 memcpy(buf,
"dead:beef::\0",
min(
static_cast<unsigned int>(13),blen));
846 if (isIPv6() && blen > 0) {
853 toStr(p, blen-8, AF_INET6);
855 toStr(p, blen-8, AF_INET);
858 while (*p !=
'\0' && p < buf+blen)
861 if (isIPv6() && p < (buf+blen-1) ) {
880 if (buf ==
nullptr) {
884 p += toHostStr(p, blen);
886 if (mSocketAddr_.sin6_port > 0 && p <= (buf+blen-7) ) {
888 snprintf(p, 7,
":%d",
port() );
906 return lookupHostIP(host,
true);
910 const char *start = host + 1;
917 tmp[strlen(tmp)-1] =
'\0';
918 const bool result = lookupHostIP(tmp,
true);
926 struct sockaddr_in *sin =
nullptr;
928 if ( family == AF_INET && !isIPv4()) {
930 debugs(14,
DBG_CRITICAL,
"ERROR: Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *
this);
934 if ( family == AF_INET6 || (family == AF_UNSPEC && isIPv6()) ) {
935 struct sockaddr_in6 *ss6 = (
struct sockaddr_in6*)&addr;
937 }
else if ( family == AF_INET || (family == AF_UNSPEC && isIPv4()) ) {
938 sin = (
struct sockaddr_in*)&addr;
949 buf.sin_family = AF_INET;
950 buf.sin_port = mSocketAddr_.sin6_port;
951 map6to4( mSocketAddr_.sin6_addr, buf.sin_addr);
953 debugs(14,
DBG_CRITICAL,
"ERROR: Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *
this );
955 memset(&buf,0xFFFFFFFF,
sizeof(
struct sockaddr_in));
959#if HAVE_SIN_LEN_IN_SAI
961 buf.sin_len =
sizeof(
struct sockaddr_in);
968 memmove(&buf, &mSocketAddr_,
sizeof(
struct sockaddr_in6));
970 buf.sin6_family = AF_INET6;
972#if HAVE_SIN6_LEN_IN_SAI
974 buf.sin6_len =
sizeof(
struct sockaddr_in6);
983 if ( in.s_addr == 0x00000000) {
986 }
else if ( in.s_addr == 0xFFFFFFFF) {
992 out.s6_addr[12] = ((uint8_t *)&in.s_addr)[0];
993 out.s6_addr[13] = ((uint8_t *)&in.s_addr)[1];
994 out.s6_addr[14] = ((uint8_t *)&in.s_addr)[2];
995 out.s6_addr[15] = ((uint8_t *)&in.s_addr)[3];
1006 memset(&out, 0,
sizeof(
struct in_addr));
1007 ((uint8_t *)&out.s_addr)[0] = in.s6_addr[12];
1008 ((uint8_t *)&out.s_addr)[1] = in.s6_addr[13];
1009 ((uint8_t *)&out.s_addr)[2] = in.s6_addr[14];
1010 ((uint8_t *)&out.s_addr)[3] = in.s6_addr[15];
1016 memmove(&buf, &mSocketAddr_.sin6_addr,
sizeof(
struct in6_addr));
1023 map6to4(mSocketAddr_.sin6_addr, buf);
1030 debugs(14,
DBG_IMPORTANT,
"ERROR: Ip::Address::getInAddr : Cannot convert non-IPv4 to IPv4. IPA=" << *
this);
1031 memset(&buf,0xFFFFFFFF,
sizeof(
struct in_addr));
static bool operator==(ESIElement const *lhs, ESIElement::Pointer const &rhs)
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
void map4to6(const struct in_addr &src, struct in6_addr &dest) const
bool isSiteLocal6() const
void setEmpty()
Fast reset of the stored content to what would be after default constructor.
static void InitAddr(struct addrinfo *&ai)
void getSockAddr(struct sockaddr_storage &addr, const int family) const
bool operator==(Address const &s) const
unsigned int toHostStr(char *buf, const unsigned int len) const
bool operator>(Address const &rhs) const
int compareWhole(const Ip::Address &rhs) const
static void FreeAddr(struct addrinfo *&ai)
bool lookupHostIP(const char *s, bool nodns)
bool getReverseString6(char buf[MAX_IPSTRLEN], const struct in6_addr &dat) const
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
bool operator>=(Address const &rhs) const
bool GetHostByName(const char *s)
void applyClientMask(const Address &mask)
bool getReverseString4(char buf[MAX_IPSTRLEN], const struct in_addr &dat) const
bool fromHost(const char *hostWithoutPort)
int matchIPAddr(const Address &rhs) const
struct sockaddr_in6 mSocketAddr_
static const struct in6_addr v6_noaddr
bool isSiteLocalAuto() const
bool operator<(Address const &rhs) const
bool operator!=(Address const &s) const
static const struct in6_addr v4_noaddr
bool getReverseString(char buf[MAX_IPSTRLEN], int show_type=AF_UNSPEC) const
Address & operator=(struct sockaddr_in const &s)
char * toUrl(char *buf, unsigned int len) const
bool getInAddr(struct in_addr &) const
int applyMask(const Address &mask)
void setAnyAddr()
NOTE: Does NOT clear the Port stored. Only the Address and Type.
bool operator<=(Address const &rhs) const
static const struct in6_addr v4_localhost
unsigned short port() const
static const struct in6_addr v4_anyaddr
void map6to4(const struct in6_addr &src, struct in_addr &dest) const
A const & min(A const &lhs, A const &rhs)
#define debugs(SECTION, LEVEL, CONTENT)
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
int EnableIpv6
Whether IPv6 is supported and type of support.