Added support for AllJoyn Reliable Datagram Protocol.

Change-Id: I3ec37d7aec0c51f9bd0791c8fa0c5ef3dabc9fbf
Signed-off-by: Joseph Huffman <jhuffman@qce.qualcomm.com>
Reviewed-on: https://code.wireshark.org/review/4414
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Joseph Huffman 2014-10-21 11:23:45 -07:00 committed by Michael Mann
parent 30742dd7c8
commit 6e5784d88a
1 changed files with 488 additions and 40 deletions

View File

@ -193,6 +193,51 @@ static int hf_alljoyn_string_size_8bit = -1; /* 8-bit size of string */
static int hf_alljoyn_string_size_32bit = -1; /* 32-bit size of string */
static int hf_alljoyn_string_data = -1; /* string characters */
/* Protocol identifiers. */
static int proto_AllJoyn_ardp = -1; /* The top level. Entire AllJoyn Reliable Datagram Protocol. */
#define ARDP_SYN_FIXED_HDR_LEN 22 /* Size of the fixed part for the ARDP connection packet header. */
#define ARDP_FIXED_HDR_LEN 34 /* Size of the fixed part for the ARDP header. */
#define ARDP_DATA_LENGTH_OFFSET 6 /* Offset into the ARDP header for the data length. */
#define ARDP_HEADER_LEN_OFFSET 1 /* Offset into the ARDP header for the actual length of the header. */
/* These are bit masks for ARDP flags. */
/* These bits are depricated and do not exist for version 1. */
#define ARDP_SYN 0x01
#define ARDP_ACK 0x02
#define ARDP_EAK 0x04
#define ARDP_RST 0x08
#define ARDP_NUL 0x10
#define ARDP_UNUSED 0x20
#define ARDP_VER0 0x40
#define ARDP_VER1 0x80
#define ARDP_VER (ARDP_VER0 | ARDP_VER1)
static int hf_ardp_syn_flag = -1; /* 0x01 -- SYN */
static int hf_ardp_ack_flag = -1; /* 0x02 -- ACK */
static int hf_ardp_eak_flag = -1; /* 0x04 -- EAK */
static int hf_ardp_rst_flag = -1; /* 0x08 -- RST */
static int hf_ardp_nul_flag = -1; /* 0x10 -- NUL */
static int hf_ardp_unused_flag = -1; /* 0x20 -- UNUSED */
static int hf_ardp_version_field = -1; /* 0xc0 */
static int hf_ardp_hlen = -1; /* header length */
static int hf_ardp_src = -1; /* source port */
static int hf_ardp_dst = -1; /* destination port */
static int hf_ardp_dlen = -1; /* data length */
static int hf_ardp_seq = -1; /* sequence number */
static int hf_ardp_ack = -1; /* acknowledge number */
static int hf_ardp_ttl = -1; /* time to live (ms) */
static int hf_ardp_lcs = -1; /* last consumed sequence number */
static int hf_ardp_nsa = -1; /* next sequence to ack */
static int hf_ardp_fss = -1; /* fragment starting sequence number */
static int hf_ardp_fcnt = -1; /* fragment count */
static int hf_ardp_bmp = -1; /* EACK bitmap */
static int hf_ardp_segmax = -1; /* The maximum number of outstanding segments the other side can send without acknowledgement. */
static int hf_ardp_segbmax = -1;/* The maximum segment size we are willing to receive. */
static int hf_ardp_dackt = -1; /* Receiver's delayed ACK timeout. Used in TTL estimate prior to sending a message. */
static int hf_ardp_options = -1;/* Options for the connection. Always Sequenced Delivery Mode (SDM). */
/* These are the ids of the subtrees we will be creating */
static gint ett_alljoyn_ns = -1; /* This is the top NS tree. */
static gint ett_alljoyn_ns_header = -1;
@ -209,6 +254,7 @@ static gint ett_alljoyn_header_flags = -1;
static gint ett_alljoyn_mess_header_field = -1;
static gint ett_alljoyn_mess_header = -1;
static gint ett_alljoyn_mess_body_parameters = -1;
static gint ett_alljoyn_ardp = -1; /* This is the top ARDP tree. */
#define ROUND_TO_2BYTE(len) ((len + 1) & ~1)
#define ROUND_TO_4BYTE(len) ((len + 3) & ~3)
@ -433,6 +479,25 @@ find_sasl_command(tvbuff_t *tvb,
return NULL;
}
/* Call this to test whether desegmentation is possible and if so correctly
* set the pinfo structure with the applicable data.
* @param pinfo contains information about the incoming packet.
* @param next_offset is the offset into the tvbuff where it is desired to start processing next time.
* @param addition_bytes_needed is the additional bytes required beyond what is already available.
* @returns TRUE if desegmentation is possible. FALSE if not.
*/
static gboolean set_pinfo_desegment(packet_info *pinfo, gint next_offset, gint addition_bytes_needed)
{
if(pinfo->can_desegment) {
pinfo->desegment_offset = next_offset;
pinfo->desegment_len = addition_bytes_needed;
return TRUE;
}
return FALSE;
}
/* This is called by dissect_AllJoyn_message() to handle SASL messages.
* If it was a SASL message and was handled then return the number of bytes
* used (should be the entire packet). If not a SASL message or unhandled return 0.
@ -466,13 +531,13 @@ handle_message_sasl(tvbuff_t *tvb,
/* If not found see if we should request another segment. */
if(0 == newline_offset) {
if((guint)tvb_captured_length_remaining(tvb, offset) < MAX_SASL_PACKET_LENGTH && pinfo->can_desegment) {
pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
pinfo->desegment_offset = offset;
/* Return the length of the buffer we need for this command. */
if((guint)tvb_captured_length_remaining(tvb, offset) < MAX_SASL_PACKET_LENGTH &&
set_pinfo_desegment(pinfo, offset, DESEGMENT_ONE_MORE_SEGMENT)) {
/* Return the length of the buffer we successfully parsed. */
return_value = offset + command->length;
} else {
/* If we can't desegment then return 0. */
/* If we can't desegment then return 0 meaning we didn't do anything. */
return_value = 0;
}
@ -486,7 +551,6 @@ handle_message_sasl(tvbuff_t *tvb,
/* Add a subtree/row for the command. */
proto_tree_add_item(message_tree, hf_alljoyn_sasl_command, tvb, offset, length, ENC_ASCII|ENC_NA);
offset += length;
length = newline_offset - offset;
@ -1383,7 +1447,7 @@ handle_message_body_parameters(tvbuff_t *tvb,
end_of_body = packet_length;
}
while(offset < end_of_body && *signature) {
while(offset < end_of_body && signature && *signature) {
offset = parse_arg(tvb,
pinfo,
NULL,
@ -1413,7 +1477,7 @@ handle_message_body_parameters(tvbuff_t *tvb,
* If it was a message with valid header and optional body then return TRUE.
* If not a valid message return false.
* @param tvb is the incoming network data buffer.
* @param pinfo contains information about the incoming packet which
* @param pinfo contains information about the incoming packet.
* @param offset is the offset into the packet to start processing.
* @param message_tree is the subtree that any connect data items should be added to.
* @returns the offset into the packet that has successfully been handled or
@ -1446,10 +1510,7 @@ handle_message_header_body(tvbuff_t *tvb,
}
if(remaining_packet_length < MESSAGE_HEADER_LENGTH) {
if(pinfo->can_desegment) {
pinfo->desegment_offset = offset;
pinfo->desegment_len = MESSAGE_HEADER_LENGTH - remaining_packet_length;
} else {
if(!set_pinfo_desegment(pinfo, offset, MESSAGE_HEADER_LENGTH - remaining_packet_length)) {
col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %d. Expected >= %d && <= %d",
remaining_packet_length, MESSAGE_HEADER_LENGTH, MAX_PACKET_LEN);
}
@ -1462,10 +1523,7 @@ handle_message_header_body(tvbuff_t *tvb,
packet_length_needed = ROUND_TO_8BYTE(header_length) + body_length + MESSAGE_HEADER_LENGTH;
if(packet_length_needed > remaining_packet_length) {
if(pinfo->can_desegment) {
pinfo->desegment_offset = offset;
pinfo->desegment_len = packet_length_needed - remaining_packet_length;
} else {
if(!set_pinfo_desegment(pinfo, offset, packet_length_needed - remaining_packet_length)) {
col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %d. Expected %d",
remaining_packet_length, packet_length_needed);
}
@ -1530,23 +1588,27 @@ handle_message_header_body(tvbuff_t *tvb,
/* Test to see if this buffer contains something that might be an AllJoyn message.
* @param tvb is the incoming network data buffer.
* @param offset where to start parsing the buffer.
* @param is_ardp If true then this is an ARDP packet which needs special treatment.
* @returns TRUE if probably an AllJoyn message.
* FALSE if probably not an AllJoyn message.
*/
static gboolean
protocol_is_alljoyn_message(tvbuff_t *tvb, gint offset)
protocol_is_alljoyn_message(tvbuff_t *tvb, gint offset, gboolean is_ardp)
{
gint length = tvb_captured_length(tvb);
if(length < offset + 1)
return FALSE;
/* initial byte for a connect message. */
if(tvb_get_guint8(tvb, offset) == 0)
return TRUE;
/* There is no initial connect byte or SASL when using ARDP. */
if(!is_ardp) {
/* initial byte for a connect message. */
if(tvb_get_guint8(tvb, offset) == 0)
return TRUE;
if(find_sasl_command(tvb, offset) != NULL)
return TRUE;
if(find_sasl_command(tvb, offset) != NULL)
return TRUE;
}
if(get_message_header_endianness(tvb, offset) == ENC_ALLJOYN_BAD_ENCODING)
return FALSE;
@ -1564,6 +1626,9 @@ protocol_is_alljoyn_message(tvbuff_t *tvb, gint offset)
* @param pinfo contains information about the incoming packet which
* we update as we dissect the packet.
* @param tree is the tree data items should be added to.
* @param offset is the offset into the already partial dissected buffer
* from dissect_AllJoyn_ardp() or 0 because this is just a bare
* AllJoyn message.
* @return 0 if not AllJoyn message protocol, or
* the offset into the buffer we have successfully dissected (which
* should normally be the packet length), or
@ -1578,16 +1643,17 @@ static gint
dissect_AllJoyn_message(tvbuff_t *tvb,
packet_info *pinfo,
proto_tree *tree,
void *data _U_)
gint offset)
{
gint offset = 0;
proto_item *message_item;
proto_tree *message_tree;
gint last_offset = -1;
gint packet_length;
gboolean is_ardp = FALSE;
if(!protocol_is_alljoyn_message(tvb, offset)) {
return 0;
/* If called after dissecting the ARDP protocol. This is the only time the offset will not be zero. */
if(offset != 0) {
is_ardp = TRUE;
}
pinfo->desegment_len = 0;
@ -1603,16 +1669,20 @@ dissect_AllJoyn_message(tvbuff_t *tvb,
/* Continue as long as we are making progress and we haven't finished with the packet. */
while(offset < packet_length && offset > last_offset) {
last_offset = offset;
offset = handle_message_connect(tvb, pinfo, offset, message_tree);
if(offset >= packet_length) {
break;
}
/* There is no initial connect byte or SASL when using ARDP. */
if(!is_ardp) {
offset = handle_message_connect(tvb, pinfo, offset, message_tree);
offset = handle_message_sasl(tvb, pinfo, offset, message_tree);
if(offset >= packet_length) {
break;
}
if(offset >= packet_length) {
break;
offset = handle_message_sasl(tvb, pinfo, offset, message_tree);
if(offset >= packet_length) {
break;
}
}
offset = handle_message_header_body(tvb, pinfo, offset, message_tree);
@ -2030,6 +2100,280 @@ dissect_AllJoyn_name_server(tvbuff_t *tvb,
return tvb_reported_length(tvb);
}
/* This is a container for the ARDP info and Wireshark tree information.
*/
typedef struct _alljoyn_ardp_tree_data
{
gint offset;
gint syn;
gint ack;
gint eak;
gint rst;
gint nul;
gint sequence;
gint acknowledge;
proto_tree *alljoyn_tree;
} alljoyn_ardp_tree_data;
/* This is called by dissect_AllJoyn_ardp() to read the header
* and fill out most of tree_data.
* @param tvb is the incoming network data buffer.
* @param pinfo contains information about the incoming packet which
* we update as we dissect the packet.
* @param tree_data is the destinationn of the data..
*/
static void
ardp_parse_header(tvbuff_t *tvb,
packet_info *pinfo,
alljoyn_ardp_tree_data *tree_data)
{
guint8 flags, header_length;
gint eaklen, packet_length;
guint16 data_length;
packet_length = tvb_reported_length(tvb);
flags = tvb_get_guint8(tvb, 0);
tree_data->syn = (flags & ARDP_SYN) != 0 ? 1 : 0;
tree_data->ack = (flags & ARDP_ACK) != 0 ? 1 : 0;
tree_data->eak = (flags & ARDP_EAK) != 0 ? 1 : 0;
tree_data->rst = (flags & ARDP_RST) != 0 ? 1 : 0;
tree_data->nul = (flags & ARDP_NUL) != 0 ? 1 : 0;
/* The packet length has to be ARDP_HEADER_LEN_OFFSET long or protocol_is_ardp() would
have returned false. Length is expressed in words so multiply by 2. */
header_length = 2 * tvb_get_guint8(tvb, ARDP_HEADER_LEN_OFFSET);
if(packet_length < ARDP_DATA_LENGTH_OFFSET + 2) {
/* If we need more data before dissecting then communicate the number of additional bytes needed. */
set_pinfo_desegment(pinfo, 0, ARDP_DATA_LENGTH_OFFSET + 2 - packet_length);
/* Inform the caller we made it this far. Returning zero means we made no progress.
This is the offset just past the last byte we successfully retrieved. */
tree_data->offset = ARDP_HEADER_LEN_OFFSET + 1;
return;
}
data_length = tvb_get_ntohs(tvb, ARDP_DATA_LENGTH_OFFSET);
if(packet_length < header_length + data_length) {
/* If we need more data before dissecting then communicate the number of additional bytes needed. */
set_pinfo_desegment(pinfo, 0, header_length + data_length - packet_length);
/* Inform the caller we made it this far. Returning zero it means we made no progress.
This is the offset just past the last byte we successfully retrieved. */
tree_data->offset = ARDP_DATA_LENGTH_OFFSET + 2;
return;
}
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_syn_flag, tvb, tree_data->offset, 1, ENC_NA);
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ack_flag, tvb, tree_data->offset, 1, ENC_NA);
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_eak_flag, tvb, tree_data->offset, 1, ENC_NA);
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_rst_flag, tvb, tree_data->offset, 1, ENC_NA);
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_nul_flag, tvb, tree_data->offset, 1, ENC_NA);
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_unused_flag, tvb, tree_data->offset, 1, ENC_NA);
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_version_field, tvb, tree_data->offset, 1, ENC_NA);
tree_data->offset += 1;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_hlen, tvb, tree_data->offset, 1, ENC_NA);
tree_data->offset += 1;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_src, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dst, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dlen, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_seq, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->sequence = tvb_get_ntohl(tvb, tree_data->offset);
tree_data->offset += 4;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ack, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->acknowledge = tvb_get_ntohl(tvb, tree_data->offset);
tree_data->offset += 4;
if(tree_data->syn) {
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_segmax, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_segbmax, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dackt, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->offset += 4;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_options, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
} else {
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ttl, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->offset += 4;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_lcs, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->offset += 4;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_nsa, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->offset += 4;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_fss, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
tree_data->offset += 4;
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_fcnt, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
tree_data->offset += 2;
eaklen = header_length - ARDP_FIXED_HDR_LEN;
/* In the case of a corrupted packet eaklen could be < 0 and bad things could happen. */
if(eaklen > 0) {
if(tree_data->eak) {
proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_bmp, tvb, tree_data->offset, eaklen, ENC_NA);
}
tree_data->offset += eaklen;
}
/* The data_length bytes, if any, will be passed on to the dissect_AllJoyn_message() handler. */
}
}
/* Test to see if this buffer contains something that might be the AllJoyn ARDP protocol.
* @param tvb is the incoming network data buffer.
* @returns TRUE if probably the AllJoyn ARDP protocol.
* FALSE if probably not the AllJoyn ARDP protocol.
*/
static gboolean
protocol_is_ardp(tvbuff_t *tvb)
{
guint8 flags, header_length;
gint length = tvb_captured_length(tvb);
/* We must be able to get the byte value at this offset to determine if it is an ARDP protocol. */
if(length < ARDP_HEADER_LEN_OFFSET + 1) {
return FALSE;
}
/* Length is expressed in words. */
header_length = 2 * tvb_get_guint8(tvb, ARDP_HEADER_LEN_OFFSET);
flags = tvb_get_guint8(tvb, 0);
if((flags & ARDP_SYN) && header_length != ARDP_SYN_FIXED_HDR_LEN) {
return FALSE;
}
if(!(flags & ARDP_SYN) && header_length < ARDP_FIXED_HDR_LEN) {
return FALSE;
}
return TRUE;
}
/* This is called by Wireshark for packet types that are registered
in the proto_reg_handoff_AllJoyn() function. This function handles
the packets for the ARDP and bare AllJoyn message protocols. A test
for bare AllJoyn message protocol is done first. If it is an AllJoyn
packet then only dissect_AllJoyn_message() is called to dissect the
data. If protocol_is_alljoyn_message() returns FALSE then a test for
the ARDP protocol is performed. If it succeeds then ARDP dissection
proceeds and may call dissect_AllJoyn_message() with the offset just
past the ARDP protocol.
* @param tvb is the incoming network data buffer.
* @param pinfo contains information about the incoming packet which
* we update as we dissect the packet.
* @param tree is the tree data items should be added to.
* @return 0 if not AllJoyn ARDP protocol, or
* the offset into the buffer we have dissected (which should normally
* be the packet length), or
* the offset into the buffer we have dissected with
* pinfo->desegment_len == additional bytes needed from the next packet
* before we can dissect.
*/
static int
dissect_AllJoyn_ardp(tvbuff_t *tvb,
packet_info *pinfo,
proto_tree *tree,
void *data _U_)
{
alljoyn_ardp_tree_data tree_data = {0, 0, 0, 0, 0, 0, 0, 0, 0};
gint packet_length = tvb_reported_length(tvb);
proto_item *alljoyn_item = NULL;
if(protocol_is_alljoyn_message(tvb, 0, FALSE)) {
return dissect_AllJoyn_message(tvb, pinfo, tree, 0);
}
if(!protocol_is_ardp(tvb)) {
return 0;
}
pinfo->desegment_len = 0;
/* Add a subtree covering the remainder of the packet */
alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ardp, tvb, 0, -1, ENC_NA);
tree_data.alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ardp);
ardp_parse_header(tvb, pinfo, &tree_data);
/* Is desegmention needed? */
if(pinfo->desegment_len != 0) {
return tree_data.offset;
}
if(tree_data.offset != 0) {
/* This is ARDP traffic. Mark it as such at the top level. */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN-ARDP");
}
if(tree_data.offset < packet_length) {
gint return_value = 0;
if(protocol_is_alljoyn_message(tvb, tree_data.offset, TRUE)) {
return_value = dissect_AllJoyn_message(tvb, pinfo, tree, tree_data.offset);
}
/* return_value will be the offset into the successfully parsed
* buffer, the requested length of a reassembled packet (with pinfo->desegment_len
* and pinfo->desegment_offset set appropriately), 0 if desegmentation is needed but
* isn't available, or the initial value (tree_data.offset) if no progress was made.
* If dissect_AllJoyn_message() made progress or is requesting desegmentation then
* return leaving the column info as handled by the AllJoyn message dissector. If
* not then we fall through to set the column info in this dissector.
*/
if(return_value > tree_data.offset) {
return return_value;
}
}
col_clear(pinfo->cinfo, COL_INFO);
col_append_str(pinfo->cinfo, COL_INFO, "flags:");
if(tree_data.syn) {
col_append_str(pinfo->cinfo, COL_INFO, " SYN");
}
if(tree_data.ack) {
col_append_str(pinfo->cinfo, COL_INFO, " ACK");
}
if(tree_data.eak) {
col_append_str(pinfo->cinfo, COL_INFO, " EAK");
}
if(tree_data.rst) {
col_append_str(pinfo->cinfo, COL_INFO, " RST");
}
if(tree_data.nul) {
col_append_str(pinfo->cinfo, COL_INFO, " NUL");
}
col_append_fstr(pinfo->cinfo, COL_INFO, " SEQ: %10u", tree_data.sequence);
col_append_fstr(pinfo->cinfo, COL_INFO, " ACK: %10u", tree_data.acknowledge);
return tree_data.offset;
}
void
proto_register_AllJoyn(void)
{
@ -2483,6 +2827,102 @@ proto_register_AllJoyn(void)
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL}
},
/******************
* Wireshark header fields for the AllJoyn Reliable Data Protocol.
******************/
{&hf_ardp_syn_flag,
{"SYN", "ardp.hdr.SYN",
FT_BOOLEAN, 8, NULL, ARDP_SYN,
NULL, HFILL}
},
{&hf_ardp_ack_flag,
{"ACK", "ardp.hdr.ACK",
FT_BOOLEAN, 8, NULL, ARDP_ACK,
NULL, HFILL}},
{&hf_ardp_eak_flag,
{"EAK", "ardp.hdr.EAK",
FT_BOOLEAN, 8, NULL, ARDP_EAK,
NULL, HFILL}},
{&hf_ardp_rst_flag,
{"RST", "ardp.hdr.RST",
FT_BOOLEAN, 8, NULL, ARDP_RST,
NULL, HFILL}},
{&hf_ardp_nul_flag,
{"NUL", "ardp.hdr.NUL",
FT_BOOLEAN, 8, NULL, ARDP_NUL,
NULL, HFILL}},
{&hf_ardp_unused_flag,
{"UNUSED", "ardp.hdr.UNUSED",
FT_BOOLEAN, 8, NULL, ARDP_UNUSED,
NULL, HFILL}},
{&hf_ardp_version_field,
{"VER", "ardp.hdr.ver",
FT_UINT8, BASE_HEX, NULL, ARDP_VER,
NULL, HFILL}},
{&hf_ardp_hlen,
{"Header Length", "ardp.hdr.hlen",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_src,
{"Source Port", "ardp.hdr.src",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_dst,
{"Destination Port", "ardp.hdr.dst",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_dlen,
{"Data Length", "ardp.hdr.dlen",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_seq,
{"Sequence", "ardp.hdr.seq",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_ack,
{"Acknowledge", "ardp.hdr.ack",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_ttl,
{"Time to Live", "ardp.hdr.ttl",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_lcs,
{"Last Consumed Sequence", "ardp.hdr.lcs",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_nsa,
{"Next Sequence to ACK", "ardp.hdr.nsa",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_fss,
{"Fragment Starting Sequence", "ardp.hdr.fss",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_fcnt,
{"Fragment Count", "ardp.hdr.fcnt",
FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_bmp,
{"EACK Bitmap", "ardp.hdr.bmp",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_segmax,
{"Segment Max", "ardp.hdr.segmentmax",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_segbmax,
{"Segment Buffer Max", "ardp.hdr.segmentbmax",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_dackt,
{"Receiver's delayed ACK timeout", "ardp.hdr.dackt",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL}},
{&hf_ardp_options,
{"Options", "ardp.hdr.options",
FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL}},
};
static gint *ett[] = {
@ -2500,7 +2940,8 @@ proto_register_AllJoyn(void)
&ett_alljoyn_header_flags,
&ett_alljoyn_mess_header_field,
&ett_alljoyn_mess_header,
&ett_alljoyn_mess_body_parameters
&ett_alljoyn_mess_body_parameters,
&ett_alljoyn_ardp
};
/* The following are protocols as opposed to data within a protocol. These appear
@ -2515,6 +2956,9 @@ proto_register_AllJoyn(void)
proto_register_field_array(proto_AllJoyn_ns, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
/* ARDP */ /* name, short name, abbrev */
proto_AllJoyn_ardp = proto_register_protocol("AllJoyn Reliable Datagram Protocol", "AllJoyn ARDP", "ardp");
}
void
@ -2522,23 +2966,26 @@ proto_reg_handoff_AllJoyn(void)
{
static gboolean initialized = FALSE;
static dissector_handle_t alljoyn_handle_ns;
static dissector_handle_t alljoyn_handle_mess;
static dissector_handle_t alljoyn_handle_ardp;
if(!initialized) {
alljoyn_handle_ns = new_create_dissector_handle(dissect_AllJoyn_name_server, proto_AllJoyn_ns);
alljoyn_handle_mess = new_create_dissector_handle(dissect_AllJoyn_message, proto_AllJoyn_mess);
alljoyn_handle_ardp = new_create_dissector_handle(dissect_AllJoyn_ardp, proto_AllJoyn_ardp);
} else {
dissector_delete_uint("udp.port", name_server_port, alljoyn_handle_ns);
dissector_delete_uint("tcp.port", name_server_port, alljoyn_handle_ns);
dissector_delete_uint("udp.port", message_port, alljoyn_handle_mess);
dissector_delete_uint("tcp.port", message_port, alljoyn_handle_mess);
dissector_delete_uint("udp.port", message_port, alljoyn_handle_ardp);
dissector_delete_uint("tcp.port", message_port, alljoyn_handle_ardp);
}
dissector_add_uint("udp.port", name_server_port, alljoyn_handle_ns);
dissector_add_uint("tcp.port", name_server_port, alljoyn_handle_ns);
dissector_add_uint("udp.port", message_port, alljoyn_handle_mess);
dissector_add_uint("tcp.port", message_port, alljoyn_handle_mess);
/* The ARDP dissector will directly call the AllJoyn message dissector if needed.
* This includes the case where there is no ARDP data. */
dissector_add_uint("udp.port", message_port, alljoyn_handle_ardp);
dissector_add_uint("tcp.port", message_port, alljoyn_handle_ardp);
}
/*
@ -2553,3 +3000,4 @@ proto_reg_handoff_AllJoyn(void)
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/