#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
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 {
};
pkt_data是抓到的包数据,这里包括了协议的头部。