summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-frame.c8
-rw-r--r--epan/dissectors/packet-hci_h1.c35
-rw-r--r--epan/packet_info.h1
-rw-r--r--wiretap/Makefile.common2
-rw-r--r--wiretap/file_access.c5
-rw-r--r--wiretap/packetlogger.c217
-rw-r--r--wiretap/packetlogger.h32
-rw-r--r--wiretap/wtap.h8
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*/
};
/*