在Ubuntu 14.04 64位上使用libpcap进行抓包和解包

为了开发需要,我决定使用最新libpcap源码包安装。在Unix环境下安装libpcap库,需要
c编译器,flex,bison等,安装Ubuntu系统时,没有这些包。安装flex需要m4编译环境,否则会提示“GNU M4 is required”错误。

1.安装系统依赖包
sudo apt-get install gcc libc6-dev
sudo apt-get install m4
sudo apt-get install flex bison

2.下载libpcap源码并安装
从官网http://www.tcpdump.org/下载最新的libpcap版本
cd /usr/local/src
wget http://www.tcpdump.org/release/libpcap-1.5.3.tar.gz
tar zxvf libpcap-1.5.3.tar.gz
cd libpcap-1.5.3
./configure
make
sudo make install

3.安装开发需要用到的依赖库
sudo apt-get install libpcap-dev

4.测试libpcap的小程序,命名为pcap_demo.c,以检验环境是否配置正确
#include <pcap.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
pcap_t *handle; /* Session handle */
char *dev; /* The device to sniff on */
char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
struct bpf_program fp; /* The compiled filter */
char filter_exp[] = "port 80"; /* The filter expression */
bpf_u_int32 mask; /* Our netmask */
bpf_u_int32 net; /* Our IP */
struct pcap_pkthdr header; /* The header that pcap gives us */
const u_char *packet; /* The actual packet */

/* Define the device */
dev = pcap_lookupdev(errbuf);
if (dev == NULL) {
fprintf(stderr, "Couldn‘t find default device: %s\n", errbuf);
return(2);
}
/* Find the properties for the device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn‘t get netmask for device %s: %s\n", dev, errbuf);
net = 0;
mask = 0;
}
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn‘t open device %s: %s\n", dev, errbuf);
return(2);
}
/* Compile and apply the filter */
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn‘t parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
return(2);
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn‘t install filter %s: %s\n", filter_exp, pcap_geterr(handle));
return(2);
}
/* Grab a packet */
packet = pcap_next(handle, &header);
/* Print its length */
printf("Jacked a packet with length of [%d]\n", header.len);
/* And close the session */
pcap_close(handle);
return(0);
}
开始编译:
gcc -g pcap_demo.c -o pcap_demo -lpcap 
开始执行
./pcap_demo

5.注意的问题
5.1.注意使用root用户来执行,或者对普通用户使用sudo来提升权限
sudo pcap_demo 
5.2.对一些PCAP API函数要有全面地理解,并时刻更新文档,比如pcap_loop这个函数,下面是官网的man page地址 
http://www.tcpdump.org/manpages/pcap.3pcap.html
5.3,对一些函数的理解:
pcap_loop和pcap_dispatch的区别,前者不会超时返回,而是会尽量去读取更多的包,直至发生一个错误才返回。正常返回的值是0,否则就是负值。我目前需要连续不断地抓包,所以应该使用pcap_loop。pcap_dispatch内部会调用pcap_loop。pcap_loop中的第四个参数在某些应用中很有用,但是在通常情况下被设为NULL。这种定义很有用,比如假如你想给pcap_loop的回调函数再额外传递一些参数,你可以使用u_char类型的指针(字符串),传人到回调函数中再做具体地处理。pcap_dispatch只会处理它收到的第一批包。
从pcap_loop返回后,我们应该显式调用pcap_close来关闭pcap以便释放资源。为了表示连续不间断的抓包,在pcap_loop中要尽量使用-1而不是0.关于其中回调函数的说明,里面有3个参数。第一个参数user是pcap_loop中最后一个参数,它表示某个不太重要的信息,可以忽略,第二个参数是包头信息,含有包的时间戳和长度,第三个参数是包的数据,从链路层头开始,它在该回调函数中并不会被释放,但是当该回调返回时不包装这些数据再合法,所以要再次使用它们,请事先复制出来。

下面再深入研究一下pcap_loop这个回调函数的定义:
首先注意函数的返回值是void类型,这完全符合逻辑,因为pcap_loop根本不知道如何处理回调函数的返回值,就是给他传出返回值也没有意义。然后就是回调函数的第一个参数对应pcap_loop中的最后一个参数,不管你给pcap_loop的最后一个参数传递什么值,当回调函数被调用时,它都会作为第一个参数传递给回调函数,第二个参数是pcap头,它包含一些信息:抓包时间,包多大,等等,这个结构在pcap.h中定义,如下
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};

抓包方式有两种,一种是每次抓一个包,另一种是循环抓包,分为循环抓有限个数的包,或者是无限循环抓包。其中每次抓一个包使用pcap_next函数。pcap_next()表示只抓取一个数据包,它的第一个参数是session handle,第二个参数是包头,返回值是包数据。函数原型如下
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
另一种循环抓包的方法,就是使用pcap_loop和回调函数,代码样例参见我整理出的两个例子。

5.4.网卡设备的设置有两种方法,第一种方法是用户直接指定网卡名称(必须要真实可用),从命令行参数传递进去,比如
#include <stdio.h>
#include <pcap.h>

int main(int argc, char *argv[])
{
char *dev = argv[1];

printf("Device: %s\n", dev);
return(0);
}
另一种方法,是让pcap自己去探测网卡设备,如果出错,会给出出错信息,但是这种方法很多情况下不靠谱,对此的改进是,让pcap探测出所有的网卡设备,让用户区选择使用那个网络设备抓包,参见下面的代码
#include <stdio.h>
#include <pcap.h>

int main(int argc, char *argv[])
{
char *dev, errbuf[PCAP_ERRBUF_SIZE];

dev = pcap_lookupdev(errbuf);
if (dev == NULL) {
fprintf(stderr, "Couldn‘t find default device: %s\n", errbuf);
return(2);
}
printf("Device: %s\n", dev);
return(0);
}

