From d574fd89f4f5698a5b14014efe0830eecce7a991 Mon Sep 17 00:00:00 2001 From: Michal Labedzki Date: Sun, 16 Feb 2014 17:01:45 +0100 Subject: Add support for Bluetooth Linux Monitor BlueZ 5/Linux Kernel introduced new way to sniffing Bluetooth interfaces. We are ready to use it. Libpcap provide new interface called "bluetooth-monior". Also fix trivial typos. Change-Id: Ic608a3d8553bbebbb21f2733ec92c758cbf8f707 Reviewed-on: https://code.wireshark.org/review/253 Reviewed-by: Alexis La Goutte Tested-by: Alexis La Goutte --- wiretap/pcap-common.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- wiretap/wtap.h | 11 +++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) (limited to 'wiretap') diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c index e0e0b1a653..6ce3d08d33 100644 --- a/wiretap/pcap-common.c +++ b/wiretap/pcap-common.c @@ -419,7 +419,8 @@ static const struct { { 252, WTAP_ENCAP_WIRESHARK_UPPER_PDU}, /* Netlink Protocol (nlmon devices) */ { 253, WTAP_ENCAP_NETLINK }, - + /* Bluetooth Linux Monitor */ + { 254, WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR }, /* * To repeat: * @@ -698,6 +699,7 @@ wtap_encap_requires_phdr(int encap) { (encap == WTAP_ENCAP_ERF) || (encap == WTAP_ENCAP_I2C) || (encap == WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR) || + (encap == WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR) || (encap == WTAP_ENCAP_PPP_WITH_PHDR) ) { return TRUE; @@ -1313,6 +1315,28 @@ pcap_read_bt_pseudoheader(FILE_T fh, return TRUE; } +static gboolean +pcap_read_bt_monitor_pseudoheader(FILE_T fh, + union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) +{ + int bytes_read; + struct libpcap_bt_monitor_phdr phdr; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(&phdr, + sizeof (struct libpcap_bt_monitor_phdr), fh); + if (bytes_read != sizeof (struct libpcap_bt_monitor_phdr)) { + *err = file_error(fh, err_info); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return FALSE; + } + + pseudo_header->btmon.adapter_id = g_ntohs(phdr.adapter_id); + pseudo_header->btmon.opcode = g_ntohs(phdr.opcode); + return TRUE; +} + static gboolean pcap_read_llcp_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) @@ -1683,6 +1707,25 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, phdr_len = (int)sizeof (struct libpcap_bt_phdr); break; + case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR: + if (check_packet_size && + packet_size < sizeof (struct libpcap_bt_monitor_phdr)) { + /* + * Uh-oh, the packet isn't big enough to even + * have a pseudo-header. + */ + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("pcap: libpcap bluetooth monitor file has a %u-byte packet, too small to have even a pseudo-header", + packet_size); + return -1; + } + if (!pcap_read_bt_monitor_pseudoheader(fh, + &phdr->pseudo_header, err, err_info)) + return -1; /* Read error */ + + phdr_len = (int)sizeof (struct libpcap_bt_monitor_phdr); + break; + case WTAP_ENCAP_NFC_LLCP: if (check_packet_size && packet_size < LLCP_HEADER_LEN) { *err = WTAP_ERR_BAD_FILE; @@ -1921,6 +1964,10 @@ pcap_get_phdr_size(int encap, const union wtap_pseudo_header *pseudo_header) hdrsize = (int)sizeof (struct libpcap_ppp_phdr); break; + case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR: + hdrsize = (int)sizeof (struct libpcap_bt_monitor_phdr); + break; + default: hdrsize = 0; break; @@ -1941,6 +1988,7 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse guint8 erf_hdr[ sizeof(struct erf_mc_phdr)]; struct i2c_file_hdr i2c_hdr; struct libpcap_bt_phdr bt_hdr; + struct libpcap_bt_monitor_phdr bt_monitor_hdr; struct libpcap_ppp_phdr ppp_hdr; size_t size; @@ -2119,6 +2167,15 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse wdh->bytes_dumped += sizeof bt_hdr; break; + case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR: + bt_monitor_hdr.adapter_id = GUINT16_TO_BE(pseudo_header->btmon.adapter_id); + bt_monitor_hdr.opcode = GUINT16_TO_BE(pseudo_header->btmon.opcode); + + if (!wtap_dump_file_write(wdh, &bt_monitor_hdr, sizeof bt_monitor_hdr, err)) + return FALSE; + wdh->bytes_dumped += sizeof bt_monitor_hdr; + break; + case WTAP_ENCAP_PPP_WITH_PHDR: ppp_hdr.direction = (pseudo_header->p2p.sent ? LIBPCAP_PPP_PHDR_SENT : LIBPCAP_PPP_PHDR_RECV); if (!wtap_dump_file_write(wdh, &ppp_hdr, sizeof ppp_hdr, err)) diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 95459d5462..1831565030 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -684,13 +684,22 @@ struct catapult_dct2000_phdr #define LIBPCAP_BT_PHDR_RECV 1 /* - * Header prepended by libpcap to each bluetooth hci h:4 frame. + * Header prepended by libpcap to each bluetooth hci h4 frame. * Values in network byte order */ struct libpcap_bt_phdr { guint32 direction; /* Bit 0 hold the frame direction. */ }; +/* + * Header prepended by libpcap to each bluetooth monitor frame + * Values in network byte order + */ +struct libpcap_bt_monitor_phdr { + guint16 adapter_id; + guint16 opcode; +}; + #define LIBPCAP_PPP_PHDR_RECV 0 #define LIBPCAP_PPP_PHDR_SENT 1 -- cgit v1.2.3