尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

ARP扫描局域网实战:比ping扫段更靠谱的设备发现方案

发布时间:2026/9/28 2:08:52

资讯中心
01
ARTICLE

ARP扫描局域网实战:比ping扫段更靠谱的设备发现方案

ARP扫描局域网实战:比ping扫段更靠谱的设备发现方案
简介这是一份面向网络管理初学者与运维人员的局域网扫描工具源码基于 Visual C 编写核心功能是快速发现同一网段内所有主机的 IP 与 MAC 地址适用于网络设备盘点、IP 冲突排查、未授权设备识别以及 DHCP 环境下的地址核对等场景。资源包共 15 个文件以 h 头文件与 cpp 源文件为主另含 rc 资源脚本、dsw/dsp 工程文件、ico 图标及 clw 类向导文件整体约 13KB属于轻量级 VC 工程可直接用 Visual Studio 打开编译调试。据描述该工具约 30 秒即可完成一个网段 255 台主机的扫描通过 ARP 或 ICMP 协议获取设备物理地址与逻辑地址的对应关系。目前已有 733 人学习下载读者可借此理解局域网二层通信原理、MAC 地址在数据链路层的作用并掌握基于 C 的网络扫描实现思路与工程组织方式。1. ScanLan 扫局域网为什么 ARP 表比 ping 扫段更靠谱很多人第一次写局域网设备发现第一反应是写个 for 循环把 192.168.1.1 到 192.168.1.254 全 ping 一遍能通的就是活着的机器。这个思路在十台设备的小网络里能跑一旦网段里塞了三四十台机器、还混着几台不响应 ICMP 的打印机和摄像头结果就开始玄学了——明明在线的设备扫不出来扫出来的 IP 又对不上 MAC。ScanLan 这类工具的核心不是「发多少包」而是「问谁要答案」它走的是 ARP地址解析协议直接向本网段广播 who-has 询问谁在线谁就得回回包里天然带着 IP 和 MAC 的对应关系。这篇文章讲的就是怎么用 ARP 这套机制把局域网里所有机子的 IP 和 MAC 地址一次性捞出来。适合两类人一类是运维或安全岗需要定期盘点内网资产、排查 IP 冲突和私接设备另一类是嵌入式或工控方向的工程师现场调试时经常要确认某台 PLC、HMI 的网口 MAC 到底是多少。读完你能拿到一套可复现的实现路径、几个必调参数以及我在真实网络里踩过的坑。局域网设备发现这件事工具只是壳底层协议才是那个不会骗你的黑匣子。2. ARP 扫描的底层逻辑与三种实现路线2.1 为什么 ping 扫段会漏设备ARP 不会ping 走的是 ICMP属于网络层。设备可以关掉 ICMP 响应防火墙可以丢弃 ICMP 包但 ARP 不行——ARP 是链路层协议只要设备接在同一个二层网络里、网卡是活的它就必须响应针对自己 IP 的 ARP 请求。这是协议栈的硬性要求不是可选项。所以用 ARP 做发现漏报率远低于 ping 扫段。具体流程是这样的主机 A 想知道 192.168.1.50 的 MAC就往广播地址 FF:FF:FF:FF:FF:FF 发一个 ARP Request内容大意是「谁的 IP 是 192.168.1.50请告诉 192.168.1.1」。网段内所有设备都收到这个广播只有 IP 匹配的那台会单播回一个 ARP Reply里面带着自己的 MAC。ScanLan 做的事就是批量构造这些 Request然后监听回复把 IP-MAC 对收集起来。这里有个关键点ARP 只能发现同一广播域内的设备。跨网段、跨 VLAN 的设备ARP 请求到不了自然扫不到。这不是工具的问题是协议边界。如果你的网络做了 VLAN 划分每个 VLAN 都得单独扫一遍。2.2 三种实现路线raw socket、scapy、系统 ARP 表实现 ARP 扫描有三条路复杂度从高到低可控性也是从高到低。第一条是 raw socket自己构造以太网帧和 ARP 报文。Python 里用socket.AF_PACKETLinux或 WinPcap/NpcapWindows。这条路最灵活能控制发送速率、重试次数、超时时间但代码量大跨平台麻烦。第二条是用 scapy 这类库。scapy 把 ARP 报文封装好了几行代码就能发出去收回来开发效率最高。缺点是依赖 scapy 安装而且默认发送速率偏快在老旧交换机上可能触发广播风暴保护。第三条最省事直接读系统 ARP 表。先 ping 扫一遍网段或者用其他方式触发 ARP然后读arp -a的输出。这条路不需要特殊权限但依赖系统缓存时效性差而且 ping 不通的设备不会进 ARP 表。我一般会选 scapy 路线做原型验证确认逻辑没问题后再根据部署环境决定是否换成 raw socket。下面给出 scapy 的完整实现。2.3 用 scapy 写一个最小可用的 ARP 扫描器先装依赖pip install scapy然后是最核心的扫描脚本from scapy.all import ARP, Ether, srp import ipaddress def scan_lan(network192.168.1.0/24, timeout3, retry2): ARP 扫描局域网返回 IP-MAC 列表 network: 目标网段CIDR 格式 timeout: 每个包的等待超时秒 retry: 重试次数应对丢包 # 构造 ARP 请求问整个网段谁的 MAC 是多少 arp ARP(pdstnetwork) # 以太网帧目的地址是广播 ether Ether(dstff:ff:ff:ff:ff:ff) # 组合成完整包 packet ether / arp # srp 发送并接收二层包verbose0 关闭冗余输出 result srp(packet, timeouttimeout, retryretry, verbose0)[0] devices [] for sent, received in result: devices.append({ ip: received.psrc, mac: received.hwsrc }) return devices if __name__ __main__: devs scan_lan(192.168.1.0/24) print(f发现 {len(devs)} 台设备) for d in sorted(devs, keylambda x: ipaddress.ip_address(x[ip])): print(f{d[ip]:16s} {d[mac]})逻辑说明ARP(pdstnetwork)里的pdst设成整个网段scapy 会自动为网段内每个 IP 生成一个 ARP 请求。Ether(dstff:ff:ff:ff:ff:ff)确保帧以广播方式发出。srp是「send and receive at layer 2」的缩写专门处理二层包返回两个列表第一个是「已发送且收到回复」的包对。参数说明timeout3意味着每个请求等 3 秒网段大时总耗时会线性增长/24 网段大约 3 到 5 秒扫完。retry2是重试次数无线网络或负载高的交换机上建议设 2 到 3有线环境设 1 就够。如果网段是 /16254 个地址变成 65534 个必须分批扫否则内存和广播压力都扛不住。2.4 扫描结果的去重与厂商识别扫出来的原始结果可能有重复——同一台设备可能回多个包或者你重试时它回了两次。去重很简单用 MAC 做 key 就行。但更有价值的是识别厂商MAC 地址的前三个字节是 OUI组织唯一标识符能查出网卡厂商。def dedup_and_vendor(devices): seen {} for d in devices: mac d[mac].upper() if mac not in seen: # OUI 是 MAC 前 3 字节这里只做展示 oui mac[:8] seen[mac] {ip: d[ip], mac: mac, oui: oui} return list(seen.values())OUI 查厂商需要一张映射表完整的 IEEE OUI 库有几十万条本地存一份 CSV 就行。实际排查时看到 OUI 是00:1B:21就知道是 Intel 网卡看到B8:27:EB就知道是树莓派对定位设备类型很有帮助。这一步不是必须的但在资产盘点场景里能省很多事。3. 把扫描器做成能日常用的工具参数、并发与输出3.1 网段大小与超时时间的取舍/24 网段有 254 个可用地址scapy 默认一次性全发出去在千兆有线网络里没问题。但如果是 /16 网段65534 个 ARP 请求同时广播交换机的 CPU 可能直接跑满这就是广播风暴。正确做法是分批def scan_large_network(network, batch_size256, timeout2): net ipaddress.ip_network(network, strictFalse) all_devices [] hosts list(net.hosts()) for i in range(0, len(hosts), batch_size): batch hosts[i:ibatch_size] # 把一批 IP 拼成逗号分隔的字符串 batch_str ,.join(str(ip) for ip in batch) devs scan_lan(batch_str, timeouttimeout) all_devices.extend(devs) return all_devicesbatch_size256是个经验值对应一个 C 类网段的规模。timeout在分批后可以适当降低因为每批设备少丢包概率低2 秒足够。如果网络里有老旧的工业交换机建议把 batch_size 降到 64timeout 提到 3 秒。3.2 多网卡环境下的源地址绑定一台机器有多张网卡时比如同时接了办公网和工控网scapy 默认从路由表选出口可能把包发到错误的网卡上。这时候必须显式指定接口from scapy.all import conf def scan_with_interface(network, iface): # iface 是网卡名Linux 下如 eth0Windows 下如 以太网 arp ARP(pdstnetwork) ether Ether(dstff:ff:ff:ff:ff:ff) packet ether / arp result srp(packet, timeout3, ifaceiface, verbose0)[0] return [{ip: r.psrc, mac: r.hwsrc} for _, r in result]iface参数在 Linux 下填eth0、enp3s0这种名字Windows 下填「以太网」「WLAN」这种显示名。不确定的话用conf.ifaces列出来看。这个坑我在工控现场踩过笔记本同时插了内网口和外网口不指定接口时扫描结果全是外网的设备内网一台都扫不到排查了半天才发现是路由选路的问题。3.3 输出成 CSV 和 JSON方便后续比对扫描结果要能存下来才能做资产比对。CSV 适合人看JSON 适合程序处理import csv import json from datetime import datetime def save_results(devices, prefixscan): ts datetime.now().strftime(%Y%m%d_%H%M%S) # CSV 输出 with open(f{prefix}_{ts}.csv, w, newline) as f: writer csv.DictWriter(f, fieldnames[ip, mac]) writer.writeheader() writer.writerows(devices) # JSON 输出 with open(f{prefix}_{ts}.json, w) as f: json.dump({time: ts, devices: devices}, f, indent2)有了历史记录就能做增量比对今天扫出来的 MAC 列表和昨天比多出来的就是新接入设备少掉的就是离线设备。这个能力在排查私接设备时特别有用——突然冒出一个陌生 MAC基本就是有人偷偷接了东西。3.4 定时扫描与 IP-MAC 变更告警把扫描脚本挂到 cron 或计划任务里每小时跑一次然后比对结果def diff_scan(old_file, new_devices): with open(old_file) as f: old json.load(f)[devices] old_map {d[mac]: d[ip] for d in old} new_map {d[mac]: d[ip] for d in new_devices} added set(new_map) - set(old_map) removed set(old_map) - set(new_map) # MAC 没变但 IP 变了说明 DHCP 重新分配或有人手动改了 changed {m for m in set(old_map) set(new_map) if old_map[m] ! new_map[m]} for m in added: print(f[新增] {new_map[m]} {m}) for m in removed: print(f[离线] {old_map[m]} {m}) for m in changed: print(f[IP变更] {m}: {old_map[m]} - {new_map[m]})changed这个集合最值得关注。MAC 不变但 IP 变了通常是 DHCP 租约到期重新分配但如果同一台设备频繁变 IP可能是 IP 冲突的前兆。反过来IP 不变但 MAC 变了那基本可以确定是有人手动改了 MAC 地址或者设备被替换了。4. 避坑与排查ARP 扫描翻车的五种典型情况4.1 扫出来全是网关的 MAC现象结果里所有 IP 对应的 MAC 都是同一个通常是网关或某台交换机的 MAC。原因网络里开了 ARP 代理proxy ARP或者中间有设备做了 ARP 欺骗/拦截。代理 ARP 会让网关代替其他设备回复 ARP 请求导致所有 IP 都指向网关。解决先确认网络拓扑里有没有三层交换机或防火墙开了代理 ARP。如果是需要登录设备关闭该功能或者换用其他发现方式比如读交换机的 MAC 地址表。如果是 ARP 欺骗那说明网络里已经有问题了得先处理安全事件。4.2 部分设备扫不到但手动 ping 能通现象脚本扫出来 20 台实际网段里有 30 台漏掉的那几台手动 ping 是通的。原因这些设备对 ARP 请求的响应有延迟或者网卡省电模式导致响应慢在 timeout 内没回来。也可能是交换机端口隔离port isolation导致广播包到不了某些端口。解决把 timeout 从 3 秒提到 5 秒retry 从 1 提到 3。如果是端口隔离需要检查交换机配置看是否关闭了端口间的广播转发。无线网络里这个问题更常见因为 AP 可能对广播包做了限速。4.3 Windows 下报权限错误现象脚本在 Linux 下跑得好好的到 Windows 上直接抛PermissionError。原因scapy 在 Windows 下需要 Npcap 驱动才能发原始二层包而且必须以管理员权限运行。解决先装 Npcap安装时勾选「WinPcap API-compatible mode」然后用管理员身份打开命令行再跑脚本。如果还是不行检查 Npcap 是否被安全软件拦截了。这个坑没有捷径Windows 下做二层操作就是需要额外驱动和权限。4.4 扫描导致网络短暂卡顿现象跑扫描脚本时同网段的其他同事反馈网络变慢视频会议卡顿。原因ARP 请求是广播包网段内所有设备都要处理。如果发送速率太快、包太多交换机和终端的 CPU 都会被占用。解决降低发送速率。scapy 的srp有个inter参数控制包间隔result srp(packet, timeout3, inter0.01, verbose0)[0]inter0.01表示每个包间隔 10 毫秒254 个包大约 2.5 秒发完对网络的影响可以忽略。如果网段更大把 inter 调到 0.05 甚至 0.1。宁可扫得慢一点也别把生产网络搞挂。4.5 虚拟机和容器扫不到宿主机现象在虚拟机里跑扫描宿主机和其他虚拟机的 IP 扫不出来。原因虚拟机的网卡通常是 NAT 模式或桥接模式。NAT 模式下虚拟机在独立子网里ARP 广播到不了宿主机所在网段。桥接模式理论上可以但某些虚拟化平台会对广播包做过滤。解决把虚拟机网卡改成桥接模式并确认虚拟交换机的「混杂模式」和「广播转发」是开启的。容器环境更复杂Docker 默认的 bridge 网络是独立的需要用--network host才能和宿主机同网段。这个问题本质上是二层可达性问题不是扫描器能解决的。5. 进阶把 ARP 扫描和交换机 MAC 表联动做资产测绘单靠 ARP 扫描只能拿到 IP 和 MAC拿不到设备接在哪个交换机端口上。但在排查「哪台机器在疯狂发包」或者「这个陌生 MAC 从哪个口进来的」时端口信息才是关键。做法是把 ARP 扫描结果和交换机的 MAC 地址表做关联。以常见的可管理交换机为例通过 SNMP 能读到dot1dTpFdbTable里面记录了每个 MAC 对应哪个桥端口。把 ARP 扫描拿到的 MAC 列表和这张表 join 一下就能得到「IP - MAC - 交换机端口」的完整映射# 伪代码示意实际用 pysnmp 读取 # mac_to_port snmp_get_bridge_table(switch_ip, community) # for dev in arp_devices: # port mac_to_port.get(dev[mac]) # print(f{dev[ip]} {dev[mac]} port{port})这张表的价值在于当 ARP 扫描发现一个陌生 MAC 时你能立刻定位到它接在哪个物理端口直接去机房拔线就行不用一层层排查。我在一次内网异常流量排查里就是靠这个组合十分钟锁定了问题设备——ARP 扫描发现陌生 MACSNMP 查到端口号去机房一看是有人私接了一台设备。另一个进阶用法是结合历史数据做基线。正常网络里设备数量和 MAC 列表在一段时间内是稳定的。把每天扫描的结果存下来跑一个简单的统计如果某天新增 MAC 超过阈值或者某个 MAC 的出现时间集中在非工作时段就触发告警。这套逻辑不需要多复杂的算法一个 diff 加一个计数器就够了但实战效果比很多商业资产管理系统都直接。最后说个我自己的习惯每次到新环境部署第一件事就是跑一遍 ARP 扫描存基线然后配个定时任务每小时扫一次。这样网络里任何风吹草动——新设备接入、IP 被占、MAC 被改——都逃不过。工具不复杂难的是坚持做基线、做比对。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。