xref: /aosp_15_r20/external/webrtc/rtc_base/ip_address.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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