5.5.对我们抓到的数据包,它的结构,大体分为Ethernet header,IP header,TCP header等等,分别对应14,20,20个字节,IP header至少20个字节,TCP头也至少20个字节。
data=recv_data[42:]这样做的原因是,recv_data 抓到的都是raw packet, tcp/ip是分了5层,一个udp包,会带有 14Bytes的Ethenet_II Frame的头,然后是20个字节的ip包头,而udp包头有8个字节,所以偏移量42之后的才是udp的实际内容
tcp包的包头大小为20Bytes,所以其实际内容在偏移量54之后

5.6.对数据包的解包和组包,需要用到Ethernet header,IP header,TCP header,UDP header等常用数据结构的定义,我们并不需要重新定义这些头,直接引用相关的头文件定义就可以了。
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>

5.6.对我们目前的程序,通常需要从命令行传人如下参数信息:
wlan0 待抓包的网卡名称
tcp port 80 过滤表达式
10000 or -1 抓包模式,是抓指定个数的包(这里是10000个包),还是无限抓包下去
当然,对这些参数,你也可以写死在程序里。

参考文献
[1].http://www.tcpdump.org/pcap.html

时间: 2024-10-08 23:43:15

在Ubuntu 14.04 64位上使用libpcap进行抓包和解包的相关文章

Ubuntu 14.04 64位上安装wps office软件(转http://m.blog.csdn.net/blog/yhc13429826359/24179933)

废话少说,只给出方法供各位参考!wps for Linux版本已经有两三年没有大的动作,当然其他平台,比如windows,Android,ios上的wps效果还是很赞的说. 下面是我成功安装的步骤: 1.去官网下载alpha版本,千万不要下载beta版本,否则安装上去但是无法打开: http://community.wps.cn/download/ 我选择安装成功的是a12p4_i386.deb 包,wps目前只有32位版本,没有64位版本. 2.安装ia-32libs安装包,目的就是在64位系

ubuntu 14.04 64位使用google官方android开发集成工具adt-64位无法使用adb

在使用ubuntu64位(14.04)时,下载来一个adt-bundle-linux-x86_64-20131030.zip,但是运行时报错: Android: Gradle: Execution failed for task Cannot run program android-studio/sdk/build-tools/android-4.2.2/aapt error=2, 没有那个文件或目录 使用aapt编译资源时报错, 提示找不到aapt这个命令, 可是在sdk中命名存在这个可执行文

ubuntu 14.04 64位安装iNodeClient

ubuntu 14.04 64位安装iNodeClieng(华三校园客服端) http://pan.baidu.com/s/12dpxk ubuntu 14.04 64bit Install H3C iNodeClient. http://pan.baidu.com/s/12dpxk

Ubuntu 12.04(64位)上搭建android 开发环境 (ADT 、android-studio)

1. ubuntu 12.04  64位 2. 下载: 1) Oracel JDK :http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 2) ADT bundle  :http://developer.android.com/sdk/index.html 3)android -studio : http://developer.android.com/sdk/installing

ubuntu 14.04 64位安装bigbluebutton

BigBlueButton 是一个使用 ActionScript 开发的在线视频会议系统或者是远程教育系统,主要功能包括在线PPT演示.视频交流和语音交流,还可以进行文字交流.举手发言等功能,特别适合用在网上教学,支持中文等多种语音. 官方首页 http://bigbluebutton.org/ 官方demo http://demo.bigbluebutton.org/ 现在BigBlueButton 1.0-beta 已经发布,这篇文章主要介绍0.9的安装 官方也有安装教程一样很详细,虽然是英

Ubuntu 14.04 64位配置Caffe 教程(基于CUDA 7.5)

深度学习是研究计算机视觉的重要工具,尤其在图像分类与识别等领域有着划时代的意义.现在有很多深度学习框架,Caffe是比较常用的一个.本文讲述了Ubuntu 14.04(64位)系统下配置Caffe的基本步骤,参考了Caffe的官方网站   http://caffe.berkeleyvision.org/. 一.系统环境配置 1.1 首先安装一般会用到的一些依赖项.打开Ubuntu系统的终端,输入以下命令: sudo apt-get install libprotobuf-dev liblevel

Ubuntu 14.04 64位版安装 QQ国际版实测可用

注:QQ国际版for Ubuntu 下载链接:http://www.ubuntukylin.com/applications/showimg.php?lang=cn&id=23 64位系统下一般需要安装ia32-libs, 在14.04版本中提示该软件已被其它版本替代,可以根据提示sudo apt-get install lib32z1,lib32ncurses5以及 lib32bz2-1.0同上. 下载后 执行 sudo unzip wine-qqintl.zip, 然后 cd wine-qq

腾讯云搭建服务器(ubuntu 14.04 64位)

首先得有64元优惠券,然后选择对应服务器购买即可,此处无需多虑.全选最便宜的.最后需要支付65元,64元抵用券.1元购买. 服务器默认账户名ubuntu ,密码在购买服务器时设置. 这个公网ip可以连接xftp和xshell用. 连接上xshell执行命令 sudo apt-get install apache2 输入y 安装成功通过外网ip即可访问. 注意:.需要配置服务器安全组,开放这些端口. 域名的解析: 单击解析: 出现该页面 中间两个是默认. 记录类型A两个是自己手动添加的.  主机记

Ubuntu 14.04 64位机上不带CUDA支持的Caffe

Caffe是一个高效的深度学习框架.它既可以在CPU上执行也可以在GPU上执行. 下面介绍在Ubuntu上不带CUDA的Caffe配置编译过程: 1.      安装BLAS:$ sudo apt-get install libatlas-base-dev 2.      安 装依赖项:$ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5