blob: bec854af0382fd0747f52a4a9d9008ddc9915fb5 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2008 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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "rtc_base/net_helpers.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000012
Mirko Bonadeie5f4c6b2021-01-15 10:41:01 +010013#include <memory>
14
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015#if defined(WEBRTC_WIN)
16#include <ws2spi.h>
17#include <ws2tcpip.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "rtc_base/win32.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000020#endif
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070021#if defined(WEBRTC_POSIX) && !defined(__native_client__)
Mirko Bonadeie5f4c6b2021-01-15 10:41:01 +010022#include <arpa/inet.h>
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070023#if defined(WEBRTC_ANDROID)
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/ifaddrs_android.h"
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070025#else
26#include <ifaddrs.h>
27#endif
28#endif // defined(WEBRTC_POSIX) && !defined(__native_client__)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000029
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000030namespace rtc {
31
Yves Gerey665174f2018-06-19 15:03:05 +020032const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000033#if defined(WEBRTC_WIN)
34 return win32_inet_ntop(af, src, dst, size);
35#else
36 return ::inet_ntop(af, src, dst, size);
37#endif
38}
39
Yves Gerey665174f2018-06-19 15:03:05 +020040int inet_pton(int af, const char* src, void* dst) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000041#if defined(WEBRTC_WIN)
42 return win32_inet_pton(af, src, dst);
43#else
44 return ::inet_pton(af, src, dst);
45#endif
46}
47
deadbeef9a6f4d42017-05-15 19:43:33 -070048bool HasIPv4Enabled() {
49#if defined(WEBRTC_POSIX) && !defined(__native_client__)
50 bool has_ipv4 = false;
51 struct ifaddrs* ifa;
52 if (getifaddrs(&ifa) < 0) {
53 return false;
54 }
55 for (struct ifaddrs* cur = ifa; cur != nullptr; cur = cur->ifa_next) {
Björn Tereliusebd20102021-03-19 15:15:18 +010056 if (cur->ifa_addr != nullptr && cur->ifa_addr->sa_family == AF_INET) {
deadbeef9a6f4d42017-05-15 19:43:33 -070057 has_ipv4 = true;
58 break;
59 }
60 }
61 freeifaddrs(ifa);
62 return has_ipv4;
63#else
64 return true;
65#endif
66}
67
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000068bool HasIPv6Enabled() {
Robin Raymondce1b1402018-11-22 20:10:11 -050069#if defined(WINUWP)
70 // WinUWP always has IPv6 capability.
71 return true;
72#elif defined(WEBRTC_WIN)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000073 if (IsWindowsVistaOrLater()) {
74 return true;
75 }
76 if (!IsWindowsXpOrLater()) {
77 return false;
78 }
79 DWORD protbuff_size = 4096;
jbauch555604a2016-04-26 03:13:22 -070080 std::unique_ptr<char[]> protocols;
deadbeef37f5ecf2017-02-27 14:06:41 -080081 LPWSAPROTOCOL_INFOW protocol_infos = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000082 int requested_protocols[2] = {AF_INET6, 0};
83
84 int err = 0;
85 int ret = 0;
86 // Check for protocols in a do-while loop until we provide a buffer large
87 // enough. (WSCEnumProtocols sets protbuff_size to its desired value).
88 // It is extremely unlikely that this will loop more than once.
89 do {
90 protocols.reset(new char[protbuff_size]);
91 protocol_infos = reinterpret_cast<LPWSAPROTOCOL_INFOW>(protocols.get());
Yves Gerey665174f2018-06-19 15:03:05 +020092 ret = WSCEnumProtocols(requested_protocols, protocol_infos, &protbuff_size,
93 &err);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000094 } while (ret == SOCKET_ERROR && err == WSAENOBUFS);
95
96 if (ret == SOCKET_ERROR) {
97 return false;
98 }
99
100 // Even if ret is positive, check specifically for IPv6.
101 // Non-IPv6 enabled WinXP will still return a RAW protocol.
102 for (int i = 0; i < ret; ++i) {
103 if (protocol_infos[i].iAddressFamily == AF_INET6) {
104 return true;
105 }
106 }
107 return false;
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700108#elif defined(WEBRTC_POSIX) && !defined(__native_client__)
109 bool has_ipv6 = false;
110 struct ifaddrs* ifa;
111 if (getifaddrs(&ifa) < 0) {
112 return false;
113 }
114 for (struct ifaddrs* cur = ifa; cur != nullptr; cur = cur->ifa_next) {
Björn Tereliusebd20102021-03-19 15:15:18 +0100115 if (cur->ifa_addr != nullptr && cur->ifa_addr->sa_family == AF_INET6) {
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700116 has_ipv6 = true;
117 break;
118 }
119 }
120 freeifaddrs(ifa);
121 return has_ipv6;
122#else
123 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000124#endif
125}
126} // namespace rtc