13 static const uint8_t
pchIPv4[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};
14 static const uint8_t
pchOnionCat[] = {0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43};
25 memset(
ip, 0,
sizeof(
ip));
29 memcpy(
ip, ipIn.
ip,
sizeof(
ip));
36 memcpy(
ip + 12, ip_in, 4);
39 memcpy(
ip, ip_in, 16);
42 assert(!
"invalid network");
64 uint8_t hash[32] = {};
65 CSHA256().
Write((
const uint8_t *)name.data(), name.size()).Finalize(hash);
83 if (strName.size() > 6 &&
84 strName.substr(strName.size() - 6, 6) ==
".onion") {
85 std::vector<uint8_t> vchAddr =
86 DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
91 for (
unsigned int i = 0; i < 16 -
sizeof(
pchOnionCat); i++) {
113 const int cmplen =
IsIPv4() ? 4 : 16;
114 for (
int i = 0; i < cmplen; ++i) {
168 static const uint8_t pchRFC6052[] = {0, 0x64, 0xFF, 0x9B, 0, 0,
170 return (memcmp(
ip, pchRFC6052,
sizeof(pchRFC6052)) == 0);
179 static const uint8_t pchRFC4862[] = {0xFE, 0x80, 0, 0, 0, 0, 0, 0};
180 return (memcmp(
ip, pchRFC4862,
sizeof(pchRFC4862)) == 0);
184 return ((
GetByte(15) & 0xFE) == 0xFC);
188 static const uint8_t pchRFC6145[] = {0, 0, 0, 0, 0, 0,
189 0, 0, 0xFF, 0xFF, 0, 0};
190 return (memcmp(
ip, pchRFC6145,
sizeof(pchRFC6145)) == 0);
225 static const uint8_t pchLocal[16] = {0, 0, 0, 0, 0, 0, 0, 0,
226 0, 0, 0, 0, 0, 0, 0, 1};
227 if (memcmp(
ip, pchLocal, 16) == 0) {
256 uint8_t ipNone6[16] = {};
257 if (memcmp(
ip, ipNone6, 16) == 0) {
272 uint32_t ipNone = INADDR_NONE;
273 if (memcmp(
ip + 12, &ipNone, 4) == 0) {
279 if (memcmp(
ip + 12, &ipNone, 4) == 0) {
342 struct sockaddr_storage sockaddr;
343 socklen_t socklen =
sizeof(sockaddr);
344 if (serv.
GetSockAddr((
struct sockaddr *)&sockaddr, &socklen)) {
345 char name[1025] =
"";
346 if (!getnameinfo((
const struct sockaddr *)&sockaddr, socklen, name,
347 sizeof(name),
nullptr, 0, NI_NUMERICHOST)) {
348 return std::string(name);
369 return (memcmp(a.
ip, b.
ip, 16) == 0);
373 return (memcmp(a.
ip, b.
ip, 16) < 0);
390 memcpy(pipv4Addr,
ip + 12, 4);
408 memcpy(pipv6Addr,
ip, 16);
444 }
else if (
IsTor()) {
452 if (asmap.size() == 0 || (net_class !=
NET_IPV4 && net_class !=
NET_IPV6)) {
456 std::vector<bool> ip_bits(128);
460 for (int8_t byte_i = 0; byte_i < 12; ++byte_i) {
461 for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
462 ip_bits[byte_i * 8 + bit_i] =
463 (
pchIPv4[byte_i] >> (7 - bit_i)) & 1;
467 for (
int i = 0; i < 32; ++i) {
468 ip_bits[96 + i] = (ipv4 >> (31 - i)) & 1;
472 for (int8_t byte_i = 0; byte_i < 16; ++byte_i) {
473 uint8_t cur_byte =
GetByte(15 - byte_i);
474 for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
475 ip_bits[byte_i * 8 + bit_i] = (cur_byte >> (7 - bit_i)) & 1;
479 uint32_t mapped_as =
Interpret(asmap, ip_bits);
494 std::vector<uint8_t> vchRet;
503 for (
int i = 0; i < 4; i++) {
504 vchRet.push_back((asn >> (8 * i)) & 0xFF);
509 vchRet.push_back(net_class);
526 vchRet.push_back((ipv4 >> 24) & 0xFF);
527 vchRet.push_back((ipv4 >> 16) & 0xFF);
529 }
else if (
IsTor()) {
542 vchRet.push_back(
GetByte(15 - nStartByte));
548 vchRet.push_back(
GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
557 memcpy(&nRet, &hash,
sizeof(nRet));
566 if (addr ==
nullptr) {
588 return REACH_UNREACHABLE;
599 return REACH_DEFAULT;
606 return REACH_DEFAULT;
613 return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG;
618 return REACH_DEFAULT;
623 return REACH_PRIVATE;
628 return REACH_DEFAULT;
632 return REACH_IPV6_WEAK;
641 return REACH_DEFAULT;
645 return REACH_IPV6_WEAK;
650 return REACH_PRIVATE;
668 assert(addr.sin_family == AF_INET);
672 :
CNetAddr(addr.sin6_addr, addr.sin6_scope_id),
673 port(ntohs(addr.sin6_port)) {
674 assert(addr.sin6_family == AF_INET6);
678 switch (paddr->sa_family) {
681 CService(*reinterpret_cast<const struct sockaddr_in *>(paddr));
685 CService(*reinterpret_cast<const struct sockaddr_in6 *>(paddr));
697 return static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) &&
702 return static_cast<CNetAddr>(a) < static_cast<CNetAddr>(b) ||
703 (
static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) &&
721 if (*addrlen < (socklen_t)
sizeof(
struct sockaddr_in)) {
724 *addrlen =
sizeof(
struct sockaddr_in);
725 struct sockaddr_in *paddrin =
726 reinterpret_cast<struct sockaddr_in *
>(paddr);
727 memset(paddrin, 0, *addrlen);
731 paddrin->sin_family = AF_INET;
732 paddrin->sin_port = htons(
port);
736 if (*addrlen < (socklen_t)
sizeof(
struct sockaddr_in6)) {
739 *addrlen =
sizeof(
struct sockaddr_in6);
740 struct sockaddr_in6 *paddrin6 =
741 reinterpret_cast<struct sockaddr_in6 *
>(paddr);
742 memset(paddrin6, 0, *addrlen);
746 paddrin6->sin6_scope_id =
scopeId;
747 paddrin6->sin6_family = AF_INET6;
748 paddrin6->sin6_port = htons(
port);
758 std::vector<uint8_t> vKey;
760 memcpy(vKey.data(),
ip, 16);
762 vKey[16] =
port / 0x100;
764 vKey[17] =
port & 0x0FF;
800 if (n >= 0 && n <= (128 - astartofs * 8)) {
803 for (; n < 128; ++n) {
804 netmask[n >> 3] &= ~(1 << (7 - (n & 7)));
811 for (
int x = 0; x < 16; ++x) {
826 for (
int x = astartofs; x < 16; ++x) {
831 for (
int x = 0; x < 16; ++x) {
849 for (
int x = 0; x < 16; ++x) {
889 bool valid_cidr =
true;
891 for (; n < 16 &&
netmask[n] == 0xff; ++n) {
903 for (; n < 16 && valid_cidr; ++n) {
904 if (netmask[n] != 0x00) {
910 std::string strNetmask;
915 strNetmask =
strprintf(
"%u.%u.%u.%u", netmask[12], netmask[13],
916 netmask[14], netmask[15]);
919 "%x:%x:%x:%x:%x:%x:%x:%x", netmask[0] << 8 | netmask[1],
920 netmask[2] << 8 | netmask[3], netmask[4] << 8 | netmask[5],
921 netmask[6] << 8 | netmask[7], netmask[8] << 8 | netmask[9],
922 netmask[10] << 8 | netmask[11], netmask[12] << 8 | netmask[13],
923 netmask[14] << 8 | netmask[15]);
int GetReachabilityFrom(const CNetAddr *paddrPartner=nullptr) const
Calculates a metric for how reachable (*this) is from a given partner.
std::string ToStringPort() const
bool HasLinkedIPv4() const
Whether this address has a linked IPv4 address (see GetLinkedIPv4()).
unsigned short GetPort() const
static const uint8_t g_internal_prefix[]
void SetIP(const CNetAddr &ip)
static const int NET_UNKNOWN
std::vector< uint8_t > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
friend bool operator==(const CService &a, const CService &b)
CNetAddr network
Network (base) address.
bool GetInAddr(struct in_addr *pipv4Addr) const
Try to get our IPv4 address.
std::string ToString() const
bool GetIn6Addr(struct in6_addr *pipv6Addr) const
Try to get our IPv6 address.
enum Network GetNetwork() const
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
static int GetExtNetwork(const CNetAddr *addr)
static const uint8_t pchIPv4[12]
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
std::string ToStringIP() const
A combination of a network address (CNetAddr) and a (TCP) port.
friend bool operator<(const CService &a, const CService &b)
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
uint32_t Interpret(const std::vector< bool > &asmap, const std::vector< bool > &ip)
unsigned int GetByte(int n) const
friend bool operator==(const CSubNet &a, const CSubNet &b)
std::vector< uint8_t > DecodeBase32(const char *p, bool *pf_invalid)
static const uint8_t pchOnionCat[]
bool valid
Is this value valid? (only used to signal parse errors)
static uint32_t ReadBE32(const uint8_t *ptr)
bool Match(const CNetAddr &addr) const
uint8_t netmask[16]
Netmask, in network byte order.
std::string EncodeBase32(const uint8_t *pch, size_t len)
static int NetmaskBits(uint8_t x)
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
friend bool operator<(const CNetAddr &a, const CNetAddr &b)
std::string ToString() const
friend bool operator==(const CNetAddr &a, const CNetAddr &b)
std::string ToStringIPPort() const
static const int NET_TEREDO
friend bool operator<(const CSubNet &a, const CSubNet &b)
CSHA256 & Write(const uint8_t *data, size_t len)
void SetRaw(Network network, const uint8_t *data)
Set raw IPv4 or IPv6 address (in network byte order)
bool SetSpecial(const std::string &strName)
Try to make this a dummy address that maps the specified onion address into IPv6 using OnionCat's ran...
std::string ToString() const
bool SanityCheckASMap(const std::vector< bool > &asmap)
uint32_t GetLinkedIPv4() const
For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv...
bool SetSockAddr(const struct sockaddr *paddr)
bool SetInternal(const std::string &name)
Try to make this a dummy address that maps the specified name into IPv6 like so: (0xFD + sha256("bitc...
A hasher class for SHA-256.
std::vector< uint8_t > GetKey() const
uint32_t GetNetClass() const
CNetAddr()
Construct an unspecified IPv6 network address (::/128).