C++ 获取本地网卡信息

// GetNetworkCardInformation.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。






 /*
   --------    相关结构体    -----------
 



 // IP_ADDRESS_STRING - store an IP address as a dotted decimal string
 //
 
 typedef struct {
     char String[4 * 4];
 } IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
 
 //
 // IP_ADDR_STRING - store an IP address with its corresponding subnet mask,
 // both as dotted decimal strings
 //
 
 typedef struct _IP_ADDR_STRING {
     struct _IP_ADDR_STRING* Next;
     IP_ADDRESS_STRING IpAddress;
     IP_MASK_STRING IpMask;
     DWORD Context;
 } IP_ADDR_STRING, *PIP_ADDR_STRING;
 
 //
 // ADAPTER_INFO - per-adapter information. All IP addresses are stored as
 // strings
 //
            //IP_ADAPTER_INFO   结构体详解:此结构包含有关本地计算机上特定网络适配器的信息。



typedef struct _IP_ADAPTER_INFO {
    struct _IP_ADAPTER_INFO* Next;                          //指向适配器链表中下一个适配器的指针。
    DWORD ComboIndex;                                       //保留。
    Char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];          //适配器的名称
    char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];   //适配器的描述
    UINT AddressLength;                                     //适配器的硬件地址长度
    BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];               //适配器的硬件地址
    DWORD Index;                                            //适配器索引。
    UINT Type;                                              //适配器类型。以下列表显示了在头文件 IPIfCons.h 中定义的适配器类型值:
                                                                            //  MIB_IF_TYPE_OTHER 1
                                                                            //  MIB_IF_TYPE_ETHERNET 6
                                                                            //  MIB_IF_TYPE_TOKENRING 9
                                                                            //  MIB_IF_TYPE_FDDI 15
                                                                            //  MIB_IF_TYPE_PPP 23
                                                                            //  MIB_IF_TYPE_LOOPBACK 24
                                                                            //  MIB_IF_TYPE_SLIP 28
    UINT DhcpEnabled;                                       //如果为此适配器启用了动态主机配置协议 (DHCP),则为 TRUE。
    PIP_ADDR_STRING CurrentIpAddress;                       //此适配器的当前 IP 地址。
    IP_ADDR_STRING IpAddressList;                           //与此适配器关联的 IP 地址列表。
    IP_ADDR_STRING GatewayList;                             //此适配器的默认网关的 IP 地址。
    IP_ADDR_STRING DhcpServer;                              //此适配器的 DHCP 服务器的 IP 地址。
    BOOL HaveWins;                                          //如果此适配器使用 Windows Internet 名称服务 (WINS),则为 TRUE。
    IP_ADDR_STRING PrimaryWinsServer;                       //主 WINS 服务器的 IP 地址。
    IP_ADDR_STRING SecondaryWinsServer;                     //辅助 WINS 服务器的 IP 地址。
    time_t LeaseObtained;                                   //获得当前 DHCP 租约的时间
    time_t LeaseExpires;                                    //当前 DHCP 租约到期的时间
} IP_ADAPTER_INFO, * PIP_ADAPTER_INFO;                      
*/





