blob: 5281d8593a9a34ceac6693055b987166bfcf0aab [file] [log] [blame]
Paul Stewart188a84a2012-01-20 16:28:15 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewart1d18e8c2011-07-15 11:00:31 -07002// 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/ip_address.h"
6
Chris Masone2aa97072011-08-09 17:35:08 -07007#include <arpa/inet.h>
Paul Stewart1d18e8c2011-07-15 11:00:31 -07008#include <netinet/in.h>
9
10#include <string>
11
Darin Petkov14c29ec2012-03-02 11:34:19 +010012#include <base/logging.h>
13
Paul Stewart1d18e8c2011-07-15 11:00:31 -070014#include "shill/byte_string.h"
15
Paul Stewart188a84a2012-01-20 16:28:15 -080016using std::string;
17
Paul Stewart1d18e8c2011-07-15 11:00:31 -070018namespace shill {
19
Chris Masone2aa97072011-08-09 17:35:08 -070020// static
Paul Stewart7355ce12011-09-02 10:47:01 -070021const IPAddress::Family IPAddress::kFamilyUnknown = AF_UNSPEC;
Chris Masone2aa97072011-08-09 17:35:08 -070022// static
Paul Stewart7355ce12011-09-02 10:47:01 -070023const IPAddress::Family IPAddress::kFamilyIPv4 = AF_INET;
Chris Masone2aa97072011-08-09 17:35:08 -070024// static
Paul Stewart7355ce12011-09-02 10:47:01 -070025const IPAddress::Family IPAddress::kFamilyIPv6 = AF_INET6;
Chris Masone2aa97072011-08-09 17:35:08 -070026
Paul Stewartf748a362012-03-07 12:01:20 -080027// static
28const char IPAddress::kFamilyNameUnknown[] = "Unknown";
29// static
30const char IPAddress::kFamilyNameIPv4[] = "IPv4";
31// static
32const char IPAddress::kFamilyNameIPv6[] = "IPv6";
33
Paul Stewart1d18e8c2011-07-15 11:00:31 -070034IPAddress::IPAddress(Family family, const ByteString &address)
35 : family_(family) ,
Paul Stewart9e3fcd72011-08-26 15:46:16 -070036 address_(address),
37 prefix_(0) {}
38
39IPAddress::IPAddress(Family family,
40 const ByteString &address,
41 unsigned int prefix)
42 : family_(family) ,
43 address_(address),
44 prefix_(prefix) {}
Paul Stewart1d18e8c2011-07-15 11:00:31 -070045
46IPAddress::IPAddress(Family family)
Paul Stewart9e3fcd72011-08-26 15:46:16 -070047 : family_(family),
48 prefix_(0) {}
Paul Stewart1d18e8c2011-07-15 11:00:31 -070049
50IPAddress::~IPAddress() {}
51
Paul Stewartf748a362012-03-07 12:01:20 -080052// static
Eric Shienbroodc74cf9c2012-03-02 15:00:35 -050053size_t IPAddress::GetAddressLength(Family family) {
Paul Stewart1d18e8c2011-07-15 11:00:31 -070054 switch (family) {
Paul Stewart7355ce12011-09-02 10:47:01 -070055 case kFamilyIPv4:
Paul Stewart1d18e8c2011-07-15 11:00:31 -070056 return sizeof(in_addr);
Paul Stewart7355ce12011-09-02 10:47:01 -070057 case kFamilyIPv6:
Paul Stewart1d18e8c2011-07-15 11:00:31 -070058 return sizeof(in6_addr);
59 default:
60 return 0;
61 }
62}
63
Darin Petkov14c29ec2012-03-02 11:34:19 +010064// static
Eric Shienbroodb5c89402012-03-13 08:29:25 -070065int IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) {
Darin Petkov14c29ec2012-03-02 11:34:19 +010066 switch (family) {
67 case kFamilyIPv4: {
68 in_addr_t mask_val = inet_network(mask.c_str());
69 int subnet_cidr = 0;
70 while (mask_val) {
71 subnet_cidr++;
72 mask_val <<= 1;
73 }
74 return subnet_cidr;
75 }
76 case kFamilyIPv6:
77 NOTIMPLEMENTED();
78 break;
79 default:
80 LOG(WARNING) << "Unexpected address family: " << family;
81 break;
82 }
83 return 0;
84}
85
Paul Stewartf748a362012-03-07 12:01:20 -080086// static
87string IPAddress::GetAddressFamilyName(Family family) {
88 switch (family) {
89 case kFamilyIPv4:
90 return kFamilyNameIPv4;
91 case kFamilyIPv6:
92 return kFamilyNameIPv6;
93 default:
94 return kFamilyNameUnknown;
95 }
96}
97
Paul Stewart188a84a2012-01-20 16:28:15 -080098bool IPAddress::SetAddressFromString(const string &address_string) {
Eric Shienbroodc74cf9c2012-03-02 15:00:35 -050099 size_t address_length = GetAddressLength(family_);
Paul Stewart1d18e8c2011-07-15 11:00:31 -0700100
101 if (!address_length) {
102 return false;
103 }
104
105 ByteString address(address_length);
106 if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) {
107 return false;
108 }
109 address_ = address;
110 return true;
111}
112
113void IPAddress::SetAddressToDefault() {
114 address_ = ByteString(GetAddressLength(family_));
115}
116
mukesh agrawal2c15d2c2012-02-21 16:09:21 -0800117bool IPAddress::IntoString(string *address_string) const {
Paul Stewart188a84a2012-01-20 16:28:15 -0800118 // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN
119 char address_buf[INET6_ADDRSTRLEN];
120 if (GetLength() != GetAddressLength(family_) ||
121 !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) {
122 return false;
123 }
124 *address_string = address_buf;
125 return true;
126}
127
mukesh agrawal2c15d2c2012-02-21 16:09:21 -0800128string IPAddress::ToString() const {
129 string out("<unknown>");
130 IntoString(&out);
131 return out;
132}
133
Paul Stewart1d18e8c2011-07-15 11:00:31 -0700134} // namespace shill