简介面向局域网网络运维与安全监测场景本下载内容提供一套基于C#与SharpPcap的ARP抓包实现用于自动发现当前网段内的在线设备并同时识别IP地址冲突风险。代码将核心抓包逻辑封装为一个类调用方只需引用SharpPcap.dll和PacketDotNet.dll即可在VS2015、.NET 4.5.2环境中完成设备扫描和异常IP冲突列表输出特别适合有一定C#基础的网络管理员或桌面工具开发者借以搭建轻量型局域网探测工具。资源内除了完整的使用示例项目外还刻意附带了WinPcap_4_1_3驱动安装包以及SharpPcap、PacketDotNet两个动态库便于使用者一次性解决底层抓包环境配置问题免去自行搜索匹配版本的麻烦。压缩包共36个文件总体积约1002KB主体为11个CS源代码文件另有可执行示例、config配置、resources资源和PDB调试信息等结构较为清晰偏重代码复用而非大型安装包。目前已有558人学习说明该实现具备一定的参考价值对想通过ARP包被动感知设备存在和地址冲突的开发者而言是一份可直接改造的样例代码。 办公室里突然弹出一句“IP地址冲突”紧接着好几台电脑开始掉线这种事只要碰上过一次网管心里就清楚又有人拿静态IP乱配了。但问题是怎么把那个“满嘴跑火车”的设备找出来。我后来在交换机上做了个端口镜像抓了十来分钟ARP包不但把冲突的设备定位得明明白白还顺手导出了一份整个办公网段的设备清单连打印机、摄像头、IoT设备全都列得清清楚楚。整个过程靠的就是在局域网里抓ARP包把每个设备的“自我介绍”听一遍。这篇东西就把我这个经验拆开来说为什么ARP抓包能同时干成“设备发现”和“冲突检测”这两件事具体怎么抓、怎么看、怎么自动出表以及我在实际环境里踩过的各种坑。适合刚接触网络排查的运维新人也适合想把手动排查变成脚本化能力的网管老手。1. ARP抓包发现设备底层逻辑是什么1.1 每个ARP包都是设备的“自我介绍”ARPAddress Resolution Protocol的作用很简单在同一个广播域里把一个已知的IP地址解析成对应的MAC地址。设备A想找192.168.1.100就在二层广播里喊一嗓子“谁是192.168.1.100把MAC告诉我”目标设备听到后回一个单播包说“我是我的MAC是xx:xx:xx:xx:xx:xx”。这里的关键在于不管请求还是应答包里都带上了设备的真实IP和真实MAC。更妙的是很多设备在上线、换IP、IP被抢占的时候还会发送一种“免费ARP”Gratuitous ARP主动向全网宣告“我用这个IP我的MAC是这个”。这种包等于设备主动做了个自我介绍抓包的人只需要蹲在链路上听就能把这些信息全记下来。1.2 被动抓包比ping扫描强在哪儿我一向不排斥ping扫描但做设备发现和冲突检测纯靠ping是很吃亏的。对比一下常见方案方案原理优点明显短板ping arp缓存逐IPping再看本机arp表零成本、上手快防火墙禁ICMP就失效arp缓存有过期时间主动ARP扫描nmap/arp-scan全网段发ARP请求速度快、结果全会产生大量探测流量部分安全设备会告警交换机MAC地址表登录交换机查FDB表精准、无干扰老设备的MAC会老化查不到历史记录被动ARP抓包监听链路上的ARP报文无打扰、能看到冲突、能积累趋势结果取决于抓包位置需要花时间等待被动抓包最大的优势有两点一是“不打草惊蛇”它不主动发包纯靠监听目标设备不会有任何感知二是能看到冲突过程的真实对话比如同一个IP地址被两个不同MAC应答这种数据是ping或者查交换机表都得不到的。做故障取证时这种原始包就是铁证。2. 环境准备和抓包位置的选择2.1 工具选型Wireshark、tcpdump还是Python脚本我做这个项目的时候按场景在三个工具之间切换Wireshark图形界面适合人眼排查。过滤语法方便还能看统计、画IO图临时定位问题首选。tcpdump服务器或者没有图形界面的环境里用。命令行工具轻量、不依赖显示器直接在Linux网关上抓最合适。Python Scapy需要出报告、出清单、长期监控时用。把抓包逻辑写成脚本定时跑、推告警比人工盯屏幕可靠得多。如果你只是做一次快速摸底其实还有更偷懒的办法Windows上先ping一遍网段再执行arp -a看缓存表。但注意这种方式依赖本机ARP缓存缓存会过期且只能看到本机和别人通信带来的记录漏掉很多不发包不通信的“哑设备”。2.2 抓包位置决定你最终能看到什么ARP是二层广播协议它的传播范围被限制在同一个广播域里。也就是说跨路由器、跨VLAN的ARP包你是绝对抓不到的。所以第一个原则是抓包点必须和目标设备在同一个VLAN内或者能收到该VLAN的镜像流量。具体位置我按优先级排核心交换机上做端口镜像SPAN/RSPAN把目标VLAN的流量镜像到抓包口。这是最标准的做法。在出问题的终端上直接抓包。适合家里、小办公室没有可管理交换机的环境。家用路由器/傻瓜交换机环境下把抓包电脑接到同一台交换机下让两个端口互通也能抓到广播请求但其他设备之间的单播ARP回复不一定能全收到。注意办公网络如果开了端口隔离Port Isolation或者无线客户端隔离普通接入端口上只能看到广播包和发给自己端口的包单播ARP应答会被交换机隔离这时候就必须以镜像口为准否则抓到的设备列表会少一大截。3. 核心实操从抓到冲突列表3.1 三步抓到高质量ARP包抓包这事会敲命令只是第一步真正决定质量的是抓包的姿势。我一般按三步走第一步确认监控网段和抓包接口。先搞清楚要排查的是哪个VLAN、哪段IP抓包口在哪个接口上。如果端口搞错蹲一天也是白等。第二步输入抓包命令开抓。Wireshark直接选网卡过滤框写arp即可。tcpdump环境用下面这句sudo tcpdump -i eth0 -nn -e arp -w arp_record.pcap参数说明-nn不做域名和端口反解-e显示链路层MAC地址-w保存为pcap文件。这里我特意加上-e因为排查冲突时要时刻看到报文的源MAC和目标MAC不是光看IP就够的。第三步录够时间再分析。很多人抓了两分钟就急着看结果结果啥也没发现。设备不是每时每刻都在发ARP的尤其是那些已经完成通信的设备ARP缓存没过期之前不会频繁发包。我建议至少抓10到30分钟最好覆盖上下班、设备启动和IP地址租约续租的时间段抓到冲突的概率才够大。抓完之后Wireshark里可以先用Statistics - Endpoints按MAC地址统计一遍所有出现过的MAC会直接列出来这就是最原始的“设备列表”。如果想要查询某个IP的对话历史过滤框输入arp.psrc 192.168.1.100或者arp.pdst 192.168.1.100就能看到这个IP的所有解析记录。3.2 怎么从包里面判定“谁是谁”拿到一堆ARP包第一步是搞清哪个MAC对应哪个设备。最快捷的方法是把MAC地址的前三位OUI厂商唯一标识符拿去查比如00:1c:xx是惠普f4:xx:xx是TP-LINK手边没资料时我用macvendors.com这类在线库或者用Python的manuf库解析。这一步能让你快速判断“咦怎么这个IP背后是个手机厂商的MAC”。接下来排查IP冲突重点看三类典型特征判定特征表现形式结论同IP异MAC应答对arp.pdst 192.168.1.100的请求先后出现不同arp.hw.src_mac回复大概率是静态IP冲突双发免费ARP同一IP由不同MAC分别发送Gratuitous ARP宣告两个设备在抢同一个IP同一IP频繁上下线时间轴上设备A出现消失设备B出现反复交替设备在网络中打架抢IP抢占后互踢Wireshark里定位冲突最快的方式先用arp.opcode 1过滤出所有ARP请求报文然后在arp.pdst上做分组统计凡是目标IP对应的源MAC超过一个的直接标红。3.3 用PythonScapy自动生成设备表和冲突列表人工盯着Wireshark看只能解决一次性的排查要想每次出问题都能快速响应我直接写了一个脚本把“听广播、建表、查冲突”的过程自动化。核心用Scapy实现代码不长#!/usr/bin/env python3 # -*- coding: utf-8 -*- # arp_watch.py # 功能被动监听ARP报文记录IP-MAC映射检测IP冲突 import time from scapy.all import sniff, ARP from collections import defaultdict # IP - MAC 映射表用于记录最新状态 ip_mac {} # 一个IP对应多个MAC则记为冲突 conflicts defaultdict(set) def handle_arp(pkt): if ARP not in pkt: return # 发送方MAC如果是全0一般表示探测包跳过 src_mac pkt[ARP].hwsrc src_ip pkt[ARP].psrc if src_mac 00:00:00:00:00:00: return # 记录IP对应的MAC if src_ip in ip_mac: if ip_mac[src_ip] ! src_mac: conflicts[src_ip].add(src_mac) print(f[冲突] IP {src_ip} -- {ip_mac[src_ip]} - {src_mac}) else: ip_mac[src_ip] src_mac print(f[发现] {src_ip} - {src_mac}) # 目标IP不为空时也把目标的IP和MAC关联起来比如收到别人的ARP请求 dst_ip pkt[ARP].pdst if dst_ip and dst_ip ! 0.0.0.0: ip_mac.setdefault(dst_ip, None) if ip_mac[dst_ip] is None: ip_mac[dst_ip] ? # 等待后续应答补充 def timer_report(): print(\n 当前设备清单 ) for ip, mac in sorted(ip_mac.items()): print(f{ip:20s} {mac}) print( 冲突汇总 ) if conflicts: for ip, mset in conflicts.items(): print(f{ip} : {, .join(mset)}) else: print(未检测到冲突) print(\n) if __name__ __main__: print(开始监听ARP包CtrlC停止...) # 抓包网卡按实际环境改比如 eth0 sniff(filterarp, prnhandle_arp, store0, timeout600) timer_report()这个脚本做两件事把监听到的ARP报文实时转成IP - MAC映射当同一个IP出现第二个MAC时立刻报警。抓满10分钟后自动打印当前设备清单和冲突汇总。如果有更多数据要沉淀可以把结果写进CSV或者推送到日志系统。主动扫描版也可以做用Scapy的arping()或者srp()发一圈ARP请求from scapy.all import Ether, ARP, srp network 192.168.1.0/24 ans, _ srp(Ether(dstff:ff:ff:ff:ff:ff) / ARP(pdstnetwork), timeout3, verbose0) for _, rcv in ans: print(f{rcv.psrc:20s} {rcv.hwsrc})不过主动扫描会和目标设备产生交互适合快速摸底不适合做“无声取证”。4. 常见问题与避坑实录4.1 ARP缓存会让抓包结果“骗人”用arp -a看列表的时候你会看到大量过期的映射。Windows和Linux系统对ARP缓存都有老化机制短则几十秒长则几分钟到二十分钟不是实时的。而且缓存里只会记录本机和其他设备通信过的记录一台设备半个小时内没跟抓包主机通信你根本看不到它。做设备清点时我从来不信单次ping arp -a的结果至少要在日志里跨几个时段比对。被动抓包也要注意时间跨度问题监听一分钟只能得到一个极小样本。4.2 交换机端口隔离导致的“只见自己”现象我实际排查中遇到过最坑的情况在贴有“安全加固”标签的办公网络里交换机上开了端口隔离两个终端之间连单播都不能互访。这时候你在其中一台终端上抓包只能抓到广播ARP请求所有单播ARP应答都会被交换机的隔离策略挡在外面看起来就像“全网都没人理我”。遇到这种情况不要琢磨是不是自己网卡坏了直接登录核心交换机查看是否配置了端口隔离或者干脆用镜像口抓包。VLAN里的镜像口通常不受端口隔离影响。4.3 虚拟机漂移、无线漫游给冲突判断带来的干扰这个坑很容易误判成“IP冲突”。我曾经看到同一台服务器的MAC地址在交换机的两个端口之间来回跳还以为有人伪造MAC后来查清楚是配置了双网卡绑定NIC Teaming和虚拟机热迁移。虚拟机在宿主机之间迁移后会主动发送免费ARP刷新网络这在抓包里看起来像“新设备上线”无线终端在多个AP之间漫游后重新关联也会触发类似行为。所以看到同IP异MAC时别急着下结论先结合时间线判断如果两个MAC交替出现并且时间戳毫无规律才是真冲突如果MAC切换有明确的时间窗口比如只在半夜迁移多半是虚拟化环境在干活。4.4 免费ARP不一定代表冲突不少安全防护类软件比如接入认证客户端、防ARP欺骗工具会主动发送免费ARP宣告“网关IP是我的MAC”。这种正常行为会在抓包里产生大量“一个IP对应多个MAC”的记录和暴力抢IP的冲突长得非常像。判断技巧是看哪个设备在发免费ARP、目标IP是谁。如果发的是网关IP且来自不同终端大概率是接入安全软件在“帮”大家刷ARP缓存属于正常现象如果发的是一台普通办公PC的IP并且源头设备变化频繁那才是真正的冲突。说实话这类问题的最终确认还是得结合DHCP服务器日志和接入交换机的端口记录单纯靠抓包会造成个别误判。常见现象可能原因处理思路单包只看到自己端口隔离/无线客户端隔离改到镜像口或核心交换机抓包同IP异MAC间歇出现虚拟机迁移/无线漫游查看时间线确认不是虚假告警大量网关IP的免费ARP接入安全软件、终端防护软件结合接入日志判断勿直接判定攻击一个MAC在多个端口跳变网卡绑定、端口聚合检查服务器网卡配置不用过分担心某IP长期无法上网对方设备可能静态IP抢占在抓包记录里找它的MAC再去交换机定位端口最后再分享一个工作习惯每次抓包我都会随手在命令行里加上-w保存pcap文件分析完绝不急着删。因为我发现单纯在屏幕上滚动看包很快就会眼花等过两天再有人报告同样问题时翻历史包往往比现场重新抓还要高效。另外一点抓包清单出来后我会把它和DHCP服务器上的租约记录交叉比对静态IP设备和不走DHCP的“野设备”立刻就现形了。这个方案做下来我现在排查局域网IP冲突基本不再需要逐台电脑跑去查IP配置了。抓到冲突包直接在交换机上查MAC对应的端口机房五分钟之内就能定位到工位效率完全不是一个级别。本文还有配套的精品资源点击获取