当前位置:文档之家› jpcap教程

jpcap教程

jpcap教程
jpcap教程

3获取网络接口设备[网卡设备]

想要捕捉网络数据包,首先要得到你电脑了的网络接口设备,也就是所谓的网卡设备.Jpcap包向我们提供了这一个类方法[静态方

法]:JpcapCaptor.getDeviceList( ) ,从字面见就知道返回的是网络接口设备的列表,NetworkInterface类,网络接口类。其封装了相应网络设口信息,比如:网卡名,网卡描述,网卡所处的数据链路层的名称,描述等等。

简单的应用代码如下:

/**

* @(#)GetDevices.java

* 显示网络接口设备信息的Demo

* @author scholar_ii

* @version 1.00 2005/12/16

*/

import jpcap.*;

public class GetDevices

{

public GetDevices()

{

}

public static void ShowNeworkInterfaceDevices()

{

//获得网卡设备的实例列表

NetworkInterface[] devices = JpcapCaptor.getDeviceList();

//循环输出全部网卡设备对象相应的信息

for (int i = 0; i < devices.length; 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.print(" MAC address:");

for (byte b : devices[i].mac_address)//JDK1.5以上版本的for语法的加强变种[循环遍历]

&nbs

欢迎光临学网,收藏本篇文章[1] [2]

$False$

p; //转化为十六进制的字串符表示

System.out.print(Integer.toHexString(b&0xff) + ":");

System.out.println(); //print out its IP address, subnet mask and broadcast address //输出网卡IP地址IPV4 IPV6 子网地址扩播地址

for (NetworkInterfaceAddress a : devices[i].addresses)

System.out.println(" address:"+a.address + " " + a.subnet + " "+ a.broadcast);} }

public static void main(String[] args) {

ShowNeworkInterfaceDevices();

}

}

可能的运行结果如下(WindowsXP下):

0: \Device\NPF_GenericDialupAdapter(Adapter for generic dialup and VPN capture)

datalink: EN10MB(Ethernet)

MAC address:0:0:0:0:0:0:

1: \Device\NPF_{B7CE211D-CEA5-4010-9A39-B833BBEC772D}(Realtek RTL8139/810x Family Fast Ethernet NIC (Microsoft''s Packet Scheduler) )

datalink: EN10MB(Ethernet)

MAC address:0:e0:4c:87:a0:5a:

address:/192.168.1.102 /255.255.255.0 /255.255.255.255

注意:0号网卡是一个操作系统的虚拟网卡(有时在上面代码前有图形界面代码如JFrame 之类的代码)可能0号网卡得不到,我的实验结果是这样的在2000下不管怎样都可以得到0与网卡,XP下有图形代码的影响就得不到了。

4 打开网络接口设备

当你得到网络接口设备列表后,你所要做的事就是打开一个网络接口设备.得到一个捕获者的实例,JpcapCaptor类的实例.如下的代码就是实现上述目的.

NetworkInterface[] devices = JpcapCaptor.openDeviceList();//获得网卡设备列表

int index = number;//设置你想要打算的网卡设备

//打开一个网络接口设备,得到一个JpcapCaptor实例

JpcapCaptor captor =

JpcapCaptor.openDevice(devices[index],65535,false,20);

openDevice方法的参数解释如下:

第一个参数类型:NetworkInterface 解释:你想要打开的网卡设备实例

第二个参数类型int 解释:一次捕捉数包的最大的字节

第三个参数类型boolean 解释:是否设置网卡为混乱模式

第四个参数类型int 解释:捕捉包的超时时间

注:JpcapCaptor实例的功能就是捕捉包.发送包并不是它的责任

5如何使用JpcapCaptor实例来捕捉网络数据包

当你通过打开网卡设备得到JpcapCaptor实例后,就可以利用它来捕捉网络数据包了。你可以利用以下两种方法来捕捉网络数据包。第一种是通过回调函数的机制,另一种是利用JpcapCaptor实例的getPacket()的方法,一个数据包一个数据包的接收。第一种是类似与

事件触发的机制。

方法一:回调函数机制。

首先,你要自定义一个类,该类必顺实现PacketReceiver接口,(在事件处理机制雷同)。PacketReciver接口只声名了receivePacket(Packet packet) 方法,所以你要在你自义的类中实现该方法,方法体里放置你处理接收到的数据包的代码,得到的数据

包为型参packet.

接着,你就可以通过调用JpcapCaptor类的实例的processPacket()或loopPacket()来开始接收数据包。开始接收数据包后,当接收到数据包时就会回调实现PacketReceiver接口的类的receivePacket的方法,使理接收到的数据包。

public int processPacket(int n , PacketRecevier handler);

参数1 类型int 解释:一次接收包的个数(个数

到时到产生回调)

参数2 类型PacketRecevier 解释:(回调者)事件临听者

返回值:捕捉到的数据包的个数

功能:捕捉自定义个数的网络数据包。与loopPacket()方法不同,当接收超时(这个由前面的openDevice()方法的最后一个接收超时参数所决定)该方法立即返回。同样的在非阻塞模式下是,没有数据

所可接收,该方法也立即返回。

public int loopPacket(int n, PacketRecevier handler):

