libpcap使用总结!
libpcap是一个开发sniffer的工具包。pcap:packetcapture!
libpcap的数据类型定义:
structpcap_addr:网卡地址描述
{
pcap_addr* next;
sockaddr* addr;
sockaddr* netmask;
sockaddr*broadaddr;
sockaddr*dstaddr;
};
pcap_addr* next;
如果非空,指向链表中一个元素的指针;空表示链表中的最后一个元素。
sockaddr* addr;
指向包含一个地址的sockaddr的结构的指针。
sockaddr* netmask;
如果非空,指向包含相对于addr指向的地址的一个网络掩码的结构。
sockaddr* broadaddr;
如果非空,指向包含相对于addr指向的地址的一个广播地址,如果网络不支持广播可能为空。
sockaddr* dstaddr;
如果非空,指向一个相对于addr指向的源地址的目的地址,如果网络不支持点对点通讯,则为空。
structpcap_file_header {
bpf_u_int32magic;
u_shortversion_major;
u_shortversion_minor;
bpf_int32thiszone; /* gmt to local correction */
bpf_u_int32sigfigs; /* accuracy of timestamps */
bpf_u_int32snaplen; /* max length saved portion of each pkt */
bpf_u_int32linktype; /* data link type (LINKTYPE_*) */
};
bpf_u_int32magic;/*magic是32位数值,代表了存储类型*/
u_shortversion_major;/* Libpcap的主版本号*/
u_shartversion_minor;/* Libpcap的从版本号*/
bpf_u_int32sigfigs;/* 时间戳描述*/
bpf_u_int32snaplen;/* 保存的每个pkt的分片号的最大值*/
bpf_u_int32linktype;/* 数据链的类型*/
细节说明:
libpcapdump文件头;
libpcapdump文件中的第一个记录包含了一些标志的保存值,这些标志在打印阶段用到。这儿的很多域都是32位的int,所以compilers不用进行转化;这些文件需要具有跨层次的可交换性。
无论如何不要改变结构的层次(包括仅仅改变这个结构中域的长度);
structpcap_if { /*网卡数据链的一个元素*/
structpcap_if *next;
char*name; /* name to hand to "pcap_open_live()" */
char*description; /* textual description of interface, or NULL */
structpcap_addr *addresses;
u_intflags; /* PCAP_IF_ interface flags */
};
pcap_if*next; 如果非空,指向链的下一个元素。如果为空是链的最后一个元素。
char *name; 指向一个字符串,该字符串是传给pcap_open_live()函数的设备名;
char *description; 如果非空,指向一个对设备的人性化的描述字符串。
pcap_addr*addresses; 指向网卡地址链中的第一个元素。
u_intflags; PCAP_IF_网卡的标志。现在唯一可用的标识是PCAP_IF_LOOKBACK,它被用来标识网卡是不是lookback网卡。
structpcap_pkthdr { /*dump 文件中的数据包头*/
structtimeval ts; /* time stamp */
bpf_u_int32caplen; /* length of portion present */
bpf_u_int32len; /* length this packet (off wire) */
};
timevalts; 数据报时间戳;
bpf_u_int32caplen; 当前分片的长度;
dpf_u_int32len; 这个数据报的长度;
细节描述:
在dump文件中的每个数据报都有这样一个报头。它用来处理不同数据报网卡的不同报头问题。
structpcap_stat { /*用来保存网卡静态变量的结构*/
u_intps_recv; /* number of packets received */
u_intps_drop; /* number of packets dropped */
u_intps_ifdrop; /* drops by interface XXX not yet supported */
};
u_intps_recv; 接受数据报的数目;
u_intps_drop; 被驱动程序丢弃的数据报的数目;
u_intps_ifdrop; 被网卡丢弃的数据报的数目;
lipcap的声明:
#definePCAP_VERSION_MAJOR 2
libpcapdump文件的主版本号;
#definePCAP_VERSION_MINOR 4
libpcapdump文件的从版本号;
#definePCAP_ERRBUF_SIZE 256 用来存放libpcap出错信息的缓冲区的大小;
#definePCAP_IF_LOOPBACK 0x00000001 网卡是回环网卡;
#defineMODE_CAPT 0 抓报模式,在调用pcap_setmode()时使用;
#defineMODE_STAT 1 静态模式,在调用pcap_setmode()时使用;
libpcap的类型定义:
typedefint bpf_int32 32bit 的整形;
typedefu_int bpf_u_int32 32bit 的无类型整形;
typedefpcap pcap_t Descriptor of an open captureinstance(一个打开的捕获实例的描述符?)这个结构对用户是不透明的。
typedefpcap_dumper pcap_dumper_t libpcap保存文件的描述符。
typedefpcap_if pcap_if_t 网卡链表的一个元素;
typedefpcap_addr pcap_addr_t 网卡地址的表示;
libpcap函数描述:
char*pcap_lookupdev(char * errbuf);
描述:这个函数用于获取一个合适的网卡描述,以供pcap_open_liver函数和pcap_lookupnet函数使用。如果找不到网卡或者所有网卡为off,则返回null。如果一个系统中有多个网卡,那么该函数返回找到的第一个on的网卡。最后才是回环接口。回环网卡一直被忽略;
参数:
char *errbuf 存放pcap_lookupdev函数的出错信息,只有在pcap_lookup失败是才有值。
返回值:如果函数执行成功,则返回一个用于描述系统上的一个网卡的描述符的指针。如果失败,返回null,errbuf中存放出错信息。
intpcap_lookupnet(char * device, bpf_u_int32 * netp, bpf_u_int32 *maskp,char * errbuf);
描述:该函数用于监测网卡所在网络的网络地址和子网掩码。
参数:
char*devic:网卡的描述符指针,由pcap_looupdev函数获取;
bpf_u_int32*netp:存放网络地址;
bpf_u_int32*maskp:存放子网掩码;
char *errbuf: 存放出错信息;
返回值:如果函数执行成功,则返回值为0,否则返回值为-1,并在errbuf中存放出错信息。
pcap_t*pcap_open_live(char * device, int snaplen,int promisc, int to_ms,char * ebuf);
描述:该函数用于打开网卡用于捕获数据报。单词live的意思就是表示一个运行的网卡(相对于offline而言)被打开了,如同一个保存有被抓数据报的文件被打开一样。在捕获数据报之前这个函数必须被执行。所有的其他的用于处理数据报捕获的函数用到的捕获数据报的描述符由该函数产生。查看pcap_open_offlin()函数的定义,了解如何打开一个预先保存的包含数据报的文件的细节。
参数:
char*device:网卡的描述符指针,由pcap_looupdev函数获取;
intsnaplen:规定捕获的每个数据报的最大字节数;
intpromisc:1为混杂模式;0为非混杂模式;
intto_ms:规定读超时的微秒(milliseconds)数;
char*ebuf:存放错误信息,只有在pcap_open_live失败时才被设置;
返回值:如果函数成功执行,则返回一个指向数据报捕获的指针;如果错误,返回null,ebuf存放出错信息;
intpcap_compile(pcap_t * p, struct bpf_ program *fp, char * str,intoptimize, bpf_u_int32 netmask);
描述:该函数用于将str指定的规则整合到fp过滤程序中去,并生成过滤程序入口地址,用于过滤选择期望的数据报;
参数:
pcap_t*p:pcap_open_live返回的数据报捕获的指针;
structbpf_program *fp:指向一个子函数用于过滤,在pcap_compile()函数中被赋值;
char*str:该字符串规定过滤规则;
intoptimize:规定了在结果代码上的选择是否被执行;
bpf_u_int32netmask:该网卡的子网掩码,可以通过pcap_lookupnet()获取;
返回值:
如果成功执行,返回0,否则返回-1;
intpcap_loop(pcap_t * p, int cnt, pcap_handler callback,u_char * user);
描述:
该函数用于读取和处理数据报。既可以用来处理事先捕获的保存在文件中的数据报,也可以用来处理实时捕获的数据报;
这个函数类似于pcap_dispatch函数,除了它继续读取数据报直至完成cnt个报的处理,或者文件处理完(在offline情况下),或者有错误发生为止。它不会在实时读超时时返回(而如果为pcap_open_live()函数指定了一个非零值的超时设置,然后调用
pcap_dispatch()函数,则当超时发生时pcap_dispatch()函数会返回。)
注意第三个参数,callback是pcap_handler类型的变量。这是一个用户提供的有着三个参数的子函数。定义为:
voiduser_routine(u_char *user, struct pcap_pkthdr *phrd, u_char *pdata)
这三个参数中,user,是传递给pcap_dispatch()的那个参数;phdr,是个pcap_pkthdr类型的指针,是savefile中的数据报的头指针,pdata,指向数据报数据;这个函数允许用户定义子集的数据报过滤程序;
参数:
pcap_t* pcap_open_live返回的数据报捕获的指针;
intcnt:规定了函数返回前应处理的数据报数目;
pcap_handlercallback:指向一个用户自定义的函数,在处理每个报后自动调用该函数进行再处理;
u_char*user:该指针用于传递给callback.(不知道有什么用?)
返回值:
如果函数成功执行(包括读文件时读到EOF),则返回0.否则返回-1,那么错误信息将由函数pcap_geterr或pcap_perror给出;