1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX)
12*d9f75844SAndroid Build Coastguard Worker #include <netinet/in.h>
13*d9f75844SAndroid Build Coastguard Worker #include <sys/socket.h>
14*d9f75844SAndroid Build Coastguard Worker
15*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
16*d9f75844SAndroid Build Coastguard Worker #ifdef OPENBSD
17*d9f75844SAndroid Build Coastguard Worker #include <netinet/in_systm.h>
18*d9f75844SAndroid Build Coastguard Worker #endif
19*d9f75844SAndroid Build Coastguard Worker #ifndef __native_client__
20*d9f75844SAndroid Build Coastguard Worker #include <netinet/ip.h>
21*d9f75844SAndroid Build Coastguard Worker #endif
22*d9f75844SAndroid Build Coastguard Worker #include <netdb.h>
23*d9f75844SAndroid Build Coastguard Worker #endif
24*d9f75844SAndroid Build Coastguard Worker
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ip_address.h"
26*d9f75844SAndroid Build Coastguard Worker
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/byte_order.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/net_helpers.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/string_utils.h"
30*d9f75844SAndroid Build Coastguard Worker
31*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
32*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/win32.h"
33*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_WIN
34*d9f75844SAndroid Build Coastguard Worker
35*d9f75844SAndroid Build Coastguard Worker namespace rtc {
36*d9f75844SAndroid Build Coastguard Worker
37*d9f75844SAndroid Build Coastguard Worker // Prefixes used for categorizing IPv6 addresses.
38*d9f75844SAndroid Build Coastguard Worker static const in6_addr kV4MappedPrefix = {
39*d9f75844SAndroid Build Coastguard Worker {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0}}};
40*d9f75844SAndroid Build Coastguard Worker static const in6_addr k6To4Prefix = {{{0x20, 0x02, 0}}};
41*d9f75844SAndroid Build Coastguard Worker static const in6_addr kTeredoPrefix = {{{0x20, 0x01, 0x00, 0x00}}};
42*d9f75844SAndroid Build Coastguard Worker static const in6_addr kV4CompatibilityPrefix = {{{0}}};
43*d9f75844SAndroid Build Coastguard Worker static const in6_addr k6BonePrefix = {{{0x3f, 0xfe, 0}}};
44*d9f75844SAndroid Build Coastguard Worker static const in6_addr kPrivateNetworkPrefix = {{{0xFD}}};
45*d9f75844SAndroid Build Coastguard Worker
46*d9f75844SAndroid Build Coastguard Worker static bool IPIsHelper(const IPAddress& ip,
47*d9f75844SAndroid Build Coastguard Worker const in6_addr& tomatch,
48*d9f75844SAndroid Build Coastguard Worker int length);
49*d9f75844SAndroid Build Coastguard Worker static in_addr ExtractMappedAddress(const in6_addr& addr);
50*d9f75844SAndroid Build Coastguard Worker
v4AddressAsHostOrderInteger() const51*d9f75844SAndroid Build Coastguard Worker uint32_t IPAddress::v4AddressAsHostOrderInteger() const {
52*d9f75844SAndroid Build Coastguard Worker if (family_ == AF_INET) {
53*d9f75844SAndroid Build Coastguard Worker return NetworkToHost32(u_.ip4.s_addr);
54*d9f75844SAndroid Build Coastguard Worker } else {
55*d9f75844SAndroid Build Coastguard Worker return 0;
56*d9f75844SAndroid Build Coastguard Worker }
57*d9f75844SAndroid Build Coastguard Worker }
58*d9f75844SAndroid Build Coastguard Worker
overhead() const59*d9f75844SAndroid Build Coastguard Worker int IPAddress::overhead() const {
60*d9f75844SAndroid Build Coastguard Worker switch (family_) {
61*d9f75844SAndroid Build Coastguard Worker case AF_INET: // IPv4
62*d9f75844SAndroid Build Coastguard Worker return 20;
63*d9f75844SAndroid Build Coastguard Worker case AF_INET6: // IPv6
64*d9f75844SAndroid Build Coastguard Worker return 40;
65*d9f75844SAndroid Build Coastguard Worker default:
66*d9f75844SAndroid Build Coastguard Worker return 0;
67*d9f75844SAndroid Build Coastguard Worker }
68*d9f75844SAndroid Build Coastguard Worker }
69*d9f75844SAndroid Build Coastguard Worker
IsNil() const70*d9f75844SAndroid Build Coastguard Worker bool IPAddress::IsNil() const {
71*d9f75844SAndroid Build Coastguard Worker return IPIsUnspec(*this);
72*d9f75844SAndroid Build Coastguard Worker }
73*d9f75844SAndroid Build Coastguard Worker
Size() const74*d9f75844SAndroid Build Coastguard Worker size_t IPAddress::Size() const {
75*d9f75844SAndroid Build Coastguard Worker switch (family_) {
76*d9f75844SAndroid Build Coastguard Worker case AF_INET:
77*d9f75844SAndroid Build Coastguard Worker return sizeof(in_addr);
78*d9f75844SAndroid Build Coastguard Worker case AF_INET6:
79*d9f75844SAndroid Build Coastguard Worker return sizeof(in6_addr);
80*d9f75844SAndroid Build Coastguard Worker }
81*d9f75844SAndroid Build Coastguard Worker return 0;
82*d9f75844SAndroid Build Coastguard Worker }
83*d9f75844SAndroid Build Coastguard Worker
operator ==(const IPAddress & other) const84*d9f75844SAndroid Build Coastguard Worker bool IPAddress::operator==(const IPAddress& other) const {
85*d9f75844SAndroid Build Coastguard Worker if (family_ != other.family_) {
86*d9f75844SAndroid Build Coastguard Worker return false;
87*d9f75844SAndroid Build Coastguard Worker }
88*d9f75844SAndroid Build Coastguard Worker if (family_ == AF_INET) {
89*d9f75844SAndroid Build Coastguard Worker return memcmp(&u_.ip4, &other.u_.ip4, sizeof(u_.ip4)) == 0;
90*d9f75844SAndroid Build Coastguard Worker }
91*d9f75844SAndroid Build Coastguard Worker if (family_ == AF_INET6) {
92*d9f75844SAndroid Build Coastguard Worker return memcmp(&u_.ip6, &other.u_.ip6, sizeof(u_.ip6)) == 0;
93*d9f75844SAndroid Build Coastguard Worker }
94*d9f75844SAndroid Build Coastguard Worker return family_ == AF_UNSPEC;
95*d9f75844SAndroid Build Coastguard Worker }
96*d9f75844SAndroid Build Coastguard Worker
operator !=(const IPAddress & other) const97*d9f75844SAndroid Build Coastguard Worker bool IPAddress::operator!=(const IPAddress& other) const {
98*d9f75844SAndroid Build Coastguard Worker return !((*this) == other);
99*d9f75844SAndroid Build Coastguard Worker }
100*d9f75844SAndroid Build Coastguard Worker
operator >(const IPAddress & other) const101*d9f75844SAndroid Build Coastguard Worker bool IPAddress::operator>(const IPAddress& other) const {
102*d9f75844SAndroid Build Coastguard Worker return (*this) != other && !((*this) < other);
103*d9f75844SAndroid Build Coastguard Worker }
104*d9f75844SAndroid Build Coastguard Worker
operator <(const IPAddress & other) const105*d9f75844SAndroid Build Coastguard Worker bool IPAddress::operator<(const IPAddress& other) const {
106*d9f75844SAndroid Build Coastguard Worker // IPv4 is 'less than' IPv6
107*d9f75844SAndroid Build Coastguard Worker if (family_ != other.family_) {
108*d9f75844SAndroid Build Coastguard Worker if (family_ == AF_UNSPEC) {
109*d9f75844SAndroid Build Coastguard Worker return true;
110*d9f75844SAndroid Build Coastguard Worker }
111*d9f75844SAndroid Build Coastguard Worker if (family_ == AF_INET && other.family_ == AF_INET6) {
112*d9f75844SAndroid Build Coastguard Worker return true;
113*d9f75844SAndroid Build Coastguard Worker }
114*d9f75844SAndroid Build Coastguard Worker return false;
115*d9f75844SAndroid Build Coastguard Worker }
116*d9f75844SAndroid Build Coastguard Worker // Comparing addresses of the same family.
117*d9f75844SAndroid Build Coastguard Worker switch (family_) {
118*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
119*d9f75844SAndroid Build Coastguard Worker return NetworkToHost32(u_.ip4.s_addr) <
120*d9f75844SAndroid Build Coastguard Worker NetworkToHost32(other.u_.ip4.s_addr);
121*d9f75844SAndroid Build Coastguard Worker }
122*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
123*d9f75844SAndroid Build Coastguard Worker return memcmp(&u_.ip6.s6_addr, &other.u_.ip6.s6_addr, 16) < 0;
124*d9f75844SAndroid Build Coastguard Worker }
125*d9f75844SAndroid Build Coastguard Worker }
126*d9f75844SAndroid Build Coastguard Worker // Catches AF_UNSPEC and invalid addresses.
127*d9f75844SAndroid Build Coastguard Worker return false;
128*d9f75844SAndroid Build Coastguard Worker }
129*d9f75844SAndroid Build Coastguard Worker
ipv6_address() const130*d9f75844SAndroid Build Coastguard Worker in6_addr IPAddress::ipv6_address() const {
131*d9f75844SAndroid Build Coastguard Worker return u_.ip6;
132*d9f75844SAndroid Build Coastguard Worker }
133*d9f75844SAndroid Build Coastguard Worker
ipv4_address() const134*d9f75844SAndroid Build Coastguard Worker in_addr IPAddress::ipv4_address() const {
135*d9f75844SAndroid Build Coastguard Worker return u_.ip4;
136*d9f75844SAndroid Build Coastguard Worker }
137*d9f75844SAndroid Build Coastguard Worker
ToString() const138*d9f75844SAndroid Build Coastguard Worker std::string IPAddress::ToString() const {
139*d9f75844SAndroid Build Coastguard Worker if (family_ != AF_INET && family_ != AF_INET6) {
140*d9f75844SAndroid Build Coastguard Worker return std::string();
141*d9f75844SAndroid Build Coastguard Worker }
142*d9f75844SAndroid Build Coastguard Worker char buf[INET6_ADDRSTRLEN] = {0};
143*d9f75844SAndroid Build Coastguard Worker const void* src = &u_.ip4;
144*d9f75844SAndroid Build Coastguard Worker if (family_ == AF_INET6) {
145*d9f75844SAndroid Build Coastguard Worker src = &u_.ip6;
146*d9f75844SAndroid Build Coastguard Worker }
147*d9f75844SAndroid Build Coastguard Worker if (!rtc::inet_ntop(family_, src, buf, sizeof(buf))) {
148*d9f75844SAndroid Build Coastguard Worker return std::string();
149*d9f75844SAndroid Build Coastguard Worker }
150*d9f75844SAndroid Build Coastguard Worker return std::string(buf);
151*d9f75844SAndroid Build Coastguard Worker }
152*d9f75844SAndroid Build Coastguard Worker
ToSensitiveString() const153*d9f75844SAndroid Build Coastguard Worker std::string IPAddress::ToSensitiveString() const {
154*d9f75844SAndroid Build Coastguard Worker switch (family_) {
155*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
156*d9f75844SAndroid Build Coastguard Worker std::string address = ToString();
157*d9f75844SAndroid Build Coastguard Worker size_t find_pos = address.rfind('.');
158*d9f75844SAndroid Build Coastguard Worker if (find_pos == std::string::npos)
159*d9f75844SAndroid Build Coastguard Worker return std::string();
160*d9f75844SAndroid Build Coastguard Worker address.resize(find_pos);
161*d9f75844SAndroid Build Coastguard Worker address += ".x";
162*d9f75844SAndroid Build Coastguard Worker return address;
163*d9f75844SAndroid Build Coastguard Worker }
164*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
165*d9f75844SAndroid Build Coastguard Worker std::string result;
166*d9f75844SAndroid Build Coastguard Worker result.resize(INET6_ADDRSTRLEN);
167*d9f75844SAndroid Build Coastguard Worker in6_addr addr = ipv6_address();
168*d9f75844SAndroid Build Coastguard Worker size_t len = snprintf(&(result[0]), result.size(), "%x:%x:%x:x:x:x:x:x",
169*d9f75844SAndroid Build Coastguard Worker (addr.s6_addr[0] << 8) + addr.s6_addr[1],
170*d9f75844SAndroid Build Coastguard Worker (addr.s6_addr[2] << 8) + addr.s6_addr[3],
171*d9f75844SAndroid Build Coastguard Worker (addr.s6_addr[4] << 8) + addr.s6_addr[5]);
172*d9f75844SAndroid Build Coastguard Worker result.resize(len);
173*d9f75844SAndroid Build Coastguard Worker return result;
174*d9f75844SAndroid Build Coastguard Worker }
175*d9f75844SAndroid Build Coastguard Worker }
176*d9f75844SAndroid Build Coastguard Worker return std::string();
177*d9f75844SAndroid Build Coastguard Worker }
178*d9f75844SAndroid Build Coastguard Worker
Normalized() const179*d9f75844SAndroid Build Coastguard Worker IPAddress IPAddress::Normalized() const {
180*d9f75844SAndroid Build Coastguard Worker if (family_ != AF_INET6) {
181*d9f75844SAndroid Build Coastguard Worker return *this;
182*d9f75844SAndroid Build Coastguard Worker }
183*d9f75844SAndroid Build Coastguard Worker if (!IPIsV4Mapped(*this)) {
184*d9f75844SAndroid Build Coastguard Worker return *this;
185*d9f75844SAndroid Build Coastguard Worker }
186*d9f75844SAndroid Build Coastguard Worker in_addr addr = ExtractMappedAddress(u_.ip6);
187*d9f75844SAndroid Build Coastguard Worker return IPAddress(addr);
188*d9f75844SAndroid Build Coastguard Worker }
189*d9f75844SAndroid Build Coastguard Worker
AsIPv6Address() const190*d9f75844SAndroid Build Coastguard Worker IPAddress IPAddress::AsIPv6Address() const {
191*d9f75844SAndroid Build Coastguard Worker if (family_ != AF_INET) {
192*d9f75844SAndroid Build Coastguard Worker return *this;
193*d9f75844SAndroid Build Coastguard Worker }
194*d9f75844SAndroid Build Coastguard Worker in6_addr v6addr = kV4MappedPrefix;
195*d9f75844SAndroid Build Coastguard Worker ::memcpy(&v6addr.s6_addr[12], &u_.ip4.s_addr, sizeof(u_.ip4.s_addr));
196*d9f75844SAndroid Build Coastguard Worker return IPAddress(v6addr);
197*d9f75844SAndroid Build Coastguard Worker }
198*d9f75844SAndroid Build Coastguard Worker
operator ==(const InterfaceAddress & other) const199*d9f75844SAndroid Build Coastguard Worker bool InterfaceAddress::operator==(const InterfaceAddress& other) const {
200*d9f75844SAndroid Build Coastguard Worker return ipv6_flags_ == other.ipv6_flags() &&
201*d9f75844SAndroid Build Coastguard Worker static_cast<const IPAddress&>(*this) == other;
202*d9f75844SAndroid Build Coastguard Worker }
203*d9f75844SAndroid Build Coastguard Worker
operator !=(const InterfaceAddress & other) const204*d9f75844SAndroid Build Coastguard Worker bool InterfaceAddress::operator!=(const InterfaceAddress& other) const {
205*d9f75844SAndroid Build Coastguard Worker return !((*this) == other);
206*d9f75844SAndroid Build Coastguard Worker }
207*d9f75844SAndroid Build Coastguard Worker
operator =(const InterfaceAddress & other)208*d9f75844SAndroid Build Coastguard Worker const InterfaceAddress& InterfaceAddress::operator=(
209*d9f75844SAndroid Build Coastguard Worker const InterfaceAddress& other) {
210*d9f75844SAndroid Build Coastguard Worker ipv6_flags_ = other.ipv6_flags_;
211*d9f75844SAndroid Build Coastguard Worker static_cast<IPAddress&>(*this) = other;
212*d9f75844SAndroid Build Coastguard Worker return *this;
213*d9f75844SAndroid Build Coastguard Worker }
214*d9f75844SAndroid Build Coastguard Worker
ToString() const215*d9f75844SAndroid Build Coastguard Worker std::string InterfaceAddress::ToString() const {
216*d9f75844SAndroid Build Coastguard Worker std::string result = IPAddress::ToString();
217*d9f75844SAndroid Build Coastguard Worker
218*d9f75844SAndroid Build Coastguard Worker if (family() == AF_INET6)
219*d9f75844SAndroid Build Coastguard Worker result += "|flags:0x" + rtc::ToHex(ipv6_flags());
220*d9f75844SAndroid Build Coastguard Worker
221*d9f75844SAndroid Build Coastguard Worker return result;
222*d9f75844SAndroid Build Coastguard Worker }
223*d9f75844SAndroid Build Coastguard Worker
IPIsPrivateNetworkV4(const IPAddress & ip)224*d9f75844SAndroid Build Coastguard Worker static bool IPIsPrivateNetworkV4(const IPAddress& ip) {
225*d9f75844SAndroid Build Coastguard Worker uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
226*d9f75844SAndroid Build Coastguard Worker return ((ip_in_host_order >> 24) == 10) ||
227*d9f75844SAndroid Build Coastguard Worker ((ip_in_host_order >> 20) == ((172 << 4) | 1)) ||
228*d9f75844SAndroid Build Coastguard Worker ((ip_in_host_order >> 16) == ((192 << 8) | 168));
229*d9f75844SAndroid Build Coastguard Worker }
230*d9f75844SAndroid Build Coastguard Worker
IPIsPrivateNetworkV6(const IPAddress & ip)231*d9f75844SAndroid Build Coastguard Worker static bool IPIsPrivateNetworkV6(const IPAddress& ip) {
232*d9f75844SAndroid Build Coastguard Worker return IPIsHelper(ip, kPrivateNetworkPrefix, 8);
233*d9f75844SAndroid Build Coastguard Worker }
234*d9f75844SAndroid Build Coastguard Worker
IPIsPrivateNetwork(const IPAddress & ip)235*d9f75844SAndroid Build Coastguard Worker bool IPIsPrivateNetwork(const IPAddress& ip) {
236*d9f75844SAndroid Build Coastguard Worker switch (ip.family()) {
237*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
238*d9f75844SAndroid Build Coastguard Worker return IPIsPrivateNetworkV4(ip);
239*d9f75844SAndroid Build Coastguard Worker }
240*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
241*d9f75844SAndroid Build Coastguard Worker return IPIsPrivateNetworkV6(ip);
242*d9f75844SAndroid Build Coastguard Worker }
243*d9f75844SAndroid Build Coastguard Worker }
244*d9f75844SAndroid Build Coastguard Worker return false;
245*d9f75844SAndroid Build Coastguard Worker }
246*d9f75844SAndroid Build Coastguard Worker
IPIsSharedNetworkV4(const IPAddress & ip)247*d9f75844SAndroid Build Coastguard Worker static bool IPIsSharedNetworkV4(const IPAddress& ip) {
248*d9f75844SAndroid Build Coastguard Worker uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
249*d9f75844SAndroid Build Coastguard Worker return (ip_in_host_order >> 22) == ((100 << 2) | 1);
250*d9f75844SAndroid Build Coastguard Worker }
251*d9f75844SAndroid Build Coastguard Worker
IPIsSharedNetwork(const IPAddress & ip)252*d9f75844SAndroid Build Coastguard Worker bool IPIsSharedNetwork(const IPAddress& ip) {
253*d9f75844SAndroid Build Coastguard Worker if (ip.family() == AF_INET) {
254*d9f75844SAndroid Build Coastguard Worker return IPIsSharedNetworkV4(ip);
255*d9f75844SAndroid Build Coastguard Worker }
256*d9f75844SAndroid Build Coastguard Worker return false;
257*d9f75844SAndroid Build Coastguard Worker }
258*d9f75844SAndroid Build Coastguard Worker
ExtractMappedAddress(const in6_addr & in6)259*d9f75844SAndroid Build Coastguard Worker in_addr ExtractMappedAddress(const in6_addr& in6) {
260*d9f75844SAndroid Build Coastguard Worker in_addr ipv4;
261*d9f75844SAndroid Build Coastguard Worker ::memcpy(&ipv4.s_addr, &in6.s6_addr[12], sizeof(ipv4.s_addr));
262*d9f75844SAndroid Build Coastguard Worker return ipv4;
263*d9f75844SAndroid Build Coastguard Worker }
264*d9f75844SAndroid Build Coastguard Worker
IPFromAddrInfo(struct addrinfo * info,IPAddress * out)265*d9f75844SAndroid Build Coastguard Worker bool IPFromAddrInfo(struct addrinfo* info, IPAddress* out) {
266*d9f75844SAndroid Build Coastguard Worker if (!info || !info->ai_addr) {
267*d9f75844SAndroid Build Coastguard Worker return false;
268*d9f75844SAndroid Build Coastguard Worker }
269*d9f75844SAndroid Build Coastguard Worker if (info->ai_addr->sa_family == AF_INET) {
270*d9f75844SAndroid Build Coastguard Worker sockaddr_in* addr = reinterpret_cast<sockaddr_in*>(info->ai_addr);
271*d9f75844SAndroid Build Coastguard Worker *out = IPAddress(addr->sin_addr);
272*d9f75844SAndroid Build Coastguard Worker return true;
273*d9f75844SAndroid Build Coastguard Worker } else if (info->ai_addr->sa_family == AF_INET6) {
274*d9f75844SAndroid Build Coastguard Worker sockaddr_in6* addr = reinterpret_cast<sockaddr_in6*>(info->ai_addr);
275*d9f75844SAndroid Build Coastguard Worker *out = IPAddress(addr->sin6_addr);
276*d9f75844SAndroid Build Coastguard Worker return true;
277*d9f75844SAndroid Build Coastguard Worker }
278*d9f75844SAndroid Build Coastguard Worker return false;
279*d9f75844SAndroid Build Coastguard Worker }
280*d9f75844SAndroid Build Coastguard Worker
IPFromString(absl::string_view str,IPAddress * out)281*d9f75844SAndroid Build Coastguard Worker bool IPFromString(absl::string_view str, IPAddress* out) {
282*d9f75844SAndroid Build Coastguard Worker if (!out) {
283*d9f75844SAndroid Build Coastguard Worker return false;
284*d9f75844SAndroid Build Coastguard Worker }
285*d9f75844SAndroid Build Coastguard Worker in_addr addr;
286*d9f75844SAndroid Build Coastguard Worker if (rtc::inet_pton(AF_INET, str, &addr) == 0) {
287*d9f75844SAndroid Build Coastguard Worker in6_addr addr6;
288*d9f75844SAndroid Build Coastguard Worker if (rtc::inet_pton(AF_INET6, str, &addr6) == 0) {
289*d9f75844SAndroid Build Coastguard Worker *out = IPAddress();
290*d9f75844SAndroid Build Coastguard Worker return false;
291*d9f75844SAndroid Build Coastguard Worker }
292*d9f75844SAndroid Build Coastguard Worker *out = IPAddress(addr6);
293*d9f75844SAndroid Build Coastguard Worker } else {
294*d9f75844SAndroid Build Coastguard Worker *out = IPAddress(addr);
295*d9f75844SAndroid Build Coastguard Worker }
296*d9f75844SAndroid Build Coastguard Worker return true;
297*d9f75844SAndroid Build Coastguard Worker }
298*d9f75844SAndroid Build Coastguard Worker
IPFromString(absl::string_view str,int flags,InterfaceAddress * out)299*d9f75844SAndroid Build Coastguard Worker bool IPFromString(absl::string_view str, int flags, InterfaceAddress* out) {
300*d9f75844SAndroid Build Coastguard Worker IPAddress ip;
301*d9f75844SAndroid Build Coastguard Worker if (!IPFromString(str, &ip)) {
302*d9f75844SAndroid Build Coastguard Worker return false;
303*d9f75844SAndroid Build Coastguard Worker }
304*d9f75844SAndroid Build Coastguard Worker
305*d9f75844SAndroid Build Coastguard Worker *out = InterfaceAddress(ip, flags);
306*d9f75844SAndroid Build Coastguard Worker return true;
307*d9f75844SAndroid Build Coastguard Worker }
308*d9f75844SAndroid Build Coastguard Worker
IPIsAny(const IPAddress & ip)309*d9f75844SAndroid Build Coastguard Worker bool IPIsAny(const IPAddress& ip) {
310*d9f75844SAndroid Build Coastguard Worker switch (ip.family()) {
311*d9f75844SAndroid Build Coastguard Worker case AF_INET:
312*d9f75844SAndroid Build Coastguard Worker return ip == IPAddress(INADDR_ANY);
313*d9f75844SAndroid Build Coastguard Worker case AF_INET6:
314*d9f75844SAndroid Build Coastguard Worker return ip == IPAddress(in6addr_any) || ip == IPAddress(kV4MappedPrefix);
315*d9f75844SAndroid Build Coastguard Worker case AF_UNSPEC:
316*d9f75844SAndroid Build Coastguard Worker return false;
317*d9f75844SAndroid Build Coastguard Worker }
318*d9f75844SAndroid Build Coastguard Worker return false;
319*d9f75844SAndroid Build Coastguard Worker }
320*d9f75844SAndroid Build Coastguard Worker
IPIsLoopbackV4(const IPAddress & ip)321*d9f75844SAndroid Build Coastguard Worker static bool IPIsLoopbackV4(const IPAddress& ip) {
322*d9f75844SAndroid Build Coastguard Worker uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
323*d9f75844SAndroid Build Coastguard Worker return ((ip_in_host_order >> 24) == 127);
324*d9f75844SAndroid Build Coastguard Worker }
325*d9f75844SAndroid Build Coastguard Worker
IPIsLoopbackV6(const IPAddress & ip)326*d9f75844SAndroid Build Coastguard Worker static bool IPIsLoopbackV6(const IPAddress& ip) {
327*d9f75844SAndroid Build Coastguard Worker return ip == IPAddress(in6addr_loopback);
328*d9f75844SAndroid Build Coastguard Worker }
329*d9f75844SAndroid Build Coastguard Worker
IPIsLoopback(const IPAddress & ip)330*d9f75844SAndroid Build Coastguard Worker bool IPIsLoopback(const IPAddress& ip) {
331*d9f75844SAndroid Build Coastguard Worker switch (ip.family()) {
332*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
333*d9f75844SAndroid Build Coastguard Worker return IPIsLoopbackV4(ip);
334*d9f75844SAndroid Build Coastguard Worker }
335*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
336*d9f75844SAndroid Build Coastguard Worker return IPIsLoopbackV6(ip);
337*d9f75844SAndroid Build Coastguard Worker }
338*d9f75844SAndroid Build Coastguard Worker }
339*d9f75844SAndroid Build Coastguard Worker return false;
340*d9f75844SAndroid Build Coastguard Worker }
341*d9f75844SAndroid Build Coastguard Worker
IPIsPrivate(const IPAddress & ip)342*d9f75844SAndroid Build Coastguard Worker bool IPIsPrivate(const IPAddress& ip) {
343*d9f75844SAndroid Build Coastguard Worker return IPIsLinkLocal(ip) || IPIsLoopback(ip) || IPIsPrivateNetwork(ip) ||
344*d9f75844SAndroid Build Coastguard Worker IPIsSharedNetwork(ip);
345*d9f75844SAndroid Build Coastguard Worker }
346*d9f75844SAndroid Build Coastguard Worker
IPIsUnspec(const IPAddress & ip)347*d9f75844SAndroid Build Coastguard Worker bool IPIsUnspec(const IPAddress& ip) {
348*d9f75844SAndroid Build Coastguard Worker return ip.family() == AF_UNSPEC;
349*d9f75844SAndroid Build Coastguard Worker }
350*d9f75844SAndroid Build Coastguard Worker
HashIP(const IPAddress & ip)351*d9f75844SAndroid Build Coastguard Worker size_t HashIP(const IPAddress& ip) {
352*d9f75844SAndroid Build Coastguard Worker switch (ip.family()) {
353*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
354*d9f75844SAndroid Build Coastguard Worker return ip.ipv4_address().s_addr;
355*d9f75844SAndroid Build Coastguard Worker }
356*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
357*d9f75844SAndroid Build Coastguard Worker in6_addr v6addr = ip.ipv6_address();
358*d9f75844SAndroid Build Coastguard Worker const uint32_t* v6_as_ints =
359*d9f75844SAndroid Build Coastguard Worker reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
360*d9f75844SAndroid Build Coastguard Worker return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3];
361*d9f75844SAndroid Build Coastguard Worker }
362*d9f75844SAndroid Build Coastguard Worker }
363*d9f75844SAndroid Build Coastguard Worker return 0;
364*d9f75844SAndroid Build Coastguard Worker }
365*d9f75844SAndroid Build Coastguard Worker
TruncateIP(const IPAddress & ip,int length)366*d9f75844SAndroid Build Coastguard Worker IPAddress TruncateIP(const IPAddress& ip, int length) {
367*d9f75844SAndroid Build Coastguard Worker if (length < 0) {
368*d9f75844SAndroid Build Coastguard Worker return IPAddress();
369*d9f75844SAndroid Build Coastguard Worker }
370*d9f75844SAndroid Build Coastguard Worker if (ip.family() == AF_INET) {
371*d9f75844SAndroid Build Coastguard Worker if (length > 31) {
372*d9f75844SAndroid Build Coastguard Worker return ip;
373*d9f75844SAndroid Build Coastguard Worker }
374*d9f75844SAndroid Build Coastguard Worker if (length == 0) {
375*d9f75844SAndroid Build Coastguard Worker return IPAddress(INADDR_ANY);
376*d9f75844SAndroid Build Coastguard Worker }
377*d9f75844SAndroid Build Coastguard Worker int mask = (0xFFFFFFFF << (32 - length));
378*d9f75844SAndroid Build Coastguard Worker uint32_t host_order_ip = NetworkToHost32(ip.ipv4_address().s_addr);
379*d9f75844SAndroid Build Coastguard Worker in_addr masked;
380*d9f75844SAndroid Build Coastguard Worker masked.s_addr = HostToNetwork32(host_order_ip & mask);
381*d9f75844SAndroid Build Coastguard Worker return IPAddress(masked);
382*d9f75844SAndroid Build Coastguard Worker } else if (ip.family() == AF_INET6) {
383*d9f75844SAndroid Build Coastguard Worker if (length > 127) {
384*d9f75844SAndroid Build Coastguard Worker return ip;
385*d9f75844SAndroid Build Coastguard Worker }
386*d9f75844SAndroid Build Coastguard Worker if (length == 0) {
387*d9f75844SAndroid Build Coastguard Worker return IPAddress(in6addr_any);
388*d9f75844SAndroid Build Coastguard Worker }
389*d9f75844SAndroid Build Coastguard Worker in6_addr v6addr = ip.ipv6_address();
390*d9f75844SAndroid Build Coastguard Worker int position = length / 32;
391*d9f75844SAndroid Build Coastguard Worker int inner_length = 32 - (length - (position * 32));
392*d9f75844SAndroid Build Coastguard Worker // Note: 64bit mask constant needed to allow possible 32-bit left shift.
393*d9f75844SAndroid Build Coastguard Worker uint32_t inner_mask = 0xFFFFFFFFLL << inner_length;
394*d9f75844SAndroid Build Coastguard Worker uint32_t* v6_as_ints = reinterpret_cast<uint32_t*>(&v6addr.s6_addr);
395*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 4; ++i) {
396*d9f75844SAndroid Build Coastguard Worker if (i == position) {
397*d9f75844SAndroid Build Coastguard Worker uint32_t host_order_inner = NetworkToHost32(v6_as_ints[i]);
398*d9f75844SAndroid Build Coastguard Worker v6_as_ints[i] = HostToNetwork32(host_order_inner & inner_mask);
399*d9f75844SAndroid Build Coastguard Worker } else if (i > position) {
400*d9f75844SAndroid Build Coastguard Worker v6_as_ints[i] = 0;
401*d9f75844SAndroid Build Coastguard Worker }
402*d9f75844SAndroid Build Coastguard Worker }
403*d9f75844SAndroid Build Coastguard Worker return IPAddress(v6addr);
404*d9f75844SAndroid Build Coastguard Worker }
405*d9f75844SAndroid Build Coastguard Worker return IPAddress();
406*d9f75844SAndroid Build Coastguard Worker }
407*d9f75844SAndroid Build Coastguard Worker
CountIPMaskBits(const IPAddress & mask)408*d9f75844SAndroid Build Coastguard Worker int CountIPMaskBits(const IPAddress& mask) {
409*d9f75844SAndroid Build Coastguard Worker uint32_t word_to_count = 0;
410*d9f75844SAndroid Build Coastguard Worker int bits = 0;
411*d9f75844SAndroid Build Coastguard Worker switch (mask.family()) {
412*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
413*d9f75844SAndroid Build Coastguard Worker word_to_count = NetworkToHost32(mask.ipv4_address().s_addr);
414*d9f75844SAndroid Build Coastguard Worker break;
415*d9f75844SAndroid Build Coastguard Worker }
416*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
417*d9f75844SAndroid Build Coastguard Worker in6_addr v6addr = mask.ipv6_address();
418*d9f75844SAndroid Build Coastguard Worker const uint32_t* v6_as_ints =
419*d9f75844SAndroid Build Coastguard Worker reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
420*d9f75844SAndroid Build Coastguard Worker int i = 0;
421*d9f75844SAndroid Build Coastguard Worker for (; i < 4; ++i) {
422*d9f75844SAndroid Build Coastguard Worker if (v6_as_ints[i] != 0xFFFFFFFF) {
423*d9f75844SAndroid Build Coastguard Worker break;
424*d9f75844SAndroid Build Coastguard Worker }
425*d9f75844SAndroid Build Coastguard Worker }
426*d9f75844SAndroid Build Coastguard Worker if (i < 4) {
427*d9f75844SAndroid Build Coastguard Worker word_to_count = NetworkToHost32(v6_as_ints[i]);
428*d9f75844SAndroid Build Coastguard Worker }
429*d9f75844SAndroid Build Coastguard Worker bits = (i * 32);
430*d9f75844SAndroid Build Coastguard Worker break;
431*d9f75844SAndroid Build Coastguard Worker }
432*d9f75844SAndroid Build Coastguard Worker default: {
433*d9f75844SAndroid Build Coastguard Worker return 0;
434*d9f75844SAndroid Build Coastguard Worker }
435*d9f75844SAndroid Build Coastguard Worker }
436*d9f75844SAndroid Build Coastguard Worker if (word_to_count == 0) {
437*d9f75844SAndroid Build Coastguard Worker return bits;
438*d9f75844SAndroid Build Coastguard Worker }
439*d9f75844SAndroid Build Coastguard Worker
440*d9f75844SAndroid Build Coastguard Worker // Public domain bit-twiddling hack from:
441*d9f75844SAndroid Build Coastguard Worker // http://graphics.stanford.edu/~seander/bithacks.html
442*d9f75844SAndroid Build Coastguard Worker // Counts the trailing 0s in the word.
443*d9f75844SAndroid Build Coastguard Worker unsigned int zeroes = 32;
444*d9f75844SAndroid Build Coastguard Worker // This could also be written word_to_count &= -word_to_count, but
445*d9f75844SAndroid Build Coastguard Worker // MSVC emits warning C4146 when negating an unsigned number.
446*d9f75844SAndroid Build Coastguard Worker word_to_count &= ~word_to_count + 1; // Isolate lowest set bit.
447*d9f75844SAndroid Build Coastguard Worker if (word_to_count)
448*d9f75844SAndroid Build Coastguard Worker zeroes--;
449*d9f75844SAndroid Build Coastguard Worker if (word_to_count & 0x0000FFFF)
450*d9f75844SAndroid Build Coastguard Worker zeroes -= 16;
451*d9f75844SAndroid Build Coastguard Worker if (word_to_count & 0x00FF00FF)
452*d9f75844SAndroid Build Coastguard Worker zeroes -= 8;
453*d9f75844SAndroid Build Coastguard Worker if (word_to_count & 0x0F0F0F0F)
454*d9f75844SAndroid Build Coastguard Worker zeroes -= 4;
455*d9f75844SAndroid Build Coastguard Worker if (word_to_count & 0x33333333)
456*d9f75844SAndroid Build Coastguard Worker zeroes -= 2;
457*d9f75844SAndroid Build Coastguard Worker if (word_to_count & 0x55555555)
458*d9f75844SAndroid Build Coastguard Worker zeroes -= 1;
459*d9f75844SAndroid Build Coastguard Worker
460*d9f75844SAndroid Build Coastguard Worker return bits + (32 - zeroes);
461*d9f75844SAndroid Build Coastguard Worker }
462*d9f75844SAndroid Build Coastguard Worker
IPIsHelper(const IPAddress & ip,const in6_addr & tomatch,int length)463*d9f75844SAndroid Build Coastguard Worker bool IPIsHelper(const IPAddress& ip, const in6_addr& tomatch, int length) {
464*d9f75844SAndroid Build Coastguard Worker // Helper method for checking IP prefix matches (but only on whole byte
465*d9f75844SAndroid Build Coastguard Worker // lengths). Length is in bits.
466*d9f75844SAndroid Build Coastguard Worker in6_addr addr = ip.ipv6_address();
467*d9f75844SAndroid Build Coastguard Worker return ::memcmp(&addr, &tomatch, (length >> 3)) == 0;
468*d9f75844SAndroid Build Coastguard Worker }
469*d9f75844SAndroid Build Coastguard Worker
IPIs6Bone(const IPAddress & ip)470*d9f75844SAndroid Build Coastguard Worker bool IPIs6Bone(const IPAddress& ip) {
471*d9f75844SAndroid Build Coastguard Worker return IPIsHelper(ip, k6BonePrefix, 16);
472*d9f75844SAndroid Build Coastguard Worker }
473*d9f75844SAndroid Build Coastguard Worker
IPIs6To4(const IPAddress & ip)474*d9f75844SAndroid Build Coastguard Worker bool IPIs6To4(const IPAddress& ip) {
475*d9f75844SAndroid Build Coastguard Worker return IPIsHelper(ip, k6To4Prefix, 16);
476*d9f75844SAndroid Build Coastguard Worker }
477*d9f75844SAndroid Build Coastguard Worker
IPIsLinkLocalV4(const IPAddress & ip)478*d9f75844SAndroid Build Coastguard Worker static bool IPIsLinkLocalV4(const IPAddress& ip) {
479*d9f75844SAndroid Build Coastguard Worker uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
480*d9f75844SAndroid Build Coastguard Worker return ((ip_in_host_order >> 16) == ((169 << 8) | 254));
481*d9f75844SAndroid Build Coastguard Worker }
482*d9f75844SAndroid Build Coastguard Worker
IPIsLinkLocalV6(const IPAddress & ip)483*d9f75844SAndroid Build Coastguard Worker static bool IPIsLinkLocalV6(const IPAddress& ip) {
484*d9f75844SAndroid Build Coastguard Worker // Can't use the helper because the prefix is 10 bits.
485*d9f75844SAndroid Build Coastguard Worker in6_addr addr = ip.ipv6_address();
486*d9f75844SAndroid Build Coastguard Worker return (addr.s6_addr[0] == 0xFE) && ((addr.s6_addr[1] & 0xC0) == 0x80);
487*d9f75844SAndroid Build Coastguard Worker }
488*d9f75844SAndroid Build Coastguard Worker
IPIsLinkLocal(const IPAddress & ip)489*d9f75844SAndroid Build Coastguard Worker bool IPIsLinkLocal(const IPAddress& ip) {
490*d9f75844SAndroid Build Coastguard Worker switch (ip.family()) {
491*d9f75844SAndroid Build Coastguard Worker case AF_INET: {
492*d9f75844SAndroid Build Coastguard Worker return IPIsLinkLocalV4(ip);
493*d9f75844SAndroid Build Coastguard Worker }
494*d9f75844SAndroid Build Coastguard Worker case AF_INET6: {
495*d9f75844SAndroid Build Coastguard Worker return IPIsLinkLocalV6(ip);
496*d9f75844SAndroid Build Coastguard Worker }
497*d9f75844SAndroid Build Coastguard Worker }
498*d9f75844SAndroid Build Coastguard Worker return false;
499*d9f75844SAndroid Build Coastguard Worker }
500*d9f75844SAndroid Build Coastguard Worker
501*d9f75844SAndroid Build Coastguard Worker // According to http://www.ietf.org/rfc/rfc2373.txt, Appendix A, page 19. An
502*d9f75844SAndroid Build Coastguard Worker // address which contains MAC will have its 11th and 12th bytes as FF:FE as well
503*d9f75844SAndroid Build Coastguard Worker // as the U/L bit as 1.
IPIsMacBased(const IPAddress & ip)504*d9f75844SAndroid Build Coastguard Worker bool IPIsMacBased(const IPAddress& ip) {
505*d9f75844SAndroid Build Coastguard Worker in6_addr addr = ip.ipv6_address();
506*d9f75844SAndroid Build Coastguard Worker return ((addr.s6_addr[8] & 0x02) && addr.s6_addr[11] == 0xFF &&
507*d9f75844SAndroid Build Coastguard Worker addr.s6_addr[12] == 0xFE);
508*d9f75844SAndroid Build Coastguard Worker }
509*d9f75844SAndroid Build Coastguard Worker
IPIsSiteLocal(const IPAddress & ip)510*d9f75844SAndroid Build Coastguard Worker bool IPIsSiteLocal(const IPAddress& ip) {
511*d9f75844SAndroid Build Coastguard Worker // Can't use the helper because the prefix is 10 bits.
512*d9f75844SAndroid Build Coastguard Worker in6_addr addr = ip.ipv6_address();
513*d9f75844SAndroid Build Coastguard Worker return addr.s6_addr[0] == 0xFE && (addr.s6_addr[1] & 0xC0) == 0xC0;
514*d9f75844SAndroid Build Coastguard Worker }
515*d9f75844SAndroid Build Coastguard Worker
IPIsULA(const IPAddress & ip)516*d9f75844SAndroid Build Coastguard Worker bool IPIsULA(const IPAddress& ip) {
517*d9f75844SAndroid Build Coastguard Worker // Can't use the helper because the prefix is 7 bits.
518*d9f75844SAndroid Build Coastguard Worker in6_addr addr = ip.ipv6_address();
519*d9f75844SAndroid Build Coastguard Worker return (addr.s6_addr[0] & 0xFE) == 0xFC;
520*d9f75844SAndroid Build Coastguard Worker }
521*d9f75844SAndroid Build Coastguard Worker
IPIsTeredo(const IPAddress & ip)522*d9f75844SAndroid Build Coastguard Worker bool IPIsTeredo(const IPAddress& ip) {
523*d9f75844SAndroid Build Coastguard Worker return IPIsHelper(ip, kTeredoPrefix, 32);
524*d9f75844SAndroid Build Coastguard Worker }
525*d9f75844SAndroid Build Coastguard Worker
IPIsV4Compatibility(const IPAddress & ip)526*d9f75844SAndroid Build Coastguard Worker bool IPIsV4Compatibility(const IPAddress& ip) {
527*d9f75844SAndroid Build Coastguard Worker return IPIsHelper(ip, kV4CompatibilityPrefix, 96);
528*d9f75844SAndroid Build Coastguard Worker }
529*d9f75844SAndroid Build Coastguard Worker
IPIsV4Mapped(const IPAddress & ip)530*d9f75844SAndroid Build Coastguard Worker bool IPIsV4Mapped(const IPAddress& ip) {
531*d9f75844SAndroid Build Coastguard Worker return IPIsHelper(ip, kV4MappedPrefix, 96);
532*d9f75844SAndroid Build Coastguard Worker }
533*d9f75844SAndroid Build Coastguard Worker
IPAddressPrecedence(const IPAddress & ip)534*d9f75844SAndroid Build Coastguard Worker int IPAddressPrecedence(const IPAddress& ip) {
535*d9f75844SAndroid Build Coastguard Worker // Precedence values from RFC 3484-bis. Prefers native v4 over 6to4/Teredo.
536*d9f75844SAndroid Build Coastguard Worker if (ip.family() == AF_INET) {
537*d9f75844SAndroid Build Coastguard Worker return 30;
538*d9f75844SAndroid Build Coastguard Worker } else if (ip.family() == AF_INET6) {
539*d9f75844SAndroid Build Coastguard Worker if (IPIsLoopback(ip)) {
540*d9f75844SAndroid Build Coastguard Worker return 60;
541*d9f75844SAndroid Build Coastguard Worker } else if (IPIsULA(ip)) {
542*d9f75844SAndroid Build Coastguard Worker return 50;
543*d9f75844SAndroid Build Coastguard Worker } else if (IPIsV4Mapped(ip)) {
544*d9f75844SAndroid Build Coastguard Worker return 30;
545*d9f75844SAndroid Build Coastguard Worker } else if (IPIs6To4(ip)) {
546*d9f75844SAndroid Build Coastguard Worker return 20;
547*d9f75844SAndroid Build Coastguard Worker } else if (IPIsTeredo(ip)) {
548*d9f75844SAndroid Build Coastguard Worker return 10;
549*d9f75844SAndroid Build Coastguard Worker } else if (IPIsV4Compatibility(ip) || IPIsSiteLocal(ip) || IPIs6Bone(ip)) {
550*d9f75844SAndroid Build Coastguard Worker return 1;
551*d9f75844SAndroid Build Coastguard Worker } else {
552*d9f75844SAndroid Build Coastguard Worker // A 'normal' IPv6 address.
553*d9f75844SAndroid Build Coastguard Worker return 40;
554*d9f75844SAndroid Build Coastguard Worker }
555*d9f75844SAndroid Build Coastguard Worker }
556*d9f75844SAndroid Build Coastguard Worker return 0;
557*d9f75844SAndroid Build Coastguard Worker }
558*d9f75844SAndroid Build Coastguard Worker
GetLoopbackIP(int family)559*d9f75844SAndroid Build Coastguard Worker IPAddress GetLoopbackIP(int family) {
560*d9f75844SAndroid Build Coastguard Worker if (family == AF_INET) {
561*d9f75844SAndroid Build Coastguard Worker return rtc::IPAddress(INADDR_LOOPBACK);
562*d9f75844SAndroid Build Coastguard Worker }
563*d9f75844SAndroid Build Coastguard Worker if (family == AF_INET6) {
564*d9f75844SAndroid Build Coastguard Worker return rtc::IPAddress(in6addr_loopback);
565*d9f75844SAndroid Build Coastguard Worker }
566*d9f75844SAndroid Build Coastguard Worker return rtc::IPAddress();
567*d9f75844SAndroid Build Coastguard Worker }
568*d9f75844SAndroid Build Coastguard Worker
GetAnyIP(int family)569*d9f75844SAndroid Build Coastguard Worker IPAddress GetAnyIP(int family) {
570*d9f75844SAndroid Build Coastguard Worker if (family == AF_INET) {
571*d9f75844SAndroid Build Coastguard Worker return rtc::IPAddress(INADDR_ANY);
572*d9f75844SAndroid Build Coastguard Worker }
573*d9f75844SAndroid Build Coastguard Worker if (family == AF_INET6) {
574*d9f75844SAndroid Build Coastguard Worker return rtc::IPAddress(in6addr_any);
575*d9f75844SAndroid Build Coastguard Worker }
576*d9f75844SAndroid Build Coastguard Worker return rtc::IPAddress();
577*d9f75844SAndroid Build Coastguard Worker }
578*d9f75844SAndroid Build Coastguard Worker
579*d9f75844SAndroid Build Coastguard Worker } // namespace rtc
580