[译]Jpcap 教程

Jpcap 教程

1.0 (for Jpcap 0.7)

Author:
    Keita Fujii (kfujii@uci.edu)
Home page:
    http://netresearch.ics.uci.edu/kfujii/jpcap/doc/index.html


目录


介绍

这个文档将会描述如何使用Jpcap开发应用。它会解释 Jpcap中定义的方法和类,当然也会通过展示一些例子来完整的描述怎样去使用Jpcap开发.

这个文档的最新版本可以在这里找到: http://netresearch.ics.uci.edu/kfujii/jpcap/doc/tutorial/index.html

什么是Jpcap

Jpcap是用JAVA捕获和发送数据包的一个开源库。它提供了许多便利:

  • 从线缆中实时捕获原始数据包. 
  • 将捕获的数据包保存为离线文件,并且可以从离线保存的文件中读取数据包.
  • 自动识别数据包类型,并生成相应的Java对象 (for Ethernet, IPv4, IPv6, ARP/RARP, TCP,UDP, and ICMPv4 packets).
  • 在数据包分发到应用之前,据用户指定的规则过滤数据包.
  • 发送原始数据包到网络

jpcap是基于 libpcap/winpcap的, 可以用于在C和Java中实现.

Jpcap 已经在下系统中测试通过:
Microsoft Windows (98/2000/XP/Vista), Linux (Fedora, Ubuntu), Mac OS X (Darwin), FreeBSD, and Solaris.

什么样的应用程序可以使用JPCAP进行开发

JPCAP可用于开发多种网络应用程序,包括(但不限于):

  • 网络和协议分析器
  • 网络监控
  • 流量日志
  • 流量生成器
  • 用户级网桥和路由器
  • 网络入侵检测系统 (NIDS)
  • 网络扫描仪
  • 安全工具

什么是JPCAP不能做的

jpcap的捕获和发送数据包是独立于主机协议的(如TCP / IP)。这意味着,JPCAP不会(也不能)去阻塞、过滤或操纵同一台机器上的其他程序产生的流量:它只是“嗅探”传输在线路上的数据包。因此,它并没有提供如traffic shapers,QoS调度和个人防火墙应用适当的支持.


jpcap的教程:一步步指导使用JPCAP

获得网络接口列表

当你想要从网络中捕获数据包,你首先要做的就是取得你的机器上的网络接口列表.要做到这一点,JPCAP提供 JpcapCaptor.getDeviceList()方法。它返回的NetworkInterface NetworkInterface对象的数组.

一个 NetworkInterface对象包含有关相应的网络接口, 如它的名称,描述,IP和MAC地址,以及datatlink名称和描述的一些信息.

下面的示例代码会获取网络接口列表,并打印出他们的信息.

//获得网络接口列表
NetworkInterface[] devices = JpcapCaptor.getDeviceList();

//遍历网络接口
for (int i = 0; i < devices.length; i++) {
//打印它的名称和描述
System.out.println(i+": "+devices[i].name + "(" + devices[i].description+")");

//打印它的datalink的名称和描述
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)
System.out.print(Integer.toHexString(b&0xff) + ":");
System.out.println();

//打印它的IP地址、子网掩码和广播地址
for (NetworkInterfaceAddress a : devices[i].addresses)
System.out.println(" address:"+a.address + " " + a.subnet + " "+ a.broadcast);
}

此示例代码可能会出现这样的结果如下(在Windows上):

0: \Device\NPF_{C3F5996D-FB82-4311-A205-25B7761897B9}(VMware Virtual Ethernet Adapter)
    data link:EN10MB(Ethernet)
    MAC address:0:50:56:c0:0:1:
    address:/fe80:0:0:0:3451:e274:322a:fd9f null null
    address:/172.16.160.1 /255.255.255.0 /255.255.255.255

或者以下 (on Linux/UNIX):

0 : eth0(null)
    datalink: EN10MB(Ethernet)
MAC address:0:c:29:fb:6c:df:
address:/172.16.32.129 /255.255.255.0 / 172.16.32.255

打开一个网络接口

一旦你获了网络接口列表,并选择了从哪个网络接口来获取数据包,您可以通过使用
using JpcapCaptor.openDevice()方法打开该接口。下面这段代码演示了如何打开一个网络接口.

