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