Raven Core  3.0.0
P2P Digital Currency
netaddress.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Copyright (c) 2017-2019 The Raven Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config/raven-config.h"
9 #endif
10 
11 #include "netaddress.h"
12 #include "hash.h"
13 #include "utilstrencodings.h"
14 #include "tinyformat.h"
15 
16 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
17 static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
18 
19 // 0xFD + sha256("raven")[0:5]
20 static const unsigned char g_internal_prefix[] = { 0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 };
21 
23 {
24  memset(ip, 0, sizeof(ip));
25  scopeId = 0;
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 
49 bool CNetAddr::SetInternal(const std::string &name)
50 {
51  if (name.empty()) {
52  return false;
53  }
54  unsigned char hash[32] = {};
55  CSHA256().Write((const unsigned char*)name.data(), name.size()).Finalize(hash);
56  memcpy(ip, g_internal_prefix, sizeof(g_internal_prefix));
57  memcpy(ip + sizeof(g_internal_prefix), hash, sizeof(ip) - sizeof(g_internal_prefix));
58  return true;
59 }
60 
61 bool CNetAddr::SetSpecial(const std::string &strName)
62 {
63  if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
64  std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
65  if (vchAddr.size() != 16-sizeof(pchOnionCat))
66  return false;
67  memcpy(ip, pchOnionCat, sizeof(pchOnionCat));
68  for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++)
69  ip[i + sizeof(pchOnionCat)] = vchAddr[i];
70  return true;
71  }
72  return false;
73 }
74 
76 {
77  Init();
78 }
79 
80 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
81 {
82  SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
83 }
84 
85 CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
86 {
87  SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr);
88  scopeId = scope;
89 }
90 
91 unsigned int CNetAddr::GetByte(int n) const
92 {
93  return ip[15-n];
94 }
95 
96 bool CNetAddr::IsIPv4() const
97 {
98  return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
99 }
100 
101 bool CNetAddr::IsIPv6() const
102 {
103  return (!IsIPv4() && !IsTor() && !IsInternal());
104 }
105 
107 {
108  return IsIPv4() && (
109  GetByte(3) == 10 ||
110  (GetByte(3) == 192 && GetByte(2) == 168) ||
111  (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
112 }
113 
115 {
116  return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19);
117 }
118 
120 {
121  return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
122 }
123 
125 {
126  return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127;
127 }
128 
130 {
131  return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
132  (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
133  (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
134 }
135 
137 {
138  return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8;
139 }
140 
142 {
143  return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
144 }
145 
147 {
148  static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0};
149  return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
150 }
151 
153 {
154  return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0);
155 }
156 
158 {
159  static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0};
160  return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
161 }
162 
164 {
165  return ((GetByte(15) & 0xFE) == 0xFC);
166 }
167 
169 {
170  static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0};
171  return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
172 }
173 
175 {
176  return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
177 }
178 
179 bool CNetAddr::IsTor() const
180 {
181  return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
182 }
183 
184 bool CNetAddr::IsLocal() const
185 {
186  // IPv4 loopback
187  if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0))
188  return true;
189 
190  // IPv6 loopback (::1/128)
191  static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
192  if (memcmp(ip, pchLocal, 16) == 0)
193  return true;
194 
195  return false;
196 }
197 
198 bool CNetAddr::IsValid() const
199 {
200  // Cleanup 3-byte shifted addresses caused by garbage in size field
201  // of addr messages from versions before 0.2.9 checksum.
202  // Two consecutive addr messages look like this:
203  // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
204  // so if the first length field is garbled, it reads the second batch
205  // of addr misaligned by 3 bytes.
206  if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
207  return false;
208 
209  // unspecified IPv6 address (::/128)
210  unsigned char ipNone6[16] = {};
211  if (memcmp(ip, ipNone6, 16) == 0)
212  return false;
213 
214  // documentation IPv6 address
215  if (IsRFC3849())
216  return false;
217 
218  if (IsInternal())
219  return false;
220 
221  if (IsIPv4())
222  {
223  // INADDR_NONE
224  uint32_t ipNone = INADDR_NONE;
225  if (memcmp(ip+12, &ipNone, 4) == 0)
226  return false;
227 
228  // 0
229  ipNone = 0;
230  if (memcmp(ip+12, &ipNone, 4) == 0)
231  return false;
232  }
233 
234  return true;
235 }
236 
238 {
239  return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal() || IsInternal());
240 }
241 
243 {
244  return memcmp(ip, g_internal_prefix, sizeof(g_internal_prefix)) == 0;
245 }
246 
248 {
249  if (IsInternal())
250  return NET_INTERNAL;
251 
252  if (!IsRoutable())
253  return NET_UNROUTABLE;
254 
255  if (IsIPv4())
256  return NET_IPV4;
257 
258  if (IsTor())
259  return NET_TOR;
260 
261  return NET_IPV6;
262 }
263 
264 std::string CNetAddr::ToStringIP() const
265 {
266  if (IsTor())
267  return EncodeBase32(&ip[6], 10) + ".onion";
268  if (IsInternal())
269  return EncodeBase32(ip + sizeof(g_internal_prefix), sizeof(ip) - sizeof(g_internal_prefix)) + ".internal";
270  CService serv(*this, 0);
271  struct sockaddr_storage sockaddr;
272  socklen_t socklen = sizeof(sockaddr);
273  if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
274  char name[1025] = "";
275  if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), nullptr, 0, NI_NUMERICHOST))
276  return std::string(name);
277  }
278  if (IsIPv4())
279  return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
280  else
281  return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
282  GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12),
283  GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8),
284  GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4),
285  GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0));
286 }
287 
288 std::string CNetAddr::ToString() const
289 {
290  return ToStringIP();
291 }
292 
293 bool operator==(const CNetAddr& a, const CNetAddr& b)
294 {
295  return (memcmp(a.ip, b.ip, 16) == 0);
296 }
297 
298 bool operator!=(const CNetAddr& a, const CNetAddr& b)
299 {
300  return (memcmp(a.ip, b.ip, 16) != 0);
301 }
302 
303 bool operator<(const CNetAddr& a, const CNetAddr& b)
304 {
305  return (memcmp(a.ip, b.ip, 16) < 0);
306 }
307 
308 bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
309 {
310  if (!IsIPv4())
311  return false;
312  memcpy(pipv4Addr, ip+12, 4);
313  return true;
314 }
315 
316 bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
317 {
318  memcpy(pipv6Addr, ip, 16);
319  return true;
320 }
321 
322 // get canonical identifier of an address' group
323 // no two connections will be attempted to addresses with the same group
324 std::vector<unsigned char> CNetAddr::GetGroup() const
325 {
326  std::vector<unsigned char> vchRet;
327  int nClass = NET_IPV6;
328  int nStartByte = 0;
329  int nBits = 16;
330 
331  // all local addresses belong to the same group
332  if (IsLocal())
333  {
334  nClass = 255;
335  nBits = 0;
336  }
337  // all internal-usage addresses get their own group
338  if (IsInternal())
339  {
340  nClass = NET_INTERNAL;
341  nStartByte = sizeof(g_internal_prefix);
342  nBits = (sizeof(ip) - sizeof(g_internal_prefix)) * 8;
343  }
344  // all other unroutable addresses belong to the same group
345  else if (!IsRoutable())
346  {
347  nClass = NET_UNROUTABLE;
348  nBits = 0;
349  }
350  // for IPv4 addresses, '1' + the 16 higher-order bits of the IP
351  // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
352  else if (IsIPv4() || IsRFC6145() || IsRFC6052())
353  {
354  nClass = NET_IPV4;
355  nStartByte = 12;
356  }
357  // for 6to4 tunnelled addresses, use the encapsulated IPv4 address
358  else if (IsRFC3964())
359  {
360  nClass = NET_IPV4;
361  nStartByte = 2;
362  }
363  // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address
364  else if (IsRFC4380())
365  {
366  vchRet.push_back(NET_IPV4);
367  vchRet.push_back(GetByte(3) ^ 0xFF);
368  vchRet.push_back(GetByte(2) ^ 0xFF);
369  return vchRet;
370  }
371  else if (IsTor())
372  {
373  nClass = NET_TOR;
374  nStartByte = 6;
375  nBits = 4;
376  }
377  // for he.net, use /36 groups
378  else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
379  nBits = 36;
380  // for the rest of the IPv6 network, use /32 groups
381  else
382  nBits = 32;
383 
384  vchRet.push_back(nClass);
385  while (nBits >= 8)
386  {
387  vchRet.push_back(GetByte(15 - nStartByte));
388  nStartByte++;
389  nBits -= 8;
390  }
391  if (nBits > 0)
392  vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
393 
394  return vchRet;
395 }
396 
397 uint64_t CNetAddr::GetHash() const
398 {
399  uint256 hash = Hash(&ip[0], &ip[16]);
400  uint64_t nRet;
401  memcpy(&nRet, &hash, sizeof(nRet));
402  return nRet;
403 }
404 
405 // private extensions to enum Network, only returned by GetExtNetwork,
406 // and only used in GetReachabilityFrom
407 static const int NET_UNKNOWN = NET_MAX + 0;
408 static const int NET_TEREDO = NET_MAX + 1;
409 int static GetExtNetwork(const CNetAddr *addr)
410 {
411  if (addr == nullptr)
412  return NET_UNKNOWN;
413  if (addr->IsRFC4380())
414  return NET_TEREDO;
415  return addr->GetNetwork();
416 }
417 
419 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
420 {
421  enum Reachability {
422  REACH_UNREACHABLE,
423  REACH_DEFAULT,
424  REACH_TEREDO,
425  REACH_IPV6_WEAK,
426  REACH_IPV4,
427  REACH_IPV6_STRONG,
428  REACH_PRIVATE
429  };
430 
431  if (!IsRoutable() || IsInternal())
432  return REACH_UNREACHABLE;
433 
434  int ourNet = GetExtNetwork(this);
435  int theirNet = GetExtNetwork(paddrPartner);
436  bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
437 
438  switch(theirNet) {
439  case NET_IPV4:
440  switch(ourNet) {
441  default: return REACH_DEFAULT;
442  case NET_IPV4: return REACH_IPV4;
443  }
444  case NET_IPV6:
445  switch(ourNet) {
446  default: return REACH_DEFAULT;
447  case NET_TEREDO: return REACH_TEREDO;
448  case NET_IPV4: return REACH_IPV4;
449  case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled
450  }
451  case NET_TOR:
452  switch(ourNet) {
453  default: return REACH_DEFAULT;
454  case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well
455  case NET_TOR: return REACH_PRIVATE;
456  }
457  case NET_TEREDO:
458  switch(ourNet) {
459  default: return REACH_DEFAULT;
460  case NET_TEREDO: return REACH_TEREDO;
461  case NET_IPV6: return REACH_IPV6_WEAK;
462  case NET_IPV4: return REACH_IPV4;
463  }
464  case NET_UNKNOWN:
465  case NET_UNROUTABLE:
466  default:
467  switch(ourNet) {
468  default: return REACH_DEFAULT;
469  case NET_TEREDO: return REACH_TEREDO;
470  case NET_IPV6: return REACH_IPV6_WEAK;
471  case NET_IPV4: return REACH_IPV4;
472  case NET_TOR: return REACH_PRIVATE; // either from Tor, or don't care about our address
473  }
474  }
475 }
476 
478 {
479  port = 0;
480 }
481 
483 {
484  Init();
485 }
486 
487 CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
488 {
489 }
490 
491 CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn)
492 {
493 }
494 
495 CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
496 {
497 }
498 
499 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
500 {
501  assert(addr.sin_family == AF_INET);
502 }
503 
504 CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port))
505 {
506  assert(addr.sin6_family == AF_INET6);
507 }
508 
509 bool CService::SetSockAddr(const struct sockaddr *paddr)
510 {
511  switch (paddr->sa_family) {
512  case AF_INET:
513  *this = CService(*(const struct sockaddr_in*)paddr);
514  return true;
515  case AF_INET6:
516  *this = CService(*(const struct sockaddr_in6*)paddr);
517  return true;
518  default:
519  return false;
520  }
521 }
522 
523 unsigned short CService::GetPort() const
524 {
525  return port;
526 }
527 
528 bool operator==(const CService& a, const CService& b)
529 {
530  return (CNetAddr)a == (CNetAddr)b && a.port == b.port;
531 }
532 
533 bool operator!=(const CService& a, const CService& b)
534 {
535  return (CNetAddr)a != (CNetAddr)b || a.port != b.port;
536 }
537 
538 bool operator<(const CService& a, const CService& b)
539 {
540  return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
541 }
542 
543 bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
544 {
545  if (IsIPv4()) {
546  if (*addrlen < (socklen_t)sizeof(struct sockaddr_in))
547  return false;
548  *addrlen = sizeof(struct sockaddr_in);
549  struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
550  memset(paddrin, 0, *addrlen);
551  if (!GetInAddr(&paddrin->sin_addr))
552  return false;
553  paddrin->sin_family = AF_INET;
554  paddrin->sin_port = htons(port);
555  return true;
556  }
557  if (IsIPv6()) {
558  if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
559  return false;
560  *addrlen = sizeof(struct sockaddr_in6);
561  struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
562  memset(paddrin6, 0, *addrlen);
563  if (!GetIn6Addr(&paddrin6->sin6_addr))
564  return false;
565  paddrin6->sin6_scope_id = scopeId;
566  paddrin6->sin6_family = AF_INET6;
567  paddrin6->sin6_port = htons(port);
568  return true;
569  }
570  return false;
571 }
572 
573 std::vector<unsigned char> CService::GetKey() const
574 {
575  std::vector<unsigned char> vKey;
576  vKey.resize(18);
577  memcpy(vKey.data(), ip, 16);
578  vKey[16] = port / 0x100;
579  vKey[17] = port & 0x0FF;
580  return vKey;
581 }
582 
583 std::string CService::ToStringPort() const
584 {
585  return strprintf("%u", port);
586 }
587 
588 std::string CService::ToStringIPPort() const
589 {
590  if (IsIPv4() || IsTor() || IsInternal()) {
591  return ToStringIP() + ":" + ToStringPort();
592  } else {
593  return "[" + ToStringIP() + "]:" + ToStringPort();
594  }
595 }
596 
597 std::string CService::ToString() const
598 {
599  return ToStringIPPort();
600 }
601 
603  valid(false)
604 {
605  memset(netmask, 0, sizeof(netmask));
606 }
607 
608 CSubNet::CSubNet(const CNetAddr &addr, int32_t mask)
609 {
610  valid = true;
611  network = addr;
612  // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
613  memset(netmask, 255, sizeof(netmask));
614 
615  // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
616  const int astartofs = network.IsIPv4() ? 12 : 0;
617 
618  int32_t n = mask;
619  if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
620  {
621  n += astartofs*8;
622  // Clear bits [n..127]
623  for (; n < 128; ++n)
624  netmask[n>>3] &= ~(1<<(7-(n&7)));
625  } else
626  valid = false;
627 
628  // Normalize network according to netmask
629  for(int x=0; x<16; ++x)
630  network.ip[x] &= netmask[x];
631 }
632 
633 CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask)
634 {
635  valid = true;
636  network = addr;
637  // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
638  memset(netmask, 255, sizeof(netmask));
639 
640  // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
641  const int astartofs = network.IsIPv4() ? 12 : 0;
642 
643  for(int x=astartofs; x<16; ++x)
644  netmask[x] = mask.ip[x];
645 
646  // Normalize network according to netmask
647  for(int x=0; x<16; ++x)
648  network.ip[x] &= netmask[x];
649 }
650 
652  valid(addr.IsValid())
653 {
654  memset(netmask, 255, sizeof(netmask));
655  network = addr;
656 }
657 
658 bool CSubNet::Match(const CNetAddr &addr) const
659 {
660  if (!valid || !addr.IsValid())
661  return false;
662  for(int x=0; x<16; ++x)
663  if ((addr.ip[x] & netmask[x]) != network.ip[x])
664  return false;
665  return true;
666 }
667 
668 static inline int NetmaskBits(uint8_t x)
669 {
670  switch(x) {
671  case 0x00: return 0; break;
672  case 0x80: return 1; break;
673  case 0xc0: return 2; break;
674  case 0xe0: return 3; break;
675  case 0xf0: return 4; break;
676  case 0xf8: return 5; break;
677  case 0xfc: return 6; break;
678  case 0xfe: return 7; break;
679  case 0xff: return 8; break;
680  default: return -1; break;
681  }
682 }
683 
684 std::string CSubNet::ToString() const
685 {
686  /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
687  int cidr = 0;
688  bool valid_cidr = true;
689  int n = network.IsIPv4() ? 12 : 0;
690  for (; n < 16 && netmask[n] == 0xff; ++n)
691  cidr += 8;
692  if (n < 16) {
693  int bits = NetmaskBits(netmask[n]);
694  if (bits < 0)
695  valid_cidr = false;
696  else
697  cidr += bits;
698  ++n;
699  }
700  for (; n < 16 && valid_cidr; ++n)
701  if (netmask[n] != 0x00)
702  valid_cidr = false;
703 
704  /* Format output */
705  std::string strNetmask;
706  if (valid_cidr) {
707  strNetmask = strprintf("%u", cidr);
708  } else {
709  if (network.IsIPv4())
710  strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
711  else
712  strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
713  netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
714  netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
715  netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
716  netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
717  }
718 
719  return network.ToString() + "/" + strNetmask;
720 }
721 
722 bool CSubNet::IsValid() const
723 {
724  return valid;
725 }
726 
727 bool operator==(const CSubNet& a, const CSubNet& b)
728 {
729  return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
730 }
731 
732 bool operator!=(const CSubNet& a, const CSubNet& b)
733 {
734  return !(a==b);
735 }
736 
737 bool operator<(const CSubNet& a, const CSubNet& b)
738 {
739  return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));
740 }
int GetReachabilityFrom(const CNetAddr *paddrPartner=nullptr) const
Calculates a metric for how reachable (*this) is from a given partner.
Definition: netaddress.cpp:419
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:202
std::string ToStringPort() const
Definition: netaddress.cpp:583
unsigned short GetPort() const
Definition: netaddress.cpp:523
bool IsLocal() const
Definition: netaddress.cpp:184
bool IsRFC4380() const
Definition: netaddress.cpp:152
void SetIP(const CNetAddr &ip)
Definition: netaddress.cpp:28
#define strprintf
Definition: tinyformat.h:1054
bool IsIPv6() const
Definition: netaddress.cpp:101
void Init()
Definition: netaddress.cpp:477
friend bool operator==(const CService &a, const CService &b)
Definition: netaddress.cpp:528
bool IsInternal() const
Definition: netaddress.cpp:242
CNetAddr network
Network (base) address.
Definition: netaddress.h:107
bool GetInAddr(struct in_addr *pipv4Addr) const
Definition: netaddress.cpp:308
std::string ToString() const
Definition: netaddress.cpp:288
bool GetIn6Addr(struct in6_addr *pipv6Addr) const
Definition: netaddress.cpp:316
enum Network GetNetwork() const
Definition: netaddress.cpp:247
bool IsRFC2544() const
Definition: netaddress.cpp:114
bool IsRFC4862() const
Definition: netaddress.cpp:157
bool IsValid() const
Definition: netaddress.cpp:198
std::vector< unsigned char > GetGroup() const
Definition: netaddress.cpp:324
friend bool operator!=(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:298
friend bool operator!=(const CSubNet &a, const CSubNet &b)
Definition: netaddress.cpp:732
bool IsIPv4() const
Definition: netaddress.cpp:96
bool IsRFC5737() const
Definition: netaddress.cpp:129
uint32_t scopeId
Definition: netaddress.h:36
bool IsRFC6145() const
Definition: netaddress.cpp:168
bool IsRFC6052() const
Definition: netaddress.cpp:146
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Definition: netaddress.cpp:543
friend bool operator!=(const CService &a, const CService &b)
Definition: netaddress.cpp:533
std::string ToStringIP() const
Definition: netaddress.cpp:264
std::vector< unsigned char > DecodeBase32(const char *p, bool *pfInvalid)
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:141
unsigned short port
Definition: netaddress.h:144
friend bool operator<(const CService &a, const CService &b)
Definition: netaddress.cpp:538
std::vector< unsigned char > GetKey() const
Definition: netaddress.cpp:573
Network
Definition: netaddress.h:20
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
Definition: hash.h:125
void Init()
Definition: netaddress.cpp:22
unsigned int GetByte(int n) const
Definition: netaddress.cpp:91
friend bool operator==(const CSubNet &a, const CSubNet &b)
Definition: netaddress.cpp:727
bool IsRFC3849() const
Definition: netaddress.cpp:136
bool IsRoutable() const
Definition: netaddress.cpp:237
uint64_t GetHash() const
Definition: netaddress.cpp:397
bool valid
Is this value valid? (only used to signal parse errors)
Definition: netaddress.h:111
bool Match(const CNetAddr &addr) const
Definition: netaddress.cpp:658
uint8_t netmask[16]
Netmask, in network byte order.
Definition: netaddress.h:109
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:32
friend bool operator<(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:303
bool IsValid() const
Definition: netaddress.cpp:722
bool IsRFC1918() const
Definition: netaddress.cpp:106
256-bit opaque blob.
Definition: uint256.h:123
bool IsRFC6598() const
Definition: netaddress.cpp:124
std::string ToString() const
Definition: netaddress.cpp:684
bool IsRFC3927() const
Definition: netaddress.cpp:119
friend bool operator==(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:293
void * memcpy(void *a, const void *b, size_t c)
std::string ToStringIPPort() const
Definition: netaddress.cpp:588
unsigned char ip[16]
Definition: netaddress.h:35
friend bool operator<(const CSubNet &a, const CSubNet &b)
Definition: netaddress.cpp:737
void SetRaw(Network network, const uint8_t *data)
Set raw IPv4 or IPv6 address (in network byte order)
Definition: netaddress.cpp:33
std::string EncodeBase32(const unsigned char *pch, size_t len)
bool SetSpecial(const std::string &strName)
Definition: netaddress.cpp:61
std::string ToString() const
Definition: netaddress.cpp:597
bool IsRFC4843() const
Definition: netaddress.cpp:174
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:509
bool SetInternal(const std::string &name)
Transform an arbitrary string into a non-routable ipv6 address.
Definition: netaddress.cpp:49
A hasher class for SHA-256.
Definition: sha256.h:14
bool IsRFC4193() const
Definition: netaddress.cpp:163
bool IsTor() const
Definition: netaddress.cpp:179
bool IsRFC3964() const
Definition: netaddress.cpp:141