aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-06-25 22:48:11 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-06-25 22:48:11 +0000
commitb8b2d513f667c2072708d73ec12f6438b290e71c (patch)
tree2a1610a6c92b24142d49d6c9dfa4f988fed99d08 /epan
parent9e1359e2fab24df5d56c3e85dfe5ba926faf2eef (diff)
From Michal Labedzki:
BT: Expose RFCOMM Channel instead of DLCI https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6567 svn path=/trunk/; revision=43489
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-btrfcomm.c200
1 files changed, 164 insertions, 36 deletions
diff --git a/epan/dissectors/packet-btrfcomm.c b/epan/dissectors/packet-btrfcomm.c
index cf7514ea9a..f7800ba0f1 100644
--- a/epan/dissectors/packet-btrfcomm.c
+++ b/epan/dissectors/packet-btrfcomm.c
@@ -53,6 +53,8 @@ static int hf_len = -1;
static int hf_frame_type = -1;
static int hf_cr = -1;
static int hf_dlci = -1;
+static int hf_channel = -1;
+static int hf_direction = -1;
static int hf_priority = -1;
static int hf_error_recovery_mode = -1;
static int hf_max_frame_size = -1;
@@ -80,6 +82,15 @@ static int hf_at_cmd = -1;
static int hf_dun_at_cmd = -1;
static int hf_data = -1;
+static int hf_mcc_dlci = -1;
+static int hf_mcc_channel = -1;
+static int hf_mcc_direction = -1;
+static int hf_mcc_const_1 = -1;
+static int hf_mcc_pn_dlci = -1;
+static int hf_mcc_pn_channel = -1;
+static int hf_mcc_pn_direction = -1;
+static int hf_mcc_pn_zeros_padding = -1;
+
/* Initialize the protocol and registered fields */
static int proto_btrfcomm = -1;
static int proto_bthf = -1;
@@ -94,6 +105,8 @@ static gint ett_control = -1;
static gint ett_mcc = -1;
static gint ett_ctrl_pn_ci = -1;
static gint ett_ctrl_pn_v24 = -1;
+static gint ett_dlci = -1;
+static gint ett_mcc_dlci = -1;
static gint ett_bthf = -1;
static gint ett_btdun = -1;
@@ -103,6 +116,7 @@ static emem_tree_t *dlci_table;
/* Initialize dissector table */
dissector_table_t rfcomm_service_dissector_table;
+dissector_table_t rfcomm_channel_dissector_table;
typedef struct _dlci_state_t {
guint32 service;
@@ -232,18 +246,29 @@ get_le_multi_byte_value(tvbuff_t *tvb, int offset, proto_tree *tree, guint32 *va
static int
-dissect_ctrl_pn(packet_info *pinfo, proto_tree *t, tvbuff_t *tvb, int offset, int cr_flag)
+dissect_ctrl_pn(packet_info *pinfo, proto_tree *t, tvbuff_t *tvb, int offset, int cr_flag, guint8 *mcc_channel)
{
proto_tree *st;
proto_item *ti;
- int dlci;
+ proto_tree *dlci_tree = NULL;
+ proto_item *dlci_item = NULL;
+ int mcc_dlci;
int cl;
dlci_state_t *dlci_state;
guint8 flags;
- /* dlci */
- dlci = tvb_get_guint8(tvb, offset) & 0x3f;
- proto_tree_add_uint(t, hf_dlci, tvb, offset, 1, dlci);
+ proto_tree_add_item(t, hf_mcc_pn_zeros_padding, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+
+ /* mcc dlci */
+ mcc_dlci = tvb_get_guint8(tvb, offset) & 0x3f;
+ *mcc_channel = mcc_dlci >> 1;
+
+ dlci_item = proto_tree_add_item(t, hf_mcc_pn_dlci, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(dlci_item, " (Direction: %d, Channel: %u)", mcc_dlci & 0x01, *mcc_channel);
+
+ dlci_tree = proto_item_add_subtree(dlci_item, ett_mcc_dlci);
+ proto_tree_add_item(dlci_tree, hf_mcc_pn_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(dlci_tree, hf_mcc_pn_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
/* cl */
@@ -281,9 +306,9 @@ dissect_ctrl_pn(packet_info *pinfo, proto_tree *t, tvbuff_t *tvb, int offset, in
guint32 token;
if (pinfo->p2p_dir == cr_flag)
- token = dlci | 0x01; /* local service */
+ token = mcc_dlci | 0x01; /* local service */
else
- token = dlci;
+ token = mcc_dlci;
dlci_state = se_tree_lookup32(dlci_table, token);
if (!dlci_state) {
@@ -307,15 +332,30 @@ dissect_ctrl_pn(packet_info *pinfo, proto_tree *t, tvbuff_t *tvb, int offset, in
}
static int
-dissect_ctrl_msc(proto_tree *t, tvbuff_t *tvb, int offset, int length)
+dissect_ctrl_msc(proto_tree *t, tvbuff_t *tvb, int offset, int length, guint8 *mcc_channel)
{
proto_tree *st;
proto_item *it;
+ proto_tree *dlci_tree = NULL;
+ proto_item *dlci_item = NULL;
+ guint8 mcc_dlci;
guint8 status;
int start_offset;
- proto_tree_add_uint(t, hf_dlci, tvb, offset, 1, tvb_get_guint8(tvb, offset)&0x3f);
+ mcc_dlci = tvb_get_guint8(tvb, offset) >> 2;
+ *mcc_channel = mcc_dlci >> 1;
+
+ dlci_item = proto_tree_add_item(t, hf_mcc_dlci, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(dlci_item, " (Direction: %d, Channel: %u)", mcc_dlci & 0x01, *mcc_channel);
+
+ dlci_tree = proto_item_add_subtree(dlci_item, ett_mcc_dlci);
+ proto_tree_add_item(dlci_tree, hf_mcc_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(dlci_tree, hf_mcc_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+
+ proto_tree_add_item(t, hf_mcc_const_1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(t, hf_mcc_ea, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+
offset += 1;
start_offset = offset;
@@ -348,6 +388,8 @@ dissect_btrfcomm_Address(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 *ea
{
proto_item *ti;
proto_tree *addr_tree;
+ proto_tree *dlci_tree = NULL;
+ proto_item *dlci_item = NULL;
guint8 dlci, cr_flag, ea_flag, flags;
flags = tvb_get_guint8(tvb, offset);
@@ -367,10 +409,16 @@ dissect_btrfcomm_Address(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 *ea
*dlcip = dlci;
}
- ti = proto_tree_add_text(tree, tvb, offset, 1, "Address: E/A flag: %d, C/R flag: %d, DLCI: 0x%02x", ea_flag, cr_flag, dlci);
+ ti = proto_tree_add_text(tree, tvb, offset, 1, "Address: E/A flag: %d, C/R flag: %d, Direction: %d, Channel: %u", ea_flag, cr_flag, dlci & 0x01, dlci >> 1);
addr_tree = proto_item_add_subtree(ti, ett_addr);
- proto_tree_add_uint(addr_tree, hf_dlci, tvb, offset, 1, dlci);
+ dlci_item = proto_tree_add_item(addr_tree, hf_dlci, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(dlci_item, " (Direction: %d, Channel: %u)", dlci & 0x01, dlci >> 1);
+
+ dlci_tree = proto_item_add_subtree(dlci_item, ett_dlci);
+ proto_tree_add_item(dlci_tree, hf_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(dlci_tree, hf_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+
proto_tree_add_item(addr_tree, hf_cr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(addr_tree, hf_ea, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -437,7 +485,7 @@ dissect_btrfcomm_PayloadLen(tvbuff_t *tvb, int offset, proto_tree *tree, guint16
}
static int
-dissect_btrfcomm_MccType(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo, guint8 *mcc_cr_flagp, guint8 *mcc_ea_flagp, guint32 *mcc_typep)
+dissect_btrfcomm_MccType(tvbuff_t *tvb, int offset, proto_tree *tree, guint8 *mcc_cr_flagp, guint8 *mcc_ea_flagp, guint32 *mcc_typep)
{
int start_offset = offset;
proto_item *ti;
@@ -464,12 +512,6 @@ dissect_btrfcomm_MccType(tvbuff_t *tvb, int offset, proto_tree *tree, packet_inf
*mcc_typep = mcc_type;
}
-
- if (mcc_type) {
- col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(mcc_type, vs_ctl, "Unknown"));
- }
-
-
ti = proto_tree_add_text(tree, tvb, start_offset, offset-start_offset,
"Type: %s (0x%x), C/R flag = %d, E/A flag = %d",
val_to_str_const(mcc_type, vs_ctl, "Unknown"),
@@ -548,8 +590,8 @@ dissect_btrfcomm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
- col_append_fstr(pinfo->cinfo, COL_INFO, "%s DLCI=%d ",
- val_to_str_const(frame_type, vs_frame_type_short, "Unknown"), dlci);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s Channel=%u ",
+ val_to_str_const(frame_type, vs_frame_type_short, "Unknown"), dlci >> 1);
if (dlci && (frame_type == 0x2f))
col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ",
val_to_str_ext_const(dlci_state->service, &vs_service_classes_ext, "Unknown"));
@@ -572,22 +614,23 @@ dissect_btrfcomm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* multiplexer control command */
if (!dlci && frame_len) {
proto_item *mcc_ti;
+ proto_tree *dlci_tree = NULL;
+ proto_item *dlci_item = NULL;
guint32 mcc_type, length;
guint8 mcc_cr_flag, mcc_ea_flag;
+ guint8 mcc_channel;
+ guint8 mcc_dlci;
int start_offset = offset;
- col_append_str(pinfo->cinfo, COL_INFO, "MPX_CTRL ");
-
mcc_ti = proto_tree_add_text(rfcomm_tree, tvb, offset, 1, "Multiplexer Control Command");
ctrl_tree = proto_item_add_subtree(mcc_ti, ett_btrfcomm_ctrl);
/* mcc type */
- offset = dissect_btrfcomm_MccType(tvb, offset, ctrl_tree, pinfo, &mcc_cr_flag, &mcc_ea_flag, &mcc_type);
+ offset = dissect_btrfcomm_MccType(tvb, offset, ctrl_tree, &mcc_cr_flag, &mcc_ea_flag, &mcc_type);
/* len */
offset = get_le_multi_byte_value(tvb, offset, ctrl_tree, &length, hf_mcc_len);
-
if (length > (guint32) tvb_length_remaining(tvb, offset)) {
expert_add_info_format(pinfo, ctrl_tree, PI_MALFORMED, PI_ERROR, "Huge MCC length: %u", length);
return;
@@ -595,14 +638,40 @@ dissect_btrfcomm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
switch(mcc_type) {
case 0x20: /* Parameter Negotiation */
- col_append_str(pinfo->cinfo, COL_INFO, "Parameter Negotiation ");
- dissect_ctrl_pn(pinfo, ctrl_tree, tvb, offset, mcc_cr_flag);
+ dissect_ctrl_pn(pinfo, ctrl_tree, tvb, offset, mcc_cr_flag, &mcc_channel);
+ break;
+ case 0x24: /* Remote Port Negotiation */
+ mcc_dlci = tvb_get_guint8(tvb, offset) >> 2;
+ mcc_channel = mcc_dlci >> 1;
+
+ dlci_item = proto_tree_add_item(ctrl_tree, hf_mcc_dlci, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(dlci_item, " (Direction: %d, Channel: %u)", mcc_dlci & 0x01, mcc_channel);
+
+ dlci_tree = proto_item_add_subtree(dlci_item, ett_mcc_dlci);
+ proto_tree_add_item(dlci_tree, hf_mcc_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(dlci_tree, hf_mcc_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+
+ proto_tree_add_item(ctrl_tree, hf_mcc_const_1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ctrl_tree, hf_mcc_ea, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+
break;
case 0x38: /* Model Status Command */
- col_append_str(pinfo->cinfo, COL_INFO, "Model Status Command ");
- dissect_ctrl_msc(ctrl_tree, tvb, offset, length);
+ dissect_ctrl_msc(ctrl_tree, tvb, offset, length, &mcc_channel);
break;
+ default:
+ mcc_channel = -1;
+ }
+
+ if (mcc_channel > 0) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "-> %d ", mcc_channel);
}
+
+ col_append_str(pinfo->cinfo, COL_INFO, "MPX_CTRL ");
+
+ if(mcc_type){
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(mcc_type, vs_ctl, "Unknown"));
+ }
+
offset += length;
proto_item_set_len(mcc_ti, offset-start_offset);
@@ -625,10 +694,13 @@ dissect_btrfcomm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
rfcomm_data.cid = l2cap_data->cid;
rfcomm_data.dlci = dlci;
- if (!dissector_try_uint(rfcomm_service_dissector_table, dlci_state->service,
- next_tvb, pinfo, tree)) {
- /* unknown service, let the data dissector handle it */
- call_dissector(data_handle, next_tvb, pinfo, tree);
+ if (!dissector_try_uint(rfcomm_channel_dissector_table, (guint32) dlci >> 1,
+ next_tvb, pinfo, tree)) {
+ if (!dissector_try_uint(rfcomm_service_dissector_table, dlci_state->service,
+ next_tvb, pinfo, tree)) {
+ /* unknown service, let the data dissector handle it */
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
}
}
@@ -642,8 +714,18 @@ proto_register_btrfcomm(void)
static hf_register_info hf[] = {
{ &hf_dlci,
{ "DLCI", "btrfcomm.dlci",
- FT_UINT8, BASE_HEX, NULL, 0,
- "RFCOMM DLCI", HFILL}
+ FT_UINT8, BASE_HEX, NULL, 0xFC,
+ "RFCOMM Data Link Connection Identifier", HFILL}
+ },
+ { &hf_channel,
+ { "Channel", "btrfcomm.channel",
+ FT_UINT8, BASE_DEC, NULL, 0xF8,
+ "RFCOMM Channel", HFILL}
+ },
+ { &hf_direction,
+ {"Direction", "btrfcomm.direction",
+ FT_UINT8, BASE_HEX, NULL, 0x04,
+ "Direction", HFILL}
},
{ &hf_priority,
{ "Priority", "btrfcomm.priority",
@@ -678,13 +760,53 @@ proto_register_btrfcomm(void)
{ &hf_mcc_ea,
{ "EA Flag", "btrfcomm.mcc.ea",
FT_UINT8, BASE_HEX, VALS(vs_ea), 0x1,
- "EA flag (should be always 1)", HFILL}
+ "EA flag", HFILL}
},
{ &hf_mcc_cr,
{ "C/R Flag", "btrfcomm.mcc.cr",
FT_UINT8, BASE_HEX, VALS(vs_cr), 0x2,
"Command/Response flag", HFILL}
},
+ { &hf_mcc_const_1,
+ { "Ones padding", "btrfcomm.mcc.padding",
+ FT_UINT8, BASE_HEX, NULL, 0x02,
+ "Ones padding", HFILL}
+ },
+ { &hf_mcc_dlci,
+ { "MCC DLCI", "btrfcomm.mcc.dlci",
+ FT_UINT8, BASE_HEX, NULL, 0xFC,
+ "RFCOMM MCC Data Link Connection Identifier", HFILL}
+ },
+ { &hf_mcc_channel,
+ { "MCC Channel", "btrfcomm.mcc.channel",
+ FT_UINT8, BASE_DEC, NULL, 0xF8,
+ "RFCOMM MCC Channel", HFILL}
+ },
+ { &hf_mcc_direction,
+ { "MCC Direction", "btrfcomm.mcc.direction",
+ FT_UINT8, BASE_HEX, NULL, 0x04,
+ "RFCOMM MCC Direction", HFILL}
+ },
+ { &hf_mcc_pn_dlci,
+ { "MCC DLCI", "btrfcomm.mcc.dlci",
+ FT_UINT8, BASE_HEX, NULL, 0x3F,
+ "RFCOMM MCC Data Link Connection Identifier", HFILL}
+ },
+ { &hf_mcc_pn_channel,
+ { "MCC Channel", "btrfcomm.mcc.channel",
+ FT_UINT8, BASE_DEC, NULL, 0x3E,
+ "RFCOMM MCC Channel", HFILL}
+ },
+ { &hf_mcc_pn_direction,
+ { "MCC Direction", "btrfcomm.mcc.direction",
+ FT_UINT8, BASE_HEX, NULL, 0x01,
+ "RFCOMM MCC Direction", HFILL}
+ },
+ { &hf_mcc_pn_zeros_padding,
+ { "Zeros padding", "btrfcomm.mcc.padding",
+ FT_UINT8, BASE_HEX, NULL, 0xC0,
+ "RFCOMM MSC Zeros padding", HFILL}
+ },
{ &hf_mcc_cmd,
{ "C/R Flag", "btrfcomm.mcc.cmd",
FT_UINT8, BASE_HEX, VALS(vs_ctl), 0xfc,
@@ -772,7 +894,9 @@ proto_register_btrfcomm(void)
&ett_control,
&ett_mcc,
&ett_ctrl_pn_ci,
- &ett_ctrl_pn_v24
+ &ett_ctrl_pn_v24,
+ &ett_dlci,
+ &ett_mcc_dlci
};
/* Register the protocol name and description */
@@ -785,6 +909,7 @@ proto_register_btrfcomm(void)
proto_register_subtree_array(ett, array_length(ett));
rfcomm_service_dissector_table = register_dissector_table("btrfcomm.service", "RFCOMM SERVICE", FT_UINT16, BASE_HEX);
+ rfcomm_channel_dissector_table = register_dissector_table("btrfcomm.channel", "RFCOMM Channel", FT_UINT16, BASE_DEC);
dlci_table = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "RFCOMM dlci table");
}
@@ -880,6 +1005,7 @@ proto_reg_handoff_bthf(void)
dissector_add_uint("btrfcomm.service", BTSDP_HFP_SERVICE_UUID, bthf_handle);
dissector_add_uint("btrfcomm.service", BTSDP_HFP_GW_SERVICE_UUID, bthf_handle);
+ dissector_add_handle("btrfcomm.channel", bthf_handle);
}
/* Bluetooth Dial-Up Networking (DUN) profile dissection */
@@ -957,6 +1083,7 @@ proto_reg_handoff_btdun(void)
btdun_handle = create_dissector_handle(dissect_btdun, proto_btdun);
dissector_add_uint("btrfcomm.service", BTSDP_DUN_SERVICE_UUID, btdun_handle);
+ dissector_add_handle("btrfcomm.channel", btdun_handle);
ppp_handle = find_dissector("ppp_raw_hdlc");
}
@@ -1022,6 +1149,7 @@ proto_reg_handoff_btspp(void)
btspp_handle = create_dissector_handle(dissect_btspp, proto_btspp);
dissector_add_uint("btrfcomm.service", BTSDP_SPP_SERVICE_UUID, btspp_handle);
+ dissector_add_handle("btrfcomm.channel", btspp_handle);
}