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问题的原因 对象创建过…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...
