libpcap/data_link_types.c

每個Interface通常支援不只一種data-link協定,這個程式會列出所有支援的類型。

Source Code

//
//  data_link_types.c
//  功能:取得Interface的data-link層支援的類型。
//  Created by 聲華 陳 on 2016/01/09.
//

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <arpa/inet.h>
int main(int argc, const char * argv[]) {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *handle = NULL;
    int dlt = -1;
    int *dlts = NULL;
    int len = 0;
    char *device = "en0";

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

    //get data-link type
    dlt = pcap_datalink(handle);
    printf("%s:\n", device);
    printf("\tValue: %d\n", dlt);
    printf("\tName: %s\n", pcap_datalink_val_to_name(dlt));
    printf("\tDescription: %s\n", pcap_datalink_val_to_description(dlt));

    //get data-link supported
    if(-1 == (len = pcap_list_datalinks(handle, &dlts))) {
        fprintf(stderr, "pcap_open_live: %s\n", errbuf);
        pcap_close(handle);
        exit(1);
    }//end if

    printf("\n%s supported:\n", device);
    for(int i = 0 ; i < len ; i++) {
        dlt = dlts[i];
        printf("\tValue: %d\n", dlt);
        printf("\tName: %s\n", pcap_datalink_val_to_name(dlt));
        printf("\tDescription: %s\n\n", pcap_datalink_val_to_description(dlt));
    }//end for

    //free
    pcap_free_datalinks(dlts);
    pcap_close(handle);
    return 0;
}

結果

libpcap % ./data_link_types 
en0:
    Value: 1
    Name: EN10MB
    Description: Ethernet

en0 supported:
    Value: 1
    Name: EN10MB
    Description: Ethernet

    Value: 192
    Name: PPI
    Description: Per-Packet Information

    Value: 127
    Name: IEEE802_11_RADIO
    Description: 802.11 plus radiotap header

    Value: 105
    Name: IEEE802_11
    Description: 802.11

    Value: 163
    Name: IEEE802_11_RADIO_AVS
    Description: 802.11 plus AVS radio information header

    Value: 12
    Name: RAW
    Description: Raw IP

我的en0介面預設是Ethernet,不過支援IEEE802.11,所以可以抓無線網路的封包。

分析

    char *device = "en0";

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

一樣要透過pcap_open_live()打開一張網卡。


    //get data-link type
    dlt = pcap_datalink(handle);
    printf("%s:\n", device);
    printf("\tValue: %d\n", dlt);
    printf("\tName: %s\n", pcap_datalink_val_to_name(dlt));
    printf("\tDescription: %s\n", pcap_datalink_val_to_description(dlt));

然後使用pcap_datalink()抓預設的data-link類型,pcap_datalink_val_to_name()pcap_datalink_val_to_description()可以將類型轉成字串。其中乙太的Value保留字是DLT_EN10MB


    //get data-link supported
    if(-1 == (len = pcap_list_datalinks(handle, &dlts))) {
        fprintf(stderr, "pcap_open_live: %s\n", errbuf);
        pcap_close(handle);
        exit(1);
    }//end if

接著再使用pcap_list_datalinks()取得該Interface所支援的data-link類型列表,傳回的數值就是支援的數量。


    printf("\n%s supported:\n", device);
    for(int i = 0 ; i < len ; i++) {
        dlt = dlts[i];
        printf("\tValue: %d\n", dlt);
        printf("\tName: %s\n", pcap_datalink_val_to_name(dlt));
        printf("\tDescription: %s\n\n", pcap_datalink_val_to_description(dlt));
    }//end for

然後就是將每個類型列印出來。


    //free
    pcap_free_datalinks(dlts);
    pcap_close(handle);

記得釋放資源。

結語

我們還可以修改data-link層的類型去抓不同類型的封包,像是無線網卡雖然預設是Ethernet,但是可以改成IEEE802.1x抓更底層封包。

results matching ""

    No results matching ""