一個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
沒有留言:
張貼留言