ip_address.cc revision 14c29ec4815e8ecda47b7ce5efdaa444580e20ce
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
271d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family, const ByteString &address)
281d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart    : family_(family) ,
299e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart      address_(address),
309e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart      prefix_(0) {}
319e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart
329e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul StewartIPAddress::IPAddress(Family family,
339e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart                     const ByteString &address,
349e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart                     unsigned int prefix)
359e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart    : family_(family) ,
369e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart      address_(address),
379e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart      prefix_(prefix) {}
381d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
391d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::IPAddress(Family family)
409e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart    : family_(family),
419e3fcd7141240bc5efd0bf1513b9e78aa79d90ebPaul Stewart      prefix_(0) {}
421d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
431d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul StewartIPAddress::~IPAddress() {}
441d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
45c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbroodsize_t IPAddress::GetAddressLength(Family family) {
461d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  switch (family) {
477355ce1937c504d836a303ac809bd436272212b3Paul Stewart  case kFamilyIPv4:
481d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart    return sizeof(in_addr);
497355ce1937c504d836a303ac809bd436272212b3Paul Stewart  case kFamilyIPv6:
501d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart    return sizeof(in6_addr);
511d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  default:
521d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart    return 0;
531d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  }
541d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart}
551d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
5614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov// static
5714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkovint IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) {
5814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  switch (family) {
5914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov    case kFamilyIPv4: {
6014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      in_addr_t mask_val = inet_network(mask.c_str());
6114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      int subnet_cidr = 0;
6214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      while (mask_val) {
6314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov        subnet_cidr++;
6414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov        mask_val <<= 1;
6514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      }
6614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      return subnet_cidr;
6714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov    }
6814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov    case kFamilyIPv6:
6914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      NOTIMPLEMENTED();
7014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      break;
7114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov    default:
7214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      LOG(WARNING) << "Unexpected address family: " << family;
7314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov      break;
7414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  }
7514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  return 0;
7614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov}
7714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov
78188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewartbool IPAddress::SetAddressFromString(const string &address_string) {
79c74cf9cb439ef518bc00210fe5cd3b121f3079b3Eric Shienbrood  size_t address_length = GetAddressLength(family_);
801d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
811d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  if (!address_length) {
821d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart    return false;
831d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  }
841d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
851d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  ByteString address(address_length);
861d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) {
871d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart    return false;
881d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  }
891d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  address_ = address;
901d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  return true;
911d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart}
921d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
931d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewartvoid IPAddress::SetAddressToDefault() {
941d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart  address_ = ByteString(GetAddressLength(family_));
951d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart}
961d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart
972c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalbool IPAddress::IntoString(string *address_string) const {
98188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart  // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN
99188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart  char address_buf[INET6_ADDRSTRLEN];
100188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart  if (GetLength() != GetAddressLength(family_) ||
101188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart      !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) {
102188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart    return false;
103188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart  }
104188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart  *address_string = address_buf;
105188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart  return true;
106188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart}
107188a84a6f75dcadb972bc33bafa00c6ba7f3bbd6Paul Stewart
1082c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawalstring IPAddress::ToString() const {
1092c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal  string out("<unknown>");
1102c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal  IntoString(&out);
1112c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal  return out;
1122c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal}
1132c15d2c7ae814d95673ea48ec8f4eb582ef3652emukesh agrawal
1141d18e8cd593cc8dce91a6faabe2f0cae700b7e38Paul Stewart}  // namespace shill
115