Pcap4j仅检测到主机设备地址,无法识别局域网其他设备求助
解决Pcap4j ARP嗅探器仅显示本地主机地址的问题
你现在的代码其实还没真正启动ARP数据包的捕获流程——它只是帮你选好了网卡,然后打印了该网卡自身的链路层地址,这就是为什么你只能看到自己主机的信息。要捕获局域网内其他设备的ARP包,我们需要完善代码,添加数据包捕获、过滤和解析的核心逻辑。
问题根源分析
你的当前代码只完成了网卡选择和本地地址的打印,缺少三个关键步骤:
- 没有打开网卡进入数据包捕获模式
- 没有设置ARP专属的数据包过滤器
- 没有监听并解析捕获到的ARP数据包
完整解决方案代码
下面是修正后的代码,它会主动捕获局域网内的ARP请求/响应包,并提取出其他设备的MAC和IP地址:
package arpsniffer; import java.io.IOException; import org.pcap4j.core.*; import org.pcap4j.packet.ArpPacket; import org.pcap4j.packet.Packet; import org.pcap4j.util.LinkLayerAddress; import org.pcap4j.util.NifSelector; import org.pcap4j.util.MacAddress; import org.pcap4j.util.Inet4Address; public class ArpSniffer { private static final int SNAPLEN = 65536; // 捕获数据包的最大长度 private static final int TIMEOUT = 10; // 捕获超时时间(毫秒) private static final String ARP_FILTER = "arp"; // BPF过滤器,仅捕获ARP类型数据包 public static void main(String[] args) { PcapNetworkInterface nif; try { // 选择要监听的目标网卡 nif = new NifSelector().selectNetworkInterface(); if (nif == null) { System.out.println("未选择网卡,程序退出"); return; } // 打印选中网卡的本地信息 System.out.println("正在监听网卡: " + nif.getName()); for(LinkLayerAddress addr : nif.getLinkLayerAddresses()){ System.out.println("本地链路层地址: " + addr.toString()); } // 打开网卡并启用混杂模式(捕获所有经过的数据包) PcapHandle handle = nif.openLive(SNAPLEN, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, TIMEOUT); // 设置ARP数据包过滤器,减少无效数据包处理 handle.setFilter(ARP_FILTER, BpfCompileMode.OPTIMIZE); System.out.println("已启用ARP过滤器,开始捕获数据包..."); // 定义数据包处理器,解析ARP包内容 PacketListener listener = packet -> { ArpPacket arpPacket = packet.get(ArpPacket.class); if (arpPacket == null) { return; } ArpPacket.ArpHeader header = arpPacket.getHeader(); // 提取ARP包中的源MAC和IP地址 MacAddress srcMac = header.getSrcHardwareAddr(); Inet4Address srcIp = header.getSrcProtocolAddr(); // 排除本地地址,避免重复打印自己的设备信息 if (!srcMac.equals(nif.getLinkLayerAddresses().get(0).getAddress())) { System.out.printf("检测到设备 -> MAC: %s, IP: %s%n", srcMac, srcIp); } }; // 启动无限捕获循环(按Ctrl+C可中断) handle.loop(-1, listener); } catch (IOException e) { System.err.println("IO错误: " + e.getMessage()); e.printStackTrace(); } catch (PcapNativeException e) { System.err.println("Pcap本地库错误: " + e.getMessage()); e.printStackTrace(); } catch (NotOpenException e) { System.err.println("网卡未打开: " + e.getMessage()); e.printStackTrace(); } catch (InterruptedException e) { System.err.println("捕获被中断"); Thread.currentThread().interrupt(); } } }
关键改进点说明
- 启用混杂模式:在打开网卡时设置
PromiscuousMode.PROMISCUOUS,让网卡可以捕获所有经过的数据包,而不只是发给自己的。 - BPF过滤器:使用
arp过滤器,只处理ARP类型的数据包,减少不必要的资源消耗。 - ARP数据包解析:通过
ArpPacket类解析捕获到的数据包,提取出其他设备的MAC和IP地址。 - 排除本地地址:添加判断逻辑,避免重复打印自己主机的地址信息。
额外注意事项
- 运行权限:务必以管理员身份运行程序,Windows环境下捕获数据包需要管理员权限。
- 网卡选择:确认选择的是连接局域网的物理网卡,而非虚拟网卡(如VPN、虚拟机网卡)。
- 触发ARP流量:如果暂时看不到其他设备,可以手动触发ARP请求(比如在另一台设备上ping网关),这样就能捕获到对应的ARP数据包了。
内容的提问来源于stack exchange,提问作者Fabio Slßr
相关产品推荐
相关产品推荐

