#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/if_ether.h>
#include <string.h>
void call_back(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
/* 捕获数据包计数器 */
static int count = 1;
printf("*****************************************************%d: /n",count);
int i = 0;
/* 打印捕获数据包的信息 */
printf("The grab time is: %s", ctime((const time_t*)&(*header).ts.tv_sec));
printf("The grab length of packet is: %d/n", (*header).caplen);
printf("The length of packet is: %d/n", (*header).len);
/* 自定义指针指将捕获的数据包的内容拷贝到指向的内存中 */
u_char *pac;
pac = (u_char *)malloc((*header).len+1);
memcpy(pac, packet, (*header).len);
/* 分字节打印数据包的内容 */
for(i=0; i<(*header).len; i++)
{
printf("packet doc%d is: %d/n", i, pac[i]);
}
/* 分割线 */
printf("********************************************************/n");
count++;
}
int main(int argc, char *argv[])
{
char *dev; /* 获得设备名称*/
pcap_t *handle; /* 捕获句柄 */
struct pcap_pkthdr header; /* 捕获数据包的时间长度信息结构体 */
const u_char *packet; /* 指向捕获的数据包内存的指针 */
struct pcap_stat stat; /* 捕获状态信息 */
char *net; /* 保存转换后网络号*/
char *mask; /* 保存转换后子网掩码*/
bpf_u_int32 netp; /* 保存32bit的网络号 */
bpf_u_int32 maskp; /* 保存32bit的子网掩码 */
struct in_addr addr; /* 用于转换网络地址的结构体*/
char errbuf[PCAP_ERRBUF_SIZE]; /* 保存出错信息 */
int ret; /* 返回值return */
/* 获得第一个可用网络设备名称 */
dev = pcap_lookupdev(errbuf);
if(NULL == dev)
{
printf("can't find dev!/n");
exit(1);
}
printf("DEV: %s/n", dev);
/* 获得网络号和子网掩码 */
ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
if(-1 == ret)
{
printf("Error in look up net!/n");
exit(1);
}
/* 打印网络号 */
addr.s_addr = netp;
net = inet_ntoa(addr);
if( NULL == net)
{
printf("net error!/n");
exit(1);
}
printf("NET: %s/n",net);
/* 打印子网掩码 */
addr.s_addr = maskp;
mask = inet_ntoa(addr);
if(NULL == mask)
{
printf("mask error!/n");
exit(1);
}
printf("MASK: %s/n", mask);
/* 获得捕获句柄 */
handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
if(NULL == handle)
{
printf("pcap_open_live(): %s/n",errbuf);
exit(1);
}
/* 获得网络类型(此处仅以10M以太网为例,其他类型参照libpcap说明文档)*/
if(pcap_datalink(handle) == DLT_EN10MB)
{
printf("10 MB internet!/n");
}
/* 使用pcap_loop()循环捕获数据包 */
pcap_loop(handle, 10, call_back, NULL);
/* 另一种循环捕获数据包的方法:使用pcap_next()函数和循环相结合的用法 */
/*
int i;
for(i=0;i<10;i++)
{
packet = pcap_next(handle, &header);//偶:注意这句,使用pcap_next来作,要用packet 来接返回值。这个与pcap_loop不同
//用pcap_loop来作的话,是用回调函数callback的第一个参数来存放抓到的数据包
printf("The grab time is: %s", ctime((const time_t*)&header.ts.tv_sec));
printf("The grab length of packet is: %d/n", header.caplen);
printf("The length of packet is: %d/n", header.len);
}
*/
/* 获得捕获状态信息 */
pcap_stats(handle, &stat);
printf("reces: %d, drops: %d/n", stat.ps_recv, stat.ps_drop);
/* 关闭捕获句柄 */
pcap_close(handle);
return 0;
}