ip_address.cc revision f748a36f2cde2b1ac7fc543cc710c81cb431cc2f
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 65b5c8940ae68f85c8c822936f41f4993c51624dcfEric Shienbroodint IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) { 6614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov switch (family) { 6714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv4: { 6814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov in_addr_t mask_val = inet_network(mask.c_str()); 6914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov int subnet_cidr = 0; 7014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov while (mask_val) { 7114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov subnet_cidr++; 7214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov mask_val <<= 1; 7314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 7414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov return subnet_cidr; 7514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 7614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov case kFamilyIPv6: 7714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov NOTIMPLEMENTED(); 7814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 7914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov default: 8014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov LOG(WARNING) << "Unexpected address family: " << family; 8114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov break; 8214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov } 8314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov return 0; 8414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov} 8514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov 86f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart// static 87f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewartstring IPAddress::GetAddressFamilyName(Family family) { 88f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart switch (family) { 89f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv4: 90f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv4; 91f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart case kFamilyIPv6: 92f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameIPv6; 93f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart default: 94f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart return kFamilyNameUnknown; 95f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart } 96f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart} 97f748a36f2cde2b1ac7fc543cc710c81cb431cc2fPaul Stewart 98188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartbool IPAddress::SetAddressFromString(const string &address_string) { 99c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbrood size_t address_length = GetAddressLength(family_); 1001d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1011d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (!address_length) { 1021d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 1031d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1041d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1051d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart ByteString address(address_length); 1061d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) { 1071d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return false; 1081d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart } 1091d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = address; 1101d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart return true; 1111d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 1121d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1131d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartvoid IPAddress::SetAddressToDefault() { 1141d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart address_ = ByteString(GetAddressLength(family_)); 1151d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} 1161d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart 1172c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalbool IPAddress::IntoString(string *address_string) const { 118188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN 119188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart char address_buf[INET6_ADDRSTRLEN]; 120188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart if (GetLength() != GetAddressLength(family_) || 121188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) { 122188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return false; 123188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart } 124188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart *address_string = address_buf; 125188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart return true; 126188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart} 127188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart 1282c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalstring IPAddress::ToString() const { 1292c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal string out("<unknown>"); 1302c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal IntoString(&out); 1312c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal return out; 1322c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal} 1332c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal 1341d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart} // namespace shill 135