要包含文件pcap.h
1.获取设备名
使用
char * pcap_lookupdev ( char * errbuf );
来获取设备名,例如返回"eth0",errbuf是出错信息字符串,一旦函数出错,其中将会包括出错信息
errbuf一般定义为
char errbuf[PCAP_ERRBUF_SIZE];
2.获取设备描述符
就像对文件操作时要取得文件描述符一样,在这里要取得网卡的描述符
pcap_t * pcap_open_live ( char * device, int snaplen, int promisc,
int to_ms, char * errbuf );
pcap_t就是网卡描述符的类型,
device是设备名,如eth0
snaplen是要抓获的最大的包的字节数
promisc如果为非0的话,则将网卡设为混杂模式
to_ms是超时时间,如果为0则永不超时
errbuf与上同
如果pcap_open_live返回NULL,则表明函数执行出错,errbuf的值将会被设置
3.循环处理包
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
pcap_loop会一直读取包,直到读完cnt个数据包
当cnt为负时,pcap_loop会永远循环运行
对于每一个包,pcap_loop会一直尝试读取,直到pcap_open_live中设置的to_ms时间达到时仍未成功读取包.
callback是一个回调函数,当抓取到一个包时,就会调用这个callback函数
callback的protype是
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *);
u_char(第一个参数)是从pcap_loop传入的值,即pcap_loop中的user.
const struct pcap_pkthdr是一个结构体,成员如下
ts a struct timeval containing the time when the packet was
captured
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
timeval中给出距1970年1月1日0时0分0秒的时间
caplen a bpf_u_int32 giving the number of bytes of the packet
that are available from the capture
给出包的大小,以byte为单位
len a bpf_u_int32 giving the length of the packet, in bytes
(which might be more than the number of bytes available
from the capture, if the length of the packet is larger
than the maximum number of bytes to capture)
这个值可能比caplen大,因为包的实际大小有可能比程序中所设置的抓包的最大长度大.
const u_char *,指向包中最开始caplen比特大小数据.不过这些数据可能不是整个包的数据,因为有可能在pcap_open_live中设置的snaplen可能小于包的大小,所以就有可能得不到整个包,如果一定要得到整个包,可以将snaplen设置为65535
返回值:
pcap_loop返回-1,表明运行时出错
pcap_loop返回0,表明已经读取了cnt个包
pcap_loop返回-1,表明循环被pcap_breakloop()中止
4.关闭设备
void pcap_close(pcap_t *p)
关闭设备并释放资源
5.获取下一个包
const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
这个函数其实是调用pcap_dispatch()(令参数cnt为1),返回指向包中数据的指针.在这个函数中,pcap_pkthdr结构没有提供.
当函数产生错误或者没有抓到包时,函数返回NULL,
6.编译过滤器
int pcap_compile(pcap_t *p, struct bpf_program *fp
char *str, int optimize, bpf_u_int32 netmask)
编译过滤字符串str,
netmask是要被过滤的子网掩码,这个参数只在检查IPV4广播地址时使用
optimize表明是否被优化
7.使用过滤器
int pcap_setfilter(pcap_t *p, struct bpf_program *fp)
// compile:gcc thisfile.c -o xthisfile -lpcap
#include < stdio.h >
#include < stdlib.h >
#include < pcap.h >
#include < errno.h >
#include < sys / socket.h >
#include < netinet / in .h >
#include < arpa / inet.h >
#include < netinet / if_ether.h > /* includes net/ethernet.h */
struct my_i