blob: 73fe86231307a245fa231cd0fad7a3df6a8376ca [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>
Ali Tofigh2ab914c2022-04-13 12:55:15 +020014#include <string>
15
16#include "absl/strings/string_view.h"
Mirko Bonadeie5f4c6b2021-01-15 10:41:01 +010017
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018#if defined(WEBRTC_WIN)
19#include <ws2spi.h>
20#include <ws2tcpip.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020021
Nico Weber79bd4f12021-10-05 15:01:26 -040022#include "rtc_base/win/windows_version.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023#endif
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070024#if defined(WEBRTC_POSIX) && !defined(__native_client__)
Mirko Bonadeie5f4c6b2021-01-15 10:41:01 +010025#include <arpa/inet.h>
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070026#if defined(WEBRTC_ANDROID)
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/ifaddrs_android.h"
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070028#else
29#include <ifaddrs.h>
30#endif
31#endif // defined(WEBRTC_POSIX) && !defined(__native_client__)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000033namespace rtc {
34
Yves Gerey665174f2018-06-19 15:03:05 +020035const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000036#if defined(WEBRTC_WIN)
37 return win32_inet_ntop(af, src, dst, size);
38#else
39 return ::inet_ntop(af, src, dst, size);
40#endif
41}
42
Ali Tofigh2ab914c2022-04-13 12:55:15 +020043int inet_pton(int af, absl::string_view src, void* dst) {
Ali Tofigh98bfd992022-07-22 22:10:49 +020044 std::string src_str(src);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000045#if defined(WEBRTC_WIN)
Ali Tofigh2ab914c2022-04-13 12:55:15 +020046 return win32_inet_pton(af, src_str.c_str(), dst);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047#else
Ali Tofigh2ab914c2022-04-13 12:55:15 +020048 return ::inet_pton(af, src_str.c_str(), dst);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000049#endif
50}
51
deadbeef9a6f4d42017-05-15 19:43:33 -070052bool HasIPv4Enabled() {
53#if defined(WEBRTC_POSIX) && !defined(__native_client__)
54 bool has_ipv4 = false;
55 struct ifaddrs* ifa;
56 if (getifaddrs(&ifa) < 0) {
57 return false;
58 }
59 for (struct ifaddrs* cur = ifa; cur != nullptr; cur = cur->ifa_next) {
Björn Tereliusebd20102021-03-19 15:15:18 +010060 if (cur->ifa_addr != nullptr && cur->ifa_addr->sa_family == AF_INET) {
deadbeef9a6f4d42017-05-15 19:43:33 -070061 has_ipv4 = true;
62 break;
63 }
64 }
65 freeifaddrs(ifa);
66 return has_ipv4;
67#else
68 return true;
69#endif
70}
71
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000072bool HasIPv6Enabled() {
Robin Raymondce1b1402018-11-22 20:10:11 -050073#if defined(WINUWP)
74 // WinUWP always has IPv6 capability.
75 return true;
76#elif defined(WEBRTC_WIN)
Nico Weber79bd4f12021-10-05 15:01:26 -040077 if (rtc::rtc_win::GetVersion() >= rtc::rtc_win::Version::VERSION_VISTA) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000078 return true;
79 }
Nico Weber79bd4f12021-10-05 15:01:26 -040080 if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_XP) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000081 return false;
82 }
83 DWORD protbuff_size = 4096;
jbauch555604a2016-04-26 03:13:22 -070084 std::unique_ptr<char[]> protocols;
deadbeef37f5ecf2017-02-27 14:06:41 -080085 LPWSAPROTOCOL_INFOW protocol_infos = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000086 int requested_protocols[2] = {AF_INET6, 0};
87
88 int err = 0;
89 int ret = 0;
90 // Check for protocols in a do-while loop until we provide a buffer large
91 // enough. (WSCEnumProtocols sets protbuff_size to its desired value).
92 // It is extremely unlikely that this will loop more than once.
93 do {
94 protocols.reset(new char[protbuff_size]);
95 protocol_infos = reinterpret_cast<LPWSAPROTOCOL_INFOW>(protocols.get());
Yves Gerey665174f2018-06-19 15:03:05 +020096 ret = WSCEnumProtocols(requested_protocols, protocol_infos, &protbuff_size,
97 &err);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000098 } while (ret == SOCKET_ERROR && err == WSAENOBUFS);
99
100 if (ret == SOCKET_ERROR) {
101 return false;
102 }
103
104 // Even if ret is positive, check specifically for IPv6.
105 // Non-IPv6 enabled WinXP will still return a RAW protocol.
106 for (int i = 0; i < ret; ++i) {
107 if (protocol_infos[i].iAddressFamily == AF_INET6) {
108 return true;
109 }
110 }
111 return false;
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700112#elif defined(WEBRTC_POSIX) && !defined(__native_client__)
113 bool has_ipv6 = false;
114 struct ifaddrs* ifa;
115 if (getifaddrs(&ifa) < 0) {
116 return false;
117 }
118 for (struct ifaddrs* cur = ifa; cur != nullptr; cur = cur->ifa_next) {
Björn Tereliusebd20102021-03-19 15:15:18 +0100119 if (cur->ifa_addr != nullptr && cur->ifa_addr->sa_family == AF_INET6) {
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -0700120 has_ipv6 = true;
121 break;
122 }
123 }
124 freeifaddrs(ifa);
125 return has_ipv6;
126#else
127 return true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000128#endif
129}
130} // namespace rtc