1 /*
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
11 #include "rtc_base/net_helpers.h"
12
13 #include <memory>
14 #include <string>
15
16 #include "absl/strings/string_view.h"
17
18 #if defined(WEBRTC_WIN)
19 #include <ws2spi.h>
20 #include <ws2tcpip.h>
21
22 #include "rtc_base/win/windows_version.h"
23 #endif
24 #if defined(WEBRTC_POSIX) && !defined(__native_client__)
25 #include <arpa/inet.h>
26 #if defined(WEBRTC_ANDROID)
27 #include "rtc_base/ifaddrs_android.h"
28 #else
29 #include <ifaddrs.h>
30 #endif
31 #endif // defined(WEBRTC_POSIX) && !defined(__native_client__)
32
33 namespace rtc {
34
inet_ntop(int af,const void * src,char * dst,socklen_t size)35 const char* inet_ntop(int af, const void* src, char* dst, socklen_t size) {
36 #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
inet_pton(int af,absl::string_view src,void * dst)43 int inet_pton(int af, absl::string_view src, void* dst) {
44 std::string src_str(src);
45 #if defined(WEBRTC_WIN)
46 return win32_inet_pton(af, src_str.c_str(), dst);
47 #else
48 return ::inet_pton(af, src_str.c_str(), dst);
49 #endif
50 }
51
HasIPv4Enabled()52 bool 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) {
60 if (cur->ifa_addr != nullptr && cur->ifa_addr->sa_family == AF_INET) {
61 has_ipv4 = true;
62 break;
63 }
64 }
65 freeifaddrs(ifa);
66 return has_ipv4;
67 #else
68 return true;
69 #endif
70 }
71
HasIPv6Enabled()72 bool HasIPv6Enabled() {
73 #if defined(WINUWP)
74 // WinUWP always has IPv6 capability.
75 return true;
76 #elif defined(WEBRTC_WIN)
77 if (rtc::rtc_win::GetVersion() >= rtc::rtc_win::Version::VERSION_VISTA) {
78 return true;
79 }
80 if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_XP) {
81 return false;
82 }
83 DWORD protbuff_size = 4096;
84 std::unique_ptr<char[]> protocols;
85 LPWSAPROTOCOL_INFOW protocol_infos = nullptr;
86 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());
96 ret = WSCEnumProtocols(requested_protocols, protocol_infos, &protbuff_size,
97 &err);
98 } 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;
112 #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) {
119 if (cur->ifa_addr != nullptr && cur->ifa_addr->sa_family == AF_INET6) {
120 has_ipv6 = true;
121 break;
122 }
123 }
124 freeifaddrs(ifa);
125 return has_ipv6;
126 #else
127 return true;
128 #endif
129 }
130 } // namespace rtc
131