-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathip_address.h
218 lines (172 loc) · 8.08 KB
/
ip_address.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_BASE_IP_ADDRESS_H_
#define NET_BASE_IP_ADDRESS_H_
#include <sys/socket.h>
#include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include <base/containers/span.h>
#include "net-base/export.h"
#include "net-base/ipv4_address.h"
#include "net-base/ipv6_address.h"
namespace net_base {
// Represents the family of the IP protocol.
enum class NET_BASE_EXPORT IPFamily {
kIPv4,
kIPv6,
};
// Helper const for iterating through both IP families.
constexpr std::initializer_list<IPFamily> kIPFamilies = {IPFamily::kIPv4,
IPFamily::kIPv6};
// Converts from IPFamily enum to sa_family_t.
NET_BASE_EXPORT sa_family_t ToSAFamily(IPFamily family);
// Converts from sa_family_t to IPFamily enum.
// Returns std::nullopt if the value cannot be converted.
NET_BASE_EXPORT std::optional<IPFamily> FromSAFamily(sa_family_t family);
// Converts from IPFamily enum to std::String.
NET_BASE_EXPORT std::string ToString(IPFamily family);
// Represents an family-agnostic IP address, either a IPv4 or a IPv6 address.
class NET_BASE_EXPORT IPAddress {
public:
// Creates the IPAddress from IPv4 dotted-decimal notation or IPv6 network
// address format.
// If |family| is not nullopt, then only returns the valid IP address with the
// assigned IP family.
static std::optional<IPAddress> CreateFromString(
std::string_view address_string,
std::optional<IPFamily> family = std::nullopt);
// Creates the IPAddress from the raw byte buffer |bytes|.
// Returns std::nullopt if |bytes|'s size is not the same as
// IPv4Address::kAddressLength or IPv6Address::kAddressLength.
// If |family| is not nullopt, then only returns the valid IP address with the
// assigned IP family.
static std::optional<IPAddress> CreateFromBytes(
base::span<const char> bytes,
std::optional<IPFamily> family = std::nullopt);
static std::optional<IPAddress> CreateFromBytes(
base::span<const uint8_t> bytes,
std::optional<IPFamily> family = std::nullopt);
// Creates the IPAddress by the family. The created address is all-zero.
// (i.e. "0.0.0.0" for IPv4, "::" for IPv6)
explicit constexpr IPAddress(IPFamily family)
: address_(family == IPFamily::kIPv4
? std::variant<IPv4Address, IPv6Address>(IPv4Address())
: std::variant<IPv4Address, IPv6Address>(IPv6Address())) {}
explicit constexpr IPAddress(const IPv4Address& address)
: address_(address) {}
explicit constexpr IPAddress(const IPv6Address& address)
: address_(address) {}
// Returns true if the address is "0.0.0.0" or "::".
bool IsZero() const;
// Compares with |rhs|. The comparation rule follows IPv4Address and
// IPv6Address if the family of |rhs| is the same. Otherwise, the IPv4Address
// is less than IPv6Address.
bool operator==(const IPAddress& rhs) const;
bool operator!=(const IPAddress& rhs) const;
bool operator<(const IPAddress& rhs) const;
// Returns the family of the IP address.
IPFamily GetFamily() const;
// Returns the length in bytes of an address of |family|.
static size_t GetAddressLength(IPFamily family);
// Returns the length in bytes of this address object.
size_t GetAddressLength() const;
// Converts to the family-specific classes. Returns std::nullopt if the IP
// family is not the same.
std::optional<IPv4Address> ToIPv4Address() const;
std::optional<IPv6Address> ToIPv6Address() const;
// Returns the address in byte, stored in network order (i.e. big endian).
std::vector<uint8_t> ToBytes() const;
std::string ToByteString() const;
// Returns the address in the IPv4 dotted-decimal notation or IPv6 network
// address format.
std::string ToString() const;
private:
std::variant<IPv4Address, IPv6Address> address_;
};
// Represents an family-agnostic IP CIDR, either a IPv4 or a IPv6 CIDR.
class NET_BASE_EXPORT IPCIDR {
public:
// Returns the maximum prefix length for address family |family|, i.e.,
// the length of this address type in bits.
static int GetMaxPrefixLength(IPFamily family);
// Creates the CIDR from either IPv4 or IPv6 CIDR notation.
// Returns std::nullopt if the string format is invalid.
// If |family| is not nullopt, then only returns the valid result with the
// assigned IP family.
static std::optional<IPCIDR> CreateFromCIDRString(
std::string_view cidr_string,
std::optional<IPFamily> family = std::nullopt);
// Creates the CIDR from the IP address notation string and the prefix length.
// Returns std::nullopt if the string format or the prefix length is invalid.
// If |family| is not nullopt, then only returns the valid result with the
// assigned IP family.
static std::optional<IPCIDR> CreateFromStringAndPrefix(
std::string_view address_string,
int prefix_length,
std::optional<IPFamily> family = std::nullopt);
// Creates the CIDR from the the raw byte buffer |bytes| and the prefix
// length. Returns std::nullopt if the |bytes|'s size or the prefix length is
// invalid. If |family| is not nullopt, then only returns the valid result
// with the assigned IP family.
static std::optional<IPCIDR> CreateFromBytesAndPrefix(
base::span<const char> bytes,
int prefix_length,
std::optional<IPFamily> family = std::nullopt);
static std::optional<IPCIDR> CreateFromBytesAndPrefix(
base::span<const uint8_t> bytes,
int prefix_length,
std::optional<IPFamily> family = std::nullopt);
// Creates the CIDR from the Address and the prefix length. Returns
// std::nullopt if the prefix length is invalid.
static std::optional<IPCIDR> CreateFromAddressAndPrefix(
const IPAddress& address, int prefix_length);
// Creates the IPCIDR by the family. The created CIDR is all-zero.
// (i.e. "0.0.0.0/0" for IPv4, "::/0" for IPv6)
explicit constexpr IPCIDR(IPFamily family)
: cidr_(family == IPFamily::kIPv4
? std::variant<IPv4CIDR, IPv6CIDR>(IPv4CIDR())
: std::variant<IPv4CIDR, IPv6CIDR>(IPv6CIDR())) {}
explicit constexpr IPCIDR(const IPv4CIDR& cidr) : cidr_(cidr) {}
explicit constexpr IPCIDR(const IPv6CIDR& cidr) : cidr_(cidr) {}
explicit constexpr IPCIDR(const IPv4Address& addr) : cidr_(IPv4CIDR(addr)) {}
explicit constexpr IPCIDR(const IPv6Address& addr) : cidr_(IPv6CIDR(addr)) {}
// Getter methods for the internal data.
IPAddress address() const;
int prefix_length() const;
bool operator==(const IPCIDR& rhs) const;
bool operator!=(const IPCIDR& rhs) const;
// Returns the family of the CIDR.
IPFamily GetFamily() const;
// Converts to the family-specific classes. Returns std::nullopt if the IP
// family is not the same.
std::optional<IPv4CIDR> ToIPv4CIDR() const;
std::optional<IPv6CIDR> ToIPv6CIDR() const;
// Creates the Address that has all the high-order of prefix length bits set.
IPAddress ToNetmask() const;
// Returns an CIDR that represents the network-part of the address
// (i.e, the address with all but the prefix bits masked out) and the same
// prefix length as |this|.
IPCIDR GetPrefixCIDR() const;
// Returns the broadcast address for the IP address, by setting all of the
// host-part bits to 1.
IPAddress GetBroadcast() const;
// Returns true if the address |b| is in the same subnet with |*this| CIDR.
bool InSameSubnetWith(const IPAddress& b) const;
// Returns true if the address is all-zero and prefix length is 0.
// (i.e. "0.0.0.0/0" for IPv4, "::/0" for IPv6)
bool IsDefault() const;
// Returns the string in the CIDR notation.
std::string ToString() const;
private:
std::variant<IPv4CIDR, IPv6CIDR> cidr_;
};
NET_BASE_EXPORT std::ostream& operator<<(std::ostream& os, IPFamily family);
NET_BASE_EXPORT std::ostream& operator<<(std::ostream& os,
const IPAddress& address);
NET_BASE_EXPORT std::ostream& operator<<(std::ostream& os, const IPCIDR& cidr);
} // namespace net_base
#endif // NET_BASE_IP_ADDRESS_H_