ip_address.cc revision 8d6b59704591ba9fad57751858835dc332dbdd37
1// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "shill/net/ip_address.h" 6 7#include <arpa/inet.h> 8#include <netinet/in.h> 9 10#include <string> 11#include <vector> 12 13#include <base/logging.h> 14#include <base/strings/string_number_conversions.h> 15#include <base/strings/string_split.h> 16 17#include "shill/net/byte_string.h" 18 19using std::string; 20using std::vector; 21 22namespace shill { 23 24namespace { 25const size_t kBitsPerByte = 8; 26} // namespace 27 28// static 29const IPAddress::Family IPAddress::kFamilyUnknown = AF_UNSPEC; 30// static 31const IPAddress::Family IPAddress::kFamilyIPv4 = AF_INET; 32// static 33const IPAddress::Family IPAddress::kFamilyIPv6 = AF_INET6; 34 35// static 36const char IPAddress::kFamilyNameUnknown[] = "Unknown"; 37// static 38const char IPAddress::kFamilyNameIPv4[] = "IPv4"; 39// static 40const char IPAddress::kFamilyNameIPv6[] = "IPv6"; 41 42IPAddress::IPAddress(Family family, const ByteString &address) 43 : family_(family) , 44 address_(address), 45 prefix_(0) {} 46 47IPAddress::IPAddress(Family family, 48 const ByteString &address, 49 unsigned int prefix) 50 : family_(family) , 51 address_(address), 52 prefix_(prefix) {} 53 54IPAddress::IPAddress(Family family) 55 : family_(family), 56 prefix_(0) {} 57 58IPAddress::IPAddress(std::string ip_string) 59 : prefix_(0) { 60 family_ = IPAddress::kFamilyIPv4; 61 if (!SetAddressFromString(ip_string)) { 62 family_ = IPAddress::kFamilyIPv6; 63 if (!SetAddressFromString(ip_string)) { 64 family_ = IPAddress::kFamilyUnknown; 65 } 66 } 67} 68 69IPAddress::~IPAddress() {} 70 71// static 72size_t IPAddress::GetAddressLength(Family family) { 73 switch (family) { 74 case kFamilyIPv4: 75 return sizeof(in_addr); 76 case kFamilyIPv6: 77 return sizeof(in6_addr); 78 default: 79 return 0; 80 } 81} 82 83// static 84size_t IPAddress::GetMaxPrefixLength(Family family) { 85 return GetAddressLength(family) * kBitsPerByte; 86} 87 88size_t IPAddress::GetMinPrefixLength() const { 89 if (family() != kFamilyIPv4) { 90 NOTIMPLEMENTED() << ": only implemented for IPv4"; 91 return GetMaxPrefixLength(family()); 92 } 93 94 CHECK(IsValid()); 95 in_addr_t address_val; 96 memcpy(&address_val, GetConstData(), sizeof(address_val)); 97 // IN_CLASSx() macros operate on addresses in host-order. 98 address_val = ntohl(address_val); 99 if (IN_CLASSA(address_val)) { 100 return GetMaxPrefixLength(family()) - IN_CLASSA_NSHIFT; 101 } else if (IN_CLASSB(address_val)) { 102 return GetMaxPrefixLength(family()) - IN_CLASSB_NSHIFT; 103 } else if (IN_CLASSC(address_val)) { 104 return GetMaxPrefixLength(family()) - IN_CLASSC_NSHIFT; 105 } 106 107 LOG(ERROR) << "Invalid IPv4 address class"; 108 return GetMaxPrefixLength(family()); 109} 110 111// static 112size_t IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) { 113 switch (family) { 114 case kFamilyIPv4: { 115 in_addr_t mask_val = inet_network(mask.c_str()); 116 int subnet_prefix = 0; 117 while (mask_val) { 118 subnet_prefix++; 119 mask_val <<= 1; 120 } 121 return subnet_prefix; 122 } 123 case kFamilyIPv6: 124 NOTIMPLEMENTED(); 125 break; 126 default: 127 LOG(WARNING) << "Unexpected address family: " << family; 128 break; 129 } 130 return 0; 131} 132 133// static 134IPAddress IPAddress::GetAddressMaskFromPrefix(Family family, size_t prefix) { 135 ByteString address_bytes(GetAddressLength(family)); 136 unsigned char *address_ptr = address_bytes.GetData(); 137 138 size_t bits = prefix; 139 if (bits > GetMaxPrefixLength(family)) { 140 bits = GetMaxPrefixLength(family); 141 } 142 143 while (bits > kBitsPerByte) { 144 bits -= kBitsPerByte; 145 *address_ptr++ = kuint8max; 146 } 147 148 // We are guaranteed to be before the end of the address data since even 149 // if the prefix is the maximum, the loop above will end before we assign 150 // and increment past the last byte. 151 *address_ptr = ~((1 << (kBitsPerByte - bits)) - 1); 152 153 return IPAddress(family, address_bytes); 154} 155 156// static 157string IPAddress::GetAddressFamilyName(Family family) { 158 switch (family) { 159 case kFamilyIPv4: 160 return kFamilyNameIPv4; 161 case kFamilyIPv6: 162 return kFamilyNameIPv6; 163 default: 164 return kFamilyNameUnknown; 165 } 166} 167 168bool IPAddress::SetAddressFromString(const string &address_string) { 169 size_t address_length = GetAddressLength(family_); 170 171 if (!address_length) { 172 return false; 173 } 174 175 ByteString address(address_length); 176 if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) { 177 return false; 178 } 179 address_ = address; 180 return true; 181} 182 183bool IPAddress::SetAddressAndPrefixFromString(const string &address_string) { 184 vector<string> address_parts; 185 base::SplitString(address_string, '/', &address_parts); 186 if (address_parts.size() != 2) { 187 LOG(ERROR) << "Cannot split address " << address_string; 188 return false; 189 } 190 if (!SetAddressFromString(address_parts[0])) { 191 LOG(ERROR) << "Cannot parse address string " << address_parts[0]; 192 return false; 193 } 194 int prefix; 195 if (!base::StringToInt(address_parts[1], &prefix) || prefix < 0) { 196 LOG(ERROR) << "Cannot parse address prefix " << address_parts[1]; 197 return false; 198 } 199 set_prefix(prefix); 200 return true; 201} 202 203void IPAddress::SetAddressToDefault() { 204 address_ = ByteString(GetAddressLength(family_)); 205} 206 207bool IPAddress::IntoString(string *address_string) const { 208 // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN 209 char address_buf[INET6_ADDRSTRLEN]; 210 if (GetLength() != GetAddressLength(family_) || 211 !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) { 212 return false; 213 } 214 *address_string = address_buf; 215 return true; 216} 217 218string IPAddress::ToString() const { 219 string out("<unknown>"); 220 IntoString(&out); 221 return out; 222} 223 224IPAddress IPAddress::MaskWith(const IPAddress &b) const { 225 CHECK(IsValid()); 226 CHECK(b.IsValid()); 227 CHECK_EQ(family(), b.family()); 228 229 ByteString address_bytes(address()); 230 address_bytes.BitwiseAnd(b.address()); 231 232 return IPAddress(family(), address_bytes); 233} 234 235IPAddress IPAddress::MergeWith(const IPAddress &b) const { 236 CHECK(IsValid()); 237 CHECK(b.IsValid()); 238 CHECK_EQ(family(), b.family()); 239 240 ByteString address_bytes(address()); 241 address_bytes.BitwiseOr(b.address()); 242 243 return IPAddress(family(), address_bytes); 244} 245 246IPAddress IPAddress::GetNetworkPart() const { 247 return MaskWith(GetAddressMaskFromPrefix(family(), prefix())); 248} 249 250IPAddress IPAddress::GetDefaultBroadcast() { 251 ByteString broadcast_bytes( 252 GetAddressMaskFromPrefix(family(), prefix()).address()); 253 broadcast_bytes.BitwiseInvert(); 254 return MergeWith(IPAddress(family(), broadcast_bytes)); 255} 256 257bool IPAddress::CanReachAddress(const IPAddress &b) const { 258 CHECK_EQ(family(), b.family()); 259 IPAddress b_prefixed(b); 260 b_prefixed.set_prefix(prefix()); 261 return GetNetworkPart().Equals(b_prefixed.GetNetworkPart()); 262} 263 264} // namespace shill 265