linux pcap 循环抓包,使用pcap库抓包的示例代码

以下示例比较简单,只是将抓取到的数据简单的打印出来。

#include

#include

#include

#include

#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

#include

#include

#include

#include

#include

#include

#include

#include

#include

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; inext, 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

参考文章

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值