大致原理:winpcap提供底层工具,我们只需要使用它的函数就可以编程,然而很繁琐。java就再封装一层,就出现JPcap这个中间件了。使用对比之后,JPcap尼玛不要太方便。
附:工具:winpcap要安装,这个我就不说了。JPcap作为中间件你需要下载,我没有安装。1.将JPcap.dll动态链接库加入到我的 C:\Program Files\Java\jdk1.7.0_71\jre\bin 中。2.Jpacp.jar我直接外部配置路径了。
不多说,贴可用代码
主程序类,用于读取网卡接口,并开多线程从各个网卡上读取包
package com.sock1;
import java.util.Scanner;
import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;
import jpcap.PacketReceiver;
import jpcap.packet.*;
/**
* 使用jpcap显示网络上的各种数据包
* @author www.NetJava.cn
*/
public class sock_main {
private static int model;
//程序启动主方法
public static void main(String args[]){
try{
System.out.println('请输入你需要抓取的类型包:');
System.out.println('TCP包输入‘1’');
System.out.println('UDP包输入‘2’');
System.out.println('ICMP包输入‘3’');
System.out.println('ARP包输入‘4’');
Scanner in=new Scanner(System.in);
model = in.nextInt();
//获取本机上的网络接口对象数组
final NetworkInterface[] devices = JpcapCaptor.getDeviceList();
for(int i=0;i<devices.length;i ){
NetworkInterface nc=devices[i];
//创建某个卡口上的抓取对象,最大为2000个
JpcapCaptor jpcap = JpcapCaptor.openDevice(nc, 2000, true, 20);
startCapThread(jpcap); //线程执行抓包
System.out.println('开始抓取第' i '个卡口上的数据');
}
}catch(Exception ef){
ef.printStackTrace();
System.out.println('启动失败: ' ef);
}
}
//将每个Captor放到独立线程中运行
public static void startCapThread(final JpcapCaptor jpcap ){
JpcapCaptor jp=jpcap;
java.lang.Runnable rnner=new Runnable(){ //创建线程
public void run(){
//使用接包处理器循环抓包
jpcap.loopPacket(-1, new TestPacketReceiver(model)); //-1无限抓取包,抓包监听器获取包
}
};
new Thread(rnner).start();//启动抓包线程
}
}
抓包类,实现抓包功能,并输出信息
package com.sock1;
import jpcap.PacketReceiver;
import jpcap.packet.ARPPacket;
import jpcap.packet.DatalinkPacket;
import jpcap.packet.EthernetPacket;
import jpcap.packet.ICMPPacket;
import jpcap.packet.Packet;
import jpcap.packet.TCPPacket;
import jpcap.packet.UDPPacket;
/**
* 抓包监听器,实现PacketReceiver中的方法:打印出数据包说明
*/
class TestPacketReceiver implements PacketReceiver {
public int model;
public TestPacketReceiver (int n)
{
this.model = n;
}
/**
* 实现的接包方法:
*/
public void receivePacket(Packet packet) {
//Tcp包
if(packet instanceof jpcap.packet.TCPPacket && model== 1){
TCPPacket p=(TCPPacket)packet;
String s='TCPPacket:| 目的ip及端口 ' p.dst_ip ':' p.dst_port
'|源ip及端口 ' p.src_ip ':' p.src_port
' |数据长度: ' p.len;
System.out.println(s);
}
//UDP包
else if(packet instanceof jpcap.packet.UDPPacket && model== 2){
UDPPacket p=(UDPPacket)packet;
String s='UDPPacket:| 目的ip及端口 ' p.dst_ip ':' p.dst_port
'||源ip及端口 ' p.src_ip ':' p.src_port
' |数据长度: ' p.len;
System.out.println(s);
}
//ICMPPacket包
else if(packet instanceof jpcap.packet.ICMPPacket && model== 3){
ICMPPacket p=(ICMPPacket)packet;
//ICMP包的路由链
String router_ip='';
for(int i=0;i<p.router_ip.length;i ){
router_ip =' ' p.router_ip[i].getHostAddress();
}
String s='@ @ @ ICMPPacket:| 路由IP: ' router_ip
' |redir_ip: ' p.redir_ip
' |最大传输单元: ' p.mtu
' |长度: ' p.len;
System.out.println(s);
}
//ARP请求包
else if(packet instanceof jpcap.packet.ARPPacket && model== 4){
ARPPacket p=(ARPPacket)packet;
//Returns the hardware address (MAC address) of the sender
Object saa= p.getSenderHardwareAddress();
Object taa=p.getTargetHardwareAddress();
String s='* * * ARPPacket:| 发送硬件地址: ' saa
'|目标硬件地址: ' taa
' |长度: ' p.len;
System.out.println(s);
}
//取得链路层数据头 :如果你想局网抓包或伪造数据包,嘿嘿
DatalinkPacket datalink =packet.datalink;
//如果是以太网包
if(datalink instanceof jpcap.packet.EthernetPacket){
EthernetPacket ep=(EthernetPacket)datalink;
String s=' 以太包: '
'|目的MAC: ' ep.getDestinationAddress()
'|源MAC: ' ep.getSourceAddress();
System.out.println(s);
}
}
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。