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抓更底層封包。