diff options
author | Michael Mann <mmann78@netscape.net> | 2014-04-15 13:20:11 -0400 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2014-04-15 21:16:28 +0000 |
commit | c538b4498bc232302e50bcb8b0b1b36db82c6f79 (patch) | |
tree | 6cb292e250d445fd6f178bbc5ff6a28881a48047 /epan/dissectors/packet-alljoyn.c | |
parent | e80f9cda3801720739c87d291a2974b21c1395e9 (diff) |
Cleanup Alljoyn dissector.
Change-Id: I8de7a196ad068506f8e7312021879d20be4063d2
Reviewed-on: https://code.wireshark.org/review/1156
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Joe Huffman <jhuffman@codeaurora.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-alljoyn.c')
-rw-r--r-- | epan/dissectors/packet-alljoyn.c | 1199 |
1 files changed, 404 insertions, 795 deletions
diff --git a/epan/dissectors/packet-alljoyn.c b/epan/dissectors/packet-alljoyn.c index 2c942ecc89..6a29d9f0b0 100644 --- a/epan/dissectors/packet-alljoyn.c +++ b/epan/dissectors/packet-alljoyn.c @@ -42,8 +42,6 @@ static const int message_port = 9955; proto_register_protocol(). */ static int proto_AllJoyn_mess = -1; /* The top level. Entire AllJoyn message protocol. */ -static int proto_mess_connect_initial_byte = -1; -static int proto_mess_sasl = -1; /* SASL messages. */ /* These are Wireshark header fields. You can search/filter on these values. */ /* The initial byte sent when first connecting. */ @@ -104,13 +102,12 @@ static int hf_alljoyn_double = -1; /* Protocol identifiers. */ static int proto_AllJoyn_ns = -1; /* The top level. Entire AllJoyn Name Service protocol. */ -static int proto_ns_header = -1; /* The name service header. */ -static int proto_question = -1; -static int proto_answer = -1; -static int proto_isat_guid_string = -1; -static int proto_isat_entry = -1; -static int proto_bus_name_string = -1; +static int hf_alljoyn_answer = -1; +static int hf_alljoyn_isat_entry = -1; +static int hf_alljoyn_isat_guid_string = -1; + +static int hf_alljoyn_ns_header = -1; static int hf_alljoyn_ns_sender_version = -1; static int hf_alljoyn_ns_message_version = -1; static int hf_alljoyn_ns_questions = -1; @@ -124,6 +121,7 @@ static int hf_alljoyn_ns_timer = -1; #define WHOHAS_S 0x02 #define WHOHAS_F 0x01 +static int hf_alljoyn_ns_whohas = -1; static int hf_alljoyn_ns_whohas_t_flag = -1; /* 0x8 -- TCP */ static int hf_alljoyn_ns_whohas_u_flag = -1; /* 0x4 -- UDP */ static int hf_alljoyn_ns_whohas_s_flag = -1; /* 0x2 -- IPV6 */ @@ -188,13 +186,26 @@ static int hf_alljoyn_ns_isat_transport_mask_lan = -1; /* Wired local-area static int hf_alljoyn_ns_isat_transport_mask_ice = -1; /* Transport using ICE protocol */ static int hf_alljoyn_ns_isat_transport_mask_wfd = -1; /* Transport using Wi-Fi Direct transport */ +static int hf_alljoyn_string = -1; 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 */ /* 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; +static gint ett_alljoyn_ns_answers = -1; +static gint ett_alljoyn_ns_guid_string = -1; +static gint ett_alljoyn_ns_isat_entry = -1; +static gint ett_alljoyn_ns_string = -1; +static gint ett_alljoyn_whohas = -1; +static gint ett_alljoyn_string = -1; +static gint ett_alljoyn_isat_entry = -1; static gint ett_alljoyn_mess = -1; /* This is the top message tree. */ +static gint ett_alljoyn_header = -1; +static gint ett_alljoyn_header_flags = -1; +static gint ett_alljoyn_mess_header_field = -1; +static gint ett_alljoyn_mess_header = -1; #define ROUND_TO_2BYTE(len) ((len + 1) & ~1) #define ROUND_TO_4BYTE(len) ((len + 3) & ~3) @@ -299,7 +310,7 @@ get_uint32(tvbuff_t *tvb, * @param pinfo contains information about the incoming packet which * we update as we dissect the packet. * @param offset is the offset into the packet to check for the connect message. - * @param message_item is the subtree that any connect data items should be added to. + * @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 * the input offset value if it was not the connect initial byte of 0. */ @@ -307,36 +318,21 @@ static gint handle_message_connect(tvbuff_t *tvb, packet_info *pinfo, gint offset, - proto_item *message_item) + proto_tree *message_tree) { - gint return_value = offset; guint8 the_one_byte; the_one_byte = tvb_get_guint8(tvb, offset); if(0 == the_one_byte) { - if(pinfo) { - col_set_str(pinfo->cinfo, COL_INFO, "CONNECT-initial byte"); - } - - if(message_item) { - proto_item *one_byte_item; - proto_tree *subtree; - proto_tree *one_byte_tree; - - /* Add a subtree/row that says "Initial byte" below "AllJoyn Protocol". */ - one_byte_tree = proto_item_add_subtree(message_item, ett_alljoyn_mess); - one_byte_item = proto_tree_add_item(one_byte_tree, proto_mess_connect_initial_byte, tvb, offset, 1, ENC_NA); + col_set_str(pinfo->cinfo, COL_INFO, "CONNECT-initial byte"); - /* Now add the value as a subtree to the inital byte. */ - subtree = proto_item_add_subtree(one_byte_item, ett_alljoyn_mess); - proto_tree_add_item(subtree, hf_alljoyn_connect_byte_value, tvb, offset, 1, ENC_NA); - } - - return_value = offset + 1; + /* Now add the value as a subtree to the inital byte. */ + proto_tree_add_item(message_tree, hf_alljoyn_connect_byte_value, tvb, offset, 1, ENC_NA); + offset++; } - return return_value; + return offset; } typedef struct _sasl_cmd @@ -397,14 +393,13 @@ find_sasl_command(tvbuff_t *tvb, * @param pinfo contains information about the incoming packet which * we update as we dissect the packet. * @param offset is the offset into the packet to start processing. - * we update as we dissect the packet. - * @param message_item is the subtree that any connect data items should be added to. + * @param message_tree is the subtree that any connect data items should be added to. */ static gint handle_message_sasl(tvbuff_t *tvb, packet_info *pinfo, gint offset, - proto_item *message_item) + proto_tree *message_tree) { gint return_value = offset; const sasl_cmd *command; @@ -418,8 +413,8 @@ handle_message_sasl(tvbuff_t *tvb, return_value = tvb_find_guint8(tvb, offset + command->length, -1, '\n') + 1; /* If not found see if we should request another segment. */ - if(0 == return_value && pinfo) { - if((guint)tvb_length_remaining(tvb, offset) < MAX_SASL_PACKET_LENGTH && pinfo->can_desegment) { + if(0 == return_value) { + 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 is set by the caller. */ } @@ -431,26 +426,19 @@ handle_message_sasl(tvbuff_t *tvb, } if(return_value > 0) { - if(pinfo) { - col_add_fstr(pinfo->cinfo, COL_INFO, "SASL-%s", command->text); - } + gint length; - if(message_item) { - proto_item *tree; - gint length; + col_add_fstr(pinfo->cinfo, COL_INFO, "SASL-%s", command->text); - length = command->length; + length = command->length; - /* Add a subtree/row for the command. */ - tree = proto_item_add_subtree(message_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_sasl_command, tvb, 0, length, ENC_ASCII|ENC_NA); + /* Add a subtree/row for the command. */ + proto_tree_add_item(message_tree, hf_alljoyn_sasl_command, tvb, 0, length, ENC_ASCII|ENC_NA); - length = return_value - command->length; + length = return_value - command->length; - /* Add a subtree for the parameter. */ - tree = proto_item_add_subtree(message_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_sasl_parameter, tvb, command->length, length, ENC_ASCII|ENC_NA); - } + /* Add a subtree for the parameter. */ + proto_tree_add_item(message_tree, hf_alljoyn_sasl_parameter, tvb, command->length, length, ENC_ASCII|ENC_NA); } } @@ -494,174 +482,6 @@ get_message_header_endianness(tvbuff_t *tvb, return encoding; } -/* This is called by handle_message_header_body() to handle endianness in message - * headers. - * @param tvb is the incoming network data buffer. - * @param offset is the current offset into network data buffer. - * @param header_item is the subtree that we connect data items to. - * the message. - */ -static void -handle_message_header_endianness(tvbuff_t *tvb, - gint offset, - proto_item *header_item) -{ - if(header_item) { - proto_tree *tree; - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_header_endian, tvb, offset + ENDIANNESS_OFFSET, 1, ENC_NA); - } -} - -#define SERIAL_OFFSET 8 /* The offset for the serial is always 8. */ - -/* This is called by handle_message_header_body() to handle the message type - * in message headers. - * @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 offset is the offset into the packet to start processing. - * @param header_item is the subtree that we connect data items to. - * @param encoding is the type of big/little endian encoding used. - * @return the message type. - */ -static guint8 -handle_message_header_type(tvbuff_t *tvb, - packet_info *pinfo, - gint offset, - proto_item *header_item, - guint encoding) -{ - const guint TYPE_OFFSET = 1; /* The offset for type is always 1. */ - guint8 message_type; /* The message type field. */ - - message_type = tvb_get_guint8(tvb, offset + TYPE_OFFSET); - - if(header_item) { - proto_tree *tree; - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_header_type, tvb, offset + TYPE_OFFSET, 1, ENC_NA); - } - - if(pinfo) { - const gchar *type_str; - guint32 serial_number; - - if(message_type < array_length(message_header_encoding_vals) - 1) { - type_str = message_header_encoding_vals[message_type].strptr; - } else { - type_str = "Unexpected message type"; - } - - serial_number = get_uint32(tvb, offset + SERIAL_OFFSET, encoding); - col_add_fstr(pinfo->cinfo, COL_INFO, "Message %010u: '%s'", serial_number, type_str); - } - - return message_type; -} - -/* This is called by handle_message_header_body() to handle the message flags - * in message headers. - * @param tvb is the incoming network data buffer. - * @param offset is the offset into the packet to start processing. - * @param header_item is the subtree that we connect data items to. - */ -static void -handle_message_header_flags(tvbuff_t *tvb, - gint offset, - proto_item *header_item) -{ - if(header_item) { - const guint FLAGS_OFFSET = 2; /* The offset for the flags is always 2. */ - - /* The flags byte. */ - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - - /* Now the individual bits. */ - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_encrypted, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_compressed, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_global_broadcast, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_sessionless, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_allow_remote_msg, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_no_auto_start, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - proto_tree_add_item(header_item, hf_alljoyn_mess_header_flags_no_reply, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - } -} - -/* This is called by handle_message_header_body() to handle the - * major version in message headers. - * @param tvb is the incoming network data buffer. - * @param offset is the offset into the packet to start processing. - * @param header_item is the subtree that we connect data items to. - */ -static void -handle_message_majorversion(tvbuff_t *tvb, - gint offset, - proto_item *header_item) -{ - if(header_item) { - const guint MAJORVERSION_OFFSET = 3; /* The offset for the major version is always 3. */ - proto_tree *tree; - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_header_majorversion, tvb, offset + MAJORVERSION_OFFSET, 1, ENC_NA); - } -} - -/* This is called by handle_message_header_body() to handle the message body - * length in message headers. - * @param tvb is the incoming network data buffer. - * @param offset is the offset into the packet to start processing. - * @param header_item is the subtree that we connect data items to. - * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) - * endianness. - * @return The length of the message body. - */ -static gint32 -handle_message_header_body_length(tvbuff_t *tvb, - gint offset, - proto_item *header_item, - guint encoding) -{ - const guint BODY_LENGTH_OFFSET = 4; /* The offset for the length is always 4. */ - gint32 return_value; - - return_value = (gint)get_uint32(tvb, offset + BODY_LENGTH_OFFSET, encoding); - - if(header_item) { - proto_tree *tree; - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_header_body_length, tvb, offset + BODY_LENGTH_OFFSET, 4, encoding); - } - - return return_value; -} - -/* This is called by handle_message_header_body() to handle the message serial - * in message headers. - * @param tvb is the incoming network data buffer. - * @param offset is the offset into the packet to start processing. - * @param header_item is the subtree that we connect data items to. - * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) - * endianness. - */ -static void -handle_message_header_serial(tvbuff_t *tvb, - gint offset, - proto_item *header_item, - guint encoding) -{ - if(header_item) { - proto_tree *tree; - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_header_serial, tvb, offset + SERIAL_OFFSET, 4, encoding); - } -} - /* This is called by handle_message_field() to handle bytes of particular values * in messages. * @param tvb is the incoming network data buffer. @@ -676,12 +496,9 @@ handle_message_header_expected_byte(tvbuff_t *tvb, guint8 expected_value) { proto_item *item; - proto_tree *tree; guint8 byte_value; - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - item = proto_tree_add_item(tree, hf_alljoyn_uint8, tvb, offset, 1, ENC_NA); - + item = proto_tree_add_item(field_tree, hf_alljoyn_uint8, tvb, offset, 1, ENC_NA); byte_value = tvb_get_guint8(tvb, offset); if(expected_value == byte_value) { @@ -691,36 +508,6 @@ handle_message_header_expected_byte(tvbuff_t *tvb, } } -/* This is called by handle_message_header_body() to handle the message header - * length in message headers. - * @param tvb is the incoming network data buffer. - * @param offset is the offset into the packet to start processing. - * @param header_item is the subtree that we connect data items to. - * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) - * endianness. - * @return The length of the message header. - */ -static gint32 -handle_message_header_header_length(tvbuff_t *tvb, - gint offset, - proto_item *header_item, - guint encoding) -{ - const gint HEADER_LENGTH_OFFSET = 12; /* The offset for the length is always 12. */ - gint32 return_value; - - return_value = (gint)get_uint32(tvb, offset + HEADER_LENGTH_OFFSET, encoding); - - if(header_item) { - proto_tree *tree; - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_header_header_length, tvb, offset + HEADER_LENGTH_OFFSET, 4, encoding); - } - - return return_value; -} - /* * Message argument types */ @@ -896,8 +683,7 @@ parse_arg(tvbuff_t *tvb, if(*signature == NULL || *signature_length < 1) { col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: A %s argument needs a signature.", header_type_name); - offset = (gint)tvb_reported_length(tvb); - goto Error; + return tvb_reported_length(tvb); } /* *sig_saved will now be the element type after the 'a'. */ @@ -909,24 +695,18 @@ parse_arg(tvbuff_t *tvb, /* The + 4 is for the length specifier. */ if(length < 0 || length > MAX_ARRAY_LEN || offset + 4 + length > packet_length) { - col_add_fstr(pinfo->cinfo, COL_INFO, bad_array_format, length, tvb_length_remaining(tvb, offset + 4)); - offset = packet_length; - goto Error; + col_add_fstr(pinfo->cinfo, COL_INFO, bad_array_format, length, tvb_reported_length_remaining(tvb, offset + 4)); + return tvb_reported_length(tvb); } - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - - /* This item is the entire array including the length specifier. */ - item = proto_tree_add_item(tree, hf_alljoyn_mess_body_array, tvb, offset, length, encoding); - } + /* This item is the entire array including the length specifier. */ + item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_array, tvb, offset, length, encoding); offset = pad_according_to_type(offset + 4, packet_length, *sig_saved); /* Advance to the data elements. */ if(offset + length > packet_length) { - col_add_fstr(pinfo->cinfo, COL_INFO, bad_array_format, length, tvb_length_remaining(tvb, offset)); - offset = packet_length; - goto Error; + col_add_fstr(pinfo->cinfo, COL_INFO, bad_array_format, length, tvb_reported_length_remaining(tvb, offset)); + return tvb_reported_length(tvb); } starting_offset = offset; @@ -966,11 +746,7 @@ parse_arg(tvbuff_t *tvb, header_type_name = "boolean"; offset = ROUND_TO_4BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_boolean, tvb, offset, 4, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_boolean, tvb, offset, 4, encoding); offset += 4; break; @@ -978,11 +754,7 @@ parse_arg(tvbuff_t *tvb, header_type_name = "IEEE 754 double"; offset = ROUND_TO_8BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_double, tvb, offset, 8, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_double, tvb, offset, 8, encoding); offset += 8; break; @@ -990,29 +762,21 @@ parse_arg(tvbuff_t *tvb, header_type_name = "signature"; *signature_length = tvb_get_guint8(tvb, offset); - if(*signature_length + 2 > tvb_length_remaining(tvb, offset)) { - gint bytes_left = tvb_length_remaining(tvb, offset); + if(*signature_length + 2 > tvb_reported_length_remaining(tvb, offset)) { + gint bytes_left = tvb_reported_length_remaining(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Signature length is %d. Only %d bytes left in packet.", (gint)(*signature_length), bytes_left); - offset = tvb_reported_length(tvb); - goto Error; + return tvb_reported_length(tvb); } /* Include the terminating '/0'. */ length = *signature_length + 1; - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding); offset += 1; - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_body_signature, tvb, offset, length, ENC_ASCII|ENC_NA); - } + proto_tree_add_item(field_tree, hf_alljoyn_mess_body_signature, tvb, offset, length, ENC_ASCII|ENC_NA); *signature = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, length, ENC_ASCII); @@ -1027,11 +791,7 @@ parse_arg(tvbuff_t *tvb, header_type_name = "socket handle"; offset = ROUND_TO_4BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_handle, tvb, offset, 4, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_handle, tvb, offset, 4, encoding); offset += 4; break; @@ -1039,11 +799,7 @@ parse_arg(tvbuff_t *tvb, header_type_name = "int32"; offset = ROUND_TO_4BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_int32, tvb, offset, 4, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_int32, tvb, offset, 4, encoding); offset += 4; break; @@ -1051,11 +807,7 @@ parse_arg(tvbuff_t *tvb, header_type_name = "int16"; offset = ROUND_TO_2BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_int16, tvb, offset, 2, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_int16, tvb, offset, 2, encoding); offset += 2; break; @@ -1065,24 +817,16 @@ parse_arg(tvbuff_t *tvb, /* The + 4 is for the length specifier. Object pathes may be of "any length" according to D-Bus spec. But there are practical limit. */ - if(length < 0 || length > MAX_ARRAY_LEN || length + 4 > tvb_length_remaining(tvb, offset)) { + if(length < 0 || length > MAX_ARRAY_LEN || length + 4 > tvb_reported_length_remaining(tvb, offset)) { col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Object path length is %d. Only %d bytes left in packet.", - length, tvb_length_remaining(tvb, offset + 4)); - offset = tvb_reported_length(tvb); - goto Error; - } - - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); + length, tvb_reported_length_remaining(tvb, offset + 4)); + return tvb_reported_length(tvb); } + proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); offset += 4; - if(tree) { - proto_tree_add_item(tree, hf_alljoyn_string_data, tvb, offset, length, ENC_ASCII|ENC_NA); - } - + proto_tree_add_item(field_tree, hf_alljoyn_string_data, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; break; @@ -1090,11 +834,7 @@ parse_arg(tvbuff_t *tvb, header_type_name = "uint16"; offset = ROUND_TO_2BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_uint16, tvb, offset, 2, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_uint16, tvb, offset, 2, encoding); offset += 2; break; @@ -1102,37 +842,27 @@ parse_arg(tvbuff_t *tvb, header_type_name = "string"; offset = ROUND_TO_4BYTE(offset); - if(field_tree) { - /* Display the length. */ - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_string_size_32bit, tvb, offset, 4, encoding); - } + proto_tree_add_item(field_tree, hf_alljoyn_string_size_32bit, tvb, offset, 4, encoding); /* Get the length so we can display the string. */ length = (gint)get_uint32(tvb, offset, encoding); - if(length < 0 || length > tvb_length_remaining(tvb, offset)) { + if(length < 0 || length > tvb_reported_length_remaining(tvb, offset)) { col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: String length is %d. Remaining packet length is %d.", - length, (gint)tvb_length_remaining(tvb, offset)); - offset = (gint)tvb_reported_length(tvb); - goto Error; + length, (gint)tvb_reported_length_remaining(tvb, offset)); + return tvb_reported_length(tvb); } length += 1; /* Include the '\0'. */ offset += 4; - if(tree) { - /* Display the actual string. */ - proto_tree_add_item(tree, hf_alljoyn_string_data, tvb, offset, length, ENC_UTF_8|ENC_NA); - } + proto_tree_add_item(field_tree, hf_alljoyn_string_data, tvb, offset, length, ENC_UTF_8|ENC_NA); if(HDR_MEMBER == field_code) { - if(pinfo->cinfo) { - guint8 *member_name; + guint8 *member_name; - member_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, length, ENC_UTF_8); - col_append_fstr(pinfo->cinfo, COL_INFO, " %s", member_name); - } + member_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, length, ENC_UTF_8); + col_append_fstr(pinfo->cinfo, COL_INFO, " %s", member_name); } offset += length; @@ -1142,16 +872,11 @@ parse_arg(tvbuff_t *tvb, header_type_name = "uint64"; offset = ROUND_TO_8BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_uint64, tvb, offset, 8, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_uint64, tvb, offset, 8, encoding); offset += 8; break; case ARG_UINT32: /* AllJoyn 32-bit unsigned integer basic type */ - header_type_name = "uint32"; offset = ROUND_TO_4BYTE(offset); @@ -1171,10 +896,7 @@ parse_arg(tvbuff_t *tvb, proto_item_set_text(item, format + 1, replies_to); } } else { - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); - } + proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); } offset += 4; @@ -1192,8 +914,8 @@ parse_arg(tvbuff_t *tvb, variant_sig_length = tvb_get_guint8(tvb, offset); length = variant_sig_length; - if(length > tvb_length_remaining(tvb, offset)) { - gint bytes_left = tvb_length_remaining(tvb, offset); + if(length > tvb_reported_length_remaining(tvb, offset)) { + gint bytes_left = tvb_reported_length_remaining(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Variant signature length is %d. Only %d bytes left in packet.", length, bytes_left); @@ -1202,14 +924,11 @@ parse_arg(tvbuff_t *tvb, length += 1; /* Include the terminating '\0'. */ - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - /* This length (4) will be updated later with the length of the entire variant object. */ - item = proto_tree_add_item(tree, hf_alljoyn_mess_body_variant, tvb, offset, 4, encoding); + /* This length (4) will be updated later with the length of the entire variant object. */ + item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_variant, tvb, offset, 4, encoding); + tree = proto_item_add_subtree(item, ett_alljoyn_mess); - tree = proto_item_add_subtree(item, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding); - } + proto_tree_add_item(tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding); offset += 1; @@ -1224,22 +943,11 @@ parse_arg(tvbuff_t *tvb, sig_pointer = sig_saved; /* The signature of the variant has now been taken care of. So now take care of the variant data. */ - while(((sig_pointer - sig_saved) < (length - 1)) && (tvb_length_remaining(tvb, offset) > 0)) { - if(item) { - proto_item_append_text(item, "%c", *sig_pointer); - } + while(((sig_pointer - sig_saved) < (length - 1)) && (tvb_reported_length_remaining(tvb, offset) > 0)) { + proto_item_append_text(item, "%c", *sig_pointer); - offset = parse_arg(tvb, - pinfo, - header_item, - encoding, - offset, - item, - is_reply_to, - *sig_pointer, - field_code, - &sig_pointer, - &variant_sig_length); + offset = parse_arg(tvb, pinfo, header_item, encoding, offset, item, is_reply_to, + *sig_pointer, field_code, &sig_pointer, &variant_sig_length); } if(item) { @@ -1253,22 +961,14 @@ parse_arg(tvbuff_t *tvb, header_type_name = "int64"; offset = ROUND_TO_8BYTE(offset); - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_int64, tvb, offset, 8, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_int64, tvb, offset, 8, encoding); offset += 8; break; case ARG_BYTE: /* AllJoyn 8-bit unsigned integer basic type */ header_type_name = "byte"; - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - proto_tree_add_item(tree, hf_alljoyn_uint8, tvb, offset, 1, encoding); - } - + proto_tree_add_item(field_tree, hf_alljoyn_uint8, tvb, offset, 1, encoding); offset += 1; break; @@ -1291,24 +991,19 @@ parse_arg(tvbuff_t *tvb, if(*signature == NULL || *signature_length < 1) { col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: A %s argument needs a signature.", header_type_name); - offset = (gint)tvb_reported_length(tvb); - goto Error; + return tvb_reported_length(tvb); } - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - - /* This length (4) will be updated later with the length of the entire struct. */ - item = proto_tree_add_item(tree, hf, tvb, offset, 4, encoding); - append_struct_signature(item, *signature, *signature_length, type_stop); - } + /* This length (4) will be updated later with the length of the entire struct. */ + item = proto_tree_add_item(field_tree, hf, tvb, offset, 4, encoding); + append_struct_signature(item, *signature, *signature_length, type_stop); offset = pad_according_to_type(offset, tvb_reported_length(tvb), type_id); (*signature)++; /* Advance past the '(' or '{'. */ /* *signature should never be NULL but just make sure to avoid potential issues. */ - while(*signature && **signature != type_stop && tvb_length_remaining(tvb, offset) > 0) { + while(*signature && **signature != type_stop && tvb_reported_length_remaining(tvb, offset) > 0) { offset = parse_arg(tvb, pinfo, header_item, @@ -1346,8 +1041,6 @@ parse_arg(tvbuff_t *tvb, proto_item_append_text(header_item, "%s", header_type_name); } -Error: - /* Make sure we never return something longer than the buffer for an offset. */ if(offset > (gint)tvb_reported_length(tvb)) { offset = (gint)tvb_reported_length(tvb); @@ -1356,6 +1049,12 @@ Error: return offset; } +static void +alljoyn_typeid( gchar *result, guint32 type ) +{ + g_snprintf( result, ITEM_LABEL_LENGTH, "'%c' => ", type); +} + /* This is called by handle_message_header_fields() to handle a single * message header field. * @param tvb is the incoming network data buffer. @@ -1375,57 +1074,40 @@ Error: static gint handle_message_field(tvbuff_t *tvb, packet_info *pinfo, - proto_item *header_item, + proto_item *header_tree, guint encoding, gint offset, guint8 **signature, guint8 *signature_length) { proto_tree *tree = NULL, *field_tree = NULL; - proto_item *item = NULL; + proto_item *item, *field_item; guint8 field_code; guint8 type_id; gboolean is_reply_to = FALSE; field_code = tvb_get_guint8(tvb, offset); - if(header_item) { - - if(HDR_REPLY_SERIAL == field_code) { - is_reply_to = TRUE; - } - - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - field_tree = proto_tree_add_item(tree, hf_alljoyn_mess_header_field, tvb, offset, 1, ENC_NA); - - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - item = proto_tree_add_item(tree, hf_alljoyn_mess_body_header_fieldcode, tvb, offset, 1, ENC_NA); + if(HDR_REPLY_SERIAL == field_code) { + is_reply_to = TRUE; } - offset += 1; + field_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_field, tvb, offset, 1, ENC_NA); + field_tree = proto_item_add_subtree(field_item, ett_alljoyn_mess_header_field); - if(field_tree) { - /* We expect a byte of 0x01 here. */ - handle_message_header_expected_byte(tvb, offset, field_tree, 0x01); - } + proto_tree_add_item(field_tree, hf_alljoyn_mess_body_header_fieldcode, tvb, offset, 1, ENC_NA); + offset += 1; + /* We expect a byte of 0x01 here. */ + handle_message_header_expected_byte(tvb, offset, field_tree, 0x01); offset += 1; + item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_header_typeid, tvb, offset, 1, ENC_NA); type_id = tvb_get_guint8(tvb, offset); - - if(field_tree) { - tree = proto_item_add_subtree(field_tree, ett_alljoyn_mess); - item = proto_tree_add_item(tree, hf_alljoyn_mess_body_header_typeid, tvb, offset, 1, ENC_NA); - proto_item_set_text(item, "Type id: '%c' => ", type_id); - } - offset += 1; - if(field_tree) { - /* We expect a byte of 0x00 here. */ - handle_message_header_expected_byte(tvb, offset, field_tree, 0x00); - } - + /* We expect a byte of 0x00 here. */ + handle_message_header_expected_byte(tvb, offset, field_tree, 0x00); offset += 1; offset = parse_arg(tvb, @@ -1446,9 +1128,7 @@ handle_message_field(tvbuff_t *tvb, offset = (gint)tvb_reported_length(tvb); } - if(field_tree) { - proto_item_set_end(field_tree, tvb, offset); - } + proto_item_set_end(field_tree, tvb, offset); return offset; } @@ -1457,7 +1137,7 @@ handle_message_field(tvbuff_t *tvb, * @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 header_item is the subtree that we connect data items to. + * @param header_tree is the subtree that we connect data items to. * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) * @param offset contains the offset into tvb for the start of the header fields. * @param header_length contains the length of the message fields. @@ -1466,28 +1146,24 @@ handle_message_field(tvbuff_t *tvb, static guint8 * handle_message_header_fields(tvbuff_t *tvb, packet_info *pinfo, - proto_item *header_item, + proto_item *header_tree, guint encoding, gint offset, guint32 header_length, guint8 *signature_length) { gint end_of_header; - proto_item *item = NULL; + proto_item *item; + proto_tree *tree; guint8 *signature = NULL; - if(header_item) { - proto_tree *tree; - - /* Add a subtree/row for the message body. */ - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - item = proto_tree_add_item(tree, hf_alljoyn_mess_header_fields, tvb, offset, header_length, ENC_NA); - } + item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_fields, tvb, offset, header_length, ENC_NA); + tree = proto_item_add_subtree(item, ett_alljoyn_mess_header); end_of_header = offset + header_length; while(offset < end_of_header) { - offset = handle_message_field(tvb, pinfo, item, encoding, offset, &signature, signature_length); + offset = handle_message_field(tvb, pinfo, tree, encoding, offset, &signature, signature_length); } return signature; @@ -1495,7 +1171,7 @@ handle_message_header_fields(tvbuff_t *tvb, /* This is called by handle_message() to handle the message body. * @param tvb is the incoming network data buffer. - * @param header_item is the subtree that we connect data items to. + * @param header_tree is the subtree that we connect data items to. * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) * @param offset contains the offset into tvb for the start of the parameters. * @param body_length contains the length of the body parameters. @@ -1505,7 +1181,7 @@ handle_message_header_fields(tvbuff_t *tvb, static gint handle_message_body_parameters(tvbuff_t *tvb, packet_info *pinfo, - proto_item *header_item, + proto_tree *header_tree, guint encoding, gint offset, gint32 body_length, @@ -1517,13 +1193,8 @@ handle_message_body_parameters(tvbuff_t *tvb, packet_length = tvb_reported_length(tvb); - if(header_item) { - proto_tree *tree; - - /* Add a subtree/row for the message body parameters. */ - tree = proto_item_add_subtree(header_item, ett_alljoyn_mess); - item = proto_tree_add_item(tree, hf_alljoyn_mess_body_parameters, tvb, offset, body_length, ENC_NA); - } + /* Add a subtree/row for the message body parameters. */ + item = proto_tree_add_item(header_tree, hf_alljoyn_mess_body_parameters, tvb, offset, body_length, ENC_NA); end_of_body = offset + body_length; @@ -1548,13 +1219,21 @@ handle_message_body_parameters(tvbuff_t *tvb, return offset; } +#define MESSAGE_HEADER_LENGTH 16 +#define TYPE_OFFSET 1 +#define FLAGS_OFFSET 2 +#define MAJORVERSION_OFFSET 3 +#define BODY_LENGTH_OFFSET 4 +#define SERIAL_OFFSET 8 +#define HEADER_LENGTH_OFFSET 12 + /* This is called by dissect_AllJoyn_message() to handle the actual message. * 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 offset is the offset into the packet to start processing. - * @param message_item is the subtree that any connect data items should be added to. + * @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 * the input offset value if it was not a message header body.. */ @@ -1562,46 +1241,30 @@ static gint handle_message_header_body(tvbuff_t *tvb, packet_info *pinfo, gint offset, - proto_item *message_item) + proto_item *message_tree) { - const guint MESSAGE_HEADER_LENGTH = 16; gint return_value; - guint remaining_packet_length; + gint remaining_packet_length; guint8 *signature = NULL; guint8 signature_length = 0; - proto_tree *header_tree = NULL; - proto_item *header_item = NULL; + proto_tree *header_tree, *flag_tree; + proto_item *header_item, *flag_item; guint encoding; - gint8 message_type; gint header_length = 0, body_length = 0; return_value = offset; encoding = get_message_header_endianness(tvb, offset); - message_type = handle_message_header_type(tvb, NULL, 0, NULL, encoding); - - /* This is just a test to see if the data is probably ours. */ - if(ENC_ALLJOYN_BAD_ENCODING == encoding || message_type == MESSAGE_TYPE_INVALID) { - return_value = 0; /* No. The data is not ours or it has been corrupted. */ - goto Done; - } - /* Is this just a protocol check? */ - if(offset == 0 && !pinfo && !message_item) { - return_value = 1; - goto Done; - } - - remaining_packet_length = tvb_length_remaining(tvb, offset); + remaining_packet_length = tvb_reported_length_remaining(tvb, offset); if(remaining_packet_length < MESSAGE_HEADER_LENGTH || remaining_packet_length > MAX_PACKET_LEN) { col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %u. Expected >= %d && <= %d", remaining_packet_length, MESSAGE_HEADER_LENGTH, MAX_PACKET_LEN); - return_value = tvb_reported_length(tvb); /* We are done with everything in this packet don't try anymore. */ - goto Done; + return tvb_reported_length(tvb); /* We are done with everything in this packet don't try anymore. */ } - header_length = handle_message_header_header_length(tvb, offset, NULL, encoding); - body_length = handle_message_header_body_length(tvb, offset, NULL, encoding); + header_length = get_uint32(tvb, offset + HEADER_LENGTH_OFFSET, encoding); + body_length = get_uint32(tvb, offset + BODY_LENGTH_OFFSET, encoding); if(ROUND_TO_8BYTE(header_length) + body_length + MESSAGE_HEADER_LENGTH > remaining_packet_length) { if(pinfo->can_desegment) { @@ -1615,41 +1278,48 @@ handle_message_header_body(tvbuff_t *tvb, return_value = 0; } - goto Done; + return return_value; } - /* Done with testing for validity and enough data. We are good to go now. */ - if(message_item) { - /* Add a subtree/row for the header. */ - header_tree = proto_item_add_subtree(message_item, ett_alljoyn_mess); - header_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header, tvb, offset, MESSAGE_HEADER_LENGTH, ENC_NA); - } + /* Add a subtree/row for the header. */ + header_item = proto_tree_add_item(message_tree, hf_alljoyn_mess_header, tvb, offset, MESSAGE_HEADER_LENGTH, ENC_NA); + header_tree = proto_item_add_subtree(header_item, ett_alljoyn_header); + + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_endian, tvb, offset + ENDIANNESS_OFFSET, 1, ENC_NA); + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_type, tvb, offset + TYPE_OFFSET, 1, ENC_NA); + + /* The flags byte. */ + flag_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_flags, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + flag_tree = proto_item_add_subtree(flag_item, ett_alljoyn_header_flags); - handle_message_header_endianness(tvb, offset, header_item); + /* Now the individual bits. */ + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_encrypted, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_compressed, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_global_broadcast, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_sessionless, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_allow_remote_msg, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_no_auto_start, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); + proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_no_reply, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); - handle_message_header_type(tvb, pinfo, offset, header_item, encoding); - handle_message_header_flags(tvb, offset, header_item); - handle_message_majorversion(tvb, offset, header_item); + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_majorversion, tvb, offset + MAJORVERSION_OFFSET, 1, ENC_NA); + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_body_length, tvb, offset + BODY_LENGTH_OFFSET, 4, encoding); - handle_message_header_body_length(tvb, offset, header_item, encoding); - handle_message_header_serial(tvb, offset, header_item, encoding); - handle_message_header_header_length(tvb, offset, header_item, encoding); + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_serial, tvb, offset + SERIAL_OFFSET, 4, encoding); + col_add_fstr(pinfo->cinfo, COL_INFO, "Message %010u: '%s'", get_uint32(tvb, offset + SERIAL_OFFSET, encoding), + val_to_str_const(tvb_get_guint8(tvb, offset + TYPE_OFFSET), message_header_encoding_vals, "Unexpected message type")); + + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_header_length, tvb, offset + HEADER_LENGTH_OFFSET, 4, encoding); offset = ROUND_TO_8BYTE(offset + MESSAGE_HEADER_LENGTH); - signature = handle_message_header_fields(tvb, - pinfo, - message_item, - encoding, - offset, - header_length, - &signature_length); + signature = handle_message_header_fields(tvb, pinfo, message_tree, encoding, + offset, header_length, &signature_length); offset += ROUND_TO_8BYTE(header_length); if(body_length > 0 && signature != NULL && signature_length > 0) { return_value = handle_message_body_parameters(tvb, pinfo, - message_item, + message_tree, encoding, offset, body_length, @@ -1659,22 +1329,31 @@ handle_message_header_body(tvbuff_t *tvb, return_value = offset; } -Done: return return_value; } static gboolean protocol_is_ours(tvbuff_t *tvb) { - gboolean return_value = TRUE; + int length = tvb_captured_length(tvb); - if(handle_message_connect(tvb, NULL, 0, NULL) == 0 && - handle_message_sasl(tvb, NULL, 0, NULL) == 0 && - handle_message_header_body(tvb, NULL, 0, NULL) == 0) { - return_value = FALSE; - } + if (length < 1) + return FALSE; - return return_value; + /* initial byte for a connect message. */ + if (tvb_get_guint8(tvb, 0) == 0) + return TRUE; + + if (find_sasl_command(tvb, 0) != NULL) + return TRUE; + + if (get_message_header_endianness(tvb, 0) == ENC_ALLJOYN_BAD_ENCODING) + return FALSE; + + if ((length < 2) || (try_val_to_str(tvb_get_guint8(tvb, 1), message_header_encoding_vals) == NULL)) + return FALSE; + + return TRUE; } /* This is called by Wireshark for packet types that are registered @@ -1696,161 +1375,93 @@ dissect_AllJoyn_message(tvbuff_t *tvb, void *data _U_) { gint offset = 0; + proto_item *message_item; + proto_tree *message_tree; + gint last_offset = -1; + gint packet_length; - if(protocol_is_ours(tvb)) { - proto_item *message_item = NULL; - gint last_offset = -1; - gint packet_length; - - packet_length = (gint)tvb_reported_length(tvb); - - col_clear(pinfo->cinfo, COL_INFO); - - if(tree) { - /* Add a subtree covering the remainder of the packet */ - message_item = proto_tree_add_item(tree, proto_AllJoyn_mess, tvb, 0, -1, ENC_NA); - } + if(!protocol_is_ours(tvb)) { + return 0; + } - /* 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_item); + packet_length = tvb_reported_length(tvb); - if(offset >= packet_length) { - break; - } + col_clear(pinfo->cinfo, COL_INFO); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN"); - offset = handle_message_sasl(tvb, pinfo, offset, message_item); + /* Add a subtree covering the remainder of the packet */ + message_item = proto_tree_add_item(tree, proto_AllJoyn_mess, tvb, 0, -1, ENC_NA); + message_tree = proto_item_add_subtree(message_item, ett_alljoyn_mess); - if(offset >= packet_length) { - break; - } + /* 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); - offset = handle_message_header_body(tvb, pinfo, offset, message_item); + if(offset >= packet_length) { + break; } - /* If we saw any traffic that we recognized in this packet mark it as ours. */ - if(offset > 0 || last_offset > 0) { - /* This is message traffic. Mark it as such at the top level. */ - col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN"); - } + offset = handle_message_sasl(tvb, pinfo, offset, message_tree); - if(0 == offset && pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) { - if(last_offset > 0) { - pinfo->desegment_offset = last_offset; - } else { - pinfo->desegment_offset = 0; - } + if(offset >= packet_length) { + break; } - } - - return offset; -} - -/* This is a container for the name service and Wireshark tree information. - */ -typedef struct _alljoyn_name_server_tree_data -{ - gint offset; - gint sender_version; - gint message_version; - gint nQuestions; - gint nAnswers; - proto_tree *alljoyn_tree; -} alljoyn_name_server_tree_data; - -/* This is called by dissect_AllJoyn_name_server() to read the header - * and put fill out most of tree_data. - * @param tvb is the incoming network data buffer. - * @param tree_data is the destinationn of the data.. - */ -static void -ns_parse_header(tvbuff_t *tvb, - alljoyn_name_server_tree_data *tree_data) -{ - gint version; - proto_tree *alljoyn_header_tree = NULL; - - if(tree_data->alljoyn_tree) { - proto_item *alljoyn_header_item; - - /* Add the "header protocol" as a subtree from the AllJoyn Name Service Protocol. */ - alljoyn_header_item = proto_tree_add_item(tree_data->alljoyn_tree, proto_ns_header, tvb, tree_data->offset, 4, ENC_NA); - alljoyn_header_tree = proto_item_add_subtree(alljoyn_header_item, ett_alljoyn_ns); - /* The the sender and message versions as fields for the header protocol. */ - proto_tree_add_item(alljoyn_header_tree, hf_alljoyn_ns_sender_version, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_header_tree, hf_alljoyn_ns_message_version, tvb, tree_data->offset, 1, ENC_NA); + offset = handle_message_header_body(tvb, pinfo, offset, message_tree); } - version = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset += 1; - - tree_data->sender_version = version >> 4; - tree_data->message_version = version & 0xF; - - if(tree_data->alljoyn_tree) { - proto_tree_add_item(alljoyn_header_tree, hf_alljoyn_ns_questions, tvb, tree_data->offset, 1, ENC_NA); - } - - tree_data->nQuestions = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset += 1; - - if(tree_data->alljoyn_tree) { - proto_tree_add_item(alljoyn_header_tree, hf_alljoyn_ns_answers, tvb, tree_data->offset, 1, ENC_NA); - } - - tree_data->nAnswers = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset += 1; - - if(tree_data->alljoyn_tree) { - proto_tree_add_item(alljoyn_header_tree, hf_alljoyn_ns_timer, tvb, tree_data->offset, 1, ENC_NA); + if(0 == offset && pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT) { + if(last_offset > 0) { + pinfo->desegment_offset = last_offset; + } else { + pinfo->desegment_offset = 0; + } } - tree_data->offset += 1; + return offset; } static void -ns_parse_questions(tvbuff_t *tvb, - alljoyn_name_server_tree_data *tree_data) +ns_parse_questions(tvbuff_t *tvb, gint* offset, proto_tree* alljoyn_tree, guint8 questions, guint message_version) { - while (tree_data->nQuestions--) { + while (questions--) { proto_item *alljoyn_questions_ti = NULL; proto_tree *alljoyn_questions_tree = NULL; gint count = 0; - alljoyn_questions_ti = proto_tree_add_item(tree_data->alljoyn_tree, proto_question, tvb, tree_data->offset, 2, ENC_NA); - alljoyn_questions_tree = proto_item_add_subtree(alljoyn_questions_ti, ett_alljoyn_ns); + alljoyn_questions_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_ns_whohas, tvb, *offset, 2, ENC_NA); /* "Who-Has Message" */ + alljoyn_questions_tree = proto_item_add_subtree(alljoyn_questions_ti, ett_alljoyn_whohas); - if(0 == tree_data->message_version) { - proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_t_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_u_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_s_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_f_flag, tvb, tree_data->offset, 1, ENC_NA); + if(0 == message_version) { + proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_t_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_u_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_s_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_f_flag, tvb, *offset, 1, ENC_NA); } - tree_data->offset++; + (*offset)++; - proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_count, tvb, tree_data->offset, 1, ENC_NA); - count = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset++; + proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_count, tvb, *offset, 1, ENC_NA); + count = tvb_get_guint8(tvb, *offset); + (*offset)++; while (count--) { proto_item *alljoyn_bus_name_ti = NULL; proto_tree *alljoyn_bus_name_tree = NULL; gint bus_name_size = 0; - bus_name_size = tvb_get_guint8(tvb, tree_data->offset); + bus_name_size = tvb_get_guint8(tvb, *offset); - alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_questions_tree, proto_bus_name_string, tvb, - tree_data->offset, 1 + bus_name_size, ENC_NA); - alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_ns); + alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_string, tvb, + *offset, 1 + bus_name_size, ENC_NA); + alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_ns_string); - proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, tree_data->offset, 1, ENC_NA); - tree_data->offset++; + proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); + (*offset)++; - proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, tree_data->offset, bus_name_size, ENC_ASCII|ENC_NA); - tree_data->offset += bus_name_size; + proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII|ENC_NA); + (*offset) += bus_name_size; } } @@ -1893,42 +1504,41 @@ ns_parse_questions(tvbuff_t *tvb, * The next data is a variable number of StringData records. */ static void -ns_parse_answers_v0(tvbuff_t *tvb, - alljoyn_name_server_tree_data *tree_data) +ns_parse_answers_v0(tvbuff_t *tvb, gint* offset, proto_tree* alljoyn_tree, guint8 answers) { - while (tree_data->nAnswers--) { + while (answers--) { proto_item *alljoyn_answers_ti = NULL; proto_tree *alljoyn_answers_tree = NULL; gint flags = 0; gint count = 0; - alljoyn_answers_ti = proto_tree_add_item(tree_data->alljoyn_tree, proto_answer, tvb, tree_data->offset, 2, ENC_NA); - alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns); + alljoyn_answers_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_answer, tvb, *offset, 2, ENC_NA); + alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns_answers); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_t_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_s_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_f_flag, tvb, tree_data->offset, 1, ENC_NA); - flags = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset++; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_t_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_s_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_f_flag, tvb, *offset, 1, ENC_NA); + flags = tvb_get_guint8(tvb, *offset); + (*offset)++; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_count, tvb, tree_data->offset, 1, ENC_NA); - count = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset++; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_count, tvb, *offset, 1, ENC_NA); + count = tvb_get_guint8(tvb, *offset); + (*offset)++; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, tree_data->offset, 2, ENC_NA); - tree_data->offset += 2; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_NA); + (*offset) += 2; if (flags & ISAT_S) { - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, tree_data->offset, 16, ENC_NA); - tree_data->offset += 16; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA); + (*offset) += 16; } if (flags & ISAT_F) { - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, tree_data->offset, 4, ENC_NA); - tree_data->offset += 4; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_NA); + (*offset) += 4; } if (flags & ISAT_G) { @@ -1936,17 +1546,17 @@ ns_parse_answers_v0(tvbuff_t *tvb, proto_tree *alljoyn_string_tree = NULL; gint guid_size = 0; - guid_size = tvb_get_guint8(tvb, tree_data->offset); + guid_size = tvb_get_guint8(tvb, *offset); - alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, proto_isat_guid_string, tvb, - tree_data->offset, 1 + guid_size, ENC_NA); - alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns); + alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_guid_string, tvb, + *offset, 1 + guid_size, ENC_NA); + alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns_guid_string); - proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, tree_data->offset, 1, ENC_NA); - tree_data->offset++; + proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); + (*offset)++; - proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, tree_data->offset, guid_size, ENC_ASCII|ENC_NA); - tree_data->offset += guid_size; + proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, *offset, guid_size, ENC_ASCII|ENC_NA); + (*offset) += guid_size; } while (count--) { @@ -1954,21 +1564,21 @@ ns_parse_answers_v0(tvbuff_t *tvb, proto_tree *alljoyn_entry_tree= NULL; proto_item *alljoyn_bus_name_ti = NULL; proto_tree *alljoyn_bus_name_tree = NULL; - gint bus_name_size = tvb_get_guint8(tvb, tree_data->offset); + gint bus_name_size = tvb_get_guint8(tvb, *offset); - alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, proto_isat_entry, tvb, - tree_data->offset, 1 + bus_name_size, ENC_NA); - alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_ns); + alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_entry, tvb, + *offset, 1 + bus_name_size, ENC_NA); + alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_ns_isat_entry); - alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, proto_bus_name_string, tvb, tree_data->offset, + alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, hf_alljoyn_string, tvb, *offset, 1 + bus_name_size, ENC_NA); - alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_ns); + alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_string); - proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, tree_data->offset, 1, ENC_NA); - tree_data->offset += 1; + proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); + (*offset) += 1; - proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, tree_data->offset, bus_name_size, ENC_ASCII|ENC_NA); - tree_data->offset += bus_name_size; + proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII|ENC_NA); + (*offset) += bus_name_size; } } } @@ -2023,78 +1633,77 @@ ns_parse_answers_v0(tvbuff_t *tvb, * The next data is a variable number of StringData records. */ static void -ns_parse_answers_v1(tvbuff_t *tvb, - alljoyn_name_server_tree_data *tree_data) +ns_parse_answers_v1(tvbuff_t *tvb, gint* offset, proto_tree* alljoyn_tree, guint8 answers) { - while (tree_data->nAnswers--) { + while (answers--) { proto_item *alljoyn_answers_ti = NULL; proto_tree *alljoyn_answers_tree = NULL; gint flags = 0; gint count = 0; - alljoyn_answers_ti = proto_tree_add_item(tree_data->alljoyn_tree, proto_answer, tvb, tree_data->offset, 2, ENC_NA); - alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns); + alljoyn_answers_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_answer, tvb, *offset, 2, ENC_NA); + alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns_answers); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, tree_data->offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, *offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r4_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u4_flag, tvb, tree_data->offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r4_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u4_flag, tvb, *offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r6_flag, tvb, tree_data->offset, 1, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u6_flag, tvb, tree_data->offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r6_flag, tvb, *offset, 1, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u6_flag, tvb, *offset, 1, ENC_NA); - flags = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset++; + flags = tvb_get_guint8(tvb, *offset); + (*offset)++; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_count, tvb, tree_data->offset, 1, ENC_NA); - count = tvb_get_guint8(tvb, tree_data->offset); - tree_data->offset++; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_count, tvb, *offset, 1, ENC_NA); + count = tvb_get_guint8(tvb, *offset); + (*offset)++; /* The entire transport mask. */ - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask, tvb, tree_data->offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask, tvb, *offset, 2, ENC_NA); /* The individual bits of the transport mask. */ - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wfd, tvb, tree_data->offset, 2, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_ice, tvb, tree_data->offset, 2, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_lan, tvb, tree_data->offset, 2, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wwan, tvb, tree_data->offset, 2, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_tcp, tvb, tree_data->offset, 2, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_bluetooth, tvb, tree_data->offset, 2, ENC_NA); - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_local, tvb, tree_data->offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wfd, tvb, *offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_ice, tvb, *offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_lan, tvb, *offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wwan, tvb, *offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_tcp, tvb, *offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_bluetooth, tvb, *offset, 2, ENC_NA); + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_local, tvb, *offset, 2, ENC_NA); - tree_data->offset += 2; + (*offset) += 2; if (flags & ISAT_R4) { - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, tree_data->offset, 4, ENC_NA); - tree_data->offset += 4; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_NA); + (*offset) += 4; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, tree_data->offset, 2, ENC_NA); - tree_data->offset += 2; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_NA); + (*offset) += 2; } if (flags & ISAT_U4) { - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, tree_data->offset, 4, ENC_NA); - tree_data->offset += 4; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_NA); + (*offset) += 4; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, tree_data->offset, 2, ENC_NA); - tree_data->offset += 2; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_NA); + (*offset) += 2; } if (flags & ISAT_R6) { - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, tree_data->offset, 16, ENC_NA); - tree_data->offset += 16; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA); + (*offset) += 16; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, tree_data->offset, 2, ENC_NA); - tree_data->offset += 2; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_NA); + (*offset) += 2; } if (flags & ISAT_U6) { - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, tree_data->offset, 16, ENC_NA); - tree_data->offset += 16; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA); + (*offset) += 16; - proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, tree_data->offset, 2, ENC_NA); - tree_data->offset += 2; + proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_NA); + (*offset) += 2; } if (flags & ISAT_G) { @@ -2102,17 +1711,17 @@ ns_parse_answers_v1(tvbuff_t *tvb, proto_tree *alljoyn_string_tree = NULL; gint guid_size = 0; - guid_size = tvb_get_guint8(tvb, tree_data->offset); + guid_size = tvb_get_guint8(tvb, *offset); - alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, proto_isat_guid_string, tvb, - tree_data->offset, 1 + guid_size, ENC_NA); - alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns); + alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_guid_string, tvb, + *offset, 1 + guid_size, ENC_NA); + alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns_guid_string); - proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, tree_data->offset, 1, ENC_NA); - tree_data->offset++; + proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); + (*offset)++; - proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, tree_data->offset, guid_size, ENC_ASCII|ENC_NA); - tree_data->offset += guid_size; + proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, *offset, guid_size, ENC_ASCII|ENC_NA); + (*offset) += guid_size; } /* The string data records. */ @@ -2122,43 +1731,25 @@ ns_parse_answers_v1(tvbuff_t *tvb, proto_tree *alljoyn_bus_name_ti = NULL; proto_tree *alljoyn_bus_name_tree = NULL; - gint bus_name_size = tvb_get_guint8(tvb, tree_data->offset); + gint bus_name_size = tvb_get_guint8(tvb, *offset); - alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, proto_isat_entry, tvb, - tree_data->offset, 1 + bus_name_size, ENC_NA); - alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_ns); + alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_entry, tvb, + *offset, 1 + bus_name_size, ENC_NA); + alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_isat_entry); - alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, proto_bus_name_string, tvb, tree_data->offset, + alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, hf_alljoyn_string, tvb, *offset, 1 + bus_name_size, ENC_NA); - alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_ns); + alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_string); - proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, tree_data->offset, 1, ENC_NA); - tree_data->offset += 1; + proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); + (*offset)++; - proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, tree_data->offset, bus_name_size, ENC_ASCII|ENC_NA); - tree_data->offset += bus_name_size; + proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII|ENC_NA); + (*offset) += bus_name_size; } } } -static void -ns_parse_answers(tvbuff_t *tvb, - alljoyn_name_server_tree_data *tree_data) -{ - switch(tree_data->message_version) { - case 0: - ns_parse_answers_v0(tvb, tree_data); - break; - case 1: - ns_parse_answers_v1(tvb, tree_data); - break; - default: - /* This case being unsupported is reported in the column info by - * the caller of this function. */ - break; - } -} - /* 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 name server traffic. @@ -2173,59 +1764,71 @@ dissect_AllJoyn_name_server(tvbuff_t *tvb, proto_tree *tree, void *data _U_) { - int return_value = 0; - gboolean isat = FALSE; - gboolean whohas = FALSE; - - alljoyn_name_server_tree_data tree_data = {0, 0, 0, 0, 0, 0}; + proto_item *alljoyn_item, *header_item; + proto_tree *alljoyn_tree, *header_tree; + guint8 questions, answers; + guint8 version; + int offset = 0; /* This is name service traffic. Mark it as such at the top level. */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN-NS"); col_clear(pinfo->cinfo, COL_INFO); - if (tree) { /* we are being asked for details */ - proto_item *alljoyn_item = NULL; + /* Add a subtree covering the remainder of the packet */ + alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ns, tvb, 0, -1, ENC_NA); + alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ns); - /* Add a subtree covering the remainder of the packet */ - alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ns, tvb, 0, -1, ENC_NA); - tree_data.alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ns); + /* Add the "header protocol" as a subtree from the AllJoyn Name Service Protocol. */ + header_item = proto_tree_add_item(alljoyn_tree, hf_alljoyn_ns_header, tvb, offset, 4, ENC_NA); + header_tree = proto_item_add_subtree(header_item, ett_alljoyn_ns_header); - ns_parse_header(tvb, &tree_data); - isat = tree_data.nAnswers > 0; - whohas = tree_data.nQuestions > 0; + /* The the sender and message versions as fields for the header protocol. */ + proto_tree_add_item(header_tree, hf_alljoyn_ns_sender_version, tvb, offset, 1, ENC_NA); + proto_tree_add_item(header_tree, hf_alljoyn_ns_message_version, tvb, offset, 1, ENC_NA); + version = tvb_get_guint8(tvb, offset) & 0xF; + offset += 1; - ns_parse_questions(tvb, &tree_data); - ns_parse_answers(tvb, &tree_data); - } else { - /* Get ISAT and WHOHAS info for COL_INFO. */ - ns_parse_header(tvb, &tree_data); - isat = tree_data.nAnswers > 0; - whohas = tree_data.nQuestions > 0; - } + col_add_fstr(pinfo->cinfo, COL_INFO, "VERSION %u", version); + if (version > 1) + col_append_str(pinfo->cinfo, COL_INFO, " (UNSUPPORTED)"); - switch(tree_data.message_version) { - case 0: - col_set_str(pinfo->cinfo, COL_INFO, "VERSION 0"); - break; - case 1: - col_set_str(pinfo->cinfo, COL_INFO, "VERSION 1"); - break; - default: - col_add_fstr(pinfo->cinfo, COL_INFO, "VERSION %u UNSUPPORTED", tree_data.message_version); - break; - } + proto_tree_add_item(header_tree, hf_alljoyn_ns_questions, tvb, offset, 1, ENC_NA); + questions = tvb_get_guint8(tvb, offset); + offset += 1; - if(isat) { + proto_tree_add_item(header_tree, hf_alljoyn_ns_answers, tvb, offset, 1, ENC_NA); + answers = tvb_get_guint8(tvb, offset); + offset += 1; + + if (answers > 0) col_append_str(pinfo->cinfo, COL_INFO, " ISAT"); - } - if(whohas) { + if (questions > 0) col_append_str(pinfo->cinfo, COL_INFO, " WHOHAS"); - } - return_value = tvb_reported_length(tvb); + proto_tree_add_item(header_tree, hf_alljoyn_ns_timer, tvb, offset, 1, ENC_NA); + offset += 1; - return return_value; + + if (tree) { /* we are being asked for details */ + ns_parse_questions(tvb, &offset, alljoyn_tree, questions, version); + + switch(version) { + case 0: + ns_parse_answers_v0(tvb, &offset, alljoyn_tree, answers); + break; + case 1: + ns_parse_answers_v1(tvb, &offset, alljoyn_tree, answers); + break; + default: + /* XXX - expert info */ + /* This case being unsupported is reported in the column info by + * the caller of this function. */ + break; + } + } + + return tvb_reported_length(tvb); } void @@ -2244,18 +1847,24 @@ proto_register_AllJoyn(void) /****************** * Wireshark header fields for the name service protocol. ******************/ + {&hf_alljoyn_ns_header, {"Header", "alljoyn.header", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}}, {&hf_alljoyn_ns_sender_version, {"Sender Version", "alljoyn.header.sendversion", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, {&hf_alljoyn_ns_message_version, {"Message Version", "alljoyn.header.messageversion", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}}, {&hf_alljoyn_ns_questions, {"Questions", "alljoyn.header.questions", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, {&hf_alljoyn_ns_answers, {"Answers", "alljoyn.header.answers", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, {&hf_alljoyn_ns_timer, {"Timer", "alljoyn.header.timer", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + {&hf_alljoyn_ns_whohas, {"Who-Has Message", "alljoyn.whohas", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}}, {&hf_alljoyn_ns_whohas_t_flag, {"TCP", "alljoyn.whohas.T", FT_BOOLEAN, 8, NULL, WHOHAS_T, NULL, HFILL}}, {&hf_alljoyn_ns_whohas_u_flag, {"UDP", "alljoyn.whohas.U", FT_BOOLEAN, 8, NULL, WHOHAS_U, NULL, HFILL}}, {&hf_alljoyn_ns_whohas_s_flag, {"IPv6", "alljoyn.whohas.S", FT_BOOLEAN, 8, NULL, WHOHAS_S, NULL, HFILL}}, {&hf_alljoyn_ns_whohas_f_flag, {"IPv4", "alljoyn.whohas.F", FT_BOOLEAN, 8, NULL, WHOHAS_F, NULL, HFILL}}, {&hf_alljoyn_ns_whohas_count, {"Count", "alljoyn.whohas.count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + {&hf_alljoyn_answer, {"Is-At Message", "alljoyn.isat", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + {&hf_alljoyn_isat_entry, {"Advertisement Entry", "alljoyn.isat_entry", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + {&hf_alljoyn_isat_guid_string, {"GUID String", "alljoyn.isat_guid_string", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + /* Common to V0 and V1 IS-AT messages. */ {&hf_alljoyn_ns_isat_g_flag, {"GUID", "alljoyn.isat.G", FT_BOOLEAN, 8, NULL, ISAT_G, NULL, HFILL}}, {&hf_alljoyn_ns_isat_c_flag, {"Complete", "alljoyn.isat.C", FT_BOOLEAN, 8, NULL, ISAT_C, NULL, HFILL}}, @@ -2289,7 +1898,7 @@ proto_register_AllJoyn(void) /****************** * Wireshark header fields for the message protocol. ******************/ - {&hf_alljoyn_connect_byte_value, {"Value", "alljoyn.InitialByte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + {&hf_alljoyn_connect_byte_value, {"Connect Initial Byte", "alljoyn.InitialByte", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, /* * Wireshark header fields for the SASL messages. @@ -2378,7 +1987,7 @@ proto_register_AllJoyn(void) }, {&hf_alljoyn_mess_body_header_typeid, {"Type ID", "alljoyn.message.typeid", - FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL} + FT_UINT8, BASE_CUSTOM, alljoyn_typeid, 0, NULL, HFILL} }, {&hf_alljoyn_mess_body_parameters, @@ -2453,6 +2062,8 @@ proto_register_AllJoyn(void) /* * Strings are composed of a size and a data arrray. */ + {&hf_alljoyn_string, + {"Bus Name", "alljoyn.string", FT_PROTOCOL, BASE_NONE, NULL, 0x0, NULL, HFILL}}, {&hf_alljoyn_string_size_8bit, {"String Size 8-bit", "alljoyn.string.size8bit", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, {&hf_alljoyn_string_size_32bit, @@ -2464,7 +2075,19 @@ proto_register_AllJoyn(void) static gint *ett[] = { &ett_alljoyn_ns, - &ett_alljoyn_mess + &ett_alljoyn_ns_header, + &ett_alljoyn_ns_answers, + &ett_alljoyn_ns_guid_string, + &ett_alljoyn_ns_isat_entry, + &ett_alljoyn_ns_string, + &ett_alljoyn_whohas, + &ett_alljoyn_string, + &ett_alljoyn_isat_entry, + &ett_alljoyn_mess, + &ett_alljoyn_header, + &ett_alljoyn_header_flags, + &ett_alljoyn_mess_header_field, + &ett_alljoyn_mess_header }; /* The following are protocols as opposed to data within a protocol. These appear @@ -2473,23 +2096,9 @@ proto_register_AllJoyn(void) /* Name service protocols. */ /* name, short name, abbrev */ proto_AllJoyn_ns = proto_register_protocol("AllJoyn Name Service Protocol", "AllJoyn NS", "ajns"); - proto_ns_header = proto_register_protocol("Header", "Header", "header"); - - proto_question = proto_register_protocol("Who-Has Message", "Who-Has", "whohas"); - proto_answer = proto_register_protocol("Is-At Message", "Is-At", "isat"); - - proto_isat_entry = proto_register_protocol("Advertisement Entry", "Advertisement Entry", "entry"); - proto_isat_guid_string = proto_register_protocol("GUID String", "GUID String", "guidstring"); - proto_bus_name_string = proto_register_protocol("Bus Name", "Bus Name", "busname"); /* Message protocols */ proto_AllJoyn_mess = proto_register_protocol("AllJoyn Message Protocol", "AllJoyn", "aj"); - proto_mess_connect_initial_byte = proto_register_protocol("AllJoyn Connect Initial Byte", "AllJoyn Connect", "ajconnect"); - - /* - * SASL. - */ - proto_mess_sasl = proto_register_protocol("SASL", "SASL", "ajsasl"); proto_register_field_array(proto_AllJoyn_ns, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); |