-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrwutil.cpp
94 lines (85 loc) · 2.72 KB
/
rwutil.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "rwutil.h"
#include <pcap.h>
#include <unordered_set>
#include <IPTypes.h>
#include <iphlpapi.h>
std::string unicode_to_str(wchar_t* unistr) {
char buf[100];
int res = WideCharToMultiByte(CP_ACP, 0, unistr, wcslen(unistr), buf, 100, NULL, NULL);
return res > 0 ? std::string(buf, res) : std::string();
}
std::vector<iface_info> find_ifaces() {
int i = 0;
pcap_if_t* alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
/* Retrieve the device list */
// 遍历所有接口
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
// 存储findalldevs返回的接口信息
std::unordered_set<std::string> pcap_ifaces;
for (pcap_if_t* d = alldevs; d; d = d->next) {
pcap_ifaces.insert(d->name);
//printf("%s\n", d->name);
}
//释放所有接口
pcap_freealldevs(alldevs);
ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_ALL_INTERFACES;
ULONG size = 10 * 1024;
std::vector<uint8_t> buf(size);
//获取所有的接口的地址信息
ULONG res = GetAdaptersAddresses(AF_INET, flags, nullptr, (IP_ADAPTER_ADDRESSES*)&buf[0], &size);
if (res == ERROR_BUFFER_OVERFLOW) {
buf.resize(size);
res = GetAdaptersAddresses(AF_INET, flags, nullptr, (IP_ADAPTER_ADDRESSES*)&buf[0], &size);
}
if (res != ERROR_SUCCESS) {
fprintf(stderr, "Can't get list of adapters: %d\n", res);
exit(1);
}
//返回结果存储
std::vector<iface_info> ifaces;
//定义指针p来遍历winapi返回的接口信息
IP_ADAPTER_ADDRESSES* p = (IP_ADAPTER_ADDRESSES*)&buf[0];
for (; p; p = p->Next) {
//printf("%s\n", p->AdapterName);
// 如果pcap返回结果中不存在这样的接口
if (pcap_ifaces.count(std::string("\\Device\\NPF_") + p->AdapterName) == 0) {
//printf("count:%s\n", p->AdapterName);
continue;
}
if (p->OperStatus != IfOperStatusUp) {
//printf("up:%s\n", p->AdapterName);
continue;
}
iface_info ii{};
//存储接口索引
ii.ifIndex = p->IfIndex;
//存储接口名(pcap打开接口的第一个参数)
ii.name = std::string("\\Device\\NPF_") + p->AdapterName;
//存储描述信息
ii.description = unicode_to_str(p->Description) + " (" + unicode_to_str(p->FriendlyName) + ")";
//存储mac地址
memcpy(ii.mac, p->PhysicalAddress, 6);
//存储网卡ip地址
if (p->FirstUnicastAddress) {
memcpy(ii.ip, &((sockaddr_in*)p->FirstUnicastAddress->Address.lpSockaddr)->sin_addr, 4);
ii.prefixlen = p->FirstUnicastAddress->OnLinkPrefixLength;
}
//排除IP地址为 0.0.0.0
if (*((uint32_t*)(ii.ip)) == 0)
{
continue;
}
//存储网关地址
if (p->FirstGatewayAddress) {
memcpy(ii.gateway, &((sockaddr_in*)p->FirstGatewayAddress->Address.lpSockaddr)->sin_addr, 4);
}
// 存入本次循环获取到的信息
ifaces.push_back(std::move(ii));
}
return ifaces;
}