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