当前位置: 首页 > news >正文

Npcap与Pcap4J

文章目录

  • 1 介绍
    • 1_Npcap介绍
    • 2_Pcap4J介绍
  • 2 下载并安装 Npcap
  • 3 编写Java程序进行测试
  • 4 补充说明

1 介绍

1_Npcap介绍

Npcap 是用于 Windows 操作系统的数据包捕获和网络分析的架构,由软件库和网络驱动程序组成。

大多数网络应用程序通过广泛使用的操作系统原语(例如 Socket 套接字)访问网络。

通过这种方式访问网络上的数据非常容易,因为操作系统会处理底层细节(例如协议处理、数据包重组等),并提供类似于读写文件的熟悉接口。

然而,有时这种“简单的方法”并不适合,因为有些应用程序需要直接访问网络上的数据包。也就是说,它们需要访问网络上的“原始”数据,而无需操作系统介入协议处理。

Npcap 的目的是为 Windows 应用程序提供此类访问权限。它提供以下功能:

  • 捕获原始数据包,包括发往运行它的机器的数据包和与其他主机(在共享媒体上)交换的数据包
  • 根据用户指定的规则过滤数据包,然后再将其发送给应用程序
  • 向网络传输原始数据包
  • 收集网络流量的统计信息

Npcap 官网:https://npcap.com/。

如果是 Linux 系统则使用 libpcap。

2_Pcap4J介绍

Pcap4J 是一个用于捕获、处理和发送数据包的 Java 库。Pcap4J 通过JNA封装了原生数据包捕获库(libpcap、 WinPcap或Npcap) ,并提供了面向 Java 的 API。

简单来说就是 Pcap4J 可以为我们的 Java 程序提供调用 Npcap 访问传输层以下网络接口的能力。

Pcap4J 官网:https://www.pcap4j.org/。

接下来简单了解一下如何进行使用。

2 下载并安装 Npcap

下载并安装最新版 Npcap。

在这里插入图片描述

打开下载的安装程序勾选如下两个选项安装即可:

  • “Install Npcap in WinPcap API-compatible Mode”
  • “Support raw 802.11 traffic (and monitor mode) for wireless adapters”

在这里插入图片描述

3 编写Java程序进行测试

通信思路说明:

  • 发送端构造一整个 Ethernet + IP + UDP 数据包。
  • 接收端在链路层捕获包并解析 UDP 载荷。
  • 不需要 socket,不依赖 Java 内核传输栈。

添加 Maven 依赖:

<dependency><groupId>org.pcap4j</groupId><artifactId>pcap4j-core</artifactId><version>1.8.2</version>
</dependency>

通过如下程序获取本机所有网卡信息:

