15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <errno.h> 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string.h> 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iterator> 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <set> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iphlpapi.h> 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <winsock2.h> 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <ws2bth.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "iphlpapi.lib") 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <netdb.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netinet/in.h> 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <unistd.h> 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if !defined(OS_NACL) 28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include <net/if.h> 29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if !defined(OS_ANDROID) 30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include <ifaddrs.h> 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif // !defined(OS_NACL) 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif // !defined(OS_ANDROID) 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif // defined(OS_POSIX) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/string_escape.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 395e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 425e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 435e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_byteorder.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_canon.h" 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_canon_ip.h" 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_parse.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/dns_util.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_module.h" 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/grit/net_resources.h" 55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "net/http/http_content_disposition.h" 56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_ANDROID) 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "net/android/network_library.h" 59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/winsock_init.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The general list of blocked ports. Will be blocked unless a specific 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// protocol overrides it. (Ex: ftp can use ports 20 and 21) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kRestrictedPorts[] = { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // tcpmux 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7, // echo 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9, // discard 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11, // systat 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13, // daytime 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15, // netstat 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17, // qotd 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19, // chargen 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20, // ftp data 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21, // ftp access 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22, // ssh 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23, // telnet 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25, // smtp 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37, // time 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42, // name 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43, // nicname 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53, // domain 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77, // priv-rjs 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79, // finger 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87, // ttylink 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95, // supdup 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101, // hostriame 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102, // iso-tsap 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103, // gppitnp 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 104, // acr-nema 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 109, // pop2 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110, // pop3 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111, // sunrpc 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 113, // auth 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115, // sftp 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117, // uucp-path 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 119, // nntp 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 123, // NTP 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135, // loc-srv /epmap 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139, // netbios 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 143, // imap2 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179, // BGP 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 389, // ldap 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465, // smtp+ssl 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 512, // print / exec 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 513, // login 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 514, // shell 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515, // printer 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 526, // tempo 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 530, // courier 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 531, // chat 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532, // netnews 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 540, // uucp 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 556, // remotefs 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 563, // nntp+ssl 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 587, // stmp? 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601, // ?? 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 636, // ldap+ssl 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 993, // ldap+ssl 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995, // pop3+ssl 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2049, // nfs 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3659, // apple-sasl / PasswordServer 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045, // lockd 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6000, // X11 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665, // Alternate IRC [Apple addition] 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6666, // Alternate IRC [Apple addition] 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6667, // Standard IRC [Apple addition] 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6668, // Alternate IRC [Apple addition] 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6669, // Alternate IRC [Apple addition] 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0xFFFF, // Used to block all invalid port numbers (see 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // third_party/WebKit/Source/platform/weborigin/KURL.cpp, 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // KURL::port()) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FTP overrides the following restricted ports. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAllowedFtpPorts[] = { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21, // ftp data 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22, // ssh 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IPNumberPrefixCheck(const IPAddressNumber& ip_number, 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const unsigned char* ip_prefix, 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t prefix_length_in_bits) { 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Compare all the bytes that fall entirely within the prefix. 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int num_entire_bytes_in_prefix = prefix_length_in_bits / 8; 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (int i = 0; i < num_entire_bytes_in_prefix; ++i) { 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (ip_number[i] != ip_prefix[i]) 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // In case the prefix was not a multiple of 8, there will be 1 byte 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // which is only partially masked. 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int remaining_bits = prefix_length_in_bits % 8; 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (remaining_bits != 0) { 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) unsigned char mask = 0xFF << (8 - remaining_bits); 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int i = num_entire_bytes_in_prefix; 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if ((ip_number[i] & mask) != (ip_prefix[i] & mask)) 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::LazyInstance<std::multiset<int> >::Leaky 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_explicitly_allowed_ports = LAZY_INSTANCE_INITIALIZER; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetCountOfExplicitlyAllowedPorts() { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_explicitly_allowed_ports.Get().size(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetSpecificHeader(const std::string& headers, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to grab the Value from the "Key: Value" pairs in the headers, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which should look like this (no leading spaces, \n-separated) (we format 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them this way in url_request_inet.cc): 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HTTP/1.1 200 OK\n 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ETag: "6d0b8-947-24f35ec0"\n 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Content-Length: 2375\n 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Content-Type: text/html; charset=UTF-8\n 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Last-Modified: Sun, 03 Sep 2006 04:34:43 GMT\n 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers.empty()) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string match('\n' + name + ':'); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator begin = 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::search(headers.begin(), headers.end(), match.begin(), match.end(), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CaseInsensitiveCompareASCII<char>()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (begin == headers.end()) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin += match.length(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ret; 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TrimWhitespace(std::string(begin, 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::find(begin, headers.end(), '\n')), 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TRIM_ALL, &ret); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CanonicalizeHost(const std::string& host, 2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::CanonHostInfo* host_info) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to canonicalize the host. 2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const url::Component raw_host_component(0, static_cast<int>(host.length())); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string canon_host; 2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::StdStringCanonOutput canon_host_output(&canon_host); 2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::CanonicalizeHostVerbose(host.c_str(), raw_host_component, 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &canon_host_output, host_info); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_info->out_host.is_nonempty() && 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu host_info->family != url::CanonHostInfo::BROKEN) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Success! Assert that there's no extra garbage. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canon_host_output.Complete(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(host_info->out_host.len, static_cast<int>(canon_host.length())); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty host, or canonicalization failed. We'll return empty. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canon_host.clear(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canon_host; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string GetDirectoryListingHeader(const base::string16& title) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::StringPiece header( 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetModule::GetResource(IDR_DIR_HEADER_HTML)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be null in unit tests. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_IF(WARNING, header.empty()) << 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing resource: directory listing header"; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string result; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!header.empty()) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.assign(header.data(), header.size()); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append("<script>start("); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::EscapeJSONString(title, true, &result); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(");</script>\n"); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochinline bool IsHostCharAlphanumeric(char c) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can just check lowercase because uppercase characters have already been 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // normalized. 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsCanonicalizedHostCompliant(const std::string& host, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& desired_tld) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host.empty()) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool in_component = false; 260558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch bool most_recent_component_started_alphanumeric = false; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool last_char_was_underscore = false; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::string::const_iterator i(host.begin()); i != host.end(); ++i) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char c = *i; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!in_component) { 266558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c); 267558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!most_recent_component_started_alphanumeric && (c != '-')) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_component = true; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (c == '.') { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_char_was_underscore) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_component = false; 275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } else if (IsHostCharAlphanumeric(c) || (c == '-')) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_char_was_underscore = false; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (c == '_') { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_char_was_underscore = true; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return most_recent_component_started_alphanumeric || 286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (!desired_tld.empty() && IsHostCharAlphanumeric(desired_tld[0])); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 StripWWW(const base::string16& text) { 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16 www(base::ASCIIToUTF16("www.")); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StartsWith(text, www, true) ? text.substr(www.length()) : text; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 StripWWWFromHost(const GURL& url) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(url.is_valid()); 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return StripWWW(base::ASCIIToUTF16(url.host())); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsPortAllowedByDefault(int port) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int array_size = arraysize(kRestrictedPorts); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < array_size; i++) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kRestrictedPorts[i] == port) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsPortAllowedByFtp(int port) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int array_size = arraysize(kAllowedFtpPorts); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < array_size; i++) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kAllowedFtpPorts[i] == port) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Port not explicitly allowed by FTP, so return the default restrictions. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsPortAllowedByDefault(port); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsPortAllowedByOverride(int port) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_explicitly_allowed_ports.Get().empty()) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_explicitly_allowed_ports.Get().count(port) > 0; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SetNonBlocking(int fd) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long no_block = 1; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ioctlsocket(fd, FIONBIO, &no_block); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = fcntl(fd, F_GETFL, 0); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (-1 == flags) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return flags; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fcntl(fd, F_SETFL, flags | O_NONBLOCK); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseHostAndPort(std::string::const_iterator host_and_port_begin, 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator host_and_port_end, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* host, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* port) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_and_port_begin >= host_and_port_end) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // When using url, we use char*. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* auth_begin = &(*host_and_port_begin); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int auth_len = host_and_port_end - host_and_port_begin; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component auth_component(0, auth_len); 3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component username_component; 3525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component password_component; 3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component hostname_component; 3545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component port_component; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::ParseAuthority(auth_begin, auth_component, &username_component, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &password_component, &hostname_component, &port_component); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There shouldn't be a username/password. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (username_component.is_valid() || password_component.is_valid()) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hostname_component.is_nonempty()) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Failed parsing. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int parsed_port_number = -1; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (port_component.is_nonempty()) { 3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu parsed_port_number = url::ParsePort(auth_begin, port_component); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If parsing failed, port_number will be either PORT_INVALID or 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PORT_UNSPECIFIED, both of which are negative. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_port_number < 0) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Failed parsing the port number. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (port_component.len == 0) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Reject inputs like "foo:" 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned char tmp_ipv6_addr[16]; 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the hostname starts with a bracket, it is either an IPv6 literal or 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // invalid. If it is an IPv6 literal then strip the brackets. 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (hostname_component.len > 0 && 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci auth_begin[hostname_component.begin] == '[') { 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (auth_begin[hostname_component.end() - 1] == ']' && 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url::IPv6AddressToNumber( 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci auth_begin, hostname_component, tmp_ipv6_addr)) { 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Strip the brackets. 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci hostname_component.begin++; 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci hostname_component.len -= 2; 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pass results back to caller. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->assign(auth_begin + hostname_component.begin, hostname_component.len); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = parsed_port_number; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // Success. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseHostAndPort(const std::string& host_and_port, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* host, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* port) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ParseHostAndPort( 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_and_port.begin(), host_and_port.end(), host, port); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetHostAndPort(const GURL& url) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For IPv6 literals, GURL::host() already includes the brackets so it is 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // safe to just append a colon. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPrintf("%s:%d", url.host().c_str(), 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.EffectiveIntPort()); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetHostAndOptionalPort(const GURL& url) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For IPv6 literals, GURL::host() already includes the brackets 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so it is safe to just append a colon. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.has_port()) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPrintf("%s:%s", url.host().c_str(), url.port().c_str()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url.host(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool IsHostnameNonUnique(const std::string& hostname) { 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string host_or_ip = hostname.find(':') != std::string::npos ? 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "[" + hostname + "]" : hostname; 4295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::CanonHostInfo host_info; 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string canonical_name = CanonicalizeHost(host_or_ip, &host_info); 431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // If canonicalization fails, then the input is truly malformed. However, 433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // to avoid mis-reporting bad inputs as "non-unique", treat them as unique. 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (canonical_name.empty()) 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If |hostname| is an IP address, check to see if it's in an IANA-reserved 4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // range. 4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (host_info.IsIPAddress()) { 4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IPAddressNumber host_addr; 4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!ParseIPLiteralToNumber(hostname.substr(host_info.out_host.begin, 4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) host_info.out_host.len), 4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &host_addr)) { 4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (host_info.family) { 4475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case url::CanonHostInfo::IPV4: 4485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case url::CanonHostInfo::IPV6: 4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return IsIPAddressReserved(host_addr); 4505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case url::CanonHostInfo::NEUTRAL: 4515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case url::CanonHostInfo::BROKEN: 4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Check for a registry controlled portion of |hostname|, ignoring private 457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // registries, as they already chain to ICANN-administered registries, 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // and explicitly ignoring unknown registries. 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Note: This means that as new gTLDs are introduced on the Internet, they 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // will be treated as non-unique until the registry controlled domain list 462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // is updated. However, because gTLDs are expected to provide significant 463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // advance notice to deprecate older versions of this code, this an 464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // acceptable tradeoff. 465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return 0 == registry_controlled_domains::GetRegistryLength( 466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) canonical_name, 467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, 468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); 469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Don't compare IPv4 and IPv6 addresses (they have different range 4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// reservations). Keep separate reservation arrays for each IP type, and 4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// consolidate adjacent reserved ranges within a reservation array when 4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// possible. 4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Sources for info: 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml 4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml 4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// They're formatted here with the prefix as the last element. For example: 4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10. 4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IsIPAddressReserved(const IPAddressNumber& host_addr) { 4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned char kReservedIPv4[][5] = { 4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0,0,0,0,8 }, { 10,0,0,0,8 }, { 100,64,0,0,10 }, { 127,0,0,0,8 }, 4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 169,254,0,0,16 }, { 172,16,0,0,12 }, { 192,0,2,0,24 }, 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 192,88,99,0,24 }, { 192,168,0,0,16 }, { 198,18,0,0,15 }, 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 198,51,100,0,24 }, { 203,0,113,0,24 }, { 224,0,0,0,3 } 4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static const unsigned char kReservedIPv6[][17] = { 4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 }, 4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, 4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, 4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3 }, 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xe0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 }, 4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xf0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5 }, 4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xf8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6 }, 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7 }, 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9 }, 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, 4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { 0xfe,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, 4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t array_size = 0; 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const unsigned char* array = NULL; 5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (host_addr.size()) { 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kIPv4AddressSize: 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) array_size = arraysize(kReservedIPv4); 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) array = kReservedIPv4[0]; 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kIPv6AddressSize: 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) array_size = arraysize(kReservedIPv6); 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) array = kReservedIPv6[0]; 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!array) 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t width = host_addr.size() + 1; 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t i = 0; i < array_size; ++i, array += width) { 5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IPNumberPrefixCheck(host_addr, array, array[width-1])) 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 522116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSockaddrStorage::SockaddrStorage(const SockaddrStorage& other) 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : addr_len(other.addr_len), 524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch addr(reinterpret_cast<struct sockaddr*>(&addr_storage)) { 525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(addr, other.addr, addr_len); 526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 528116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid SockaddrStorage::operator=(const SockaddrStorage& other) { 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch addr_len = other.addr_len; 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // addr is already set to &this->addr_storage by default ctor. 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(addr, other.addr, addr_len); 532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extracts the address and port portions of a sockaddr. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t sock_addr_len, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8** address, 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* address_len, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16* port) { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock_addr->sa_family == AF_INET) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in* addr = 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in*>(sock_addr); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *address = reinterpret_cast<const uint8*>(&addr->sin_addr); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *address_len = kIPv4AddressSize; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (port) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = base::NetToHost16(addr->sin_port); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock_addr->sa_family == AF_INET6) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in6))) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* addr = 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in6*>(sock_addr); 5575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *address = reinterpret_cast<const uint8*>(&addr->sin6_addr); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *address_len = kIPv6AddressSize; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (port) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = base::NetToHost16(addr->sin6_port); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if defined(OS_WIN) 5655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (sock_addr->sa_family == AF_BTH) { 5665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (sock_addr_len < static_cast<socklen_t>(sizeof(SOCKADDR_BTH))) 5675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 5685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const SOCKADDR_BTH* addr = 5695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu reinterpret_cast<const SOCKADDR_BTH*>(sock_addr); 5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *address = reinterpret_cast<const uint8*>(&addr->btAddr); 5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *address_len = kBluetoothAddressSize; 5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (port) 5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *port = addr->port; 5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 5755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 5775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Unrecognized |sa_family|. 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IPAddressToString(const uint8* address, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_len) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str; 5845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::StdStringCanonOutput output(&str); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address_len == kIPv4AddressSize) { 5875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::AppendIPv4Address(address, &output); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (address_len == kIPv6AddressSize) { 5895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::AppendIPv6Address(address, &output); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(false) << "Invalid IP address with length: " << address_len; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.Complete(); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return str; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IPAddressToStringWithPort(const uint8* address, 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_len, 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 port) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string address_str = IPAddressToString(address, address_len); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address_len == kIPv6AddressSize) { 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to bracket IPv6 addresses since they contain colons. 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPrintf("[%s]:%d", address_str.c_str(), port); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPrintf("%s:%d", address_str.c_str(), port); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NetAddressToString(const struct sockaddr* sa, 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t sock_addr_len) { 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* address; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_len; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetIPAddressFromSockAddr(sa, sock_addr_len, &address, 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &address_len, NULL)) { 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPAddressToString(address, address_len); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NetAddressToStringWithPort(const struct sockaddr* sa, 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t sock_addr_len) { 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* address; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_len; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 port; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetIPAddressFromSockAddr(sa, sock_addr_len, &address, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &address_len, &port)) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPAddressToStringWithPort(address, address_len, port); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IPAddressToString(const IPAddressNumber& addr) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPAddressToString(&addr.front(), addr.size()); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string IPAddressToStringWithPort(const IPAddressNumber& addr, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 port) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPAddressToStringWithPort(&addr.front(), addr.size(), port); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string IPAddressToPackedString(const IPAddressNumber& addr) { 64558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return std::string(reinterpret_cast<const char *>(&addr.front()), 64658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) addr.size()); 64758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 64858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetHostName() { 650a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_NACL) 651a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NOTIMPLEMENTED(); 652a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return std::string(); 653a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#else // defined(OS_NACL) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureWinsockInit(); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Host names are limited to 255 bytes. 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[256]; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = gethostname(buffer, sizeof(buffer)); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != 0) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "gethostname() failed with " << result; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer[0] = '\0'; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(buffer); 666a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif // !defined(OS_NACL) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetIdentityFromURL(const GURL& url, 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* username, 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16* password) { 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnescapeRule::Type flags = 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS; 6740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *username = UnescapeAndDecodeUTF8URLComponent(url.username(), flags); 6750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetHostOrSpecFromURL(const GURL& url) { 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url.has_host() ? TrimEndingDot(url.host()) : url.spec(); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CanStripTrailingSlash(const GURL& url) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Omit the path only for standard, non-file URLs with nothing but "/" after 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the hostname. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url.IsStandard() && !url.SchemeIsFile() && 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !url.SchemeIsFileSystem() && !url.has_query() && !url.has_ref() 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && url.path() == "/"; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL SimplifyUrlForRequest(const GURL& url) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(url.is_valid()); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL::Replacements replacements; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearUsername(); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearPassword(); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearRef(); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url.ReplaceComponents(replacements); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specifies a comma separated list of port numbers that should be accepted 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// despite bans. If the string is invalid no allowed ports are stored. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetExplicitlyAllowedPorts(const std::string& allowed_ports) { 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (allowed_ports.empty()) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::multiset<int> ports; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t last = 0; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = allowed_ports.size(); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The comma delimiter. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string::value_type kComma = ','; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overflow is still possible for evil user inputs. 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i <= size; ++i) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string should be composed of only digits and commas. 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != size && !IsAsciiDigit(allowed_ports[i]) && 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (allowed_ports[i] != kComma)) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == size || allowed_ports[i] == kComma) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > last) { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringToInt(base::StringPiece(allowed_ports.begin() + last, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allowed_ports.begin() + i), 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &port); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ports.insert(port); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = i + 1; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_explicitly_allowed_ports.Get() = ports; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedPortException::ScopedPortException(int port) : port_(port) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_explicitly_allowed_ports.Get().insert(port); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedPortException::~ScopedPortException() { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::multiset<int>::iterator it = 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_explicitly_allowed_ports.Get().find(port_); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != g_explicitly_allowed_ports.Get().end()) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_explicitly_allowed_ports.Get().erase(it); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HaveOnlyLoopbackAddresses() { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return android::HaveOnlyLoopbackAddresses(); 747a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#elif defined(OS_NACL) 748a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NOTIMPLEMENTED(); 749a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return false; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ifaddrs* interface_addr = NULL; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = getifaddrs(&interface_addr); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != 0) { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "getifaddrs() failed with errno = " << errno; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = true; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (struct ifaddrs* interface = interface_addr; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface != NULL; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interface = interface->ifa_next) { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(IFF_UP & interface->ifa_flags)) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IFF_LOOPBACK & interface->ifa_flags) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr* addr = interface->ifa_addr; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr->sa_family == AF_INET6) { 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safe cast since this is AF_INET6. 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* addr_in6 = 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in6*>(addr); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct in6_addr* sin6_addr = &addr_in6->sin6_addr; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr)) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr->sa_family != AF_INET6 && addr->sa_family != AF_INET) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = false; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) freeifaddrs(interface_addr); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(wtc): implement with the GetAdaptersAddresses function. 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(various platforms) 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AddressFamily GetAddressFamily(const IPAddressNumber& address) { 79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (address.size()) { 79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kIPv4AddressSize: 79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ADDRESS_FAMILY_IPV4; 79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kIPv6AddressSize: 80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ADDRESS_FAMILY_IPV6; 80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 80290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ADDRESS_FAMILY_UNSPECIFIED; 80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 80658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)int ConvertAddressFamily(AddressFamily address_family) { 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (address_family) { 80858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ADDRESS_FAMILY_UNSPECIFIED: 80958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return AF_UNSPEC; 81058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ADDRESS_FAMILY_IPV4: 81158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return AF_INET; 81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ADDRESS_FAMILY_IPV6: 81358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return AF_INET6; 81458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 81558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); 81658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return AF_UNSPEC; 81758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 81858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ParseURLHostnameToNumber(const std::string& hostname, 8206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) IPAddressNumber* ip_number) { 8216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |hostname| is an already canoncalized hostname, conforming to RFC 3986. 8226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // For an IP address, this is defined in Section 3.2.2 of RFC 3986, with 8236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // the canonical form for IPv6 addresses defined in Section 4 of RFC 5952. 8246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) url::Component host_comp(0, hostname.size()); 8256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 8266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If it has a bracket, try parsing it as an IPv6 address. 8276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (hostname[0] == '[') { 8286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ip_number->resize(16); // 128 bits. 8296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return url::IPv6AddressToNumber( 8306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) hostname.data(), host_comp, &(*ip_number)[0]); 8316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 8326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 8336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Otherwise, try IPv4. 8346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ip_number->resize(4); // 32 bits. 8356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int num_components; 8366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) url::CanonHostInfo::Family family = url::IPv4AddressToNumber( 8376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) hostname.data(), host_comp, &(*ip_number)[0], &num_components); 8386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return family == url::CanonHostInfo::IPV4; 8396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 8406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseIPLiteralToNumber(const std::string& ip_literal, 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber* ip_number) { 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ip_literal| could be either a IPv4 or an IPv6 literal. If it contains 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a colon however, it must be an IPv6 address. 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip_literal.find(':') != std::string::npos) { 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GURL expects IPv6 hostnames to be surrounded with brackets. 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host_brackets = "[" + ip_literal + "]"; 8485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component host_comp(0, host_brackets.size()); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try parsing the hostname as an IPv6 literal. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_number->resize(16); // 128 bits. 8525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return url::IPv6AddressToNumber(host_brackets.data(), host_comp, 8535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &(*ip_number)[0]); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise the string is an IPv4 address. 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_number->resize(4); // 32 bits. 8585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Component host_comp(0, ip_literal.size()); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_components; 8605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::CanonHostInfo::Family family = url::IPv4AddressToNumber( 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_literal.data(), host_comp, &(*ip_number)[0], &num_components); 8625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return family == url::CanonHostInfo::IPV4; 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned char kIPv4MappedPrefix[] = 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF }; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPAddressNumber ConvertIPv4NumberToIPv6Number( 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPAddressNumber& ipv4_number) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ipv4_number.size() == 4); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4-mapped addresses are formed by: 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // <80 bits of zeros> + <16 bits of ones> + <32-bit IPv4 address>. 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber ipv6_number; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipv6_number.reserve(16); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipv6_number.insert(ipv6_number.end(), 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIPv4MappedPrefix, 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIPv4MappedPrefix + arraysize(kIPv4MappedPrefix)); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipv6_number.insert(ipv6_number.end(), ipv4_number.begin(), ipv4_number.end()); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ipv6_number; 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsIPv4Mapped(const IPAddressNumber& address) { 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address.size() != kIPv6AddressSize) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::equal(address.begin(), 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address.begin() + arraysize(kIPv4MappedPrefix), 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIPv4MappedPrefix); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPAddressNumber ConvertIPv4MappedToIPv4(const IPAddressNumber& address) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsIPv4Mapped(address)); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPAddressNumber(address.begin() + arraysize(kIPv4MappedPrefix), 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address.end()); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseCIDRBlock(const std::string& cidr_literal, 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber* ip_number, 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* prefix_length_in_bits) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We expect CIDR notation to match one of these two templates: 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // <IPv4-literal> "/" <number of bits> 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // <IPv6-literal> "/" <number of bits> 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> parts; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SplitString(cidr_literal, '/', &parts); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parts.size() != 2) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the IP address. 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseIPLiteralToNumber(parts[0], ip_number)) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the prefix length. 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int number_of_bits = -1; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(parts[1], &number_of_bits)) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the prefix length is in a valid range. 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (number_of_bits < 0 || 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number_of_bits > static_cast<int>(ip_number->size() * 8)) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *prefix_length_in_bits = static_cast<size_t>(number_of_bits); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IPNumberMatchesPrefix(const IPAddressNumber& ip_number, 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IPAddressNumber& ip_prefix, 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t prefix_length_in_bits) { 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Both the input IP address and the prefix IP address should be 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either IPv4 or IPv6. 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ip_number.size() == 4 || ip_number.size() == 16); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ip_prefix.size() == 4 || ip_prefix.size() == 16); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(prefix_length_in_bits, ip_prefix.size() * 8); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case we have an IPv6 / IPv4 mismatch, convert the IPv4 addresses to 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv6 addresses in order to do the comparison. 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip_number.size() != ip_prefix.size()) { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ip_number.size() == 4) { 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number), 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_prefix, prefix_length_in_bits); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPNumberMatchesPrefix(ip_number, 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertIPv4NumberToIPv6Number(ip_prefix), 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96 + prefix_length_in_bits); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return IPNumberPrefixCheck(ip_number, &ip_prefix[0], prefix_length_in_bits); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address, 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t address_len) { 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address->sa_family == AF_INET) { 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len)); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in* sockaddr = 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in*>(address); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &sockaddr->sin_port; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (address->sa_family == AF_INET6) { 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(sizeof(sockaddr_in6), static_cast<size_t>(address_len)); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* sockaddr = 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in6*>(address); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &sockaddr->sin6_port; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) { 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16* port_field = GetPortFieldFromSockaddr(address, address_len); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!port_field) 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::NetToHost16(*port_field); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsLocalhost(const std::string& host) { 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host == "localhost" || 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host == "localhost.localdomain" || 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host == "localhost6" || 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host == "localhost6.localdomain6") 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber ip_number; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ParseIPLiteralToNumber(host, &ip_number)) { 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = ip_number.size(); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (size) { 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv4AddressSize: { 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPAddressNumber localhost_prefix; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) localhost_prefix.push_back(127); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 3; ++i) { 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) localhost_prefix.push_back(0); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IPNumberMatchesPrefix(ip_number, localhost_prefix, 8); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv6AddressSize: { 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct in6_addr sin6_addr; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&sin6_addr, &ip_number[0], kIPv6AddressSize); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!IN6_IS_ADDR_LOOPBACK(&sin6_addr); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1014c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochNetworkInterface::NetworkInterface() 1015010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : type(NetworkChangeNotifier::CONNECTION_UNKNOWN), 1016c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch network_prefix(0) { 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetworkInterface::NetworkInterface(const std::string& name, 1020a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& friendly_name, 1021a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 interface_index, 1022010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NetworkChangeNotifier::ConnectionType type, 102368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const IPAddressNumber& address, 10241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 network_prefix, 10251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int ip_address_attributes) 1026a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : name(name), 1027a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) friendly_name(friendly_name), 1028a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) interface_index(interface_index), 1029c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch type(type), 1030a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) address(address), 10311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci network_prefix(network_prefix), 10321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ip_address_attributes(ip_address_attributes) { 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetworkInterface::~NetworkInterface() { 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)unsigned CommonPrefixLength(const IPAddressNumber& a1, 103968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const IPAddressNumber& a2) { 104068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(a1.size(), a2.size()); 104168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < a1.size(); ++i) { 104268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) unsigned diff = a1[i] ^ a2[i]; 104368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!diff) 104468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) continue; 104568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (unsigned j = 0; j < CHAR_BIT; ++j) { 104668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (diff & (1 << (CHAR_BIT - 1))) 104768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return i * CHAR_BIT + j; 104868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) diff <<= 1; 104968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 105068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NOTREACHED(); 105168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 105268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return a1.size() * CHAR_BIT; 105368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 105468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 105568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)unsigned MaskPrefixLength(const IPAddressNumber& mask) { 105668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) IPAddressNumber all_ones(mask.size(), 0xFF); 105768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return CommonPrefixLength(mask, all_ones); 105868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 105968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciScopedWifiOptions::~ScopedWifiOptions() { 10611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 10621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1064