ip_address.cc revision 48100b0f484fb59d5f34eb4565375759202295e1
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 51d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include "shill/ip_address.h" 61d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 72aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone#include <arpa/inet.h> 81d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include <netinet/in.h> 91d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 101d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include <string> 111d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov#include <base/logging.h> 1314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 141d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart#include "shill/byte_string.h" 151d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 16188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartusing std::string; 17188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 181d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartnamespace shill { 191d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 202aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 217355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyUnknown = AF_UNSPEC; 222aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 237355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyIPv4 = AF_INET; 242aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone// static 257355ce1937c504d836a303ac809bd436272212b3Paul Stewartconst IPAddress::Family IPAddress::kFamilyIPv6 = AF_INET6; 262aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone 27f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 28f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameUnknown[] = "Unknown"; 29f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 30f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameIPv4[] = "IPv4"; 31f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 32f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartconst char IPAddress::kFamilyNameIPv6[] = "IPv6"; 33f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 341d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family, const ByteString &address) 351d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart : family_(family) , 369e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart address_(address), 379e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(0) {} 389e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart 399e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul StewartIPAddress::IPAddress(Family family, 409e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart const ByteString &address, 419e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart unsigned int prefix) 429e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart : family_(family) , 439e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart address_(address), 449e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(prefix) {} 451d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 461d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family) 479e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart : family_(family), 489e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart prefix_(0) {} 491d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 501d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::~IPAddress() {} 511d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 52f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 53c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbroodsize_t IPAddress::GetAddressLength(Family family) { 541d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart switch (family) { 557355ce1937c504d836a303ac809bd436272212b3Paul Stewart case kFamilyIPv4: 561d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return sizeof(in_addr); 577355ce1937c504d836a303ac809bd436272212b3Paul Stewart case kFamilyIPv6: 581d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return sizeof(in6_addr); 591d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart default: 601d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return 0; 611d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 621d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 631d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 6414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov// static 6548100b0f484fb59d5f34eb4565375759202295e1Paul Stewartsize_t IPAddress::GetMaxPrefixLength(Family family) { 6648100b0f484fb59d5f34eb4565375759202295e1Paul Stewart return GetAddressLength(family) * 8; 6748100b0f484fb59d5f34eb4565375759202295e1Paul Stewart} 6848100b0f484fb59d5f34eb4565375759202295e1Paul Stewart 6948100b0f484fb59d5f34eb4565375759202295e1Paul Stewart// static 703e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodsize_t IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) { 7114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov switch (family) { 7214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv4: { 7314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov in_addr_t mask_val = inet_network(mask.c_str()); 7448100b0f484fb59d5f34eb4565375759202295e1Paul Stewart int subnet_prefix = 0; 7514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov while (mask_val) { 7648100b0f484fb59d5f34eb4565375759202295e1Paul Stewart subnet_prefix++; 7714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov mask_val <<= 1; 7814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 7948100b0f484fb59d5f34eb4565375759202295e1Paul Stewart return subnet_prefix; 8014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 8114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv6: 8214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov NOTIMPLEMENTED(); 8314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 8414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov default: 8514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov LOG(WARNING) << "Unexpected address family: " << family; 8614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 8714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 8814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov return 0; 8914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov} 9014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 91f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 92f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartstring IPAddress::GetAddressFamilyName(Family family) { 93f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart switch (family) { 94f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv4: 95f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv4; 96f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv6: 97f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv6; 98f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart default: 99f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameUnknown; 100f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart } 101f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart} 102f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 103188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartbool IPAddress::SetAddressFromString(const string &address_string) { 104c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbrood size_t address_length = GetAddressLength(family_); 1051d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1061d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (!address_length) { 1071d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 1081d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1091d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1101d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart ByteString address(address_length); 1111d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) { 1121d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 1131d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1141d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = address; 1151d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return true; 1161d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 1171d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1181d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartvoid IPAddress::SetAddressToDefault() { 1191d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = ByteString(GetAddressLength(family_)); 1201d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 1211d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1222c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalbool IPAddress::IntoString(string *address_string) const { 123188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN 124188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart char address_buf[INET6_ADDRSTRLEN]; 125188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart if (GetLength() != GetAddressLength(family_) || 126188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) { 127188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return false; 128188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart } 129188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart *address_string = address_buf; 130188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return true; 131188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart} 132188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 1332c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalstring IPAddress::ToString() const { 1342c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal string out("<unknown>"); 1352c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal IntoString(&out); 1362c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal return out; 1372c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal} 1382c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal 1391d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} // namespace shill 140