Home | History | Annotate | Download | only in net
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "shill/net/ip_address.h"
     18 
     19 #include <arpa/inet.h>
     20 #include <netinet/in.h>
     21 
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/logging.h>
     26 #include <base/strings/string_number_conversions.h>
     27 #include <base/strings/string_split.h>
     28 
     29 #include "shill/net/byte_string.h"
     30 
     31 using std::string;
     32 using std::vector;
     33 
     34 namespace shill {
     35 
     36 namespace {
     37 const size_t kBitsPerByte = 8;
     38 }  // namespace
     39 
     40 // static
     41 const IPAddress::Family IPAddress::kFamilyUnknown = AF_UNSPEC;
     42 // static
     43 const IPAddress::Family IPAddress::kFamilyIPv4 = AF_INET;
     44 // static
     45 const IPAddress::Family IPAddress::kFamilyIPv6 = AF_INET6;
     46 
     47 // static
     48 const char IPAddress::kFamilyNameUnknown[] = "Unknown";
     49 // static
     50 const char IPAddress::kFamilyNameIPv4[] = "IPv4";
     51 // static
     52 const char IPAddress::kFamilyNameIPv6[] = "IPv6";
     53 
     54 IPAddress::IPAddress(Family family, const ByteString& address)
     55     : family_(family) ,
     56       address_(address),
     57       prefix_(0) {}
     58 
     59 IPAddress::IPAddress(Family family,
     60                      const ByteString& address,
     61                      unsigned int prefix)
     62     : family_(family) ,
     63       address_(address),
     64       prefix_(prefix) {}
     65 
     66 IPAddress::IPAddress(Family family)
     67     : family_(family),
     68       prefix_(0) {}
     69 
     70 IPAddress::IPAddress(std::string ip_string)
     71     : prefix_(0) {
     72   family_ = IPAddress::kFamilyIPv4;
     73   if (!SetAddressFromString(ip_string)) {
     74     family_ = IPAddress::kFamilyIPv6;
     75     if (!SetAddressFromString(ip_string)) {
     76       family_ = IPAddress::kFamilyUnknown;
     77     }
     78   }
     79 }
     80 
     81 IPAddress::IPAddress(const sockaddr* address_struct, size_t size)
     82     : family_(kFamilyUnknown),
     83       prefix_(0) {
     84   if (address_struct->sa_family == kFamilyIPv4 && size >= sizeof(sockaddr_in)) {
     85     family_ = address_struct->sa_family;
     86     auto sin = reinterpret_cast<const sockaddr_in*>(address_struct);
     87     // Preserve network byte order of s_addr.
     88     auto bytes = reinterpret_cast<const uint8_t*>(&sin->sin_addr.s_addr);
     89     address_ = ByteString(bytes, sizeof(sin->sin_addr.s_addr));
     90   } else if (address_struct->sa_family == kFamilyIPv6 &&
     91              size >= sizeof(sockaddr_in6)) {
     92     family_ = address_struct->sa_family;
     93     auto sin6 = reinterpret_cast<const sockaddr_in6*>(address_struct);
     94     address_ = ByteString(sin6->sin6_addr.s6_addr,
     95                           sizeof(sin6->sin6_addr.s6_addr));
     96   }
     97 }
     98 
     99 IPAddress::~IPAddress() {}
    100 
    101 // static
    102 size_t IPAddress::GetAddressLength(Family family) {
    103   switch (family) {
    104   case kFamilyIPv4:
    105     return sizeof(in_addr);
    106   case kFamilyIPv6:
    107     return sizeof(in6_addr);
    108   default:
    109     return 0;
    110   }
    111 }
    112 
    113 // static
    114 size_t IPAddress::GetMaxPrefixLength(Family family) {
    115   return GetAddressLength(family) * kBitsPerByte;
    116 }
    117 
    118 size_t IPAddress::GetMinPrefixLength() const {
    119   if (family() != kFamilyIPv4) {
    120     NOTIMPLEMENTED() << ": only implemented for IPv4";
    121     return GetMaxPrefixLength(family());
    122   }
    123 
    124   CHECK(IsValid());
    125   in_addr_t address_val;
    126   memcpy(&address_val, GetConstData(), sizeof(address_val));
    127   // IN_CLASSx() macros operate on addresses in host-order.
    128   address_val = ntohl(address_val);
    129   if (IN_CLASSA(address_val)) {
    130     return GetMaxPrefixLength(family()) - IN_CLASSA_NSHIFT;
    131   } else if (IN_CLASSB(address_val)) {
    132     return GetMaxPrefixLength(family()) - IN_CLASSB_NSHIFT;
    133   } else if (IN_CLASSC(address_val)) {
    134     return GetMaxPrefixLength(family()) - IN_CLASSC_NSHIFT;
    135   }
    136 
    137   LOG(ERROR) << "Invalid IPv4 address class";
    138   return GetMaxPrefixLength(family());
    139 }
    140 
    141 // static
    142 size_t IPAddress::GetPrefixLengthFromMask(Family family, const string& mask) {
    143   switch (family) {
    144     case kFamilyIPv4: {
    145       in_addr_t mask_val = inet_network(mask.c_str());
    146       int subnet_prefix = 0;
    147       while (mask_val) {
    148         subnet_prefix++;
    149         mask_val <<= 1;
    150       }
    151       return subnet_prefix;
    152     }
    153     case kFamilyIPv6:
    154       NOTIMPLEMENTED();
    155       break;
    156     default:
    157       LOG(WARNING) << "Unexpected address family: " << family;
    158       break;
    159   }
    160   return 0;
    161 }
    162 
    163 // static
    164 IPAddress IPAddress::GetAddressMaskFromPrefix(Family family, size_t prefix) {
    165   ByteString address_bytes(GetAddressLength(family));
    166   unsigned char* address_ptr = address_bytes.GetData();
    167 
    168   size_t bits = prefix;
    169   if (bits > GetMaxPrefixLength(family)) {
    170     bits = GetMaxPrefixLength(family);
    171   }
    172 
    173   while (bits > kBitsPerByte) {
    174     bits -= kBitsPerByte;
    175     *address_ptr++ = std::numeric_limits<uint8_t>::max();
    176   }
    177 
    178   // We are guaranteed to be before the end of the address data since even
    179   // if the prefix is the maximum, the loop above will end before we assign
    180   // and increment past the last byte.
    181   *address_ptr = ~((1 << (kBitsPerByte - bits)) - 1);
    182 
    183   return IPAddress(family, address_bytes);
    184 }
    185 
    186 // static
    187 string IPAddress::GetAddressFamilyName(Family family) {
    188   switch (family) {
    189   case kFamilyIPv4:
    190     return kFamilyNameIPv4;
    191   case kFamilyIPv6:
    192     return kFamilyNameIPv6;
    193   default:
    194     return kFamilyNameUnknown;
    195   }
    196 }
    197 
    198 bool IPAddress::SetAddressFromString(const string& address_string) {
    199   size_t address_length = GetAddressLength(family_);
    200 
    201   if (!address_length) {
    202     return false;
    203   }
    204 
    205   ByteString address(address_length);
    206   if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) {
    207     return false;
    208   }
    209   address_ = address;
    210   return true;
    211 }
    212 
    213 bool IPAddress::SetAddressAndPrefixFromString(const string& address_string) {
    214   vector<string> address_parts = base::SplitString(
    215       address_string, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    216   if (address_parts.size() != 2) {
    217     LOG(ERROR) << "Cannot split address " << address_string;
    218     return false;
    219   }
    220   if (!SetAddressFromString(address_parts[0])) {
    221     LOG(ERROR) << "Cannot parse address string " << address_parts[0];
    222     return false;
    223   }
    224   size_t prefix;
    225   if (!base::StringToSizeT(address_parts[1], &prefix) ||
    226       prefix > GetMaxPrefixLength(family_)) {
    227     LOG(ERROR) << "Cannot parse address prefix " << address_parts[1];
    228     return false;
    229   }
    230   set_prefix(prefix);
    231   return true;
    232 }
    233 
    234 void IPAddress::SetAddressToDefault() {
    235   address_ = ByteString(GetAddressLength(family_));
    236 }
    237 
    238 bool IPAddress::IntoString(string* address_string) const {
    239   // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN
    240   char address_buf[INET6_ADDRSTRLEN];
    241   if (GetLength() != GetAddressLength(family_) ||
    242       !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) {
    243     return false;
    244   }
    245   *address_string = address_buf;
    246   return true;
    247 }
    248 
    249 string IPAddress::ToString() const {
    250   string out("<unknown>");
    251   IntoString(&out);
    252   return out;
    253 }
    254 
    255 bool IPAddress::IntoSockAddr(sockaddr* address_struct, size_t size) const {
    256   if (!IsValid()) {
    257     return false;
    258   }
    259   if (family_ == kFamilyIPv4 && size >= sizeof(sockaddr_in)) {
    260     auto sin = reinterpret_cast<sockaddr_in*>(address_struct);
    261     memcpy(&sin->sin_addr.s_addr, GetConstData(), GetLength());
    262   } else if (family_ == kFamilyIPv6 && size >= sizeof(sockaddr_in6)) {
    263     auto sin6 = reinterpret_cast<sockaddr_in6*>(address_struct);
    264     memcpy(&sin6->sin6_addr.s6_addr, GetConstData(), GetLength());
    265   } else {
    266     return false;
    267   }
    268   address_struct->sa_family = family_;
    269   return true;
    270 }
    271 
    272 bool IPAddress::Equals(const IPAddress& b) const {
    273   return family_ == b.family_ && address_.Equals(b.address_) &&
    274       prefix_ == b.prefix_;
    275 }
    276 
    277 bool IPAddress::HasSameAddressAs(const IPAddress& b) const {
    278   return family_ == b.family_ && address_.Equals(b.address_);
    279 }
    280 
    281 IPAddress IPAddress::MaskWith(const IPAddress& b) const {
    282   CHECK(IsValid());
    283   CHECK(b.IsValid());
    284   CHECK_EQ(family(), b.family());
    285 
    286   ByteString address_bytes(address());
    287   address_bytes.BitwiseAnd(b.address());
    288 
    289   return IPAddress(family(), address_bytes);
    290 }
    291 
    292 IPAddress IPAddress::MergeWith(const IPAddress& b) const {
    293   CHECK(IsValid());
    294   CHECK(b.IsValid());
    295   CHECK_EQ(family(), b.family());
    296 
    297   ByteString address_bytes(address());
    298   address_bytes.BitwiseOr(b.address());
    299 
    300   return IPAddress(family(), address_bytes);
    301 }
    302 
    303 IPAddress IPAddress::GetNetworkPart() const {
    304   return MaskWith(GetAddressMaskFromPrefix(family(), prefix()));
    305 }
    306 
    307 IPAddress IPAddress::GetDefaultBroadcast() {
    308   ByteString broadcast_bytes(
    309     GetAddressMaskFromPrefix(family(), prefix()).address());
    310   broadcast_bytes.BitwiseInvert();
    311   return MergeWith(IPAddress(family(), broadcast_bytes));
    312 }
    313 
    314 bool IPAddress::CanReachAddress(const IPAddress& b) const {
    315   CHECK_EQ(family(), b.family());
    316   IPAddress b_prefixed(b);
    317   b_prefixed.set_prefix(prefix());
    318   return GetNetworkPart().Equals(b_prefixed.GetNetworkPart());
    319 }
    320 
    321 }  // namespace shill
    322