netif.cpp
1 // Copyright (c) 2024-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or https://www.opensource.org/licenses/mit-license.php. 4 5 #include <bitcoin-build-config.h> // IWYU pragma: keep 6 7 #include <common/netif.h> 8 9 #include <logging.h> 10 #include <netbase.h> 11 #include <util/check.h> 12 #include <util/sock.h> 13 #include <util/syserror.h> 14 15 #if defined(__linux__) 16 #include <linux/rtnetlink.h> 17 #elif defined(__FreeBSD__) 18 #include <osreldate.h> 19 #if __FreeBSD_version >= 1400000 20 // Workaround https://github.com/freebsd/freebsd-src/pull/1070. 21 #define typeof __typeof 22 #include <netlink/netlink.h> 23 #include <netlink/netlink_route.h> 24 #endif 25 #elif defined(WIN32) 26 #include <iphlpapi.h> 27 #elif defined(__APPLE__) 28 #include <net/route.h> 29 #include <sys/sysctl.h> 30 #endif 31 32 #ifdef HAVE_IFADDRS 33 #include <sys/types.h> 34 #include <ifaddrs.h> 35 #endif 36 37 #include <type_traits> 38 39 namespace { 40 41 //! Return CNetAddr for the specified OS-level network address. 42 //! If a length is not given, it is taken to be sizeof(struct sockaddr_*) for the family. 43 std::optional<CNetAddr> FromSockAddr(const struct sockaddr* addr, std::optional<socklen_t> sa_len_opt) 44 { 45 socklen_t sa_len = 0; 46 if (sa_len_opt.has_value()) { 47 sa_len = *sa_len_opt; 48 } else { 49 // If sockaddr length was not specified, determine it from the family. 50 switch (addr->sa_family) { 51 case AF_INET: sa_len = sizeof(struct sockaddr_in); break; 52 case AF_INET6: sa_len = sizeof(struct sockaddr_in6); break; 53 default: 54 return std::nullopt; 55 } 56 } 57 // Fill in a CService from the sockaddr, then drop the port part. 58 CService service; 59 if (service.SetSockAddr(addr, sa_len)) { 60 return (CNetAddr)service; 61 } 62 return std::nullopt; 63 } 64 65 // Linux and FreeBSD 14.0+. For FreeBSD 13.2 the code can be compiled but 66 // running it requires loading a special kernel module, otherwise socket(AF_NETLINK,...) 67 // will fail, so we skip that. 68 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 1400000) 69 70 // Good for responses containing ~ 10,000-15,000 routes. 71 static constexpr ssize_t NETLINK_MAX_RESPONSE_SIZE{1'048'576}; 72 73 std::optional<CNetAddr> QueryDefaultGatewayImpl(sa_family_t family) 74 { 75 // Create a netlink socket. 76 auto sock{CreateSock(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)}; 77 if (!sock) { 78 LogError("socket(AF_NETLINK): %s\n", NetworkErrorString(errno)); 79 return std::nullopt; 80 } 81 82 // Send request. 83 struct { 84 nlmsghdr hdr; ///< Request header. 85 rtmsg data; ///< Request data, a "route message". 86 nlattr dst_hdr; ///< One attribute, conveying the route destination address. 87 char dst_data[16]; ///< Route destination address. To query the default route we use 0.0.0.0/0 or [::]/0. For IPv4 the first 4 bytes are used. 88 } request{}; 89 90 // Whether to use the first 4 or 16 bytes from request.dst_data. 91 const size_t dst_data_len = family == AF_INET ? 4 : 16; 92 93 request.hdr.nlmsg_type = RTM_GETROUTE; 94 request.hdr.nlmsg_flags = NLM_F_REQUEST; 95 #ifdef __linux__ 96 // Linux IPv4 / IPv6 - this must be present, otherwise no gateway is found 97 // FreeBSD IPv4 - does not matter, the gateway is found with or without this 98 // FreeBSD IPv6 - this must be absent, otherwise no gateway is found 99 request.hdr.nlmsg_flags |= NLM_F_DUMP; 100 #endif 101 request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg) + sizeof(nlattr) + dst_data_len); 102 request.hdr.nlmsg_seq = 0; // Sequence number, used to match which reply is to which request. Irrelevant for us because we send just one request. 103 request.data.rtm_family = family; 104 request.data.rtm_dst_len = 0; // Prefix length. 105 #ifdef __FreeBSD__ 106 // Linux IPv4 / IPv6 this must be absent, otherwise no gateway is found 107 // FreeBSD IPv4 - does not matter, the gateway is found with or without this 108 // FreeBSD IPv6 - this must be present, otherwise no gateway is found 109 request.data.rtm_flags = RTM_F_PREFIX; 110 #endif 111 request.dst_hdr.nla_type = RTA_DST; 112 request.dst_hdr.nla_len = sizeof(nlattr) + dst_data_len; 113 114 if (sock->Send(&request, request.hdr.nlmsg_len, 0) != static_cast<ssize_t>(request.hdr.nlmsg_len)) { 115 LogError("send() to netlink socket: %s\n", NetworkErrorString(errno)); 116 return std::nullopt; 117 } 118 119 // Receive response. 120 char response[4096]; 121 ssize_t total_bytes_read{0}; 122 bool done{false}; 123 while (!done) { 124 int64_t recv_result; 125 do { 126 recv_result = sock->Recv(response, sizeof(response), 0); 127 } while (recv_result < 0 && (errno == EINTR || errno == EAGAIN)); 128 if (recv_result < 0) { 129 LogError("recv() from netlink socket: %s\n", NetworkErrorString(errno)); 130 return std::nullopt; 131 } 132 133 total_bytes_read += recv_result; 134 if (total_bytes_read > NETLINK_MAX_RESPONSE_SIZE) { 135 LogWarning("Netlink response exceeded size limit (%zu bytes, family=%d)\n", NETLINK_MAX_RESPONSE_SIZE, family); 136 return std::nullopt; 137 } 138 139 using recv_result_t = std::conditional_t<std::is_signed_v<decltype(NLMSG_HDRLEN)>, int64_t, decltype(NLMSG_HDRLEN)>; 140 141 for (nlmsghdr* hdr = (nlmsghdr*)response; NLMSG_OK(hdr, static_cast<recv_result_t>(recv_result)); hdr = NLMSG_NEXT(hdr, recv_result)) { 142 if (!(hdr->nlmsg_flags & NLM_F_MULTI)) { 143 done = true; 144 } 145 146 if (hdr->nlmsg_type == NLMSG_DONE) { 147 done = true; 148 break; 149 } 150 151 rtmsg* r = (rtmsg*)NLMSG_DATA(hdr); 152 int remaining_len = RTM_PAYLOAD(hdr); 153 154 if (hdr->nlmsg_type != RTM_NEWROUTE) { 155 continue; // Skip non-route messages 156 } 157 158 // Only consider default routes (destination prefix length of 0). 159 if (r->rtm_dst_len != 0) { 160 continue; 161 } 162 163 // Iterate over the attributes. 164 rtattr* rta_gateway = nullptr; 165 int scope_id = 0; 166 for (rtattr* attr = RTM_RTA(r); RTA_OK(attr, remaining_len); attr = RTA_NEXT(attr, remaining_len)) { 167 if (attr->rta_type == RTA_GATEWAY) { 168 rta_gateway = attr; 169 } else if (attr->rta_type == RTA_OIF && sizeof(int) == RTA_PAYLOAD(attr)) { 170 std::memcpy(&scope_id, RTA_DATA(attr), sizeof(scope_id)); 171 } 172 } 173 174 // Found gateway? 175 if (rta_gateway != nullptr) { 176 if (family == AF_INET && sizeof(in_addr) == RTA_PAYLOAD(rta_gateway)) { 177 in_addr gw; 178 std::memcpy(&gw, RTA_DATA(rta_gateway), sizeof(gw)); 179 return CNetAddr(gw); 180 } else if (family == AF_INET6 && sizeof(in6_addr) == RTA_PAYLOAD(rta_gateway)) { 181 in6_addr gw; 182 std::memcpy(&gw, RTA_DATA(rta_gateway), sizeof(gw)); 183 return CNetAddr(gw, scope_id); 184 } 185 } 186 } 187 } 188 189 return std::nullopt; 190 } 191 192 #elif defined(WIN32) 193 194 std::optional<CNetAddr> QueryDefaultGatewayImpl(sa_family_t family) 195 { 196 NET_LUID interface_luid = {}; 197 SOCKADDR_INET destination_address = {}; 198 MIB_IPFORWARD_ROW2 best_route = {}; 199 SOCKADDR_INET best_source_address = {}; 200 DWORD best_if_idx = 0; 201 DWORD status = 0; 202 203 // Pass empty destination address of the requested type (:: or 0.0.0.0) to get interface of default route. 204 destination_address.si_family = family; 205 status = GetBestInterfaceEx((sockaddr*)&destination_address, &best_if_idx); 206 if (status != NO_ERROR) { 207 LogError("Could not get best interface for default route: %s\n", NetworkErrorString(status)); 208 return std::nullopt; 209 } 210 211 // Get best route to default gateway. 212 // Leave interface_luid at all-zeros to use interface index instead. 213 status = GetBestRoute2(&interface_luid, best_if_idx, nullptr, &destination_address, 0, &best_route, &best_source_address); 214 if (status != NO_ERROR) { 215 LogError("Could not get best route for default route for interface index %d: %s\n", 216 best_if_idx, NetworkErrorString(status)); 217 return std::nullopt; 218 } 219 220 Assume(best_route.NextHop.si_family == family); 221 if (family == AF_INET) { 222 return CNetAddr(best_route.NextHop.Ipv4.sin_addr); 223 } else if(family == AF_INET6) { 224 return CNetAddr(best_route.NextHop.Ipv6.sin6_addr, best_route.InterfaceIndex); 225 } 226 return std::nullopt; 227 } 228 229 #elif defined(__APPLE__) 230 231 #define ROUNDUP32(a) \ 232 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t)) 233 234 //! MacOS: Get default gateway from route table. See route(4) for the format. 235 std::optional<CNetAddr> QueryDefaultGatewayImpl(sa_family_t family) 236 { 237 // net.route.0.inet[6].flags.gateway 238 int mib[] = {CTL_NET, PF_ROUTE, 0, family, NET_RT_FLAGS, RTF_GATEWAY}; 239 // The size of the available data is determined by calling sysctl() with oldp=nullptr. See sysctl(3). 240 size_t l = 0; 241 if (sysctl(/*name=*/mib, /*namelen=*/sizeof(mib) / sizeof(int), /*oldp=*/nullptr, /*oldlenp=*/&l, /*newp=*/nullptr, /*newlen=*/0) < 0) { 242 LogError("Could not get sysctl length of routing table: %s\n", SysErrorString(errno)); 243 return std::nullopt; 244 } 245 std::vector<std::byte> buf(l); 246 if (sysctl(/*name=*/mib, /*namelen=*/sizeof(mib) / sizeof(int), /*oldp=*/buf.data(), /*oldlenp=*/&l, /*newp=*/nullptr, /*newlen=*/0) < 0) { 247 LogError("Could not get sysctl data of routing table: %s\n", SysErrorString(errno)); 248 return std::nullopt; 249 } 250 // Iterate over messages (each message is a routing table entry). 251 for (size_t msg_pos = 0; msg_pos < buf.size(); ) { 252 if ((msg_pos + sizeof(rt_msghdr)) > buf.size()) return std::nullopt; 253 const struct rt_msghdr* rt = (const struct rt_msghdr*)(buf.data() + msg_pos); 254 const size_t next_msg_pos = msg_pos + rt->rtm_msglen; 255 if (rt->rtm_msglen < sizeof(rt_msghdr) || next_msg_pos > buf.size()) return std::nullopt; 256 // Iterate over addresses within message, get destination and gateway (if present). 257 // Address data starts after header. 258 size_t sa_pos = msg_pos + sizeof(struct rt_msghdr); 259 std::optional<CNetAddr> dst, gateway; 260 for (int i = 0; i < RTAX_MAX; i++) { 261 if (rt->rtm_addrs & (1 << i)) { 262 // 2 is just sa_len + sa_family, the theoretical minimum size of a socket address. 263 if ((sa_pos + 2) > next_msg_pos) return std::nullopt; 264 const struct sockaddr* sa = (const struct sockaddr*)(buf.data() + sa_pos); 265 if ((sa_pos + sa->sa_len) > next_msg_pos) return std::nullopt; 266 if (i == RTAX_DST) { 267 dst = FromSockAddr(sa, sa->sa_len); 268 } else if (i == RTAX_GATEWAY) { 269 gateway = FromSockAddr(sa, sa->sa_len); 270 } 271 // Skip sockaddr entries for bit flags we're not interested in, 272 // move cursor. 273 sa_pos += ROUNDUP32(sa->sa_len); 274 } 275 } 276 // Found default gateway? 277 if (dst && gateway && dst->IsBindAny()) { // Route to 0.0.0.0 or :: ? 278 return *gateway; 279 } 280 // Skip to next message. 281 msg_pos = next_msg_pos; 282 } 283 return std::nullopt; 284 } 285 286 #else 287 288 // Dummy implementation. 289 std::optional<CNetAddr> QueryDefaultGatewayImpl(sa_family_t) 290 { 291 return std::nullopt; 292 } 293 294 #endif 295 296 } 297 298 std::optional<CNetAddr> QueryDefaultGateway(Network network) 299 { 300 Assume(network == NET_IPV4 || network == NET_IPV6); 301 302 sa_family_t family; 303 if (network == NET_IPV4) { 304 family = AF_INET; 305 } else if(network == NET_IPV6) { 306 family = AF_INET6; 307 } else { 308 return std::nullopt; 309 } 310 311 std::optional<CNetAddr> ret = QueryDefaultGatewayImpl(family); 312 313 // It's possible for the default gateway to be 0.0.0.0 or ::0 on at least Windows 314 // for some routing strategies. If so, return as if no default gateway was found. 315 if (ret && !ret->IsBindAny()) { 316 return ret; 317 } else { 318 return std::nullopt; 319 } 320 } 321 322 std::vector<CNetAddr> GetLocalAddresses() 323 { 324 std::vector<CNetAddr> addresses; 325 #ifdef WIN32 326 DWORD status = 0; 327 constexpr size_t MAX_ADAPTER_ADDR_SIZE = 4 * 1000 * 1000; // Absolute maximum size of adapter addresses structure we're willing to handle, as a precaution. 328 std::vector<std::byte> out_buf(15000, {}); // Start with 15KB allocation as recommended in GetAdaptersAddresses documentation. 329 while (true) { 330 ULONG out_buf_len = out_buf.size(); 331 status = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, 332 nullptr, reinterpret_cast<PIP_ADAPTER_ADDRESSES>(out_buf.data()), &out_buf_len); 333 if (status == ERROR_BUFFER_OVERFLOW && out_buf.size() < MAX_ADAPTER_ADDR_SIZE) { 334 // If status == ERROR_BUFFER_OVERFLOW, out_buf_len will contain the needed size. 335 // Unfortunately, this cannot be fully relied on, because another process may have added interfaces. 336 // So to avoid getting stuck due to a race condition, double the buffer size at least 337 // once before retrying (but only up to the maximum allowed size). 338 out_buf.resize(std::min(std::max<size_t>(out_buf_len, out_buf.size()) * 2, MAX_ADAPTER_ADDR_SIZE)); 339 } else { 340 break; 341 } 342 } 343 344 if (status != NO_ERROR) { 345 // This includes ERROR_NO_DATA if there are no addresses and thus there's not even one PIP_ADAPTER_ADDRESSES 346 // record in the returned structure. 347 LogError("Could not get local adapter addresses: %s\n", NetworkErrorString(status)); 348 return addresses; 349 } 350 351 // Iterate over network adapters. 352 for (PIP_ADAPTER_ADDRESSES cur_adapter = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(out_buf.data()); 353 cur_adapter != nullptr; cur_adapter = cur_adapter->Next) { 354 if (cur_adapter->OperStatus != IfOperStatusUp) continue; 355 if (cur_adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; 356 357 // Iterate over unicast addresses for adapter, the only address type we're interested in. 358 for (PIP_ADAPTER_UNICAST_ADDRESS cur_address = cur_adapter->FirstUnicastAddress; 359 cur_address != nullptr; cur_address = cur_address->Next) { 360 // "The IP address is a cluster address and should not be used by most applications." 361 if ((cur_address->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) != 0) continue; 362 363 if (std::optional<CNetAddr> addr = FromSockAddr(cur_address->Address.lpSockaddr, static_cast<socklen_t>(cur_address->Address.iSockaddrLength))) { 364 addresses.push_back(*addr); 365 } 366 } 367 } 368 #elif defined(HAVE_IFADDRS) 369 struct ifaddrs* myaddrs; 370 if (getifaddrs(&myaddrs) == 0) { 371 for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next) 372 { 373 if (ifa->ifa_addr == nullptr) continue; 374 if ((ifa->ifa_flags & IFF_UP) == 0) continue; 375 if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) continue; 376 377 if (std::optional<CNetAddr> addr = FromSockAddr(ifa->ifa_addr, std::nullopt)) { 378 addresses.push_back(*addr); 379 } 380 } 381 freeifaddrs(myaddrs); 382 } 383 #endif 384 return addresses; 385 }