统计TCP流量抓包,jpcap抓包时,通过loopPacket()方法,笔记本的有限网卡抓不包,而无线网可以,这是为什么?

1281人阅读
这是我们网络编程与协议分析的课设,由于最近一直在用JAVA写项目,后面就快要写到界面了,所以干脆直接学习用JAVA来写这次的课设,算是一举两得了。
课设的要求是获取局域网内的所有数据包,并且分析TCP,UDP,ICMP各个字段,和一些应用层协议(HTTP,DNS等)。
要实现在JAVA下抓包,需要利用Jpcap这个包。它实现了JAVA到winpcap的一个中间接口,所以实际上它就是通过调用winpcap来实现抓包的,而winpcap说白了就是一个流氓软件,它提供了一个访问网络底层的能力,并且具有独立于系统的dll。
winpcap在去年计算机网络课设的时候已经安装过了,东西不知道丢哪了,这里只给个64为的Jpcap的包、
创建工程后导入就好,有时候会出现导入完了还是提示错误,这里我把jar全部删了然后重新导入一遍就没问题了,具体原因不知。
这段代码可以实现打开网卡列表,选择一个网卡(this.num)打开一个捕捉器,进行无限次抓包(参数 -1代表无限,其他正数代表抓多少包后停止)
将这段代码放在一个extends Thread 的类当中,并重载run函数可以实现多线程。
public void run(){
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
jcap = JpcapCaptor.openDevice(devices[this.num], 65535, false, 20);
} catch (IOException e) {
e.printStackTrace();
jcap.loopPacket(-1, new ClientPacketHandler());
这里用到的ClientPacketHandler类是一个实现PacketReceiver接口的类,其中只有一个函数
public void receivePacket(Packet packet)
这个函数就是loopPacket抓到一个包后的处理函数,而packet就是相应的数据包,这里的Packet就是Jpcap下数据包的基类,直接从Object继承来,而其他的例如TCPPacket,IPPacket都是由它继承来的。
if(packet instanceof TCPPacket) //可以判断这个包是否是TCP包,其它同
TCPPacket tp = (TCPPacket)packet //可以将它转换成TCP数据包
EthernetPacket EP = (EthernetPacket)packet. //可以取出数据链路层头部
依次类推。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:196807次
积分:5923
积分:5923
排名:第4000名
原创:282篇
评论:89条
(2)(6)(3)(13)(21)(16)(13)(7)(9)(3)(22)(9)(4)(13)(5)(31)(49)(16)(23)(18)JPCAP实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用wincap/libpcap,而给JAVA语言提供一个公共的接口,从而实现了平台无关性。在官方网站上声明,JPCAP支持FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft
Windows 2000/XP等系统。
一个简单的示例,获得arp包
import java.io.IOE
import jpcap.JpcapC
import jpcap.NetworkI
import jpcap.NetworkInterfaceA
import jpcap.PacketR
import jpcap.packet.ARPP
import jpcap.packet.P
import jpcap.packet.TCPP
public class tea {
public static void main(String[] args) throws IOException {
NetworkInterface[] net = JpcapCaptor.getDeviceList() ; // JpcapCaptor.getDeviceList( )返回的是网络接口设备的列表,
//NetworkInterface类,网络接口类。其封装了相应网络设口信息,比如:网卡名,网卡描述,网卡所处的数据链路层的名称
JpcapCaptor jpcap = JpcapCaptor.openDevice(net[3], 65535, false, 20 ) ;//打开网卡
jpcap.setFilter(&arp&, true);//过滤
只接收arp包
jpcap.loopPacket(-1, new receiver());//回调函数
class receiver implements PacketReceiver{
public void receivePacket(Packet arg0) {
// TODO Auto-generated method stub
System.out.println(arg0);
一个全一点的复杂一点的程序
import java.io.IOE
import jpcap.JpcapC
import jpcap.NetworkI
import jpcap.NetworkInterfaceA
import jpcap.PacketR
import jpcap.packet.ARPP
import jpcap.packet.P
import jpcap.packet.TCPP
public class D {
public static void main(String[] args) {
/******获取网络接口设备*****/
System.out.println(&/***获取网络接口设备*****/&) ;
NetworkInterface[] devices = JpcapCaptor.getDeviceList() ; //获得所有网卡列表
String s = devices.toString() ;
System.out.println(s) ;
//JpcapCaptor captor=JpcapCaptor.openDevice(devices[0], 65535, false, 20);
for (int i = 0 ; i & devices. i ++) {
System.out.println(i + &:
& + devices[i].name + &
devices[i].description + &)&) ;
// 网卡所处数据链路层的名称与其描述
System.out.println(&datalink:
& + devices[i].datalink_name + &
(& + devices[i].datalink_description + &)&) ;
// 网卡MAC地址
System.out.println(&网卡MAC:
&+devices[i].mac_address);//
System.out.print(&网卡MAC(16进账): &);
for (byte b : devices[i].mac_address){
// 转化为16进账
//System.out.print(&(&+b+&)&);
System.out.print(Integer.toHexString(b&0xff) + &:&); // byte 有符号 最高位为1时
System.out.println();
System.out.println(&Ipv6: &+devices[i].addresses[0].address); //ipv6
System.out.println(&Ipv4: &+devices[i].addresses[1].address);
//输出网卡ipv6
for (NetworkInterfaceAddress a :devices[i].addresses) {
System.out.println(&address: & + a.address + &
& + a.subnet + &
&+a.broadcast);
System.out.println();
System.out.println();
System.out.println();
/***打开网络接口设备*******/
System.out.println(&/***打开网络接口设备****/&);
//NetworkInterface[] devices1 = JpcapCaptor.getDeviceList();
int index = 1 ;// 打开的网卡设备号
//打开一个网络接口设备
// 各参数(设备实例
一次捕捉最大字节 ,是否为混乱模式 , 捕捉包的超时时间)
JpcapCaptor captor = JpcapCaptor.openDevice(devices[index], 65535, false, 20);
//jpcapCaptor 实例的功能是捕捉包
发送包不是它的责任
System.out.println(captor);
System.out.println(captor.getDeviceList());
System.out.println(JpcapCaptor.getDeviceList());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println();
System.out.println();
/***使用实例jpcapCaptor捕捉网络数据包******/
System.out.println(&/****使用实例jpcapCaptor捕捉网络数据包***/&);
//NetworkInterface[] devices_1 = JpcapCaptor.getDeviceList() ;
int index = 3 ; // 打开的网卡设备号
// 打开一个网络接口设备 得到一个JpcapCaptor 实例
JpcapCaptor captor = JpcapCaptor.openDevice(devices[index], 65535, false, 20);
captor.setFilter(&arp&, true);
//调用JpcapCaptor类的实例的loopPacket() 开始接受数据包
int a = captor.loopPacket(2 , new Receiver()) ;// 第一个参数
一次接受包的数目
//int a = captor.processPacket(-1, new Receiver()) ;// 接收超时 或 没有数据接收 立即返回
System.out.println(captor.getPacket());System.out.println(a+&[]&);
//captor.processPacket(1 , new Receiver()) ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Receiver implements PacketReceiver { // 定义一个类
该类需实现receiverPacket()方法
public void receivePacket(Packet packet) {
// TODO Auto-generated method stub
System.out.println(&========&);
System.out.println(packet);
ARPPacket arp = (ARPPacket)
System.out.println(&硬件类型:
&+Integer.toHexString(arp.hardtype)); // short 转换为16进账字符串
System.out.println(&协议类型:
&+Integer.toHexString(arp.prototype));
System.out.println(&操作类型 :
&+Integer.toHexString(arp.operation));
System.out.println(&发送端MAC地址: &+arp.getSenderHardwareAddress());
System.out.println(&发送端IP地址:
&+arp.getSenderProtocolAddress());
System.out.println(&目标MAC址:
&+arp.getTargetHardwareAddress());
System.out.println(&目标IP地址:
&+arp.getTargetProtocolAddress());
//System.out.println(&数据
&+arp.data);
//System.out.println(&数据
&+arp.ARP_REPLY);
System.out.println();
/***获取网络接口设备*****/
[Ljpcap.NetworkI@135fbaa4
0: & \Device\NPF_{A1C-46D6-A355-1DD} & &(Qualcomm Atheros Ar81xx series PCI-E Ethernet Controller)
datalink: &EN10MB &(Ethernet)
网卡MAC: &[B@45ee12a7
网卡MAC(16进账): 20:1a:6:bd:cb:7e:
Ipv6: /fe80:0:0:0:61b1:35cd:3606:7ebe
Ipv4: /192.168.0.106
address: /fe80:0:0:0:61b1:35cd:3606:7ebe & null & null
address: /192.168.0.106 & /255.255.255.0 & /0.0.0.0
1: & \Device\NPF_{4E6BE974-A4FC-64005D2FEC} & &(VMware Virtual Ethernet Adapter)
datalink: &EN10MB &(Ethernet)
网卡MAC: &[B@330bedb4
网卡MAC(16进账): 0:50:56:c0:0:8:
Ipv6: /fe80:0:0:0:99b0:9737:bdb8:d87
Ipv4: /0.0.0.0
address: /fe80:0:0:0:99b0:9737:bdb8:d87 & null & null
address: /0.0.0.0 & /255.0.0.0 & /255.255.255.255
2: & \Device\NPF_{FE54F32A-0432-41AA-9C45-3DE8BE6D4DC8} & &(TAP-Windows Adapter V9)
datalink: &EN10MB &(Ethernet)
网卡MAC: &[B@2503dbd3
网卡MAC(16进账): 0:ff:fe:54:f3:2a:
Ipv6: /fe80:0:0:0::652:acfe
Ipv4: /fe80:0:0:0::652:acfe
address: /fe80:0:0:0::652:acfe & null & null
address: /fe80:0:0:0::652:acfe & null & null
3: & \Device\NPF_{A783EA17-120D-4B12-8851-FEAB3CA3F4FF} & &(Microsoft)
datalink: &EN10MB &(Ethernet)
网卡MAC: &[B@4b67cf4d
网卡MAC(16进账): 48:5a:b6:d6:24:4f:
Ipv6: /fe80:0:0:0:a0ed:d13a:8a80:bed
Ipv4: /192.168.0.107
address: /fe80:0:0:0:a0ed:d13a:8a80:bed & null & null
address: /192.168.0.107 & /255.255.255.0 & /255.255.255.255
4: & \Device\NPF_{9--AFCAAD1D6560} & &(VMware Virtual Ethernet Adapter)
datalink: &EN10MB &(Ethernet)
网卡MAC: &[B@7ea987ac
网卡MAC(16进账): 0:50:56:c0:0:1:
Ipv6: /fe80:0:0:0:c4f2:f985:e034:1e47
Ipv4: /0.0.0.0
address: /fe80:0:0:0:c4f2:f985:e034:1e47 & null & null
address: /0.0.0.0 & /255.0.0.0 & /255.255.255.255
/***打开网络接口设备****/
jpcap.JpcapCaptor@d716361
[Ljpcap.NetworkI@6ff3c5b5
[Ljpcap.NetworkI@3764951d
/****使用实例jpcapCaptor捕捉网络数据包***/
ARP REQUEST 48:5a:b6:d6:24:4f(/192.168.0.107) -& c8:3a:35:4e:5e:30(/192.168.0.1)
硬件类型: & & 1
协议类型: & & 800
操作类型 : & & 1
发送端MAC地址: 48:5a:b6:d6:24:4f
发送端IP地址: &/192.168.0.107
目标MAC址: & &c8:3a:35:4e:5e:30
目标IP地址: & &/192.168.0.1
ARP REPLY c8:3a:35:4e:5e:30(/192.168.0.1) -& 48:5a:b6:d6:24:4f(/192.168.0.107)
硬件类型: & & 1
协议类型: & & 800
操作类型 : & & 2
发送端MAC地址: c8:3a:35:4e:5e:30
发送端IP地址: &/192.168.0.1
目标MAC址: & &48:5a:b6:d6:24:4f
目标IP地址: & &/192.168.0.107
计算机网络的课程设计,要求抓arp包。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:51603次
积分:1982
积分:1982
排名:第18650名
原创:147篇
转载:11篇
(2)(4)(1)(8)(1)(1)(5)(7)(10)(30)(17)(1)(1)(2)(11)(13)(4)(18)(15)(4)(4)> 施用jFreeChart实现web实时设备状态的图形化监控之二:jPcap使用简介
施用jFreeChart实现web实时设备状态的图形化监控之二:jPcap使用简介
xiaomi0733 & &
发布时间: & &
浏览:2 & &
回复:0 & &
悬赏:0.0希赛币
使用jFreeChart实现web实时设备状态的图形化监控之二:jPcap使用简介
1.jpcap说明与安装JAVA语言虽然在TCP/UDP传输方面给予了良好的定义,但对于网络层以下的控制,却是无能为力的。JPCAP扩展包弥补了这一点,jPcap是一个可以让java工作在链路层的类库;当然,它底层还是使用了本机API通过Jini调用,在javaAPI中得到数据。JPCAP实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用wincap/libpcap,而给JAVA语言提供一个公共的接口,从而实现了平台无关性。在官方网站上声明,JPCAP支持FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP等系统。jPcap下载地址: ;
你可以从jpcap网站上直接下载它的桌面应用程序进行测试,可以全面的统计本机的网络数据流量及收发包数据。   Jpcap is a Java class package that allows Java applications to capture and/or send packets to the network.  Jpcap is based on libpcap/winpcap and Raw Socket API. Therefore, Jpcap is supposed to work on any OS on which libpcap/winpcap has been implemented. Currently, Jpcap has been tested on FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP.Jpcap supports the following types of packets: Ethernet, IPv4, IPv6, ARP/RARP, TCP, UDP, and ICMPv4.
Other types of packets are captured as raw packets (i.e., instances of the Packet class) which contains the whole data of the packets.
This allows Java applications to analyze unsupported packet types.  本项目中使用的是jPcap0.6版本,从其网站上下载Source build后,可以看到其下详细的目录结构,源码,例程及Native lib。  使用jPcap可以编写出功能完备的网络嗅测程序,本节中,我们只是使用其非常简单的一个功能:统计本机每块网卡上收发数据的总量。特别注意:jpcap运行时依赖winCap的类库,使用前必须在机地安装winCap()(如果是在liunx上,则请到下载)。本节中jPcap版本为0.6,winCap版本为4.0,运行与win32系统上。 2.jPcap小试:显示本机网络接口详情jPcap中的API非常简单,可查看其在线文档:。当然,要灵活的使用,你必须有良好的tcp/ip协议知识基础,对常用的3个关键类,简介如下:   JpcapCaptor类这个类是jPcap中的核心对象,一个JpcapCaptor对象代表了了系统中的一个网络接口卡;通过对JpcapCaptor对象的调用,实现网络数据包的抓取和发送。它供了一系列静态方法调用如:获取网卡列表,获取某个网卡上的JpcapCaptor对象。static NetworkInterface[]getDeviceList()这个静态方法调用,可以返回机器上网络接口卡对象的数组,数组中每一个NetworkInterface元素对象代表一个网络接口;一般使用jPcap所要做的第一步调用就是这个方法。static JpcapCaptor openDevice(NetworkInterface interface, int snaplen, boolean promisc, int to_ms)取得在指定网卡上的Jpcapcator对象,Interface:上所返回的某个网卡对象Snaplen:一次性要抓取数据包的最大长度。Promisc:设置是否混杂模式。处于混杂模式将接收所有数据包,如果设置为混杂模式后调用了包过滤函数setFilter()将不起任何作用;To_ms:这个参数主要用于processPacket()方法,指定超时的时间; int loopPacket(int count, PacketReceiver handler)常用的一种模式是,通过getDeviceList()取得所有网络接口,再通过openDevice方法取得每个网络接口上的JpcapCaptor对象,就可通过这个方法抓包了。loopPacket方法中count参数表示要抓的包的数目,如果设备为-1,责表示永远抓下去---方法不会返回;第二个参数必须是实现了PacketReceiver接口的一个对象,抓到的包将调用这个PacketReceiver对象中的receivePacket(Packet packet)方法处理;所以抓包前,我们必须写一个实现了PacketReceiver接口的类。
特别注意的是:这个方法的调用会阻塞等待,如果没有抓到指定count的包、或count设为-1,这个方法都不会返回。所以,聪明的你肯定想到了,如果要抓取机器上多个卡口上的包,这个方法必须放在一个独立的线程中。void breakLoop()    即上JpcapCaptor对象上阻塞等待的方法强制终止。当调用processPacket()和loopPacket()后,再调用这个方法可以强制让processPacket()和loopPacket()停止。interface PacketReceiver :数据包处理器接口定义,要处理收到的数据包,必须编写这个接口的实现类,在JpcapCaptor对象的loopPacket方法中调用. 这个接口中仅有一个方法定义:Void receivePacket (Packet p)  实现类中处理接收到的Packet对象的方法。每个Packet对象代表从热指定网络接口上抓取到的数据包。NetworkInterface类该类的每一个实例代表一个网络设备,一般就是网卡。这个类只有一些数据成员,除了继承自java.lang.Object的基本方法以外,没有定义其它方法。(但我还不知它与jdk5.0以上的API中的java.net.InterfaceAddress类是否可以互换)。NetworkInterfaceAddress[]addresses  
这个接口的网络地址。设定为数组应该是考虑到有些设备同时连接多条线路,例如路由器。但我们的PC机的网卡一般只有一条线路,所以我们一般取addresses[0]就够了。java.lang.String datalink_description. 
数据链路层的描述。描述所在的局域网是什么网。例如,以太网(Ethernet)、无线LAN网(wireless LAN)、令牌环网(token ring)等等。java.lang.String datalink_namedatalink_name   该网络设备所对应数据链路层的名称。具体来说,例如Ethernet10M、100M、1000M等等。java.lang.String description   网卡是XXXX牌子XXXX型号之类的描述。例如我的网卡描述:Realtek RTL Family Gigabit Ethernet NIC boolean Loopback  
标志这个设备是否loopback设备。byte[]mac_address   网卡的MAC地址,6个字节。 java.lang.String Name 
这个设备的名称。例如我的网卡名称:\Device\NPF_{3CE5FDA5-E15D-4F87-B217-255BCB351CD5}  jPcap的API使用很简单,如下代码示例:显示机器上的所有网络接口DispalyNetInterface.java:   import jpcap.JpcapC
import jpcap.NetworkI
import jpcap.PacketR
import jpcap.packet.P
* 使用jpcap显示网络接口数据.
* @author 胡东峰
public class DispalyNetInterface {
public static void main(String args[]){
//获取本机上的网络接口对象数组
final NetworkInterface[] devices = JpcapCaptor.getDeviceList();
for(int i=0;i&devices.i++){
NetworkInterface nc=devices[i];
//一块卡上可能有多个地址:
String address="";
for(int t=0;t&nc.addresses.t++){
address+="|addresses["+t+"]: "+nc.addresses[t].address.toString();
//打印说明:
System.out.println("第"+i+"个接口:"+"|name: "+nc.name
+"|loopback: "+nc.loopback+"\r\naddress: "+address);
}catch(Exception ef){
ef.printStackTrace();
System.out.println("显示网络接口数据失败:
  不幸的是,这段代码运行时会报如下错误:   Exception in thread "main" java.lang.UnsatisfiedLinkError: no jpcap in java.library.path 
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682) 
at java.lang.Runtime.loadLibrary0(Runtime.java:823) 
at java.lang.System.loadLibrary(System.java:1030) 
at jpcap.JpcapCaptor.&clinit&(JpcapCaptor.java:250) 
at cn.netjava.cewolf.DispalyNetInterface.main(DispalyNetInterface.java:19) 还记得我们介绍jPcap: “它底层还是使用了本机API通过Jini调用,在javaAPI中得到数据”,这是因为当前cp中少了jpcap要调用的本地dll库。将jpacp下载后lib下面的jpcap.dll复制到当前项目目录下,如果你仅得制了jpcap.dll,操作系统没有安装wincap( ),则会看到如下错误提示:   Exception in thread "main" java.lang.UnsatisfiedLinkError: E:\workspace\trafficManager\jpcap.dll: Can't find dependent libraries 
at java.lang.ClassLoader$NativeLibrary.load(Native Method) 
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751) 
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676) 
at java.lang.Runtime.loadLibrary0(Runtime.java:823) 
at java.lang.System.loadLibrary(System.java:1030) 
at jpcap.JpcapCaptor.&clinit&(JpcapCaptor.java:250) 
at cn.netjava.cewolf.DispalyNetInterface.main(DispalyNetInterface.java:17)配置完好后,再次运行,输出结果正常:   第0个接口:|name: \Device\NPF_GenericDialupAdapter|loopback: falseaddress: 第1个接口:|name: \Device\NPF_{2A5FD532-45A3-4A2B-9B68-F34C14E4FD2C}|loopback: falseaddress: |addresses[0]: /220.192.159.105第2个接口:|name: \Device\NPF_{DB3-4BC9-979E-CBB}|loopback: falseaddress: |addresses[0]: /192.168.1.44  在我的机器上,开着一块局网网卡和一块无线网卡,都显示出来了;上面的”第0个接口”就是指本机的127.0.0.1的回环地址。但不知为什么,loopback也会是false?  要注意两点:一个是jpcap.dll要在路径中;另外,在统计流量时,本机回环地址不需要统计,一般是第0个接口。接下来我们看抓取网卡上的数据包是多么简单:
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&JPcap的网络流量分析研究与应用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
JPcap的网络流量分析研究与应用
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩33页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢Java底层网络编程包-jpcap_Java_第七城市
Java底层网络编程包-jpcap
1.jpcap说明与安装 JAVA语言虽然在TCP/UDP传输方面给予了良好的定义,但对于网络层以下的控制,却是无能为力的。JPCAP扩展包弥补了这一点,jPcap是一个可以让java工作在链路层的类库;当然,它底层还是使用了本机API通过Jini调用,在javaAPI中得到数据。JPCAP实际上并非一个真正去实现对数据链路层的控制,而是一个中间件,JPCAP调用wincap/libpcap,而给JAVA语言提供一个公共的接口,从而实现了平台无关性。在官方网站上声明,JPCAP支持FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP等系统。jPcap下载地址:http://netresearch.ics.uci.edu/kfujii/jpcap/doc/index.html ; 你可以从jpcap网站上直接下载它的桌面应用程序进行测试,可以全面的统计本机的网络数据流量及收发包数据。 解释: JpcapisaJavaclasspackagethatallowsJavaapplicationstocaptureand/orsendpacketstothenetwork.Jpcapisbasedonlibpcap/winpcapandRawSocketAPI.Therefore,JpcapissupposedtoworkonanyOSonwhichlibpcap/winpcaphasbeenimplemented.Currently,JpcaphasbeentestedonFreeBSD3.x,LinuxRedHat6.1,FedoraCore4,Solaris,andMicrosoftWindows2000/XP.
Jpcapsupportsthefollowingtypesofpackets:Ethernet,IPv4,IPv6,ARP/RARP,TCP,UDP,andICMPv4.Othertypesofpacketsarecapturedasrawpackets(i.e.,instancesofthePacketclass)whichcontainsthewholedataofthepackets.ThisallowsJavaapplicationstoanalyzeunsupportedpackettypes.
本项目中使用的是jPcap0.6版本,从其网站上下载Source build后,可以看到其下详细的目录结构,源码,例程及Native lib。 使用jPcap可以编写出功能完备的网络嗅测程序,本节中,我们只是使用其非常简单的一个功能:统计本机每块网卡上收发数据的总量。特别注意:jpcap运行时依赖winCap的类库,使用前必须在机地安装winCap(/2014th7cj/d/file/p//zdim5p2rb1j )(如果是在liunx上,则请到/2014th7cj/d/file/p//mzomgrav0qf 下载)。本节中jPcap版本为0.6,winCap版本为4.0,运行与win32系统上。 2.jPcap小试:显示本机网络接口详情jPcap中的API非常简单,可查看其在线文档:/2014th7cj/d/file/p/a5f4pcxwqz.html 。当然,要灵活的使用,你必须有良好的tcp/ip协议知识基础,对常用的3个关键类,简介如下: JpcapCaptor类
这个类是jPcap中的核心对象,一个JpcapCaptor对象代表了了系统中的一个网络接口卡;通过对JpcapCaptor对象的调用,实现网络数据包的抓取和发送。它供了一系列静态方法调用如:获取网卡列表,获取某个网卡上的JpcapCaptor对象。
static NetworkInterface[]getDeviceList()
这个静态方法调用,可以返回机器上网络接口卡对象的数组,数组中每一个NetworkInterface元素对象代表一个网络接口;一般使用jPcap所要做的第一步调用就是这个方法。 static JpcapCaptor openDevice(NetworkInterface interface, int snaplen, boolean promisc, int to_ms)取得在指定网卡上的Jpcapcator对象,Interface:上所返回的某个网卡对象Snaplen:一次性要抓取数据包的最大长度。Promisc:设置是否混杂模式。处于混杂模式将接收所有数据包,如果设置为混杂模式后调用了包过滤函数setFilter()将不起任何作用;To_ms:这个参数主要用于processPacket()方法,指定超时的时间; int loopPacket(int count, PacketReceiver handler)常用的一种模式是,通过getDeviceList()取得所有网络接口,再通过openDevice方法取得每个网络接口上的JpcapCaptor对象,就可通过这个方法抓包了。loopPacket方法中count参数表示要抓的包的数目,如果设备为-1,责表示永远抓下去---方法不会返回;第二个参数必须是实现了PacketReceiver接口的一个对象,抓到的包将调用这个PacketReceiver对象中的receivePacket(Packet packet)方法处理;所以抓包前,我们必须写一个实现了PacketReceiver接口的类。 特别注意的是:这个方法的调用会阻塞等待,如果没有抓到指定count的包、或count设为-1,这个方法都不会返回。所以,聪明的你肯定想到了,如果要抓取机器上多个卡口上的包,这个方法必须放在一个独立的线程中。 void breakLoop()即上JpcapCaptor对象上阻塞等待的方法强制终止。当调用processPacket()和loopPacket()后,再调用这个方法可以强制让processPacket()和loopPacket()停止。interface PacketReceiver :
数据包处理器接口定义,要处理收到的数据包,必须编写这个接口的实现类,在JpcapCaptor对象的loopPacket方法中调用.
这个接口中仅有一个方法定义: Void receivePacket (Packet p) 实现类中处理接收到的Packet对象的方法。每个Packet对象代表从热指定网络接口上抓取到的数据包。NetworkInterface类
NetworkInterface类该类的每一个实例代表一个网络设备,一般就是网卡。这个类只有一些数据成员,除了继承自java.lang.Object的基本方法以外,没有定义其它方法。(但我还不知它与jdk5.0以上的API中的java.net.InterfaceAddress类是否可以互换)。
NetworkInterfaceAddress[]addresses这个接口的网络地址。设定为数组应该是考虑到有些设备同时连接多条线路,例如路由器。但我们的PC机的网卡一般只有一条线路,所以我们一般取addresses[0]就够了。 java.lang.String datalink_description. 数据链路层的描述。描述所在的局域网是什么网。例如,以太网(Ethernet)、无线LAN网(wireless LAN)、令牌环网(token ring)等等。 java.lang.String datalink_name datalink_name该网络设备所对应数据链路层的名称。具体来说,例如Ethernet10M、100M、1000M等等。 java.lang.String description 网卡是XXXX牌子XXXX型号之类的描述。例如我的网卡描述:Realtek RTL Family Gigabit Ethernet NIC boolean Loopback 标志这个设备是否loopback设备。 byte[]mac_address 网卡的MAC地址,6个字节。 java.lang.String Name这个设备的名称。例如我的网卡名称:/Device/NPF_{3CE5FDA5-E15D-4F87-B217-255BCB351CD5} jPcap的API使用很简单,如下代码示例:显示机器上的所有网络接口DispalyNetInterface.java:
Java代码importjpcap.JpcapCimportjpcap.NetworkIimportjpcap.PacketRimportjpcap.packet.P/***使用jpcap显示网络接口数据.*/publicclassDispalyNetInterface{publicstaticvoidmain(Stringargs[]){try{//获取本机上的网络接口对象数组finalNetworkInterface[]devices=JpcapCaptor.getDeviceList();for(inti=0;i<devices.i++){NetworkInterfacenc=devices[i];//一块卡上可能有多个地址:Stringaddress="";for(intt=0;t<nc.addresses.t++){address+="|addresses["+t+"]:"+nc.addresses[t].address.toString();}//打印说明:System.out.println("第"+i+"个接口:"+"|name:"+nc.name+"|loopback:"+nc.loopback+"/r/naddress:"+address);}}catch(Exceptionef){ef.printStackTrace();System.out.println("显示网络接口数据失败:"+ef);}}} 不幸的是,这段代码运行时会报如下错误: Exceptioninthread"main"java.lang.UnsatisfiedLinkError:nojpcapinjava.library.pathatjava.lang.ClassLoader.loadLibrary(ClassLoader.java:1682) atjava.lang.Runtime.loadLibrary0(Runtime.java:823)atjava.lang.System.loadLibrary(System.java:1030)atjpcap.JpcapCaptor.(JpcapCaptor.java:250)atcn.netjava.cewolf.DispalyNetInterface.main(DispalyNetInterface.java:19) 还记得我们介绍jPcap: “它底层还是使用了本机API通过Jini调用,在javaAPI中得到数据”,这是因为当前cp中少了jpcap要调用的本地dll库。将jpacp下载后lib下面的jpcap.dll复制到当前项目目录下,如果你仅得制了jpcap.dll,操作系统没有安装wincap(/2014th7cj/d/file/p//zdim5p2rb1jinstall/default.htm ),则会看到如下错误提示:Java代码Exceptioninthread"main"java.lang.UnsatisfiedLinkError:E:/workspace/trafficManager/jpcap.dll:Can'tfinddependentlibrariesatjava.lang.ClassLoader$NativeLibrary.load(NativeMethod)atjava.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)atjava.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)atjava.lang.Runtime.loadLibrary0(Runtime.java:823) atjava.lang.System.loadLibrary(System.java:1030) atjpcap.JpcapCaptor.(JpcapCaptor.java:250)atcn.netjava.cewolf.DispalyNetInterface.main(DispalyNetInterface.java:17)
配置完好后,再次运行,输出结果正常: 第0个接口:|name: /Device/NPF_GenericDialupAdapter|loopback: falseaddress: 第1个接口:|name: /Device/NPF_{2A5FD532-45A3-4A2B-9B68-F34C14E4FD2C}|loopback: falseaddress: |addresses[0]: /220.192.159.105 第2个接口:|name: /Device/NPF_{DB3-4BC9-979E-CBB}|loopback: falseaddress: |addresses[0]: /192.168.1.44在我的机器上,开着一块局网网卡和一块无线网卡,都显示出来了;上面的”第0个接口”就是指本机的127.0.0.1的回环地址。但不知为什么,loopback也会是false? 要注意两点:一个是jpcap.dll要在路径中;另外,在统计流量时,本机回环地址不需要统计,一般是第0个接口。接下来我们看抓取网卡上的数据包是多么简单:抓包前,首先要编写实现了PacketReceiver接口的类,即数据包处理器,由与抓包时,对应某个网络接口的JpcapCaptor对象会阻塞,所以我们将每个网卡上得到的对应的JpcapCaptor对象放到一个独立线程中运行;TestPacketReceiver是个数据包解析器,本例中我们只是简单打印出收到的数据包类型及关键参数,阅读如下代码建议参照jPcap的在线文档(/2014th7cj/d/file/p/a5f4pcxwqz.html) TestPacketReceiver.java代码如下: Java代码importjpcap.JpcapCimportjpcap.NetworkIimportjpcap.PacketRimportjpcap.packet.*;/***使用jpcap显示网络上的各种数据包*/publicclassDispalyNetPacket{//程序启动主方法publicstaticvoidmain(Stringargs[]){try{//获取本机上的网络接口对象数组finalNetworkInterface[]devices=JpcapCaptor.getDeviceList();for(inti=0;i<devices.i++){NetworkInterfacenc=devices[i];//创建某个卡口上的抓取对象,最大为2000个JpcapCaptorjpcap=JpcapCaptor.openDevice(nc,2000,true,20);startCapThread(jpcap);System.out.println("开始抓取第"+i+"个卡口上的数据");}}catch(Exceptionef){ef.printStackTrace();System.out.println("启动失败:"+ef);}}//将每个Captor放到独立线程中运行publicstaticvoidstartCapThread(finalJpcapCaptorjpcap){JpcapCaptorjp=java.lang.Runnablernner=newRunnable(){publicvoidrun(){//使用接包处理器循环抓包jpcap.loopPacket(-1,newTestPacketReceiver());}};newThread(rnner).start();//启动抓包线程}}/***抓包监听器,实现PacketReceiver中的方法:打印出数据包说明*/classTestPacketReceiverimplementsPacketReceiver{/***实现的接包方法:*/publicvoidreceivePacket(Packetpacket){//Tcp包,在javaSocket中只能得到负载数据if(packetinstanceofjpcap.packet.TCPPacket){TCPPacketp=(TCPPacket)Strings="TCPPacket:|dst_ip"+p.dst_ip+":"+p.dst_port+"|src_ip"+p.src_ip+":"+p.src_port+"|len:"+p.System.out.println(s);}//UDP包,开着QQ,你就会看到:它是tcp+udpelseif(packetinstanceofjpcap.packet.UDPPacket){UDPPacketp=(UDPPacket)Strings="UDPPacket:|dst_ip"+p.dst_ip+":"+p.dst_port+"|src_ip"+p.src_ip+":"+p.src_port+"|len:"+p.System.out.println(s);}//如果你要在程序中构造一个ping报文,就要构建ICMPPacket包elseif(packetinstanceofjpcap.packet.ICMPPacket){ICMPPacketp=(ICMPPacket)//ICMP包的路由链Stringrouter_ip="";for(inti=0;i<p.router_ip.i++){router_ip+=""+p.router_ip[i].getHostAddress();}Strings="@@@ICMPPacket:|router_ip"+router_ip+"|redir_ip:"+p.redir_ip+"|mtu:"+p.mtu+"|length:"+p.System.out.println(s);}//是否地址转换协议请求包elseif(packetinstanceofjpcap.packet.ARPPacket){ARPPacketp=(ARPPacket)//Returnsthehardwareaddress(MACaddress)ofthesenderObjectsaa=p.getSenderHardwareAddress();Objecttaa=p.getTargetHardwareAddress();Strings="***ARPPacket:|SenderHardwareAddress"+saa+"|TargetHardwareAddress"+taa+"|len:"+p.System.out.println(s);}//取得链路层数据头:如果你想局网抓包或伪造数据包,嘿嘿DatalinkPacketdatalink=packet.//如果是以太网包if(datalinkinstanceofjpcap.packet.EthernetPacket){EthernetPacketep=(EthernetPacket)Strings="datalinklayerpacket:"+"|DestinationAddress:"+ep.getDestinationAddress()+"|SourceAddress:"+ep.getSourceAddress();System.out.println(s);}}} 运行这段程序,你机器从网络收所有收发到的数据,就都可以展现在你眼前了!,在我的机器上,摘抄一段输出如下:datalinklayerpacket:|DestinationAddress:01:00:5e:00:00:01|SourceAddress:00:19:e0:f0:ee:55
datalinklayerpacket:|DestinationAddress:01:00:5e:26:4c:da|SourceAddress:00:e0:81:03:7c:01TCPPacket:|dst_ip/128.195.10.200:80|src_ip/192.168.1.44:1083|len:62datalinklayerpacket:|DestinationAddress:00:19:e0:f0:ee:55|SourceAddress:00:02:8a:96:d1:ab***ARPPacket:|SenderHardwareAddress00:19:e0:f0:ee:55|TargetHardwareAddress00:00:00:00:00:00|len:60datalinklayerpacket:|DestinationAddress:ff:ff:ff:ff:ff:ff|SourceAddress:00:19:e0:f0:ee:55***ARPPacket:|SenderHardwareAddress00:02:8a:96:d1:ab|TargetHardwareAddress00:19:e0:f0:ee:55|len:42datalinklayerpacket:|DestinationAddress:00:19:e0:f0:ee:55|SourceAddress:00:02:8a:96:d1:abTCPPacket:|dst_ip/192.168.1.44:1083|src_ip/128.195.10.200:80|len:62datalinklayerpacket:|DestinationAddress:00:02:8a:96:d1:ab|SourceAddress:00:19:e0:f0:ee:55
注意:你可能认为要抓取的数据包应分为发送出去的和接收到的;但对jPcap而言,数据包是从网卡上抓取到的一个packet对象,packet没有收发的概念;如果你要确定这个packet的方向,则可根据其中的属性数据值,如源地址、目标地址确认。如果想深入的研究网络协议就请继续钻研吧,我们的任务可仅仅只是统计网络流量,demo了这么多,赶快实现我们的数据统计模块。original address:/blog/165704
最新教程周点击榜
微信扫一扫

我要回帖

更多关于 jpcap 抓包 的文章

 

随机推荐