相关文章: 使用winsock2
说明
监控网卡可以使用 NotifyRouteChange
和 NotifyRouteChange2
函数,通过注册回调实现路由监控
主要步骤
- 声明一个回调函数处理通知
- 调用notifyRouteChange2注册通知,指定通知类型
- 等待通知
- 取消通知(可选)
- 在回调函数中根据通知类型进行处理
代码
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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream> #include<iomanip> #include<string> #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "ws2_32.lib")
using namespace std;
#define NAMEPRINTFORMAT(X) std::left << setw(60)<< #X << "\t\t" << X
std::string ipToString(DWORD dwIP) { std::string strDestIp = ""; std::string strMaskIp = "";
struct in_addr network; network.S_un.S_addr = dwIP; strDestIp = inet_ntoa(network);
return strDestIp; }
void CALLBACK RouteChanged1(void* CallerContext, PMIB_IPFORWARD_ROW2 Table, MIB_NOTIFICATION_TYPE NotificationType) { using context = void(*)(DWORD);
context ctx = (context)CallerContext;
auto PrintTable = [](MIB_IPFORWARD_ROW2 table) { cout << "---------------" << endl; cout << NAMEPRINTFORMAT(table.InterfaceLuid.Info.IfType) << endl;
cout << NAMEPRINTFORMAT(table.InterfaceLuid.Info.NetLuidIndex) << endl; cout << NAMEPRINTFORMAT(table.InterfaceLuid.Info.Reserved) << endl; cout << NAMEPRINTFORMAT(table.InterfaceLuid.Value) << endl;
cout << NAMEPRINTFORMAT(table.InterfaceIndex) << endl;
cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.si_family) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr) << "\t" << ipToString(table.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv4.sin_family) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv4.sin_port) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv4.sin_zero) << endl;
cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Word) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_family) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_flowinfo) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_port) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_scope_id) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_scope_struct.Level) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_scope_struct.Value) << endl; cout << NAMEPRINTFORMAT(table.DestinationPrefix.Prefix.Ipv6.sin6_scope_struct.Zone) << endl;
cout << NAMEPRINTFORMAT(table.NextHop.Ipv4.sin_addr.S_un.S_addr) << "\t" << ipToString(table.NextHop.Ipv4.sin_addr.S_un.S_addr) << endl; cout << NAMEPRINTFORMAT(table.NextHop.Ipv6.sin6_addr.u.Byte) << endl; cout << NAMEPRINTFORMAT(table.NextHop.Ipv6.sin6_addr.u.Word) << endl; cout << NAMEPRINTFORMAT(table.SitePrefixLength) << endl; cout << NAMEPRINTFORMAT(table.ValidLifetime) << endl; cout << NAMEPRINTFORMAT(table.PreferredLifetime) << endl; cout << NAMEPRINTFORMAT(table.Metric) << endl; cout << NAMEPRINTFORMAT(table.Protocol) << endl; cout << NAMEPRINTFORMAT(table.Loopback) << endl; cout << NAMEPRINTFORMAT(table.AutoconfigureAddress) << endl; cout << NAMEPRINTFORMAT(table.Immortal) << endl; cout << NAMEPRINTFORMAT(table.Age) << endl; cout << NAMEPRINTFORMAT(table.Origin) << endl;
cout << "---------------" << endl << endl; }; switch (NotificationType) { case MibParameterNotification: cout << "1-- 参数被更改" << endl; break; case MibAddInstance: cout << "2-- 添加" << endl; PrintTable(*Table);
ctx(Table->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr); break; case MibDeleteInstance: cout << "3-- 删除" << endl; PrintTable(*Table);
ctx(Table->DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr); break; case MibInitialNotification: cout << "4-- 函数已注册" << endl; break;
default: break; } }
void checkIsMyRoute (DWORD ip) { cout << NAMEPRINTFORMAT(ipToString(ip)) << endl; };
void main() { HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); HANDLE hNotify = NULL; PVOID callerContext = static_cast<PVOID>(&checkIsMyRoute); BOOLEAN bSuccess = TRUE; ULONG pdwPrevNotified = 0;
if (callerContext != nullptr && NotifyRouteChange2(AF_UNSPEC, &RouteChanged1, callerContext, bSuccess, &hNotify) != NO_ERROR) { printf("Could not register for route change notifications\n"); return ; }
while (TRUE) { DWORD dwWait = WaitForSingleObject(hNotify, INFINITE); if (dwWait == WAIT_OBJECT_0) { break; } }
CancelMibChangeNotify2(hNotify); CloseHandle(hNotify);
return ; }
|