forked from osmocom/wireshark
Redo dissction of blocks in a bluecom packet.
It *looks* as if a bluecom packet has a count of blocks, and a sequence of that number of blocks, with each one containing a block header and a block data. Dissect the packet in that fashion. If we get an exception (other than "we hit the snaplen") while dissecting a block, record it and step on to the next block. Don't try to avoid hitting the snaplen - we *want* that to be reported, so the user knows that the capture only includes the first part of the packet. Change-Id: I1b668ffea9b67d3a6ff06100b868f7d941c1f509 Reviewed-on: https://code.wireshark.org/review/27106 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
40de0010bb
commit
352b7a9fd5
|
@ -20,6 +20,8 @@
|
|||
#include <epan/packet.h>
|
||||
#include <epan/etypes.h>
|
||||
#include <epan/to_str.h>
|
||||
#include <epan/exceptions.h>
|
||||
#include <epan/show_exception.h>
|
||||
|
||||
/* bluecom protocol defines */
|
||||
|
||||
|
@ -153,268 +155,254 @@ static const value_string bcp_cmds[] = {
|
|||
/*
|
||||
* dissector function of connect data (request and response)
|
||||
*
|
||||
* input: tree, buffer (data), offset (data pointer), length of data, flags (req or rsp)
|
||||
* output: offset
|
||||
* input: tree, buffer (block data), flags (req or rsp)
|
||||
* return: nothing
|
||||
*/
|
||||
static void
|
||||
dissect_bcp_connect_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
||||
guint *offset, guint len, gint flags)
|
||||
dissect_bcp_connect_data(proto_tree *bcp_tree, tvbuff_t *tvb, gint flags)
|
||||
{
|
||||
proto_tree *bcp_subtree = NULL;
|
||||
guint offset_base = *offset;
|
||||
guint offset = 0;
|
||||
guint offset_base = offset;
|
||||
guint len = tvb_reported_length(tvb);
|
||||
|
||||
if (flags & BCP_PROT_FLG_REQ)
|
||||
{
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Connect Request: Name=%s IpAddr=%s",
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, *offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
||||
tvb_ip_to_str(tvb, *offset + 12));
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
||||
tvb_ip_to_str(tvb, offset + 12));
|
||||
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenin, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenout, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_cycletime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_offlinefactor, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ipaddr, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
*offset += BCP_NAME_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
if((len-(*offset-offset_base)))
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_cycletime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_offlinefactor, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
offset += BCP_NAME_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
if((len-(offset-offset_base)))
|
||||
{
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & BCP_PROT_FLG_RSP)
|
||||
{
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Connect Response: Error=%d",
|
||||
tvb_get_ntohl(tvb, *offset));
|
||||
tvb_get_ntohl(tvb, offset));
|
||||
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_error, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenin, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenout, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
}
|
||||
|
||||
*offset = offset_base + len;
|
||||
}
|
||||
|
||||
/*
|
||||
* dissector function of search data (request and response)
|
||||
*
|
||||
* input: tree, buffer (data), offset (data pointer), length of data, flags (req or rsp)
|
||||
* output: offset
|
||||
* input: tree, buffer (block data) flags (req or rsp)
|
||||
* return: nothing
|
||||
*/
|
||||
static void
|
||||
dissect_bcp_search_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
||||
guint *offset, guint len, gint flags)
|
||||
dissect_bcp_search_data(proto_tree *bcp_tree, tvbuff_t *tvb, gint flags)
|
||||
{
|
||||
proto_tree *bcp_subtree = NULL;
|
||||
guint type = 0;
|
||||
guint offset_base = *offset;
|
||||
guint offset = 0;
|
||||
guint offset_base = offset;
|
||||
guint len = tvb_reported_length(tvb);
|
||||
|
||||
if (flags & BCP_PROT_FLG_REQ)
|
||||
{
|
||||
type = tvb_get_ntohl(tvb, *offset);
|
||||
type = tvb_get_ntohl(tvb, offset);
|
||||
switch (type)
|
||||
{
|
||||
case BCP_SEARCH_IPADDR:
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Search Request: IpAddrFirst=%s, IpAddrLast=%s",
|
||||
tvb_ip_to_str(tvb, *offset + 8),
|
||||
tvb_ip_to_str(tvb, *offset + 12)
|
||||
tvb_ip_to_str(tvb, offset + 8),
|
||||
tvb_ip_to_str(tvb, offset + 12)
|
||||
);
|
||||
break;
|
||||
|
||||
case BCP_SEARCH_NAME:
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Search Request: Name=%s",
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, *offset + 8, BCP_NAME_LEN, ENC_ASCII)
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 8, BCP_NAME_LEN, ENC_ASCII)
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Search Request: Unknown AddrType");
|
||||
break;
|
||||
}
|
||||
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_addrtype, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_reserved, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_addrtype, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case BCP_SEARCH_IPADDR:
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_ipaddrfirst, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_ipaddrlast, tvb, *offset + 4, 4, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_ipaddrfirst, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_ipaddrlast, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
|
||||
break;
|
||||
|
||||
case BCP_SEARCH_NAME:
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
break;
|
||||
|
||||
default:
|
||||
proto_tree_add_bytes_format(bcp_subtree, hf_bcp_searchreq_addrdata, tvb, *offset, BCP_NAME_LEN,
|
||||
proto_tree_add_bytes_format(bcp_subtree, hf_bcp_searchreq_addrdata, tvb, offset, BCP_NAME_LEN,
|
||||
NULL, "Unknown Address Data (%u bytes)", BCP_NAME_LEN);
|
||||
break;
|
||||
}
|
||||
*offset += BCP_NAME_LEN;
|
||||
offset += BCP_NAME_LEN;
|
||||
}
|
||||
|
||||
if (flags & BCP_PROT_FLG_RSP)
|
||||
{
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Search Response: Name=%s, IpAddr=%s Error=%d",
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, *offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
||||
tvb_ip_to_str(tvb, *offset + 12),
|
||||
tvb_get_letohl(tvb, *offset)
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
||||
tvb_ip_to_str(tvb, offset + 12),
|
||||
tvb_get_letohl(tvb, offset)
|
||||
);
|
||||
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_error, tvb, *offset, 4, ENC_NA);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_starttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenin, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenout, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ipaddr, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
*offset += BCP_NAME_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
if((len-(*offset-offset_base)))
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_error, tvb, offset, 4, ENC_NA);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
offset += BCP_NAME_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
if((len-(offset-offset_base)))
|
||||
{
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
}
|
||||
}
|
||||
*offset = offset_base + len;
|
||||
}
|
||||
|
||||
/*
|
||||
* dissector function of identify data (request)
|
||||
*
|
||||
* input: tree, buffer (data), offset (data pointer), length of data, flags (req or rsp)
|
||||
* output: offset
|
||||
* input: tree, buffer (block data), flags (req or rsp)
|
||||
* return: nothing
|
||||
*/
|
||||
static void
|
||||
dissect_bcp_identify_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
||||
guint *offset, guint len)
|
||||
dissect_bcp_identify_data(proto_tree *bcp_tree, tvbuff_t *tvb)
|
||||
{
|
||||
proto_tree *bcp_subtree = NULL;
|
||||
guint offset_base = *offset;
|
||||
guint offset = 0;
|
||||
guint offset_base = offset;
|
||||
guint len = tvb_reported_length(tvb);
|
||||
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Identify Request: Name=%s, IpAddr=%s",
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, *offset + 12, BCP_NAME_LEN, ENC_ASCII),
|
||||
tvb_ip_to_str(tvb, *offset + 8)
|
||||
tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 12, BCP_NAME_LEN, ENC_ASCII),
|
||||
tvb_ip_to_str(tvb, offset + 8)
|
||||
);
|
||||
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_error, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_starttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ipaddr, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
*offset += BCP_NAME_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
if((len-(*offset-offset_base)))
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_error, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||
offset += BCP_NAME_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
if((len-(offset-offset_base)))
|
||||
{
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
}
|
||||
|
||||
*offset = offset_base + len;
|
||||
}
|
||||
|
||||
/*
|
||||
* dissector function of sync data
|
||||
*
|
||||
* input: tree, buffer (data), offset (data pointer), length of data
|
||||
* output: offset
|
||||
* input: tree, buffer (block data)
|
||||
* return: nothing
|
||||
*/
|
||||
static void
|
||||
dissect_bcp_sync_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
||||
guint *offset, guint len)
|
||||
dissect_bcp_sync_data(proto_tree *bcp_tree, tvbuff_t *tvb)
|
||||
{
|
||||
proto_tree *bcp_subtree = NULL;
|
||||
guint offset_base = *offset;
|
||||
guint offset = 0;
|
||||
guint offset_base = offset;
|
||||
guint len = tvb_reported_length(tvb);
|
||||
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, len, ett_bcp_data, NULL,
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, offset, len, ett_bcp_data, NULL,
|
||||
"BCP Sync Data: Identify=%s",
|
||||
BOOLSTR(tvb_get_guint8(tvb, *offset + 9)));
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_starttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_cycletime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
||||
*offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_dataratio, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
||||
*offset += 1;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_identify, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
||||
*offset += 1;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_vlantag, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
||||
*offset += 2;
|
||||
BOOLSTR(tvb_get_guint8(tvb, offset + 9)));
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_cycletime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_dataratio, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_identify, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_vlantag, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
/* protocol expansion*/
|
||||
if((len-(*offset-offset_base)))
|
||||
if((len-(offset-offset_base)))
|
||||
{
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
*offset += BCP_ETHADDR_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||
offset += BCP_ETHADDR_LEN;
|
||||
}
|
||||
|
||||
*offset = offset_base + len;
|
||||
}
|
||||
|
||||
/*
|
||||
* dissector function of data command
|
||||
*
|
||||
* input: tree, buffer (data), offset (data pointer), length of data
|
||||
* output: offset
|
||||
* input: tree, buffer (block data)
|
||||
* return: nothing
|
||||
*/
|
||||
static void
|
||||
dissect_bcp_data(proto_tree *bcp_tree, packet_info *pinfo, tvbuff_t *tvb,
|
||||
guint *offset, guint len, gint segcode)
|
||||
guint segcode)
|
||||
{
|
||||
dissector_handle_t handle;
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
/* Probably a sub-dissector exists for this type/version combination. */
|
||||
handle = dissector_get_uint_handle(bcp_subdissector_table, segcode);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
/* Generate a new tvb for the rest. */
|
||||
next_tvb = tvb_new_subset_length_caplen(tvb, *offset, len, len);
|
||||
|
||||
/* Call the sub-dissector. */
|
||||
call_dissector(handle, next_tvb, pinfo, bcp_tree);
|
||||
*offset += len;
|
||||
call_dissector(handle, tvb, pinfo, bcp_tree);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_tree_add_item(bcp_tree, hf_bcp_userdata, tvb, *offset, len, ENC_NA);
|
||||
*offset += len;
|
||||
proto_tree_add_item(bcp_tree, hf_bcp_userdata, tvb, 0, -1, ENC_NA);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +416,7 @@ dissect_bcp_data(proto_tree *bcp_tree, packet_info *pinfo, tvbuff_t *tvb,
|
|||
*/
|
||||
static void
|
||||
dissect_bcp_block_header(proto_tree *bcp_tree, tvbuff_t *tvb, guint *offset,
|
||||
gint blocknb, gint *cmd, guint *len)
|
||||
guint blocknb, guint *cmd, guint *len)
|
||||
{
|
||||
proto_tree *bcp_subtree = NULL;
|
||||
|
||||
|
@ -436,7 +424,7 @@ dissect_bcp_block_header(proto_tree *bcp_tree, tvbuff_t *tvb, guint *offset,
|
|||
*len = tvb_get_ntohs(tvb, *offset + 12);
|
||||
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, *offset, BCP_BLOCK_HDR_LEN, ett_bcp_blockheader, NULL,
|
||||
"BCP Block Header (%d): Cmd=%s (%d), Len=%d",
|
||||
"BCP Block Header (%u): Cmd=%s (%u), Len=%u",
|
||||
blocknb,
|
||||
val_to_str(*cmd, bcp_cmds, "UNKNOWN"), *cmd,
|
||||
*len
|
||||
|
@ -471,7 +459,8 @@ dissect_bcp_block_header(proto_tree *bcp_tree, tvbuff_t *tvb, guint *offset,
|
|||
*/
|
||||
static void
|
||||
dissect_bcp_protocol_header(proto_tree *bcp_tree, tvbuff_t *tvb,
|
||||
guint *offset, gint *flags, gint *blocknb, gint *segcode)
|
||||
guint *offset, gint *flags, guint *blocknb,
|
||||
guint *segcode)
|
||||
{
|
||||
proto_tree *bcp_subtree = NULL;
|
||||
|
||||
|
@ -481,8 +470,8 @@ dissect_bcp_protocol_header(proto_tree *bcp_tree, tvbuff_t *tvb,
|
|||
|
||||
bcp_subtree = proto_tree_add_subtree_format(bcp_tree, tvb, 0, BCP_PROTOCOL_HDR_LEN, ett_bcp_header, NULL,
|
||||
"BCP Protocol Header: BlockNb=%d, SegCode=%d",
|
||||
tvb_get_guint8(tvb, *offset + 3),
|
||||
tvb_get_ntohs(tvb, *offset + 4));
|
||||
*blocknb,
|
||||
*segcode);
|
||||
|
||||
proto_tree_add_item(bcp_subtree, hf_bcp_hdr_version, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
||||
*offset += 1;
|
||||
|
@ -504,12 +493,12 @@ dissect_bcp_protocol_header(proto_tree *bcp_tree, tvbuff_t *tvb,
|
|||
*/
|
||||
static int dissect_bluecom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||
{
|
||||
gint cmd, flags, blocknb, segcode=0;
|
||||
gint data_cnt = 0;
|
||||
guint len, rlen;
|
||||
guint cmd, flags, blocknb, segcode=0, block;
|
||||
guint len;
|
||||
guint offset = 0;
|
||||
proto_tree *bcp_tree = NULL;
|
||||
proto_item *bcp_item_base = NULL;
|
||||
tvbuff_t *block_tvb;
|
||||
|
||||
/* set protocol name column */
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "bluecom");
|
||||
|
@ -523,128 +512,57 @@ static int dissect_bluecom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
|
||||
/* BCP header */
|
||||
dissect_bcp_protocol_header(bcp_tree, tvb, &offset, &flags, &blocknb, &segcode);
|
||||
/* BCP block header*/
|
||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, data_cnt, &cmd, &len);
|
||||
|
||||
/* set info column */
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, "%s (%d) segcode=%d blocks=%d",
|
||||
val_to_str(cmd, bcp_cmds, "UNKNOWN"), cmd, segcode, blocknb);
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, "segcode=%u blocks=%u",
|
||||
segcode, blocknb);
|
||||
|
||||
/* append text to BCP base */
|
||||
proto_item_append_text(bcp_item_base, ", %s (%d) len=%d",
|
||||
val_to_str(cmd, bcp_cmds, "UNKNOWN"), cmd, tvb_reported_length(tvb));
|
||||
/* Iterate over blocks */
|
||||
for (block = 0; block < blocknb; block++)
|
||||
{
|
||||
/* BCP block header*/
|
||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, block, &cmd, &len);
|
||||
|
||||
switch (cmd) {
|
||||
case BCP_BLK_CMD_SYNC:
|
||||
dissect_bcp_sync_data(bcp_tree, tvb, &offset, len);
|
||||
break;
|
||||
/* append text to BCP base */
|
||||
proto_item_append_text(bcp_item_base, ", %s (%u) len=%u",
|
||||
val_to_str(cmd, bcp_cmds, "UNKNOWN"), cmd, len);
|
||||
|
||||
case BCP_BLK_CMD_IDENTIFY:
|
||||
dissect_bcp_identify_data(bcp_tree, tvb, &offset, len);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
/* ignore additional bytes if < block header. Could be padding or cut of recording */
|
||||
while (rlen >= BCP_BLOCK_HDR_LEN)
|
||||
block_tvb = tvb_new_subset_length(tvb, offset, len);
|
||||
TRY {
|
||||
switch (cmd)
|
||||
{
|
||||
/* BCP block header*/
|
||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, ++data_cnt, &cmd, &len);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
/* calculate remaining data length */
|
||||
if (len > rlen)
|
||||
{
|
||||
len = rlen;
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " [data len of block %d limited to %d]",
|
||||
data_cnt, len);
|
||||
break;
|
||||
}
|
||||
dissect_bcp_identify_data(bcp_tree, tvb, &offset, len);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
case BCP_BLK_CMD_SYNC:
|
||||
dissect_bcp_sync_data(bcp_tree, block_tvb);
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_IDENTIFY:
|
||||
dissect_bcp_identify_data(bcp_tree, block_tvb);
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_SEARCH:
|
||||
col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
|
||||
dissect_bcp_search_data(bcp_tree, block_tvb, flags);
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_CONNECT:
|
||||
col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
|
||||
dissect_bcp_connect_data(bcp_tree, block_tvb, flags);
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_DATA:
|
||||
default:
|
||||
dissect_bcp_data(bcp_tree, pinfo, block_tvb, segcode);
|
||||
break;
|
||||
}
|
||||
offset += rlen;
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_SEARCH:
|
||||
col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
|
||||
dissect_bcp_search_data(bcp_tree, tvb, &offset, len, flags);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
/* ignore additional bytes if < block header. Could be padding or cut of recording */
|
||||
while (rlen >= BCP_BLOCK_HDR_LEN)
|
||||
{
|
||||
/* BCP block header*/
|
||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, ++data_cnt, &cmd, &len);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
/* calculate remaining data length */
|
||||
if (len > rlen)
|
||||
{
|
||||
len = rlen;
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " [data len of block %d limited to %d]",
|
||||
data_cnt, len);
|
||||
break;
|
||||
}
|
||||
dissect_bcp_search_data(bcp_tree, tvb, &offset, len, flags);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
}
|
||||
offset += rlen;
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_CONNECT:
|
||||
col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
|
||||
dissect_bcp_connect_data(bcp_tree, tvb, &offset, len, flags);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
/* ignore additional bytes if < block header. Could be padding or cut of recording */
|
||||
while (rlen >= BCP_BLOCK_HDR_LEN)
|
||||
{
|
||||
/* BCP block header*/
|
||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, ++data_cnt, &cmd, &len);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
/* calculate remaining data length */
|
||||
if (len > rlen)
|
||||
{
|
||||
len = rlen;
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " [data len of block %d limited to %d]",
|
||||
data_cnt, len);
|
||||
break;
|
||||
}
|
||||
dissect_bcp_connect_data(bcp_tree, tvb, &offset, len, flags);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
}
|
||||
offset += rlen;
|
||||
break;
|
||||
|
||||
case BCP_BLK_CMD_DATA:
|
||||
default:
|
||||
/* check if data packet was limited */
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
if (len > rlen)
|
||||
{
|
||||
len = rlen;
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " [data len of block %d limited to %d]",
|
||||
data_cnt, len);
|
||||
}
|
||||
dissect_bcp_data(bcp_tree, pinfo, tvb, &offset, len, segcode);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
|
||||
/* ignore additional bytes if < block header. Could be padding or cut of recording */
|
||||
while (rlen >= BCP_BLOCK_HDR_LEN)
|
||||
{
|
||||
/* BCP block header*/
|
||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, ++data_cnt, &cmd, &len);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
/* calculate remaining data length */
|
||||
if (len > rlen)
|
||||
{
|
||||
len = rlen;
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " [data len of block %d limited to %d]",
|
||||
data_cnt, len);
|
||||
break;
|
||||
}
|
||||
dissect_bcp_data(bcp_tree, pinfo, tvb, &offset, len, segcode);
|
||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
||||
}
|
||||
offset += rlen;
|
||||
break;
|
||||
} CATCH_NONFATAL_ERRORS {
|
||||
/*
|
||||
* Somebody threw an exception that means that there was
|
||||
* a problem dissecting the block. Just show the exception
|
||||
* and then continue to dissect blocks.
|
||||
*/
|
||||
show_exception(block_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
|
||||
} ENDTRY;
|
||||
offset += len;
|
||||
}
|
||||
|
||||
return offset;
|
||||
|
|
Loading…
Reference in New Issue