libpcap核心pcap_loop

pcap_next虽然也是通过网口获取数据包,但是只要抓取了一个就会返回,假如想持续不停抓包,当然可以while(1)里持续进行,但是显然有些难看

while(1){
    const u_char* pktStr = pcap_next(p, &pkthdr);
    if (!pktStr){
        printf(“Cannot capture pkt!\n”);
        exit(1);
    }
    printf(“Capture packet length: %d\n”, pkthdr.len);
}   

但是libpcap提供了核心函数pcap_loop直接可以实现这一目的

int
pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

参数cnt设定了需要抓取的数据包的个数,抓了cnt个之后,pcap_loop就会返回,显然如果cnt为1的时候,跟pcap_next的效果是一样的;但大部分都会设置为-1,这样就会一直持续抓包,跟上面的while(1)情况类似

参数callback是一个用户层的回调函数,数据包抓取了之后就交给callback来处理,任人宰割

typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,const u_char *data);

user参数传递了用户自定义一些数据,是pcap_loop的最后一个参数,进而传递给回调函数

h是收到数据包pcap_pkthdr类型的指针

data是真正数据包的内容

 

因此可以直接调用pcap_loop来持续抓包,然后在回调函数里,尽情地挖掘你想要的数据包信息吧!!!

[lihui@localhost ~]$ cat loop.c
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>

int current_pkt = 0;

void lihui_callback(u_char *u, const struct pcap_pkthdr *hdr, const u_char *data){
    ++current_pkt;
    printf(“The %d packet length: %d\n”, current_pkt, hdr->len);
}

int main(){
    char ebuf[PCAP_ERRBUF_SIZE];
    char *device;
    int pktlen = 65535;
    int misc = 1;
    int timeout = 0;
    device = pcap_lookupdev(ebuf);
    if (device)
        printf(“Capture Nic: %s\n”, device);
    else {
        printf(“Nic Error: %s\n”, ebuf);
        exit(1);
    }
    pcap_t *p = pcap_open_live(device, pktlen, misc, timeout, ebuf);
/*
    struct pcap_pkthdr pkthdr;
    const u_char* pktStr = pcap_next(p, &pkthdr);
    if (!pktStr){
        printf(“Cannot capture pkt!\n”);
        exit(1);
    }
    printf(“Capture packet length: %d\n”, pkthdr.len);
*/   
    printf(“Capture pkt start:\n”);
    pcap_loop(p, -1, (pcap_handler)lihui_callback, (u_char *)p);

    pcap_close(p);
    return 0;
}

发表评论