NetworkInterface[] devices = JpcapCaptor.getDeviceList();
int index=...; // 设置您要打开的接口索引.

//Open an interface with openDevice(NetworkInterface intrface, int snaplen, boolean promics, int to_ms)
JpcapCaptor captor=JpcapCaptor.openDevice(device[index], 65535, false, 20);

当调用 JpcapCaptor.openDevice()方法时,你可以指定以下参数:
 

Name: Purpose
NetworkInterface intrface 你要打开的网络接口.
int snaplen 一次最多获取bytes.
boolean promics 如果你想在混杂模式(promiscuous mode)下打开网络接口, 否则选择false.

在混杂模式下,你可以从电线中获取每一个数据包,也就是说,即使它的源或目的MAC地址是和你打开的网络接口MAC地址不是一样的.
In在非混杂模式下,您只能捕获你自己主机发送和接收的数据包发.
int to_ms 以毫秒为单位设置一个捕获超时值.

JpcapCaptor.openDevice() 返回JpcapCaptorJpcapCaptor.的一个实例。然后,您可以调用  JpcapCaptor类的几种方法从网络接口捕获数据包.

从网络接口捕获数据包

一旦你获得 JpcapCaptor,的一个实例,就可以从接口捕获数据包.

这里有两种主要的方法使用 JpcapCaptor实例来捕获数据包:使用回调方法,或者一个接一个的捕获数据包.

使用回调方法

在这种方法中,您将实现一个回调方法来处理捕获的数据包,然后将回调方法传递给JPCAP,以便JPCAP每次捕获数据包的时候回调它。让我们来看看做到这一点的方法的细节.

首先,通过定义一个新的class来实现一个回调,它实现了 PacketReceiver接口。该 PacketReceiver接口定义了一个  a receivePacket()方法,所以你需要在类中实现receivePacket()方法.

下面的类实现了 receivePacket()方法 ,该方法简单地打印出所捕获的数据包.

class PacketPrinter implements PacketReceiver {
//这个方法在Jpcap捕获到数据包时都会被调用到
public void receivePacket(Packet packet) {
//仅仅打印出捕获的数据包
System.out.println(packet);
}
}

然后,您可以调用 JpcapCaptor.processPacket()JpcapCaptor.loopPacket() 使用回调方法来启动捕获. 当调用 processPacket() 或 loopPacket()方法, 你也可以指定方法返回之前捕获数据包的数量. 您可以指定-1,无限捕获数据包.

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

//call processPacket() to let Jpcap call PacketPrinter.receivePacket() for every packet capture.
captor.processPacket(10,new PacketPrinter());

captor.close();

The two methods for callback, processPacket() and loopPacket(), are very similar. Usually you might want to use processPacket() because it supports timeout and non_blocking mode, while loopPacket() doesn’t.

Capturing
packets one-by-one

Using
a callback method is a little bit tricky because you don’t know when
the callback method is called by Jpcap. If you don’t want to use a
callback method, you can also capture packets using the JpcapCaptor.getPacket() method.

getPacket() method simply returns a captured packet. You can (or have to) call getPacket() method multiple times to capture consecutive packets.

The following sample code also prints out captured packets.

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

for(int i=0;i<10;i++){
//capture a single packet and print it out
System.out.println(captor.getPacket());
}

captor.close();

Set capturing filter

In Jpcap, you can set a
filter so that Jpcap doesn’t capture unwanted packets. For example, if
you only want to capture TCP/IPv4 packets, you can set a filter as
following:

JpcapCaptor captor=JpcapCaptor.openDevice(device[index], 65535, false, 20);
//set a filter to only capture TCP/IPv4 packets
captor.setFilter("ip and tcp", true);

The
filter expression “ip and tcp” means to to “keep only the packets that
are both IPv4 and TCP and deliver them to the application”.

By
properly setting a filter, you can reduce the number of packets to
examine, and thus can improve the performance of your application.

You can check the following homepage for more details about filter expression.

Designing
Capture Filters for Ethereal/Wireshark

Save captured packets
into a file

You
can save captured packets into a binary file so that you can later
retrieve them using Jpcap or other applications which supports reading
a tcpdump format file.