// GetNetworkCardInformation.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。






 /*
   --------    相关结构体    -----------
 



 // IP_ADDRESS_STRING - store an IP address as a dotted decimal string
 //
 
 typedef struct {
     char String[4 * 4];
 } IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
 
 //
 // IP_ADDR_STRING - store an IP address with its corresponding subnet mask,
 // both as dotted decimal strings
 //
 
 typedef struct _IP_ADDR_STRING {
     struct _IP_ADDR_STRING* Next;
     IP_ADDRESS_STRING IpAddress;
     IP_MASK_STRING IpMask;
     DWORD Context;
 } IP_ADDR_STRING, *PIP_ADDR_STRING;
 
 //
 // ADAPTER_INFO - per-adapter information. All IP addresses are stored as
 // strings
 //
            //IP_ADAPTER_INFO   结构体详解:此结构包含有关本地计算机上特定网络适配器的信息。



typedef struct _IP_ADAPTER_INFO {
    struct _IP_ADAPTER_INFO* Next;                          //指向适配器链表中下一个适配器的指针。
    DWORD ComboIndex;                                       //保留。
    Char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];          //适配器的名称
    char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];   //适配器的描述
    UINT AddressLength;                                     //适配器的硬件地址长度
    BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];               //适配器的硬件地址
    DWORD Index;                                            //适配器索引。
    UINT Type;                                              //适配器类型。以下列表显示了在头文件 IPIfCons.h 中定义的适配器类型值:
                                                                            //  MIB_IF_TYPE_OTHER 1
                                                                            //  MIB_IF_TYPE_ETHERNET 6
                                                                            //  MIB_IF_TYPE_TOKENRING 9
                                                                            //  MIB_IF_TYPE_FDDI 15
                                                                            //  MIB_IF_TYPE_PPP 23
                                                                            //  MIB_IF_TYPE_LOOPBACK 24
                                                                            //  MIB_IF_TYPE_SLIP 28
    UINT DhcpEnabled;                                       //如果为此适配器启用了动态主机配置协议 (DHCP),则为 TRUE。
    PIP_ADDR_STRING CurrentIpAddress;                       //此适配器的当前 IP 地址。
    IP_ADDR_STRING IpAddressList;                           //与此适配器关联的 IP 地址列表。
    IP_ADDR_STRING GatewayList;                             //此适配器的默认网关的 IP 地址。
    IP_ADDR_STRING DhcpServer;                              //此适配器的 DHCP 服务器的 IP 地址。
    BOOL HaveWins;                                          //如果此适配器使用 Windows Internet 名称服务 (WINS),则为 TRUE。
    IP_ADDR_STRING PrimaryWinsServer;                       //主 WINS 服务器的 IP 地址。
    IP_ADDR_STRING SecondaryWinsServer;                     //辅助 WINS 服务器的 IP 地址。
    time_t LeaseObtained;                                   //获得当前 DHCP 租约的时间
    time_t LeaseExpires;                                    //当前 DHCP 租约到期的时间
} IP_ADAPTER_INFO, * PIP_ADAPTER_INFO;                      
*/





#include <WinSock2.h>

#include <iostream>

#include <Iphlpapi.h>

#include <string>

#include <stdlib.h>

#pragma comment(lib,"Iphlpapi.lib")


/// @brief 拆功能键结构体, 获取信息
void GetNetworkCard();

void NetworkCardInformation(PIP_ADAPTER_INFO pIpAdapterInfo);

int getMac();

int main()
{
   //两个都可以使用
   GetNetworkCard();
  // getMac();
    return 0;
}



