16.2 ARP 主机探测技术
ARP (Address Resolution Protocol,地址解析协议),是一种用于将 IP
地址转换为物理地址(MAC地址
)的协议。它在 TCP/IP
协议栈中处于链路层,为了在局域网中能够正确传输数据包而设计,由协议数据单元和对应的操作命令组成。ARP
既可以由操作系统处理,也可以由网卡处理。
该协议的作用是通过一个局域网上的互联网协议(IP)地址来查询对应的物理硬件地址,如数据包发送到路由器时,ARP 协议将使用嵌入在数据包中的目的 IP 地址查找对应的物理地址,路由器根据获取的 MAC 地址转发数据包到下一个网络。
协议工作过程如下:
- 主机A通过查找其ARP缓存表,比对目标的IP地址是否存在于ARP缓存表中。
- 如果目标机器的IP地址不存在于本地ARP缓存表中,则主机A需要进行ARP请求过程,它广播一个ARP请求。
- 当其他主机收到这个请求时,它会比对主机A设置的这个目标IP地址和自己的IP地址是否一致。
- 如果一致的话,说明被查询的这个IP地址正是自己的IP地址,此时这个主机就会直接向主机A发送ARP响应数据包。
- 主机A在获得了目标主机的MAC地址信息之后,会把这个MAC地址信息存储到自己的ARP缓存表中,以便以后再次使用。
ARP主机探测原理是通过发送 ARP 查询报文,来获取目标主机的 MAC 地址,进而获取目标主机的 IP 地址。
主机探测的具体实现步骤如下:
- 构造一个
ARP
查询报文,报文中的目标IP
地址为需要探测的主机IP
地址,源IP
地址为探测主机的IP地址,源MAC
地址为探测主机网卡的MAC
地址。 - 发送
ARP
查询报文。如果目标主机在线,且相应功能正常,它将返回一个ARP
响应报文,其中包含目标主机的MAC
地址。 - 接收到
ARP
响应报文之后,分析报文,从中提取出目标主机的MAC
地址和IP
地址等信息。
在Windows
系统下,我们可以调用SendARP()
函数实现ARP
探测,该函数用于发送ARP
请求到指定的 IP
地址,以获取其 MAC
地址。该函数参数传入目标 IP
地址时能够返回对应 MAC
地址。
SendARP 函数原型如下:
DWORD SendARP(IN IPAddr DestIP, // 目标 IP 地址IN IPAddr SrcIP, // 源 IP 地址(可以为 0)OUT PULONG pMacAddr, // 接收目标 MAC 地址IN OUT PULONG PhyAddrLen // 接收目标 MAC 地址的缓冲区大小,单位为字节
);
该函数的第一个参数为目标IP
地址,第二个参数为本地主机IP
地址(可以填 0),第三个参数为接收返回的目标 MAC
地址的指针,第四个参数为指向缓冲区大小的指针。
当调用 SendARP()
函数时,如果目标 IP
地址是在同一物理网络中,则返回目标 IP
地址对应的 MAC
地址,并且函数返回值为 NO_ERROR
。如果目标 IP
地址无效,或者无法获得对应的 MAC
地址,则函数返回值为错误代码,应该根据错误代码来进行处理。
如下代码实现了扫描局域网中指定ARP
主机地址的功能。代码主要使用了SendARP()
函数来查询目标主机的MAC
地址,并将结果输出。具体实现步骤如下:
#include <stdio.h>
#include <winsock2.h>
#include <IPHlpApi.h>#pragma comment (lib,"ws2_32.lib")
#pragma comment (lib,"iphlpapi.lib")// 扫描局域网中指定ARP主机地址
void ArpScan(char *LocalIP,char *TargetIP)
{ULONG localIP = inet_addr(LocalIP);ULONG targetIP = inet_addr(TargetIP);ULONG macBuf[2] = { 0 };ULONG macLen = 6;DWORD retValue = SendARP(targetIP, localIP, macBuf, &macLen);unsigned char *mac = (unsigned char*)macBuf;printf("IP: %-12s --> MAC: ", TargetIP);for (int x = 0; x < macLen; x++){printf("%.2X", mac[x]);if (x != macLen - 1)printf("-");}printf("\n");
}int main(int argc,char * argv[])
{for (int x = 1; x < 100; x++){char target[32] = { 0 };sprintf(target, "192.168.1.%d", x);ArpScan("192.168.1.2", target);}system("pause");return 0;
}
根据端口探测中所使用的方法,实现多线程也很容易,如下代码实现了使用多线程方式扫描局域网内存活的主机。代码中使用 SendARP()
函数来探测目标主机是否存活,并使用多线程方式来加快扫描速度,同时使用临界区来控制多线程条件下的输出效果。
具体实现过程如下:
-
定义
checkActive()
函数,该函数使用SendARP()
函数来判断目标主机是否存活。如果目标主机存活,则在屏幕上输出其IP
和MAC
地址。 -
定义
threadProc()
函数来作为多线程的回调函数。该函数接收一台主机的IP
地址,并调用checkActive()
函数来探测该主机是否在线。 -
在
main()
函数中,定义开始和结束的IP
地址,并使用for
循环遍历这个IP
地址段。在循环中,使用CreateThread()
函数来创建多个线程,每个线程负责探测其中一台主机是否在线。 -
在
checkActive()
函数中,多线程会涉及到在界面上的输出,为了控制多线程在输出上的次序,使用了EnterCriticalSection()
和LeaveCriticalSection()
函数来表示临界区,只有进入临界区的线程能够打印输出,其他线程需要等待进入临界区。
#include <stdio.h>
#include <winsock2.h>
#include <iphlpapi.h>#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"iphlpapi.lib")// 临界区,控制多线程打印顺序
CRITICAL_SECTION g_critical;bool checkActive(in_addr ip)
{ULONG dstMac[2] = { 0 };memset(dstMac, 0xff, sizeof(dstMac));ULONG size = 6;HRESULT re = SendARP(ip.S_un.S_addr, 0, dstMac, &size);if (re == NO_ERROR && size == 6){// 线程进入临界区,其他线程不能再进入,控制多线程在界面上的打印顺序EnterCriticalSection(&g_critical);printf("[+] 发现存活主机: %-15s ---> MAC :", inet_ntoa(ip));BYTE *bPhysAddr = (BYTE *)& dstMac;for (int i = 0; i < (int)size; i++){// 如果是mac地址的最后一段,就输出换行if (i == (size - 1)){printf("%.2X\n", (int)bPhysAddr[i]);}else{// 否则没有到最后一段,依旧输出,但不换行printf("%.2X-", (int)bPhysAddr[i]);}}// 线程离开临界区,其他线程能够继续进入LeaveCriticalSection(&g_critical);return true;}else{return false;}
}// 启动多线程
DWORD WINAPI threadProc(LPVOID lpThreadParameter)
{in_addr ip;ip.S_un.S_addr = (ULONG)lpThreadParameter;checkActive(ip);return 0;
}int main(int argc, char *argv[])
{in_addr ip_start, ip_end;// 定义开始IPip_start.S_un.S_addr = inet_addr("192.168.9.1");// 定义结束IPip_end.S_un.S_addr = inet_addr("192.168.9.254");// 循环探测主机//初始临界区InitializeCriticalSection(&g_critical);for (in_addr ip = ip_start; ip.S_un.S_addr < ip_end.S_un.S_addr; ip.S_un.S_un_b.s_b4++){printf("探测: %s \r", inet_ntoa(ip));CreateThread(NULL, 0, threadProc, (LPVOID)ip.S_un.S_addr, 0, 0);}system("pause");return 0;
}
编译并运行上述代码片段,则会探测192.168.9.1
到192.168.9.254
网段内存活的主机,并输出该主机的MAC信息,输出效果图如下所示;
本文作者: 王瑞
本文链接: https://www.lyshark.com/post/57dc46.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章:

16.2 ARP 主机探测技术
ARP (Address Resolution Protocol,地址解析协议),是一种用于将 IP 地址转换为物理地址(MAC地址)的协议。它在 TCP/IP 协议栈中处于链路层,为了在局域网中能够正确传输数据包而设计,…...

三级等保-linux服务器三权分立设置
安全问题 安全控制点 风险分析 风险等级 标准要求 加固建议 服务器未严格按照系统管理员权限、审计管理员权限、安全管理员权限进行分配管理员账户,未实现管理员用户的最小权限划分。 访问控制 可能存在管理员越权操作的风险 中 d)应授予管理用户所需的最…...

