Windows下获取网卡基础信息及MAC地址IP子网掩码DNS信息
#pragma once #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") #include <ws2tcpip.h> #include <tcpestats.h> #include <iphlpapi.h> #pragma comment(lib,"iphlpapi.lib") #include <vector> #include <unordered_map> #include <utils.h> class CNetworkMgr { public: #if (_WIN32_WINNT < 0x0600/*_WIN32_WINNT_VISTA*/) #define IN6ADDRSZ 16 #define INT16SZ 2 static const char* inet_ntop4(const u_char* src, char* dst, size_t size) { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; sprintf(tmp, fmt, src[0], src[1], src[2], src[3]); if (strlen(tmp) > size) { return NULL; } strcpy(dst, tmp); return (dst); } static const char* inet_ntop6(const u_char* src, char* dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], * tp; struct { int base, len; } best, cur; u_int words[IN6ADDRSZ / INT16SZ]; int i; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, 0, sizeof words); for (i = 0; i < IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp))) return (NULL); tp += strlen(tp); break; } sprintf(tp, "%x", words[i]); tp += strlen(tp); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((tp - tmp) > size) { return (NULL); } strcpy(dst, tmp); return (dst); } static const char* inet_ntop(int af, const void* src, char* dst, size_t size) { switch (af) { case AF_INET: return (inet_ntop4((const u_char*)src, dst, size)); case AF_INET6: return (inet_ntop6((const u_char*)src, dst, size)); default: return (NULL); } /* NOTREACHED */ } #endif//(0x0600/*_WIN32_WINNT_VISTA*/) class InOutBytes { public: uint64_t InBytes = 0; uint64_t OutBytes = 0; void clear() { this->InBytes = 0; this->OutBytes = 0; } }; class NICInfo { public: std::string FriendlyName = (""); //显示名称 std::string AdapterName = (""); //网卡名称 std::string Description = (""); //网卡描述 std::string MacAddr = (""); //MAC地址 std::string CurrentIpAddress = (""); //当前IP地址 std::unordered_map<std::string, std::string> IpAddressMaskList = {}; //<IP地址,子网掩码>列表 std::vector<std::string> GateAwayIpAddressList = {}; //网关IP地址列表 std::vector<std::string> DNSIpAddressList = {}; //DNS列表 InOutBytes BytesLinkSpeed = {};//接收和发送带宽速率 }; std::vector<NICInfo> m_nicInfoList = {}; InOutBytes m_totalBytes = {}; InOutBytes m_totalBytesPerSecond = {}; std::unordered_map<DWORD, InOutBytes> m_procStatList = {}; std::unordered_map<DWORD, InOutBytes> m_procStatSpeedList = {}; BOOL GetHostAdaptersInfo() //获取网卡信息 及 IP地址 列表 { m_nicInfoList.clear(); ULONG ulRet = 0; PBYTE pIpAdapterInfo = NULL; ULONG ulAdapterInfoSize = 0; ULONG Flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS;//包括 IPV4 ,IPV6 网关 ULONG Family = AF_INET;// AF_UNSPEC;//返回包括 IPV4 和 IPV6 地址 PBYTE pIpAdapterAddresses = NULL; ULONG ulAdapterAddressSize = 0; PIP_ADAPTER_INFO pAdapterInfoIterater = NULL; PIP_ADAPTER_ADDRESSES pAdapterAddressIterater = NULL; IP_ADAPTER_DNS_SERVER_ADDRESS* pIpAdapterDNSServerAddress = NULL; ulRet = GetAdaptersAddresses(Family, Flags, NULL, (PIP_ADAPTER_ADDRESSES)pIpAdapterAddresses, &ulAdapterAddressSize); if (ulRet == ERROR_BUFFER_OVERFLOW) { //重新分配大小 pIpAdapterAddresses = new BYTE[ulAdapterAddressSize]; if (pIpAdapterAddresses == nullptr) { return FALSE; } //获取适配器信息 ulRet = GetAdaptersAddresses(Family, Flags, NULL, (PIP_ADAPTER_ADDRESSES)pIpAdapterAddresses, &ulAdapterAddressSize); //获取失败 if (ulRet != ERROR_SUCCESS) { if (pIpAdapterAddresses != nullptr) { delete[]pIpAdapterAddresses; } return FALSE; } pAdapterAddressIterater = (PIP_ADAPTER_ADDRESSES)pIpAdapterAddresses; } //获取适配器信息 ulRet = GetAdaptersInfo((PIP_ADAPTER_INFO)pIpAdapterInfo, &ulAdapterInfoSize); if (ulRet == ERROR_BUFFER_OVERFLOW) { //重新分配大小 pIpAdapterInfo = new BYTE[ulAdapterInfoSize]; if (pIpAdapterInfo == nullptr) { if (pIpAdapterAddresses != nullptr) { delete[]pIpAdapterAddresses; } return FALSE; } //获取适配器信息 ulRet = GetAdaptersInfo((PIP_ADAPTER_INFO)pIpAdapterInfo, &ulAdapterInfoSize); //获取失败 if (ulRet != ERROR_SUCCESS) { if (pIpAdapterAddresses != nullptr) { delete[]pIpAdapterAddresses; } if (pIpAdapterInfo != NULL) { delete[]pIpAdapterInfo; } return FALSE; } pAdapterInfoIterater = (PIP_ADAPTER_INFO)pIpAdapterInfo; } while (pAdapterInfoIterater != nullptr) { NICInfo nicInfo = { }; nicInfo.AdapterName = pAdapterInfoIterater->AdapterName; //网卡名称 nicInfo.Description = pAdapterInfoIterater->Description; //网卡描述 //MAC地址 nicInfo.MacAddr = CUtils::format_string("%02X-%02X-%02X-%02X-%02X-%02X", pAdapterInfoIterater->Address[0], pAdapterInfoIterater->Address[1], pAdapterInfoIterater->Address[2], pAdapterInfoIterater->Address[3], pAdapterInfoIterater->Address[4], pAdapterInfoIterater->Address[5]); //当前IP地址 if (pAdapterInfoIterater->CurrentIpAddress != nullptr) { nicInfo.CurrentIpAddress = pAdapterInfoIterater->CurrentIpAddress->IpAddress.String; } //指向IP地址子网掩码列表 PIP_ADDR_STRING pIpAddr = &pAdapterInfoIterater->IpAddressList; while (pIpAddr != nullptr) { nicInfo.IpAddressMaskList.emplace(pIpAddr->IpAddress.String, pIpAddr->IpMask.String);//<IP地址,子网掩码> //指向网关地址列表 PIP_ADDR_STRING pGateAwayList = &pAdapterInfoIterater->GatewayList; while (pGateAwayList != nullptr) { nicInfo.GateAwayIpAddressList.emplace_back(pGateAwayList->IpAddress.String); //网关 pGateAwayList = pGateAwayList->Next; } pIpAddr = pIpAddr->Next; } //DNS1/DNS2地址 pAdapterAddressIterater = (PIP_ADAPTER_ADDRESSES)pIpAdapterAddresses; while (pAdapterAddressIterater != nullptr) { if (nicInfo.AdapterName.compare(pAdapterAddressIterater->AdapterName) == 0) { nicInfo.FriendlyName = CUtils::W_To_A(pAdapterAddressIterater->FriendlyName); nicInfo.BytesLinkSpeed.InBytes = pAdapterAddressIterater->ReceiveLinkSpeed; nicInfo.BytesLinkSpeed.OutBytes = pAdapterAddressIterater->TransmitLinkSpeed; pIpAdapterDNSServerAddress = pAdapterAddressIterater->FirstDnsServerAddress; while (pIpAdapterDNSServerAddress != nullptr) { CHAR DNS[132] = { 0 }; switch (pIpAdapterDNSServerAddress->Address.lpSockaddr->sa_family) { case AF_INET: { inet_ntop(pIpAdapterDNSServerAddress->Address.lpSockaddr->sa_family, &((sockaddr_in*)pIpAdapterDNSServerAddress->Address.lpSockaddr)->sin_addr, DNS, sizeof(DNS)); nicInfo.DNSIpAddressList.emplace_back(DNS); } break; case AF_INET6: { inet_ntop(pIpAdapterDNSServerAddress->Address.lpSockaddr->sa_family, &((sockaddr_in6*)pIpAdapterDNSServerAddress->Address.lpSockaddr)->sin6_addr, DNS, sizeof(DNS)); } break; default: break; } pIpAdapterDNSServerAddress = pIpAdapterDNSServerAddress->Next; } break; } pAdapterAddressIterater = pAdapterAddressIterater->Next; } m_nicInfoList.emplace_back(nicInfo); pAdapterInfoIterater = pAdapterInfoIterater->Next; } if (pIpAdapterInfo != nullptr) { delete[]pIpAdapterInfo; } if (pIpAdapterAddresses != nullptr) { delete[]pIpAdapterAddresses; } return TRUE; } void GetProcessIpInOutBytes() { GetNetworkProcessStat(m_procStatList); } void GetProcessIpInOutSpeed() { std::unordered_map<DWORD, InOutBytes> procStatSpeedList = {}; m_procStatSpeedList.clear(); GetNetworkProcessStat(procStatSpeedList); TIMERSTARTS(A); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); GetNetworkProcessStat(m_procStatSpeedList); TIMERSTARTS(B); for (auto &it : m_procStatSpeedList) { auto itFind = procStatSpeedList.find(it.first); if(itFind != procStatSpeedList.end()) { it.second.InBytes = (it.second.InBytes - itFind->second.InBytes) * 1000 / TIMERCNT_MS(A, B); it.second.OutBytes = (it.second.OutBytes - itFind->second.OutBytes) * 1000 / TIMERCNT_MS(A, B); } } } void GetIpInOutBytes() { m_totalBytes.clear(); GetTotalIpStatistics(m_totalBytes); } void GetIpInOutSpeed() { InOutBytes utotalBytesPerSecond = {}; m_totalBytesPerSecond.clear(); GetTotalIpStatistics(utotalBytesPerSecond); TIMERSTARTS(A); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); GetTotalIpStatistics(m_totalBytesPerSecond); TIMERSTARTS(B); m_totalBytesPerSecond.InBytes = (m_totalBytesPerSecond.InBytes - utotalBytesPerSecond.InBytes) * 1000 / TIMERCNT_MS(A, B); m_totalBytesPerSecond.OutBytes = (m_totalBytesPerSecond.OutBytes - utotalBytesPerSecond.OutBytes) * 1000 / TIMERCNT_MS(A, B); } double ToK(uint64_t n) { return (double)n / 1024; } double ToM(uint64_t n) { return (double)n / 1024 / 1024; } double ToG(uint64_t n) { return (double)n / 1024 / 1024 / 1024; } std::string ToKMG(uint64_t n) { if (n > 1024) { if ((n / 1024) > 1024) { if ((n / 1024 / 1024) > 1024) { return CUtils::format_string("%.2f gb", ToG(n)); } else { return CUtils::format_string("%.2f mb", ToM(n)); } } else { return CUtils::format_string("%.2f kb", ToK(n)); } } else { return CUtils::format_string("%.2f b", (double)n); } } void Print() { for (auto it : m_nicInfoList) { std::cout << it.FriendlyName << std::endl; std::cout << it.AdapterName << std::endl; std::cout << it.Description << std::endl; std::cout << it.MacAddr << std::endl; std::cout << it.CurrentIpAddress << std::endl; for (auto iit : it.IpAddressMaskList) { std::cout << iit.first << std::endl; std::cout << iit.second << std::endl; } for (auto git : it.GateAwayIpAddressList) { std::cout << git << std::endl; } for (auto dit : it.DNSIpAddressList) { std::cout << dit << std::endl; } std::cout << it.BytesLinkSpeed.InBytes / 1000 / 1000 << "m" << std::endl; std::cout << it.BytesLinkSpeed.OutBytes / 1000 / 1000 << "m" << std::endl; } std::cout << "接收大小:" << ToKMG(m_totalBytes.InBytes) << std::endl; std::cout << "发送大小:" << ToKMG(m_totalBytes.OutBytes) << std::endl; std::cout << "接收速率:" << ToKMG(m_totalBytesPerSecond.InBytes) << "/s" << std::endl; std::cout << "发送速率:" << ToKMG(m_totalBytesPerSecond.OutBytes) << "/s" << std::endl; for (auto it : m_procStatList) { std::cout << it.first << std::endl; std::cout << ToKMG(it.second.InBytes) << "/s" << std::endl; std::cout << ToKMG(it.second.OutBytes) << "/s" << std::endl; } for (auto it : m_procStatSpeedList) { std::cout << it.first << std::endl; std::cout << ToKMG(it.second.InBytes) << "/s" << std::endl; std::cout << ToKMG(it.second.OutBytes) << "/s" << std::endl; } } private: BOOL GetNetworkProcessStat(std::unordered_map<DWORD, InOutBytes> & procStatList) { DWORD dwRet = 0; PBYTE pTcpTable = NULL; DWORD dwTcpTableSize = 0; PMIB_TCPTABLE_OWNER_PID pTcpTableIterator = NULL; PMIB_TCPROW_OWNER_PID pTcpRow = NULL; PTCP_ESTATS_DATA_ROD_v0 dataRod = { 0 }; dwRet = GetExtendedTcpTable((PMIB_TCPTABLE_OWNER_PID)pTcpTable, &dwTcpTableSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); if (dwRet == ERROR_INSUFFICIENT_BUFFER) { pTcpTable = new BYTE[dwTcpTableSize]; if (pTcpTable == NULL) { printf("Error allocating memory\n"); return FALSE; } } dwRet = GetExtendedTcpTable((PMIB_TCPTABLE_OWNER_PID)pTcpTable, &dwTcpTableSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); if (dwRet == ERROR_SUCCESS) { pTcpTableIterator = (PMIB_TCPTABLE_OWNER_PID)pTcpTable; for (DWORD i = 0; i < (int)pTcpTableIterator->dwNumEntries; i++) { pTcpRow = &pTcpTableIterator->table[i]; if (pTcpRow->dwState == MIB_TCP_STATE_ESTAB) { TCP_ESTATS_DATA_ROD_v0 rod = { 0 }; dwRet = GetPerTcpConnectionEStats((PMIB_TCPROW)pTcpRow, TcpConnectionEstatsData, NULL, 0, 0, NULL, 0, 0, (PUCHAR)&rod, 0, sizeof(rod)); if (dwRet == ERROR_SUCCESS) { auto it = procStatList.find(pTcpRow->dwOwningPid); if (it == procStatList.end()) { InOutBytes inOutBytes = {}; inOutBytes.InBytes += rod.DataBytesIn; inOutBytes.OutBytes += rod.DataBytesOut; procStatList.emplace(pTcpRow->dwOwningPid, inOutBytes); } else { it->second.InBytes += rod.DataBytesIn; it->second.OutBytes += rod.DataBytesOut; } } } } } if (pTcpTable != NULL) { delete[]pTcpTable; pTcpTable = NULL; } return TRUE; } BOOL GetTotalIpStatistics(InOutBytes& totalBytes) { ULONG dwRet = 0; PBYTE pIfTable = NULL; PMIB_IFTABLE pIfTableIterator = NULL; ULONG ulIfTableSize = 0; dwRet = GetIfTable(NULL, &ulIfTableSize, FALSE); if (dwRet == ERROR_INSUFFICIENT_BUFFER) { pIfTable = new BYTE[ulIfTableSize]; if (pIfTable == NULL) { printf("Error allocating memory\n"); return 1; } } dwRet = GetIfTable((PMIB_IFTABLE)pIfTable, &ulIfTableSize, FALSE); if (dwRet == ERROR_SUCCESS) { pIfTableIterator = (PMIB_IFTABLE)pIfTable; for (DWORD i = 0; i < pIfTableIterator->dwNumEntries; i++) { PMIB_IFROW pIfRow = &pIfTableIterator->table[i]; if (pIfRow->dwType <= IF_TYPE_PPP) { totalBytes.InBytes += pIfRow->dwInOctets;// *8; totalBytes.OutBytes += pIfRow->dwOutOctets;// *8; } } } delete[]pIfTable; return TRUE; } };
收藏的用户(0)
X
正在加载信息~
2
最新回复 (0)