| 406 | } |
| 407 | |
| 408 | std::vector<std::string> GetLocalIPAddresses() { |
| 409 | std::vector<std::string> ip_addresses; |
| 410 | ifaddrs *if_addr_struct = nullptr; |
| 411 | std::unique_ptr<ifaddrs, decltype(&freeifaddrs)> ifaddrs_ptr(nullptr, &freeifaddrs); |
| 412 | if (getifaddrs(&if_addr_struct) == -1) { |
| 413 | return ip_addresses; |
| 414 | } |
| 415 | ifaddrs_ptr.reset(if_addr_struct); |
| 416 | |
| 417 | for (ifaddrs *ifa = if_addr_struct; ifa; ifa = ifa->ifa_next) { |
| 418 | if (!ifa->ifa_addr) { |
| 419 | continue; |
| 420 | } |
| 421 | void *tmp_addr_ptr = nullptr; |
| 422 | if (ifa->ifa_addr->sa_family == AF_INET) { |
| 423 | // check it is IPv4 |
| 424 | tmp_addr_ptr = &((sockaddr_in *)ifa->ifa_addr)->sin_addr; |
| 425 | char address_buffer[INET_ADDRSTRLEN]; |
| 426 | inet_ntop(AF_INET, tmp_addr_ptr, address_buffer, INET_ADDRSTRLEN); |
| 427 | ip_addresses.emplace_back(address_buffer); |
| 428 | } else if (ifa->ifa_addr->sa_family == AF_INET6) { |
| 429 | // check it is IPv6 |
| 430 | tmp_addr_ptr = &((sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; |
| 431 | char address_buffer[INET6_ADDRSTRLEN]; |
| 432 | inet_ntop(AF_INET6, tmp_addr_ptr, address_buffer, INET6_ADDRSTRLEN); |
| 433 | ip_addresses.emplace_back(address_buffer); |
| 434 | } |
| 435 | } |
| 436 | |
| 437 | return ip_addresses; |
| 438 | } |
| 439 | |
| 440 | template <auto syscall, typename FD, typename... Args> |
| 441 | Status WriteImpl(FD fd, std::string_view data, Args &&...args) { |