获取网卡上的IP、网关及DNS信息,获取最佳路由,遍历路由表中的条目(附源码)

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html       我们可以通过调用系统API函数去获取机器上所有网卡的信息,可以获取到网卡上配置的IP、网关及DNS等信息。调用系统API可以获取最佳路由网卡,可以遍历系统路由表中的条目,可以看到默认路由和添加的策略路由。

1、获取系统中所有网卡的信息

      主要是通过调用系统API函数GetAdaptersInfo来获取网卡上配置的IP、网关、DNS等信息,相关代码如下:

// 获取所有网卡信息
void  GetNetAdaptersInfo
{// IP路由表ULONG               ulOutBufLen     = NULL;PMIB_IPFORWARDTABLE pIpForwardTable = NULL;GetIpForwardTable( pIpForwardTable, &ulOutBufLen, TRUE );pIpForwardTable = (PMIB_IPFORWARDTABLE)malloc( ulOutBufLen );if ( NULL != pIpForwardTable ){// 找到最佳路由,读出对应的IP索引if ( NO_ERROR == GetIpForwardTable( pIpForwardTable, &ulOutBufLen, FALSE ) ){}}DWORD dwRetVal = 0;PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );unsigned long ulOutBufLen = sizeof(IP_ADAPTER_INFO);// 试探以下buffer长度够不够if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS) {free(pAdapterInfo);pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);}PIP_ADAPTER_INFO pAdapter = NULL;if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {int nIndex = 0;pAdapter = pAdapterInfo;while (pAdapter != NULL ) {// 1、读出网卡名称CString szAdapter;szAdapter.Format( _T("第%d块网卡:"), nIndex + 1);szAdapter += pAdapter->Description;// 2、网卡上所有IP信息IP_ADDR_STRING *pIPStr = &(pAdapter->IpAddressList);for(  ; pIPStr != NULL;  ){szAdapter += _T("\r\n");s8* byIpAddr = pIPStr->IpAddress.String;szAdapter += _T("IP: ");szAdapter += byIpAddr;szAdapter += _T("  ");szAdapter += STRING_MASK;s8 *byMaskAddr = pIPStr->IpMask.String;szAdapter += byMaskAddr;// 寻找IP对应的跳数for ( u32 dw = 0; dw < pIpForwardTable->dwNumEntries; dw++ ) {CString szRoute;IN_ADDR inDest;inDest.S_un.S_addr = pIpForwardTable->table[dw].dwForwardDest;if ( inet_ntoa( ntohl(inDest.S_un.S_addr) ) == (CString)byIpAddr ){        CString szMetric;szMetric = _T("  ");CString strTemp;strTemp.Format( _T("跳数:"), pIpForwardTable->table[dw].dwForwardMetric1 );szMetric += strTemp;szAdapter += szMetric;}}pIPStr = pIPStr->Next;}// 3、网卡上的网关信息IP_ADDR_STRING *pGatewayStr = &(pAdapter->GatewayList);for( ; pGatewayStr != NULL; ){szAdapter +=_T( " " );s8* byGwAddr = pGatewayStr->IpAddress.String;szAdapter += STRING_GATEWAY;szAdapter += byGwAddr;pGatewayStr = pGatewayStr->Next;}// 4、网卡上的DNS信息:TCHAR achDnsInfo[MAX_PATH] = {0};CString szSubKey = _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");szSubKey += CopyUtf8ToCStringT( pAdapter->AdapterName );HKEY    hKey = NULL;LONG lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, (LPCTSTR)szSubKey,0, KEY_READ, &hKey );if ( lRet == ERROR_SUCCESS ){DWORD dwSize = MAX_PATH;DWORD dwType = REG_SZ;lRet = RegQueryValueEx( hKey, _T("NameServer"), NULL, &dwType,(LPBYTE)achDnsInfo, &dwSize );CString szDns;CString strDnsInfo = achDnsInfo;if ( _tcscmp( strDnsInfo, _T("") ) != 0 ){szDns.Format( _T("DNS服务器: %s"), strDnsInfo ); }szAdapter += szDns;RegCloseKey( hKey );			}pAdapter = pAdapter->Next;}}if ( pIpForwardTable != NULL ){free( pIpForwardTable );}if ( pAdapterInfo != NULL ){free( pAdapterInfo );}
}

 2、获取最佳路由网卡

       调用系统API函数GetBestInterface,传入要访问的目标IP,如下所示:

// 获取最佳路由对应的网卡索引号
DWORD dwResult = GetBestInterface(inet_addr(pDestIp), &dwBestIndex);

GetBestInterface函数返回后,返回的dwBestIndex值,就是最佳路由网卡的序号。

       获取最佳路由网卡,一般是用在多网卡的机器上,比如一张是连外网的网卡,一张是连局域网的网卡。在Windows系统中,不管插有多少张网卡,只能设置一个默认网关,即只能在一个网卡上设置网关,其他网卡不能设置网关。没设置网关的,可以通过添加策略路由去解决路由问题。

       有一点需要注意的是,系统选择的最佳路由可能是有问题的,比如我访问一个内网的地址,结果系统选择走外网的网卡,这就需要我们人为地去干预了。