int getMac() {
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;
    UINT i;

    /* variables used to print DHCP time info */
    struct tm newtime;
    char buffer[32];
    errno_t error;

    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
    if (pAdapterInfo == NULL) {
        printf("Error allocating memory needed to call GetAdaptersinfo\n");
        return 1;
    }
    // Make an initial call to GetAdaptersInfo to get
    // the necessary size into the ulOutBufLen variable
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
        if (pAdapterInfo == NULL) {
            printf("Error allocating memory needed to call GetAdaptersinfo\n");
            return 1;
        }
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
        pAdapter = pAdapterInfo;
        while (pAdapter) {
            std::cout << "------------------------" << std::endl;
            printf("\tComboIndex: \t5d\n", pAdapter->ComboIndex);
            printf("\tAdapter Name: \t%s\n", pAdapter->AdapterName);
            printf("\tAdapter Desc: \t%s\n", pAdapter->Description);
            printf("\tAdapter Addr: \t");
            for (i = 0; i < pAdapter->AddressLength; i++) {
                if (i == (pAdapter->AddressLength - 1))
                    printf("%.2X\n", (int)pAdapter->Address[i]);
                else
                    printf("%.2X-", (int)pAdapter->Address[i]);
            }
            printf("\tIndex: \t%d\n", pAdapter->Index);
            printf("\tType: \t");
            switch (pAdapter->Type) {
            case MIB_IF_TYPE_OTHER:
                printf("Other\n");
                break;
            case MIB_IF_TYPE_ETHERNET:
                printf("Ethernet\n");
                break;
            case MIB_IF_TYPE_TOKENRING:
                printf("Token Ring\n");
                break;
            case MIB_IF_TYPE_FDDI:
                printf("FDDI\n");
                break;
            case MIB_IF_TYPE_PPP:
                printf("PPP\n");
                break;
            case MIB_IF_TYPE_LOOPBACK:
                printf("Lookback\n");
                break;
            case MIB_IF_TYPE_SLIP:
                printf("Slip\n");
                break;
            default:
                printf("Unknown type %ld\n", pAdapter->Type);
                break;
            }

            printf("\tIP Address: \t%s\n",
                pAdapter->IpAddressList.IpAddress.String);
            printf("\tIP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);

            printf("\tGateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
            printf("\t***\n");

            if (pAdapter->DhcpEnabled) {
                printf("\tDHCP Enabled: Yes\n");
                printf("\t  DHCP Server: \t%s\n",
                    pAdapter->DhcpServer.IpAddress.String);

                printf("\t  Lease Obtained: ");
                /* Display local time */
                error = _localtime32_s(&newtime, (const __time32_t* )&pAdapter->LeaseObtained);
                if (error)
                    printf("Invalid Argument to _localtime32_s\n");
                else {
                    // Convert to an ASCII representation 
                    error = asctime_s(buffer, 32, &newtime);
                    if (error)
                        printf("Invalid Argument to asctime_s\n");
                    else
                        /* asctime_s returns the string terminated by \n\0 */
                        printf("%s", buffer);
                }

                printf("\t  Lease Expires:  ");
                error = _localtime32_s(&newtime, (const __time32_t*)&pAdapter->LeaseExpires);
                if (error)
                    printf("Invalid Argument to _localtime32_s\n");
                else {
                    // Convert to an ASCII representation 
                    error = asctime_s(buffer, 32, &newtime);
                    if (error)
                        printf("Invalid Argument to asctime_s\n");
                    else
                        /* asctime_s returns the string terminated by \n\0 */
                        printf("%s", buffer);
                }
            }
            else
                printf("\tDHCP Enabled: No\n");

            if (pAdapter->HaveWins) {
                printf("\tHave Wins: Yes\n");
                printf("\t  Primary Wins Server:    %s\n",
                    pAdapter->PrimaryWinsServer.IpAddress.String);
                printf("\t  Secondary Wins Server:  %s\n",
                    pAdapter->SecondaryWinsServer.IpAddress.String);
            }
            else
                printf("\tHave Wins: No\n");
            pAdapter = pAdapter->Next;
            std::cout << "------------------------" << std::endl;
            printf("\n");
        }
    }
    else {
        printf("GetAdaptersInfo failed with error: %d\n", dwRetVal);

    }
    if (pAdapterInfo)
        free(pAdapterInfo);

    return 0;

}

/// @brief 拆功能键结构体, 获取信息
void GetNetworkCard() {
    //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
    PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();

    //得到结构体大小,用于GetAdaptersInfo参数
    unsigned long stSize = sizeof(IP_ADAPTER_INFO);

    //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
    int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);

    if (ERROR_BUFFER_OVERFLOW == nRel)
    {
        //如果函数返回的是ERROR_BUFFER_OVERFLOW
           //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
       //这也是说明为什么stSize既是一个输入量也是一个输出量
       //释放原来的内存空间
        delete pIpAdapterInfo;

        //重新申请内存空间用来存储所有网卡信息
        pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];

        //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
        nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);

    }
    if (ERROR_SUCCESS == nRel)
    {
        //输出网卡信息
        NetworkCardInformation(pIpAdapterInfo);
    }
    //释放内存空间
    if (pIpAdapterInfo)
    {
        delete pIpAdapterInfo;
    }
}






///函数作用,输出网卡信息
void NetworkCardInformation(PIP_ADAPTER_INFO pIpAdapterInfo)
{
    //可能有多网卡,因此通过循环去判断
    while (pIpAdapterInfo)
    {
        int i;
        std::cout << "网卡名称:" << pIpAdapterInfo->AdapterName << std::endl;
        std::cout << "网卡描述:" << pIpAdapterInfo->Description << std::endl;
        std::cout << "网卡MAC地址:";// << (unsigned char*)pIpAdapterInfo->Address << std::endl;
        for (i = 0; i < pIpAdapterInfo->AddressLength; i++) {
            if (i == (pIpAdapterInfo->AddressLength - 1))
                printf("%.2X\n", (int)pIpAdapterInfo->Address[i]);
            else
                printf("%.2X-", (int)pIpAdapterInfo->Address[i]);
        }
        std::cout << "默认网关:"    << pIpAdapterInfo->GatewayList.IpAddress.String << std::endl;
        for (UINT i = 0; i < pIpAdapterInfo->AddressLength; i++)
            if (i == pIpAdapterInfo->AddressLength - 1)
            {
                printf("%02x\n", pIpAdapterInfo->Address[i]);
            }
            else
            {
                printf("%02x-", pIpAdapterInfo->Address[i]);
            }
        std::cout << "网卡IP地址如下:" << std::endl;
        //可能网卡有多IP,因此通过循环去判断
        IP_ADDR_STRING* pIpAddrString = &(pIpAdapterInfo->IpAddressList);
        do
        {
            std::cout << pIpAddrString->IpAddress.String << std::endl;
            pIpAddrString = pIpAddrString->Next;
        } while (pIpAddrString);
        pIpAdapterInfo = pIpAdapterInfo->Next;
        std::cout << "*****************************************************" << std::endl;
    }
    return;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

孔二他老表

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

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

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

打赏作者

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

抵扣说明:

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

余额充值