使用getifaddrs获取本机网口IP地址

本文介绍了一个C++工具类,用于获取本机所有网卡的IPv4和IPv6地址信息。通过调用getifaddrs和getnameinfo系统函数,程序遍历接口地址并解析为可读格式。示例代码展示了如何使用该工具类并在main函数中打印结果。
摘要由CSDN通过智能技术生成

getifaddrs函数用来获取本机网卡上ip地址信息,如下所示我们实现了一个工具类,并测试验证。

#include <string>
#include <vector>
#include <map>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <string.h>

struct IfaceIpInfo {
    std::string ifName;
    std::vector<std::string> ipv4;
    std::vector<std::string> ipv6;
};

class IpTool {
public:
    static bool FetchAllIpAddress(std::map<std::string, IfaceIpInfo> &local)
    {
        struct ifaddrs *ifaddr = nullptr;
        struct ifaddrs *ifa = nullptr;
        if (getifaddrs(&ifaddr) == -1) {
            printf("getifaddrs failed, %s", strerror(errno));
            return false;
        }
        for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
            if (ifa->ifa_addr == nullptr) {
                continue;
            }
            int family = ifa->ifa_addr->sa_family;
            if (family != AF_INET && family != AF_INET6) {
                continue;
            }
            char addr[NI_MAXHOST] = {0};
            int ret = getnameinfo(ifa->ifa_addr,
                (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
                addr, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
            if (ret != 0) {
                printf("getnameinfo() failed: %s\n", gai_strerror(ret));
                freeifaddrs(ifaddr);
                return false;
            }
            std::string ifName = ifa->ifa_name;
            std::map<std::string, IfaceIpInfo>::iterator iter = local.find(ifName);
            if (iter == local.end()) {
                IfaceIpInfo tmp;
                iter = local.emplace(ifName, tmp).first;
            }
            if (family == AF_INET) {
                iter->second.ipv4.push_back(addr);
            } else {
                /* For an IPv6 address, the suffix %wlan0 exists. */
                char *sepNum = strchr(addr, '%');
                if (sepNum != nullptr) {
                    *sepNum = '\0';
                }
                iter->second.ipv6.push_back(addr);
            }
        }
        freeifaddrs(ifaddr);
        return true;
    }
};

int main(void)
{
    std::map<std::string, IfaceIpInfo> local;
    if (!IpTool::FetchAllIpAddress(local)) {
        printf("fetch ip address failed!");
        return -1;
    }
    for (auto iter = local.begin(); iter != local.end(); ++iter) {
        printf("iface [%s]\n", iter->first.c_str());
        printf("    ipv4 address is [\n");
        for (auto it = iter->second.ipv4.begin(); it != iter->second.ipv4.end(); ++it) {
            printf("        %s\n", it->c_str());
        }
        printf("]\n       ipv6 address is [\n");
        for (auto it = iter->second.ipv6.begin(); it != iter->second.ipv6.end(); ++it) {
            printf("        %s\n", it->c_str());
        }
        printf("]\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

togolife

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值