aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-alljoyn.c
diff options
context:
space:
mode:
authorJoseph Huffman <jhuffman@codeaurora.org>2014-10-21 11:23:45 -0700
committerMichael Mann <mmann78@netscape.net>2014-10-26 00:20:26 +0000
commit6e5784d88a3657b738db8a00a1a8a1c29ed16753 (patch)
treee2ce2ca86138de0604f2b34e6bbdb265961477c7 /epan/dissectors/packet-alljoyn.c
parent30742dd7c82bb74c0693e0ac2546473f1bc7c653 (diff)
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>
Diffstat (limited to 'epan/dissectors/packet-alljoyn.c')
-rw-r--r--epan/dissectors/packet-alljoyn.c528
1 files changed, 488 insertions, 40 deletions
diff --git a/epan/dissectors/packet-alljoyn.c b/epan/dissectors/packet-alljoyn.c
index 7b72e62428..4d37885554 100644
--- a/epan/dissectors/packet-alljoyn.c
+++ b/epan/dissectors/packet-alljoyn.c
@@ -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:
*/
+