Add support for reading Apple's Bluetooth PacketLogger capture files to

wiretap.  Modify various other locations to accommodate the fact that
PacketLogger files do not specify the direction of packets. 


svn path=/trunk/; revision=27463
This commit is contained in:
Stephen Fisher 2009-02-16 07:24:04 +00:00
parent 5742ede54c
commit 18f3436e85
8 changed files with 297 additions and 11 deletions

View File

@ -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,

View File

@ -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 }},
};

View File

@ -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

View File

@ -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 \

View File

@ -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,

217
wiretap/packetlogger.c Normal file
View File

@ -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;
}

32
wiretap/packetlogger.h Normal file
View File

@ -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__ */

View File

@ -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*/
};
/*