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