To save captured packets, you first need to open a file by calling JpcapWriter.openDumpFile() method with an instance of JpcapCaptor which was used to capture packets, and a String filename.

JpcapCaptor captor=JpcapCaptor.openDevice(device[index], 65535, false, 20);
//open a file to save captured packets
JpcapWriter writer=JpcapWriter.openDumpFile(captor,"yourfilename");

Once you obtained an instance of JpcapWriter through openDumpFile() method, you can save captured packets using JpcapWriter.writePacket() method. After you saved all the packets you want to save, you need to call JpcapWriter.close() method to close the opened file.

The following sample code, combined with the above code, captures and saves first 100 packets captured.

for(int i=0;i<10;i++){
//capture a single packet
Packet packet=captor.getPacket();
//save it into the opened file
writer.writePacket(packet);
}
writer.close();

Read saved packets from
a file

In Jpcap, you can read the packets you saved using JpcapWriter by opening the file using JpcapCaptor.openFile() method. Similar to JpcapCaptor.openDevice() method, JpcapCaptor.openFile() method also returns an instance of JpcapCaptor class. So you can use the same ways described in Capture packets from the
network interface
section to read packets from the file. For example, you can read and print out saved packets from a file as follows:

//open a file to read saved packets
JpcapCaptor captor=JpcapCaptor.openFile("yourfilename");

while(true){
//read a packet from the opened file
Packet packet=captor.getPacket();
//if some error occurred or EOF has reached, break the loop
if(packet==null || packet==Packet.EOF) break;
//otherwise, print out the packet
System.out.println(packet);
}

captor.close();

Send packets through a
network interface

You can also send packets to the network using Jpcap.  To send a packet, you need to obtain an instance of JpcapSender by calling either JpcapSender.openDevice() or JpcapCaptor.getJpcapSenderInstance() methods.

Once you obtain an instance of JpcapSender, you can pass an instance of Packet class to JpcapSender.sendPacket() method.

The following sample code sends a TCP/IPv4/Ethernet packet onto a network interface.

//open a network interface to send a packet to
JpcapSender sender=JpcapSender.openDevice(devices[index]);

//create a TCP packet with specified port numbers, flags, and other parameters
TCPPacket p=new TCPPacket(12,34,56,78,false,false,false,false,true,true,true,true,10,10);

//specify IPv4 header parameters
p.setIPv4Parameter(0,false,false,false,0,false,false,false,0,1010101,100,IPPacket.IPPROTO_TCP,
InetAddress.getByName("www.microsoft.com"),InetAddress.getByName("www.google.com"));

//set the data field of the packet
p.data=("data").getBytes();

//create an Ethernet packet (frame)
EthernetPacket ether=new EthernetPacket();
//set frame type as IP
ether.frametype=EthernetPacket.ETHERTYPE_IP;
//set source and destination MAC addresses
ether.src_mac=new byte[]{(byte)0,(byte)1,(byte)2,(byte)3,(byte)4,(byte)5};
ether.dst_mac=new byte[]{(byte)0,(byte)6,(byte)7,(byte)8,(byte)9,(byte)10};

//set the datalink frame of the packet p as ether
p.datalink=ether;

//send the packet p
sender.sendPacket(p);

sender.close();


Jpcap documentation.
Copyright (c) 2007 Keita Fujii. All rights reserved.

centos下安装apache和mysql的一些问题记录

一.安装apache2

1.报错:

error: no acceptable C compiler found in $PATH

原因未安装GCC
解决:

yum install gcc

2.报错

Error: Cannot find a valid baseurl for repo: addons

原因dns未设置
解决:

vi /etc/resolv.conf

添加

nameserver 8.8.8.8

保存
继续

yum install gcc

3.安装完成无法访问

curl http://127.0.0.1

可以看到源码

可以暂时关闭

/etc/init.d/iptables stop

或者:

#/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
#/etc/rc.d/init.d/iptables save

二.安装mysql

1.报错:

error: No curses/termcap library found

缺少ncurses安装包
解决:

yum list|grep ncurses
yum -y install ncurses-devel
yum install ncurses-devel

2.报错:

make exec: g++: not found
yum install -y gcc-c++
error: redeclaration of C++ built-in type ‘bool’

是因为gcc-c++是在configure之后安装的,此时只需重新configure后再编译make即可。
重新./configure