21 #include <arpa/inet.h>
29 #if !defined(IN6_ARE_ADDR_EQUAL) && _SQUID_WINDOWS_
30 #define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL
34 #define IASSERT(a,b) \
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); \
43 std::optional<Ip::Address>
59 const uint8_t *ptr= mSocketAddr_.sin6_addr.s6_addr;
72 for (; shift<
sizeof(mSocketAddr_.sin6_addr) ; ++shift) {
80 for (caught = 0, bit= 7 ; !caught && (bit <= 7); --bit) {
81 caught = ((ipbyte & 0x80) == 0x00);
99 uint32_t *p1 = (uint32_t*)(&mSocketAddr_.sin6_addr);
100 uint32_t
const *p2 = (uint32_t
const *)(&mask_addr.
mSocketAddr_.sin6_addr);
101 unsigned int blen =
sizeof(mSocketAddr_.sin6_addr)/
sizeof(uint32_t);
102 unsigned int changes = 0;
104 for (
unsigned int i = 0; i < blen; ++i) {
105 if ((p1[i] & p2[i]) != p1[i])
117 const auto addressWords =
reinterpret_cast<uint32_t*
>(&mSocketAddr_.sin6_addr);
118 const auto maskWords =
reinterpret_cast<const uint32_t*
>(&mask.
mSocketAddr_.sin6_addr);
119 const auto len =
sizeof(mSocketAddr_.sin6_addr)/
sizeof(uint32_t);
120 for (
size_t i = 0; i < len; ++i)
121 addressWords[i] |= ~maskWords[i];
127 if (!isLocalhost() && isIPv4())
128 (void)applyMask(mask);
134 uint8_t clearbits = 0;
135 uint8_t* p =
nullptr;
141 if (cidrMask > 32 && mtype == AF_INET)
150 clearbits = (uint8_t)( (mtype==AF_INET6?128:32) - cidrMask);
156 p = (uint8_t*)(&mSocketAddr_.sin6_addr) + 15;
158 for (; clearbits>0 && p >= (uint8_t*)&mSocketAddr_.sin6_addr ; --p ) {
160 *p &= ((0xFF << clearbits) & 0xFF);
174 return (mSocketAddr_.sin6_port != 0);
180 return IN6_IS_ADDR_V4MAPPED( &mSocketAddr_.sin6_addr );
192 return IN6_IS_ADDR_UNSPECIFIED(&mSocketAddr_.sin6_addr) || IN6_ARE_ADDR_EQUAL(&mSocketAddr_.sin6_addr, &v4_anyaddr);
199 memset(&mSocketAddr_.sin6_addr, 0,
sizeof(
struct in6_addr) );
206 memset(&mSocketAddr_, 0,
sizeof(mSocketAddr_) );
213 const struct in6_addr
Ip::
Address::v4_anyaddr = {{{ 0x00000000, 0x00000000, 0x0000ffff, 0x00000000 }}};
214 const struct in6_addr
Ip::
Address::v4_noaddr = {{{ 0x00000000, 0x00000000, 0x0000ffff, 0xffffffff }}};
215 const struct in6_addr
Ip::
Address::v6_noaddr = {{{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }}};
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
236 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
237 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
246 if ( isLocalhost() ) {
247 mSocketAddr_.sin6_addr = v4_localhost;
252 mSocketAddr_.sin6_addr = v4_anyaddr;
257 mSocketAddr_.sin6_addr = v4_noaddr;
271 return IN6_IS_ADDR_LOOPBACK( &mSocketAddr_.sin6_addr ) || IN6_ARE_ADDR_EQUAL( &mSocketAddr_.sin6_addr, &v4_localhost );
278 mSocketAddr_.sin6_addr = in6addr_loopback;
279 mSocketAddr_.sin6_family = AF_INET6;
281 mSocketAddr_.sin6_addr = v4_localhost;
282 mSocketAddr_.sin6_family = AF_INET;
292 return mSocketAddr_.sin6_addr.s6_addr[0] ==
static_cast<uint8_t
>(0xfd) ||
293 mSocketAddr_.sin6_addr.s6_addr[0] ==
static_cast<uint8_t
>(0xfc);
299 return mSocketAddr_.sin6_addr.s6_addr[11] ==
static_cast<uint8_t
>(0xff) &&
300 mSocketAddr_.sin6_addr.s6_addr[12] ==
static_cast<uint8_t
>(0xfe);
307 return IN6_ARE_ADDR_EQUAL( &mSocketAddr_.sin6_addr, &v6_noaddr )
308 || IN6_ARE_ADDR_EQUAL( &mSocketAddr_.sin6_addr, &v4_noaddr );
314 memset(&mSocketAddr_.sin6_addr, 0xFF,
sizeof(
struct in6_addr) );
315 mSocketAddr_.sin6_family = AF_INET6;
322 unsigned char const *r = dat.s6_addr;
334 for (
int i = 15; i >= 0; --i, p+=4) {
335 snprintf(p, 5,
"%x.%x.", ((r[i])&0xf), (((r[i])>>4)&0xf) );
340 snprintf(p,10,
"ip6.arpa.");
348 unsigned int i = (
unsigned int) ntohl(dat.s_addr);
349 snprintf(buf, 32,
"%u.%u.%u.%u.in-addr.arpa.",
361 if (show_type == AF_UNSPEC) {
362 show_type = isIPv6() ? AF_INET6 : AF_INET ;
365 if (show_type == AF_INET && isIPv4()) {
366 struct in_addr* tmp = (
struct in_addr*)&mSocketAddr_.sin6_addr.s6_addr[12];
367 return getReverseString4(buf, *tmp);
368 }
else if ( show_type == AF_INET6 && isIPv6() ) {
369 return getReverseString6(buf, mSocketAddr_.sin6_addr);
382 lookupHostIP(s,
true);
388 return lookupHostIP(s,
true);
394 return lookupHostIP(s,
false);
400 struct addrinfo want;
401 memset(&want, 0,
sizeof(
struct addrinfo));
403 want.ai_flags = AI_NUMERICHOST;
407 struct addrinfo *res =
nullptr;
408 if ( (err = getaddrinfo(s,
nullptr, &want, &res)) != 0) {
409 debugs(14,3,
"Given Non-IP '" << s <<
"': " << gai_strerror(err) );
416 struct addrinfo *resHead = res;
419 struct addrinfo *maybeIpv4 = res;
421 if (maybeIpv4->ai_family == AF_INET)
423 maybeIpv4 = maybeIpv4->ai_next;
425 if (maybeIpv4 !=
nullptr)
434 short portSaved =
port();
439 freeaddrinfo(resHead);
452 map4to6((
const in_addr)s.sin_addr, mSocketAddr_.sin6_addr);
453 mSocketAddr_.sin6_port = s.sin_port;
454 mSocketAddr_.sin6_family = AF_INET6;
462 if (s.ss_family == AF_INET6) {
463 memmove(&mSocketAddr_, &s,
sizeof(
struct sockaddr_in6));
465 struct sockaddr_in *sin = (
struct sockaddr_in*)&s;
466 mSocketAddr_.sin6_port = sin->sin_port;
467 map4to6( sin->sin_addr, mSocketAddr_.sin6_addr);
481 memmove(&mSocketAddr_, &s,
sizeof(
struct sockaddr_in6));
494 map4to6((
const in_addr)s, mSocketAddr_.sin6_addr);
495 mSocketAddr_.sin6_family = AF_INET6;
508 memmove(&mSocketAddr_.sin6_addr, &s,
sizeof(
struct in6_addr));
509 mSocketAddr_.sin6_family = AF_INET6;
524 struct in_addr* ipv4 =
nullptr;
526 struct in6_addr* ipv6 =
nullptr;
536 switch (s.h_addrtype) {
539 ipv4 = (in_addr*)(s.h_addr_list[0]);
545 ipv6 = (in6_addr*)(s.h_addr_list[0]);
568 struct sockaddr_in* ipv4 =
nullptr;
570 struct sockaddr_in6* ipv6 =
nullptr;
583 switch (s.ai_family) {
586 ipv4 = (sockaddr_in*)(s.ai_addr);
593 ipv6 = (sockaddr_in6*)(s.ai_addr);
603 if (s.ai_addr !=
nullptr) {
604 if (s.ai_addrlen ==
sizeof(
struct sockaddr_in6)) {
605 operator=(*((
struct sockaddr_in6*)s.ai_addr));
607 }
else if (s.ai_addrlen ==
sizeof(
struct sockaddr_in)) {
608 operator=(*((
struct sockaddr_in*)s.ai_addr));
621 if (dst ==
nullptr) {
625 memset(dst, 0,
sizeof(
struct addrinfo));
632 dst->ai_flags = AI_NUMERICHOST;
635 if (dst->ai_socktype == 0)
636 dst->ai_socktype = SOCK_STREAM;
638 if (dst->ai_socktype == SOCK_STREAM
639 && dst->ai_protocol == 0)
640 dst->ai_protocol = IPPROTO_TCP;
642 if (dst->ai_socktype == SOCK_DGRAM
643 && dst->ai_protocol == 0)
644 dst->ai_protocol = IPPROTO_UDP;
647 if (force == AF_INET6 || (force == AF_UNSPEC && isIPv6()) ) {
648 getSockAddr(*((
struct sockaddr_in6*)dst->ai_addr));
650 dst->ai_addrlen =
sizeof(
struct sockaddr_in6);
652 dst->ai_family = ((
struct sockaddr_in6*)dst->ai_addr)->sin6_family;
665 dst->ai_protocol = IPPROTO_IPV6;
668 }
else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
669 getSockAddr(*((
struct sockaddr_in*)dst->ai_addr));
671 dst->ai_addrlen =
sizeof(
struct sockaddr_in);
673 dst->ai_family = ((
struct sockaddr_in*)dst->ai_addr)->sin_family;
684 memset(ai,0,
sizeof(
struct addrinfo));
688 delete reinterpret_cast<struct sockaddr_storage *
>(ai->ai_addr);
690 ai->ai_addr =
reinterpret_cast<struct sockaddr *
>(
new sockaddr_storage);
691 memset(ai->ai_addr, 0,
sizeof(
struct sockaddr_storage));
693 ai->ai_addrlen =
sizeof(
struct sockaddr_storage);
700 if (ai ==
nullptr)
return;
702 delete reinterpret_cast<struct sockaddr_storage *
>(ai->ai_addr);
704 ai->ai_addr =
nullptr;
717 uint8_t *l = (uint8_t*)mSocketAddr_.sin6_addr.s6_addr;
718 uint8_t *r = (uint8_t*)rhs.
mSocketAddr_.sin6_addr.s6_addr;
723 for (
unsigned int i = 0 ; i <
sizeof(mSocketAddr_.sin6_addr) ; ++i) {
738 return memcmp(
this, &rhs,
sizeof(*
this));
744 return (0 == matchIPAddr(s));
759 return (matchIPAddr(rhs) <= 0);
768 return ( matchIPAddr(rhs) >= 0);
777 return ( matchIPAddr(rhs) > 0);
786 return ( matchIPAddr(rhs) < 0);
792 return ntohs( mSocketAddr_.sin6_port );
798 mSocketAddr_.sin6_port = htons(prt);
807 if (buf ==
nullptr) {
815 memcpy(buf,
"::\0",
min(
static_cast<unsigned int>(3),blen));
817 memcpy(buf,
"0.0.0.0\0",
min(
static_cast<unsigned int>(8),blen));
825 if ( force == AF_INET && !isIPv4() ) {
827 memcpy(buf,
"{!IPv4}\0",
min(
static_cast<unsigned int>(8),blen));
832 if ( force == AF_INET6 || (force == AF_UNSPEC && isIPv6()) ) {
834 inet_ntop(AF_INET6, &mSocketAddr_.sin6_addr, buf, blen);
836 }
else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
840 inet_ntop(AF_INET, &tmp, buf, blen);
842 debugs(14,
DBG_CRITICAL,
"WARNING: Corrupt IP Address details OR required to display in unknown format (" <<
843 force <<
"). accepted={" << AF_UNSPEC <<
"," << AF_INET <<
"," << AF_INET6 <<
"}");
844 fprintf(stderr,
"WARNING: Corrupt IP Address details OR required to display in unknown format (%d). accepted={%d,%d,%d} ",
845 force, AF_UNSPEC, AF_INET, AF_INET6);
846 memcpy(buf,
"dead:beef::\0",
min(
static_cast<unsigned int>(13),blen));
858 if (isIPv6() && blen > 0) {
865 toStr(p, blen-8, AF_INET6);
867 toStr(p, blen-8, AF_INET);
870 while (*p !=
'\0' && p < buf+blen)
873 if (isIPv6() && p < (buf+blen-1) ) {
892 if (buf ==
nullptr) {
896 p += toHostStr(p, blen);
898 if (mSocketAddr_.sin6_port > 0 && p <= (buf+blen-7) ) {
900 snprintf(p, 7,
":%d",
port() );
918 return lookupHostIP(host,
true);
922 const char *start = host + 1;
929 tmp[strlen(tmp)-1] =
'\0';
930 const bool result = lookupHostIP(tmp,
true);
938 struct sockaddr_in *sin =
nullptr;
940 if ( family == AF_INET && !isIPv4()) {
942 debugs(14,
DBG_CRITICAL,
"ERROR: Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *
this);
946 if ( family == AF_INET6 || (family == AF_UNSPEC && isIPv6()) ) {
947 struct sockaddr_in6 *ss6 = (
struct sockaddr_in6*)&addr;
949 }
else if ( family == AF_INET || (family == AF_UNSPEC && isIPv4()) ) {
950 sin = (
struct sockaddr_in*)&addr;
961 buf.sin_family = AF_INET;
962 buf.sin_port = mSocketAddr_.sin6_port;
963 map6to4( mSocketAddr_.sin6_addr, buf.sin_addr);
965 debugs(14,
DBG_CRITICAL,
"ERROR: Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *
this );
967 memset(&buf,0xFFFFFFFF,
sizeof(
struct sockaddr_in));
971 #if HAVE_SIN_LEN_IN_SAI
973 buf.sin_len =
sizeof(
struct sockaddr_in);
980 memmove(&buf, &mSocketAddr_,
sizeof(
struct sockaddr_in6));
982 buf.sin6_family = AF_INET6;
984 #if HAVE_SIN6_LEN_IN_SAI
986 buf.sin6_len =
sizeof(
struct sockaddr_in6);
995 if ( in.s_addr == 0x00000000) {
998 }
else if ( in.s_addr == 0xFFFFFFFF) {
1004 out.s6_addr[12] = ((uint8_t *)&in.s_addr)[0];
1005 out.s6_addr[13] = ((uint8_t *)&in.s_addr)[1];
1006 out.s6_addr[14] = ((uint8_t *)&in.s_addr)[2];
1007 out.s6_addr[15] = ((uint8_t *)&in.s_addr)[3];
1018 memset(&out, 0,
sizeof(
struct in_addr));
1019 ((uint8_t *)&out.s_addr)[0] = in.s6_addr[12];
1020 ((uint8_t *)&out.s_addr)[1] = in.s6_addr[13];
1021 ((uint8_t *)&out.s_addr)[2] = in.s6_addr[14];
1022 ((uint8_t *)&out.s_addr)[3] = in.s6_addr[15];
1028 memmove(&buf, &mSocketAddr_.sin6_addr,
sizeof(
struct in6_addr));
1035 map6to4(mSocketAddr_.sin6_addr, buf);
1042 debugs(14,
DBG_IMPORTANT,
"ERROR: Ip::Address::getInAddr : Cannot convert non-IPv4 to IPv4. IPA=" << *
this);
1043 memset(&buf,0xFFFFFFFF,
sizeof(
struct in_addr));