ip_address.cc revision 55d9550e72197a203efbe06087edc2424676d886
1188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 21d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart// Use of this source code is governed by a BSD-style license that can be 31d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart// found in the LICENSE file. 41d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 58d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h" 61d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 72aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone#include <arpa/inet.h> 81d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include <netinet/in.h> 91d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 101d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include <string> 11f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart#include <vector> 121d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 138d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include <base/logging.h> 14a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_number_conversions.h> 15a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_split.h> 1614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 178d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/byte_string.h" 181d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 19188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartusing std::string; 20f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartusing std::vector; 21188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 221d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartnamespace shill { 231d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 24f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartnamespace { 25f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartconst size_t kBitsPerByte = 8; 268a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko} // namespace 27f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 282aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 297355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyUnknown = AF_UNSPEC; 302aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 317355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyIPv4 = AF_INET; 322aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 337355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyIPv6 = AF_INET6; 342aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone 35f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 36f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameUnknown[] = "Unknown"; 37f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 38f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameIPv4[] = "IPv4"; 39f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 40f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameIPv6[] = "IPv6"; 41f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 421d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family, const ByteString &address) 431d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart : family_(family) , 449e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart address_(address), 459e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(0) {} 469e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart 479e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul StewartIPAddress::IPAddress(Family family, 489e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart const ByteString &address, 499e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart unsigned int prefix) 509e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart : family_(family) , 519e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart address_(address), 529e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(prefix) {} 531d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 541d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family) 559e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart : family_(family), 569e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(0) {} 571d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 58da775de010f64cf404c23632da4da0abce2ad2d8Samuel TanIPAddress::IPAddress(std::string ip_string) 59da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan : prefix_(0) { 60da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan family_ = IPAddress::kFamilyIPv4; 61da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan if (!SetAddressFromString(ip_string)) { 62da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan family_ = IPAddress::kFamilyIPv6; 63da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan if (!SetAddressFromString(ip_string)) { 64da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan family_ = IPAddress::kFamilyUnknown; 65da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan } 66da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan } 67da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan} 68da775de010f64cf404c23632da4da0abce2ad2d8Samuel Tan 691d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::~IPAddress() {} 701d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 71f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 72c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbroodsize_t IPAddress::GetAddressLength(Family family) { 731d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart switch (family) { 747355ce1937c504d836a303ac809bd436272212b3Paul Stewart case kFamilyIPv4: 751d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return sizeof(in_addr); 767355ce1937c504d836a303ac809bd436272212b3Paul Stewart case kFamilyIPv6: 771d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return sizeof(in6_addr); 781d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart default: 791d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return 0; 801d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 811d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 821d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 8314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov// static 8448100b0f484fb59d5f34eb4565375759202295e1Paul Stewartsize_t IPAddress::GetMaxPrefixLength(Family family) { 85f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetAddressLength(family) * kBitsPerByte; 86f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 87f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 88f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartsize_t IPAddress::GetMinPrefixLength() const { 89f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (family() != kFamilyIPv4) { 90f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart NOTIMPLEMENTED() << ": only implemented for IPv4"; 91f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()); 92f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 93f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 94f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK(IsValid()); 95f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart in_addr_t address_val; 96f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart memcpy(&address_val, GetConstData(), sizeof(address_val)); 97f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // IN_CLASSx() macros operate on addresses in host-order. 98f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart address_val = ntohl(address_val); 99f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (IN_CLASSA(address_val)) { 100f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()) - IN_CLASSA_NSHIFT; 101f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } else if (IN_CLASSB(address_val)) { 102f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()) - IN_CLASSB_NSHIFT; 103f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } else if (IN_CLASSC(address_val)) { 104f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()) - IN_CLASSC_NSHIFT; 105f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 106f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 107f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Invalid IPv4 address class"; 108f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetMaxPrefixLength(family()); 10948100b0f484fb59d5f34eb4565375759202295e1Paul Stewart} 11048100b0f484fb59d5f34eb4565375759202295e1Paul Stewart 11148100b0f484fb59d5f34eb4565375759202295e1Paul Stewart// static 1123e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodsize_t IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) { 11314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov switch (family) { 11414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv4: { 11514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov in_addr_t mask_val = inet_network(mask.c_str()); 11648100b0f484fb59d5f34eb4565375759202295e1Paul Stewart int subnet_prefix = 0; 11714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov while (mask_val) { 11848100b0f484fb59d5f34eb4565375759202295e1Paul Stewart subnet_prefix++; 11914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov mask_val <<= 1; 12014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 12148100b0f484fb59d5f34eb4565375759202295e1Paul Stewart return subnet_prefix; 12214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 12314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv6: 12414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov NOTIMPLEMENTED(); 12514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 12614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov default: 12714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov LOG(WARNING) << "Unexpected address family: " << family; 12814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 12914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 13014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov return 0; 13114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov} 13214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 133f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 134f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul StewartIPAddress IPAddress::GetAddressMaskFromPrefix(Family family, size_t prefix) { 135f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart ByteString address_bytes(GetAddressLength(family)); 136f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart unsigned char *address_ptr = address_bytes.GetData(); 137f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 138f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart size_t bits = prefix; 139f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (bits > GetMaxPrefixLength(family)) { 140f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart bits = GetMaxPrefixLength(family); 141f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 142f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 143f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart while (bits > kBitsPerByte) { 144f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart bits -= kBitsPerByte; 145f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart *address_ptr++ = kuint8max; 146f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 147f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 148f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // We are guaranteed to be before the end of the address data since even 149f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // if the prefix is the maximum, the loop above will end before we assign 150f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart // and increment past the last byte. 151f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart *address_ptr = ~((1 << (kBitsPerByte - bits)) - 1); 152f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 153f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return IPAddress(family, address_bytes); 154f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 155f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 156f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart// static 157f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartstring IPAddress::GetAddressFamilyName(Family family) { 158f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart switch (family) { 159f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv4: 160f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv4; 161f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv6: 162f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv6; 163f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart default: 164f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameUnknown; 165f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart } 166f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart} 167f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 168188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartbool IPAddress::SetAddressFromString(const string &address_string) { 169c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbrood size_t address_length = GetAddressLength(family_); 1701d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1711d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (!address_length) { 1721d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 1731d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1741d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1751d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart ByteString address(address_length); 1761d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) { 1771d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 1781d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1791d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = address; 1801d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return true; 1811d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 1821d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 183f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewartbool IPAddress::SetAddressAndPrefixFromString(const string &address_string) { 184f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart vector<string> address_parts; 185f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart base::SplitString(address_string, '/', &address_parts); 186f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (address_parts.size() != 2) { 187f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Cannot split address " << address_string; 188f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return false; 189f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 190f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart if (!SetAddressFromString(address_parts[0])) { 191f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Cannot parse address string " << address_parts[0]; 192f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return false; 193f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 194762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi size_t prefix; 195762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi if (!base::StringToSizeT(address_parts[1], &prefix) || 196762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi prefix > GetMaxPrefixLength(family_)) { 197f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart LOG(ERROR) << "Cannot parse address prefix " << address_parts[1]; 198f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return false; 199f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart } 200f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart set_prefix(prefix); 201f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return true; 202f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 203f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 2041d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartvoid IPAddress::SetAddressToDefault() { 2051d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = ByteString(GetAddressLength(family_)); 2061d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 2071d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 2082c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalbool IPAddress::IntoString(string *address_string) const { 209188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN 210188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart char address_buf[INET6_ADDRSTRLEN]; 211188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart if (GetLength() != GetAddressLength(family_) || 212188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) { 213188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return false; 214188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart } 215188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart *address_string = address_buf; 216188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return true; 217188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart} 218188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 2192c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalstring IPAddress::ToString() const { 2202c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal string out("<unknown>"); 2212c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal IntoString(&out); 2222c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal return out; 2232c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal} 2242c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal 22555d9550e72197a203efbe06087edc2424676d886Paul Stewartbool IPAddress::Equals(const IPAddress &b) const { 22655d9550e72197a203efbe06087edc2424676d886Paul Stewart return family_ == b.family_ && address_.Equals(b.address_) && 22755d9550e72197a203efbe06087edc2424676d886Paul Stewart prefix_ == b.prefix_; 22855d9550e72197a203efbe06087edc2424676d886Paul Stewart} 22955d9550e72197a203efbe06087edc2424676d886Paul Stewart 23055d9550e72197a203efbe06087edc2424676d886Paul Stewartbool IPAddress::HasSameAddressAs(const IPAddress &b) const { 23155d9550e72197a203efbe06087edc2424676d886Paul Stewart return family_ == b.family_ && address_.Equals(b.address_); 23255d9550e72197a203efbe06087edc2424676d886Paul Stewart} 23355d9550e72197a203efbe06087edc2424676d886Paul Stewart 2344a6748d492214afcb7c484668fa8cfd3ad963f10Paul StewartIPAddress IPAddress::MaskWith(const IPAddress &b) const { 235f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK(IsValid()); 236f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK(b.IsValid()); 237f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK_EQ(family(), b.family()); 238f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 239f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart ByteString address_bytes(address()); 240fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart address_bytes.BitwiseAnd(b.address()); 241fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 242fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart return IPAddress(family(), address_bytes); 243fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart} 244fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 2454a6748d492214afcb7c484668fa8cfd3ad963f10Paul StewartIPAddress IPAddress::MergeWith(const IPAddress &b) const { 246fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart CHECK(IsValid()); 247fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart CHECK(b.IsValid()); 248fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart CHECK_EQ(family(), b.family()); 249fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 250fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart ByteString address_bytes(address()); 251fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart address_bytes.BitwiseOr(b.address()); 252f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 253f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return IPAddress(family(), address_bytes); 254f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 255f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 2564a6748d492214afcb7c484668fa8cfd3ad963f10Paul StewartIPAddress IPAddress::GetNetworkPart() const { 257f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return MaskWith(GetAddressMaskFromPrefix(family(), prefix())); 258f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 259f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 260fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul StewartIPAddress IPAddress::GetDefaultBroadcast() { 261fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart ByteString broadcast_bytes( 262fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart GetAddressMaskFromPrefix(family(), prefix()).address()); 263fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart broadcast_bytes.BitwiseInvert(); 264fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart return MergeWith(IPAddress(family(), broadcast_bytes)); 265fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart} 266fe1c0e17fe470de449a1aadb6c202a41da146ef7Paul Stewart 2674a6748d492214afcb7c484668fa8cfd3ad963f10Paul Stewartbool IPAddress::CanReachAddress(const IPAddress &b) const { 268f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart CHECK_EQ(family(), b.family()); 269f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart IPAddress b_prefixed(b); 270f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart b_prefixed.set_prefix(prefix()); 271f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart return GetNetworkPart().Equals(b_prefixed.GetNetworkPart()); 272f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart} 273f7bf9bf2d7cb7fe7ebf98c7a575a267c190f6ec1Paul Stewart 2741d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} // namespace shill 275