blob: 1e36d55af29d795bc548163c96335cfb412036fa [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
Paul Stewart48100b02012-03-19 07:53:52 -070065size_t IPAddress::GetMaxPrefixLength(Family family) {
66 return GetAddressLength(family) * 8;
67}
68
69// static
Eric Shienbrood3e20a232012-02-16 11:35:56 -050070size_t IPAddress::GetPrefixLengthFromMask(Family family, const string &mask) {
Darin Petkov14c29ec2012-03-02 11:34:19 +010071 switch (family) {
72 case kFamilyIPv4: {
73 in_addr_t mask_val = inet_network(mask.c_str());
Paul Stewart48100b02012-03-19 07:53:52 -070074 int subnet_prefix = 0;
Darin Petkov14c29ec2012-03-02 11:34:19 +010075 while (mask_val) {
Paul Stewart48100b02012-03-19 07:53:52 -070076 subnet_prefix++;
Darin Petkov14c29ec2012-03-02 11:34:19 +010077 mask_val <<= 1;
78 }
Paul Stewart48100b02012-03-19 07:53:52 -070079 return subnet_prefix;
Darin Petkov14c29ec2012-03-02 11:34:19 +010080 }
81 case kFamilyIPv6:
82 NOTIMPLEMENTED();
83 break;
84 default:
85 LOG(WARNING) << "Unexpected address family: " << family;
86 break;
87 }
88 return 0;
89}
90
Paul Stewartf748a362012-03-07 12:01:20 -080091// static
92string IPAddress::GetAddressFamilyName(Family family) {
93 switch (family) {
94 case kFamilyIPv4:
95 return kFamilyNameIPv4;
96 case kFamilyIPv6:
97 return kFamilyNameIPv6;
98 default:
99 return kFamilyNameUnknown;
100 }
101}
102
Paul Stewart188a84a2012-01-20 16:28:15 -0800103bool IPAddress::SetAddressFromString(const string &address_string) {
Eric Shienbroodc74cf9c2012-03-02 15:00:35 -0500104 size_t address_length = GetAddressLength(family_);
Paul Stewart1d18e8c2011-07-15 11:00:31 -0700105
106 if (!address_length) {
107 return false;
108 }
109
110 ByteString address(address_length);
111 if (inet_pton(family_, address_string.c_str(), address.GetData()) <= 0) {
112 return false;
113 }
114 address_ = address;
115 return true;
116}
117
118void IPAddress::SetAddressToDefault() {
119 address_ = ByteString(GetAddressLength(family_));
120}
121
mukesh agrawal2c15d2c2012-02-21 16:09:21 -0800122bool IPAddress::IntoString(string *address_string) const {
Paul Stewart188a84a2012-01-20 16:28:15 -0800123 // Noting that INET6_ADDRSTRLEN > INET_ADDRSTRLEN
124 char address_buf[INET6_ADDRSTRLEN];
125 if (GetLength() != GetAddressLength(family_) ||
126 !inet_ntop(family_, GetConstData(), address_buf, sizeof(address_buf))) {
127 return false;
128 }
129 *address_string = address_buf;
130 return true;
131}
132
mukesh agrawal2c15d2c2012-02-21 16:09:21 -0800133string IPAddress::ToString() const {
134 string out("<unknown>");
135 IntoString(&out);
136 return out;
137}
138
Paul Stewart1d18e8c2011-07-15 11:00:31 -0700139} // namespace shill