3、遍历系统路由表,获取最佳路由

      在Windows系统中,可以在cmd中输入route print命令查看系统的路由表,如下所示:

我们可以通过调用系统API函数GetIpForwardTable去遍历路由表中的条目。比如如下的代码,代码中通过访问的目标地址,到路由表中找一个对应的路由:

// 传入要访问的目标IP,在路由表条目中找到最佳路由
BOOL FindBestRouteEntry( DWORD dwDestIp)
{PMIB_IPFORWARDTABLE pIpForwardTable = NULL;DWORD dwActualSize = 0;DWORD dwRst = NO_ERROR;// 获取系统路由表dwRst = ::GetIpForwardTable( pIpForwardTable, &dwActualSize, TRUE );if( NO_ERROR !=  dwRst){if ( ERROR_INSUFFICIENT_BUFFER == dwRst){pIpForwardTable = (PMIB_IPFORWARDTABLE)malloc(dwActualSize);if (NO_ERROR != GetIpForwardTable( pIpForwardTable, &dwActualSize, TRUE)){free(pIpForwardTable);return FALSE;}}else{return FALSE;}} else{assert(FALSE);}// 遍历系统路由表条目,根据目标地址确定使用哪条路由,然后获取该条路由// 对应的网关for(DWORD i = 0; i < pIpForwardTable->dwNumEntries; i++){DWORD dwForwardDest = pIpForwardTable->table[i].dwForwardDest;DWORD dwForwardMask = pIpForwardTable->table[i].dwForwardMask;DWORD dwForwardNextHop = pIpForwardTable->table[i].dwForwardNextHop;// 将0.0.0.0这条默认路由过滤掉if ( 0 == dwForwardMask ){continue;}// 判断目标IP地址与路由条目中的IP和子网掩码是否在同一子网中// 在一个子网中,则使用该路由条目if ( ( dwForwardDest & dwForwardMask ) == ( dwDestIp & dwForwardMask ) ) {dwDefaultGate = dwForwardNextHop;free(pIpForwardTable);return TRUE;}}free(pIpForwardTable);return FALSE;
}

对于人为添加的策略路由,也大概是通过上述代码的方法找到对应的策略路由的。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147719.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

flutter开发实战-应用更新apk下载、安装apk、启动应用实现

flutter开发实战-应用更新apk下载、安装apk、启动应用实现 在开发过程中&#xff0c;经常遇到需要更新下载新版本的apk文件&#xff0c;之后进行应用更新apk下载、安装apk、启动应用。我们在flutter工程中实现下载apk&#xff0c;判断当前版本与需要更新安装的版本进行比对判断…

【强化算法专题一】双指针算法

【强化算法专题一】双指针算法 1.双指针算法--移动零2.双指针算法--复写零3.双指针算法--快乐数4.双指针算法--盛水最多的容器5.双指针算法--有效三角形的个数6.双指针算法--和为s的两个数7.双指针算法--三数之和8.双指针算法--四数之和 1.双指针算法–移动零 算法原理解析----…

普通人需要做副业吗?有什么合适的副业

普通人现在需要做副业吗&#xff0c;我觉得有这个必要&#xff0c;当然也要根据个人情况选择&#xff0c;那么做副业有什么好处呢&#xff1f;做副业可以带来额外的收入&#xff0c;增加灵活性&#xff0c;提升技能&#xff0c;发展创造力&#xff0c;降低风险&#xff0c;提供…

计算机竞赛 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

【高强度聚焦超声模拟器】模拟分层介质中的高强度聚焦超声波束和加热效应(Matlab代码)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

实体行业数字化转型怎么做?线上线下相结合的新零售体系怎么做?

如今&#xff0c;实体行业想要取得收入增长&#xff0c;只做线下业务或者只做线上业务&#xff0c;在当前的市场环境中是难以长久生存的&#xff0c;因此一定要线上线下相结合&#xff0c;将流量运作与线下转化进行充分结合&#xff0c;才能更好地发挥实体优势&#xff0c;带来…

Java后端模拟面试,题集①

1.Spring bean的生命周期 实例化 Instantiation属性赋值 Populate初始化 Initialization销毁 Destruction 2.Spring AOP的创建在bean的哪个时期进行的 &#xff08;图片转载自Spring Bean的完整生命周期&#xff08;带流程图&#xff0c;好记&#xff09;&#xff09; 3.MQ如…

毛玻璃用户卡交互

效果展示 页面结构组成 从效果展示可以看到&#xff0c;此效果都是比较常规的。主要的核心就是卡片的悬停效果。 CSS 知识点 backdrop-filter 回顾transitiontransform 页面基础布局实现 <section><div class"container"><div class"card&q…

第8期ThreadX视频教程:应用实战,将裸机工程移植到RTOS的任务划分,驱动和应用层交互,中断DMA,C库和中间件处理等注意事项