抓取网页的含义和URL基本构成
抓取网页是指通过爬虫程序从互联网上获取网页的内容和数据。抓取网页是爬虫的核心功能之一,通过抓取网页,可以获取到网页中的文本、图片、链接等信息,用于后续的数据分析、挖掘和应用。 URL(Uniform Resource Locator)…...
计算机毕业设计 机器学习深度学习人工智能
视频参考: 计算机毕业设计项目分享_哔哩哔哩_bilibili 基于深度学习的农业病虫害识别基于SpringBootVue的博客系统基于SpringBootVue的仓库管理系统基于卷积网络的花卉图像识别 毕业设计选题: VX:whbwqq123 基于机器学习的大气数据的污染物pm2.5预测基…...

施密特正交化
相信大家在平时的期末考试中一定少不了对某某向量组执行标准正交化类型的题目。今天我们从这个题目入手,说明这个如何执行施密特正交化,以及为什么要进行正交化。 一、例子 例子:设 a 1 [ 1 2 − 1 ] a_1\begin{bmatrix}1\\2\\-1\end{bmat…...
低代码开发:加速应用开发的利器
目录 一、引言 二、低代码开发的定义和原理 三、低代码开发的关键特性和优势 四、低代码开发的应用场景 五、低代码开发平台的市场现状和发展趋势 六、成功案例分析 七、结论 一、引言 随着信息技术的快速发展,企业对于应用开发的需求也日益增长。传统的应用…...

数据安全发展趋势与密码保护技术研究
随着数据跃升为新型生产要素,数据安全的内涵也从数据本身安全、数据资源安全,发展到数据资产安全三个层面提出了不同的要求,本文就是详细探讨数据安全的这三个层面的安全内容进行分析。 通过对数据安全不同发展阶段的安全需求和保障对象进行研…...
368周赛leetcode
1 2题元素和最小的山形三元组 经典动规 题目内容 给你一个下标从 0 开始的整数数组 nums 。 如果下标三元组 (i, j, k) 满足下述全部条件,则认为它是一个 山形三元组 : i < j < k nums[i] < nums[j] 且 nums[k] < nums[j] 请你找出 num…...
Vue 的 nextTick:深入理解异步更新机制
目录 一、前言 二、Vue.js 异步更新机制简述 三、Vue.nextTick原理 四、nextTick 的应用场景 1. 获取更新后的 DOM 元素 2. 在 DOM 更新后执行自定义的回调函数 3. 解决事件监听器中的更新问题 五、Vue.nextTick与其他异步更新方法的比较 六、总结 一、前言 Vue.js&a…...

SQL关于日期的计算合集
前言 在SQL Server中,时间和日期是常见的数据类型,也是数据处理中重要的一部分。SQL Server提供了许多内置函数,用于处理时间和日期数据类型。这些函数可以帮助我们执行各种常见的任务,例如从日期中提取特定的部分,计…...
shell_44.Linux使用 getopt 命令
使用 getopt 命令 getopt 命令在处理命令行选项和参数时非常方便。它能够识别命令行参数,简化解析过程 1. 命令格式 getopt 命令可以接受一系列任意形式的命令行选项和参数,并自动将其转换成适当的格式。 getopt 的命令格式如下: getopt opt…...

Linux备份Docker的mysql数据并传输到其他服务器保证数据级容灾
目录 简介什么是容灾 ?容灾的分类容灾和备份有什么连系 ? 数据级容灾备份步骤1、scp命令:用于Linux之间复制文件和目录2、编写备份数据库脚本3、crontab定时任务执行脚本4、测试 应用级容灾业务级容灾 简介 为了防止客户系统的数据丢失&…...

【vue+nestjs】qq第三方授权登录【超详细】
项目场景: 前端使用vue3ts 后端使用nestjs 1.申请appId,appKey 1.进入qq互联官网。创建应用 特别注意 1.在填写网站回调域时,需要你线上真实能访问的。不然审核不通过。我的回调地址是前端路由地址 2.如果你想本地调试,回调到你的线上地址。你可以在本…...

经典卷积神经网络 - VGG
使用块的网络 - VGG。 使用多个 3 3 3\times 3 33的要比使用少个 5 5 5\times 5 55的效果要好。 VGG全称是Visual Geometry Group,因为是由Oxford的Visual Geometry Group提出的。AlexNet问世之后,很多学者通过改进AlexNet的网络结构来提高自己的准确…...
系统集成测试(SIT)/系统测试(ST)/用户验收测试(UAT)
文章目录 单元测试集成测试系统测试用户验收测试黑盒测试白盒测试压力测试性能测试容量测试安全测试SIT和UAT的区别 单元测试 英文 unit testing,缩写 UT。测试粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”。 …...
Android Gradle8.0以上多渠道写法以及针对不同渠道导入包的方式,填坑!
目录 多渠道的写法 针对多渠道引用不同的包 There was a failure while populating the build operation queue: Could not stat file E:\xxxx\xxxx\xxxx\app\src\UAT\libsUAT\xxx-provider(?)-xx.aar 最近升级了Gradle8.3之后,从Groovy 迁移到 Kotlinÿ…...

hdlbits系列verilog解答(向量门操作)-14
文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 构建一个具有两个 3 位输入的电路,用于计算两个向量的按位 OR、两个向量的逻辑 OR 以及两个向量的逆 (NOT)。将b反相输出到out_not上半部分,将a 的反相输出到out…...
工厂模式(初学)
工厂模式 1、简单工厂模式 是一种创建型设计模式,旨在通过一个工厂类(简单工厂)来封装对象的实例化过程 运算类 public class Operation { //这个是父类private double num1; //运算器中的两个值private double num2;public double getNu…...
python试题实例
背景: 在外地出差,突然接到单位电话,让自己出一些python考题供新人教育训练使用,以下是10道Python编程试题及其答案: 1.试题:请写一个Python程序,计算并输出1到100之间所有偶数的和。 答案&am…...
Java Heap Space问题解析与解决方案(InsCode AI 创作助手)
Heap Space问题是Java开发中常见的内存溢出问题之一,我们需要理解其原因和表现形式,然后通过优化代码、增加JVM内存和使用垃圾回收机制等方法来解决。 一、常见报错 java.lang.OutOfMemoryError: Java heap space二、Heap Space问题的原因 对象创建过…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...