参数1 类型int 解释:一次接收包的个数(个数

到时到产生回调)

如下为一个简单的demo:

/**

* @(#)GetPacketDemo.java

*

* 演示利用回调机制来捕捉网络数据包

* @author scholar_ii

* @version 1.00 2007/12/17 *

import jpcap.*;

import jpcap.packet.*;

public class GetPacketDemo

{

public static void main(String [] args) throws Exception

{

NetworkInterface[] devices = JpcapCaptor.getDeviceList();

int index = 0;

if(devices.length>1)/*去掉虚拟网卡的处理*/

index = 1;

JpcapCaptor captor = JpcapCaptor.openDevice(devices[index], 65535, false, 20);

captor.loopPacket(-1, new Receiver());

}

}

class Receiver implements PacketReceiver

{

/*实例receivePacket方法*/

public void receivePacket(Packet packet)

{

/*进行简单的处理*/

System.out.println(packet);

}

}

参数2 类型PacketRecevier 解释:(回调者)事件临听者

返回值:捕捉到的数据包的个数

功能:捉自定义个数的网络数据包。与processPacket()方法不同,该方法忽

视超时,不支持工作在非阻塞模式。

注意:在这两个方法的第一个参数中,你可以设定其值为-1。这时你可以停的捕捉数据包,直到捕捉结束,或错误发生为止

主要程序如下:

public class ARPMsg implements Runnable {

static JpcapCaptor captor;

static NetworkInterface[] devices;

static BufferedReader in = new BufferedReader(new InputStreamReader(

System.in));

static int i = 0;

static String str;

static IPPacket p;

static IPPacket ip;

static boolean bl = true;

public static void main(String[] args) {

System.out.println(".....ARP ....");

nic();

try {

captor = JpcapCaptor.openDevice(devices[i], 65535, false, 2000); //创建一个与指定设备的连接并返回该连接

captor.setFilter("arp", true); //过滤得到需要的ARP 包

} catch (IOException e) {

System.out.println(e.getMessage());

}

Runnable runnable = new ARPMsg();

Thread thread = new Thread(runnable); //开启一个子线程监听ARP报文

thread.setName("thread1");

thread.setPriority(6);

thread.start();

Scanner s = new Scanner(System.in); //在main线程中,,输入"exit"用于停止监听

String input = s.next();

if (input.equals("exit"))

System.exit(0); //normal exit

}

public void run() { //子线程thread1运行时调用的方法

while (bl) {

captor.processPacket(1, handler); //监听并捕获ARP包 }

}

public static int nic() {

devices = JpcapCaptor.getDeviceList(); //返回一个网络设备列表

for (int i = 0; i < devices.length; i++) { //打印可选设备的网卡信息

System.out.println(i + ". > " + "NIO_gen_eth: " + devices[i].name); for (NetworkInterfaceAddress a : devices[i].addresses) {

System.out.println(" IP address:" + a.address);

}

}

System.out.print("> Choose the NIC you want to use: ");

try {

str = in.readLine(); //输入数字并选择网卡 } catch (IOException e) {

System.out.println(e.getMessage());

}

i = Integer.parseInt(str);

return i;

}

private static PacketReceiver handler = new PacketReceiver() {

public void receivePacket(Packet packet) { //匿名类,每捕获一个包就调用此方法

System.out.println("===================================");

if(Short.valueOf(ARPPacket.ARP_REQUEST).equals(((ARPPacket) packet) .opration))

{

System.out.println("This is arp request message");

}

if(Short.valueOf(ARPPacket.ARP_REPLY).equals(((ARPPacket) packet).o peration))

{

System.out.println("This is arp reply message");

}

System.out.println("硬件类型" + ((ARPPacket) packet).hardtype);

System.out.println("操作类型" + ((ARPPacket) packet).operation); System.out.println("源MAC地址

" + ((ARPPacket) packet).getSenderHardwareAddress());

System.out.println("源IP地

址" + ((ARPPacket) packet).getSenderProtocolAddress());

System.out.println("目标MAC地

址" + ((ARPPacket) packet).getTargetHardwareAddress());

System.out.println("目标IP地

址" + ((ARPPacket) packet).getTargetProtocolAddress());

System.out.println("===================================");

}

};

}

本程序采用多线程的实现对ARP数据包进行监听并捕获,首先

JpcapCaptor.getDeviceList()获得可用的设备,并输出以供用户选择,当用户选择并输入可用的设备号后,JpcapCaptor.openDevice()创建一个与所选设备的连接,false参数表示启用混杂模式,captor.setFilter("arp",true)过滤得到ARP数据包,这时开启一个叫做JARP的

子线程,运行captor.processPacket(1, handler)方法用于捕获ARP数据包,一旦ARP数据包出现,交由PacketReceiver接口的唯一实现方法receivePacket()来处理。与此同时,在另外一个main线程中,通过new Scanner(System.in)来指定当输入字符"exit"时,程序退出。之所以在main线程而不是在子线程来指定输入的字符"exit",是因为System.in是一个阻塞函数,若在子线程中会阻断子线程监听捕获ARP数据包。

相关主题
文本预览
相关文档 最新文档