Merge #10197: [tests] Functional test warnings
[bitcoinplatinum.git] / src / netaddress.cpp
blobab07270f3f9087e355e1799de6a38c10a2509091
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #ifdef HAVE_CONFIG_H
7 #include "config/bitcoin-config.h"
8 #endif
10 #include "netaddress.h"
11 #include "hash.h"
12 #include "utilstrencodings.h"
13 #include "tinyformat.h"
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};
18 void CNetAddr::Init()
20 memset(ip, 0, sizeof(ip));
21 scopeId = 0;
24 void CNetAddr::SetIP(const CNetAddr& ipIn)
26 memcpy(ip, ipIn.ip, sizeof(ip));
29 void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
31 switch(network)
33 case NET_IPV4:
34 memcpy(ip, pchIPv4, 12);
35 memcpy(ip+12, ip_in, 4);
36 break;
37 case NET_IPV6:
38 memcpy(ip, ip_in, 16);
39 break;
40 default:
41 assert(!"invalid network");
45 bool CNetAddr::SetSpecial(const std::string &strName)
47 if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
48 std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
49 if (vchAddr.size() != 16-sizeof(pchOnionCat))
50 return false;
51 memcpy(ip, pchOnionCat, sizeof(pchOnionCat));
52 for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++)
53 ip[i + sizeof(pchOnionCat)] = vchAddr[i];
54 return true;
56 return false;
59 CNetAddr::CNetAddr()
61 Init();
64 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
66 SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
69 CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
71 SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr);
72 scopeId = scope;
75 unsigned int CNetAddr::GetByte(int n) const
77 return ip[15-n];
80 bool CNetAddr::IsIPv4() const
82 return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
85 bool CNetAddr::IsIPv6() const
87 return (!IsIPv4() && !IsTor());
90 bool CNetAddr::IsRFC1918() const
92 return IsIPv4() && (
93 GetByte(3) == 10 ||
94 (GetByte(3) == 192 && GetByte(2) == 168) ||
95 (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
98 bool CNetAddr::IsRFC2544() const
100 return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19);
103 bool CNetAddr::IsRFC3927() const
105 return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
108 bool CNetAddr::IsRFC6598() const
110 return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127;
113 bool CNetAddr::IsRFC5737() const
115 return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
116 (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
117 (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
120 bool CNetAddr::IsRFC3849() const
122 return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8;
125 bool CNetAddr::IsRFC3964() const
127 return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
130 bool CNetAddr::IsRFC6052() const
132 static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0};
133 return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
136 bool CNetAddr::IsRFC4380() const
138 return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0);
141 bool CNetAddr::IsRFC4862() const
143 static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0};
144 return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
147 bool CNetAddr::IsRFC4193() const
149 return ((GetByte(15) & 0xFE) == 0xFC);
152 bool CNetAddr::IsRFC6145() const
154 static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0};
155 return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
158 bool CNetAddr::IsRFC4843() const
160 return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
163 bool CNetAddr::IsTor() const
165 return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
168 bool CNetAddr::IsLocal() const
170 // IPv4 loopback
171 if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0))
172 return true;
174 // IPv6 loopback (::1/128)
175 static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
176 if (memcmp(ip, pchLocal, 16) == 0)
177 return true;
179 return false;
182 bool CNetAddr::IsMulticast() const
184 return (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0)
185 || (GetByte(15) == 0xFF);
188 bool CNetAddr::IsValid() const
190 // Cleanup 3-byte shifted addresses caused by garbage in size field
191 // of addr messages from versions before 0.2.9 checksum.
192 // Two consecutive addr messages look like this:
193 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
194 // so if the first length field is garbled, it reads the second batch
195 // of addr misaligned by 3 bytes.
196 if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
197 return false;
199 // unspecified IPv6 address (::/128)
200 unsigned char ipNone6[16] = {};
201 if (memcmp(ip, ipNone6, 16) == 0)
202 return false;
204 // documentation IPv6 address
205 if (IsRFC3849())
206 return false;
208 if (IsIPv4())
210 // INADDR_NONE
211 uint32_t ipNone = INADDR_NONE;
212 if (memcmp(ip+12, &ipNone, 4) == 0)
213 return false;
215 // 0
216 ipNone = 0;
217 if (memcmp(ip+12, &ipNone, 4) == 0)
218 return false;
221 return true;
224 bool CNetAddr::IsRoutable() const
226 return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal());
229 enum Network CNetAddr::GetNetwork() const
231 if (!IsRoutable())
232 return NET_UNROUTABLE;
234 if (IsIPv4())
235 return NET_IPV4;
237 if (IsTor())
238 return NET_TOR;
240 return NET_IPV6;
243 std::string CNetAddr::ToStringIP() const
245 if (IsTor())
246 return EncodeBase32(&ip[6], 10) + ".onion";
247 CService serv(*this, 0);
248 struct sockaddr_storage sockaddr;
249 socklen_t socklen = sizeof(sockaddr);
250 if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
251 char name[1025] = "";
252 if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST))
253 return std::string(name);
255 if (IsIPv4())
256 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
257 else
258 return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
259 GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12),
260 GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8),
261 GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4),
262 GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0));
265 std::string CNetAddr::ToString() const
267 return ToStringIP();
270 bool operator==(const CNetAddr& a, const CNetAddr& b)
272 return (memcmp(a.ip, b.ip, 16) == 0);
275 bool operator!=(const CNetAddr& a, const CNetAddr& b)
277 return (memcmp(a.ip, b.ip, 16) != 0);
280 bool operator<(const CNetAddr& a, const CNetAddr& b)
282 return (memcmp(a.ip, b.ip, 16) < 0);
285 bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
287 if (!IsIPv4())
288 return false;
289 memcpy(pipv4Addr, ip+12, 4);
290 return true;
293 bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
295 memcpy(pipv6Addr, ip, 16);
296 return true;
299 // get canonical identifier of an address' group
300 // no two connections will be attempted to addresses with the same group
301 std::vector<unsigned char> CNetAddr::GetGroup() const
303 std::vector<unsigned char> vchRet;
304 int nClass = NET_IPV6;
305 int nStartByte = 0;
306 int nBits = 16;
308 // all local addresses belong to the same group
309 if (IsLocal())
311 nClass = 255;
312 nBits = 0;
315 // all unroutable addresses belong to the same group
316 if (!IsRoutable())
318 nClass = NET_UNROUTABLE;
319 nBits = 0;
321 // for IPv4 addresses, '1' + the 16 higher-order bits of the IP
322 // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
323 else if (IsIPv4() || IsRFC6145() || IsRFC6052())
325 nClass = NET_IPV4;
326 nStartByte = 12;
328 // for 6to4 tunnelled addresses, use the encapsulated IPv4 address
329 else if (IsRFC3964())
331 nClass = NET_IPV4;
332 nStartByte = 2;
334 // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address
335 else if (IsRFC4380())
337 vchRet.push_back(NET_IPV4);
338 vchRet.push_back(GetByte(3) ^ 0xFF);
339 vchRet.push_back(GetByte(2) ^ 0xFF);
340 return vchRet;
342 else if (IsTor())
344 nClass = NET_TOR;
345 nStartByte = 6;
346 nBits = 4;
348 // for he.net, use /36 groups
349 else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
350 nBits = 36;
351 // for the rest of the IPv6 network, use /32 groups
352 else
353 nBits = 32;
355 vchRet.push_back(nClass);
356 while (nBits >= 8)
358 vchRet.push_back(GetByte(15 - nStartByte));
359 nStartByte++;
360 nBits -= 8;
362 if (nBits > 0)
363 vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
365 return vchRet;
368 uint64_t CNetAddr::GetHash() const
370 uint256 hash = Hash(&ip[0], &ip[16]);
371 uint64_t nRet;
372 memcpy(&nRet, &hash, sizeof(nRet));
373 return nRet;
376 // private extensions to enum Network, only returned by GetExtNetwork,
377 // and only used in GetReachabilityFrom
378 static const int NET_UNKNOWN = NET_MAX + 0;
379 static const int NET_TEREDO = NET_MAX + 1;
380 int static GetExtNetwork(const CNetAddr *addr)
382 if (addr == NULL)
383 return NET_UNKNOWN;
384 if (addr->IsRFC4380())
385 return NET_TEREDO;
386 return addr->GetNetwork();
389 /** Calculates a metric for how reachable (*this) is from a given partner */
390 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
392 enum Reachability {
393 REACH_UNREACHABLE,
394 REACH_DEFAULT,
395 REACH_TEREDO,
396 REACH_IPV6_WEAK,
397 REACH_IPV4,
398 REACH_IPV6_STRONG,
399 REACH_PRIVATE
402 if (!IsRoutable())
403 return REACH_UNREACHABLE;
405 int ourNet = GetExtNetwork(this);
406 int theirNet = GetExtNetwork(paddrPartner);
407 bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
409 switch(theirNet) {
410 case NET_IPV4:
411 switch(ourNet) {
412 default: return REACH_DEFAULT;
413 case NET_IPV4: return REACH_IPV4;
415 case NET_IPV6:
416 switch(ourNet) {
417 default: return REACH_DEFAULT;
418 case NET_TEREDO: return REACH_TEREDO;
419 case NET_IPV4: return REACH_IPV4;
420 case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled
422 case NET_TOR:
423 switch(ourNet) {
424 default: return REACH_DEFAULT;
425 case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well
426 case NET_TOR: return REACH_PRIVATE;
428 case NET_TEREDO:
429 switch(ourNet) {
430 default: return REACH_DEFAULT;
431 case NET_TEREDO: return REACH_TEREDO;
432 case NET_IPV6: return REACH_IPV6_WEAK;
433 case NET_IPV4: return REACH_IPV4;
435 case NET_UNKNOWN:
436 case NET_UNROUTABLE:
437 default:
438 switch(ourNet) {
439 default: return REACH_DEFAULT;
440 case NET_TEREDO: return REACH_TEREDO;
441 case NET_IPV6: return REACH_IPV6_WEAK;
442 case NET_IPV4: return REACH_IPV4;
443 case NET_TOR: return REACH_PRIVATE; // either from Tor, or don't care about our address
448 void CService::Init()
450 port = 0;
453 CService::CService()
455 Init();
458 CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
462 CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn)
466 CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
470 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
472 assert(addr.sin_family == AF_INET);
475 CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port))
477 assert(addr.sin6_family == AF_INET6);
480 bool CService::SetSockAddr(const struct sockaddr *paddr)
482 switch (paddr->sa_family) {
483 case AF_INET:
484 *this = CService(*(const struct sockaddr_in*)paddr);
485 return true;
486 case AF_INET6:
487 *this = CService(*(const struct sockaddr_in6*)paddr);
488 return true;
489 default:
490 return false;
494 unsigned short CService::GetPort() const
496 return port;
499 bool operator==(const CService& a, const CService& b)
501 return (CNetAddr)a == (CNetAddr)b && a.port == b.port;
504 bool operator!=(const CService& a, const CService& b)
506 return (CNetAddr)a != (CNetAddr)b || a.port != b.port;
509 bool operator<(const CService& a, const CService& b)
511 return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
514 bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
516 if (IsIPv4()) {
517 if (*addrlen < (socklen_t)sizeof(struct sockaddr_in))
518 return false;
519 *addrlen = sizeof(struct sockaddr_in);
520 struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
521 memset(paddrin, 0, *addrlen);
522 if (!GetInAddr(&paddrin->sin_addr))
523 return false;
524 paddrin->sin_family = AF_INET;
525 paddrin->sin_port = htons(port);
526 return true;
528 if (IsIPv6()) {
529 if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
530 return false;
531 *addrlen = sizeof(struct sockaddr_in6);
532 struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
533 memset(paddrin6, 0, *addrlen);
534 if (!GetIn6Addr(&paddrin6->sin6_addr))
535 return false;
536 paddrin6->sin6_scope_id = scopeId;
537 paddrin6->sin6_family = AF_INET6;
538 paddrin6->sin6_port = htons(port);
539 return true;
541 return false;
544 std::vector<unsigned char> CService::GetKey() const
546 std::vector<unsigned char> vKey;
547 vKey.resize(18);
548 memcpy(&vKey[0], ip, 16);
549 vKey[16] = port / 0x100;
550 vKey[17] = port & 0x0FF;
551 return vKey;
554 std::string CService::ToStringPort() const
556 return strprintf("%u", port);
559 std::string CService::ToStringIPPort() const
561 if (IsIPv4() || IsTor()) {
562 return ToStringIP() + ":" + ToStringPort();
563 } else {
564 return "[" + ToStringIP() + "]:" + ToStringPort();
568 std::string CService::ToString() const
570 return ToStringIPPort();
573 void CService::SetPort(unsigned short portIn)
575 port = portIn;
578 CSubNet::CSubNet():
579 valid(false)
581 memset(netmask, 0, sizeof(netmask));
584 CSubNet::CSubNet(const CNetAddr &addr, int32_t mask)
586 valid = true;
587 network = addr;
588 // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
589 memset(netmask, 255, sizeof(netmask));
591 // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
592 const int astartofs = network.IsIPv4() ? 12 : 0;
594 int32_t n = mask;
595 if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
597 n += astartofs*8;
598 // Clear bits [n..127]
599 for (; n < 128; ++n)
600 netmask[n>>3] &= ~(1<<(7-(n&7)));
601 } else
602 valid = false;
604 // Normalize network according to netmask
605 for(int x=0; x<16; ++x)
606 network.ip[x] &= netmask[x];
609 CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask)
611 valid = true;
612 network = addr;
613 // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
614 memset(netmask, 255, sizeof(netmask));
616 // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
617 const int astartofs = network.IsIPv4() ? 12 : 0;
619 for(int x=astartofs; x<16; ++x)
620 netmask[x] = mask.ip[x];
622 // Normalize network according to netmask
623 for(int x=0; x<16; ++x)
624 network.ip[x] &= netmask[x];
627 CSubNet::CSubNet(const CNetAddr &addr):
628 valid(addr.IsValid())
630 memset(netmask, 255, sizeof(netmask));
631 network = addr;
634 bool CSubNet::Match(const CNetAddr &addr) const
636 if (!valid || !addr.IsValid())
637 return false;
638 for(int x=0; x<16; ++x)
639 if ((addr.ip[x] & netmask[x]) != network.ip[x])
640 return false;
641 return true;
644 static inline int NetmaskBits(uint8_t x)
646 switch(x) {
647 case 0x00: return 0; break;
648 case 0x80: return 1; break;
649 case 0xc0: return 2; break;
650 case 0xe0: return 3; break;
651 case 0xf0: return 4; break;
652 case 0xf8: return 5; break;
653 case 0xfc: return 6; break;
654 case 0xfe: return 7; break;
655 case 0xff: return 8; break;
656 default: return -1; break;
660 std::string CSubNet::ToString() const
662 /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
663 int cidr = 0;
664 bool valid_cidr = true;
665 int n = network.IsIPv4() ? 12 : 0;
666 for (; n < 16 && netmask[n] == 0xff; ++n)
667 cidr += 8;
668 if (n < 16) {
669 int bits = NetmaskBits(netmask[n]);
670 if (bits < 0)
671 valid_cidr = false;
672 else
673 cidr += bits;
674 ++n;
676 for (; n < 16 && valid_cidr; ++n)
677 if (netmask[n] != 0x00)
678 valid_cidr = false;
680 /* Format output */
681 std::string strNetmask;
682 if (valid_cidr) {
683 strNetmask = strprintf("%u", cidr);
684 } else {
685 if (network.IsIPv4())
686 strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
687 else
688 strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
689 netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
690 netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
691 netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
692 netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
695 return network.ToString() + "/" + strNetmask;
698 bool CSubNet::IsValid() const
700 return valid;
703 bool operator==(const CSubNet& a, const CSubNet& b)
705 return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
708 bool operator!=(const CSubNet& a, const CSubNet& b)
710 return !(a==b);
713 bool operator<(const CSubNet& a, const CSubNet& b)
715 return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));