以下示例比较简单,只是将抓取到的数据简单的打印出来。
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <pcap.h>
#define MAXBYTE2CAPTURE 2048
void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
unsigned int i = 0;
int *counter = (int *)arg;
printf("Packet Count: %d\n", ++(*counter));
printf("Received Packet Size: %d\n", pkthdr->len);
printf("Payload:\n");
for (i = 0; i < pkthdr->len; i++) {
if (isprint(packet[i]))
printf("%c ", packet[i]);
else
printf(". ");
if ((i % 16 == 0 && i != 0) || i == pkthdr->len-1)
printf("\n");
}
return;
}
int main(int argc, char **argv)
{
int i = 0, count = 0;
pcap_t *descr = NULL;
char errbuf[PCAP_ERRBUF_SIZE] = {0};
char *device = NULL;
/* Get the name of the first device suitable for capture */
device = pcap_lookupdev(errbuf);
printf("Opening device %s\n", device);
/* Open device in promiscuous mode */
descr = pcap_open_live(device, MAXBYTE2CAPTURE, 1, 512, errbuf);
/* Loop forever & call processPacket() for every received packet */
pcap_loop(descr, -1, processPacket, (u_char *)&count);
return 0;
}
第二个示例解析了包中的数据协议。
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <pcap.h>
void tcp_packet_callback(unsigned char *argument, const struct pcap_pkthdr *pcap_header,
const unsigned char *packet_content)
{
struct tcphdr *tcpptr = (struct tcphdr *)(packet_content + 14 + 20);
printf("----tcp protocol-----\n");
printf("source port: %d\n", ntohs(tcpptr->source));
printf("dest port: %d\n", ntohs(tcpptr->dest));
printf("sequence number: %u\n", ntohl(tcpptr->seq));
printf("acknowledgement number: %u\n", ntohl(tcpptr->ack_seq));
printf("header length: %d\n", tcpptr->doff*4);
printf("check sum: %d\n", ntohs(tcpptr->check));
printf("window size: %d\n", ntohs(tcpptr->window));
printf("urgent pointer: %d\n", ntohs(tcpptr->urg_ptr));
return;
}
void ip_packet_callback(unsigned char *argument, const struct pcap_pkthdr *pcap_header,
const unsigned char *packet_content)
{
struct in_addr s, d;
struct iphdr *ipptr;
ipptr = (struct iphdr *)(packet_content + 14);
printf("-----IP Protocol (network layer)-----\n");
printf("version: %d\n", ipptr->version);
printf("header length: %d\n", ipptr->ihl*4);
printf("tos: %d\n", ipptr->tos);
printf("total length: %d\n", ntohs(ipptr->tot_len));
printf("identification: %d\n", ntohs(ipptr->id));
printf("offset: %d\n", ntohs((ipptr->frag_off & 0x1fff) * 8));
printf("TTL: %d\n", ipptr->ttl);
printf("checksum: %d\n", ntohs(ipptr->check));
printf("protocol: %d\n", ipptr->protocol);
s.s_addr=ipptr->saddr;
d.s_addr=ipptr->daddr;
printf("source address: %s\n", inet_ntoa(s));
printf("destination address: %s\n", inet_ntoa(d));
switch(ipptr->protocol) {
case 6:
printf("tcp protocol\n");
tcp_packet_callback(argument, pcap_header, packet_content);
break;
case 1:
printf("icmp protocol\n");
break;
case 17:
printf("udp protocol\n");
break;
default:
break;
}
return;
}
void arp_packet_callback(unsigned char *argument, const struct pcap_pkthdr *pcap_header,
const unsigned char *packet_content)
{
printf("------ARP Protocol-------\n");
return;
}
void ethernet_packet_callback(unsigned char *argument, const struct pcap_pkthdr *pcap_header,
const unsigned char *packet_content)
{
struct ethhdr *ethptr;
struct iphdr *ipptr;
unsigned char *mac;
ethptr=(struct ethhdr *)packet_content;
printf("\n----ethernet protocol(physical layer)-----\n");
printf("MAC source Address:\n");
mac = ethptr->h_source;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac, *(mac+1), *(mac+2), *(mac+3), *(mac+4), *(mac+5));
printf("MAC destination Address:\n");
mac = ethptr->h_dest;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *mac, *(mac+1), *(mac+2), *(mac+3), *(mac+4), *(mac+5));
printf("protocol: %04x\n", ntohs(ethptr->h_proto));
switch(ntohs(ethptr->h_proto)) {
case 0x0800:
printf("this is a IP protocol\n");
ip_packet_callback(argument,pcap_header,packet_content);
break;
case 0x0806:
printf("this is a ARP protocol\n");
arp_packet_callback(argument,pcap_header,packet_content);
break;
case 0x8035:
printf("this is a RARP protocol\n");
break;
default:
break;
}
return;
}
int main(int argc, char **argv)
{
pcap_t *pt;
char *dev;
char errbuf[128];
struct bpf_program fp;
bpf_u_int32 maskp, netp;
int ret,i=0,inum;
int pcap_time_out = 5;
char filter[128] = {0};
unsigned char *packet;
struct pcap_pkthdr hdr;
pcap_if_t *alldevs,*d;
if(pcap_findalldevs(&alldevs, errbuf) == -1) {
fprintf(stderr,"find interface failed!\n");
return -1;
}
for(d = alldevs; d; d = d->next) {
printf("%02d. %s", ++i, d->name);
if(d->description)
printf("(%s)\n", d->description);
else
printf("(no description available)\n");
}
if(i == 1) {
dev = alldevs->name;
} else {
printf("input a interface(1-%d):", i);
scanf("%d", &inum);
if(inum < 1 || inum > i) {
printf("interface number out of range\n");
return -1;
}
for(d = alldevs, i = 1; i<inum; d = d->next, i++);
dev = d->name;
}
/*
dev=pcap_lookupdev(errbuf);
if(dev==NULL){
fprintf(stderr,"%s/n",errbuf);
return;
}
*/
printf("dev: %s\n", dev);
ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
if(ret == -1) {
fprintf(stderr,"%s\n", errbuf);
return -1;
}
pt = pcap_open_live(dev, BUFSIZ, 1, pcap_time_out, errbuf);
if(pt == NULL) {
fprintf(stderr,"open error :%s\n", errbuf);
return -1;
}
if(pcap_compile(pt, &fp, filter, 0, netp) == -1) {
fprintf(stderr, "compile error\n");
return -1;
}
if(pcap_setfilter(pt, &fp) == -1) {
fprintf(stderr,"setfilter error\n");
return -1;
}
pcap_loop(pt, -1, ethernet_packet_callback, NULL);
/*
while(1) {
printf("wait packet:filter %s/n",filter);
packet=(char *)pcap_next(pt,&hdr);
if(packet==NULL)
continue;
else
printf("get a packet/n");
}
*/
pcap_close(pt);
return 0;
}
编译测试程序时,可能遇到以下的问题:
fatal error: pcap.h: No such file or directory compilation terminated.
解决方法:
sudo apt-get install libpcap0.8-dev
参考文章
PCAP数据包过滤器设置 及 过滤表达式语法
pcap学习
基于 linux 平台的 libpcap 源代码分析
libpcap使用
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。