Linux/Windows枚举主机IP和MAC等网卡信息

xingyun86 2022-1-14 766

Linux/Windows枚举主机IP和MAC等网卡信息

#include <string>
#include <vector>
#ifdef _MSC_VER
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
#define  _WINSOCK_DEPRECATED_NO_WARNINGS
#endif // !_WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include <iphlpapi.h>
#pragma comment(lib, "Iphlpapi.lib")
#else
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <limits.h>
#endif
#pragma pack(1)
typedef struct __xxx__ { uint8_t v; }__xxx__;
typedef struct netcardinfo {
    char ip[16];
    char mac[6];
    char ifname[512];
    char ifdesc[512];
    char netmask[16];
}netcardinfo;
#pragma pack()
class SockUtil {
public:
#ifdef _MSC_VER
    WSADATA wsadata = { 0 };
#endif
    SockUtil()
    {
#ifdef _MSC_VER
        //初始化套接字库
        WORD w_req = MAKEWORD(2, 2);//版本号
        int err;
        err = WSAStartup(w_req, &wsadata);
        if (err != 0)
        {
            std::cout << "Initialize winsock library failed!" << std::endl;
        }
        else
        {
            std::cout << "Initialize winsock library ok!" << std::endl;
        }
        //检测版本号
        if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2)
        {
            std::cout << "Winsock library version failed!" << std::endl;
            WSACleanup();
        }
        else
        {
            std::cout << "Winsock library version ok!" << std::endl;
        }
#endif
    }
    ~SockUtil()
    {
#ifdef _MSC_VER
        WSACleanup();
#endif
    }
private:
    int enum_host_addr(std::vector<std::string>& sv, int af/*= AF_INET or AF_INET6*/)
    {
        int ret = 0;
        char ip[65] = { 0 };
        struct sockaddr_in* addr = nullptr;
#ifdef _MSC_VER
        char host_name[33] = { 0 };
        struct addrinfo hints = { 0 };
        struct addrinfo* res = nullptr;
        struct addrinfo* cur = nullptr;
        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family = af; /* Allow IPv4 */
        hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
        hints.ai_protocol = 0; /* Any protocol */
        hints.ai_socktype = SOCK_STREAM;
        ret = gethostname(host_name, sizeof(host_name) / sizeof(*host_name));
        if (ret == 0)
        {
            ret = getaddrinfo(host_name, nullptr, &hints, &res);
            if (ret == 0) {
                for (cur = res; cur != nullptr; cur = cur->ai_next) {
                    addr = (struct sockaddr_in*)cur->ai_addr;
                    inet_ntop(af, &addr->sin_addr, ip, sizeof(ip) / sizeof(*ip));
                    //std::cout << ip << std::endl;
                    sv.emplace_back(ip);
                }
                freeaddrinfo(res);
            }
        }
#else
        struct ifaddrs* ifa = nullptr;
        struct ifaddrs* oifa = nullptr;
        ret = getifaddrs(&ifa);
        if (ret == 0)
        {
            oifa = ifa;
            while (ifa != nullptr)
            {
                // IPv4 排除localhost
                if (ifa->ifa_addr != nullptr
                    && ifa->ifa_addr->sa_family == af
                    && strncmp(ifa->ifa_name, "lo", 2) != 0)
                {
                    addr = (struct sockaddr_in*)ifa->ifa_addr;
                    inet_ntop(af, &addr->sin_addr, ip, sizeof(ip) / sizeof(*ip));
                    //std::cout << ip << std::endl;
                    sv.emplace_back(ip);
                }
                ifa = ifa->ifa_next;
            }
            freeifaddrs(oifa);
        }
#endif
        return ret;
    }
