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;
646 if (force == AF_INET6 || (force == AF_UNSPEC && isIPv6()) ) {
647 dst->ai_addr = (
struct sockaddr*)
new sockaddr_in6;
649 memset(dst->ai_addr,0,
sizeof(
struct sockaddr_in6));
651 getSockAddr(*((
struct sockaddr_in6*)dst->ai_addr));
653 dst->ai_addrlen =
sizeof(
struct sockaddr_in6);
655 dst->ai_family = ((
struct sockaddr_in6*)dst->ai_addr)->sin6_family;
668 dst->ai_protocol = IPPROTO_IPV6;
671 }
else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
673 dst->ai_addr = (
struct sockaddr*)
new sockaddr_in;
675 memset(dst->ai_addr,0,
sizeof(
struct sockaddr_in));
677 getSockAddr(*((
struct sockaddr_in*)dst->ai_addr));
679 dst->ai_addrlen =
sizeof(
struct sockaddr_in);
681 dst->ai_family = ((
struct sockaddr_in*)dst->ai_addr)->sin_family;
692 memset(ai,0,
sizeof(
struct addrinfo));
696 if (ai->ai_addr)
delete ai->ai_addr;
698 ai->ai_addr = (
struct sockaddr*)
new sockaddr_in6;
699 memset(ai->ai_addr, 0,
sizeof(
struct sockaddr_in6));
701 ai->ai_addrlen =
sizeof(
struct sockaddr_in6);
708 if (ai ==
nullptr)
return;
710 if (ai->ai_addr)
delete ai->ai_addr;
712 ai->ai_addr =
nullptr;
725 uint8_t *l = (uint8_t*)mSocketAddr_.sin6_addr.s6_addr;
726 uint8_t *r = (uint8_t*)rhs.
mSocketAddr_.sin6_addr.s6_addr;
731 for (
unsigned int i = 0 ; i <
sizeof(mSocketAddr_.sin6_addr) ; ++i) {
746 return memcmp(
this, &rhs,
sizeof(*
this));
752 return (0 == matchIPAddr(s));
767 return (matchIPAddr(rhs) <= 0);
776 return ( matchIPAddr(rhs) >= 0);
785 return ( matchIPAddr(rhs) > 0);
794 return ( matchIPAddr(rhs) < 0);
800 return ntohs( mSocketAddr_.sin6_port );
806 mSocketAddr_.sin6_port = htons(prt);
815 if (buf ==
nullptr) {
823 memcpy(buf,
"::\0",
min(
static_cast<unsigned int>(3),blen));
825 memcpy(buf,
"0.0.0.0\0",
min(
static_cast<unsigned int>(8),blen));
833 if ( force == AF_INET && !isIPv4() ) {
835 memcpy(buf,
"{!IPv4}\0",
min(
static_cast<unsigned int>(8),blen));
840 if ( force == AF_INET6 || (force == AF_UNSPEC && isIPv6()) ) {
842 inet_ntop(AF_INET6, &mSocketAddr_.sin6_addr, buf, blen);
844 }
else if ( force == AF_INET || (force == AF_UNSPEC && isIPv4()) ) {
848 inet_ntop(AF_INET, &tmp, buf, blen);
850 debugs(14,
DBG_CRITICAL,
"WARNING: Corrupt IP Address details OR required to display in unknown format (" <<
851 force <<
"). accepted={" << AF_UNSPEC <<
"," << AF_INET <<
"," << AF_INET6 <<
"}");
852 fprintf(stderr,
"WARNING: Corrupt IP Address details OR required to display in unknown format (%d). accepted={%d,%d,%d} ",
853 force, AF_UNSPEC, AF_INET, AF_INET6);
854 memcpy(buf,
"dead:beef::\0",
min(
static_cast<unsigned int>(13),blen));
866 if (isIPv6() && blen > 0) {
873 toStr(p, blen-8, AF_INET6);
875 toStr(p, blen-8, AF_INET);
878 while (*p !=
'\0' && p < buf+blen)
881 if (isIPv6() && p < (buf+blen-1) ) {
900 if (buf ==
nullptr) {
904 p += toHostStr(p, blen);
906 if (mSocketAddr_.sin6_port > 0 && p <= (buf+blen-7) ) {
908 snprintf(p, 7,
":%d",
port() );
926 return lookupHostIP(host,
true);
930 const char *start = host + 1;
937 tmp[strlen(tmp)-1] =
'\0';
938 const bool result = lookupHostIP(tmp,
true);
946 struct sockaddr_in *sin =
nullptr;
948 if ( family == AF_INET && !isIPv4()) {
950 debugs(14,
DBG_CRITICAL,
"ERROR: Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *
this);
954 if ( family == AF_INET6 || (family == AF_UNSPEC && isIPv6()) ) {
955 struct sockaddr_in6 *ss6 = (
struct sockaddr_in6*)&addr;
957 }
else if ( family == AF_INET || (family == AF_UNSPEC && isIPv4()) ) {
958 sin = (
struct sockaddr_in*)&addr;
969 buf.sin_family = AF_INET;
970 buf.sin_port = mSocketAddr_.sin6_port;
971 map6to4( mSocketAddr_.sin6_addr, buf.sin_addr);
973 debugs(14,
DBG_CRITICAL,
"ERROR: Ip::Address::getSockAddr : Cannot convert non-IPv4 to IPv4. from " << *
this );
975 memset(&buf,0xFFFFFFFF,
sizeof(
struct sockaddr_in));
979 #if HAVE_SIN_LEN_IN_SAI
981 buf.sin_len =
sizeof(
struct sockaddr_in);
988 memmove(&buf, &mSocketAddr_,
sizeof(
struct sockaddr_in6));
990 buf.sin6_family = AF_INET6;
992 #if HAVE_SIN6_LEN_IN_SAI
994 buf.sin6_len =
sizeof(
struct sockaddr_in6);
1003 if ( in.s_addr == 0x00000000) {
1006 }
else if ( in.s_addr == 0xFFFFFFFF) {
1012 out.s6_addr[12] = ((uint8_t *)&in.s_addr)[0];
1013 out.s6_addr[13] = ((uint8_t *)&in.s_addr)[1];
1014 out.s6_addr[14] = ((uint8_t *)&in.s_addr)[2];
1015 out.s6_addr[15] = ((uint8_t *)&in.s_addr)[3];
1026 memset(&out, 0,
sizeof(
struct in_addr));
1027 ((uint8_t *)&out.s_addr)[0] = in.s6_addr[12];
1028 ((uint8_t *)&out.s_addr)[1] = in.s6_addr[13];
1029 ((uint8_t *)&out.s_addr)[2] = in.s6_addr[14];
1030 ((uint8_t *)&out.s_addr)[3] = in.s6_addr[15];
1036 memmove(&buf, &mSocketAddr_.sin6_addr,
sizeof(
struct in6_addr));
1043 map6to4(mSocketAddr_.sin6_addr, buf);
1050 debugs(14,
DBG_IMPORTANT,
"ERROR: Ip::Address::getInAddr : Cannot convert non-IPv4 to IPv4. IPA=" << *
this);
1051 memset(&buf,0xFFFFFFFF,
sizeof(
struct in_addr));