|
常用链接
留言簿
随笔分类
随笔档案
文章档案
搜索
最新评论
阅读排行榜
评论排行榜
Powered by: 博客园
模板提供:沪江博客
|
|
|
|
|
发新文章 |
|
|
#include "pcap.h"
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main() { pcap_if_t *alldevs; pcap_if_t *d; int inum; int i=0; pcap_t *adhandle; char errbuf[PCAP_ERRBUF_SIZE]; if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); exit(1); } for(d=alldevs; d; d=d->next) { printf("%d. %s", ++i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" (No description available)\n"); } if(i==0) { printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); return -1; } printf("Enter the interface number (1-%d):",i); scanf_s("%d", &inum); if(inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); pcap_freealldevs(alldevs); return -1; } for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); if ( (adhandle= pcap_open(d->name, // name of the device 65536, // portion of the packet to capture // 65536 guarantees that the whole packet will be captured on all the link layers PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode 1000, // read timeout NULL, // authentication on the remote machine errbuf // error buffer ) ) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); pcap_freealldevs(alldevs); return -1; } printf("\nlistening on %s\n", d->description); pcap_freealldevs(alldevs); pcap_loop(adhandle, 0, packet_handler, NULL); return 0; }
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct tm ltime; char timestr[16]; time_t local_tv_sec;
(VOID)(param); (VOID)(pkt_data);
local_tv_sec = header->ts.tv_sec; localtime_s(<ime, &local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", <ime); printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len); }
这里主要是想说明下回调函数的各个参数,顺便讲下pcap_loop
int pcap_loop (
pcap_t * p,
int cnt,
pcap_handler callback,
u_char * user
)
pcap_t结构对开发者是不透明的,一般是由pcap_open返回,可以认为是抓包的句柄。cnt表示抓到cnt个包后loop结束,callback就是处理包的回调函数了。user只是用来描述这次抓包,可以置为NULL,如果觉得需要,也可以把抓包的目的啊什么的写上去。
-1 is returned on an error; 0 is returned if cnt is exhausted; -2 is returned if the loop terminated due to a call to pcap_breakloop() before any packets were processed. If your application uses pcap_breakloop(), make sure that you explicitly check for -1 and -2, rather than just checking for a return value < 0.
出错返回-1,抓完了cnt个包返回0,在处理包之前就调用pcap_breakloop()终结loop则返回-2.所有如果调用了pcap_breakloop() ,必须检查返回值是-1还是-2,不能来笼统检查是否小于0.
int pcap_dispatch (
pcap_t * p,
int cnt,
pcap_handler callback,
u_char * user
)
pcap_dispatch和pcap_loop的唯一区别是pcap_dispatch会因为超时而结束(这个时间是在pcap_open里面设置的),pcap_loop则不管,一定要抓玩cnt个包
pcap_t* pcap_open ( const char * source, int snaplen, int flags, int read_timeout, //就是这个设置超时了,单位是毫秒 struct pcap_rmtauth * auth, char * errbuf )
typedef void(* pcap_handler)(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
user就是pcap_loop里的u_char*user
pkt_header是winpcap给抓到的包附上的头,不是IP报文头部、UDP报文头部等等协议头部。
struct pcap_pkthdr { struct timeval ts; bpf_u_int32 caplen; bpf_u_int32 len; };
pkt_data是抓到的包数据,这里包括了协议的头部。
|
|