diff options
-rw-r--r-- | epan/dissectors/packet-frame.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-hci_h1.c | 35 | ||||
-rw-r--r-- | epan/packet_info.h | 1 | ||||
-rw-r--r-- | wiretap/Makefile.common | 2 | ||||
-rw-r--r-- | wiretap/file_access.c | 5 | ||||
-rw-r--r-- | wiretap/packetlogger.c | 217 | ||||
-rw-r--r-- | wiretap/packetlogger.h | 32 | ||||
-rw-r--r-- | wiretap/wtap.h | 8 |
8 files changed, 297 insertions, 11 deletions
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index 8cff404268..49fb0b9154 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -81,6 +81,7 @@ static gboolean force_docsis_encap = FALSE; static gboolean generate_md5_hash = FALSE; static const value_string p2p_dirs[] = { + { P2P_DIR_UNKNOWN, "Unknown" }, { P2P_DIR_SENT, "Sent" }, { P2P_DIR_RECV, "Received" }, { 0, NULL } @@ -143,8 +144,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) break; case WTAP_ENCAP_BLUETOOTH_HCI: - pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent ? - P2P_DIR_SENT : P2P_DIR_RECV; + pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent; break; case WTAP_ENCAP_LAPB: @@ -283,7 +283,7 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) /* Check for existences of P2P pseudo header */ if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) { - proto_tree_add_uint(fh_tree, hf_frame_p2p_dir, tvb, + proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb, 0, 0, pinfo->p2p_dir); } @@ -574,7 +574,7 @@ proto_register_frame(void) NULL, HFILL }}, { &hf_frame_p2p_dir, - { "Point-to-Point Direction", "frame.p2p_dir", FT_UINT8, BASE_DEC, VALS(p2p_dirs), 0x0, + { "Point-to-Point Direction", "frame.p2p_dir", FT_INT8, BASE_DEC, VALS(p2p_dirs), 0x0, NULL, HFILL }}, { &hf_link_number, diff --git a/epan/dissectors/packet-hci_h1.c b/epan/dissectors/packet-hci_h1.c index 8d3bc07000..1596d8535a 100644 --- a/epan/dissectors/packet-hci_h1.c +++ b/epan/dissectors/packet-hci_h1.c @@ -48,6 +48,7 @@ static const value_string hci_h1_type_vals[] = { {0, NULL } }; static const value_string hci_h1_direction_vals[] = { + {-1, "Unknown"}, {0, "Sent"}, {1, "Rcvd"}, {0, NULL} @@ -72,14 +73,38 @@ dissect_hci_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if(tree){ ti = proto_tree_add_item(tree, proto_hci_h1, tvb, 0, 1, FALSE); hci_h1_tree = proto_item_add_subtree(ti, ett_hci_h1); + + if(pinfo->p2p_dir == P2P_DIR_SENT || + pinfo->p2p_dir == P2P_DIR_RECV) + proto_item_append_text(hci_h1_tree, " %s %s", + match_strval(pinfo->p2p_dir, + hci_h1_direction_vals), + val_to_str(type, + hci_h1_type_vals, + "Unknown 0x%02x")); + else + proto_item_append_text(hci_h1_tree, " %s", + val_to_str(type, + hci_h1_type_vals, + "Unknown 0x%02x")); } if(check_col(pinfo->cinfo, COL_INFO)){ - col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",pinfo->p2p_dir==P2P_DIR_SENT?"Sent":"Rcvd",val_to_str(type, hci_h1_type_vals, "Unknown 0x%02x")); + if(pinfo->p2p_dir == P2P_DIR_SENT || + pinfo->p2p_dir == P2P_DIR_RECV) + col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", + match_strval(pinfo->p2p_dir, + hci_h1_direction_vals), + val_to_str(type, hci_h1_type_vals, + "Unknown 0x%02x")); + else + col_add_fstr(pinfo->cinfo, COL_INFO, "%s", + val_to_str(type, hci_h1_type_vals, + "Unknown 0x%02x")); } - ti=proto_tree_add_uint(hci_h1_tree, hf_hci_h1_direction, tvb, 0, 0, pinfo->p2p_dir); + + ti=proto_tree_add_int(hci_h1_tree, hf_hci_h1_direction, tvb, 0, 0, pinfo->p2p_dir); PROTO_ITEM_SET_GENERATED(ti); - proto_item_append_text(hci_h1_tree, " %s %s", val_to_str(pinfo->p2p_dir, hci_h1_direction_vals, "0x%02x"), val_to_str(type, hci_h1_type_vals, "Unknown 0x%02x")); next_tvb = tvb_new_subset(tvb, 0, -1, -1); if(!dissector_try_port(hci_h1_table, type, next_tvb, pinfo, tree)) { @@ -99,8 +124,8 @@ proto_register_hci_h1(void) { &hf_hci_h1_direction, { "Direction", "hci_h1.direction", - FT_UINT8, BASE_HEX, VALS(hci_h1_direction_vals), 0x0, - "HCI Packet Direction Sent/Rcvd", HFILL }}, + FT_INT8, BASE_DEC, VALS(hci_h1_direction_vals), 0x0, + "HCI Packet Direction Sent/Rcvd/Unknown", HFILL }}, }; diff --git a/epan/packet_info.h b/epan/packet_info.h index 5970344f1a..c865783b71 100644 --- a/epan/packet_info.h +++ b/epan/packet_info.h @@ -29,6 +29,7 @@ #include "tvbuff.h" #include "address.h" +/* Also defined in wiretap/wtap.h */ #define P2P_DIR_UNKNOWN -1 #define P2P_DIR_SENT 0 #define P2P_DIR_RECV 1 diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common index 68c411f1e8..624473ee2a 100644 --- a/wiretap/Makefile.common +++ b/wiretap/Makefile.common @@ -61,6 +61,7 @@ NONGENERATED_C_FILES = \ network_instruments.c \ netxray.c \ ngsniffer.c \ + packetlogger.c \ pcapng.c \ pppdump.c \ radcom.c \ @@ -106,6 +107,7 @@ NONGENERATED_HEADER_FILES = \ network_instruments.h \ netxray.h \ ngsniffer.h \ + packetlogger.h \ pcapng.h \ pppdump.h \ radcom.h \ diff --git a/wiretap/file_access.c b/wiretap/file_access.c index e69df0b46f..4d325357e3 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -79,6 +79,7 @@ #include "btsnoop.h" #include "tnef.h" #include "dct3trace.h" +#include "packetlogger.h" /* The open_file_* routines should return: @@ -120,9 +121,11 @@ static wtap_open_routine_t open_routines_base[] = { k12_open, catapult_dct2000_open, ber_open, - mpeg_open, pcapng_open, btsnoop_open, + packetlogger_open, /* This type does not have a magic number, but its + * files are sometimes grabbed by mpeg_open. */ + mpeg_open, tnef_open, dct3trace_open, /* Files that don't have magic bytes at a fixed location, diff --git a/wiretap/packetlogger.c b/wiretap/packetlogger.c new file mode 100644 index 0000000000..33dbb55635 --- /dev/null +++ b/wiretap/packetlogger.c @@ -0,0 +1,217 @@ +/* packetlogger.c + * Routines for opening Apple's (Bluetooth) PacketLogger file format captures + * Copyright 2008-2009, Stephen Fisher <stephentfisher@yahoo.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Based on commview.c, Linux's BlueZ-Gnome Analyzer program and hexdumps of + * the output files from Apple's PacketLogger tool. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> + +#include "wtap.h" +#include "wtap-int.h" +#include "buffer.h" +#include "file_wrappers.h" +#include "packetlogger.h" + +typedef struct packetlogger_header { + guint32 len; + guint64 ts; + guint8 type; +} packetlogger_header_t; + +#define PACKETLOGGER_HEADER_SIZE 13 + +static gboolean packetlogger_read(wtap *wth, int *err, gchar **err_info _U_, + gint64 *data_offset); +static gboolean packetlogger_seek_read(wtap *wth, gint64 seek_off, + union wtap_pseudo_header *pseudo_header, + guchar *pd, int length, int *err, + gchar **err_info _U_); +static gboolean packetlogger_read_header(packetlogger_header_t *pl_hdr, + FILE_T fh, int *err); + + +int packetlogger_open(wtap *wth, int *err, gchar **err_info _U_) +{ + packetlogger_header_t pl_hdr; + + if(!packetlogger_read_header(&pl_hdr, wth->fh, err)) + return -1; + + /* Verify this file belongs to us */ + if(!((pl_hdr.len & 0xFFFF0000) == 0 && (pl_hdr.type < 0x04 || + pl_hdr.type == 0xFE || + pl_hdr.type == 0xFF))) + return 0; + + /* No file header. Reset the fh to 0 so we can read the first packet */ + if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) + return -1; + + /* Set up the pointers to the handlers for this file type */ + wth->subtype_read = packetlogger_read; + wth->subtype_seek_read = packetlogger_seek_read; + + wth->data_offset = 0; + wth->file_type = WTAP_FILE_PACKETLOGGER; + wth->file_encap = WTAP_ENCAP_BLUETOOTH_HCI; + wth->tsprecision = WTAP_FILE_TSPREC_USEC; + + return 1; /* Our kind of file */ +} + +static gboolean +packetlogger_read(wtap *wth, int *err, gchar **err_info _U_, gint64 *data_offset) +{ + packetlogger_header_t pl_hdr; + guint bytes_read; + + *data_offset = wth->data_offset; + + if(!packetlogger_read_header(&pl_hdr, wth->fh, err)) + return FALSE; + + buffer_assure_space(wth->frame_buffer, pl_hdr.len - 9); + bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, + pl_hdr.len - 9, + wth->fh); + if(bytes_read != pl_hdr.len - 9) { + *err = file_error(wth->fh); + if(*err == 0) + *err = WTAP_ERR_SHORT_READ; + + return FALSE; + } + + wth->data_offset += (pl_hdr.len + 4); + + wth->phdr.len = pl_hdr.len - 9; + wth->phdr.caplen = pl_hdr.len - 9; + + wth->phdr.ts.secs = (time_t) (pl_hdr.ts >> 32); + wth->phdr.ts.nsecs = (pl_hdr.ts & 0xFFFFFFFF) * 1000; + + switch(pl_hdr.type) { + + case 0 : + wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_COMMAND; + break; + case 1 : + wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_EVENT; + break; + + default : + wth->pseudo_header.bthci.channel = pl_hdr.type; + break; + } + + wth->pseudo_header.bthci.sent = P2P_DIR_UNKNOWN; + + return TRUE; +} + +static gboolean +packetlogger_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header + *pseudo_header, guchar *pd, int length, int *err, + gchar **err_info _U_) +{ + packetlogger_header_t pl_hdr; + guint bytes_read; + + if(file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + + if(!packetlogger_read_header(&pl_hdr, wth->random_fh, err)) { + if(*err == 0) + *err = WTAP_ERR_SHORT_READ; + + return FALSE; + } + + if(length != (int)pl_hdr.len - 9) { + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("packetlogger: record length %u doesn't match requested length %d", pl_hdr.len, length); + return FALSE; + } + + bytes_read = file_read(pd, 1, pl_hdr.len - 9, wth->random_fh); + if(bytes_read != (pl_hdr.len - 9)) { + *err = file_error(wth->random_fh); + if(*err == 0) + *err = WTAP_ERR_SHORT_READ; + + return FALSE; + } + + switch(pl_hdr.type) { + + case 0 : + pseudo_header->bthci.channel = BTHCI_CHANNEL_COMMAND; + break; + case 1 : + pseudo_header->bthci.channel = BTHCI_CHANNEL_EVENT; + break; + + default : + pseudo_header->bthci.channel = pl_hdr.type; + break; + } + + pseudo_header->bthci.sent = P2P_DIR_UNKNOWN; + + return TRUE; +} + +static gboolean +packetlogger_read_header(packetlogger_header_t *pl_hdr, FILE_T fh, int *err) +{ + guint bytes_read = 0; + + bytes_read += file_read(&pl_hdr->len, 4, 1, fh); + bytes_read += file_read(&pl_hdr->ts, 8, 1, fh); + bytes_read += file_read(&pl_hdr->type, 1, 1, fh); + + /* Convert multi-byte values from big endian to host endian */ + pl_hdr->len = GUINT32_FROM_BE(pl_hdr->len); + pl_hdr->ts = GUINT64_FROM_BE(pl_hdr->ts); + + if(bytes_read < PACKETLOGGER_HEADER_SIZE) { + *err = file_error(fh); + if(*err == 0 && bytes_read > 0) + *err = WTAP_ERR_SHORT_READ; + + return FALSE; + } + + return TRUE; +} diff --git a/wiretap/packetlogger.h b/wiretap/packetlogger.h new file mode 100644 index 0000000000..6a34def720 --- /dev/null +++ b/wiretap/packetlogger.h @@ -0,0 +1,32 @@ +/* packetlogger.h + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + */ + +#ifndef __PACKETLOGGER_H__ +#define __PACKETLOGGER_H__ + +int packetlogger_open(wtap *wth, int *err, gchar **err_info _U_); + +#endif /* __PACKETLOGGER_H__ */ + diff --git a/wiretap/wtap.h b/wiretap/wtap.h index cbcee2e74e..1ead2e817d 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -269,6 +269,7 @@ extern "C" { #define WTAP_FILE_X2E_XORAYA 52 #define WTAP_FILE_TNEF 53 #define WTAP_FILE_DCT3TRACE 54 +#define WTAP_FILE_PACKETLOGGER 55 #define WTAP_NUM_FILE_TYPES wtap_get_num_file_types() @@ -427,9 +428,14 @@ struct ascend_phdr { guint32 task; /* Task number */ }; +/* Also defined in epan/packet_info.h */ +#define P2P_DIR_UNKNOWN -1 +#define P2P_DIR_SENT 0 +#define P2P_DIR_RECV 1 + /* Packet "pseudo-header" for point-to-point links with direction flags. */ struct p2p_phdr { - gboolean sent; /* TRUE=sent, FALSE=received */ + int sent; /* TRUE=sent, FALSE=received, -1=unknown*/ }; /* |