一個device可以支援不同種data-link類型,目前為止只看到Ethernet這類,libpcap可以列出該裝置所有支援的data-link類型,也可以切換類型。
那來列出預設device所支援的data-link類型。
char errbuf[PCAP_ERRBUF_SIZE];
char *device = NULL;
//get default interface name
device = pcap_lookupdev(errbuf);
if(!device) {
fprintf(stderr, "pcap_lookupdev(): %s\n", errbuf);
exit(1);
}//end if
printf("Device: %s\n", device);
//open handle
pcap_t *handle = pcap_open_live(device, 65535, 1, 1, errbuf);
if(!handle) {
fprintf(stderr, "pcap_open_live(): %s\n", errbuf);
exit(1);
}//end if
先取得預設的device名稱,然後開啟它。函數
pcap_datalink()可以取得該裝置預設的data-link類型。
//get defalt data-link type
int default_dlt = pcap_datalink(handle);
函數
pcap_datalink()原型:int pcap_datalink(pcap_t *p);
- 返回值:傳回p的data-link類型。
- 參數:p一個libpcap handle。
- 功能:取得p的data-link類型。
接著利用函數
pcap_list_datalinks()來取得支援的data-link類型。
//get data-link list
int *dlts = NULL;
int dlt_len = 0;
if((dlt_len = pcap_list_datalinks(handle, &dlts)) == -1) {
fprintf(stderr, "pcap_list_datalinks(): %s\n", pcap_geterr(handle));
pcap_close(handle);
exit(1);
}//end if
函數
pcap_list_datalinks()原型:int pcap_list_datalinks(pcap_t *p, int **dlt_buf);
- 返回值:傳回p的data-link支援類型數量,失敗傳回-1。
- 參數:p一個libpcap handle。dlt_buf結果陣列指標。
- 功能:取得p所支援的data-link所有類型。
data-link層的類型都被marcos成保留字,都是
DLT_開頭,乙太網路保留字為DLT_EN10MB,其他libpcap的保留字還有:
#define DLT_CHOICE(code, description) { #code, description, code }
#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_NULL, "BSD loopback"),
DLT_CHOICE(DLT_EN10MB, "Ethernet"),
DLT_CHOICE(DLT_IEEE802, "Token ring"),
DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"),
DLT_CHOICE(DLT_SLIP, "SLIP"),
DLT_CHOICE(DLT_PPP, "PPP"),
DLT_CHOICE(DLT_FDDI, "FDDI"),
DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"),
DLT_CHOICE(DLT_RAW, "Raw IP"),
DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
DLT_CHOICE(DLT_IEEE802_11, "802.11"),
DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
DLT_CHOICE(DLT_LTALK, "Localtalk"),
DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"),
DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"),
DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
DLT_CHOICE(DLT_MTP2, "SS7 MTP2"),
DLT_CHOICE(DLT_MTP3, "SS7 MTP3"),
DLT_CHOICE(DLT_SCCP, "SS7 SCCP"),
DLT_CHOICE(DLT_DOCSIS, "DOCSIS"),
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
DLT_CHOICE(DLT_BACNET_MS_TP, "BACnet MS/TP"),
DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"),
DLT_CHOICE(DLT_GPF_T, "GPF-T"),
DLT_CHOICE(DLT_GPF_F, "GPF-F"),
DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"),
DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"),
DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"),
DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"),
DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"),
DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"),
DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"),
DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"),
DLT_CHOICE(DLT_A429, "Arinc 429"),
DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"),
DLT_CHOICE(DLT_USB, "USB"),
DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"),
DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"),
DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
DLT_CHOICE(DLT_PPI, "Per-Packet Information"),
DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"),
DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"),
DLT_CHOICE(DLT_SITA, "SITA pseudo-header"),
DLT_CHOICE(DLT_ERF, "Endace ERF header"),
DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"),
DLT_CHOICE(DLT_IPMB, "IPMB"),
DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"),
DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"),
DLT_CHOICE(DLT_LINUX_EVDEV, "Linux evdev events"),
DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"),
DLT_CHOICE(DLT_DECT, "DECT"),
DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"),
DLT_CHOICE(DLT_WIHART, "Wireless HART"),
DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"),
DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"),
DLT_CHOICE(DLT_IPNET, "Solaris ipnet"),
DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
DLT_CHOICE(DLT_DBUS, "D-Bus"),
DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"),
DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"),
DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
DLT_CHOICE(DLT_DVB_CI, "DVB-CI"),
DLT_CHOICE(DLT_MUX27010, "MUX27010"),
DLT_CHOICE(DLT_STANAG_5066_D_PDU, "STANAG 5066 D_PDUs"),
DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"),
DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
DLT_CHOICE(DLT_MPEG_2_TS, "MPEG-2 transport stream"),
DLT_CHOICE(DLT_NG40, "ng40 protocol tester Iub/Iur"),
DLT_CHOICE(DLT_NFC_LLCP, "NFC LLCP PDUs with pseudo-header"),
DLT_CHOICE(DLT_INFINIBAND, "InfiniBand"),
DLT_CHOICE(DLT_SCTP, "SCTP"),
DLT_CHOICE(DLT_USBPCAP, "USB with USBPcap header"),
DLT_CHOICE(DLT_RTAC_SERIAL, "Schweitzer Engineering Laboratories RTAC packets"),
DLT_CHOICE(DLT_BLUETOOTH_LE_LL, "Bluetooth Low Energy air interface"),
DLT_CHOICE(DLT_NETLINK, "Linux netlink"),
DLT_CHOICE(DLT_BLUETOOTH_LINUX_MONITOR, "Bluetooth Linux Monitor"),
DLT_CHOICE(DLT_BLUETOOTH_BREDR_BB, "Bluetooth Basic Rate/Enhanced Data Rate baseband packets"),
DLT_CHOICE(DLT_BLUETOOTH_LE_LL_WITH_PHDR, "Bluetooth Low Energy air interface with pseudo-header"),
DLT_CHOICE(DLT_PROFIBUS_DL, "PROFIBUS data link layer"),
DLT_CHOICE(DLT_PKTAP, "Apple DLT_PKTAP"),
DLT_CHOICE(DLT_EPON, "Ethernet with 802.3 Clause 65 EPON preamble"),
DLT_CHOICE_SENTINEL
};
接著把它列印出來,函數
pcap_datalink_val_to_name()可以把類型轉成名稱;函數pcap_datalink_val_to_description()可以把類型轉成詳細的描述;另外當data-link類型為預設的類型再另外標示出來。
for(int i = 0 ; i < dlt_len ; i++) {
printf("%d", i + 1);
printf(": %s(%s)",
pcap_datalink_val_to_name(dlts[i]),
pcap_datalink_val_to_description(dlts[i]));
if(default_dlt == dlts[i]) {
printf(" [default]");
}//end if data-link type is default
printf("\n");
}//end for
函數
pcap_datalink_val_to_name()原型:const char *pcap_datalink_val_to_name(int dlt);
- 返回值:傳回dlt的字串名稱。
- 參數:dlt要取得字串名稱的data-link類型。
- 功能:取得dlt的字串名稱。
函數
pcap_datalink_val_to_description()原型:const char *pcap_datalink_val_to_description(int dlt);
- 返回值:傳回dlt的字串描述。
- 參數:dlt要取得字串描述的data-link類型。
- 功能:取得dlt的字串描述。
最後記得data-link類型的陣列是需要被釋放的。
//free
pcap_free_datalinks(dlts);
pcap_close(handle);
函數
pcap_free_datalinks()原型:void pcap_free_datalinks(int *dlt_buf);
- 參數:dlt_buf要釋放的指標。
- 功能:釋放從pcap_list_datalinks()取得的指標。
編譯:
libpcap % gcc -I/usr/local/opt/libpcap/include -Wall -std=gnu99 -L/usr/local/opt/libpcap/lib -lpcap list-data-link-type.c -o list-data-link-type
執行結果:
libpcap % ./list-data-link-type Device: en0 1: EN10MB(Ethernet) [default] 2: PPI(Per-Packet Information) 3: IEEE802_11_RADIO(802.11 plus radiotap header) 4: IEEE802_11(802.11) 5: IEEE802_11_RADIO_AVS(802.11 plus AVS radio information header) 6: RAW(Raw IP)
另外關於修改data-link類型,可以使用函數
pcap_set_datalink()來達成,這邊就不多介紹了(修改後第二層解析方式就不一定是Ethernet了)。函數
pcap_set_datalink()原型:int pcap_set_datalink(pcap_t *p, int dlt);
- 返回值:成功傳回0,失敗傳回-1,錯誤訊息從pcap_geterr()取得。
- 參數:p一個libpcap handle。dlt要修改得類型。
- 功能:修改打開handle的data-link類型,會因為類型不同所抓到的封包完全不同方式解析。
Source code on Github
沒有留言:
張貼留言