视频教程汇总帖&#xff1a;【学以致用&#xff0c;授人以渔】2023视频教程汇总&#xff0c;DSP第12期&#xff0c;ThreadX第8期&#xff0c;BSP驱动第26期&#xff0c;USB实战第5期&#xff0c;GUI实战第3期&#xff08;2023-10-01&#xff09; - STM32F429 - 硬汉嵌入式论坛 …

【springboot3.x 记录】关于spring-cloud-gateway引入openfeign导致的循环依赖问题

最近升级springboot3真是一挖一个坑&#xff0c;又给我发现了 spring-cloud-gateway 引入 openfeign 会导致循环依赖异常&#xff0c;特此记录一下这个坑 一、发现问题 网关里面有一个全局的过滤器&#xff0c;因为要查询一些配置信息&#xff0c;目前是通过 feign client 的方…

掌机小霸王,开源俄罗斯方块小游戏

俄罗斯方块试玩gi PC或手机 点开即玩: https://chvin.github.io/react-tetris/?lanzh-cn 也可以扫码开玩: 实现了数据的持久化 游戏进度的数据可以持久存储到本地浏览器, 即使刷新网页也无需重新开始游戏 小结: 俄罗斯方块属于超级经典的游戏, 感兴趣可以玩一下, 找回一点童…

【初识Linux】上

初识Linux上 一、Linux背景1.1 UNIX发展的历史1.2 UNIX发展的历史 二、开源三、官网Linux官网 四、企业应用现状五、发行版本六、 os概念&#xff0c;定位 本博客简介 初始Linux操作系统初识shell命令 ,了解若干背景知识。使用常用Linux命令了解Linux权限概念与思想,能深度理解…

AMD GPU 内核驱动分析(三)-dma-fence 同步工作模型

在Linux Kernel 的AMDGPU驱动实现中&#xff0c;dma-fence扮演着重要角色&#xff0c;AMDGPU的Render/解码操作可能涉及到多个方面同时引用buffer的情况&#xff0c;以渲染/视频解码场景为例&#xff0c;应用将渲染/解码命令写入和GPU共享的BUFFER之后&#xff0c;需要将任务提…

海外媒体发稿:商务视频推广销售利器之完全指南

在当今数字化时代&#xff0c;商务视频推广已经成为了企业获取市场份额和提升销售业绩的重要手段。视频作为一种视听媒体&#xff0c;拥有更强大的感染力和传达信息的能力&#xff0c;因此在各种销售场景中得到了广泛应用。本文为大家提供了一份完全指南&#xff0c;帮助你了解…

代码随想录Day9 栈与队列 LeetCodeT20 有效的括号 T1047 删除字符串中所有相邻重复项 T150 逆波兰表达式求值

题目详细思路和解法来自于:代码随想录 (programmercarl.com) LeetCode T20 有效的括号 题目思路 这道题分为三种情况 1.左括号多了 ([{}]() 2.括号不匹配 [{(]}] 3.右括号多了 []{}()))) 处理思路:我们在遇到左括号的时候,直接入栈其对应的右括号即可…

【Java】微服务——微服务介绍和Eureka注册中心

目录 1.微服务介绍2.服务拆分和远程调用2.1.提供者与消费者 3.Eureka注册中心3.1.Eureka的结构和作用3.2.Eureka的结构3.3.搭建Eureka服务3.3.1.引入eureka依赖3.3.2.编写配置文件 3.4.服务注册及拉1&#xff09;引入依赖2&#xff09;配置文件3&#xff09;启动多个user-servi…

UE5.1编辑器拓展【二、脚本化资产行为,快速更改资产名字,1.直接添加前缀或后缀2.通过资产类判断添加修改前缀】

目录 了解相关的函数 第一种做法&#xff1a;自定义添加选择资产的前缀或后缀 代码 效果 第二种做法&#xff1a;通过映射来获取资产类型添加前缀和修改前缀 映射代码 代码 效果 在之前一章中&#xff0c;我们创建了插件&#xff0c;用来扩展编辑器的使用&#xff1a; …

【高阶数据结构】哈希(哈希表、哈希桶)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C进阶 ⭐代码仓库&#xff1a;C进阶 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们的支持是我…

微服务技术栈-认识微服务和第一个微服务Demo

文章目录 前言一、认识微服务二、微服务技术栈三、Eureka注册中心四、微服务DEMO1、搭建eureka-server2、服务注册和服务发现 总结 前言 随着业务的不断复杂&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。 本章就从微服…

VD6283TX环境光传感器驱动开发(1)----获取ID

VD6283TX环境光传感器驱动开发----1.获取ID 概述视频教学样品申请源码下载模块参数IIC接线方式设备ID生成STM32CUBEMX串口配置 IIC配置串口重定向模块地址获取ID主函数结果演示 概述 环境光传感器是一种光电探测器&#xff0c;能够将光转换为电压或者电流&#xff0c;使用多光…