Files
GdCpp12/source/IpHelper.cpp

203 lines
6.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "pch.h"
#include "IpHelper.h"
#include <IPTypes.h>
#include <IPHlpApi.h>
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment (lib,"ws2_32.lib") //加载 ws2_32.dll
std::vector<std::wstring> CAdapterList::gExcludedList;
//枚举网卡列表
//void CAdapterList::Enum(bool excludelist, bool includelocalhost)
//{
// //得到结构体大小
// unsigned long stSize = 0;
// int nRel = GetAdaptersInfo(0, &stSize);
//
// //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
// PIP_ADAPTER_INFO allIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
// // 指向第一条
// PIP_ADAPTER_INFO pIpAdapterInfo = allIpAdapterInfo;
//
// nRel = GetAdaptersInfo(allIpAdapterInfo, &stSize);
//
// if (ERROR_SUCCESS == nRel)
// {
// //输出网卡信息
// //可能有多网卡,因此通过循环去判断
// while (pIpAdapterInfo)
// {
// sAdapter s(pIpAdapterInfo->AdapterName, pIpAdapterInfo->Description);
// bool skip = false;
// if(excludelist) {
// for (auto& e : Excluded) {
// if (s.Description._Starts_with(e)) {
// skip = true;
// break;
// }
// }
// }
//
// if (!skip) {
// d.push_back(s);
// auto last = d.rbegin();
// //可能网卡有多IP,因此通过循环去判断
// IP_ADDR_STRING* pIpAddrString = &(pIpAdapterInfo->IpAddressList);
// do
// {
// last->IpAddr.push_back({ pIpAddrString->IpAddress.String, pIpAddrString->IpMask.String });
// pIpAddrString = pIpAddrString->Next;
// } while (pIpAddrString);
//
// }
// pIpAdapterInfo = pIpAdapterInfo->Next;
// }
// }
// if (includelocalhost) {
// d.push_back({ "", "localhost" });
// auto last = d.rbegin();
// last->IpAddr.push_back({ "127.0.0.1", "255.255.255.0" });
// }
//
//
// //释放内存空间
//
// delete[] allIpAdapterInfo;
//}
void CAdapterList::Enum(uint32_t exclude_flag)
{
d.clear();
std::vector<std::wstring> localExcluedList;
if(exclude_flag) _SetExcludedList(localExcluedList, exclude_flag);
DWORD dwRetVal = 0;
LPVOID lpMsgBuf = NULL;
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
ULONG outBufLen = 16384; // Allocate a 16 KB buffer to start with不够可以递增
ULONG Iterations = 0; // 递增次数
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (pAddresses == NULL) {
//printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
return;
}
/* Set to AF_INET to specify the IPv4 address family */
// 不要返回 IPv6 任何广播地址。不要返回多播地址。
dwRetVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
free(pAddresses);
pAddresses = NULL;
Iterations++;
outBufLen += 16384;//增加缓冲区
}else {
break;
}
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < 3));
if (dwRetVal == NO_ERROR) {
pCurrAddresses = pAddresses;
while (pCurrAddresses) {
pUnicast = pCurrAddresses->FirstUnicastAddress;
if (pUnicast != NULL) {
bool skip = false;
std::wstring desc(pCurrAddresses->Description);
// 比对全局排除列表
for (auto& e : gExcludedList) {
if (desc._Starts_with(e)) { skip = true; break; }
}
// 比对标志位添加的排除列表
if (!skip && exclude_flag) {
for (auto& e : localExcluedList) {
if (desc._Starts_with(e)) { skip = true; break; }
}
}
if (!skip) {
sAdapter s;
s.Description = pCurrAddresses->Description;
s.FriendlyName = pCurrAddresses->FriendlyName;
s.OperStatus = pCurrAddresses->OperStatus;
//printf("%d, %S\n", s.OperStatus, pCurrAddresses->FriendlyName);
while (pUnicast != NULL) {
if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) {//限制IPV4
ipv4addr addr(pUnicast->Address.lpSockaddr);
// 保留最后一个ip
// 如果网卡设置了固定IP但未连接会出现两个ip第一个是169.254.x.x第2个才是设置的ip
s.IpAddr=addr;
//printf("\tIPv4 Address: %s\n", addr.ipStr().c_str());
}
pUnicast = pUnicast->Next;
}
d.push_back(s);
}
}
else {
//printf("\tNo unicast addresses found for this adapter\n");
}
pCurrAddresses = pCurrAddresses->Next;
}
}
//else {
// printf("Call to GetAdaptersAddresses failed with error: %d\n", dwRetVal);
// if (dwRetVal == ERROR_NO_DATA) {
// printf("\tNo addresses were found for the requested parameters\n");
// }
// else {
// if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
// FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
// NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// // Default language
// (char*)&lpMsgBuf, 0, NULL)) {
// printf("\tError: %s", (char*)lpMsgBuf);
// LocalFree(lpMsgBuf);
// }
// }
//}
if (pAddresses) {
free(pAddresses);
}
}
// 要求已经执行过WSAStartup(MAKEWORD(2, 2), &wsaData);
int getIPFromHostname(const char* hostname, std::vector<ipv4addr>& foundIp)
{
struct addrinfo* result_list = NULL;
struct addrinfo hints = {};
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM;
int result = getaddrinfo(hostname, nullptr, &hints, &result_list);
if (result != 0) {
//std::cerr << "getaddrinfo failed: " << gai_strerror(result) << std::endl;
//WSACleanup();
return -1;
}
for (struct addrinfo* res = result_list; res != NULL; res = res->ai_next) {
struct sockaddr_in* ip4 = (struct sockaddr_in*)res->ai_addr;
ipv4addr addr(ip4);
foundIp.push_back(addr);
}
freeaddrinfo(result_list);
return int(foundIp.size());
}