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