diff -Nur ./Makefile.am ../ethereal-0.9.5-patched/Makefile.am --- ./Makefile.am 2002-06-29 02:30:29.000000000 +0200 +++ ../ethereal-0.9.5-patched/Makefile.am 2002-09-13 20:05:44.000000000 +0200 @@ -331,7 +331,14 @@ packet-yppasswd.c \ packet-ypserv.c \ packet-ypxfr.c \ - packet-zebra.c + packet-zebra.c \ + packet-affix-hci.c \ + packet-bthci-cmd.c \ + packet-bthci-evt.c \ + packet-btacl.c \ + packet-btsco.c \ + packet-btl2cap.c \ + packet-btbnep.c if HAVE_PLUGINS plugin_src = \ @@ -483,7 +490,8 @@ packet-ypbind.h \ packet-yppasswd.h \ packet-ypserv.h \ - packet-ypxfr.h + packet-ypxfr.h \ + packet-bthci-cmd.h ETHEREAL_COMMON_SRC = \ aftypes.h \ diff -Nur ./packet-affix-hci.c ../ethereal-0.9.5-patched/packet-affix-hci.c --- ./packet-affix-hci.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-affix-hci.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,183 @@ +/* packet-affix-hci.c + * Routines for the Affix HCI dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include + +/* Initialize the protocol and registered fields */ +static int proto_affix_hci = -1; + +/* Initialize the subtree pointers */ +static gint ett_affix_hci = -1; + + +/* Code to actually dissect the packets */ +static void +dissect_affix_hci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + + guint16 ptype, rtype; + tvbuff_t *next_tvb; + tvbuff_t *affix_hci_tvb; + dissector_handle_t bthci_cmd_handle, bthci_evt_handle; + dissector_handle_t btacl_handle, btsco_handle; + + proto_item *ti; + proto_tree *affix_hci_tree; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "affix_hci"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + ptype = tvb_get_ntohs(tvb, 0); + rtype = tvb_get_guint8(tvb, 16); + + if (ptype == 0) { /* Packet has been received */ + pinfo->p2p_dir = P2P_DIR_RECV; + if (rtype == 2) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Incoming ACL"); + } + if (rtype == 3) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Incoming SCO"); + } + if (rtype == 4) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Event"); + } + } + else if (ptype == 4) { /* Packet has been sent */ + pinfo->p2p_dir = P2P_DIR_SENT; + if (rtype == 1) { /* Command */ + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Command"); + } + else if (rtype == 2) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Outgoing ACL"); + } + else if (rtype == 3) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_set_str(pinfo->cinfo, COL_INFO, "Outgoing SCO"); + } + + } + + affix_hci_tvb = tvb_new_subset(tvb, 16, -1, -1); + next_tvb = tvb_new_subset(tvb, 17, -1, -1); + + ti = proto_tree_add_item(tree, proto_affix_hci, affix_hci_tvb, 0, -1, FALSE); + affix_hci_tree = proto_item_add_subtree(ti, ett_affix_hci); + + if (rtype == 1) { /* Command */ + bthci_cmd_handle = find_dissector("bthci_cmd"); + call_dissector(bthci_cmd_handle, next_tvb, pinfo, tree); + } + else if (rtype == 2) { /* ACL */ + btacl_handle = find_dissector("btacl"); + call_dissector(btacl_handle, next_tvb, pinfo, tree); + } + else if (rtype == 3) { /* SCO */ + btsco_handle = find_dissector("btsco"); + call_dissector(btsco_handle, next_tvb, pinfo, tree); + } + if (rtype == 4) { /* Event */ + bthci_evt_handle = find_dissector("bthci_evt"); + call_dissector(bthci_evt_handle, next_tvb, pinfo, tree); + } +} + + +/* Register the protocol with Ethereal */ + +/* this format is require because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_affix_hci(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + }; + +/* Setup protocol subtree array */ + static gint *ett[] = { + &ett_affix_hci, + }; + +/* Register the protocol name and description */ + proto_affix_hci = proto_register_protocol("Affix HCI", + "Affix_HCI", "affix_hci"); + + register_dissector("affix_hci", dissect_affix_hci, proto_affix_hci); + + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_affix_hci, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_bthci(void) +{ + dissector_handle_t affix_hci_handle; + + affix_hci_handle = find_dissector("affix_hci"); +} + + diff -Nur ./packet-btacl.c ../ethereal-0.9.5-patched/packet-btacl.c --- ./packet-btacl.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-btacl.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,372 @@ +/* packet-btacl.c + * Routines for the Bluetooth ACL dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include + +/* Initialize the protocol and registered fields */ +static int proto_btacl = -1; +static int hf_btacl_chandle = -1; +static int hf_btacl_pb_flag = -1; +static int hf_btacl_bc_flag = -1; +static int hf_btacl_length = -1; +static int hf_btacl_data = -1; + +/* Initialize the subtree pointers */ +static gint ett_btacl = -1; + + +static const value_string pb_flag_vals[] = { + {1, "Continuing Fragment"}, + {2, "Start Fragment"}, +}; + +static const value_string bc_flag_vals[] = { + {0, "Point-To-Point"}, + {1, "Active Broadcast"}, + {2, "Piconet Broadcast"}, +}; + +typedef struct { + guint16 handle; + struct l2cap_packet *l2p; +} handle_info; +#define HANDLE_TABLE_SIZE 20 + +static handle_info handle_table[HANDLE_TABLE_SIZE]; + +struct l2cap_packet { + guint8 data [65540]; + guint32 packet_len; + guint32 recvd_len; +}; + +static struct l2cap_packet *add_l2p(guint16 handle) { + handle_info *t = handle_table; + int i; + + for (i=0; i> 12; + + + /* determine if packet is fragmented */ + if (pb_flag == 1) { /* Continuing fragment */ + fragmented = TRUE; + } + else if (pb_flag == 2) { /* Start fragment */ + if (length < 2) { + fragmented = TRUE; + } + else { + l2cap_length = tvb_get_letohs(tvb, 4); + fragmented = ((l2cap_length + 4) != length); + } + } + else { /* unknown pb_flag */ + fragmented = FALSE; + } + + + if (!fragmented) { + /* call L2CAP dissector */ + next_tvb = tvb_new_subset(tvb, 4, -1, -1); + btl2cap_handle = find_dissector("btl2cap"); + call_dissector(btl2cap_handle, next_tvb, pinfo, tree); + } + else { + proto_tree_add_item(btacl_tree, hf_btacl_data, tvb, 4, -1, TRUE); + + if (pinfo->fd->flags.visited == 0) { /* This is the first pass */ + + chandle = tvb_get_letohs(tvb, 0) & 0x0FFF; + + /* same connection handle but differnet direction needs to be + distinguished, therefore we set the highest bit of the + handle for outgoing packets */ + if (pinfo->p2p_dir == P2P_DIR_RECV) { + handle = chandle; + } + else { + handle = chandle + 0x8000; + } + + + l2p = NULL; + if (pb_flag == 2) { /* Start Fragment */ + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, " (Start Fragment)"); + + if (get_l2p(handle)) { /* Error: There is still data for the same handle */ + fprintf(stderr, "Incomplete L2CAP packet detected\n"); + } + else { /* OK: Start reassembly */ + if ((l2p = add_l2p(handle))) { + l2p->packet_len = 65540; /* Maybe we don't know the length now */ + /* So we have to set it to maximum */ + + /* memcpy the data */ + tvb_memcpy(tvb, l2p->data, 4, length); + l2p->recvd_len = length; + } + else { + fprintf(stderr, "no more handles!\n"); + } + } + } + + if (pb_flag == 1) { /* Continuing Fragment */ + if (!(l2p = get_l2p(handle))) { /* Error: Cont fragment without start */ + fprintf(stderr, "Cont. fragment without start detected!\n"); + } + else { /* OK: Continue reassembly */ + + /* memcpy the data */ + tvb_memcpy(tvb, (l2p->data)+l2p->recvd_len, 4, length); + l2p->recvd_len += length; + } + } + + + if (l2p) { + if (l2p->recvd_len > 1) { /* We have collected enough bytes */ + l2p->packet_len = ((l2p->data)[0])+256*((l2p->data)[1])+4; + } + + if (l2p->recvd_len > l2p->packet_len) { + fprintf(stderr, "Packet too long!\n"); + del_l2p(handle); + l2p = NULL; + } + + else if (l2p->recvd_len == l2p->packet_len) { + + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, " (End Fragment)"); + + reassembled_packet = malloc(sizeof(struct l2cap_packet)); + memcpy(reassembled_packet, l2p, sizeof(struct l2cap_packet)); + l2p = reassembled_packet; + + p_add_proto_data(pinfo->fd, proto_btacl, reassembled_packet); + + del_l2p(handle); + } + + else { /* Packet is not complete */ + l2p = NULL; + if (pb_flag == 1) { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, " (Continuation Fragment)"); + } + } + } + } + else { /* This is an additional pass */ + l2p = p_get_proto_data(pinfo->fd, proto_btacl); /* Is there a reassembled packet saved ? */ + } + + if (l2p) { + next_tvb = tvb_new_real_data(l2p->data, l2p->packet_len, + l2p->packet_len); + tvb_set_child_real_data_tvbuff(tvb, next_tvb); + add_new_data_source(pinfo, next_tvb, "Reassembled L2CAP"); + + /* call L2CAP dissector */ + btl2cap_handle = find_dissector("btl2cap"); + call_dissector(btl2cap_handle, next_tvb, pinfo, tree); + } + + } + +} + + +/* Register the protocol with Ethereal */ + +/* this format is require because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_btacl(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_btacl_chandle, + { "Connection Handle", "btacl.chandle", + FT_UINT16, BASE_HEX, NULL, 0x0FFF, + "Connection Handle" } + }, + { &hf_btacl_pb_flag, + { "PB Flag", "btacl.pb_flag", + FT_UINT16, BASE_BIN, VALS(pb_flag_vals), 0x3000, + "Packet Boundary Flag" } + }, + { &hf_btacl_bc_flag, + { "BC Flag", "btacl.bc_flag", + FT_UINT16, BASE_BIN, VALS(bc_flag_vals), 0xC000, + "Broadcast Flag" } + }, + { &hf_btacl_length, + { "Data Total Length", "btacl.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Data Total Length" } + }, + { &hf_btacl_data, + { "Data", "btacl.data", + FT_NONE, BASE_NONE, NULL, 0x0, + "Data" } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btacl, + }; + +/* Register the protocol name and description */ + proto_btacl = proto_register_protocol("Bluetooth ACL Packet", + "ACL", "btacl"); + + register_dissector("btacl", dissect_btacl, proto_btacl); + + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btacl, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + register_init_routine(l2cap_defragment_init); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_btacl(void) +{ + dissector_handle_t btacl_handle; + + btacl_handle = find_dissector("btacl"); + +} + + diff -Nur ./packet-btbnep.c ../ethereal-0.9.5-patched/packet-btbnep.c --- ./packet-btbnep.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-btbnep.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,684 @@ +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ + +/* packet-btbnep.c + * Routines for the Bluetooth BNEP dissection + * Copyright 2002, Wolfgang Hansmann + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include +#include + +#include "packet-btbnep.h" + +extern dissector_table_t ethertype_dissector_table; + +/* Initialize the protocol and registered fields */ +static int proto_btbnep = -1; + +static int hf_btbnep_type = -1; +static int hf_btbnep_extflag = -1; + +static int hf_btbnep_exthdr_type = 1; +static int hf_btbnep_exthdr_extflag = 1; +static int hf_btbnep_exthdr_len = 1; + +static int hf_btbnep_cmd_type = 1; + +static int hf_btbnep_conn_resp_msg = -1; + +static int hf_btbnep_src = -1; +static int hf_btbnep_dst = -1; +static int hf_btbnep_proto = -1; + +static int hf_btbnep_src_uuid = -1; +static int hf_btbnep_dst_uuid = -1; + +static int hf_btbnep_pset_list_len = -1; + +static int hf_btbnep_pres_msg = -1; +static int hf_btbnep_mres_msg = -1; + +/* Initialize the subtree pointers */ + +static gint ett_btbnep = -1; +static gint ett_btbnep_ethgen = -1; +static gint ett_btbnep_eth = 1; +static gint ett_btbnep_ethdst = 1; +static gint ett_btbnep_ethsrc = 1; +static gint ett_btbnep_exthdr = 1; +static gint ett_btbnep_cmd = 1; + +static dissector_handle_t data_handle; + +static const value_string vs_extension_type[] = { + {0x0, "Control Extension Header"}, + {0x0, NULL} +}; + +static const value_string vs_type[] = { + {BTBNEP_TYPE_GENERAL_ETHERNET, "General Ethernet"}, + {BTBNEP_TYPE_CONTROL, "Control Packet"}, + {BTBNEP_TYPE_COMPRESSED_ETHERNET, "Compressed Ethernet"}, + {BTBNEP_TYPE_COMPRESSED_ETHERNET_SOURCE_ONLY, + "Compressed Ethernet Source only"}, + {BTBNEP_TYPE_COMPRESSED_ETHERNET_DEST_ONLY, + "Compressed Ethernet Destination only"}, + {0x0, NULL} +}; + +static const value_string vs_control_type[] = { + {BTBNEP_CONTROL_CMD_NOT_UNDERSTOOD, "Command not understood"}, + {BTBNEP_SETUP_CONN_REQ_MSG, "Setup Connection Request"}, + {BTBNEP_SETUP_CONN_RESP_MSG, "Setup Connection Response"}, + {BTBNEP_FILTER_NET_TYPE_SET_MSG, "Filter Net Type Set"}, + {BTBNEP_FILTER_NET_TYPE_RESP_MSG, "Filter Net Type Response"}, + {BTBNEP_FILTER_MULTI_ADDR_SET_MSG, "Multicast Addr. Set"}, + {BTBNEP_FILTER_MULTI_ADDR_RESP_MSG, "Multicast Addr. Response"}, + {0x0, NULL} +}; + +static const value_string vs_conn_resp_msg[] = { + {BTBNEP_CONN_MSG_SUCCESS, "Operation Successful"}, + {BTBNEP_CONN_MSG_INV_DST_UUID, "Operation Failed: Invalid Dest. Service UUID"}, + {BTBNEP_CONN_MSG_INV_SRC_UUID, "Operation Failed: Invalid Src. Service UUIID"}, + {BTBNEP_CONN_MSG_INV_UUID_SIZE, "Operation Failed: Invalid Service UUID Size"}, + {BTBNEP_CONN_MSG_CONN_NOT_ALLOWED, "Operation Failed: Connection not allowed"}, + {0x0, NULL} +}; + +static const value_string vs_proto_filter_resp_msg[] = { + {BTBNEP_FLT_SUCCESS, "Operation Successful"}, + {BTBNEP_FLT_UNSUPPORTED, "Unsupported Request"}, + {BTBNEP_FLT_INV_RANGE, "Operation Failed: Invalid " + "Networking Protocol Range"}, + {BTBNEP_FLT_LIMIT_REACHED, "Operation Failed: Max. " + "Protocol Filter Limit Reached"}, + {BTBNEP_CONN_MSG_CONN_NOT_ALLOWED, "Operation Failed: " + "Unable to fulfill request due to security reasons"}, + {0x0, NULL} +}; + +static const value_string vs_mc_filter_resp_msg[] = { + {BTBNEP_MC_SUCCESS, "Operation Successful"}, + {BTBNEP_MC_UNSUPPORTED, "Unsupported Request"}, + {BTBNEP_MC_INV_RANGE, "Operation Failed: Invalid Multicast Addr. Range"}, + {BTBNEP_MC_LIMIT_REACHED, "Operation Failed: Max. Multicast Address " + "Filter Limit reached"}, + {BTBNEP_MC_SEC_NOT_ALLOWED, "Operation Failed: Unable to fulfill " + "request due to security reasons"}, + {0x0, NULL} +}; + + +static int dissect_type_ethfull(tvbuff_t *tvb, proto_tree *tree, int off, + guint16 *ethertype) { + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 14) { + proto_tree_add_text(tree, tvb, off, len, "Garbled General " + "Ethernet Packet Type Header"); + return -1; + } + + proto_tree_add_item(tree, hf_btbnep_dst, tvb, off, 6, FALSE); + proto_tree_add_item(tree, hf_btbnep_src, tvb, off + 6, 6, FALSE); + proto_tree_add_uint(tree, hf_btbnep_proto, tvb, off + 12, 2, FALSE); + + *ethertype = tvb_get_ntohs(tvb, off + 12); + + return 14; +} + + +static int dissect_type_eth(tvbuff_t *tvb, proto_tree *tree, int off, + guint16 *ethertype) { + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, len, "Garbled Compressed " + "Ethernet Packet Type Header"); + return -1; + } + proto_tree_add_item(tree, hf_btbnep_proto, tvb, off, 2, FALSE); + + *ethertype = tvb_get_ntohs(tvb, off); + + return 2; +} + + +static int dissect_type_ethsrc(tvbuff_t *tvb, proto_tree *tree, int off, + guint16 *ethertype) { + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 8) { + proto_tree_add_text(tree, tvb, off, len, "Garbled Compressed " + "Ethernet Source only Packet Type Header"); + return -1; + } + + proto_tree_add_item(tree, hf_btbnep_src, tvb, off, 6, FALSE); + proto_tree_add_item(tree, hf_btbnep_proto, tvb, off + 6, 2, FALSE); + + *ethertype = tvb_get_ntohs(tvb, off + 6); + + return 8; +} + + +static int dissect_type_ethdst(tvbuff_t *tvb, proto_tree *tree, int off, + guint16 *ethertype) { + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 8) { + proto_tree_add_text(tree, tvb, off, len, "Garbled Compressed " + "Ethernet Destination only Packet Type Header"); + return -1; + } + + proto_tree_add_item(tree, hf_btbnep_dst, tvb, off, 6, FALSE); + proto_tree_add_item(tree, hf_btbnep_proto, tvb, off + 6, 2, FALSE); + + *ethertype = tvb_get_ntohs(tvb, off + 6); + + return 8; +} + + +static int dissect_extension(tvbuff_t *tvb, proto_tree *tree, int off) { + + proto_tree *st; + proto_item *it; + int len, size; + guint8 type; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, len, "Garbled Extension Header"); + return -1; + } + + type = tvb_get_guint8(tvb, off); + + it = proto_tree_add_item(tree, hf_btbnep_cmd_type, tvb, off, 1, FALSE); + st = proto_item_add_subtree(it, ett_btbnep_exthdr); + + proto_tree_add_item(st, hf_btbnep_exthdr_type, tvb, off, 1, FALSE); + proto_tree_add_item(st, hf_btbnep_exthdr_extflag, tvb, off, 1, FALSE); + proto_tree_add_item(st, hf_btbnep_exthdr_len, tvb, off + 1, 1, FALSE); + + switch(type & 0x7f) { + case 0x0: + size = dissect_type_control(tvb, tree, off + 2); + if (size == -1) + return -1; + break; + default: + proto_tree_add_text(tree, tvb, off + 1, -1, + "Unknown Extension type 0x%x", type & 0x7f); + return -1; + } + return 2 + size; +} + + +static int dissect_ctr_err(tvbuff_t *tvb, proto_tree *tree, int off) { + + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 1) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + proto_tree_add_text(tree, tvb, off, 1, "Unknown opcode was: 0x%x", + tvb_get_guint8(tvb, off)); + return 1; +} + + +static int dissect_ctr_conreq(tvbuff_t *tvb, proto_tree *tree, int off) { + + gint uuid_size; + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 1) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + uuid_size = tvb_get_guint8(tvb, off); + proto_tree_add_text(tree, tvb, off, 1, "UUID Size: %d", + uuid_size); + if (len < 1 + uuid_size * 2) { + proto_tree_add_text(tree, tvb, off + 1, -1, "Garbled"); + return -1; + } + proto_tree_add_bytes(tree, hf_btbnep_dst_uuid, tvb, off + 1, uuid_size, + tvb_get_ptr(tvb, off + 1, uuid_size)); + proto_tree_add_bytes(tree, hf_btbnep_src_uuid, tvb, off + 1 + uuid_size, + uuid_size, + tvb_get_ptr(tvb, off + 1 + uuid_size, uuid_size)); + + return 1 + 2 * uuid_size; +} + + +static int dissect_ctr_conres(tvbuff_t *tvb, proto_tree *tree, int off) { + + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + proto_tree_add_item(tree, hf_btbnep_conn_resp_msg, tvb, off, 2, 0); + return 2; +} + + +static int dissect_ctr_pset(tvbuff_t *tvb, proto_tree *tree, int off) { + + int i, len, off_tmp; + guint16 list_length; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + + list_length = tvb_get_ntohs(tvb, off); + proto_tree_add_uint(tree, hf_btbnep_pset_list_len, tvb, + off, 2, list_length); + if (len < 2 + list_length || (list_length % 4) != 0) { + proto_tree_add_text(tree, tvb, off + 2, -1, "Garbled"); + return -1; + } + + for (off_tmp = 2, i = 0; i < list_length; i += 4, off_tmp += 4) { + proto_tree_add_text(tree, tvb, off_tmp, 4, + "Allowed Protocol Range: 0x%x - 0x%x", + tvb_get_ntohs(tvb, off_tmp), + tvb_get_ntohs(tvb, off_tmp + 2)); + } + + return 2 + list_length; +} + + +static int dissect_ctr_pres(tvbuff_t *tvb, proto_tree *tree, int off) { + + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + + proto_tree_add_uint(tree, hf_btbnep_pres_msg, tvb, off, 2, + tvb_get_ntohs(tvb, off)); + + return 2; +} + + +static int dissect_ctr_mset(tvbuff_t *tvb, proto_tree *tree, int off) { + + int i, len, off_tmp; + guint16 list_length; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + + list_length = tvb_get_ntohs(tvb, off); + proto_tree_add_uint(tree, hf_btbnep_pset_list_len, tvb, + off, 2, list_length); + if (len < 2 + list_length || (list_length % 12) != 0) { + proto_tree_add_text(tree, tvb, off + 2, -1, "Garbled"); + return -1; + } + + for (off_tmp = off + 2, i = 0; i < list_length; i += 12, off_tmp += 12) { + + char buf1[32], buf2[32]; + + strncpy(buf1, ether_to_str(tvb_get_ptr(tvb, off_tmp, 6)), 32); + strncpy(buf2, ether_to_str(tvb_get_ptr(tvb, off_tmp + 6, 6)), 32); + buf1[31] = buf2[31] = 0; + + proto_tree_add_text(tree, tvb, off_tmp, 4, + "Allowed Multicast Range: %s - %s", buf1, buf2); + } + return 2 + list_length; +} + + +static int dissect_ctr_mres(tvbuff_t *tvb, proto_tree *tree, int off) { + + int len; + + len = tvb_length_remaining(tvb, off); + if (len < 2) { + proto_tree_add_text(tree, tvb, off, -1, "Garbled"); + return -1; + } + + proto_tree_add_uint(tree, hf_btbnep_mres_msg, tvb, off, 2, + tvb_get_ntohs(tvb, off + 1)); + return 2; +} + + +static int dissect_type_control(tvbuff_t *tvb, proto_tree *tree, int off) { + + proto_tree *st; + proto_item *it; + int len, size; + guint8 type; + + len = tvb_length_remaining(tvb, off); + if (len < 1) { + proto_tree_add_text(tree, tvb, off, len, "Garbled Compressed " + "Command Packet"); + return -1; + } + + it = proto_tree_add_item(tree, hf_btbnep_cmd_type, tvb, off, 1, FALSE); + st = proto_item_add_subtree(it, ett_btbnep_cmd); + + type = tvb_get_guint8(tvb, off); + + off++; + + switch(type) { + case BTBNEP_CONTROL_CMD_NOT_UNDERSTOOD: + size = dissect_ctr_err(tvb, st, off); + break; + case BTBNEP_SETUP_CONN_REQ_MSG: + size = dissect_ctr_conreq(tvb, st, off); + break; + case BTBNEP_SETUP_CONN_RESP_MSG: + size = dissect_ctr_conres(tvb, st, off); + break; + case BTBNEP_FILTER_NET_TYPE_SET_MSG: + size = dissect_ctr_pset(tvb, st, off); + break; + case BTBNEP_FILTER_NET_TYPE_RESP_MSG: + size = dissect_ctr_pres(tvb, st, off); + break; + case BTBNEP_FILTER_MULTI_ADDR_SET_MSG: + size = dissect_ctr_mset(tvb, st, off); + break; + case BTBNEP_FILTER_MULTI_ADDR_RESP_MSG: + size = dissect_ctr_mres(tvb, st, off); + break; + default: + /* TODO: display error */ + size = -1; + } + if (size == -1) + return -1; + + proto_item_set_len(it, 1 + size); + return size + 1; +} + +/* Code to actually dissect the packets */ + +static void dissect_btbnep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + gchar *col_info; + proto_item *ti; + proto_tree *st; + guint8 type, off = 1, size, extflag; + guint16 ethertype = 0; + tvbuff_t *next_tvb; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "BNEP"); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + if (tvb_length_remaining(tvb, 0) < 1) + return; + + ti = proto_tree_add_item(tree, proto_btbnep, tvb, 0, -1, FALSE); + st = proto_item_add_subtree(ti, ett_btbnep); + + proto_tree_add_item(st, hf_btbnep_type, tvb, 0, 1, TRUE); + proto_tree_add_item(st, hf_btbnep_extflag, tvb, 0, 1, TRUE); + + type = tvb_get_guint8(tvb, 0); + extflag = type & 0x80; + + col_info = val_to_str(type & 0x7f, VALS(vs_type), "%s"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, col_info ? + col_info : "(Unknown)"); + + switch (type) { + case BTBNEP_TYPE_GENERAL_ETHERNET: + size = dissect_type_ethfull(tvb, st, off, ðertype); + break; + case BTBNEP_TYPE_CONTROL: + size = dissect_type_control(tvb, tree, off); + break; + case BTBNEP_TYPE_COMPRESSED_ETHERNET: + size = dissect_type_eth(tvb, st, off, ðertype); + break; + case BTBNEP_TYPE_COMPRESSED_ETHERNET_SOURCE_ONLY: + size = dissect_type_ethsrc(tvb, st, off, ðertype); + break; + case BTBNEP_TYPE_COMPRESSED_ETHERNET_DEST_ONLY: + size = dissect_type_ethdst(tvb, st, off, ðertype); + break; + default: + /* error */ + size = -1; + } + + if (size < 2) + return; + + off += size; + + while (extflag) { + size = dissect_extension(tvb, tree, off); + off += size; + } + + /* set length of ti */ + + next_tvb = tvb_new_subset(tvb, off, -1, -1); + + if (ethertype) { + /* call next dissector */ + if (!dissector_try_port(ethertype_dissector_table, (guint32) ethertype, + next_tvb, pinfo, tree)) { + /* unknown protocol. declare as data */ + call_dissector(data_handle, next_tvb, pinfo, tree); + } + } +} + + + +void proto_register_btbnep(void) +{ + static hf_register_info hf[] = { + {&hf_btbnep_type, + {"Type", "btbnep.type", + FT_UINT8, BASE_HEX, &vs_type, 0x7f, + "BNEP Packet Type"} + }, + {&hf_btbnep_extflag, + {"Extension flag", "btbnep.extflag", + FT_UINT8, BASE_HEX, NULL, 0x80, + "Extension flag"} + }, + {&hf_btbnep_src, + {"Source MAC", "btbnep.src", + FT_ETHER, BASE_NONE, NULL, 0x0, "Source MAC"} + }, + {&hf_btbnep_dst, + {"Destination MAC", "btbnep.dst", + FT_ETHER, BASE_NONE, NULL, 0x0, "Destination MAC"} + }, + {&hf_btbnep_proto, + {"Protocol type", "btbnep.proto", + FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0, "Protocol Type"} + }, + {&hf_btbnep_cmd_type, + {"Command type", "btbnep.cmdtype", + FT_UINT8, BASE_HEX, VALS(vs_control_type), 0x0, + "Command Type"} + }, + {&hf_btbnep_exthdr_type, + {"Extension Type", "btbnep.ext_type", + FT_UINT8, BASE_HEX, VALS(vs_extension_type), 0x0, + "Extension Type"} + }, + {&hf_btbnep_exthdr_extflag, + {"Extension Flag", "btbnep.ext_flag", + FT_BOOLEAN, BASE_HEX, NULL, 0x80, + "Extension Type"} + }, + {&hf_btbnep_exthdr_len, + {"Extension Length", "btbnep.ext_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Extension Length"} + }, + {&hf_btbnep_src_uuid, + {"Source Service UUID", "btbnep.SS_uuid", + FT_BYTES, BASE_HEX, NULL, 0x0, "Source Service UUID"} + }, + {&hf_btbnep_dst_uuid, + {"Destination Service UUID", "btbnep.DS_uuid", + FT_BYTES, BASE_HEX, NULL, 0x0, "Destination Service UUID"} + }, + {&hf_btbnep_conn_resp_msg, + {"Response Message", "btbnep.cresp_mess", + FT_UINT16, BASE_HEX, VALS(vs_conn_resp_msg), 0x0, + "Response Message"} + }, + {&hf_btbnep_pset_list_len, + {"List Length", "btbnep.list_length", + FT_UINT16, BASE_DEC, NULL, 0x0, "List Length"} + }, + {&hf_btbnep_pres_msg, + {"Response Message", "btbnep.presp_mess", + FT_UINT16, BASE_HEX, VALS(vs_proto_filter_resp_msg), + 0x0, "Response Message"} + }, + {&hf_btbnep_mres_msg, + {"Response Message", "btbnep.mresp_mess", + FT_UINT16, BASE_DEC, VALS(vs_mc_filter_resp_msg), + 0x0, "Response Message"} + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btbnep, + &ett_btbnep_ethgen, + &ett_btbnep_eth, + &ett_btbnep_ethdst, + &ett_btbnep_ethsrc, + &ett_btbnep_exthdr, + &ett_btbnep_cmd + }; + +/* Register the protocol name and description */ + + proto_btbnep = proto_register_protocol("Bluetooth BNEP Packet", + "BNEP", "btbnep"); + + register_dissector("btbnep", dissect_btbnep, proto_btbnep); + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btbnep, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_btbnep(void) +{ + dissector_handle_t btbnep_handle; + + btbnep_handle = find_dissector("btbnep"); + dissector_add("btl2cap.psm", 0x000f, btbnep_handle); + + data_handle = find_dissector("data"); +} + + + + + + + + + + + + diff -Nur ./packet-btbnep.h ../ethereal-0.9.5-patched/packet-btbnep.h --- ./packet-btbnep.h 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-btbnep.h 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,57 @@ +#ifndef ETHEREAL_PACKET_BTBNEP_H +#define ETHEREAL_PACKET_BTBNEP_H + +/* packet types */ + +#define BTBNEP_TYPE_GENERAL_ETHERNET 0 +#define BTBNEP_TYPE_CONTROL 1 +#define BTBNEP_TYPE_COMPRESSED_ETHERNET 2 +#define BTBNEP_TYPE_COMPRESSED_ETHERNET_SOURCE_ONLY 3 +#define BTBNEP_TYPE_COMPRESSED_ETHERNET_DEST_ONLY 4 + +/* command types */ + +#define BTBNEP_CONTROL_CMD_NOT_UNDERSTOOD 0 +#define BTBNEP_SETUP_CONN_REQ_MSG 1 +#define BTBNEP_SETUP_CONN_RESP_MSG 2 +#define BTBNEP_FILTER_NET_TYPE_SET_MSG 3 +#define BTBNEP_FILTER_NET_TYPE_RESP_MSG 4 +#define BTBNEP_FILTER_MULTI_ADDR_SET_MSG 5 +#define BTBNEP_FILTER_MULTI_ADDR_RESP_MSG 6 + +/* setup connection response messages */ + +#define BTBNEP_CONN_MSG_SUCCESS 0 +#define BTBNEP_CONN_MSG_INV_DST_UUID 1 +#define BTBNEP_CONN_MSG_INV_SRC_UUID 2 +#define BTBNEP_CONN_MSG_INV_UUID_SIZE 3 +#define BTBNEP_CONN_MSG_CONN_NOT_ALLOWED 4 + +/* protocol filter response messages */ + +#define BTBNEP_FLT_SUCCESS 0 +#define BTBNEP_FLT_UNSUPPORTED 1 +#define BTBNEP_FLT_INV_RANGE 2 +#define BTBNEP_FLT_LIMIT_REACHED 3 +#define BTBNEP_FLT_SEC_NOT_ALLOWED 4 + +/* multicast filter response messages */ + +#define BTBNEP_MC_SUCCESS 0 +#define BTBNEP_MC_UNSUPPORTED 1 +#define BTBNEP_MC_INV_RANGE 2 +#define BTBNEP_MC_LIMIT_REACHED 3 +#define BTBNEP_MC_SEC_NOT_ALLOWED 4 + + + +static int dissect_type_control(tvbuff_t *, proto_tree *, int); + +#endif /* ETHEREAL_PACKET_BTBNEP_H */ + + + + + + + diff -Nur ./packet-bthci-cmd.c ../ethereal-0.9.5-patched/packet-bthci-cmd.c --- ./packet-bthci-cmd.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-bthci-cmd.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,218 @@ +/* packet-bthci-cmd.c + * Routines for the Bluetooth HCI Command dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include + +#include + +/* Initialize the protocol and registered fields */ +static int proto_bthci_cmd = -1; +static int hf_bthci_cmd_opcode = -1; +static int hf_bthci_cmd_ogf = -1; +static int hf_bthci_cmd_ocf = -1; +static int hf_bthci_cmd_param_length = -1; +static int hf_bthci_cmd_params = -1; +static int hf_bthci_cmd_lap = -1; +static int hf_bthci_cmd_inq_length = -1; +static int hf_bthci_cmd_num_responses = -1; +static int hf_bthci_cmd_encrypt_mode = -1; + +/* Initialize the subtree pointers */ +static gint ett_bthci_cmd = -1; +static gint ett_opcode = -1; + +static const value_string encrypt_mode_vals[] = { + { 0x00, "Encryption Disabled" }, + { 0x01, "Encryption only for Point-To-Point Packets" }, + { 0x02, "Encryption for Point-To-Point and Broadcast Packets" }, + { 0, NULL } +}; + + +/* Code to actually dissect the packets */ +static void +dissect_bthci_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint16 opcode; + guint8 param_length; + + proto_item *ti_cmd; + proto_item *ti_opcode; + proto_tree *bthci_cmd_tree; + proto_tree *opcode_tree; + + ti_cmd = proto_tree_add_item(tree, proto_bthci_cmd, tvb, 0, -1, FALSE); + bthci_cmd_tree = proto_item_add_subtree(ti_cmd, ett_bthci_cmd); + + opcode = tvb_get_letohs(tvb, 0); + ti_opcode = proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_opcode, tvb, 0, 2, TRUE); + opcode_tree = proto_item_add_subtree(ti_opcode, ett_opcode); + + proto_tree_add_item(opcode_tree, hf_bthci_cmd_ogf, tvb, 0, 2, TRUE); + proto_tree_add_item(opcode_tree, hf_bthci_cmd_ocf, tvb, 0, 2, TRUE); + + proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_param_length, tvb, 2, 1, TRUE); + param_length = tvb_get_guint8(tvb, 2); + + if (param_length > 0) { + switch (opcode) { + + case 0x0401: /* Inquiry */ + proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_lap, tvb, 3, 3, TRUE); + proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_inq_length, tvb, 6, 1, TRUE); + proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_num_responses, tvb, 7, 1, TRUE); + break; + + case 0x0c22: /* Write Encryption Mode */ + proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_encrypt_mode, tvb, 3, 1, TRUE); + break; + + default: + proto_tree_add_item(bthci_cmd_tree, hf_bthci_cmd_params, tvb, 3, -1, TRUE); + break; + } + } + +} + + +/* Register the protocol with Ethereal */ + +/* this format is require because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_bthci_cmd(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_bthci_cmd_opcode, + { "Command Opcode", "bthci_cmd.opcode", + FT_UINT16, BASE_HEX, VALS(cmd_opcode_vals), 0x0, + "HCI Command Opcode" } + }, + { &hf_bthci_cmd_ogf, + { "ogf", "bthci_cmd.ogf", + FT_UINT16, BASE_HEX, VALS(ogf_vals), 0xfc00, + "Opcode Group Field" } + }, + { &hf_bthci_cmd_ocf, + { "ocf", "bthci_cmd.ocf", + FT_UINT16, BASE_HEX, NULL, 0x03ff, + "Opcode Command Field" } + }, + { &hf_bthci_cmd_param_length, + { "Parameter Total Length", "bthci_cmd.param_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Parameter Total Length" } + }, + { &hf_bthci_cmd_params, + { "Command Parameter", "bthci_cmd.params", + FT_NONE, BASE_NONE, NULL, 0x0, + "Command Parameter" } + }, + { &hf_bthci_cmd_lap, + { "LAP", "bthci_cmd.lap", + FT_UINT24, BASE_HEX, NULL, 0x0, + "LAP for the inquiry access code" } + }, + { &hf_bthci_cmd_inq_length, + { "Inquiry Length", "bthci_cmd.inq_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Inquiry Length (*1.28s)" } + }, + { &hf_bthci_cmd_num_responses, + { "Num Responses", "bthci_cmd.num_responses", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Number of Responses" } + }, + { &hf_bthci_cmd_encrypt_mode, + { "Encryption Mode", "bthci_cmd.encrypt_mode", + FT_UINT8, BASE_HEX, VALS(encrypt_mode_vals), 0x0, + "Encryption Mode" } + }, + + + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_bthci_cmd, + &ett_opcode, + }; + +/* Register the protocol name and description */ + proto_bthci_cmd = proto_register_protocol("Bluetooth HCI Command", + "HCI_CMD", "bthci_cmd"); + + register_dissector("bthci_cmd", dissect_bthci_cmd, proto_bthci_cmd); + + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_bthci_cmd, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_bthci_cmd(void) +{ + dissector_handle_t bthci_cmd_handle; + + bthci_cmd_handle = find_dissector("bthci_cmd"); + +} + + diff -Nur ./packet-bthci-cmd.h ../ethereal-0.9.5-patched/packet-bthci-cmd.h --- ./packet-bthci-cmd.h 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-bthci-cmd.h 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,151 @@ +/* packet-bthci-cmd.h + * Definitionsfor the Bluetooth HCI Command dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef __PACKET_BTHCI_CMD_H__ +#define __PACKET_BTHCI_CMD_H__ + +static const value_string cmd_opcode_vals[] = { + {0x0000, "No Operation"}, + {0x0401, "Inquiry"}, + {0x0402, "Inquiry Cancel"}, + {0x0403, "Periodic Inquiry Mode"}, + {0x0404, "Exit Periodic Inquiry Mode"}, + {0x0405, "Create Connection"}, + {0x0406, "Disconnect"}, + {0x0407, "Add SCO Connection"}, + {0x0409, "Accept Connection Request"}, + {0x040a, "Reject Connection Request"}, + {0x040b, "Link Key Request Reply"}, + {0x040c, "Link Key Request Negative Reply"}, + {0x040d, "PIN Code Request Reply"}, + {0x040e, "PIN Code Request Negative Reply"}, + {0x040f, "Change Connection Packet Type"}, + {0x0411, "Authentication Requested"}, + {0x0413, "Set Connection Encryption"}, + {0x0415, "Change Connection Link Key"}, + {0x0417, "Master Link Key"}, + {0x0419, "Remote Name Request"}, + {0x041b, "Read Remote Supported Features"}, + {0x041d, "Read Remote Version Information"}, + {0x041f, "Read Clock offset"}, + {0x0801, "Hold Mode"}, + {0x0803, "Sniff Mode"}, + {0x0804, "Exit Sniff Mode"}, + {0x0805, "Park Mode"}, + {0x0806, "Exit Park Mode"}, + {0x0807, "QoS Setup"}, + {0x0809, "Role Discovery"}, + {0x080b, "Switch Role"}, + {0x080c, "Read Link Policy Settings"}, + {0x080d, "Write Link Policy Settings"}, + {0x0c01, "Set Event Mask"}, + {0x0c03, "Reset"}, + {0x0c05, "Set Event Filter"}, + {0x0c08, "Flush"}, + {0x0c09, "Read PIN Type "}, + {0x0c0a, "Write PIN Type"}, + {0x0c0b, "Create New Unit Key"}, + {0x0c0d, "Read Stored Link Key"}, + {0x0c11, "Write Stored Link Key"}, + {0x0c12, "Delete Stored Link Key"}, + {0x0c13, "Change Local Name"}, + {0x0c14, "Read Local Name"}, + {0x0c15, "Read Connection Accept Timeout"}, + {0x0c16, "Write Connection Accept Timeout"}, + {0x0c17, "Read Page Timeout"}, + {0x0c18, "Write Page Timeout"}, + {0x0c19, "Read Scan Enable"}, + {0x0c1a, "Write Scan Enable"}, + {0x0c1b, "Read Page Scan Activity"}, + {0x0c1c, "Write Page Scan Activity"}, + {0x0c1d, "Read Inquiry Scan Activity"}, + {0x0c1e, "Write Inquiry Scan Activity"}, + {0x0c1f, "Read Authentication Enable"}, + {0x0c20, "Write Authentication Enable"}, + {0x0c21, "Read Encryption Mode"}, + {0x0c22, "Write Encryption Mode"}, + {0x0c23, "Read Class of Device"}, + {0x0c24, "Write Class of Device"}, + {0x0c25, "Read Voice Setting"}, + {0x0c26, "Write Voice Setting"}, + {0x0c27, "Read Automatic Flush Timeout"}, + {0x0c28, "Write Automatic Flush Timeout"}, + {0x0c29, "Read Num Broadcast Retransmissions"}, + {0x0c2a, "Write Num Broadcast Retransmissions"}, + {0x0c2b, "Read Hold Mode Activity "}, + {0x0c2c, "Write Hold Mode Activity"}, + {0x0c2d, "Read Transmit Power Level"}, + {0x0c2e, "Read SCO Flow Control Enable"}, + {0x0c2f, "Write SCO Flow Control Enable"}, + {0x0c31, "Set Host Controller To Host Flow Control"}, + {0x0c33, "Host Buffer Size"}, + {0x0c35, "Host Number of Completed Packets"}, + {0x0c36, "Read Link Supervision Timeout"}, + {0x0c37, "Write Link Supervision Timeout"}, + {0x0c38, "Read Number of Supported IAC"}, + {0x0c39, "Read Current IAC LAP"}, + {0x0c3a, "Write Current IAC LAP"}, + {0x0c3b, "Read Page Scan Period Mode"}, + {0x0c3c, "Write Page Scan Period Mode"}, + {0x0c3d, "Read Page Scan Mode"}, + {0x0c3e, "Write Page Scan Mode"}, + {0x1001, "Read Local Version Information"}, + {0x1003, "Read Local Supported Features"}, + {0x1005, "Read Buffer Size"}, + {0x1007, "Read Country Code"}, + {0x1009, "Read BD ADDR"}, + {0x1401, "Read Failed Contact Counter"}, + {0x1402, "Reset Failed Contact Counter"}, + {0x1403, "Get Link Quality"}, + {0x1405, "Read RSSI"}, + {0x1801, "Read Loopback Mode"}, + {0x1802, "Write Loopback Mode"}, + {0x1803, "Enable Device Under Test Mode"}, +}; + +/* + * The HCI_OGF_ values for "ogf". + */ +#define HCI_OGF_LINK_CONTROL 0x01 +#define HCI_OGF_LINK_POLICY 0x02 +#define HCI_OGF_HOST_CONTROLLER 0x03 +#define HCI_OGF_INFORMATIONAL 0x04 +#define HCI_OGF_STATUS 0x05 +#define HCI_OGF_TESTING 0x06 + +static const value_string ogf_vals[] = { + { HCI_OGF_LINK_CONTROL, "Link Control Commands" }, + { HCI_OGF_LINK_POLICY, "Link Policy Commands" }, + { HCI_OGF_HOST_CONTROLLER,"Host Controller & Baseband Commands" }, + { HCI_OGF_INFORMATIONAL, "Informational Parameters" }, + { HCI_OGF_STATUS, "Status Parameters" }, + { HCI_OGF_TESTING, "Testing Commands" }, + { 0, NULL } +}; + + + +#endif diff -Nur ./packet-bthci-evt.c ../ethereal-0.9.5-patched/packet-bthci-evt.c --- ./packet-bthci-evt.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-bthci-evt.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,337 @@ +/* packet-bthci-evt.c + * Routines for the Bluetooth HCI Event dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include + +#include + +/* Initialize the protocol and registered fields */ +static int proto_bthci_evt = -1; +static int hf_bthci_evt_code = -1; +static int hf_bthci_evt_param_length = -1; +static int hf_bthci_evt_params = -1; +static int hf_bthci_evt_num_command_packets = -1; +static int hf_bthci_evt_com_opcode = -1; +static int hf_bthci_evt_ret_params = -1; +static int hf_bthci_evt_status = -1; +static int hf_bthci_evt_ocf = -1; +static int hf_bthci_evt_ogf = -1; + +/* Initialize the subtree pointers */ +static gint ett_bthci_evt = -1; +static gint ett_opcode = -1; + + +static const value_string evt_code_vals[] = { + {0x01, "Inquiry Complete"}, + {0x02, "Inquiry Result"}, + {0x03, "Connect Complete"}, + {0x04, "Connect Request"}, + {0x05, "Disconn Complete"}, + {0x06, "Auth Complete"}, + {0x07, "Remote Name Req Complete"}, + {0x08, "Encrypt Change"}, + {0x09, "Change Connection Link Key Complete"}, + {0x0a, "Master Link Key Complete"}, + {0x0b, "Read Remote Supported Features"}, + {0x0c, "Read Remote Ver Info Complete"}, + {0x0d, "QoS Setup Complete"}, + {0x0e, "Command Complete"}, + {0x0f, "Command Status"}, + {0x10, "Hardware Error"}, + {0x11, "Flush Occurred"}, + {0x12, "Role Change"}, + {0x13, "Number of Completed Packets"}, + {0x14, "Mode Change"}, + {0x15, "Return Link Keys"}, + {0x16, "PIN Code Request"}, + {0x17, "Link Key Request"}, + {0x18, "Link Key Notification"}, + {0x19, "Loopback Command"}, + {0x1a, "Data Buffer Overflow"}, + {0x1b, "Max Slots Change"}, + {0x1c, "Read Clock Offset Complete"}, + {0x1d, "Connection Packet Type Changed"}, + {0x1e, "QoS Violation"}, + {0x1f, "Page Scan Mode Change"}, + {0x20, "Page Scan Repetition Mode Change"}, +}; + +static const value_string evt_status_vals[] = { + {0x00, "Command Succeeded"}, + {0x01, "Unknown HCI Command"}, + {0x02, "No Connection"}, + {0x03, "Hardware Failure"}, + {0x04, "Page Timeout"}, + {0x05, "Authentication Failure"}, + {0x06, "Key Missing"}, + {0x07, "Memory Full"}, + {0x08, "Connection Timeout"}, + {0x09, "Max Number Of Connections"}, + {0x0A, "Max Number Of SCO Connections To A Device"}, + {0x0B, "ACL connection already exists"}, + {0x0C, "Command Disallowed"}, + {0x0D, "Host Rejected due to limited resources"}, + {0x0E, "Host Rejected due to security reasons"}, + {0x0F, "Host Rejected due to remote device is only a personal device"}, + {0x10, "Host Timeout"}, + {0x11, "Unsupported Feature or Parameter Value"}, + {0x12, "Invalid HCI Command Parameters"}, + {0x13, "Other End Terminated Connection: User Ended Connection"}, + {0x14, "Other End Terminated Connection: Low Resources"}, + {0x15, "Other End Terminated Connection: About to Power Off"}, + {0x16, "Connection Terminated by Local Host"}, + {0x17, "Repeated Attempts"}, + {0x18, "Pairing Not Allowed"}, + {0x19, "Unknown LMP PDU"}, + {0x1A, "Unsupported Remote Feature"}, + {0x1B, "SCO Offset Rejected"}, + {0x1C, "SCO Interval Rejected"}, + {0x1D, "SCO Air Mode Rejected"}, + {0x1E, "Invalid LMP Parameters"}, + {0x1F, "Unspecified Error"}, + {0x20, "Unsupported LMP Parameter Value"}, + {0x21, "Role Change Not Allowed"}, + {0x22, "LMP Response Timeout"}, + {0x23, "LMP Error Transaction Collision"}, + {0x24, "LMP PDU Not Allowed"}, + {0x25, "Encryption Mode Not Acceptable"}, + {0x26, "Unit Key Used"}, + {0x27, "QoS is Not Supported"}, + {0x28, "Instant Passed"}, + {0x29, "Pairing with Unit Key Not Supported"}, +}; + + + + + +/* Code to actually dissect the packets */ +static void +dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti; + proto_item *ti_opcode; + proto_tree *bthci_evt_tree; + proto_tree *opcode_tree; + guint8 param_length, evt_code; + guint16 com_opcode; + + + ti = proto_tree_add_item(tree, proto_bthci_evt, tvb, 0, -1, FALSE); + bthci_evt_tree = proto_item_add_subtree(ti, ett_bthci_evt); + + proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_code, tvb, 0, 1, TRUE); + evt_code = tvb_get_guint8(tvb, 0); + + proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_param_length, tvb, 1, 1, TRUE); + param_length = tvb_get_guint8(tvb, 1); + + if (param_length > 0) { + switch(evt_code) { + + case 0x0e: /* Command Complete */ + proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_num_command_packets, tvb, 2, 1, TRUE); + ti_opcode = proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_com_opcode, tvb, 3, 2, TRUE); + com_opcode = tvb_get_letohs(tvb, 3); + + opcode_tree = proto_item_add_subtree(ti_opcode, ett_opcode); + proto_tree_add_item(opcode_tree, hf_bthci_evt_ogf, tvb, 3, 2, TRUE); + proto_tree_add_item(opcode_tree, hf_bthci_evt_ocf, tvb, 3, 2, TRUE); + + + + if (param_length > 3) { + + switch(com_opcode) { + + /* This is a list of Commands that all return just the status */ + case 0x0402: /* Inquiry Cancel */ + case 0x0403: /* Periodic Inquiry Mode */ + case 0x0404: /* Exit Periodic Enquiry Mode */ + case 0x0c01: /* Set Event Mask */ + case 0x0c03: /* Reset */ + case 0x0c05: /* Set Event Filter */ + case 0x0c0a: /* Write PIN Type */ + case 0x0c0b: /* Create Unit Key */ + case 0x0c13: /* Change Local Name */ + case 0x0c16: /* Write Connection Accept Timeout */ + case 0x0c18: /* Write Page Timeout */ + case 0x0c1a: /* Write Scan Enable */ + case 0x0c1c: /* Write Page Scan Activity */ + case 0x0c1e: /* Write Inquiry Scan Activity */ + case 0x0c20: /* Write Authentication Enable */ + case 0x0c22: /* Write Encryption Mode */ + case 0x0c24: /* Write Class of Device */ + case 0x0c26: /* Write Voice Setting */ + case 0x0c2a: /* Write Num Broadcast Retransmissions */ + case 0x0c2c: /* Write Hold Mode Activity */ + case 0x0c2f: /* Write SCO Flow Control Enable */ + case 0x0c31: /* Set Host Controller To Host Flow Control */ + case 0x0c33: /* Host Buffer Size */ + case 0x0c39: /* Write Current IAC LAP */ + case 0x0c3c: /* Write Page Scan Period Mode */ + case 0x0c3e: /* Write Page Scan Mode */ + case 0x1802: /* Write Loopback Mode */ + case 0x1803: /* Enable Device Under Test Mode */ + proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_status, tvb, 5, 1, TRUE); + break; + + default: + proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_ret_params, tvb, 5, -1, TRUE); + break; + + } + + } + break; + + default: + proto_tree_add_item(bthci_evt_tree, hf_bthci_evt_params, tvb, 2, -1, TRUE); + break; + } + } + + + +} + + +/* Register the protocol with Ethereal */ + +/* this format is require because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_bthci_evt(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_bthci_evt_code, + { "Event Code", "bthci_evt.code", + FT_UINT8, BASE_HEX, VALS(evt_code_vals), 0x0, + "Event Code" } + }, + { &hf_bthci_evt_param_length, + { "Parameter Total Length", "bthci_evt.param_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Parameter Total Length" } + }, + { &hf_bthci_evt_params, + { "Event Parameter", "bthci_evt.params", + FT_NONE, BASE_NONE, NULL, 0x0, + "Event Parameter" } + }, + { &hf_bthci_evt_num_command_packets, + { "Number of Allowed Command Packets", "bthci_evt.num_command_packets", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Number of Allowed Command Packets" } + }, + { &hf_bthci_evt_com_opcode, + { "Command Opcode", "bthci_evt.com_opcode", + FT_UINT16, BASE_HEX, VALS(cmd_opcode_vals), 0x0, + "Command Opcode" } + }, + { &hf_bthci_evt_ogf, + { "ogf", "bthci_evt.ogf", + FT_UINT16, BASE_HEX, VALS(ogf_vals), 0xfc00, + "Opcode Group Field" } + }, + { &hf_bthci_evt_ocf, + { "ocf", "bthci_evt.ocf", + FT_UINT16, BASE_HEX, NULL, 0x03ff, + "Opcode Command Field" } + }, + { &hf_bthci_evt_ret_params, + { "Return Parameter", "bthci_evt.ret_params", + FT_NONE, BASE_NONE, NULL, 0x0, + "Return Parameter" } + }, + { &hf_bthci_evt_status, + { "Status", "bthci_evt.status", + FT_UINT8, BASE_HEX, VALS(evt_status_vals), 0x0, + "Status" } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_bthci_evt, + &ett_opcode, + }; + +/* Register the protocol name and description */ + proto_bthci_evt = proto_register_protocol("Bluetooth HCI Event", + "HCI_EVT", "bthci_evt"); + + register_dissector("bthci_evt", dissect_bthci_evt, proto_bthci_evt); + + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_bthci_evt, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_bthci_evt(void) +{ + dissector_handle_t bthci_evt_handle; + + bthci_evt_handle = find_dissector("bthci_evt"); + +} + + diff -Nur ./packet-btl2cap.c ../ethereal-0.9.5-patched/packet-btl2cap.c --- ./packet-btl2cap.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-btl2cap.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,464 @@ +/* packet-btl2cap.c + * Routines for the Bluetooth L2CAP dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include + + + +/* structures needed for mapping between CIDs and PSMs */ +/* thankfully taken from BlueZ HCIDump by Maxim Krasnyansky */ +typedef struct { + guint16 cid; + guint16 psm; +} cid_info; + +#define CID_TABLE_SIZE 20 + +static cid_info cid_table[2][CID_TABLE_SIZE]; + +#define SCID cid_table[0] +#define DCID cid_table[1] + +static void add_cid(int in, guint16 cid, guint16 psm) +{ + cid_info *table = cid_table[in]; + int i; + + for (i=0; ifd->flags.visited == 0) { + psm = tvb_get_letohs(tvb, offset+4); + scid = tvb_get_letohs(tvb, offset+6); + + add_cid(((pinfo->p2p_dir == P2P_DIR_RECV) ? 1 : 0), scid, psm); + } + + break; + + case 0x03: /* Connection Response */ + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_dcid, tvb, offset+4, 2, TRUE); + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_scid, tvb, offset+6, 2, TRUE); + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_result, tvb, offset+8, 2, TRUE); + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_status, tvb, offset+10, 2, TRUE); + + + if (pinfo->fd->flags.visited == 0) { + dcid = tvb_get_letohs(tvb, offset+4); + scid = tvb_get_letohs(tvb, offset+6); + + if ((psm = get_psm(((pinfo->p2p_dir == P2P_DIR_RECV) ? 0 : 1), scid))) + add_cid(((pinfo->p2p_dir == P2P_DIR_RECV) ? 1 : 0), dcid, psm); + } + + break; + + case 0x07: /* Disconnect Response */ + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_dcid, tvb, offset+4, 2, TRUE); + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_scid, tvb, offset+6, 2, TRUE); + + if (pinfo->fd->flags.visited == 0) { + dcid = tvb_get_letohs(tvb, offset+4); + scid = tvb_get_letohs(tvb, offset+6); + del_cid(((pinfo->p2p_dir == P2P_DIR_RECV) ? 1 : 0), dcid, scid); + } + + default: + proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_data, tvb, offset+4, -1, TRUE); + break; + } + + + + offset += cmd_length + 4; /* Skip command data + header */ + } + + } + else if ((cid >= 0x0040) && (cid <= 0xFFFF)) { /* Connection oriented channel */ + if (pinfo->fd->flags.visited == 0) { + psm = get_psm(((pinfo->p2p_dir == P2P_DIR_RECV) ? 0 : 1), cid); + psm_pointer = malloc(sizeof(guint16)); + *psm_pointer = psm; + p_add_proto_data(pinfo->fd, proto_btl2cap, psm_pointer); + } + else if ((psm_pointer = p_get_proto_data(pinfo->fd, proto_btl2cap))) { + psm = *psm_pointer; + } + else { + psm = 0; + } + + + next_tvb = tvb_new_subset(tvb, 4, -1, length); + + if (psm != 0) { + /* call next dissector */ + if (!dissector_try_port(l2cap_psm_dissector_table, (guint32) psm, + next_tvb, pinfo, tree)) { + /* unknown protocol. declare as data */ + proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, 4, -1, TRUE); + } + } + else { + proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, 4, -1, TRUE); + } + + + } + else { /* Something else */ + proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, 4, -1, TRUE); + } + + + +} + + +/* Register the protocol with Ethereal */ + +/* this format is require because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_btl2cap(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_btl2cap_length, + { "Length", "btl2cap.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "L2CAP Payload Length" } + }, + { &hf_btl2cap_cid, + { "CID", "btl2cap.cid", + FT_UINT16, BASE_HEX, NULL, 0x0, + "L2CAP Channel Identifier" } + }, + { &hf_btl2cap_payload, + { "Payload", "btl2cap.payload", + FT_NONE, BASE_NONE, NULL, 0x0, + "L2CAP Payload" } + }, + { &hf_btl2cap_command, + { "Command", "btl2cap.command", + FT_NONE, BASE_NONE, NULL, 0x0, + "L2CAP Command" } + }, + { &hf_btl2cap_cmd_code, + { "Command Code", "btl2cap.cmd_code", + FT_UINT8, BASE_HEX, VALS(command_code_vals), 0x0, + "L2CAP Command Code" } + }, + { &hf_btl2cap_cmd_ident, + { "Command Identifier", "btl2cap.cmd_ident", + FT_UINT8, BASE_HEX, NULL, 0x0, + "L2CAP Command Identifier" } + }, + { &hf_btl2cap_cmd_length, + { "Command Length", "btl2cap.cmd_length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "L2CAP Command Length" } + }, + { &hf_btl2cap_cmd_data, + { "Command Data", "btl2cap.cmd_data", + FT_NONE, BASE_NONE, NULL, 0x0, + "L2CAP Command Data" } + }, + { &hf_btl2cap_psm, + { "PSM", "btl2cap.psm", + FT_UINT16, BASE_HEX, VALS(psm_vals), 0x0, + "Protocol/Service Multiplexor" } + }, + { &hf_btl2cap_scid, + { "Source CID", "btl2cap.scid", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Source Channel Identifier" } + }, + { &hf_btl2cap_dcid, + { "Destination CID", "btl2cap.dcid", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Destination Channel Identifier" } + }, + { &hf_btl2cap_result, + { "Result", "btl2cap.result", + FT_UINT16, BASE_HEX, VALS(result_vals), 0x0, + "Result" } + }, + { &hf_btl2cap_status, + { "Status", "btl2cap.status", + FT_UINT16, BASE_HEX, VALS(status_vals), 0x0, + "Status" } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btl2cap, + &ett_btl2cap_cmd, + }; + +/* Register the protocol name and description */ + proto_btl2cap = proto_register_protocol("Bluetooth L2CAP Packet", + "L2CAP", "btl2cap"); + + register_dissector("btl2cap", dissect_btl2cap, proto_btl2cap); + + +/* subdissector code */ + l2cap_psm_dissector_table = register_dissector_table("btl2cap.psm", + "L2CAP PSM", FT_UINT16, BASE_HEX); + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btl2cap, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + register_init_routine(l2cap_map_init); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_btl2cap(void) +{ + dissector_handle_t btl2cap_handle; + + btl2cap_handle = find_dissector("btl2cap"); + +} + + diff -Nur ./packet-btsco.c ../ethereal-0.9.5-patched/packet-btsco.c --- ./packet-btsco.c 1970-01-01 01:00:00.000000000 +0100 +++ ../ethereal-0.9.5-patched/packet-btsco.c 2002-09-13 20:05:44.000000000 +0200 @@ -0,0 +1,140 @@ +/* packet-bthci-evt.c + * Routines for the Bluetooth SCO dissection + * Copyright 2002, Christoph Scholz + * + * $Id: ethereal_affix.patch,v 1.1 2002/09/19 15:22:23 kds Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include +#include + +/* Initialize the protocol and registered fields */ +static int proto_btsco = -1; +static int hf_btsco_chandle = -1; +static int hf_btsco_length = -1; +static int hf_btsco_data = -1; + +/* Initialize the subtree pointers */ +static gint ett_btsco = -1; + + +/* Code to actually dissect the packets */ +static void +dissect_btsco(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti; + proto_tree *btsco_tree; + + + ti = proto_tree_add_item(tree, proto_btsco, tvb, 0, -1, FALSE); + btsco_tree = proto_item_add_subtree(ti, ett_btsco); + + proto_tree_add_item(btsco_tree, hf_btsco_chandle, tvb, 0, 2, TRUE); + proto_tree_add_item(btsco_tree, hf_btsco_length, tvb, 2, 1, TRUE); + proto_tree_add_item(btsco_tree, hf_btsco_data, tvb, 3, -1, TRUE); + +} + + +/* Register the protocol with Ethereal */ + +/* this format is require because a script is used to build the C function + that calls all the protocol registration. +*/ + +void +proto_register_btsco(void) +{ + +/* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_btsco_chandle, + { "Connection Handle", "btsco.chandle", + FT_UINT16, BASE_HEX, NULL, 0x0FFF, + "Connection Handle" } + }, + { &hf_btsco_length, + { "Data Total Length", "btsco.length", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Data Total Length" } + }, + { &hf_btsco_data, + { "Data", "btsco.data", + FT_NONE, BASE_NONE, NULL, 0x0, + "Data" } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_btsco, + }; + +/* Register the protocol name and description */ + proto_btsco = proto_register_protocol("Bluetooth SCO Packet", + "SCO", "btsco"); + + register_dissector("btsco", dissect_btsco, proto_btsco); + + + +/* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_btsco, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +/* If this dissector uses sub-dissector registration add a registration routine. + This format is required because a script is used to find these routines and + create the code that calls these routines. +*/ +void +proto_reg_handoff_btsco(void) +{ + dissector_handle_t btsco_handle; + + btsco_handle = find_dissector("btsco"); + +} + + diff -Nur ./packet-ethertype.c ../ethereal-0.9.5-patched/packet-ethertype.c --- ./packet-ethertype.c 2002-06-16 17:08:18.000000000 +0200 +++ ../ethereal-0.9.5-patched/packet-ethertype.c 2002-09-13 20:05:44.000000000 +0200 @@ -41,7 +41,7 @@ #include "etypes.h" #include "ppptypes.h" -static dissector_table_t ethertype_dissector_table; +dissector_table_t ethertype_dissector_table; static dissector_handle_t data_handle; diff -Nur ./packet-sll.c ../ethereal-0.9.5-patched/packet-sll.c --- ./packet-sll.c 2002-05-11 18:23:33.000000000 +0200 +++ ../ethereal-0.9.5-patched/packet-sll.c 2002-09-13 20:05:44.000000000 +0200 @@ -81,16 +81,19 @@ */ #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_AFFIX_HCI 0x0027 /* Bluetooth HCI */ static const value_string ltype_vals[] = { { LINUX_SLL_P_802_3, "Raw 802.3" }, { LINUX_SLL_P_802_2, "802.2 LLC" }, + { LINUX_SLL_P_AFFIX_HCI, "Affix HCI"}, { 0, NULL } }; static dissector_handle_t ipx_handle; static dissector_handle_t llc_handle; static dissector_handle_t data_handle; +static dissector_handle_t affix_hci_handle; void capture_sll(const u_char *pd, int len, packet_counts *ld) @@ -216,6 +219,11 @@ call_dissector(ipx_handle, next_tvb, pinfo, tree); break; + case LINUX_SLL_P_AFFIX_HCI: + call_dissector(affix_hci_handle, tvb, pinfo, tree); + break; + + default: call_dissector(data_handle,next_tvb, pinfo, tree); break; @@ -287,6 +295,7 @@ */ llc_handle = find_dissector("llc"); ipx_handle = find_dissector("ipx"); + affix_hci_handle = find_dissector("affix_hci"); data_handle = find_dissector("data"); sll_handle = create_dissector_handle(dissect_sll, proto_sll);