public:
    int enum_host_addr_ipv4(std::vector<std::string>& sv)
    {
        return enum_host_addr(sv, AF_INET);
    }
    int enum_host_addr_ipv6(std::vector<std::string>& sv)
    {
        return enum_host_addr(sv, AF_INET6);
    }
    int enum_host_mac_addr_ipv4(std::vector<netcardinfo>&vNetcardInfo)
    {
#ifndef _MSC_VER
        int s = (-1);
        int ifc_num = 0;
        struct ifreq ifr = { 0 };
        struct ifconf ifc = { 0 };
        struct ifreq buf[64] = { 0 };
        s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
        if (s == -1)
        {
            printf("socket error\n");
            goto __leave_clean__;
        }
        ifc.ifc_len = sizeof(buf);
        ifc.ifc_buf = (caddr_t)buf;
        if (ioctl(s, SIOCGIFCONF, &ifc) == -1) 
        {
            printf("ioctl error\n");
            goto __leave_clean__;
        }
        ifc_num = ifc.ifc_len / sizeof(struct ifreq);
        
        while ((ifc_num--) > 0)
        {
            struct ifreq& ifr_it = buf[ifc_num];
            if (ioctl(s, SIOCGIFFLAGS, &ifr_it) == 0)
            {
                if ((ifr_it.ifr_flags & IFF_LOOPBACK) != IFF_LOOPBACK)
                {
                    // don't need loopback
                    netcardinfo nci = { 0 };
                    strcpy(nci.ifname, ifr_it.ifr_name);
                    strcpy(nci.ifdesc, ifr_it.ifr_name);
                    if (ioctl(s, SIOCGIFHWADDR, &ifr_it) == 0)
                    {
                        memcpy(nci.mac, ifr_it.ifr_ifru.ifru_hwaddr.sa_data, sizeof(nci.mac));
                        if (ioctl(s, SIOCGIFADDR, (char*)&ifr_it) == 0)
                        {
                            snprintf(nci.ip, sizeof(nci.ip)/sizeof(*nci.ip), "%s", (char*)inet_ntoa(((struct sockaddr_in*)&(ifr_it.ifr_addr))->sin_addr));
                            if (ioctl(s, SIOCGIFNETMASK, (char*)&ifr_it) == 0)
                            {
                                snprintf(nci.netmask, sizeof(*nci.netmask), "%s", (char*)inet_ntoa(((struct sockaddr_in*)&(ifr_it.ifr_netmask))->sin_addr));
                                vNetcardInfo.emplace_back(nci);
                            }
                        }
                    }
                }
            }
            else 
            {
                printf("get if flags error\n");
                goto __leave_clean__;
            }
        }
    __leave_clean__:
        if (s != (-1))
        {
            shutdown(s, SHUT_RDWR);
            close(s);
        }
#else
        ULONG nIpAdapterInfoSize = 0;
        IP_ADAPTER_INFO* pIpAdapterInfo = NULL;
        int IPnumPerNetCard = 0;
        if ((::GetAdaptersInfo(NULL, &nIpAdapterInfoSize) == ERROR_BUFFER_OVERFLOW) && (nIpAdapterInfoSize > 0))
        {
            pIpAdapterInfo = (IP_ADAPTER_INFO*)malloc(nIpAdapterInfoSize);
            if (pIpAdapterInfo != NULL)
            {
                if (::GetAdaptersInfo(pIpAdapterInfo, &nIpAdapterInfoSize) == ERROR_SUCCESS)
                {
                    IP_ADAPTER_INFO* pIter = pIpAdapterInfo;
                    while (pIter)
                    {
                        IP_ADDR_STRING* pIpAddressList = &(pIter->IpAddressList);
                        while (pIpAddressList)
                        {
                            netcardinfo nci = { 0 };
                            if (pIpAdapterInfo->AddressLength == sizeof(nci.mac) / sizeof(*nci.mac))
                            {
                                strcpy(nci.ifname, pIter->AdapterName);
                                strcpy(nci.ifdesc, pIter->Description);
                                memcpy(nci.mac, pIter->Address, pIter->AddressLength);
                                strcpy(nci.ip, pIpAddressList->IpAddress.String);
                                strcpy(nci.netmask, pIpAddressList->IpMask.String);
                                vNetcardInfo.emplace_back(nci);
                            }
                            pIpAddressList = pIpAddressList->Next;
                        }
                        pIter = pIter->Next;
                    }
                }
                free(pIpAdapterInfo);
                pIpAdapterInfo = NULL;
            }
        }
#endif // !_MSC_VER
        return 0;
    }
public:
    static SockUtil* Inst()
    {
        static SockUtil SockUtilInstance;
        return &SockUtilInstance;
    }
};


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回