• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IPAddress(Family family,const ByteString & address)54 IPAddress::IPAddress(Family family, const ByteString& address)
55     : family_(family) ,
56       address_(address),
57       prefix_(0) {}
58 
IPAddress(Family family,const ByteString & address,unsigned int prefix)59 IPAddress::IPAddress(Family family,
60                      const ByteString& address,
61                      unsigned int prefix)
62     : family_(family) ,
63       address_(address),
64       prefix_(prefix) {}
65 
IPAddress(Family family)66 IPAddress::IPAddress(Family family)
67     : family_(family),
68       prefix_(0) {}
69 
IPAddress(std::string ip_string)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 
IPAddress(const sockaddr * address_struct,size_t size)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 
~IPAddress()99 IPAddress::~IPAddress() {}
100 
101 // static
GetAddressLength(Family family)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
GetMaxPrefixLength(Family family)114 size_t IPAddress::GetMaxPrefixLength(Family family) {
115   return GetAddressLength(family) * kBitsPerByte;
116 }
117 
GetMinPrefixLength() const118 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
GetPrefixLengthFromMask(Family family,const string & mask)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
GetAddressMaskFromPrefix(Family family,size_t prefix)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
GetAddressFamilyName(Family family)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 
SetAddressFromString(const string & address_string)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 
SetAddressAndPrefixFromString(const string & address_string)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 
SetAddressToDefault()234 void IPAddress::SetAddressToDefault() {
235   address_ = ByteString(GetAddressLength(family_));
236 }
237 
IntoString(string * address_string) const238 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 
ToString() const249 string IPAddress::ToString() const {
250   string out("<unknown>");
251   IntoString(&out);
252   return out;
253 }
254 
IntoSockAddr(sockaddr * address_struct,size_t size) const255 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 
Equals(const IPAddress & b) const272 bool IPAddress::Equals(const IPAddress& b) const {
273   return family_ == b.family_ && address_.Equals(b.address_) &&
274       prefix_ == b.prefix_;
275 }
276 
HasSameAddressAs(const IPAddress & b) const277 bool IPAddress::HasSameAddressAs(const IPAddress& b) const {
278   return family_ == b.family_ && address_.Equals(b.address_);
279 }
280 
MaskWith(const IPAddress & b) const281 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 
MergeWith(const IPAddress & b) const292 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 
GetNetworkPart() const303 IPAddress IPAddress::GetNetworkPart() const {
304   return MaskWith(GetAddressMaskFromPrefix(family(), prefix()));
305 }
306 
GetDefaultBroadcast()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 
CanReachAddress(const IPAddress & b) const314 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