| 2656 | |
| 2657 | #ifdef USE_IF2IP |
| 2658 | inline std::string if2ip(int address_family, const std::string &ifn) { |
| 2659 | struct ifaddrs *ifap; |
| 2660 | getifaddrs(&ifap); |
| 2661 | std::string addr_candidate; |
| 2662 | for (auto ifa = ifap; ifa; ifa = ifa->ifa_next) { |
| 2663 | if (ifa->ifa_addr && ifn == ifa->ifa_name && |
| 2664 | (AF_UNSPEC == address_family || |
| 2665 | ifa->ifa_addr->sa_family == address_family)) { |
| 2666 | if (ifa->ifa_addr->sa_family == AF_INET) { |
| 2667 | auto sa = reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr); |
| 2668 | char buf[INET_ADDRSTRLEN]; |
| 2669 | if (inet_ntop(AF_INET, &sa->sin_addr, buf, INET_ADDRSTRLEN)) { |
| 2670 | freeifaddrs(ifap); |
| 2671 | return std::string(buf, INET_ADDRSTRLEN); |
| 2672 | } |
| 2673 | } else if (ifa->ifa_addr->sa_family == AF_INET6) { |
| 2674 | auto sa = reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_addr); |
| 2675 | if (!IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr)) { |
| 2676 | char buf[INET6_ADDRSTRLEN] = {}; |
| 2677 | if (inet_ntop(AF_INET6, &sa->sin6_addr, buf, INET6_ADDRSTRLEN)) { |
| 2678 | // equivalent to mac's IN6_IS_ADDR_UNIQUE_LOCAL |
| 2679 | auto s6_addr_head = sa->sin6_addr.s6_addr[0]; |
| 2680 | if (s6_addr_head == 0xfc || s6_addr_head == 0xfd) { |
| 2681 | addr_candidate = std::string(buf, INET6_ADDRSTRLEN); |
| 2682 | } else { |
| 2683 | freeifaddrs(ifap); |
| 2684 | return std::string(buf, INET6_ADDRSTRLEN); |
| 2685 | } |
| 2686 | } |
| 2687 | } |
| 2688 | } |
| 2689 | } |
| 2690 | } |
| 2691 | freeifaddrs(ifap); |
| 2692 | return addr_candidate; |
| 2693 | } |
| 2694 | #endif |
| 2695 | |
| 2696 | inline socket_t create_client_socket( |
no outgoing calls
no test coverage detected