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/packet.h>
|
||||||
#include <epan/etypes.h>
|
#include <epan/etypes.h>
|
||||||
#include <epan/to_str.h>
|
#include <epan/to_str.h>
|
||||||
|
#include <epan/exceptions.h>
|
||||||
|
#include <epan/show_exception.h>
|
||||||
|
|
||||||
/* bluecom protocol defines */
|
/* bluecom protocol defines */
|
||||||
|
|
||||||
|
@ -153,268 +155,254 @@ static const value_string bcp_cmds[] = {
|
||||||
/*
|
/*
|
||||||
* dissector function of connect data (request and response)
|
* dissector function of connect data (request and response)
|
||||||
*
|
*
|
||||||
* input: tree, buffer (data), offset (data pointer), length of data, flags (req or rsp)
|
* input: tree, buffer (block data), flags (req or rsp)
|
||||||
* output: offset
|
|
||||||
* return: nothing
|
* return: nothing
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_connect_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
dissect_bcp_connect_data(proto_tree *bcp_tree, tvbuff_t *tvb, gint flags)
|
||||||
guint *offset, guint len, gint flags)
|
|
||||||
{
|
{
|
||||||
proto_tree *bcp_subtree = NULL;
|
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)
|
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",
|
"BCP Connect Request: Name=%s IpAddr=%s",
|
||||||
tvb_get_string_enc(wmem_packet_scope(), tvb, *offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
||||||
tvb_ip_to_str(tvb, *offset + 12));
|
tvb_ip_to_str(tvb, offset + 12));
|
||||||
|
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenin, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenout, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_cycletime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_cycletime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_offlinefactor, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_offlinefactor, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ipaddr, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||||
*offset += BCP_NAME_LEN;
|
offset += BCP_NAME_LEN;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
if((len-(*offset-offset_base)))
|
if((len-(offset-offset_base)))
|
||||||
{
|
{
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectreq_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & BCP_PROT_FLG_RSP)
|
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",
|
"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);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenin, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenout, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_connectrsp_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
*offset = offset_base + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dissector function of search data (request and response)
|
* dissector function of search data (request and response)
|
||||||
*
|
*
|
||||||
* input: tree, buffer (data), offset (data pointer), length of data, flags (req or rsp)
|
* input: tree, buffer (block data) flags (req or rsp)
|
||||||
* output: offset
|
|
||||||
* return: nothing
|
* return: nothing
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_search_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
dissect_bcp_search_data(proto_tree *bcp_tree, tvbuff_t *tvb, gint flags)
|
||||||
guint *offset, guint len, gint flags)
|
|
||||||
{
|
{
|
||||||
proto_tree *bcp_subtree = NULL;
|
proto_tree *bcp_subtree = NULL;
|
||||||
guint type = 0;
|
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)
|
if (flags & BCP_PROT_FLG_REQ)
|
||||||
{
|
{
|
||||||
type = tvb_get_ntohl(tvb, *offset);
|
type = tvb_get_ntohl(tvb, offset);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case BCP_SEARCH_IPADDR:
|
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",
|
"BCP Search Request: IpAddrFirst=%s, IpAddrLast=%s",
|
||||||
tvb_ip_to_str(tvb, *offset + 8),
|
tvb_ip_to_str(tvb, offset + 8),
|
||||||
tvb_ip_to_str(tvb, *offset + 12)
|
tvb_ip_to_str(tvb, offset + 12)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BCP_SEARCH_NAME:
|
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",
|
"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;
|
break;
|
||||||
|
|
||||||
default:
|
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");
|
"BCP Search Request: Unknown AddrType");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_addrtype, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_addrtype, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_reserved, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchreq_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case BCP_SEARCH_IPADDR:
|
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_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_ipaddrlast, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BCP_SEARCH_NAME:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
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);
|
NULL, "Unknown Address Data (%u bytes)", BCP_NAME_LEN);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*offset += BCP_NAME_LEN;
|
offset += BCP_NAME_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & BCP_PROT_FLG_RSP)
|
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",
|
"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_get_string_enc(wmem_packet_scope(), tvb, offset + 16, BCP_NAME_LEN, ENC_ASCII),
|
||||||
tvb_ip_to_str(tvb, *offset + 12),
|
tvb_ip_to_str(tvb, offset + 12),
|
||||||
tvb_get_letohl(tvb, *offset)
|
tvb_get_letohl(tvb, offset)
|
||||||
);
|
);
|
||||||
|
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_error, tvb, *offset, 4, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_error, tvb, offset, 4, ENC_NA);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_starttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenin, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenin, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenout, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_lenout, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ipaddr, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||||
*offset += BCP_NAME_LEN;
|
offset += BCP_NAME_LEN;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
if((len-(*offset-offset_base)))
|
if((len-(offset-offset_base)))
|
||||||
{
|
{
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_searchrsp_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*offset = offset_base + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dissector function of identify data (request)
|
* dissector function of identify data (request)
|
||||||
*
|
*
|
||||||
* input: tree, buffer (data), offset (data pointer), length of data, flags (req or rsp)
|
* input: tree, buffer (block data), flags (req or rsp)
|
||||||
* output: offset
|
|
||||||
* return: nothing
|
* return: nothing
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_identify_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
dissect_bcp_identify_data(proto_tree *bcp_tree, tvbuff_t *tvb)
|
||||||
guint *offset, guint len)
|
|
||||||
{
|
{
|
||||||
proto_tree *bcp_subtree = NULL;
|
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",
|
"BCP Identify Request: Name=%s, IpAddr=%s",
|
||||||
tvb_get_string_enc(wmem_packet_scope(), tvb, *offset + 12, BCP_NAME_LEN, ENC_ASCII),
|
tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 12, BCP_NAME_LEN, ENC_ASCII),
|
||||||
tvb_ip_to_str(tvb, *offset + 8)
|
tvb_ip_to_str(tvb, offset + 8)
|
||||||
);
|
);
|
||||||
|
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_error, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_identify_error, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_starttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_identify_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ipaddr, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_name, tvb, *offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_identify_name, tvb, offset, BCP_NAME_LEN, ENC_ASCII|ENC_NA);
|
||||||
*offset += BCP_NAME_LEN;
|
offset += BCP_NAME_LEN;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
if((len-(*offset-offset_base)))
|
if((len-(offset-offset_base)))
|
||||||
{
|
{
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_identify_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*offset = offset_base + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dissector function of sync data
|
* dissector function of sync data
|
||||||
*
|
*
|
||||||
* input: tree, buffer (data), offset (data pointer), length of data
|
* input: tree, buffer (block data)
|
||||||
* output: offset
|
|
||||||
* return: nothing
|
* return: nothing
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_sync_data(proto_tree *bcp_tree, tvbuff_t *tvb,
|
dissect_bcp_sync_data(proto_tree *bcp_tree, tvbuff_t *tvb)
|
||||||
guint *offset, guint len)
|
|
||||||
{
|
{
|
||||||
proto_tree *bcp_subtree = NULL;
|
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",
|
"BCP Sync Data: Identify=%s",
|
||||||
BOOLSTR(tvb_get_guint8(tvb, *offset + 9)));
|
BOOLSTR(tvb_get_guint8(tvb, offset + 9)));
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_starttime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_starttime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_cycletime, tvb, *offset, 4, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_cycletime, tvb, offset, 4, ENC_BIG_ENDIAN);
|
||||||
*offset += 4;
|
offset += 4;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_dataratio, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_dataratio, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||||
*offset += 1;
|
offset += 1;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_identify, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_identify, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||||
*offset += 1;
|
offset += 1;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_vlantag, tvb, *offset, 2, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_vlantag, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||||
*offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
/* protocol expansion*/
|
/* 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);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr2, tvb, *offset, BCP_ETHADDR_LEN, ENC_NA);
|
proto_tree_add_item(bcp_subtree, hf_bcp_sync_ethaddr2, tvb, offset, BCP_ETHADDR_LEN, ENC_NA);
|
||||||
*offset += BCP_ETHADDR_LEN;
|
offset += BCP_ETHADDR_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*offset = offset_base + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dissector function of data command
|
* dissector function of data command
|
||||||
*
|
*
|
||||||
* input: tree, buffer (data), offset (data pointer), length of data
|
* input: tree, buffer (block data)
|
||||||
* output: offset
|
|
||||||
* return: nothing
|
* return: nothing
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_data(proto_tree *bcp_tree, packet_info *pinfo, tvbuff_t *tvb,
|
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;
|
dissector_handle_t handle;
|
||||||
tvbuff_t *next_tvb;
|
|
||||||
|
|
||||||
/* Probably a sub-dissector exists for this type/version combination. */
|
/* Probably a sub-dissector exists for this type/version combination. */
|
||||||
handle = dissector_get_uint_handle(bcp_subdissector_table, segcode);
|
handle = dissector_get_uint_handle(bcp_subdissector_table, segcode);
|
||||||
|
|
||||||
if (handle)
|
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 the sub-dissector. */
|
||||||
call_dissector(handle, next_tvb, pinfo, bcp_tree);
|
call_dissector(handle, tvb, pinfo, bcp_tree);
|
||||||
*offset += len;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
proto_tree_add_item(bcp_tree, hf_bcp_userdata, tvb, *offset, len, ENC_NA);
|
proto_tree_add_item(bcp_tree, hf_bcp_userdata, tvb, 0, -1, ENC_NA);
|
||||||
*offset += len;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +416,7 @@ dissect_bcp_data(proto_tree *bcp_tree, packet_info *pinfo, tvbuff_t *tvb,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_block_header(proto_tree *bcp_tree, tvbuff_t *tvb, guint *offset,
|
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;
|
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);
|
*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_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,
|
blocknb,
|
||||||
val_to_str(*cmd, bcp_cmds, "UNKNOWN"), *cmd,
|
val_to_str(*cmd, bcp_cmds, "UNKNOWN"), *cmd,
|
||||||
*len
|
*len
|
||||||
|
@ -471,7 +459,8 @@ dissect_bcp_block_header(proto_tree *bcp_tree, tvbuff_t *tvb, guint *offset,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dissect_bcp_protocol_header(proto_tree *bcp_tree, tvbuff_t *tvb,
|
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;
|
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_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",
|
"BCP Protocol Header: BlockNb=%d, SegCode=%d",
|
||||||
tvb_get_guint8(tvb, *offset + 3),
|
*blocknb,
|
||||||
tvb_get_ntohs(tvb, *offset + 4));
|
*segcode);
|
||||||
|
|
||||||
proto_tree_add_item(bcp_subtree, hf_bcp_hdr_version, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
proto_tree_add_item(bcp_subtree, hf_bcp_hdr_version, tvb, *offset, 1, ENC_BIG_ENDIAN);
|
||||||
*offset += 1;
|
*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_)
|
static int dissect_bluecom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
||||||
{
|
{
|
||||||
gint cmd, flags, blocknb, segcode=0;
|
guint cmd, flags, blocknb, segcode=0, block;
|
||||||
gint data_cnt = 0;
|
guint len;
|
||||||
guint len, rlen;
|
|
||||||
guint offset = 0;
|
guint offset = 0;
|
||||||
proto_tree *bcp_tree = NULL;
|
proto_tree *bcp_tree = NULL;
|
||||||
proto_item *bcp_item_base = NULL;
|
proto_item *bcp_item_base = NULL;
|
||||||
|
tvbuff_t *block_tvb;
|
||||||
|
|
||||||
/* set protocol name column */
|
/* set protocol name column */
|
||||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "bluecom");
|
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 */
|
/* BCP header */
|
||||||
dissect_bcp_protocol_header(bcp_tree, tvb, &offset, &flags, &blocknb, &segcode);
|
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 */
|
/* set info column */
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, "%s (%d) segcode=%d blocks=%d",
|
col_append_fstr(pinfo->cinfo, COL_INFO, "segcode=%u blocks=%u",
|
||||||
val_to_str(cmd, bcp_cmds, "UNKNOWN"), cmd, segcode, blocknb);
|
segcode, blocknb);
|
||||||
|
|
||||||
/* append text to BCP base */
|
/* Iterate over blocks */
|
||||||
proto_item_append_text(bcp_item_base, ", %s (%d) len=%d",
|
for (block = 0; block < blocknb; block++)
|
||||||
val_to_str(cmd, bcp_cmds, "UNKNOWN"), cmd, tvb_reported_length(tvb));
|
{
|
||||||
|
/* BCP block header*/
|
||||||
|
dissect_bcp_block_header(bcp_tree, tvb, &offset, block, &cmd, &len);
|
||||||
|
|
||||||
switch (cmd) {
|
/* append text to BCP base */
|
||||||
case BCP_BLK_CMD_SYNC:
|
proto_item_append_text(bcp_item_base, ", %s (%u) len=%u",
|
||||||
dissect_bcp_sync_data(bcp_tree, tvb, &offset, len);
|
val_to_str(cmd, bcp_cmds, "UNKNOWN"), cmd, len);
|
||||||
break;
|
|
||||||
|
|
||||||
case BCP_BLK_CMD_IDENTIFY:
|
block_tvb = tvb_new_subset_length(tvb, offset, len);
|
||||||
dissect_bcp_identify_data(bcp_tree, tvb, &offset, len);
|
TRY {
|
||||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
switch (cmd)
|
||||||
|
|
||||||
/* ignore additional bytes if < block header. Could be padding or cut of recording */
|
|
||||||
while (rlen >= BCP_BLOCK_HDR_LEN)
|
|
||||||
{
|
{
|
||||||
/* BCP block header*/
|
case BCP_BLK_CMD_SYNC:
|
||||||
dissect_bcp_block_header(bcp_tree, tvb, &offset, ++data_cnt, &cmd, &len);
|
dissect_bcp_sync_data(bcp_tree, block_tvb);
|
||||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
break;
|
||||||
/* calculate remaining data length */
|
|
||||||
if (len > rlen)
|
case BCP_BLK_CMD_IDENTIFY:
|
||||||
{
|
dissect_bcp_identify_data(bcp_tree, block_tvb);
|
||||||
len = rlen;
|
break;
|
||||||
col_append_fstr(pinfo->cinfo, COL_INFO, " [data len of block %d limited to %d]",
|
|
||||||
data_cnt, len);
|
case BCP_BLK_CMD_SEARCH:
|
||||||
break;
|
col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
|
||||||
}
|
dissect_bcp_search_data(bcp_tree, block_tvb, flags);
|
||||||
dissect_bcp_identify_data(bcp_tree, tvb, &offset, len);
|
break;
|
||||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
|
||||||
|
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;
|
} CATCH_NONFATAL_ERRORS {
|
||||||
break;
|
/*
|
||||||
|
* Somebody threw an exception that means that there was
|
||||||
case BCP_BLK_CMD_SEARCH:
|
* a problem dissecting the block. Just show the exception
|
||||||
col_append_str(pinfo->cinfo, COL_INFO, REQRSP(flags));
|
* and then continue to dissect blocks.
|
||||||
dissect_bcp_search_data(bcp_tree, tvb, &offset, len, flags);
|
*/
|
||||||
rlen = tvb_captured_length_remaining(tvb, offset);
|
show_exception(block_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
|
||||||
|
} ENDTRY;
|
||||||
/* ignore additional bytes if < block header. Could be padding or cut of recording */
|
offset += len;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
|
Loading…
Reference in New Issue