【Windows】 监控路由事件

2023-11-15

说明

监控网卡可以使用 NotifyRouteChangeNotifyRouteChange2 函数,通过注册回调实现路由监控

主要步骤

  1. 声明一个回调函数处理通知
  2. 调用notifyRouteChange2注册通知,指定通知类型
  3. 等待通知
  4. 取消通知(可选)
  5. 在回调函数中根据通知类型进行处理

代码

#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;    //为s_addr赋值--网络字节序
	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 ;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Windows】 监控路由事件 的相关文章

随机推荐

  • Git — husky + eslint 实现代码提交检测

    一 配置ESlint 1 1 安装eslint npm install eslint D 1 2 初始化eslint 生成配置文件 npx eslint init 1 3 在编辑器安装ESlint插件 1 4 通过执行命令检测文件代码规范
  • 要隐藏高德地图的线外面的区域

    要隐藏高德地图的线外面的区域 可以通过设置地图的 mask 属性来实现 下面是具体的步骤 获取需要隐藏的区域的边界坐标点集合 这些坐标点必须按照顺时针或逆时针方向排序 这样才能正确地关闭区域 推荐使用高德官方提供的在线地图工具获取坐标点 创
  • 栈.栈STL

    栈 是后进先出的数据结构 它叫做栈 栈限定为只能在一端进行插入和删除操作 栈的实现只需要一个一维数组和一个指向栈顶的变量top就可以了 我们通过top来对栈进行插入和删除操作 栈的使用 1 判定回文串 利用栈实现判断字符串是不是回文串 栈用
  • 腾讯 T10级 Jetpack 学习思维导图意外流出,还不赶紧过来围观?

    引言 2018年 Google 官方推出一个全新的开发组件工具库 Jetpack 并将2017年所推出的一个架构组件库 Architecture Components 作为 Jetpack 的一部分纳入其中 当然 Jetpack 并没有就此
  • spark程序运行异常:java.lang.OutOfMemoryError: GC overhead limit exceeded

    此次异常是在集群上运行的spark程序日志中发现的 由于这个异常导致sparkcontext被终止 以致于任务失败 出现的一些原因 参考 GC overhead limit exceeded java lang OutOfMemoryErr
  • Edittext出现两个光标且位置不一致

    问题发生 近期的UI调整中发现在对Edittext设置居中过后 点击存在内容的ET会出现两个光标且不一致 解决方案 设置控件为单行
  • 什么是BI分析系统

    BI分析系统是一种用于帮助企业进行数据分析和决策的工具 它通过收集 整理 分析和可视化庞大的数据集 帮助企业了解自身的业务状况 并提供有关未来预测和战略决策的有价值信息 BI分析系统以其强大的功能和灵活性 在企业管理和决策中发挥着重要的作用
  • P5744 【深基7.习9】培训

    include
  • 详解目标检测Faster R-CNN

    目标检测的一般结构 背景 R CNN 是 Faster R CNN 的启发版本 R CNN 是采用 Selective Search算法来提取 propose 可能的 RoIs regions of interest 区域 然后对每个提取区
  • IC验证常见问题 地图

    SV SystemVerilog和Verilog中的表达式位宽 https blog csdn net m0 46345246 article details 121758747 dist 权重 https www cnblogs com
  • flutter -- 创建一个新的应用

    VS Code 启动 VS Code 调用 View gt Command Palette shift command P 输入 flutter 然后选择 Flutter New Module Project action 指定放置项目的位
  • PyCharm 装 cv2(openCV)

    首先在下面这个网址找对应的openCV版本 cp后就是python版本号 cp39是python3 9 Python Extension Packages for Windows Christoph Gohlke uci edu https
  • 如何成长为一名机器学习工程师

    如何成长为一名机器学习工程师 经常有人这么问 而这篇文章就尝试回答这个问题 其中会谈到关于机器学习的方方面面 从简单的线性回归到最新的神经网络 你不仅将学习如何使用这些技术 还将学习如何从头开始构建它们 这个指南主要面向计算机视觉 CV 这
  • 人工智能概论--第三次作业(三分类模型)

    1 建立数据集 三组数据 2 建立神经网络 3 训练网络 4 可视化训练过程 5 训练结果
  • 【漏洞复现】CVE-2022-46169 Cacti命令执行

    开启环境 查看端口号 登录ip 8080 发现网页报错如下 FATAL Connection to Cacti database failed Please ensure the PHP MySQL module is installed
  • Spring框架中bean的生命周期(理解)

    1 解释Spring框架中bean的生命周期 在传统的Java应用中 bean的生命周期很简单 使用Java关键字new进行bean实例化 然后该bean就可以使用了 一旦该bean不再被使用 则由Java自动进行垃圾回收 相比之下 Spr
  • 2023最全最新前端面试题(附加解答)

    JS 1 说一下innerHTML 与 innerText的作用与区别 作用 都可以获取或者设置元素的内容 区别 innerHTML可以解析内容中的html标签 innerText不能解析内容中的html标签 2 JavaScript 由以
  • FastAPI学习(一)——介绍+并发测试结果+正确打开方式(Python Web框架--异步、高并发、后台)

    最近发现一个很nice的python web框架 官方介绍是 FastAPI是一种现代 快速 高性能 的Web框架 用于基于标准 Python类型提示使用Python 3 6 构建API 主要功能是 官方内容 快速 非常高的性能 看齐的No
  • 修改图像RGB颜色

    每个图片都是由多个像素块组成 每个像素块颜色是rgb形式 修改RGB即可改变颜色 调整相关数字 便可以得到深浅不一的各种颜色 某种颜色的RGB值越接近 这种颜色就越接近灰色或黑白 数值越大就越白 反之越黑 比如RGB 150 152 183
  • 【Windows】 监控路由事件

    说明 监控网卡可以使用 NotifyRouteChange 和 NotifyRouteChange2 函数 通过注册回调实现路由监控 主要步骤 声明一个回调函数处理通知 调用notifyRouteChange2注册通知 指定通知类型 等待通