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