Bitcoin Core  0.20.99
P2P Digital Currency
netaddress.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <netaddress.h>
7 #include <hash.h>
8 #include <util/strencodings.h>
9 #include <util/asmap.h>
10 #include <tinyformat.h>
11 
12 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
13 static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
14 
15 // 0xFD + sha256("bitcoin")[0:5]
16 static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 };
17 
24 {
25  memset(ip, 0, sizeof(ip));
26 }
27 
28 void CNetAddr::SetIP(const CNetAddr& ipIn)
29 {
30  memcpy(ip, ipIn.ip, sizeof(ip));
31 }
32 
33 void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
34 {
35  switch(network)
36  {
37  case NET_IPV4:
38  memcpy(ip, pchIPv4, 12);
39  memcpy(ip+12, ip_in, 4);
40  break;
41  case NET_IPV6:
42  memcpy(ip, ip_in, 16);
43  break;
44  default:
45  assert(!"invalid network");
46  }
47 }
48 
63 bool CNetAddr::SetInternal(const std::string &name)
64 {
65  if (name.empty()) {
66  return false;
67  }
68  unsigned char hash[32] = {};
69  CSHA256().Write((const unsigned char*)name.data(), name.size()).Finalize(hash);
71  memcpy(ip + sizeof(g_internal_prefix), hash, sizeof(ip) - sizeof(g_internal_prefix));
72  return true;
73 }
74 
85 bool CNetAddr::SetSpecial(const std::string &strName)
86 {
87  if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
88  std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
89  if (vchAddr.size() != 16-sizeof(pchOnionCat))
90  return false;
91  memcpy(ip, pchOnionCat, sizeof(pchOnionCat));
92  for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++)
93  ip[i + sizeof(pchOnionCat)] = vchAddr[i];
94  return true;
95  }
96  return false;
97 }
98 
99 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
100 {
101  SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
102 }
103 
104 CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
105 {
106  SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr);
107  scopeId = scope;
108 }
109 
110 unsigned int CNetAddr::GetByte(int n) const
111 {
112  return ip[15-n];
113 }
114 
116 {
117  const int cmplen = IsIPv4() ? 4 : 16;
118  for (int i = 0; i < cmplen; ++i) {
119  if (GetByte(i)) return false;
120  }
121 
122  return true;
123 }
124 
125 bool CNetAddr::IsIPv4() const
126 {
127  return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
128 }
129 
130 bool CNetAddr::IsIPv6() const
131 {
132  return (!IsIPv4() && !IsTor() && !IsInternal());
133 }
134 
136 {
137  return IsIPv4() && (
138  GetByte(3) == 10 ||
139  (GetByte(3) == 192 && GetByte(2) == 168) ||
140  (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
141 }
142 
144 {
145  return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19);
146 }
147 
149 {
150  return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
151 }
152 
154 {
155  return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127;
156 }
157 
159 {
160  return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
161  (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
162  (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
163 }
164 
166 {
167  return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8;
168 }
169 
171 {
172  return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
173 }
174 
176 {
177  static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0};
178  return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
179 }
180 
182 {
183  return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0);
184 }
185 
187 {
188  static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0};
189  return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
190 }
191 
193 {
194  return ((GetByte(15) & 0xFE) == 0xFC);
195 }
196 
198 {
199  static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0};
200  return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
201 }
202 
204 {
205  return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
206 }
207 
209 {
210  return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x20);
211 }
212 
213 bool CNetAddr::IsHeNet() const
214 {
215  return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70);
216 }
217 
224 bool CNetAddr::IsTor() const
225 {
226  return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
227 }
228 
229 bool CNetAddr::IsLocal() const
230 {
231  // IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)
232  if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0))
233  return true;
234 
235  // IPv6 loopback (::1/128)
236  static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
237  if (memcmp(ip, pchLocal, 16) == 0)
238  return true;
239 
240  return false;
241 }
242 
253 bool CNetAddr::IsValid() const
254 {
255  // Cleanup 3-byte shifted addresses caused by garbage in size field
256  // of addr messages from versions before 0.2.9 checksum.
257  // Two consecutive addr messages look like this:
258  // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
259  // so if the first length field is garbled, it reads the second batch
260  // of addr misaligned by 3 bytes.
261  if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
262  return false;
263 
264  // unspecified IPv6 address (::/128)
265  unsigned char ipNone6[16] = {};
266  if (memcmp(ip, ipNone6, 16) == 0)
267  return false;
268 
269  // documentation IPv6 address
270  if (IsRFC3849())
271  return false;
272 
273  if (IsInternal())
274  return false;
275 
276  if (IsIPv4())
277  {
278  // INADDR_NONE
279  uint32_t ipNone = INADDR_NONE;
280  if (memcmp(ip+12, &ipNone, 4) == 0)
281  return false;
282 
283  // 0
284  ipNone = 0;
285  if (memcmp(ip+12, &ipNone, 4) == 0)
286  return false;
287  }
288 
289  return true;
290 }
291 
302 {
303  return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsRFC7343() || IsLocal() || IsInternal());
304 }
305 
312 {
313  return memcmp(ip, g_internal_prefix, sizeof(g_internal_prefix)) == 0;
314 }
315 
317 {
318  if (IsInternal())
319  return NET_INTERNAL;
320 
321  if (!IsRoutable())
322  return NET_UNROUTABLE;
323 
324  if (IsIPv4())
325  return NET_IPV4;
326 
327  if (IsTor())
328  return NET_ONION;
329 
330  return NET_IPV6;
331 }
332 
333 std::string CNetAddr::ToStringIP() const
334 {
335  if (IsTor())
336  return EncodeBase32(&ip[6], 10) + ".onion";
337  if (IsInternal())
338  return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal";
339  CService serv(*this, 0);
340  struct sockaddr_storage sockaddr;
341  socklen_t socklen = sizeof(sockaddr);
342  if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
343  char name[1025] = "";
344  if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), nullptr, 0, NI_NUMERICHOST))
345  return std::string(name);
346  }
347  if (IsIPv4())
348  return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
349  else
350  return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
351  GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12),
352  GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8),
353  GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4),
354  GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0));
355 }
356 
357 std::string CNetAddr::ToString() const
358 {
359  return ToStringIP();
360 }
361 
362 bool operator==(const CNetAddr& a, const CNetAddr& b)
363 {
364  return (memcmp(a.ip, b.ip, 16) == 0);
365 }
366 
367 bool operator<(const CNetAddr& a, const CNetAddr& b)
368 {
369  return (memcmp(a.ip, b.ip, 16) < 0);
370 }
371 
382 bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
383 {
384  if (!IsIPv4())
385  return false;
386  memcpy(pipv4Addr, ip+12, 4);
387  return true;
388 }
389 
400 bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
401 {
402  if (!IsIPv6()) {
403  return false;
404  }
405  memcpy(pipv6Addr, ip, 16);
406  return true;
407 }
408 
410 {
411  return IsRoutable() && (IsIPv4() || IsRFC6145() || IsRFC6052() || IsRFC3964() || IsRFC4380());
412 }
413 
414 uint32_t CNetAddr::GetLinkedIPv4() const
415 {
416  if (IsIPv4() || IsRFC6145() || IsRFC6052()) {
417  // IPv4, mapped IPv4, SIIT translated IPv4: the IPv4 address is the last 4 bytes of the address
418  return ReadBE32(ip + 12);
419  } else if (IsRFC3964()) {
420  // 6to4 tunneled IPv4: the IPv4 address is in bytes 2-6
421  return ReadBE32(ip + 2);
422  } else if (IsRFC4380()) {
423  // Teredo tunneled IPv4: the IPv4 address is in the last 4 bytes of the address, but bitflipped
424  return ~ReadBE32(ip + 12);
425  }
426  assert(false);
427 }
428 
429 uint32_t CNetAddr::GetNetClass() const {
430  uint32_t net_class = NET_IPV6;
431  if (IsLocal()) {
432  net_class = 255;
433  }
434  if (IsInternal()) {
435  net_class = NET_INTERNAL;
436  } else if (!IsRoutable()) {
437  net_class = NET_UNROUTABLE;
438  } else if (HasLinkedIPv4()) {
439  net_class = NET_IPV4;
440  } else if (IsTor()) {
441  net_class = NET_ONION;
442  }
443  return net_class;
444 }
445 
446 uint32_t CNetAddr::GetMappedAS(const std::vector<bool> &asmap) const {
447  uint32_t net_class = GetNetClass();
448  if (asmap.size() == 0 || (net_class != NET_IPV4 && net_class != NET_IPV6)) {
449  return 0; // Indicates not found, safe because AS0 is reserved per RFC7607.
450  }
451  std::vector<bool> ip_bits(128);
452  if (HasLinkedIPv4()) {
453  // For lookup, treat as if it was just an IPv4 address (pchIPv4 prefix + IPv4 bits)
454  for (int8_t byte_i = 0; byte_i < 12; ++byte_i) {
455  for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
456  ip_bits[byte_i * 8 + bit_i] = (pchIPv4[byte_i] >> (7 - bit_i)) & 1;
457  }
458  }
459  uint32_t ipv4 = GetLinkedIPv4();
460  for (int i = 0; i < 32; ++i) {
461  ip_bits[96 + i] = (ipv4 >> (31 - i)) & 1;
462  }
463  } else {
464  // Use all 128 bits of the IPv6 address otherwise
465  for (int8_t byte_i = 0; byte_i < 16; ++byte_i) {
466  uint8_t cur_byte = GetByte(15 - byte_i);
467  for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
468  ip_bits[byte_i * 8 + bit_i] = (cur_byte >> (7 - bit_i)) & 1;
469  }
470  }
471  }
472  uint32_t mapped_as = Interpret(asmap, ip_bits);
473  return mapped_as;
474 }
475 
486 std::vector<unsigned char> CNetAddr::GetGroup(const std::vector<bool> &asmap) const
487 {
488  std::vector<unsigned char> vchRet;
489  uint32_t net_class = GetNetClass();
490  // If non-empty asmap is supplied and the address is IPv4/IPv6,
491  // return ASN to be used for bucketing.
492  uint32_t asn = GetMappedAS(asmap);
493  if (asn != 0) { // Either asmap was empty, or address has non-asmappable net class (e.g. TOR).
494  vchRet.push_back(NET_IPV6); // IPv4 and IPv6 with same ASN should be in the same bucket
495  for (int i = 0; i < 4; i++) {
496  vchRet.push_back((asn >> (8 * i)) & 0xFF);
497  }
498  return vchRet;
499  }
500 
501  vchRet.push_back(net_class);
502  int nStartByte = 0;
503  int nBits = 16;
504 
505  if (IsLocal()) {
506  // all local addresses belong to the same group
507  nBits = 0;
508  } else if (IsInternal()) {
509  // all internal-usage addresses get their own group
510  nStartByte = sizeof(g_internal_prefix);
511  nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8;
512  } else if (!IsRoutable()) {
513  // all other unroutable addresses belong to the same group
514  nBits = 0;
515  } else if (HasLinkedIPv4()) {
516  // IPv4 addresses (and mapped IPv4 addresses) use /16 groups
517  uint32_t ipv4 = GetLinkedIPv4();
518  vchRet.push_back((ipv4 >> 24) & 0xFF);
519  vchRet.push_back((ipv4 >> 16) & 0xFF);
520  return vchRet;
521  } else if (IsTor()) {
522  nStartByte = 6;
523  nBits = 4;
524  } else if (IsHeNet()) {
525  // for he.net, use /36 groups
526  nBits = 36;
527  } else {
528  // for the rest of the IPv6 network, use /32 groups
529  nBits = 32;
530  }
531 
532  // push our ip onto vchRet byte by byte...
533  while (nBits >= 8)
534  {
535  vchRet.push_back(GetByte(15 - nStartByte));
536  nStartByte++;
537  nBits -= 8;
538  }
539  // ...for the last byte, push nBits and for the rest of the byte push 1's
540  if (nBits > 0)
541  vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
542 
543  return vchRet;
544 }
545 
546 uint64_t CNetAddr::GetHash() const
547 {
548  uint256 hash = Hash(&ip[0], &ip[16]);
549  uint64_t nRet;
550  memcpy(&nRet, &hash, sizeof(nRet));
551  return nRet;
552 }
553 
554 // private extensions to enum Network, only returned by GetExtNetwork,
555 // and only used in GetReachabilityFrom
556 static const int NET_UNKNOWN = NET_MAX + 0;
557 static const int NET_TEREDO = NET_MAX + 1;
558 int static GetExtNetwork(const CNetAddr *addr)
559 {
560  if (addr == nullptr)
561  return NET_UNKNOWN;
562  if (addr->IsRFC4380())
563  return NET_TEREDO;
564  return addr->GetNetwork();
565 }
566 
568 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
569 {
570  enum Reachability {
571  REACH_UNREACHABLE,
572  REACH_DEFAULT,
573  REACH_TEREDO,
574  REACH_IPV6_WEAK,
575  REACH_IPV4,
576  REACH_IPV6_STRONG,
577  REACH_PRIVATE
578  };
579 
580  if (!IsRoutable() || IsInternal())
581  return REACH_UNREACHABLE;
582 
583  int ourNet = GetExtNetwork(this);
584  int theirNet = GetExtNetwork(paddrPartner);
585  bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
586 
587  switch(theirNet) {
588  case NET_IPV4:
589  switch(ourNet) {
590  default: return REACH_DEFAULT;
591  case NET_IPV4: return REACH_IPV4;
592  }
593  case NET_IPV6:
594  switch(ourNet) {
595  default: return REACH_DEFAULT;
596  case NET_TEREDO: return REACH_TEREDO;
597  case NET_IPV4: return REACH_IPV4;
598  case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled
599  }
600  case NET_ONION:
601  switch(ourNet) {
602  default: return REACH_DEFAULT;
603  case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well
604  case NET_ONION: return REACH_PRIVATE;
605  }
606  case NET_TEREDO:
607  switch(ourNet) {
608  default: return REACH_DEFAULT;
609  case NET_TEREDO: return REACH_TEREDO;
610  case NET_IPV6: return REACH_IPV6_WEAK;
611  case NET_IPV4: return REACH_IPV4;
612  }
613  case NET_UNKNOWN:
614  case NET_UNROUTABLE:
615  default:
616  switch(ourNet) {
617  default: return REACH_DEFAULT;
618  case NET_TEREDO: return REACH_TEREDO;
619  case NET_IPV6: return REACH_IPV6_WEAK;
620  case NET_IPV4: return REACH_IPV4;
621  case NET_ONION: return REACH_PRIVATE; // either from Tor, or don't care about our address
622  }
623  }
624 }
625 
627 {
628 }
629 
630 CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
631 {
632 }
633 
634 CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn)
635 {
636 }
637 
638 CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
639 {
640 }
641 
642 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
643 {
644  assert(addr.sin_family == AF_INET);
645 }
646 
647 CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port))
648 {
649  assert(addr.sin6_family == AF_INET6);
650 }
651 
652 bool CService::SetSockAddr(const struct sockaddr *paddr)
653 {
654  switch (paddr->sa_family) {
655  case AF_INET:
656  *this = CService(*(const struct sockaddr_in*)paddr);
657  return true;
658  case AF_INET6:
659  *this = CService(*(const struct sockaddr_in6*)paddr);
660  return true;
661  default:
662  return false;
663  }
664 }
665 
666 unsigned short CService::GetPort() const
667 {
668  return port;
669 }
670 
671 bool operator==(const CService& a, const CService& b)
672 {
673  return static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) && a.port == b.port;
674 }
675 
676 bool operator<(const CService& a, const CService& b)
677 {
678  return static_cast<CNetAddr>(a) < static_cast<CNetAddr>(b) || (static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) && a.port < b.port);
679 }
680 
693 bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
694 {
695  if (IsIPv4()) {
696  if (*addrlen < (socklen_t)sizeof(struct sockaddr_in))
697  return false;
698  *addrlen = sizeof(struct sockaddr_in);
699  struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
700  memset(paddrin, 0, *addrlen);
701  if (!GetInAddr(&paddrin->sin_addr))
702  return false;
703  paddrin->sin_family = AF_INET;
704  paddrin->sin_port = htons(port);
705  return true;
706  }
707  if (IsIPv6()) {
708  if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
709  return false;
710  *addrlen = sizeof(struct sockaddr_in6);
711  struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
712  memset(paddrin6, 0, *addrlen);
713  if (!GetIn6Addr(&paddrin6->sin6_addr))
714  return false;
715  paddrin6->sin6_scope_id = scopeId;
716  paddrin6->sin6_family = AF_INET6;
717  paddrin6->sin6_port = htons(port);
718  return true;
719  }
720  return false;
721 }
722 
726 std::vector<unsigned char> CService::GetKey() const
727 {
728  std::vector<unsigned char> vKey;
729  vKey.resize(18);
730  memcpy(vKey.data(), ip, 16);
731  vKey[16] = port / 0x100; // most significant byte of our port
732  vKey[17] = port & 0x0FF; // least significant byte of our port
733  return vKey;
734 }
735 
736 std::string CService::ToStringPort() const
737 {
738  return strprintf("%u", port);
739 }
740 
741 std::string CService::ToStringIPPort() const
742 {
743  if (IsIPv4() || IsTor() || IsInternal()) {
744  return ToStringIP() + ":" + ToStringPort();
745  } else {
746  return "[" + ToStringIP() + "]:" + ToStringPort();
747  }
748 }
749 
750 std::string CService::ToString() const
751 {
752  return ToStringIPPort();
753 }
754 
756  valid(false)
757 {
758  memset(netmask, 0, sizeof(netmask));
759 }
760 
761 CSubNet::CSubNet(const CNetAddr &addr, int32_t mask)
762 {
763  valid = true;
764  network = addr;
765  // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
766  memset(netmask, 255, sizeof(netmask));
767 
768  // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
769  const int astartofs = network.IsIPv4() ? 12 : 0;
770 
771  int32_t n = mask;
772  if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
773  {
774  n += astartofs*8;
775  // Clear bits [n..127]
776  for (; n < 128; ++n)
777  netmask[n>>3] &= ~(1<<(7-(n&7)));
778  } else
779  valid = false;
780 
781  // Normalize network according to netmask
782  for(int x=0; x<16; ++x)
783  network.ip[x] &= netmask[x];
784 }
785 
786 CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask)
787 {
788  valid = true;
789  network = addr;
790  // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
791  memset(netmask, 255, sizeof(netmask));
792 
793  // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
794  const int astartofs = network.IsIPv4() ? 12 : 0;
795 
796  for(int x=astartofs; x<16; ++x)
797  netmask[x] = mask.ip[x];
798 
799  // Normalize network according to netmask
800  for(int x=0; x<16; ++x)
801  network.ip[x] &= netmask[x];
802 }
803 
805  valid(addr.IsValid())
806 {
807  memset(netmask, 255, sizeof(netmask));
808  network = addr;
809 }
810 
815 bool CSubNet::Match(const CNetAddr &addr) const
816 {
817  if (!valid || !addr.IsValid())
818  return false;
819  for(int x=0; x<16; ++x)
820  if ((addr.ip[x] & netmask[x]) != network.ip[x])
821  return false;
822  return true;
823 }
824 
829 static inline int NetmaskBits(uint8_t x)
830 {
831  switch(x) {
832  case 0x00: return 0;
833  case 0x80: return 1;
834  case 0xc0: return 2;
835  case 0xe0: return 3;
836  case 0xf0: return 4;
837  case 0xf8: return 5;
838  case 0xfc: return 6;
839  case 0xfe: return 7;
840  case 0xff: return 8;
841  default: return -1;
842  }
843 }
844 
845 std::string CSubNet::ToString() const
846 {
847  /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
848  int cidr = 0;
849  bool valid_cidr = true;
850  int n = network.IsIPv4() ? 12 : 0;
851  for (; n < 16 && netmask[n] == 0xff; ++n)
852  cidr += 8;
853  if (n < 16) {
854  int bits = NetmaskBits(netmask[n]);
855  if (bits < 0)
856  valid_cidr = false;
857  else
858  cidr += bits;
859  ++n;
860  }
861  for (; n < 16 && valid_cidr; ++n)
862  if (netmask[n] != 0x00)
863  valid_cidr = false;
864 
865  /* Format output */
866  std::string strNetmask;
867  if (valid_cidr) {
868  strNetmask = strprintf("%u", cidr);
869  } else {
870  if (network.IsIPv4())
871  strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
872  else
873  strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
874  netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
875  netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
876  netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
877  netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
878  }
879 
880  return network.ToString() + "/" + strNetmask;
881 }
882 
883 bool CSubNet::IsValid() const
884 {
885  return valid;
886 }
887 
888 bool operator==(const CSubNet& a, const CSubNet& b)
889 {
890  return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
891 }
892 
893 bool operator<(const CSubNet& a, const CSubNet& b)
894 {
895  return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));
896 }
897 
898 bool SanityCheckASMap(const std::vector<bool>& asmap)
899 {
900  return SanityCheckASMap(asmap, 128); // For IP address lookups, the input is 128 bits
901 }
int GetReachabilityFrom(const CNetAddr *paddrPartner=nullptr) const
Calculates a metric for how reachable (*this) is from a given partner.
Definition: netaddress.cpp:568
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
Definition: netaddress.cpp:486
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:637
std::string ToStringPort() const
Definition: netaddress.cpp:736
bool HasLinkedIPv4() const
Whether this address has a linked IPv4 address (see GetLinkedIPv4()).
Definition: netaddress.cpp:409
std::string EncodeBase32(const unsigned char *pch, size_t len)
unsigned short GetPort() const
Definition: netaddress.cpp:666
bool IsLocal() const
Definition: netaddress.cpp:229
bool IsRFC4380() const
Definition: netaddress.cpp:181
void SetIP(const CNetAddr &ip)
Definition: netaddress.cpp:28
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
bool IsIPv6() const
Definition: netaddress.cpp:130
static const int NET_UNKNOWN
Definition: netaddress.cpp:556
uint16_t port
Definition: netaddress.h:141
friend bool operator==(const CService &a, const CService &b)
Definition: netaddress.cpp:671
std::vector< unsigned char > DecodeBase32(const char *p, bool *pf_invalid)
bool IsInternal() const
Definition: netaddress.cpp:311
CNetAddr network
Network (base) address.
Definition: netaddress.h:111
bool IsBindAny() const
Definition: netaddress.cpp:115
bool GetInAddr(struct in_addr *pipv4Addr) const
Try to get our IPv4 address.
Definition: netaddress.cpp:382
std::string ToString() const
Definition: netaddress.cpp:357
bool GetIn6Addr(struct in6_addr *pipv6Addr) const
Try to get our IPv6 address.
Definition: netaddress.cpp:400
enum Network GetNetwork() const
Definition: netaddress.cpp:316
bool IsRFC2544() const
Definition: netaddress.cpp:143
bool IsRFC4862() const
Definition: netaddress.cpp:186
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
Definition: netaddress.cpp:446
bool IsValid() const
Definition: netaddress.cpp:253
bool IsIPv4() const
Definition: netaddress.cpp:125
bool IsRFC5737() const
Definition: netaddress.cpp:158
static const unsigned char pchOnionCat[]
Definition: netaddress.cpp:13
uint32_t scopeId
Definition: netaddress.h:35
static int GetExtNetwork(const CNetAddr *addr)
Definition: netaddress.cpp:558
bool IsRFC6145() const
Definition: netaddress.cpp:197
bool IsRFC6052() const
Definition: netaddress.cpp:175
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
Definition: netaddress.cpp:693
std::string ToStringIP() const
Definition: netaddress.cpp:333
const char * name
Definition: rest.cpp:41
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:138
friend bool operator<(const CService &a, const CService &b)
Definition: netaddress.cpp:676
std::vector< unsigned char > GetKey() const
Definition: netaddress.cpp:726
static uint32_t ReadBE32(const unsigned char *ptr)
Definition: common.h:56
Network
Definition: netaddress.h:19
static const unsigned char g_internal_prefix[]
Definition: netaddress.cpp:16
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
Definition: hash.h:71
uint32_t Interpret(const std::vector< bool > &asmap, const std::vector< bool > &ip)
Definition: asmap.cpp:78
unsigned int GetByte(int n) const
Definition: netaddress.cpp:110
friend bool operator==(const CSubNet &a, const CSubNet &b)
Definition: netaddress.cpp:888
bool IsRFC3849() const
Definition: netaddress.cpp:165
bool IsRoutable() const
Definition: netaddress.cpp:301
uint64_t GetHash() const
Definition: netaddress.cpp:546
bool valid
Is this value valid? (only used to signal parse errors)
Definition: netaddress.h:115
bool Match(const CNetAddr &addr) const
Definition: netaddress.cpp:815
uint8_t netmask[16]
Netmask, in network byte order.
Definition: netaddress.h:113
static int NetmaskBits(uint8_t x)
Definition: netaddress.cpp:829
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:31
friend bool operator<(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:367
bool IsValid() const
Definition: netaddress.cpp:883
bool IsRFC1918() const
Definition: netaddress.cpp:135
256-bit opaque blob.
Definition: uint256.h:120
bool IsRFC6598() const
Definition: netaddress.cpp:153
bool IsHeNet() const
Definition: netaddress.cpp:213
std::string ToString() const
Definition: netaddress.cpp:845
bool IsRFC3927() const
Definition: netaddress.cpp:148
friend bool operator==(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:362
void * memcpy(void *a, const void *b, size_t c)
std::string ToStringIPPort() const
Definition: netaddress.cpp:741
static const int NET_TEREDO
Definition: netaddress.cpp:557
unsigned char ip[16]
Definition: netaddress.h:34
friend bool operator<(const CSubNet &a, const CSubNet &b)
Definition: netaddress.cpp:893
void SetRaw(Network network, const uint8_t *data)
Set raw IPv4 or IPv6 address (in network byte order)
Definition: netaddress.cpp:33
bool SetSpecial(const std::string &strName)
Try to make this a dummy address that maps the specified onion address into IPv6 using OnionCat&#39;s ran...
Definition: netaddress.cpp:85
bool IsRFC7343() const
Definition: netaddress.cpp:208
std::string ToString() const
Definition: netaddress.cpp:750
bool IsRFC4843() const
Definition: netaddress.cpp:203
bool SanityCheckASMap(const std::vector< bool > &asmap)
Definition: netaddress.cpp:898
uint32_t GetLinkedIPv4() const
For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv...
Definition: netaddress.cpp:414
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:652
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...
Definition: netaddress.cpp:63
A hasher class for SHA-256.
Definition: sha256.h:13
bool IsRFC4193() const
Definition: netaddress.cpp:192
static const unsigned char pchIPv4[12]
Definition: netaddress.cpp:12
uint32_t GetNetClass() const
Definition: netaddress.cpp:429
bool IsTor() const
Definition: netaddress.cpp:224
bool IsRFC3964() const
Definition: netaddress.cpp:170
CNetAddr()
Construct an unspecified IPv6 network address (::/128).
Definition: netaddress.cpp:23