在工作中经常需要抓包进行分析,我们可以使用各种工具来抓包,比如常用的tcpdump和wireshark。但有时候我们想用程序来进行控制,比如把抓到的包存储到数据库中,以后可以进行查询等等。我在工作中用的是Java,那么就用它来做示范吧。
本教程在centos和ubuntu上测试通过。
1)安装libpcap库
先安装底层使用的库吧,我们用到了libpcap库,tcpdump也是用的这个库,所以先去http://www.tcpdump.org/#old-releases
下载源码进行编译安装,不需要用太新的库吧,因为jpcap挺老的。这里我选了1.1.1版本。
解压,configure,make,make install,完成了。
2)安装jpcap库
我们使用v0.01.16版本,下载为:
http://sourceforge.net/projects/jpcap/files/jpcap/v0.01.16/
我们下载的是源代码版本,虽然有rpm包提供,但却是32位版本的,我们的服务器是64位的,只能自己编译生成了。
解压后编译scripts/env_jpcap文件,配置编译过程中的环境变量,只需要改其中的两项:
# 你解压后的目录
export PROJECT_HOME=~/dev/sourceforge/jpcap
# 生成目录
export RELEASE_HOME=~/dev/releases
# 选填,指定你的JDK目录
#export JAVA_HOME=/usr/java/jdk1.3 ; export PATH=$JAVA_HOME/bin:$PATH
然后让配置生效
. ./scripts/env_jpcap
编译
make clean && make
哈哈,发现出错了:
g++ -Wall -O2 -I/usr/include/pcap -I/usr/local/jdk1.6.0_29/include -I/usr/local/jdk1.6.0_29/include/linux jpcap.c process.cpp -fPIC -shared -o libjpcap.so -lnsl /usr/lib/libpcap.a
g++: /usr/lib/libpcap.a: No such file or directory
说是没有libpcap.a,我们刚才不是安装好了吗!!find一下发现原来在/usr/local/lib目录中。拷贝过去就好了:
sudo cp /usr/local/lib/libpcap.a /usr/lib
OK,继续。
恭喜,又报错了:
jpcap.c:678: error: lvalue required as left operand of assignment
因为这个版本的jpcap是2004年的,我们的机器的gcc版本是4.4.6,也许gcc的版本太新了吧。可以考虑安装多个版本的gcc,但这里直接把代码改改就好:
vi capture/jpcap.c
定位到678行,进行修改:
// for(;ifr < last; (char*)ifr += ifrSize) {
for(;ifr < last; ifr = (ifreq*)((char*)ifr + ifrSize)) {
OK,继续。
没有报错,完成了,再执行:
make release
就可以在之前配置的RELEASE_HOME目录下发现编译好的文件了:
javadoc_net.sourceforge.jpcap-0.01.16.jar
net.sourceforge.jpcap-0.01.16.jar
解压后者,发现libjpcap.so也在里面,需要把这个库也安装到合适的地方,你可以把库放到下面代码打印的任意一个目录中:
System.out.println(System.getProperty("java.library.path"));
下面就开始写Java代码了,需要引入3个Jar包,分别是前面生成的net.sourceforge.jpcap-0.01.16.jar,还有之前下载的jpcap-0.01.16/thirdParty/jars目录下的包。
net.sourceforge.jpcap-0.01.16.jar中其实就包含了很多例子程序,如图所示:
例子就不写了,附上java doc文档地址:
http://jpcap.sourceforge.net/javadoc/index.html
使用过程需要注意2个地方:
1,必须使用root权限执行,因为要使网卡进入混杂模式必须要有root权限,不过不使用root会报这样的错误:
Exception in thread "main" net.sourceforge.jpcap.capture.CaptureDeviceNotFoundException: no suitable device found
2,如果你发现抓到的tcp的data的数据跟实际发送的数据少了一段,那么在代码中需要注意要这样使用:
Instead of pcap.open(device, true); try pcap.open(device, 65535, true, 1000);
原因参考:
http://stackoverflow.com/questions/17906635/get-full-tcp-packet-data-using-jpcap