libpcap/capture_pcap_next_ex.c

前面兩種方法pcap_loop()pcap_dispatch()都是利用callback的方式抓封包,在物件導向語言使用上比較不方便,在這裡介紹第三種方法:pcap_next_ex()pcap_next()就不介紹了,跟pcap_next_ex()用法差不多)。

Source Code

//
//  capture_pcap_next_ex.c
//  功能:使用pcap_next_ex抓取封包。
//  Created by 聲華 陳 on 2015/12/30.
//

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>

int main(int argc, const char * argv[]) {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *handle = NULL;
    struct pcap_pkthdr *header = NULL;
    const u_char *content = NULL;

    //open interface
    handle = pcap_open_live("en0", 65535, 1, 1000, errbuf);
    if(!handle) {
        fprintf(stderr, "pcap_open_live: %s\n", errbuf);
        exit(1);
    }//end if

    //start capture
    int ret =
    pcap_next_ex(handle, &header, &content);
    if(ret == 1) {
        struct tm *ltime;
        char timestr[16];
        time_t local_tv_sec;

        local_tv_sec = header->ts.tv_sec;
        ltime = localtime(&local_tv_sec);
        strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

        //print header
        printf("Time: %s.%.6d\n", timestr, header->ts.tv_usec);
        printf("Length: %d bytes\n", header->len);
        printf("Capture length: %d bytes\n", header->caplen);

        //print packet in hex dump
        for(int i = 0 ; i < header->caplen ; i++) {
            printf("%02x ", content[i]);
        }//end for
        printf("\n\n");
    }//end if success
    else if(ret == 0) {
        printf("Timeout\n");
    }//end if timeout
    else if(ret == -1) {
        fprintf(stderr, "pcap_next_ex: %s\n", pcap_geterr(handle));
    }//end if fail
    else if(ret == -2) {
        printf("No more packet from file\n");
    }//end if read no more packet

    //free
    pcap_close(handle);

    return 0;
}

結果

libpcap % ./capture_pcap_next_ex
Time: 23:48:03.256262
Length: 66 bytes
Capture length: 66 bytes
f8 1a 67 53 f5 dc 6c 40 08 bc ae 98 08 00 45 00 00 34 b6 ec 40 00 40 06 a9 29 c0 a8 01 64 6c a0 ac 01 dd 15 01 bb a4 3a 46 c0 e8 c0 ea c1 80 11 10 00 7a 10 00 00 01 01 08 0a 41 75 56 1f 86 73 56 a7

分析

    //open interface
    handle = pcap_open_live("en0", 65535, 1, 1000, errbuf);
    if(!handle) {
        fprintf(stderr, "pcap_open_live: %s\n", errbuf);
        exit(1);
    }//end if

這次就不分割封包,直接第二個參數給65535to_ms設置1000毫秒。


    //start capture
    int ret =
    pcap_next_ex(handle, &header, &content);
    if(ret == 1) {
        struct tm *ltime;
        char timestr[16];
        time_t local_tv_sec;

        local_tv_sec = header->ts.tv_sec;
        ltime = localtime(&local_tv_sec);
        strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

        //print header
        printf("Time: %s.%.6d\n", timestr, header->ts.tv_usec);
        printf("Length: %d bytes\n", header->len);
        printf("Capture length: %d bytes\n", header->caplen);

        //print packet in hex dump
        for(int i = 0 ; i < header->caplen ; i++) {
            printf("%02x ", content[i]);
        }//end for
        printf("\n\n");
    }//end if success
    else if(ret == 0) {
        printf("Timeout\n");
    }//end if timeout
    else if(ret == -1) {
        fprintf(stderr, "pcap_next_ex: %s\n", pcap_geterr(handle));
    }//end if fail
    else if(ret == -2) {
        printf("No more packet from file\n");
    }//end if read no more packet

函數pcap_next()只會抓取一個封包而已,如果要一直抓封包可以利用迴圈。這裡一樣把封包的時間資訊、長度以及封包內容給顯示出來。


    //free
    pcap_close(handle);

結束後記得釋放。

結語

這個函數不同於pcap_loop()pcap_dispatch()在於它不使用callback方式處理封包,在物件導向語言使用上比較方便,Wireshark也是用此函數來抓取封包。至於什麼時候要用什麼函數,就看需求來使用。

results matching ""

    No results matching ""