import lombok.Data;import java.net.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Random;public class NetworkInfoUtil {private static final List<Mac> macs = new ArrayList<>();@Datapublic static class Mac {private String interfaceName;private String interfaceDesc;private String macAddr;private String ipv4Addr;}static {try {Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();while (interfaces.hasMoreElements()) {Mac mac = new Mac();NetworkInterface ni = interfaces.nextElement();// 排除回环、禁用、虚拟网卡if (ni.isLoopback() || !ni.isUp() || ni.isVirtual()) {continue;}mac.setInterfaceName(ni.getName());mac.setInterfaceDesc(ni.getDisplayName());// 获取 MAC 地址byte[] macBytes = ni.getHardwareAddress();if (macBytes != null) {StringBuilder macAddr = new StringBuilder();for (int i = 0; i < macBytes.length; i++) {macAddr.append(String.format("%02X%s", macBytes[i], (i < macBytes.length - 1) ? "-" : ""));}mac.setMacAddr(macAddr.toString());} else {System.out.println("MAC 地址: 无法获取");}// 获取 IPv4 地址Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();while (inetAddresses.hasMoreElements()) {InetAddress addr = inetAddresses.nextElement();if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {mac.setIpv4Addr(addr.getHostAddress());}}macs.add(mac);System.out.println(mac);System.out.println("--------------------------");}} catch (SocketException ignored) {}}public static Mac getMacRandom() {Random random = new Random();int index = random.nextInt(macs.size());return macs.get(index);}
}

服务端程序,抓取数据包:

import org.pcap4j.core.*;import java.util.List;public class RawUdpReceiver {public static void main(String[] args) throws Exception {// 1. 获取网络接口列表List<PcapNetworkInterface> allDevs = Pcaps.findAllDevs();// 选择第一个接口 (通常修改为你的目标网卡索引)PcapNetworkInterface nif = allDevs.get(0); // 可以根据描述筛选特定网卡// 2. 打开接口 - 关键设置 snapLen 和 promiscuous mode// snapLen = 65536;  捕获完整包PcapHandle handle = nif.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 50);handle.setFilter("udp port 54321", BpfProgram.BpfCompileMode.OPTIMIZE);// 3. 设置抓包回调 (这里简单打印包到达时间和长度)PacketListener listener = packet -> {System.out.println("收到数据包:" + packet);};try {// 4. 开始抓包 (持续抓10个包)handle.loop(10, listener); } catch (Exception e) {System.out.println("捕获完毕");}// 5. 清理handle.close();}
}

客户端程序,发送数据包

import org.pcap4j.core.*;
import org.pcap4j.packet.*;
import org.pcap4j.packet.namednumber.EtherType;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.IpVersion;
import org.pcap4j.packet.namednumber.UdpPort;
import org.pcap4j.util.MacAddress;import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;public class RawUdpSender {public static void main(String[] args) throws PcapNativeException, NotOpenException, UnknownHostException {// 1. 获取并选择网络接口PcapNetworkInterface nif = Pcaps.findAllDevs().get(0);; // 或者你网卡的名称,例如 "eth0"if (nif == null) {System.out.println("找不到网卡");return;}// 2. 打开接口 (混杂模式)PcapHandle handle = nif.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);// 3. 构造 一个简单的以太网帧 Ethernet 包NetworkInfoUtil.Mac macRandom = NetworkInfoUtil.getMacRandom();String macAddr = macRandom.getMacAddr();MacAddress srcMac = MacAddress.getByName(macAddr);MacAddress dstMac = MacAddress.getByName(macAddr);String ipv4Addr = macRandom.getIpv4Addr();InetAddress srcIp = InetAddress.getByName(ipv4Addr);InetAddress dstIp = InetAddress.getByName(ipv4Addr);//载荷 - 这里简单放点数据byte[] udpPayload = "你好,这是一段原始UDP包".getBytes();// 构建 UDP 数据包UdpPacket.Builder udpBuilder = new UdpPacket.Builder();udpBuilder.srcAddr(srcIp).dstAddr(dstIp).srcPort(UdpPort.getInstance((short) 12345)).dstPort(UdpPort.getInstance((short) 54321)).correctChecksumAtBuild(true).correctLengthAtBuild(true).payloadBuilder(new UnknownPacket.Builder().rawData(udpPayload));// IPIpV4Packet.Builder ipBuilder = new IpV4Packet.Builder();ipBuilder.version(IpVersion.IPV4).tos(IpV4Rfc791Tos.newInstance((byte) 0)).ttl((byte) 64).protocol(IpNumber.UDP).srcAddr((Inet4Address) srcIp).dstAddr((Inet4Address) dstIp).payloadBuilder(udpBuilder).correctChecksumAtBuild(true).correctLengthAtBuild(true);// 构建以太帧EthernetPacket.Builder etherBuilder = new EthernetPacket.Builder();etherBuilder.dstAddr(dstMac).srcAddr(srcMac).type(EtherType.IPV4).payloadBuilder(ipBuilder).paddingAtBuild(true);// 4. 发送数据包handle.sendPacket(etherBuilder.build());System.out.println("发送成功");// 5. 清理handle.close();}
}

运行结果如下:

在这里插入图片描述

4 补充说明

更多使用说明详见:https://github.com/kaitoy/pcap4j。

http://www.lryc.cn/news/576872.html

相关文章:

  • 学习记录:DAY35
  • vite | vite-plugin-dts 插件生成类型文件 的安装和使用
  • Python爬虫实战:研究untangle库相关技术
  • MYSQL的基础信息如何存放
  • PL-SLAM: Real-Time Monocular Visual SLAM with Points and Lines
  • 实战四:基于PyTorch实现猫狗分类的web应用【2/3】
  • Rust函数与所有权
  • Webpack中的Loader详解
  • SpringBoot医疗用品销售网站源码
  • 什么是P2P 网络(Peer-to-Peer Network)
  • (八)聚类
  • KPL战队近五年热度指数
  • 如何解决大语言模型微调时的模型遗忘问题?
  • MYSQL与PostgreSQL的差异
  • Segment Anything in High Quality之SAM-HQ论文阅读
  • ​扣子Coze飞书多维表插件-创建数据表
  • 机器学习9——决策树
  • MyBatis修改(update)操作
  • 【PaddleOCR】PaddlePaddle 3.0环境安装,及PaddleOCR3.0 快速入门使用
  • 企业级路由器技术全解析:从基础原理到实战开发
  • 学习使用Visual Studio分析.net内存转储文件的基本用法
  • cJSON 使用方法详解
  • 华为云 Flexus+DeepSeek 征文|华为云 Flexus 云服务 Dify-LLM 平台深度部署指南:从基础搭建到高可用实践
  • NLP随机插入
  • 如果将Word里每页的行数设置成50行
  • jenkins启动报错,一直无法启动
  • 高并发电商返利 APP 架构设计:从淘客佣金模型到分布式导购系统的技术落地
  • [分布式并行] 流水线并行 PP(NaivePP/GPipe/F-then-B/PipeDream/1F1B)
  • MySQL数据库的增删改查
  • 茶叶根茎分割数据集介绍与应用