ip_address.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. // Copyright (c) 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/base/ip_address.h"
  5. #include <algorithm>
  6. #include <climits>
  7. #include "base/check_op.h"
  8. #include "base/containers/stack_container.h"
  9. #include "base/notreached.h"
  10. #include "base/strings/strcat.h"
  11. #include "base/strings/string_piece.h"
  12. #include "base/strings/string_split.h"
  13. #include "base/strings/stringprintf.h"
  14. #include "net/base/parse_number.h"
  15. #include "url/gurl.h"
  16. #include "url/url_canon_ip.h"
  17. namespace net {
  18. namespace {
  19. // The prefix for IPv6 mapped IPv4 addresses.
  20. // https://tools.ietf.org/html/rfc4291#section-2.5.5.2
  21. constexpr uint8_t kIPv4MappedPrefix[] = {0, 0, 0, 0, 0, 0,
  22. 0, 0, 0, 0, 0xFF, 0xFF};
  23. // Note that this function assumes:
  24. // * |ip_address| is at least |prefix_length_in_bits| (bits) long;
  25. // * |ip_prefix| is at least |prefix_length_in_bits| (bits) long.
  26. bool IPAddressPrefixCheck(const IPAddressBytes& ip_address,
  27. const uint8_t* ip_prefix,
  28. size_t prefix_length_in_bits) {
  29. // Compare all the bytes that fall entirely within the prefix.
  30. size_t num_entire_bytes_in_prefix = prefix_length_in_bits / 8;
  31. for (size_t i = 0; i < num_entire_bytes_in_prefix; ++i) {
  32. if (ip_address[i] != ip_prefix[i])
  33. return false;
  34. }
  35. // In case the prefix was not a multiple of 8, there will be 1 byte
  36. // which is only partially masked.
  37. size_t remaining_bits = prefix_length_in_bits % 8;
  38. if (remaining_bits != 0) {
  39. uint8_t mask = 0xFF << (8 - remaining_bits);
  40. size_t i = num_entire_bytes_in_prefix;
  41. if ((ip_address[i] & mask) != (ip_prefix[i] & mask))
  42. return false;
  43. }
  44. return true;
  45. }
  46. // Returns false if |ip_address| matches any of the reserved IPv4 ranges. This
  47. // method operates on a list of reserved IPv4 ranges. Some ranges are
  48. // consolidated.
  49. // Sources for info:
  50. // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml
  51. // www.iana.org/assignments/iana-ipv4-special-registry/
  52. // iana-ipv4-special-registry.xhtml
  53. bool IsPubliclyRoutableIPv4(const IPAddressBytes& ip_address) {
  54. // Different IP versions have different range reservations.
  55. DCHECK_EQ(IPAddress::kIPv4AddressSize, ip_address.size());
  56. struct {
  57. const uint8_t address[4];
  58. size_t prefix_length_in_bits;
  59. } static const kReservedIPv4Ranges[] = {
  60. {{0, 0, 0, 0}, 8}, {{10, 0, 0, 0}, 8}, {{100, 64, 0, 0}, 10},
  61. {{127, 0, 0, 0}, 8}, {{169, 254, 0, 0}, 16}, {{172, 16, 0, 0}, 12},
  62. {{192, 0, 0, 0}, 24}, {{192, 0, 2, 0}, 24}, {{192, 88, 99, 0}, 24},
  63. {{192, 168, 0, 0}, 16}, {{198, 18, 0, 0}, 15}, {{198, 51, 100, 0}, 24},
  64. {{203, 0, 113, 0}, 24}, {{224, 0, 0, 0}, 3}};
  65. for (const auto& range : kReservedIPv4Ranges) {
  66. if (IPAddressPrefixCheck(ip_address, range.address,
  67. range.prefix_length_in_bits)) {
  68. return false;
  69. }
  70. }
  71. return true;
  72. }
  73. // Returns false if |ip_address| matches any of the IPv6 ranges IANA reserved
  74. // for local networks. This method operates on an allowlist of non-reserved
  75. // IPv6 ranges, plus the list of reserved IPv4 ranges mapped to IPv6.
  76. // Sources for info:
  77. // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
  78. bool IsPubliclyRoutableIPv6(const IPAddressBytes& ip_address) {
  79. DCHECK_EQ(IPAddress::kIPv6AddressSize, ip_address.size());
  80. struct {
  81. const uint8_t address_prefix[2];
  82. size_t prefix_length_in_bits;
  83. } static const kPublicIPv6Ranges[] = {// 2000::/3 -- Global Unicast
  84. {{0x20, 0}, 3},
  85. // ff00::/8 -- Multicast
  86. {{0xff, 0}, 8}};
  87. for (const auto& range : kPublicIPv6Ranges) {
  88. if (IPAddressPrefixCheck(ip_address, range.address_prefix,
  89. range.prefix_length_in_bits)) {
  90. return true;
  91. }
  92. }
  93. IPAddress addr(ip_address);
  94. if (addr.IsIPv4MappedIPv6()) {
  95. IPAddress ipv4 = ConvertIPv4MappedIPv6ToIPv4(addr);
  96. return IsPubliclyRoutableIPv4(ipv4.bytes());
  97. }
  98. return false;
  99. }
  100. bool ParseIPLiteralToBytes(const base::StringPiece& ip_literal,
  101. IPAddressBytes* bytes) {
  102. // |ip_literal| could be either an IPv4 or an IPv6 literal. If it contains
  103. // a colon however, it must be an IPv6 address.
  104. if (ip_literal.find(':') != base::StringPiece::npos) {
  105. // GURL expects IPv6 hostnames to be surrounded with brackets.
  106. std::string host_brackets = base::StrCat({"[", ip_literal, "]"});
  107. url::Component host_comp(0, host_brackets.size());
  108. // Try parsing the hostname as an IPv6 literal.
  109. bytes->Resize(16); // 128 bits.
  110. return url::IPv6AddressToNumber(host_brackets.data(), host_comp,
  111. bytes->data());
  112. }
  113. // Otherwise the string is an IPv4 address.
  114. bytes->Resize(4); // 32 bits.
  115. url::Component host_comp(0, ip_literal.size());
  116. int num_components;
  117. url::CanonHostInfo::Family family = url::IPv4AddressToNumber(
  118. ip_literal.data(), host_comp, bytes->data(), &num_components);
  119. return family == url::CanonHostInfo::IPV4;
  120. }
  121. } // namespace
  122. IPAddressBytes::IPAddressBytes() : size_(0) {}
  123. IPAddressBytes::IPAddressBytes(const uint8_t* data, size_t data_len) {
  124. Assign(data, data_len);
  125. }
  126. IPAddressBytes::~IPAddressBytes() = default;
  127. IPAddressBytes::IPAddressBytes(IPAddressBytes const& other) = default;
  128. void IPAddressBytes::Assign(const uint8_t* data, size_t data_len) {
  129. size_ = data_len;
  130. CHECK_GE(16u, data_len);
  131. std::copy_n(data, data_len, bytes_.data());
  132. }
  133. bool IPAddressBytes::operator<(const IPAddressBytes& other) const {
  134. if (size_ == other.size_)
  135. return std::lexicographical_compare(begin(), end(), other.begin(),
  136. other.end());
  137. return size_ < other.size_;
  138. }
  139. bool IPAddressBytes::operator==(const IPAddressBytes& other) const {
  140. return size_ == other.size_ && std::equal(begin(), end(), other.begin());
  141. }
  142. bool IPAddressBytes::operator!=(const IPAddressBytes& other) const {
  143. return !(*this == other);
  144. }
  145. IPAddress::IPAddress() = default;
  146. IPAddress::IPAddress(const IPAddress& other) = default;
  147. IPAddress::IPAddress(const IPAddressBytes& address) : ip_address_(address) {}
  148. IPAddress::IPAddress(const uint8_t* address, size_t address_len)
  149. : ip_address_(address, address_len) {}
  150. IPAddress::IPAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) {
  151. ip_address_.push_back(b0);
  152. ip_address_.push_back(b1);
  153. ip_address_.push_back(b2);
  154. ip_address_.push_back(b3);
  155. }
  156. IPAddress::IPAddress(uint8_t b0,
  157. uint8_t b1,
  158. uint8_t b2,
  159. uint8_t b3,
  160. uint8_t b4,
  161. uint8_t b5,
  162. uint8_t b6,
  163. uint8_t b7,
  164. uint8_t b8,
  165. uint8_t b9,
  166. uint8_t b10,
  167. uint8_t b11,
  168. uint8_t b12,
  169. uint8_t b13,
  170. uint8_t b14,
  171. uint8_t b15) {
  172. ip_address_.push_back(b0);
  173. ip_address_.push_back(b1);
  174. ip_address_.push_back(b2);
  175. ip_address_.push_back(b3);
  176. ip_address_.push_back(b4);
  177. ip_address_.push_back(b5);
  178. ip_address_.push_back(b6);
  179. ip_address_.push_back(b7);
  180. ip_address_.push_back(b8);
  181. ip_address_.push_back(b9);
  182. ip_address_.push_back(b10);
  183. ip_address_.push_back(b11);
  184. ip_address_.push_back(b12);
  185. ip_address_.push_back(b13);
  186. ip_address_.push_back(b14);
  187. ip_address_.push_back(b15);
  188. }
  189. IPAddress::~IPAddress() = default;
  190. bool IPAddress::IsIPv4() const {
  191. return ip_address_.size() == kIPv4AddressSize;
  192. }
  193. bool IPAddress::IsIPv6() const {
  194. return ip_address_.size() == kIPv6AddressSize;
  195. }
  196. bool IPAddress::IsValid() const {
  197. return IsIPv4() || IsIPv6();
  198. }
  199. bool IPAddress::IsPubliclyRoutable() const {
  200. if (IsIPv4()) {
  201. return IsPubliclyRoutableIPv4(ip_address_);
  202. } else if (IsIPv6()) {
  203. return IsPubliclyRoutableIPv6(ip_address_);
  204. }
  205. return true;
  206. }
  207. bool IPAddress::IsZero() const {
  208. for (auto x : ip_address_) {
  209. if (x != 0)
  210. return false;
  211. }
  212. return !empty();
  213. }
  214. bool IPAddress::IsIPv4MappedIPv6() const {
  215. return IsIPv6() && IPAddressStartsWith(*this, kIPv4MappedPrefix);
  216. }
  217. bool IPAddress::IsLoopback() const {
  218. // 127.0.0.1/8
  219. if (IsIPv4())
  220. return ip_address_[0] == 127;
  221. // ::1
  222. if (IsIPv6()) {
  223. for (size_t i = 0; i + 1 < ip_address_.size(); ++i) {
  224. if (ip_address_[i] != 0)
  225. return false;
  226. }
  227. return ip_address_.back() == 1;
  228. }
  229. return false;
  230. }
  231. bool IPAddress::IsLinkLocal() const {
  232. // 169.254.0.0/16
  233. if (IsIPv4())
  234. return (ip_address_[0] == 169) && (ip_address_[1] == 254);
  235. // [::ffff:169.254.0.0]/112
  236. if (IsIPv4MappedIPv6())
  237. return (ip_address_[12] == 169) && (ip_address_[13] == 254);
  238. // [fe80::]/10
  239. if (IsIPv6())
  240. return (ip_address_[0] == 0xFE) && ((ip_address_[1] & 0xC0) == 0x80);
  241. return false;
  242. }
  243. bool IPAddress::AssignFromIPLiteral(const base::StringPiece& ip_literal) {
  244. bool success = ParseIPLiteralToBytes(ip_literal, &ip_address_);
  245. if (!success)
  246. ip_address_.Resize(0);
  247. return success;
  248. }
  249. std::vector<uint8_t> IPAddress::CopyBytesToVector() const {
  250. return std::vector<uint8_t>(ip_address_.begin(), ip_address_.end());
  251. }
  252. // static
  253. IPAddress IPAddress::IPv4Localhost() {
  254. static const uint8_t kLocalhostIPv4[] = {127, 0, 0, 1};
  255. return IPAddress(kLocalhostIPv4);
  256. }
  257. // static
  258. IPAddress IPAddress::IPv6Localhost() {
  259. static const uint8_t kLocalhostIPv6[] = {0, 0, 0, 0, 0, 0, 0, 0,
  260. 0, 0, 0, 0, 0, 0, 0, 1};
  261. return IPAddress(kLocalhostIPv6);
  262. }
  263. // static
  264. IPAddress IPAddress::AllZeros(size_t num_zero_bytes) {
  265. CHECK_LE(num_zero_bytes, 16u);
  266. IPAddress result;
  267. for (size_t i = 0; i < num_zero_bytes; ++i)
  268. result.ip_address_.push_back(0u);
  269. return result;
  270. }
  271. // static
  272. IPAddress IPAddress::IPv4AllZeros() {
  273. return AllZeros(kIPv4AddressSize);
  274. }
  275. // static
  276. IPAddress IPAddress::IPv6AllZeros() {
  277. return AllZeros(kIPv6AddressSize);
  278. }
  279. bool IPAddress::operator==(const IPAddress& that) const {
  280. return ip_address_ == that.ip_address_;
  281. }
  282. bool IPAddress::operator!=(const IPAddress& that) const {
  283. return ip_address_ != that.ip_address_;
  284. }
  285. bool IPAddress::operator<(const IPAddress& that) const {
  286. // Sort IPv4 before IPv6.
  287. if (ip_address_.size() != that.ip_address_.size()) {
  288. return ip_address_.size() < that.ip_address_.size();
  289. }
  290. return ip_address_ < that.ip_address_;
  291. }
  292. std::string IPAddress::ToString() const {
  293. std::string str;
  294. url::StdStringCanonOutput output(&str);
  295. if (IsIPv4()) {
  296. url::AppendIPv4Address(ip_address_.data(), &output);
  297. } else if (IsIPv6()) {
  298. url::AppendIPv6Address(ip_address_.data(), &output);
  299. }
  300. output.Complete();
  301. return str;
  302. }
  303. std::string IPAddressToStringWithPort(const IPAddress& address, uint16_t port) {
  304. std::string address_str = address.ToString();
  305. if (address_str.empty())
  306. return address_str;
  307. if (address.IsIPv6()) {
  308. // Need to bracket IPv6 addresses since they contain colons.
  309. return base::StringPrintf("[%s]:%d", address_str.c_str(), port);
  310. }
  311. return base::StringPrintf("%s:%d", address_str.c_str(), port);
  312. }
  313. std::string IPAddressToPackedString(const IPAddress& address) {
  314. return std::string(reinterpret_cast<const char*>(address.bytes().data()),
  315. address.size());
  316. }
  317. IPAddress ConvertIPv4ToIPv4MappedIPv6(const IPAddress& address) {
  318. DCHECK(address.IsIPv4());
  319. // IPv4-mapped addresses are formed by:
  320. // <80 bits of zeros> + <16 bits of ones> + <32-bit IPv4 address>.
  321. base::StackVector<uint8_t, 16> bytes;
  322. bytes->insert(bytes->end(), std::begin(kIPv4MappedPrefix),
  323. std::end(kIPv4MappedPrefix));
  324. bytes->insert(bytes->end(), address.bytes().begin(), address.bytes().end());
  325. return IPAddress(bytes->data(), bytes->size());
  326. }
  327. IPAddress ConvertIPv4MappedIPv6ToIPv4(const IPAddress& address) {
  328. DCHECK(address.IsIPv4MappedIPv6());
  329. base::StackVector<uint8_t, 16> bytes;
  330. bytes->insert(bytes->end(),
  331. address.bytes().begin() + std::size(kIPv4MappedPrefix),
  332. address.bytes().end());
  333. return IPAddress(bytes->data(), bytes->size());
  334. }
  335. bool IPAddressMatchesPrefix(const IPAddress& ip_address,
  336. const IPAddress& ip_prefix,
  337. size_t prefix_length_in_bits) {
  338. // Both the input IP address and the prefix IP address should be either IPv4
  339. // or IPv6.
  340. DCHECK(ip_address.IsValid());
  341. DCHECK(ip_prefix.IsValid());
  342. DCHECK_LE(prefix_length_in_bits, ip_prefix.size() * 8);
  343. // In case we have an IPv6 / IPv4 mismatch, convert the IPv4 addresses to
  344. // IPv6 addresses in order to do the comparison.
  345. if (ip_address.size() != ip_prefix.size()) {
  346. if (ip_address.IsIPv4()) {
  347. return IPAddressMatchesPrefix(ConvertIPv4ToIPv4MappedIPv6(ip_address),
  348. ip_prefix, prefix_length_in_bits);
  349. }
  350. return IPAddressMatchesPrefix(ip_address,
  351. ConvertIPv4ToIPv4MappedIPv6(ip_prefix),
  352. 96 + prefix_length_in_bits);
  353. }
  354. return IPAddressPrefixCheck(ip_address.bytes(), ip_prefix.bytes().data(),
  355. prefix_length_in_bits);
  356. }
  357. bool ParseCIDRBlock(base::StringPiece cidr_literal,
  358. IPAddress* ip_address,
  359. size_t* prefix_length_in_bits) {
  360. // We expect CIDR notation to match one of these two templates:
  361. // <IPv4-literal> "/" <number of bits>
  362. // <IPv6-literal> "/" <number of bits>
  363. std::vector<base::StringPiece> parts = base::SplitStringPiece(
  364. cidr_literal, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  365. if (parts.size() != 2)
  366. return false;
  367. // Parse the IP address.
  368. if (!ip_address->AssignFromIPLiteral(parts[0]))
  369. return false;
  370. // Parse the prefix length.
  371. uint32_t number_of_bits;
  372. if (!ParseUint32(parts[1], &number_of_bits))
  373. return false;
  374. // Make sure the prefix length is in a valid range.
  375. if (number_of_bits > ip_address->size() * 8)
  376. return false;
  377. *prefix_length_in_bits = number_of_bits;
  378. return true;
  379. }
  380. bool ParseURLHostnameToAddress(const base::StringPiece& hostname,
  381. IPAddress* ip_address) {
  382. if (hostname.size() >= 2 && hostname.front() == '[' &&
  383. hostname.back() == ']') {
  384. // Strip the square brackets that surround IPv6 literals.
  385. auto ip_literal =
  386. base::StringPiece(hostname).substr(1, hostname.size() - 2);
  387. return ip_address->AssignFromIPLiteral(ip_literal) && ip_address->IsIPv6();
  388. }
  389. return ip_address->AssignFromIPLiteral(hostname) && ip_address->IsIPv4();
  390. }
  391. size_t CommonPrefixLength(const IPAddress& a1, const IPAddress& a2) {
  392. DCHECK_EQ(a1.size(), a2.size());
  393. for (size_t i = 0; i < a1.size(); ++i) {
  394. unsigned diff = a1.bytes()[i] ^ a2.bytes()[i];
  395. if (!diff)
  396. continue;
  397. for (unsigned j = 0; j < CHAR_BIT; ++j) {
  398. if (diff & (1 << (CHAR_BIT - 1)))
  399. return i * CHAR_BIT + j;
  400. diff <<= 1;
  401. }
  402. NOTREACHED();
  403. }
  404. return a1.size() * CHAR_BIT;
  405. }
  406. size_t MaskPrefixLength(const IPAddress& mask) {
  407. base::StackVector<uint8_t, 16> all_ones;
  408. all_ones->resize(mask.size(), 0xFF);
  409. return CommonPrefixLength(mask,
  410. IPAddress(all_ones->data(), all_ones->size()));
  411. }
  412. } // namespace net