在Windows系统上,使用Java JNA调用wintun.dll创建网络适配器,并通过pcap4解析网络数据包。
wintun官网:www.wintun.net/ 下载wintun的dll
使用idea创建一个maven项目,maven需要的依赖。(jna调用wintun.dll,pcap4j用于解析数据包。)
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.10.0</version>
</dependency>
<dependency>
<groupId>org.pcap4j</groupId>
<artifactId>pcap4j-core</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.pcap4j</groupId>
<artifactId>pcap4j-packetfactory-static</artifactId>
<version>1.8.2</version>
</dependency>
创建WintunLibrary类,通过jna调用wintun.dll
public interface WintunLibrary extends Library {
WintunLibrary INSTANCE = (WintunLibrary) Native.load("wintun", WintunLibrary.class);
Pointer WintunCreateAdapter(WString name, WString tunnelType, Pointer requestedGUID);
Pointer WintunStartSession(Pointer sessionHandle, int capacity);
Pointer WintunReceivePacket(Pointer sessionHandle, IntByReference packetSize);
void WintunSendPacket(Pointer sessionHandle, Pointer packet);
void WintunReleaseReceivePacket(Pointer sessionHandle, Pointer packet);
Pointer WintunGetReadWaitEvent(Pointer sessionHandle);
void WintunGetAdapterLuid(Pointer sessionHandle, Pointer luid);
Pointer WintunAllocateSendPacket(Pointer sessionHandle, int packetSize);
void WintunCloseAdapter(Pointer sessionHandle);
}
main方法(需要管理员启动idea,主线程关闭会销毁网络适配器)
public static void main(String[] args) {
String name = "Test";
String tunnelType = "Wintun";
//创建网络适配器
Pointer adapterHandle = WintunLibrary.INSTANCE.WintunCreateAdapter(new WString(name), new WString(tunnelType), null);
if (adapterHandle == null) {
//可能没用管理员启动
throw new RuntimeException("网络适配器创建失败!");
}
//启动适配器
Pointer sessionHandle = WintunLibrary.INSTANCE.WintunStartSession(adapterHandle, 0x400000);
while (true){
//读取适配器数据包
IntByReference incomingPacketSize = new IntByReference();
Pointer incomingPacket = WintunLibrary.INSTANCE.WintunReceivePacket(sessionHandle, incomingPacketSize);
if (incomingPacket != null) {
try {
int packetSize = incomingPacketSize.getValue();
byte[] packetBytes = incomingPacket.getByteArray(0, packetSize);
//解析数据包
IpPacket packet1 = (IpPacket) IpSelector.newPacket(packetBytes, 0, packetBytes.length);
System.out.println(packet1);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
WintunLibrary.INSTANCE.WintunReleaseReceivePacket(sessionHandle, incomingPacket);
}
} else {
int lastError = Native.getLastError();
if (lastError == 0x103) {
//没数据等待数据
Pointer readWaitEvent = WintunLibrary.INSTANCE.WintunGetReadWaitEvent(sessionHandle);
} else {
WintunLibrary.INSTANCE.WintunCloseAdapter(sessionHandle);
throw new RuntimeException("数据包读取失败,错误码:"+lastError);
}
}
}
}
网络适配器可以在 ->控制面板->网络和 Internet->更改适配器设置->查看
查看实际抓包数据可以通过 Wireshark 软件查看,对比一下java的抓包