libpcap/capture_pcap_loop.c

接著就開要開始講怎麼抓封包了,在libpcap裡有幾種抓封包的方式:

  1. pcap_loop()
  2. pcap_dispatch()
  3. pcap_next()(最好別使用)
  4. pcap\_next\_ex()

而這篇會示範如何用pcap_loop()抓封包。

Source Code

//
//  capture_pcap_loop.c
//  功能:使用pcap_loop抓取封包。
//  Created by 聲華 陳 on 2015/12/28.
//

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

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

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

    //start capture loop
    if(0 != pcap_loop(handle, 10, pcap_callback, NULL)) {
        fprintf(stderr, "pcap_loop: %s\n", pcap_geterr(handle));
    }//end if

    //free
    pcap_close(handle);

    return 0;
}

void pcap_callback(u_char *arg, const struct pcap_pkthdr *header, const u_char *content) {
    static int d = 0;
    printf("%d: captured\n", ++d);
}//end pcap_callback

結果

libpcap % ./capture_pcap_loop 
1: captured
2: captured
3: captured
4: captured
5: captured
6: captured
7: captured
8: captured
9: captured
10: captured

當有封包進出時,就會列印出目前抓到第幾個封包。

分析

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

在抓封包的時候要先指定該從哪個Interface抓取封包,先使用pcap_open_live()打開一個Interface,這邊因為我是要抓Wi-Fi所以第一個參數選擇en0,第二個參數指定封包最大值表示說不切割封包。然後使用混雜模式以及設置to_ms表示每毫秒處理封包。


    //start capture loop
    if(0 != pcap_loop(handle, 10, pcap_callback, NULL)) {
        fprintf(stderr, "pcap_loop: %s\n", pcap_geterr(handle));
    }//end if

如果沒有要設定過濾器就可以馬上抓封包了,這裡抓取十個封包後就停止,當有封包經過的時候會呼叫第三個參數所給的callback:pcap_callback(),第四個參數是要傳給pcap_callback()哪個變數。


    //free
    pcap_close(handle);

結束後記得要釋放pcap_open_live()傳回的pcap_t *結構指標。


void pcap_callback(u_char *arg, const struct pcap_pkthdr *header, const u_char *content) {
    static int d = 0;
    printf("%d: captured\n", ++d);
}//end pcap_callback

當有封包進出的時候,pcap_loop()會呼叫這個callback,這個callback會記錄目前有幾個封包並列印出來。當pcap_loop()的第四個參數有給參數的話,會傳給arg變數,在這個程式裡pcap_loop()第四個參數為NULL,所以這裡的arg就是NULL囉。

結語

抓取封包最簡單只要兩個函數就可以完成,libpcap簡化了很多步驟讓開發者專心在封包分析上。但是這個方法使用callback方式,在一些物件導向語言會不好開發,例如Objective-C,可以使用pcap_next_ex()代替。

results matching ""

    No results matching ""