1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 161d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 178d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h" 181d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 192aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone#include <arpa/inet.h> 201d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include <netinet/in.h> 211d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 221d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include <string> 23f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart#include <vector> 241d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 258d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include <base/logging.h> 26a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_number_conversions.h> 27a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_split.h> 2814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 298d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/byte_string.h" 301d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 31188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartusing std::string; 32f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartusing std::vector; 33188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 341d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartnamespace shill { 351d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 36f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartnamespace { 37f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartconst size_t kBitsPerByte = 8; 388a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko} // namespace 39f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 402aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 417355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyUnknown = AF_UNSPEC; 422aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 437355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyIPv4 = AF_INET; 442aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 457355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyIPv6 = AF_INET6; 462aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone 47f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 48f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameUnknown[] = "Unknown"; 49f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 50f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameIPv4[] = "IPv4"; 51f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 52f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameIPv6[] = "IPv6"; 53f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 54e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul StewartIPAddress::IPAddress(Family family, const ByteString& address) 551d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart : family_(family) , 569e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart address_(address), 579e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(0) {} 589e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart 599e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul StewartIPAddress::IPAddress(Family family, 60e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewart const ByteString& address, 619e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart unsigned int prefix) 629e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart : family_(family) , 639e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart address_(address), 649e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(prefix) {} 651d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 661d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family) 679e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart : family_(family), 689e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(0) {} 691d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 70da775de010f64cf404c23632da4da0abce2ad2d8Samuel TanIPAddress::IPAddress(std::string ip_string) 71da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan : prefix_(0) { 72da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan family_ = IPAddress::kFamilyIPv4; 73da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan if (!SetAddressFromString(ip_string)) { 74da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan family_ = IPAddress::kFamilyIPv6; 75da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan if (!SetAddressFromString(ip_string)) { 76da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan family_ = IPAddress::kFamilyUnknown; 77da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan } 78da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan } 79da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan} 80da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan 81b3953b8fa428c46b48598396d2a8270a85934f72Christopher GrantIPAddress::IPAddress(const sockaddr* address_struct, size_t size) 82b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant : family_(kFamilyUnknown), 83b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant prefix_(0) { 84b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant if (address_struct->sa_family == kFamilyIPv4 && size >= sizeof(sockaddr_in)) { 85b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant family_ = address_struct->sa_family; 86b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant auto sin = reinterpret_cast<const sockaddr_in*>(address_struct); 87b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant // Preserve network byte order of s_addr. 88b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant auto bytes = reinterpret_cast<const uint8_t*>(&sin->sin_addr.s_addr); 89b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant address_ = ByteString(bytes, sizeof(sin->sin_addr.s_addr)); 90b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant } else if (address_struct->sa_family == kFamilyIPv6 && 91b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant size >= sizeof(sockaddr_in6)) { 92b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant family_ = address_struct->sa_family; 93b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant auto sin6 = reinterpret_cast<const sockaddr_in6*>(address_struct); 94b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant address_ = ByteString(sin6->sin6_addr.s6_addr, 95b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant sizeof(sin6->sin6_addr.s6_addr)); 96b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant } 97b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant} 98b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant 991d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::~IPAddress() {} 1001d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 101f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 102c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbroodsize_t IPAddress::GetAddressLength(Family family) { 1031d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart switch (family) { 1047355ce1937c504d836a303ac809bd436272212b3Paul Stewart case kFamilyIPv4: 1051d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return sizeof(in_addr); 1067355ce1937c504d836a303ac809bd436272212b3Paul Stewart case kFamilyIPv6: 1071d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return sizeof(in6_addr); 1081d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart default: 1091d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return 0; 1101d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1111d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 1121d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 11314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov// static 11448100b0f484fb59d5f34eb4565375759202295e1Paul Stewartsize_t IPAddress::GetMaxPrefixLength(Family family) { 115f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetAddressLength(family) * kBitsPerByte; 116f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 117f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 118f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartsize_t IPAddress::GetMinPrefixLength() const { 119f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (family() != kFamilyIPv4) { 120f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart NOTIMPLEMENTED() << ": only implemented for IPv4"; 121f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()); 122f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 123f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 124f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK(IsValid()); 125f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart in_addr_t address_val; 126f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart memcpy(&address_val, GetConstData(), sizeof(address_val)); 127f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // IN_CLASSx() macros operate on addresses in host-order. 128f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart address_val = ntohl(address_val); 129f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (IN_CLASSA(address_val)) { 130f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()) - IN_CLASSA_NSHIFT; 131f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } else if (IN_CLASSB(address_val)) { 132f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()) - IN_CLASSB_NSHIFT; 133f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } else if (IN_CLASSC(address_val)) { 134f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()) - IN_CLASSC_NSHIFT; 135f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 136f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 137f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Invalid IPv4 address class"; 138f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()); 13948100b0f484fb59d5f34eb4565375759202295e1Paul Stewart} 14048100b0f484fb59d5f34eb4565375759202295e1Paul Stewart 14148100b0f484fb59d5f34eb4565375759202295e1Paul Stewart// static 142e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartsize_t IPAddress::GetPrefixLengthFromMask(Family family, const string& mask) { 14314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov switch (family) { 14414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv4: { 14514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov in_addr_t mask_val = inet_network(mask.c_str()); 14648100b0f484fb59d5f34eb4565375759202295e1Paul Stewart int subnet_prefix = 0; 14714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov while (mask_val) { 14848100b0f484fb59d5f34eb4565375759202295e1Paul Stewart subnet_prefix++; 14914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov mask_val <<= 1; 15014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 15148100b0f484fb59d5f34eb4565375759202295e1Paul Stewart return subnet_prefix; 15214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 15314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv6: 15414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov NOTIMPLEMENTED(); 15514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 15614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov default: 15714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov LOG(WARNING) << "Unexpected address family: " << family; 15814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 15914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 16014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov return 0; 16114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov} 16214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 163f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 164f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul StewartIPAddress IPAddress::GetAddressMaskFromPrefix(Family family, size_t prefix) { 165f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart ByteString address_bytes(GetAddressLength(family)); 166e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewart unsigned char* address_ptr = address_bytes.GetData(); 167f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 168f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart size_t bits = prefix; 169f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (bits > GetMaxPrefixLength(family)) { 170f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart bits = GetMaxPrefixLength(family); 171f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 172f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 173f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart while (bits > kBitsPerByte) { 174f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart bits -= kBitsPerByte; 1753a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko *address_ptr++ = std::numeric_limits<uint8_t>::max(); 176f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 177f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 178f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // We are guaranteed to be before the end of the address data since even 179f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // if the prefix is the maximum, the loop above will end before we assign 180f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // and increment past the last byte. 181f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart *address_ptr = ~((1 << (kBitsPerByte - bits)) - 1); 182f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 183f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return IPAddress(family, address_bytes); 184f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 185f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 186f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart// static 187f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartstring IPAddress::GetAddressFamilyName(Family family) { 188f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart switch (family) { 189f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv4: 190f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv4; 191f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv6: 192f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv6; 193f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart default: 194f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameUnknown; 195f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart } 196f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart} 197f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 198e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartbool IPAddress::SetAddressFromString(const string& address_string) { 199c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbrood size_t address_length = GetAddressLength(family_); 2001d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 2011d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (!address_length) { 2021d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 2031d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 2041d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 2051d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart ByteString address(address_length); 2061d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) { 2071d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 2081d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 2091d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = address; 2101d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return true; 2111d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 2121d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 213e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartbool IPAddress::SetAddressAndPrefixFromString(const string& address_string) { 2143a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko vector<string> address_parts = base::SplitString( 2153a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko address_string, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 216f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (address_parts.size() != 2) { 217f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Cannot split address " << address_string; 218f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return false; 219f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 220f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (!SetAddressFromString(address_parts[0])) { 221f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Cannot parse address string " << address_parts[0]; 222f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return false; 223f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 224762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi size_t prefix; 225762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi if (!base::StringToSizeT(address_parts[1], &prefix) || 226762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi prefix > GetMaxPrefixLength(family_)) { 227f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Cannot parse address prefix " << address_parts[1]; 228f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return false; 229f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 230f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart set_prefix(prefix); 231f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return true; 232f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 233f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 2341d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartvoid IPAddress::SetAddressToDefault() { 2351d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = ByteString(GetAddressLength(family_)); 2361d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 2371d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 238e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartbool IPAddress::IntoString(string* address_string) const { 239188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN 240188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart char address_buf[INET6_ADDRSTRLEN]; 241188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart if (GetLength() != GetAddressLength(family_) || 242188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) { 243188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return false; 244188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart } 245188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart *address_string = address_buf; 246188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return true; 247188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart} 248188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 2492c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalstring IPAddress::ToString() const { 2502c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal string out("<unknown>"); 2512c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal IntoString(&out); 2522c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal return out; 2532c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal} 2542c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal 255b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grantbool IPAddress::IntoSockAddr(sockaddr* address_struct, size_t size) const { 256b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant if (!IsValid()) { 257b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant return false; 258b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant } 259b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant if (family_ == kFamilyIPv4 && size >= sizeof(sockaddr_in)) { 260b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant auto sin = reinterpret_cast<sockaddr_in*>(address_struct); 261b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant memcpy(&sin->sin_addr.s_addr, GetConstData(), GetLength()); 262b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant } else if (family_ == kFamilyIPv6 && size >= sizeof(sockaddr_in6)) { 263b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant auto sin6 = reinterpret_cast<sockaddr_in6*>(address_struct); 264b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant memcpy(&sin6->sin6_addr.s6_addr, GetConstData(), GetLength()); 265b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant } else { 266b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant return false; 267b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant } 268b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant address_struct->sa_family = family_; 269b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant return true; 270b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant} 271b3953b8fa428c46b48598396d2a8270a85934f72Christopher Grant 272e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartbool IPAddress::Equals(const IPAddress& b) const { 27355d9550e72197a203efbe06087edc2424676d886Paul Stewart return family_ == b.family_ && address_.Equals(b.address_) && 27455d9550e72197a203efbe06087edc2424676d886Paul Stewart prefix_ == b.prefix_; 27555d9550e72197a203efbe06087edc2424676d886Paul Stewart} 27655d9550e72197a203efbe06087edc2424676d886Paul Stewart 277e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartbool IPAddress::HasSameAddressAs(const IPAddress& b) const { 27855d9550e72197a203efbe06087edc2424676d886Paul Stewart return family_ == b.family_ && address_.Equals(b.address_); 27955d9550e72197a203efbe06087edc2424676d886Paul Stewart} 28055d9550e72197a203efbe06087edc2424676d886Paul Stewart 281e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul StewartIPAddress IPAddress::MaskWith(const IPAddress& b) const { 282f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK(IsValid()); 283f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK(b.IsValid()); 284f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK_EQ(family(), b.family()); 285f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 286f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart ByteString address_bytes(address()); 287fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart address_bytes.BitwiseAnd(b.address()); 288fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 289fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart return IPAddress(family(), address_bytes); 290fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart} 291fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 292e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul StewartIPAddress IPAddress::MergeWith(const IPAddress& b) const { 293fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart CHECK(IsValid()); 294fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart CHECK(b.IsValid()); 295fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart CHECK_EQ(family(), b.family()); 296fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 297fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart ByteString address_bytes(address()); 298fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart address_bytes.BitwiseOr(b.address()); 299f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 300f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return IPAddress(family(), address_bytes); 301f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 302f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 3034a6748d492214afcb7c484668fa8cfd3ad963f10Paul StewartIPAddress IPAddress::GetNetworkPart() const { 304f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return MaskWith(GetAddressMaskFromPrefix(family(), prefix())); 305f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 306f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 307fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul StewartIPAddress IPAddress::GetDefaultBroadcast() { 308fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart ByteString broadcast_bytes( 309fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart GetAddressMaskFromPrefix(family(), prefix()).address()); 310fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart broadcast_bytes.BitwiseInvert(); 311fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart return MergeWith(IPAddress(family(), broadcast_bytes)); 312fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart} 313fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 314e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewartbool IPAddress::CanReachAddress(const IPAddress& b) const { 315f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK_EQ(family(), b.family()); 316f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart IPAddress b_prefixed(b); 317f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart b_prefixed.set_prefix(prefix()); 318f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetNetworkPart().Equals(b_prefixed.GetNetworkPart()); 319f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 320f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 3211d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} // namespace shill 322