blob: 5a0d52974fdb0c3d050aaba26a6a1945a7dbaf35 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jeremy Leconte1bd331f2024-09-11 02:48:4111#include <cstddef>
12#include <cstdint>
13#include <cstdio>
14#include <cstring>
15#include <string>
henrike@webrtc.orgf0488722014-05-13 18:00:2616#if defined(WEBRTC_POSIX)
henrike@webrtc.orgf0488722014-05-13 18:00:2617#ifdef OPENBSD
18#include <netinet/in_systm.h>
19#endif
20#ifndef __native_client__
henrike@webrtc.orgf0488722014-05-13 18:00:2621#endif
henrike@webrtc.orgf0488722014-05-13 18:00:2622#include <netdb.h>
henrike@webrtc.orgf0488722014-05-13 18:00:2623#endif
24
Jeremy Leconte1bd331f2024-09-11 02:48:4125#include "absl/strings/string_view.h"
Mirko Bonadeie5f4c6b2021-01-15 09:41:0126#include "rtc_base/byte_order.h"
Jared Siskin802e8e52023-04-20 00:35:2827#include "rtc_base/ip_address.h"
Steve Anton10542f22019-01-11 17:11:0028#include "rtc_base/net_helpers.h"
29#include "rtc_base/string_utils.h"
Mirko Bonadeie0623852018-02-01 10:17:4030
henrike@webrtc.orgf0488722014-05-13 18:00:2631namespace rtc {
32
33// Prefixes used for categorizing IPv6 addresses.
Yves Gerey665174f2018-06-19 13:03:0534static const in6_addr kV4MappedPrefix = {
35 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0}}};
henrike@webrtc.orgf0488722014-05-13 18:00:2636static const in6_addr k6To4Prefix = {{{0x20, 0x02, 0}}};
37static const in6_addr kTeredoPrefix = {{{0x20, 0x01, 0x00, 0x00}}};
38static const in6_addr kV4CompatibilityPrefix = {{{0}}};
39static const in6_addr k6BonePrefix = {{{0x3f, 0xfe, 0}}};
Daniel Lazarenko2870b0a2018-01-25 09:30:2240static const in6_addr kPrivateNetworkPrefix = {{{0xFD}}};
henrike@webrtc.orgf0488722014-05-13 18:00:2641
Daniel Lazarenko2870b0a2018-01-25 09:30:2242static bool IPIsHelper(const IPAddress& ip,
Yves Gerey665174f2018-06-19 13:03:0543 const in6_addr& tomatch,
44 int length);
henrike@webrtc.orgf0488722014-05-13 18:00:2645static in_addr ExtractMappedAddress(const in6_addr& addr);
46
Peter Boström0c4e06b2015-10-07 10:23:2147uint32_t IPAddress::v4AddressAsHostOrderInteger() const {
henrike@webrtc.orgf0488722014-05-13 18:00:2648 if (family_ == AF_INET) {
49 return NetworkToHost32(u_.ip4.s_addr);
50 } else {
51 return 0;
52 }
53}
54
Sebastian Janssondb5d7e42020-03-02 10:32:2355int IPAddress::overhead() const {
56 switch (family_) {
57 case AF_INET: // IPv4
58 return 20;
59 case AF_INET6: // IPv6
60 return 40;
61 default:
62 return 0;
63 }
64}
65
Guo-wei Shieh11477022015-08-15 16:28:4166bool IPAddress::IsNil() const {
67 return IPIsUnspec(*this);
68}
69
henrike@webrtc.orgf0488722014-05-13 18:00:2670size_t IPAddress::Size() const {
71 switch (family_) {
72 case AF_INET:
73 return sizeof(in_addr);
74 case AF_INET6:
75 return sizeof(in6_addr);
76 }
77 return 0;
78}
79
Yves Gerey665174f2018-06-19 13:03:0580bool IPAddress::operator==(const IPAddress& other) const {
henrike@webrtc.orgf0488722014-05-13 18:00:2681 if (family_ != other.family_) {
82 return false;
83 }
84 if (family_ == AF_INET) {
85 return memcmp(&u_.ip4, &other.u_.ip4, sizeof(u_.ip4)) == 0;
86 }
87 if (family_ == AF_INET6) {
88 return memcmp(&u_.ip6, &other.u_.ip6, sizeof(u_.ip6)) == 0;
89 }
90 return family_ == AF_UNSPEC;
91}
92
Yves Gerey665174f2018-06-19 13:03:0593bool IPAddress::operator!=(const IPAddress& other) const {
henrike@webrtc.orgf0488722014-05-13 18:00:2694 return !((*this) == other);
95}
96
Yves Gerey665174f2018-06-19 13:03:0597bool IPAddress::operator>(const IPAddress& other) const {
henrike@webrtc.orgf0488722014-05-13 18:00:2698 return (*this) != other && !((*this) < other);
99}
100
Yves Gerey665174f2018-06-19 13:03:05101bool IPAddress::operator<(const IPAddress& other) const {
henrike@webrtc.orgf0488722014-05-13 18:00:26102 // IPv4 is 'less than' IPv6
103 if (family_ != other.family_) {
104 if (family_ == AF_UNSPEC) {
105 return true;
106 }
107 if (family_ == AF_INET && other.family_ == AF_INET6) {
108 return true;
109 }
110 return false;
111 }
112 // Comparing addresses of the same family.
113 switch (family_) {
114 case AF_INET: {
115 return NetworkToHost32(u_.ip4.s_addr) <
Yves Gerey665174f2018-06-19 13:03:05116 NetworkToHost32(other.u_.ip4.s_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26117 }
118 case AF_INET6: {
119 return memcmp(&u_.ip6.s6_addr, &other.u_.ip6.s6_addr, 16) < 0;
120 }
121 }
122 // Catches AF_UNSPEC and invalid addresses.
123 return false;
124}
125
henrike@webrtc.orgf0488722014-05-13 18:00:26126in6_addr IPAddress::ipv6_address() const {
127 return u_.ip6;
128}
129
130in_addr IPAddress::ipv4_address() const {
131 return u_.ip4;
132}
133
134std::string IPAddress::ToString() const {
135 if (family_ != AF_INET && family_ != AF_INET6) {
136 return std::string();
137 }
138 char buf[INET6_ADDRSTRLEN] = {0};
139 const void* src = &u_.ip4;
140 if (family_ == AF_INET6) {
141 src = &u_.ip6;
142 }
143 if (!rtc::inet_ntop(family_, src, buf, sizeof(buf))) {
144 return std::string();
145 }
146 return std::string(buf);
147}
148
149std::string IPAddress::ToSensitiveString() const {
henrike@webrtc.orgf0488722014-05-13 18:00:26150 switch (family_) {
151 case AF_INET: {
152 std::string address = ToString();
153 size_t find_pos = address.rfind('.');
154 if (find_pos == std::string::npos)
155 return std::string();
156 address.resize(find_pos);
157 address += ".x";
158 return address;
159 }
160 case AF_INET6: {
Sergey Ulanovbeed8282016-01-14 02:14:49161 std::string result;
162 result.resize(INET6_ADDRSTRLEN);
163 in6_addr addr = ipv6_address();
Niels Mölleraba06332018-10-16 13:14:15164 size_t len = snprintf(&(result[0]), result.size(), "%x:%x:%x:x:x:x:x:x",
165 (addr.s6_addr[0] << 8) + addr.s6_addr[1],
166 (addr.s6_addr[2] << 8) + addr.s6_addr[3],
167 (addr.s6_addr[4] << 8) + addr.s6_addr[5]);
Sergey Ulanovbeed8282016-01-14 02:14:49168 result.resize(len);
169 return result;
henrike@webrtc.orgf0488722014-05-13 18:00:26170 }
171 }
172 return std::string();
173}
174
175IPAddress IPAddress::Normalized() const {
176 if (family_ != AF_INET6) {
177 return *this;
178 }
179 if (!IPIsV4Mapped(*this)) {
180 return *this;
181 }
182 in_addr addr = ExtractMappedAddress(u_.ip6);
183 return IPAddress(addr);
184}
185
186IPAddress IPAddress::AsIPv6Address() const {
187 if (family_ != AF_INET) {
188 return *this;
189 }
190 in6_addr v6addr = kV4MappedPrefix;
191 ::memcpy(&v6addr.s6_addr[12], &u_.ip4.s_addr, sizeof(u_.ip4.s_addr));
192 return IPAddress(v6addr);
193}
194
Yves Gerey665174f2018-06-19 13:03:05195bool InterfaceAddress::operator==(const InterfaceAddress& other) const {
guoweis@webrtc.orgfa603982014-09-09 23:42:40196 return ipv6_flags_ == other.ipv6_flags() &&
Yves Gerey665174f2018-06-19 13:03:05197 static_cast<const IPAddress&>(*this) == other;
guoweis@webrtc.orgfa603982014-09-09 23:42:40198}
199
Yves Gerey665174f2018-06-19 13:03:05200bool InterfaceAddress::operator!=(const InterfaceAddress& other) const {
guoweis@webrtc.orgfa603982014-09-09 23:42:40201 return !((*this) == other);
202}
203
204const InterfaceAddress& InterfaceAddress::operator=(
Yves Gerey665174f2018-06-19 13:03:05205 const InterfaceAddress& other) {
guoweis@webrtc.orgfa603982014-09-09 23:42:40206 ipv6_flags_ = other.ipv6_flags_;
207 static_cast<IPAddress&>(*this) = other;
208 return *this;
209}
210
Jonas Olsson74395342018-04-03 10:22:07211std::string InterfaceAddress::ToString() const {
212 std::string result = IPAddress::ToString();
guoweis@webrtc.orgfa603982014-09-09 23:42:40213
Jonas Olsson74395342018-04-03 10:22:07214 if (family() == AF_INET6)
215 result += "|flags:0x" + rtc::ToHex(ipv6_flags());
216
217 return result;
guoweis@webrtc.orgfa603982014-09-09 23:42:40218}
henrike@webrtc.orgf0488722014-05-13 18:00:26219
Daniel Lazarenko2870b0a2018-01-25 09:30:22220static bool IPIsPrivateNetworkV4(const IPAddress& ip) {
221 uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
222 return ((ip_in_host_order >> 24) == 10) ||
Yves Gerey665174f2018-06-19 13:03:05223 ((ip_in_host_order >> 20) == ((172 << 4) | 1)) ||
224 ((ip_in_host_order >> 16) == ((192 << 8) | 168));
Daniel Lazarenko2870b0a2018-01-25 09:30:22225}
226
227static bool IPIsPrivateNetworkV6(const IPAddress& ip) {
228 return IPIsHelper(ip, kPrivateNetworkPrefix, 8);
229}
230
231bool IPIsPrivateNetwork(const IPAddress& ip) {
232 switch (ip.family()) {
233 case AF_INET: {
234 return IPIsPrivateNetworkV4(ip);
235 }
236 case AF_INET6: {
237 return IPIsPrivateNetworkV6(ip);
238 }
239 }
240 return false;
henrike@webrtc.orgf0488722014-05-13 18:00:26241}
242
Jeroen de Borstaf242c82019-04-24 20:13:48243static bool IPIsSharedNetworkV4(const IPAddress& ip) {
244 uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
245 return (ip_in_host_order >> 22) == ((100 << 2) | 1);
246}
247
248bool IPIsSharedNetwork(const IPAddress& ip) {
249 if (ip.family() == AF_INET) {
250 return IPIsSharedNetworkV4(ip);
251 }
252 return false;
253}
254
henrike@webrtc.orgf0488722014-05-13 18:00:26255in_addr ExtractMappedAddress(const in6_addr& in6) {
256 in_addr ipv4;
257 ::memcpy(&ipv4.s_addr, &in6.s6_addr[12], sizeof(ipv4.s_addr));
258 return ipv4;
259}
260
261bool IPFromAddrInfo(struct addrinfo* info, IPAddress* out) {
262 if (!info || !info->ai_addr) {
263 return false;
264 }
265 if (info->ai_addr->sa_family == AF_INET) {
266 sockaddr_in* addr = reinterpret_cast<sockaddr_in*>(info->ai_addr);
267 *out = IPAddress(addr->sin_addr);
268 return true;
269 } else if (info->ai_addr->sa_family == AF_INET6) {
270 sockaddr_in6* addr = reinterpret_cast<sockaddr_in6*>(info->ai_addr);
271 *out = IPAddress(addr->sin6_addr);
272 return true;
273 }
274 return false;
275}
276
Ali Tofigh7fa90572022-03-17 14:47:49277bool IPFromString(absl::string_view str, IPAddress* out) {
henrike@webrtc.orgf0488722014-05-13 18:00:26278 if (!out) {
279 return false;
280 }
281 in_addr addr;
Ali Tofigh2ab914c2022-04-13 10:55:15282 if (rtc::inet_pton(AF_INET, str, &addr) == 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:26283 in6_addr addr6;
Ali Tofigh2ab914c2022-04-13 10:55:15284 if (rtc::inet_pton(AF_INET6, str, &addr6) == 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:26285 *out = IPAddress();
286 return false;
287 }
288 *out = IPAddress(addr6);
289 } else {
290 *out = IPAddress(addr);
291 }
292 return true;
293}
294
Ali Tofigh7fa90572022-03-17 14:47:49295bool IPFromString(absl::string_view str, int flags, InterfaceAddress* out) {
guoweis@webrtc.orgfa603982014-09-09 23:42:40296 IPAddress ip;
297 if (!IPFromString(str, &ip)) {
298 return false;
299 }
300
301 *out = InterfaceAddress(ip, flags);
302 return true;
303}
304
henrike@webrtc.orgf0488722014-05-13 18:00:26305bool IPIsAny(const IPAddress& ip) {
306 switch (ip.family()) {
307 case AF_INET:
308 return ip == IPAddress(INADDR_ANY);
309 case AF_INET6:
guoweis@webrtc.org59ae5ff2015-03-01 23:45:16310 return ip == IPAddress(in6addr_any) || ip == IPAddress(kV4MappedPrefix);
henrike@webrtc.orgf0488722014-05-13 18:00:26311 case AF_UNSPEC:
312 return false;
313 }
314 return false;
315}
316
Daniel Lazarenko2870b0a2018-01-25 09:30:22317static bool IPIsLoopbackV4(const IPAddress& ip) {
318 uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
319 return ((ip_in_host_order >> 24) == 127);
320}
321
322static bool IPIsLoopbackV6(const IPAddress& ip) {
323 return ip == IPAddress(in6addr_loopback);
324}
325
henrike@webrtc.orgf0488722014-05-13 18:00:26326bool IPIsLoopback(const IPAddress& ip) {
327 switch (ip.family()) {
328 case AF_INET: {
Daniel Lazarenko2870b0a2018-01-25 09:30:22329 return IPIsLoopbackV4(ip);
henrike@webrtc.orgf0488722014-05-13 18:00:26330 }
331 case AF_INET6: {
Daniel Lazarenko2870b0a2018-01-25 09:30:22332 return IPIsLoopbackV6(ip);
Yuwei Huangb181f712018-01-23 01:01:28333 }
334 }
335 return false;
336}
337
henrike@webrtc.orgf0488722014-05-13 18:00:26338bool IPIsPrivate(const IPAddress& ip) {
Jeroen de Borstaf242c82019-04-24 20:13:48339 return IPIsLinkLocal(ip) || IPIsLoopback(ip) || IPIsPrivateNetwork(ip) ||
340 IPIsSharedNetwork(ip);
henrike@webrtc.orgf0488722014-05-13 18:00:26341}
342
343bool IPIsUnspec(const IPAddress& ip) {
344 return ip.family() == AF_UNSPEC;
345}
346
347size_t HashIP(const IPAddress& ip) {
348 switch (ip.family()) {
349 case AF_INET: {
350 return ip.ipv4_address().s_addr;
351 }
352 case AF_INET6: {
353 in6_addr v6addr = ip.ipv6_address();
Peter Boström0c4e06b2015-10-07 10:23:21354 const uint32_t* v6_as_ints =
355 reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26356 return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3];
357 }
358 }
359 return 0;
360}
361
362IPAddress TruncateIP(const IPAddress& ip, int length) {
363 if (length < 0) {
364 return IPAddress();
365 }
366 if (ip.family() == AF_INET) {
367 if (length > 31) {
368 return ip;
369 }
370 if (length == 0) {
371 return IPAddress(INADDR_ANY);
372 }
373 int mask = (0xFFFFFFFF << (32 - length));
Peter Boström0c4e06b2015-10-07 10:23:21374 uint32_t host_order_ip = NetworkToHost32(ip.ipv4_address().s_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26375 in_addr masked;
376 masked.s_addr = HostToNetwork32(host_order_ip & mask);
377 return IPAddress(masked);
378 } else if (ip.family() == AF_INET6) {
379 if (length > 127) {
380 return ip;
381 }
382 if (length == 0) {
383 return IPAddress(in6addr_any);
384 }
385 in6_addr v6addr = ip.ipv6_address();
386 int position = length / 32;
387 int inner_length = 32 - (length - (position * 32));
388 // Note: 64bit mask constant needed to allow possible 32-bit left shift.
Peter Boström0c4e06b2015-10-07 10:23:21389 uint32_t inner_mask = 0xFFFFFFFFLL << inner_length;
390 uint32_t* v6_as_ints = reinterpret_cast<uint32_t*>(&v6addr.s6_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26391 for (int i = 0; i < 4; ++i) {
392 if (i == position) {
Peter Boström0c4e06b2015-10-07 10:23:21393 uint32_t host_order_inner = NetworkToHost32(v6_as_ints[i]);
henrike@webrtc.orgf0488722014-05-13 18:00:26394 v6_as_ints[i] = HostToNetwork32(host_order_inner & inner_mask);
395 } else if (i > position) {
396 v6_as_ints[i] = 0;
397 }
398 }
399 return IPAddress(v6addr);
400 }
401 return IPAddress();
402}
403
Yves Gerey2257c082020-01-03 11:37:56404int CountIPMaskBits(const IPAddress& mask) {
Peter Boström0c4e06b2015-10-07 10:23:21405 uint32_t word_to_count = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26406 int bits = 0;
407 switch (mask.family()) {
408 case AF_INET: {
409 word_to_count = NetworkToHost32(mask.ipv4_address().s_addr);
410 break;
411 }
412 case AF_INET6: {
413 in6_addr v6addr = mask.ipv6_address();
Peter Boström0c4e06b2015-10-07 10:23:21414 const uint32_t* v6_as_ints =
415 reinterpret_cast<const uint32_t*>(&v6addr.s6_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26416 int i = 0;
417 for (; i < 4; ++i) {
418 if (v6_as_ints[i] != 0xFFFFFFFF) {
419 break;
420 }
421 }
422 if (i < 4) {
423 word_to_count = NetworkToHost32(v6_as_ints[i]);
424 }
425 bits = (i * 32);
426 break;
427 }
Jeroen de Borstaf242c82019-04-24 20:13:48428 default: {
429 return 0;
430 }
henrike@webrtc.orgf0488722014-05-13 18:00:26431 }
432 if (word_to_count == 0) {
433 return bits;
434 }
435
436 // Public domain bit-twiddling hack from:
437 // http://graphics.stanford.edu/~seander/bithacks.html
438 // Counts the trailing 0s in the word.
439 unsigned int zeroes = 32;
tereliusd802b5b2016-03-01 19:07:34440 // This could also be written word_to_count &= -word_to_count, but
441 // MSVC emits warning C4146 when negating an unsigned number.
442 word_to_count &= ~word_to_count + 1; // Isolate lowest set bit.
Yves Gerey665174f2018-06-19 13:03:05443 if (word_to_count)
444 zeroes--;
445 if (word_to_count & 0x0000FFFF)
446 zeroes -= 16;
447 if (word_to_count & 0x00FF00FF)
448 zeroes -= 8;
449 if (word_to_count & 0x0F0F0F0F)
450 zeroes -= 4;
451 if (word_to_count & 0x33333333)
452 zeroes -= 2;
453 if (word_to_count & 0x55555555)
454 zeroes -= 1;
henrike@webrtc.orgf0488722014-05-13 18:00:26455
456 return bits + (32 - zeroes);
457}
458
459bool IPIsHelper(const IPAddress& ip, const in6_addr& tomatch, int length) {
460 // Helper method for checking IP prefix matches (but only on whole byte
461 // lengths). Length is in bits.
462 in6_addr addr = ip.ipv6_address();
463 return ::memcmp(&addr, &tomatch, (length >> 3)) == 0;
464}
465
466bool IPIs6Bone(const IPAddress& ip) {
467 return IPIsHelper(ip, k6BonePrefix, 16);
468}
469
470bool IPIs6To4(const IPAddress& ip) {
471 return IPIsHelper(ip, k6To4Prefix, 16);
472}
473
Daniel Lazarenko2870b0a2018-01-25 09:30:22474static bool IPIsLinkLocalV4(const IPAddress& ip) {
475 uint32_t ip_in_host_order = ip.v4AddressAsHostOrderInteger();
476 return ((ip_in_host_order >> 16) == ((169 << 8) | 254));
477}
478
479static bool IPIsLinkLocalV6(const IPAddress& ip) {
480 // Can't use the helper because the prefix is 10 bits.
481 in6_addr addr = ip.ipv6_address();
482 return (addr.s6_addr[0] == 0xFE) && ((addr.s6_addr[1] & 0xC0) == 0x80);
483}
484
485bool IPIsLinkLocal(const IPAddress& ip) {
486 switch (ip.family()) {
487 case AF_INET: {
488 return IPIsLinkLocalV4(ip);
489 }
490 case AF_INET6: {
491 return IPIsLinkLocalV6(ip);
492 }
493 }
494 return false;
495}
496
guoweis@webrtc.orgb91d0f52015-03-17 14:43:20497// According to http://www.ietf.org/rfc/rfc2373.txt, Appendix A, page 19. An
498// address which contains MAC will have its 11th and 12th bytes as FF:FE as well
499// as the U/L bit as 1.
500bool IPIsMacBased(const IPAddress& ip) {
501 in6_addr addr = ip.ipv6_address();
502 return ((addr.s6_addr[8] & 0x02) && addr.s6_addr[11] == 0xFF &&
503 addr.s6_addr[12] == 0xFE);
guoweis@webrtc.orgbbce5ef2015-03-05 04:38:29504}
505
henrike@webrtc.orgf0488722014-05-13 18:00:26506bool IPIsSiteLocal(const IPAddress& ip) {
507 // Can't use the helper because the prefix is 10 bits.
508 in6_addr addr = ip.ipv6_address();
509 return addr.s6_addr[0] == 0xFE && (addr.s6_addr[1] & 0xC0) == 0xC0;
510}
511
512bool IPIsULA(const IPAddress& ip) {
513 // Can't use the helper because the prefix is 7 bits.
514 in6_addr addr = ip.ipv6_address();
515 return (addr.s6_addr[0] & 0xFE) == 0xFC;
516}
517
518bool IPIsTeredo(const IPAddress& ip) {
519 return IPIsHelper(ip, kTeredoPrefix, 32);
520}
521
522bool IPIsV4Compatibility(const IPAddress& ip) {
523 return IPIsHelper(ip, kV4CompatibilityPrefix, 96);
524}
525
526bool IPIsV4Mapped(const IPAddress& ip) {
527 return IPIsHelper(ip, kV4MappedPrefix, 96);
528}
529
530int IPAddressPrecedence(const IPAddress& ip) {
531 // Precedence values from RFC 3484-bis. Prefers native v4 over 6to4/Teredo.
532 if (ip.family() == AF_INET) {
533 return 30;
534 } else if (ip.family() == AF_INET6) {
535 if (IPIsLoopback(ip)) {
536 return 60;
537 } else if (IPIsULA(ip)) {
538 return 50;
539 } else if (IPIsV4Mapped(ip)) {
540 return 30;
541 } else if (IPIs6To4(ip)) {
542 return 20;
543 } else if (IPIsTeredo(ip)) {
544 return 10;
545 } else if (IPIsV4Compatibility(ip) || IPIsSiteLocal(ip) || IPIs6Bone(ip)) {
546 return 1;
547 } else {
548 // A 'normal' IPv6 address.
549 return 40;
550 }
551 }
552 return 0;
553}
554
Guo-wei Shiehfe3bc9d2015-08-20 15:48:20555IPAddress GetLoopbackIP(int family) {
556 if (family == AF_INET) {
557 return rtc::IPAddress(INADDR_LOOPBACK);
558 }
559 if (family == AF_INET6) {
560 return rtc::IPAddress(in6addr_loopback);
561 }
562 return rtc::IPAddress();
563}
Guo-wei Shieh9af97f82015-11-10 22:47:39564
565IPAddress GetAnyIP(int family) {
566 if (family == AF_INET) {
567 return rtc::IPAddress(INADDR_ANY);
568 }
569 if (family == AF_INET6) {
570 return rtc::IPAddress(in6addr_any);
571 }
572 return rtc::IPAddress();
573}
574
tereliusd802b5b2016-03-01 19:07:34575} // namespace rtc