1 /* packet-allJoyn.c 2 * Routines for AllJoyn (AllJoyn.org) packet dissection 3 * Copyright (c) 2013-2014, The Linux Foundation. 4 * 5 * Wireshark - Network traffic analyzer 6 * By Gerald Combs <gerald@wireshark.org> 7 * Copyright 1998 Gerald Combs 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 10 */ 11 12 #include "config.h" 13 #include <epan/packet.h> 14 #include <epan/expert.h> 15 #include <wsutil/ws_roundup.h> 16 17 void proto_register_AllJoyn(void); 18 void proto_reg_handoff_AllJoyn(void); 19 20 #define ALLJOYN_NAME_SERVER_PORT 9956 /* IANA lists only UDP as being registered (dissector also uses TCP port) */ 21 #define ALLJOYN_MESSAGE_PORT 9955 22 23 /* DBus limits array length to 2^26. AllJoyn limits it to 2^17 */ 24 #define MAX_ARRAY_LEN 131072 25 /* DBus limits packet length to 2^27. AllJoyn limits it further to 2^17 + 4096 to allow for 2^17 payload */ 26 #define MAX_PACKET_LEN (MAX_ARRAY_LEN + 4096) 27 28 /* The following are protocols within a frame. 29 The actual value of the handle is set when the various fields are 30 registered in proto_register_AllJoyn() with a call to 31 proto_register_protocol(). 32 */ 33 static int proto_AllJoyn_mess = -1; /* The top level. Entire AllJoyn message protocol. */ 34 35 /* These are Wireshark header fields. You can search/filter on these values. */ 36 /* The initial byte sent when first connecting. */ 37 static int hf_alljoyn_connect_byte_value = -1; 38 39 /* SASL fields. */ 40 static int hf_alljoyn_sasl_command = -1; 41 static int hf_alljoyn_sasl_parameter = -1; 42 /* Message header fields. 43 See http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages 44 for details. */ 45 static int hf_alljoyn_mess_header = -1; /* The complete header. */ 46 static int hf_alljoyn_mess_header_endian = -1; /* 1st byte. */ 47 static int hf_alljoyn_mess_header_type = -1; /* 2nd byte. */ 48 static int hf_alljoyn_mess_header_flags = -1; /* 3rd byte. */ 49 static int hf_alljoyn_mess_header_majorversion = -1; /* 4th byte. */ 50 static int hf_alljoyn_mess_header_body_length = -1; /* 1st uint32. */ 51 static int hf_alljoyn_mess_header_serial = -1; /* 2nd uint32. */ 52 static int hf_alljoyn_mess_header_header_length = -1;/* 3rd uint32. AllJoyn extension. */ 53 54 static int hf_alljoyn_mess_header_flags_no_reply = -1; /* Part of 3rd byte. */ 55 static int hf_alljoyn_mess_header_flags_no_auto_start = -1; /* Part of 3rd byte. */ 56 static int hf_alljoyn_mess_header_flags_allow_remote_msg = -1; /* Part of 3rd byte. */ 57 static int hf_alljoyn_mess_header_flags_sessionless = -1; /* Part of 3rd byte. */ 58 static int hf_alljoyn_mess_header_flags_global_broadcast = -1; /* Part of 3rd byte. */ 59 static int hf_alljoyn_mess_header_flags_compressed = -1; /* Part of 3rd byte. */ 60 static int hf_alljoyn_mess_header_flags_encrypted = -1; /* Part of 3rd byte. */ 61 static int hf_alljoyn_mess_header_field = -1; 62 static int hf_alljoyn_mess_header_fields = -1; 63 static int hf_alljoyn_mess_body_header_fieldcode = -1; 64 static int hf_alljoyn_mess_body_header_typeid = -1; 65 static int hf_alljoyn_mess_body_array = -1; 66 static int hf_alljoyn_mess_body_structure = -1; 67 static int hf_alljoyn_mess_body_dictionary_entry = -1; 68 static int hf_alljoyn_mess_body_parameters = -1; 69 static int hf_alljoyn_mess_body_variant = -1; 70 static int hf_alljoyn_mess_body_signature = -1; 71 static int hf_alljoyn_mess_body_signature_length = -1; 72 73 static int hf_alljoyn_boolean = -1; 74 static int hf_alljoyn_uint8 = -1; 75 static int hf_alljoyn_int16 = -1; 76 static int hf_alljoyn_uint16 = -1; 77 static int hf_alljoyn_int32 = -1; 78 static int hf_alljoyn_handle = -1; 79 static int hf_alljoyn_uint32 = -1; 80 static int hf_alljoyn_int64 = -1; 81 static int hf_alljoyn_uint64 = -1; 82 static int hf_alljoyn_double = -1; 83 static int hf_padding = -1; /* Some fields are padded to an even number of 2, 4, or 8 bytes. */ 84 85 #define MESSAGE_HEADER_FLAG_NO_REPLY_EXPECTED 0x01 86 #define MESSAGE_HEADER_FLAG_NO_AUTO_START 0x02 87 #define MESSAGE_HEADER_FLAG_ALLOW_REMOTE_MSG 0x04 88 #define MESSAGE_HEADER_FLAG_SESSIONLESS 0x10 89 #define MESSAGE_HEADER_FLAG_GLOBAL_BROADCAST 0x20 90 #define MESSAGE_HEADER_FLAG_COMPRESSED 0x40 91 #define MESSAGE_HEADER_FLAG_ENCRYPTED 0x80 92 93 /* Protocol identifiers. */ 94 static int proto_AllJoyn_ns = -1; /* The top level. Entire AllJoyn Name Service protocol. */ 95 96 static int hf_alljoyn_answer = -1; 97 static int hf_alljoyn_isat_entry = -1; 98 static int hf_alljoyn_isat_guid_string = -1; 99 100 static int hf_alljoyn_ns_header = -1; 101 static int hf_alljoyn_ns_sender_version = -1; 102 static int hf_alljoyn_ns_message_version = -1; 103 static int hf_alljoyn_ns_questions = -1; 104 static int hf_alljoyn_ns_answers = -1; 105 static int hf_alljoyn_ns_timer = -1; 106 107 /* These are bit masks for version 0 "who has" records. */ 108 /* These bits are deprecated and do not exist for version 1. */ 109 #define WHOHAS_T 0x08 110 #define WHOHAS_U 0x04 111 #define WHOHAS_S 0x02 112 #define WHOHAS_F 0x01 113 114 static int hf_alljoyn_ns_whohas = -1; 115 static int hf_alljoyn_ns_whohas_t_flag = -1; /* 0x8 -- TCP */ 116 static int hf_alljoyn_ns_whohas_u_flag = -1; /* 0x4 -- UDP */ 117 static int hf_alljoyn_ns_whohas_s_flag = -1; /* 0x2 -- IPV6 */ 118 static int hf_alljoyn_ns_whohas_f_flag = -1; /* 0x1 -- IPV4 */ 119 /* End of version 0 bit masks. */ 120 121 static int hf_alljoyn_ns_whohas_count = -1; /* octet count of bus names */ 122 123 /* Bitmasks common to v0 and v1 IS-AT messages. */ 124 #define ISAT_C 0x10 125 #define ISAT_G 0x20 126 127 /* Bitmasks for v0 IS-AT messages. */ 128 #define ISAT_F 0x01 129 #define ISAT_S 0x02 130 #define ISAT_U 0x04 131 #define ISAT_T 0x08 132 133 /* Bitmasks for v1 IS-AT messages. */ 134 #define ISAT_U6 0x01 135 #define ISAT_R6 0x02 136 #define ISAT_U4 0x04 137 #define ISAT_R4 0x08 138 139 /* Bitmasks for v1 transports. */ 140 #define TRANSPORT_LOCAL 0x0001 /* Local (same device) transport. */ 141 #define TRANSPORT_BLUETOOTH 0x0002 /* Bluetooth transport. */ 142 #define TRANSPORT_TCP 0x0004 /* Transport using TCP (same as TRANSPORT_WLAN). */ 143 #define TRANSPORT_WWAN 0x0008 /* Wireless wide-area network transport. */ 144 #define TRANSPORT_LAN 0x0010 /* Wired local-area network transport. */ 145 #define TRANSPORT_ICE 0x0020 /* Transport using ICE protocol. */ 146 #define TRANSPORT_WFD 0x0080 /* Transport using Wi-Fi Direct transport. */ 147 148 /* Tree indexes common to v0 and v1 IS-AT messages. */ 149 static int hf_alljoyn_ns_isat_g_flag = -1; /* 0x20 -- GUID present */ 150 static int hf_alljoyn_ns_isat_c_flag = -1; /* 0x10 -- Complete */ 151 152 /* Tree indexes for v0 IS-AT messages. */ 153 static int hf_alljoyn_ns_isat_t_flag = -1; /* 0x8 -- TCP */ 154 static int hf_alljoyn_ns_isat_u_flag = -1; /* 0x4 -- UDP */ 155 static int hf_alljoyn_ns_isat_s_flag = -1; /* 0x2 -- IPV6 */ 156 static int hf_alljoyn_ns_isat_f_flag = -1; /* 0x1 -- IPV4 */ 157 static int hf_alljoyn_ns_isat_count = -1; /* octet count of bus names */ 158 static int hf_alljoyn_ns_isat_port = -1; /* two octets of port number */ 159 static int hf_alljoyn_ns_isat_ipv4 = -1; /* four octets of IPv4 address */ 160 static int hf_alljoyn_ns_isat_ipv6 = -1; /* sixteen octets of IPv6 address */ 161 162 /* Tree indexes for v1 IS-AT messages. */ 163 static int hf_alljoyn_ns_isat_u6_flag = -1; /* 0x8 -- UDP IPV6 */ 164 static int hf_alljoyn_ns_isat_r6_flag = -1; /* 0x4 -- TCP IPV6 */ 165 static int hf_alljoyn_ns_isat_u4_flag = -1; /* 0x2 -- UDP IPV4 */ 166 static int hf_alljoyn_ns_isat_r4_flag = -1; /* 0x1 -- TCP IPV4 */ 167 168 static int hf_alljoyn_ns_isat_transport_mask = -1; /* All bits of the transport mask. */ 169 170 /* Individual bits of the mask. */ 171 static int hf_alljoyn_ns_isat_transport_mask_local = -1; /* Local (same device) transport */ 172 static int hf_alljoyn_ns_isat_transport_mask_bluetooth = -1;/* Bluetooth transport */ 173 static int hf_alljoyn_ns_isat_transport_mask_tcp = -1; /* Transport using TCP (same as TRANSPORT_WLAN) */ 174 static int hf_alljoyn_ns_isat_transport_mask_wwan = -1; /* Wireless wide-area network transport */ 175 static int hf_alljoyn_ns_isat_transport_mask_lan = -1; /* Wired local-area network transport */ 176 static int hf_alljoyn_ns_isat_transport_mask_ice = -1; /* Transport using ICE protocol */ 177 static int hf_alljoyn_ns_isat_transport_mask_wfd = -1; /* Transport using Wi-Fi Direct transport */ 178 179 static int hf_alljoyn_string = -1; 180 static int hf_alljoyn_string_size_8bit = -1; /* 8-bit size of string */ 181 static int hf_alljoyn_string_size_32bit = -1; /* 32-bit size of string */ 182 static int hf_alljoyn_string_data = -1; /* string characters */ 183 184 /* Protocol identifiers. */ 185 static int proto_AllJoyn_ardp = -1; /* The top level. Entire AllJoyn Reliable Datagram Protocol. */ 186 187 #define ARDP_SYN_FIXED_HDR_LEN 28 /* Size of the fixed part for the ARDP connection packet header. */ 188 #define ARDP_FIXED_HDR_LEN 34 /* Size of the fixed part for the ARDP header. */ 189 #define ARDP_DATA_LENGTH_OFFSET 6 /* Offset into the ARDP header for the data length. */ 190 #define ARDP_HEADER_LEN_OFFSET 1 /* Offset into the ARDP header for the actual length of the header. */ 191 192 /* These are bit masks for ARDP flags. */ 193 /* These bits are deprecated and do not exist for version 1. */ 194 #define ARDP_SYN 0x01 195 #define ARDP_ACK 0x02 196 #define ARDP_EAK 0x04 197 #define ARDP_RST 0x08 198 #define ARDP_NUL 0x10 199 #define ARDP_UNUSED 0x20 200 #define ARDP_VER0 0x40 201 #define ARDP_VER1 0x80 202 #define ARDP_VER (ARDP_VER0 | ARDP_VER1) 203 204 static int hf_ardp_syn_flag = -1; /* 0x01 -- SYN */ 205 static int hf_ardp_ack_flag = -1; /* 0x02 -- ACK */ 206 static int hf_ardp_eak_flag = -1; /* 0x04 -- EAK */ 207 static int hf_ardp_rst_flag = -1; /* 0x08 -- RST */ 208 static int hf_ardp_nul_flag = -1; /* 0x10 -- NUL */ 209 static int hf_ardp_unused_flag = -1; /* 0x20 -- UNUSED */ 210 static int hf_ardp_version_field = -1; /* 0xc0 */ 211 212 static int hf_ardp_hlen = -1; /* header length */ 213 static int hf_ardp_src = -1; /* source port */ 214 static int hf_ardp_dst = -1; /* destination port */ 215 static int hf_ardp_dlen = -1; /* data length */ 216 static int hf_ardp_seq = -1; /* sequence number */ 217 static int hf_ardp_ack = -1; /* acknowledge number */ 218 static int hf_ardp_ttl = -1; /* time to live (ms) */ 219 static int hf_ardp_lcs = -1; /* last consumed sequence number */ 220 static int hf_ardp_nsa = -1; /* next sequence to ack */ 221 static int hf_ardp_fss = -1; /* fragment starting sequence number */ 222 static int hf_ardp_fcnt = -1; /* fragment count */ 223 static int hf_ardp_bmp = -1; /* EACK bitmap */ 224 static int hf_ardp_segmax = -1; /* The maximum number of outstanding segments the other side can send without acknowledgment. */ 225 static int hf_ardp_segbmax = -1;/* The maximum segment size we are willing to receive. */ 226 static int hf_ardp_dackt = -1; /* Receiver's delayed ACK timeout. Used in TTL estimate prior to sending a message. */ 227 static int hf_ardp_options = -1;/* Options for the connection. Always Sequenced Delivery Mode (SDM). */ 228 229 static expert_field ei_alljoyn_empty_arg = EI_INIT; 230 231 /* These are the ids of the subtrees we will be creating */ 232 static gint ett_alljoyn_ns = -1; /* This is the top NS tree. */ 233 static gint ett_alljoyn_ns_header = -1; 234 static gint ett_alljoyn_ns_answers = -1; 235 static gint ett_alljoyn_ns_guid_string = -1; 236 static gint ett_alljoyn_ns_isat_entry = -1; 237 static gint ett_alljoyn_ns_string = -1; 238 static gint ett_alljoyn_whohas = -1; 239 static gint ett_alljoyn_string = -1; 240 static gint ett_alljoyn_isat_entry = -1; 241 static gint ett_alljoyn_mess = -1; /* This is the top message tree. */ 242 static gint ett_alljoyn_header = -1; 243 static gint ett_alljoyn_header_flags = -1; 244 static gint ett_alljoyn_mess_header_field = -1; 245 static gint ett_alljoyn_mess_header = -1; 246 static gint ett_alljoyn_mess_body_parameters = -1; 247 static gint ett_alljoyn_ardp = -1; /* This is the top ARDP tree. */ 248 249 #define ROUND_TO_2BYTE(len) WS_ROUNDUP_2(len) 250 #define ROUND_TO_4BYTE(len) WS_ROUNDUP_4(len) 251 #define ROUND_TO_8BYTE(len) WS_ROUNDUP_8(len) 252 253 static const value_string endian_encoding_vals[] = { 254 { 'B', "Big endian" }, 255 { 'l', "Little endian" }, 256 { 0, NULL }, 257 }; 258 259 #define MESSAGE_TYPE_INVALID 0 260 #define MESSAGE_TYPE_METHOD_CALL 1 261 #define MESSAGE_TYPE_METHOD_REPLY 2 262 #define MESSAGE_TYPE_ERROR_REPLY 3 263 #define MESSAGE_TYPE_SIGNAL 4 264 265 static const value_string message_header_encoding_vals[] = { 266 { MESSAGE_TYPE_INVALID, "Invalid type" }, 267 { MESSAGE_TYPE_METHOD_CALL, "Method call" }, 268 { MESSAGE_TYPE_METHOD_REPLY, "Method reply with returned data" }, 269 { MESSAGE_TYPE_ERROR_REPLY, "Error reply" }, 270 { MESSAGE_TYPE_SIGNAL, "Signal emission" }, 271 { 0, NULL } 272 }; 273 274 /* 275 * The array at the end of the header contains header fields, 276 * where each field is a 1-byte field code followed by a field value. 277 * See also: http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages 278 * 279 * In the D-Bus world these are the "field codes". 280 * In the AllJoyn world these are called "field types". 281 */ 282 #define HDR_INVALID 0x00 283 #define HDR_OBJ_PATH 0x01 284 #define HDR_INTERFACE 0x02 285 #define HDR_MEMBER 0x03 286 #define HDR_ERROR_NAME 0x04 287 #define HDR_REPLY_SERIAL 0x05 288 #define HDR_DESTINATION 0x06 289 #define HDR_SENDER 0x07 290 #define HDR_SIGNATURE 0x08 291 #define HDR_HANDLES 0x09 292 #define HDR_TIMESTAMP 0x10 /* AllJoyn specific headers start at 0x10 */ 293 #define HDR_TIME_TO_LIVE 0x11 294 #define HDR_COMPRESSION_TOKEN 0x12 295 #define HDR_SESSION_ID 0x13 296 297 static const value_string mess_header_field_encoding_vals[] = { 298 { HDR_INVALID, "Invalid" }, /* Not a valid field name (error if it appears in a message). */ 299 { HDR_OBJ_PATH, "Object Path" }, /* The object to send a call to, or the object a signal 300 is emitted from. */ 301 { HDR_INTERFACE, "Interface" }, /* The interface to invoke a method call on, or that a 302 signal is emitted from. Optional for method calls, 303 required for signals. */ 304 { HDR_MEMBER, "Member" }, /* The member, either the method name or signal name. */ 305 { HDR_ERROR_NAME, "Error Name" }, /* The name of the error that occurred, for errors. */ 306 { HDR_REPLY_SERIAL, "Reply Serial" }, /* The serial number of the message this message is a reply to. */ 307 { HDR_DESTINATION, "Destination" }, /* The name of the connection this message is intended for. */ 308 { HDR_SENDER, "Sender" }, /* Unique name of the sending connection. */ 309 { HDR_SIGNATURE, "Signature" }, /* The signature of the message body. */ 310 { HDR_HANDLES, "Handles" }, /* The number of handles (Unix file descriptors) that 311 accompany the message. */ 312 { HDR_TIMESTAMP, "Time stamp" }, 313 { HDR_TIME_TO_LIVE, "Time to live" }, 314 { HDR_COMPRESSION_TOKEN, "Compression token" }, 315 { HDR_SESSION_ID, "Session ID" }, 316 { 0, NULL } 317 }; 318 319 /* This is used to round up offsets into a packet to an even two byte 320 * boundary from starting_offset. 321 * @param current_offset is the current offset into the packet. 322 * @param starting_offset is offset into the packet from the beginning of 323 * the message. 324 * @returns the offset rounded up to the next even two byte boundary from 325 start of the message. 326 */ 327 static gint round_to_2byte(gint current_offset, 328 gint starting_offset) 329 { 330 gint length = current_offset - starting_offset; 331 332 return starting_offset + ROUND_TO_2BYTE(length); 333 } 334 335 /* This is used to round up offsets into a packet to an even four byte 336 * boundary from starting_offset. 337 * @param current_offset is the current offset into the packet. 338 * @param starting_offset is offset into the packet from the beginning of 339 * the message. 340 * @returns the offset rounded up to the next even four byte boundary from 341 start of the message. 342 */ 343 static gint round_to_4byte(gint current_offset, 344 gint starting_offset) 345 { 346 gint length = current_offset - starting_offset; 347 348 return starting_offset + ROUND_TO_4BYTE(length); 349 } 350 351 /* This is used to round up offsets into a packet to an even eight byte 352 * boundary from starting_offset. 353 * @param current_offset is the current offset into the packet. 354 * @param starting_offset is offset into the packet from the beginning of 355 * the message. 356 * @returns the offset rounded up to the next even eight byte boundary from 357 start of the message. 358 */ 359 static gint round_to_8byte(gint current_offset, 360 gint starting_offset) 361 { 362 gint length = current_offset - starting_offset; 363 364 return starting_offset + ROUND_TO_8BYTE(length); 365 } 366 367 /* This is the maximum number of rounding bytes that is ever used. 368 * This define is used for error checking. */ 369 #define MAX_ROUND_TO_BYTES 7 370 371 /* Gets a 32-bit unsigned integer from the packet buffer with 372 * the proper byte-swap. 373 * @param tvb is the incoming network data buffer. 374 * @param offset is the offset into the buffer. 375 * @param encoding is ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN. 376 * @return The 32-bit unsigned int interpretation of the bits 377 * in the buffer. 378 */ 379 static guint32 380 get_uint32(tvbuff_t *tvb, 381 gint32 offset, 382 gint encoding) 383 { 384 return (ENC_BIG_ENDIAN == encoding) ? 385 tvb_get_ntohl(tvb, offset) : 386 tvb_get_letohl(tvb, offset); 387 } 388 389 /* This is called by dissect_AllJoyn_message() to handle the initial byte for 390 * a connect message. 391 * If it was the initial byte for a connect message and was handled then return 392 * the number of bytes consumed out of the packet. If not an connect initial 393 * byte message or unhandled return 0. 394 * @param tvb is the incoming network data buffer. 395 * @param pinfo contains information about the incoming packet which 396 * we update as we dissect the packet. 397 * @param offset is the offset into the packet to check for the connect message. 398 * @param message_tree is the subtree that any connect data items should be added to. 399 * @returns the offset into the packet that has successfully been handled or 400 * the input offset value if it was not the connect initial byte of 0. 401 */ 402 static gint 403 handle_message_connect(tvbuff_t *tvb, 404 packet_info *pinfo, 405 gint offset, 406 proto_tree *message_tree) 407 { 408 guint8 the_one_byte; 409 410 the_one_byte = tvb_get_guint8(tvb, offset); 411 412 if(0 == the_one_byte) { 413 col_set_str(pinfo->cinfo, COL_INFO, "CONNECT-initial byte"); 414 415 /* Now add the value as a subtree to the initial byte. */ 416 proto_tree_add_item(message_tree, hf_alljoyn_connect_byte_value, tvb, offset, 1, ENC_NA); 417 offset += 1; 418 } 419 420 return offset; 421 } 422 423 typedef struct _sasl_cmd 424 { 425 const gchar *text; 426 guint length; 427 } sasl_cmd; 428 429 static const gchar CMD_AUTH[] = "AUTH"; 430 static const gchar CMD_CANCEL[] = "CANCEL"; 431 static const gchar CMD_BEGIN[] = "BEGIN"; 432 static const gchar CMD_DATA[] = "DATA"; 433 static const gchar CMD_ERROR[] = "ERROR"; 434 static const gchar CMD_REJECTED[] = "REJECTED"; 435 static const gchar CMD_OK[] = "OK"; 436 437 #define MAX_SASL_COMMAND_LENGTH sizeof(CMD_REJECTED) 438 /* The 256 is just something I pulled out of the air. */ 439 #define MAX_SASL_PACKET_LENGTH (MAX_SASL_COMMAND_LENGTH + 256) 440 441 static const sasl_cmd sasl_commands[] = { 442 {CMD_AUTH, G_N_ELEMENTS(CMD_AUTH) - 1}, 443 {CMD_CANCEL, G_N_ELEMENTS(CMD_CANCEL) - 1}, 444 {CMD_BEGIN, G_N_ELEMENTS(CMD_BEGIN) - 1}, 445 {CMD_DATA, G_N_ELEMENTS(CMD_DATA) - 1}, 446 {CMD_ERROR, G_N_ELEMENTS(CMD_ERROR) - 1}, 447 {CMD_REJECTED, G_N_ELEMENTS(CMD_REJECTED) - 1}, 448 {CMD_OK, G_N_ELEMENTS(CMD_OK) - 1}, 449 }; 450 451 static const gint sasl_commands_count = G_N_ELEMENTS(sasl_commands); 452 453 static const sasl_cmd * 454 find_sasl_command(tvbuff_t *tvb, 455 gint offset) 456 { 457 gint command_index; 458 459 for(command_index = 0; command_index < sasl_commands_count; command_index++) { 460 const sasl_cmd *cmd; 461 462 cmd = &sasl_commands[command_index]; 463 464 if(0 == tvb_strneql(tvb, offset, cmd->text, cmd->length)) { 465 return cmd; 466 } 467 } 468 469 return NULL; 470 } 471 472 /* Call this to test whether desegmentation is possible and if so correctly 473 * set the pinfo structure with the applicable data. 474 * @param pinfo contains information about the incoming packet. 475 * @param next_offset is the offset into the tvbuff where it is desired to start processing next time. 476 * @param addition_bytes_needed is the additional bytes required beyond what is already available. 477 * @returns TRUE if desegmentation is possible. FALSE if not. 478 */ 479 static gboolean set_pinfo_desegment(packet_info *pinfo, gint next_offset, gint addition_bytes_needed) 480 { 481 if(pinfo->can_desegment) { 482 pinfo->desegment_offset = next_offset; 483 pinfo->desegment_len = addition_bytes_needed; 484 485 return TRUE; 486 } 487 488 return FALSE; 489 } 490 491 /* This is called by dissect_AllJoyn_message() to handle SASL messages. 492 * If it was a SASL message and was handled then return the number of bytes 493 * used (should be the entire packet). If not a SASL message or unhandled return 0. 494 * If more bytes are needed then return the negative of the bytes expected. 495 * @param tvb is the incoming network data buffer. 496 * @param pinfo contains information about the incoming packet which 497 * we update as we dissect the packet. 498 * @param offset is the offset into the packet to start processing. 499 * @param message_tree is the subtree that any connect data items should be added to. 500 * @returns the offset into the packet that has successfully been handled or 501 * the input offset value if it was not a sasl message. 502 */ 503 static gint 504 handle_message_sasl(tvbuff_t *tvb, 505 packet_info *pinfo, 506 gint offset, 507 proto_tree *message_tree) 508 { 509 gint return_value = offset; 510 const sasl_cmd *command; 511 512 command = find_sasl_command(tvb, offset); 513 514 if(command) { 515 /* This gives us the offset into the buffer of the terminating character of 516 * the command, the '\n'. + 1 to get the number of bytes used for the 517 * command in the buffer. tvb_find_guint8() returns -1 if not found so the + 1 518 * will result in a newline_offset of 0 if not found. 519 */ 520 gint newline_offset = tvb_find_guint8(tvb, offset + command->length, -1, '\n') + 1; 521 522 /* If not found see if we should request another segment. */ 523 if(0 == newline_offset) { 524 if((guint)tvb_captured_length_remaining(tvb, offset) < MAX_SASL_PACKET_LENGTH && 525 set_pinfo_desegment(pinfo, offset, DESEGMENT_ONE_MORE_SEGMENT)) { 526 527 /* Return the length of the buffer we successfully parsed. */ 528 return_value = offset + command->length; 529 } else { 530 /* If we can't desegment then return 0 meaning we didn't do anything. */ 531 return_value = 0; 532 } 533 534 return return_value; 535 } 536 537 if(newline_offset > 0) { 538 gint length = command->length; 539 540 col_add_fstr(pinfo->cinfo, COL_INFO, "SASL-%s", command->text); 541 542 /* Add a subtree/row for the command. */ 543 proto_tree_add_item(message_tree, hf_alljoyn_sasl_command, tvb, offset, length, ENC_ASCII|ENC_NA); 544 offset += length; 545 length = newline_offset - offset; 546 547 /* Add a subtree for the parameter. */ 548 proto_tree_add_item(message_tree, hf_alljoyn_sasl_parameter, tvb, offset, length, ENC_ASCII|ENC_NA); 549 550 return_value = newline_offset; 551 } 552 } 553 554 return return_value; 555 } 556 557 #define ENC_ALLJOYN_BAD_ENCODING 0xBADF00D 558 559 #define ENDIANNESS_OFFSET 0 /* The offset for endianness is always 0. */ 560 561 /* This is called by handle_message_header_body() to get the endianness from 562 * message headers. 563 * @param tvb is the incoming network data buffer. 564 * @param offset is the current offset into network data buffer. 565 * @return The type of encoding, ENC_LITTLE_ENDIAN or ENC_BIG_ENDIAN, for 566 * the message. 567 */ 568 static guint32 569 get_message_header_endianness(tvbuff_t *tvb, 570 gint offset) 571 { 572 guint8 endianness; 573 guint encoding; 574 575 /* The endianness field. */ 576 endianness = tvb_get_guint8(tvb, offset + ENDIANNESS_OFFSET); 577 578 switch(endianness) 579 { 580 case 'l': 581 encoding = ENC_LITTLE_ENDIAN; 582 break; 583 case 'B': 584 encoding = ENC_BIG_ENDIAN; 585 break; 586 default: 587 encoding = ENC_ALLJOYN_BAD_ENCODING; 588 break; 589 } 590 591 return encoding; 592 } 593 594 /* This is called by handle_message_field() to handle bytes of particular values 595 * in messages. 596 * @param tvb is the incoming network data buffer. 597 * @param offset is the offset into the packet to start processing. 598 * @param field_tree is the subtree that we connect data items to. 599 * @param expected_value is the value the byte is expected to have. 600 */ 601 static void 602 handle_message_header_expected_byte(tvbuff_t *tvb, 603 gint offset, 604 proto_tree *field_tree, 605 guint8 expected_value) 606 { 607 proto_item *item; 608 guint8 byte_value; 609 610 item = proto_tree_add_item(field_tree, hf_alljoyn_uint8, tvb, offset, 1, ENC_NA); 611 byte_value = tvb_get_guint8(tvb, offset); 612 613 if(expected_value == byte_value) { 614 proto_item_set_text(item, "0x%02x byte", expected_value); 615 } else { 616 proto_item_set_text(item, "Expected '0x%02x byte' but found '0x%02x'", expected_value, byte_value); 617 } 618 } 619 620 /* 621 * Message argument types 622 */ 623 #define ARG_INVALID '\0' 624 #define ARG_ARRAY 'a' /* AllJoyn array container type */ 625 #define ARG_BOOLEAN 'b' /* AllJoyn boolean basic type */ 626 #define ARG_DOUBLE 'd' /* AllJoyn IEEE 754 double basic type */ 627 #define ARG_SIGNATURE 'g' /* AllJoyn signature basic type */ 628 #define ARG_HANDLE 'h' /* AllJoyn socket handle basic type */ 629 #define ARG_INT32 'i' /* AllJoyn 32-bit signed integer basic type */ 630 #define ARG_INT16 'n' /* AllJoyn 16-bit signed integer basic type */ 631 #define ARG_OBJ_PATH 'o' /* AllJoyn Name of an AllJoyn object instance basic type */ 632 #define ARG_UINT16 'q' /* AllJoyn 16-bit unsigned integer basic type */ 633 #define ARG_STRING 's' /* AllJoyn UTF-8 NULL terminated string basic type */ 634 #define ARG_UINT64 't' /* AllJoyn 64-bit unsigned integer basic type */ 635 #define ARG_UINT32 'u' /* AllJoyn 32-bit unsigned integer basic type */ 636 #define ARG_VARIANT 'v' /* AllJoyn variant container type */ 637 #define ARG_INT64 'x' /* AllJoyn 64-bit signed integer basic type */ 638 #define ARG_BYTE 'y' /* AllJoyn 8-bit unsigned integer basic type */ 639 #define ARG_STRUCT '(' /* AllJoyn struct container type */ 640 #define ARG_DICT_ENTRY '{' /* AllJoyn dictionary or map container type - an array of key-value pairs */ 641 642 static gint 643 pad_according_to_type(gint offset, gint field_starting_offset, gint max_offset, guint8 type) 644 { 645 switch(type) 646 { 647 case ARG_BYTE: 648 break; 649 650 case ARG_DOUBLE: 651 case ARG_UINT64: 652 case ARG_INT64: 653 case ARG_STRUCT: 654 case ARG_DICT_ENTRY: 655 offset = round_to_8byte(offset, field_starting_offset); 656 break; 657 658 case ARG_SIGNATURE: 659 break; 660 661 case ARG_HANDLE: 662 break; 663 664 case ARG_INT32: 665 case ARG_UINT32: 666 case ARG_BOOLEAN: 667 offset = round_to_4byte(offset, field_starting_offset); 668 break; 669 670 case ARG_INT16: 671 case ARG_UINT16: 672 offset = round_to_2byte(offset, field_starting_offset); 673 break; 674 675 case ARG_STRING: 676 break; 677 678 case ARG_VARIANT: 679 break; 680 681 case ARG_OBJ_PATH: 682 break; 683 684 default: 685 break; 686 } 687 688 if(offset > max_offset) { 689 offset = max_offset; 690 } 691 692 return offset; 693 } 694 695 /* This is called by parse_arg to append the signature of structure or dictionary 696 * to an item. This is complicated a bit by the fact that structures can be nested. 697 * @param item is the item to append the signature data to. 698 * @param signature points to the signature to be appended. 699 * @param signature_max_length is the specified maximum length of this signature. 700 * @param type_stop is the character when indicates the end of the signature. 701 */ 702 static void 703 append_struct_signature(proto_item *item, 704 const guint8 *signature, 705 gint signature_max_length, 706 const guint8 type_stop) 707 { 708 int depth = 0; 709 guint8 type_start; 710 gint signature_length = 0; 711 712 proto_item_append_text(item, "%c", ' '); 713 type_start = *signature; 714 715 do { 716 if(type_start == *signature) { 717 depth++; 718 } 719 720 if(type_stop == *signature) { 721 depth--; 722 } 723 724 proto_item_append_text(item, "%c", *signature++); 725 } while(depth > 0 && ++signature_length < signature_max_length); 726 727 if(signature_length >= signature_max_length) { 728 proto_item_append_text(item, "... Invalid signature!"); 729 } 730 } 731 732 /* This is called to advance the signature pointer to the end of the signature 733 * it is currently pointing at. signature_length is decreased by the appropriate 734 * amount before returning. 735 * @param signature is a pointer to the signature. It could be simple data type 736 * such as 'i', 'b', etc. In these cases *signature is advanced by 1 and 737 * *signature_length is decreased by 1. Or it could be an array, structure, dictionary, 738 * array of arrays or even more complex things. In these cases the advancement could 739 * be much larger. For example with the signature "a(bdas)i" *signature will be advanced 740 * to the 'i' and *signature_length will be set to '1'. 741 * @param signature_length is a pointer to the length of the signature. 742 */ 743 static void 744 advance_to_end_of_signature(const guint8 **signature, 745 guint8 *signature_length) 746 { 747 gboolean done = FALSE; 748 gint8 current_type; 749 gint8 end_type = ARG_INVALID; 750 751 while (*signature_length > 0 && **signature && !done) { 752 current_type = *(++(*signature)); 753 --*signature_length; 754 755 /* Were we looking for the end of a structure or dictionary? If so, did we find it? */ 756 if(end_type != ARG_INVALID) { 757 if(end_type == current_type) { 758 done = TRUE; /* Found the end of the structure or dictionary. All done. */ 759 } 760 761 continue; 762 } 763 764 switch(current_type) 765 { 766 case ARG_ARRAY: 767 advance_to_end_of_signature(signature, signature_length); 768 break; 769 case ARG_STRUCT: 770 end_type = ')'; 771 advance_to_end_of_signature(signature, signature_length); 772 break; 773 case ARG_DICT_ENTRY: 774 end_type = '}'; 775 advance_to_end_of_signature(signature, signature_length); 776 break; 777 778 case ARG_BYTE: 779 case ARG_DOUBLE: 780 case ARG_UINT64: 781 case ARG_INT64: 782 case ARG_SIGNATURE: 783 case ARG_HANDLE: 784 case ARG_INT32: 785 case ARG_UINT32: 786 case ARG_BOOLEAN: 787 case ARG_INT16: 788 case ARG_UINT16: 789 case ARG_STRING: 790 case ARG_VARIANT: 791 case ARG_OBJ_PATH: 792 done = TRUE; 793 break; 794 795 default: /* Unrecognized signature. Bail out. */ 796 done = TRUE; 797 break; 798 } 799 } 800 } 801 802 /* This is called to add a padding item. There is not padding done for each call made. 803 * There is testing for the padding length which must be greater than zero. It's also possible, 804 * in the case of bad packets, that the end of the padding is wrong so range checking is 805 * also done. In the case of something being obviously wrong this function returns 806 * without adding the padding item. 807 * @param padding_start is the offset into tvb at which the (possible) padding starts. 808 * @param padding_end is the offset into tvb at which the (possible) padding ends. 809 * @param tvb is the incoming network data buffer. 810 * @param tree is the tree to which the new item should be attached. 811 */ 812 static void add_padding_item(gint padding_start, gint padding_end, tvbuff_t *tvb, proto_tree *tree) 813 { 814 if(padding_end > padding_start && padding_end < (gint)tvb_reported_length(tvb)) { 815 gint padding_length = padding_end - padding_start; 816 817 if (padding_length <= MAX_ROUND_TO_BYTES) { 818 proto_tree_add_item(tree, hf_padding, tvb, padding_start, padding_length, ENC_NA); 819 } 820 } 821 } 822 823 /* This is called to handle a single typed argument. Recursion is used 824 * to handle arrays and structures. 825 * @param tvb is the incoming network data buffer. 826 * @param pinfo contains information about the incoming packet which 827 * we update as we dissect the packet. 828 * @param header_item, if not NULL, is appended with the text name of the data type. 829 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) 830 * @param offset is the offset into tvb to get the field from. 831 * @param field_tree is the tree to which this argument should be attached. 832 * @param is_reply_to, if TRUE, means this uint32 value should be used to update 833 * header_item and pinfo->cinfo with a special message. 834 * @param type_id is the type of this argument. 835 * @param field_code is the type of header, or HDR_INVALID if not used, which this 836 * arg is a part of. If field_code is HDR_MEMBER or HDR_SIGNATURE then 837 * pinfo->cinfo is updated with information. 838 * @param signature is a pointer to the signature of the parameters. If type_id is 839 * ARG_SIGNATURE this is a return value for the caller to pass to the function 840 * that parses the parameters. If type_id is something like ARG_STRUCT then it points 841 * to the actual signature of the type. 842 * @param signature_length is a pointer to the length of the signature and if type_id is 843 * ARG_SIGNATURE this is a return value for the caller to pass to the function 844 * that parses the parameters. 845 * @param field_starting_offset is the offset at the beginning of the field that contains 846 * this arg. When rounding this starting_offset is used rather than the absolute offset. 847 * @return The new offset into the buffer after removing the field code and value. 848 * the message or the packet length to stop further processing if "really bad" 849 * parameters come in. 850 */ 851 static gint 852 parse_arg(tvbuff_t *tvb, 853 packet_info *pinfo, 854 proto_item *header_item, 855 guint encoding, 856 gint offset, 857 proto_tree *field_tree, 858 gboolean is_reply_to, 859 guint8 type_id, 860 guint8 field_code, 861 const guint8 **signature, 862 guint8 *signature_length, 863 gint field_starting_offset) 864 { 865 gint length; 866 gint padding_start; 867 gint saved_offset = offset; 868 const gchar *header_type_name = NULL; 869 870 switch(type_id) 871 { 872 case ARG_INVALID: 873 header_type_name = "invalid"; 874 offset = round_to_8byte(offset + 1, field_starting_offset); 875 break; 876 877 case ARG_ARRAY: /* AllJoyn array container type */ 878 { 879 static gchar bad_array_format[] = "BAD DATA: Array length (in bytes) is %d. Remaining packet length is %d."; 880 proto_item *item; 881 proto_tree *tree; 882 const guint8 *sig_saved; 883 gint starting_offset; 884 gint number_of_items = 0; 885 gint packet_length = (gint)tvb_reported_length(tvb); 886 887 header_type_name = "array"; 888 889 if(*signature == NULL || *signature_length < 1) { 890 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: A %s argument needs a signature.", header_type_name); 891 return tvb_reported_length(tvb); 892 } 893 894 /* *sig_saved will now be the element type after the 'a'. */ 895 sig_saved = (*signature) + 1; 896 897 padding_start = offset; 898 offset = round_to_4byte(offset, field_starting_offset); 899 add_padding_item(padding_start, offset, tvb, field_tree); 900 901 /* This is the length of the entire array in bytes but does not include the length field. */ 902 length = (gint)get_uint32(tvb, offset, encoding); 903 904 padding_start = offset + 4; 905 starting_offset = pad_according_to_type(padding_start, field_starting_offset, packet_length, *sig_saved); /* Advance to the data elements. */ 906 907 if(length < 0 || length > MAX_ARRAY_LEN || starting_offset + length > packet_length) { 908 col_add_fstr(pinfo->cinfo, COL_INFO, bad_array_format, length, tvb_reported_length_remaining(tvb, starting_offset)); 909 return tvb_reported_length(tvb); 910 } 911 912 /* This item is the entire array including the length specifier plus any pad bytes. */ 913 item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_array, tvb, offset, (starting_offset-offset) + length, encoding); 914 tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters); 915 916 offset = starting_offset; 917 add_padding_item(padding_start, offset, tvb, tree); 918 919 if(0 == length) { 920 advance_to_end_of_signature(signature, signature_length); 921 } else { 922 guint8 sig_length_saved = *signature_length - 1; 923 924 while((offset - starting_offset) < length) { 925 const guint8 *sig_pointer; 926 guint8 remaining_sig_length; 927 928 number_of_items++; 929 sig_pointer = sig_saved; 930 remaining_sig_length = sig_length_saved; 931 932 offset = parse_arg(tvb, 933 pinfo, 934 header_item, 935 encoding, 936 offset, 937 tree, 938 is_reply_to, 939 *sig_pointer, 940 field_code, 941 &sig_pointer, 942 &remaining_sig_length, 943 field_starting_offset); 944 945 /* Set the signature pointer to be just past the type just handled. */ 946 *signature = sig_pointer; 947 *signature_length = remaining_sig_length; 948 } 949 } 950 951 if(item) { 952 proto_item_append_text(item, " of %d '%c' elements", number_of_items, *sig_saved); 953 } 954 } 955 break; 956 957 case ARG_BOOLEAN: /* AllJoyn boolean basic type */ 958 header_type_name = "boolean"; 959 padding_start = offset; 960 offset = round_to_4byte(offset, field_starting_offset); 961 add_padding_item(padding_start, offset, tvb, field_tree); 962 963 proto_tree_add_item(field_tree, hf_alljoyn_boolean, tvb, offset, 4, encoding); 964 offset += 4; 965 break; 966 967 case ARG_DOUBLE: /* AllJoyn IEEE 754 double basic type */ 968 header_type_name = "IEEE 754 double"; 969 padding_start = offset; 970 offset = round_to_8byte(offset, field_starting_offset); 971 add_padding_item(padding_start, offset, tvb, field_tree); 972 973 proto_tree_add_item(field_tree, hf_alljoyn_double, tvb, offset, 8, encoding); 974 offset += 8; 975 break; 976 977 case ARG_SIGNATURE: /* AllJoyn signature basic type */ 978 header_type_name = "signature"; 979 length = tvb_get_guint8(tvb, offset); 980 981 if (length + 2 > tvb_reported_length_remaining(tvb, offset)) { 982 gint bytes_left = tvb_reported_length_remaining(tvb, offset); 983 984 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Signature length is %d. Only %d bytes left in packet.", 985 length, bytes_left); 986 return tvb_reported_length(tvb); 987 } 988 989 /* Include the terminating '/0'. */ 990 length++; 991 992 proto_tree_add_item(field_tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding); 993 offset += 1; 994 995 /* Extract signature from tvb and return to caller. */ 996 /* XXX should this extract "length - 1" since we always expect /0? */ 997 proto_tree_add_item_ret_string(field_tree, hf_alljoyn_mess_body_signature, tvb, offset, length, ENC_ASCII|ENC_NA, pinfo->pool, signature); 998 *signature_length = length; 999 1000 if(HDR_SIGNATURE == field_code) { 1001 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", *signature); 1002 } 1003 1004 offset += length; 1005 break; 1006 1007 case ARG_HANDLE: /* AllJoyn socket handle basic type. */ 1008 header_type_name = "socket handle"; 1009 padding_start = offset; 1010 offset = round_to_4byte(offset, field_starting_offset); 1011 add_padding_item(padding_start, offset, tvb, field_tree); 1012 1013 proto_tree_add_item(field_tree, hf_alljoyn_handle, tvb, offset, 4, encoding); 1014 offset += 4; 1015 break; 1016 1017 case ARG_INT32: /* AllJoyn 32-bit signed integer basic type. */ 1018 header_type_name = "int32"; 1019 padding_start = offset; 1020 offset = round_to_4byte(offset, field_starting_offset); 1021 add_padding_item(padding_start, offset, tvb, field_tree); 1022 1023 proto_tree_add_item(field_tree, hf_alljoyn_int32, tvb, offset, 4, encoding); 1024 offset += 4; 1025 break; 1026 1027 case ARG_INT16: /* AllJoyn 16-bit signed integer basic type. */ 1028 header_type_name = "int16"; 1029 padding_start = offset; 1030 offset = round_to_2byte(offset, field_starting_offset); 1031 add_padding_item(padding_start, offset, tvb, field_tree); 1032 1033 proto_tree_add_item(field_tree, hf_alljoyn_int16, tvb, offset, 2, encoding); 1034 offset += 2; 1035 break; 1036 1037 case ARG_OBJ_PATH: /* AllJoyn Name of an AllJoyn object instance basic type */ 1038 header_type_name = "object path"; 1039 length = get_uint32(tvb, offset, encoding) + 1; 1040 1041 /* The + 4 is for the length specifier. Object paths may be of "any length" 1042 according to D-Bus spec. But there are practical limits. */ 1043 if(length < 0 || length > MAX_ARRAY_LEN || length + 4 > tvb_reported_length_remaining(tvb, offset)) { 1044 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Object path length is %d. Only %d bytes left in packet.", 1045 length, tvb_reported_length_remaining(tvb, offset + 4)); 1046 return tvb_reported_length(tvb); 1047 } 1048 1049 proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); 1050 offset += 4; 1051 1052 proto_tree_add_item(field_tree, hf_alljoyn_string_data, tvb, offset, length, ENC_ASCII|ENC_NA); 1053 offset += length; 1054 break; 1055 1056 case ARG_UINT16: /* AllJoyn 16-bit unsigned integer basic type */ 1057 header_type_name = "uint16"; 1058 padding_start = offset; 1059 offset = round_to_2byte(offset, field_starting_offset); 1060 add_padding_item(padding_start, offset, tvb, field_tree); 1061 1062 proto_tree_add_item(field_tree, hf_alljoyn_uint16, tvb, offset, 2, encoding); 1063 offset += 2; 1064 break; 1065 1066 case ARG_STRING: /* AllJoyn UTF-8 NULL terminated string basic type */ 1067 { 1068 const guint8 *member_name; 1069 1070 header_type_name = "string"; 1071 padding_start = offset; 1072 offset = round_to_4byte(offset, field_starting_offset); 1073 add_padding_item(padding_start, offset, tvb, field_tree); 1074 1075 proto_tree_add_item(field_tree, hf_alljoyn_string_size_32bit, tvb, offset, 4, encoding); 1076 1077 /* Get the length so we can display the string. */ 1078 length = (gint)get_uint32(tvb, offset, encoding); 1079 1080 if(length < 0 || length > tvb_reported_length_remaining(tvb, offset)) { 1081 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: String length is %d. Remaining packet length is %d.", 1082 length, (gint)tvb_reported_length_remaining(tvb, offset)); 1083 return tvb_reported_length(tvb); 1084 } 1085 1086 length += 1; /* Include the '\0'. */ 1087 offset += 4; 1088 1089 proto_tree_add_item_ret_string(field_tree, hf_alljoyn_string_data, tvb, offset, length, ENC_UTF_8|ENC_NA, pinfo->pool, &member_name); 1090 1091 if(HDR_MEMBER == field_code) { 1092 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", member_name); 1093 } 1094 1095 offset += length; 1096 } 1097 break; 1098 1099 case ARG_UINT64: /* AllJoyn 64-bit unsigned integer basic type */ 1100 header_type_name = "uint64"; 1101 padding_start = offset; 1102 offset = round_to_8byte(offset, field_starting_offset); 1103 add_padding_item(padding_start, offset, tvb, field_tree); 1104 1105 proto_tree_add_item(field_tree, hf_alljoyn_uint64, tvb, offset, 8, encoding); 1106 offset += 8; 1107 break; 1108 1109 case ARG_UINT32: /* AllJoyn 32-bit unsigned integer basic type */ 1110 header_type_name = "uint32"; 1111 padding_start = offset; 1112 offset = round_to_4byte(offset, field_starting_offset); 1113 add_padding_item(padding_start, offset, tvb, field_tree); 1114 1115 if(is_reply_to) { 1116 static const gchar format[] = " Replies to: %09u"; 1117 guint32 replies_to; 1118 1119 replies_to = get_uint32(tvb, offset, encoding); 1120 col_append_fstr(pinfo->cinfo, COL_INFO, format, replies_to); 1121 1122 if(header_item) { 1123 proto_item *item; 1124 1125 item = proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); 1126 proto_item_set_text(item, format + 1, replies_to); 1127 } 1128 } else { 1129 proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding); 1130 } 1131 1132 offset += 4; 1133 break; 1134 1135 case ARG_VARIANT: /* AllJoyn variant container type */ 1136 { 1137 proto_item *item; 1138 proto_tree *tree; 1139 const guint8 *sig_saved; 1140 const guint8 *sig_pointer; 1141 guint8 variant_sig_length; 1142 1143 header_type_name = "variant"; 1144 1145 variant_sig_length = tvb_get_guint8(tvb, offset); 1146 length = variant_sig_length; 1147 1148 if(length > tvb_reported_length_remaining(tvb, offset)) { 1149 gint bytes_left = tvb_reported_length_remaining(tvb, offset); 1150 1151 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Variant signature length is %d. Only %d bytes left in packet.", 1152 length, bytes_left); 1153 offset = tvb_reported_length(tvb); 1154 } 1155 1156 length += 1; /* Include the terminating '\0'. */ 1157 1158 /* This length (4) will be updated later with the length of the entire variant object. */ 1159 item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_variant, tvb, offset, 4, encoding); 1160 tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters); 1161 1162 proto_tree_add_item(tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding); 1163 1164 offset += 1; 1165 1166 tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters); 1167 proto_tree_add_item_ret_string(tree, hf_alljoyn_mess_body_signature, tvb, offset, length, ENC_ASCII|ENC_NA, pinfo->pool, &sig_saved); 1168 1169 offset += length; 1170 sig_pointer = sig_saved; 1171 1172 /* The signature of the variant has now been taken care of. So now take care of the variant data. */ 1173 while(((sig_pointer - sig_saved) < (length - 1)) && (tvb_reported_length_remaining(tvb, offset) > 0)) { 1174 proto_item_append_text(item, "%c", *sig_pointer); 1175 1176 offset = parse_arg(tvb, pinfo, header_item, encoding, offset, tree, is_reply_to, 1177 *sig_pointer, field_code, &sig_pointer, &variant_sig_length, field_starting_offset); 1178 } 1179 1180 proto_item_append_text(item, "'"); 1181 proto_item_set_end(item, tvb, offset); 1182 } 1183 break; 1184 1185 case ARG_INT64: /* AllJoyn 64-bit signed integer basic type */ 1186 header_type_name = "int64"; 1187 padding_start = offset; 1188 offset = round_to_8byte(offset, field_starting_offset); 1189 add_padding_item(padding_start, offset, tvb, field_tree); 1190 1191 proto_tree_add_item(field_tree, hf_alljoyn_int64, tvb, offset, 8, encoding); 1192 offset += 8; 1193 break; 1194 1195 case ARG_BYTE: /* AllJoyn 8-bit unsigned integer basic type */ 1196 header_type_name = "byte"; 1197 1198 proto_tree_add_item(field_tree, hf_alljoyn_uint8, tvb, offset, 1, encoding); 1199 offset += 1; 1200 break; 1201 1202 case ARG_DICT_ENTRY: /* AllJoyn dictionary or map container type - an array of key-value pairs */ 1203 case ARG_STRUCT: /* AllJoyn struct container type */ 1204 { 1205 proto_item *item; 1206 proto_tree *tree; 1207 int hf; 1208 guint8 type_stop; 1209 1210 if(type_id == ARG_STRUCT) { 1211 header_type_name = "structure"; 1212 hf = hf_alljoyn_mess_body_structure; 1213 type_stop = ')'; 1214 } else { 1215 header_type_name = "dictionary"; 1216 hf = hf_alljoyn_mess_body_dictionary_entry; 1217 type_stop = '}'; 1218 } 1219 1220 if(*signature == NULL || *signature_length < 1) { 1221 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: A %s argument needs a signature.", header_type_name); 1222 return tvb_reported_length(tvb); 1223 } 1224 1225 /* This length (4) will be updated later with the length of the entire struct. */ 1226 item = proto_tree_add_item(field_tree, hf, tvb, offset, 4, encoding); 1227 append_struct_signature(item, *signature, *signature_length, type_stop); 1228 tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters); 1229 1230 padding_start = offset; 1231 offset = pad_according_to_type(offset, field_starting_offset, tvb_reported_length(tvb), type_id); 1232 add_padding_item(padding_start, offset, tvb, tree); 1233 1234 (*signature)++; /* Advance past the '(' or '{'. */ 1235 (*signature_length)--; 1236 1237 /* *signature should never be NULL but just make sure to avoid potential issues. */ 1238 while(*signature && **signature && **signature != type_stop 1239 && tvb_reported_length_remaining(tvb, offset) > 0) { 1240 offset = parse_arg(tvb, 1241 pinfo, 1242 header_item, 1243 encoding, 1244 offset, 1245 tree, 1246 is_reply_to, 1247 **signature, 1248 field_code, 1249 signature, 1250 signature_length, 1251 field_starting_offset); 1252 } 1253 1254 proto_item_set_end(item, tvb, offset); 1255 } 1256 break; 1257 1258 default: 1259 header_type_name = "unexpected"; 1260 /* Just say we are done with this packet. */ 1261 offset = tvb_reported_length(tvb); 1262 break; 1263 } 1264 1265 if (*signature && *signature_length > 0 && ARG_ARRAY != type_id && HDR_INVALID == field_code) { 1266 (*signature)++; 1267 (*signature_length)--; 1268 } 1269 1270 if(NULL != header_item && NULL != header_type_name) { 1271 /* Using "%s" and the argument "header_type_name" because some compilers don't like 1272 "header_type_name" by itself. */ 1273 proto_item_append_text(header_item, "%s", header_type_name); 1274 } 1275 1276 /* Make sure we never return something longer than the buffer for an offset. */ 1277 if(offset > (gint)tvb_reported_length(tvb)) { 1278 offset = (gint)tvb_reported_length(tvb); 1279 } else if (offset == saved_offset) { 1280 /* The argument has a null size. Let's report the packet length to avoid an infinite loop. */ 1281 /*expert_add_info(pinfo, header_item, &ei_alljoyn_empty_arg);*/ 1282 proto_tree_add_expert(field_tree, pinfo, &ei_alljoyn_empty_arg, tvb, offset, 0); 1283 offset = (gint)tvb_reported_length(tvb); 1284 } 1285 1286 return offset; 1287 } 1288 1289 static void 1290 alljoyn_typeid( gchar *result, guint32 type ) 1291 { 1292 g_snprintf( result, ITEM_LABEL_LENGTH, "'%c' => ", type); 1293 } 1294 1295 /* This is called by handle_message_header_fields() to handle a single 1296 * message header field. 1297 * @param tvb is the incoming network data buffer. 1298 * @param pinfo contains information about the incoming packet which 1299 * we update as we dissect the packet. 1300 * @param header_item is the subtree that we connect data items to. 1301 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) 1302 * @param offset is the offset into tvb to get the field from. 1303 * endianness. 1304 * @param signature pointer to the signature of the parameters. This is a return 1305 * value for the caller to pass to the function that parses the parameters. 1306 * @param signature_length pointer to the length of the signature. This is a return 1307 * value for the caller to pass to the function that parses the parameters. 1308 * @return The new offset into the buffer after removing the field code and value. 1309 * the message. 1310 */ 1311 static gint 1312 handle_message_field(tvbuff_t *tvb, 1313 packet_info *pinfo, 1314 proto_item *header_tree, 1315 guint encoding, 1316 gint offset, 1317 const guint8 **signature, 1318 guint8 *signature_length) 1319 { 1320 proto_tree *field_tree; 1321 proto_item *item, *field_item; 1322 guint8 field_code; 1323 guint8 type_id; 1324 gboolean is_reply_to = FALSE; 1325 gint starting_offset = offset; 1326 gint padding_start; 1327 1328 field_code = tvb_get_guint8(tvb, offset); 1329 1330 if(HDR_REPLY_SERIAL == field_code) { 1331 is_reply_to = TRUE; 1332 } 1333 1334 field_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_field, tvb, offset, 1, ENC_NA); 1335 field_tree = proto_item_add_subtree(field_item, ett_alljoyn_mess_header_field); 1336 1337 proto_tree_add_item(field_tree, hf_alljoyn_mess_body_header_fieldcode, tvb, offset, 1, ENC_NA); 1338 offset += 1; 1339 1340 /* We expect a byte of 0x01 here. */ 1341 handle_message_header_expected_byte(tvb, offset, field_tree, 0x01); 1342 offset += 1; 1343 1344 item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_header_typeid, tvb, offset, 1, ENC_NA); 1345 type_id = tvb_get_guint8(tvb, offset); 1346 offset += 1; 1347 1348 /* We expect a byte of 0x00 here. */ 1349 handle_message_header_expected_byte(tvb, offset, field_tree, 0x00); 1350 offset += 1; 1351 1352 offset = parse_arg(tvb, 1353 pinfo, 1354 item, 1355 encoding, 1356 offset, 1357 field_tree, 1358 is_reply_to, 1359 type_id, 1360 field_code, 1361 signature, 1362 signature_length, 1363 starting_offset); 1364 1365 padding_start = offset; 1366 offset = round_to_8byte(offset, starting_offset); 1367 add_padding_item(padding_start, offset, tvb, field_tree); 1368 1369 if(offset < 0 || offset > (gint)tvb_reported_length(tvb)) { 1370 offset = (gint)tvb_reported_length(tvb); 1371 } 1372 1373 proto_item_set_end(field_tree, tvb, offset); 1374 1375 return offset; 1376 } 1377 1378 /* This is called by handle_message() to handle the message body. 1379 * @param tvb is the incoming network data buffer. 1380 * @param pinfo contains information about the incoming packet which 1381 * we update as we dissect the packet. 1382 * @param header_tree is the subtree that we connect data items to. 1383 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) 1384 * @param offset contains the offset into tvb for the start of the header fields. 1385 * @param header_length contains the length of the message fields. 1386 * @param signature_length contains the signature field length. 1387 */ 1388 static const guint8 * 1389 handle_message_header_fields(tvbuff_t *tvb, 1390 packet_info *pinfo, 1391 proto_item *header_tree, 1392 guint encoding, 1393 gint offset, 1394 guint32 header_length, 1395 guint8 *signature_length) 1396 { 1397 gint end_of_header; 1398 proto_item *item; 1399 proto_tree *tree; 1400 const guint8 *signature = NULL; 1401 1402 item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_fields, tvb, offset, header_length, ENC_NA); 1403 tree = proto_item_add_subtree(item, ett_alljoyn_mess_header); 1404 1405 end_of_header = offset + header_length; 1406 1407 while(offset < end_of_header) { 1408 offset = handle_message_field(tvb, pinfo, tree, encoding, offset, &signature, signature_length); 1409 } 1410 1411 return signature; 1412 } 1413 1414 /* This is called by handle_message() to handle the message body. 1415 * @param tvb is the incoming network data buffer. 1416 * @param header_tree is the subtree that we connect data items to. 1417 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN) 1418 * @param offset contains the offset into tvb for the start of the parameters. 1419 * @param body_length contains the length of the body parameters. 1420 * @param signature the signature of the parameters. 1421 * @param signature_length contains the signature field length. 1422 */ 1423 static gint 1424 handle_message_body_parameters(tvbuff_t *tvb, 1425 packet_info *pinfo, 1426 proto_tree *header_tree, 1427 guint encoding, 1428 gint offset, 1429 gint32 body_length, 1430 const guint8 *signature, 1431 guint8 signature_length) 1432 { 1433 gint packet_length, end_of_body; 1434 proto_tree *tree; 1435 proto_item *item; 1436 const gint starting_offset = offset; 1437 1438 packet_length = tvb_reported_length(tvb); 1439 1440 /* Add a subtree/row for the message body parameters. */ 1441 item = proto_tree_add_item(header_tree, hf_alljoyn_mess_body_parameters, tvb, offset, body_length, ENC_NA); 1442 tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters); 1443 1444 end_of_body = offset + body_length; 1445 1446 if(end_of_body > packet_length) { 1447 end_of_body = packet_length; 1448 } 1449 1450 while(offset < end_of_body && signature_length > 0 && signature && *signature) { 1451 offset = parse_arg(tvb, 1452 pinfo, 1453 NULL, 1454 encoding, 1455 offset, 1456 tree, /* Add the args to the Parameters tree. */ 1457 FALSE, 1458 *signature, 1459 HDR_INVALID, 1460 &signature, 1461 &signature_length, 1462 starting_offset); 1463 } 1464 1465 return offset; 1466 } 1467 1468 #define MESSAGE_HEADER_LENGTH 16 1469 #define TYPE_OFFSET 1 1470 #define FLAGS_OFFSET 2 1471 #define MAJORVERSION_OFFSET 3 1472 #define BODY_LENGTH_OFFSET 4 1473 #define SERIAL_OFFSET 8 1474 #define HEADER_LENGTH_OFFSET 12 1475 1476 /* This is called by dissect_AllJoyn_message() to handle the actual message. 1477 * If it was a message with valid header and optional body then return TRUE. 1478 * If not a valid message return false. 1479 * @param tvb is the incoming network data buffer. 1480 * @param pinfo contains information about the incoming packet. 1481 * @param offset is the offset into the packet to start processing. 1482 * @param message_tree is the subtree that any connect data items should be added to. 1483 * @param is_ardp is true if this is an ARDP packet. 1484 * @returns the offset into the packet that has successfully been handled or 1485 * the input offset value if it was not a message header body. 1486 */ 1487 static gint 1488 handle_message_header_body(tvbuff_t *tvb, 1489 packet_info *pinfo, 1490 gint offset, 1491 proto_item *message_tree, 1492 gboolean is_ardp) 1493 { 1494 gint remaining_packet_length; 1495 const guint8 *signature; 1496 guint8 signature_length = 0; 1497 proto_tree *header_tree, *flag_tree; 1498 proto_item *header_item, *flag_item; 1499 guint encoding; 1500 gint packet_length_needed; 1501 gint header_length = 0, body_length = 0; 1502 1503 remaining_packet_length = tvb_reported_length_remaining(tvb, offset); 1504 encoding = get_message_header_endianness(tvb, offset); 1505 1506 if(ENC_ALLJOYN_BAD_ENCODING == encoding) { 1507 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Endian encoding '0x%0x'. Expected 'l' or 'B'", 1508 tvb_get_guint8(tvb, offset + ENDIANNESS_OFFSET)); 1509 1510 /* We are done with everything in this packet don't try anymore. */ 1511 return offset + remaining_packet_length; 1512 } 1513 1514 if(remaining_packet_length < MESSAGE_HEADER_LENGTH) { 1515 if(!set_pinfo_desegment(pinfo, offset, MESSAGE_HEADER_LENGTH - remaining_packet_length)) { 1516 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %d. Expected >= %d && <= %d", 1517 remaining_packet_length, MESSAGE_HEADER_LENGTH, MAX_PACKET_LEN); 1518 } 1519 1520 return offset + remaining_packet_length; 1521 } 1522 1523 header_length = get_uint32(tvb, offset + HEADER_LENGTH_OFFSET, encoding); 1524 body_length = get_uint32(tvb, offset + BODY_LENGTH_OFFSET, encoding); 1525 packet_length_needed = ROUND_TO_8BYTE(header_length) + body_length + MESSAGE_HEADER_LENGTH; 1526 1527 /* ARDP (UDP) packets can't be desegmented by Wireshark and it is normal to see them in 1528 * fragments. Don't scare the user when they occur. Dissect as much as we easily can. 1529 * It should be possible to desegment TCIP packets. If not then something is wrong so tell 1530 * the user. 1531 */ 1532 if(packet_length_needed > remaining_packet_length) { 1533 if(!set_pinfo_desegment(pinfo, offset, packet_length_needed - remaining_packet_length)) { 1534 if(!is_ardp) { 1535 col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %d. Expected %d", 1536 remaining_packet_length, packet_length_needed); 1537 1538 return offset + remaining_packet_length; 1539 } 1540 1541 /* In this case we can't desegment but it is an ARDP message so we want to dissect 1542 * at least the header. Therefore we fall through to the header parsing code if the packet size 1543 * is greater than or equal to the header size. Otherwise we return and report what we know. 1544 */ 1545 if (remaining_packet_length < header_length) { 1546 col_add_fstr(pinfo->cinfo, COL_INFO, "Fragmented ARDP message: Remaining packet length is %d. Expected %d", 1547 remaining_packet_length, packet_length_needed); 1548 return offset + remaining_packet_length; 1549 } 1550 } 1551 else { 1552 /* In this case we can desegment */ 1553 return offset + remaining_packet_length; 1554 } 1555 } 1556 1557 /* Add a subtree/row for the header. */ 1558 header_item = proto_tree_add_item(message_tree, hf_alljoyn_mess_header, tvb, offset, MESSAGE_HEADER_LENGTH, ENC_NA); 1559 header_tree = proto_item_add_subtree(header_item, ett_alljoyn_header); 1560 1561 proto_tree_add_item(header_tree, hf_alljoyn_mess_header_endian, tvb, offset + ENDIANNESS_OFFSET, 1, ENC_ASCII|ENC_NA); 1562 proto_tree_add_item(header_tree, hf_alljoyn_mess_header_type, tvb, offset + TYPE_OFFSET, 1, ENC_NA); 1563 1564 /* The flags byte. */ 1565 flag_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_flags, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1566 flag_tree = proto_item_add_subtree(flag_item, ett_alljoyn_header_flags); 1567 1568 /* Now the individual bits. */ 1569 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_encrypted, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1570 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_compressed, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1571 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_global_broadcast, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1572 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_sessionless, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1573 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_allow_remote_msg, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1574 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_no_auto_start, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1575 proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_no_reply, tvb, offset + FLAGS_OFFSET, 1, ENC_NA); 1576 1577 proto_tree_add_item(header_tree, hf_alljoyn_mess_header_majorversion, tvb, offset + MAJORVERSION_OFFSET, 1, ENC_NA); 1578 proto_tree_add_item(header_tree, hf_alljoyn_mess_header_body_length, tvb, offset + BODY_LENGTH_OFFSET, 4, encoding); 1579 1580 proto_tree_add_item(header_tree, hf_alljoyn_mess_header_serial, tvb, offset + SERIAL_OFFSET, 4, encoding); 1581 col_add_fstr(pinfo->cinfo, COL_INFO, "Message %010u: '%s'", get_uint32(tvb, offset + SERIAL_OFFSET, encoding), 1582 val_to_str_const(tvb_get_guint8(tvb, offset + TYPE_OFFSET), message_header_encoding_vals, "Unexpected message type")); 1583 1584 proto_tree_add_item(header_tree, hf_alljoyn_mess_header_header_length, tvb, offset + HEADER_LENGTH_OFFSET, 4, encoding); 1585 offset += MESSAGE_HEADER_LENGTH; 1586 packet_length_needed -= MESSAGE_HEADER_LENGTH; 1587 1588 signature = handle_message_header_fields(tvb, pinfo, message_tree, encoding, 1589 offset, header_length, &signature_length); 1590 /* No need to call add_padding_item() after the following operation. It's not needed 1591 * because all message header fields widths are multiples of 8 and are padded as necessary. 1592 * Because the padding is taken care of in the individual message header field there is no 1593 * need for it here. The rounding here just gets the offset to the end of the last header 1594 * field and its (possible) padding. 1595 */ 1596 offset += ROUND_TO_8BYTE(header_length); 1597 packet_length_needed -= ROUND_TO_8BYTE(header_length); 1598 remaining_packet_length = tvb_reported_length_remaining(tvb, offset); 1599 1600 if (packet_length_needed > remaining_packet_length) { 1601 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Fragmented ARDP message or bad data: Remaining packet length is %d. Expected %d", 1602 remaining_packet_length, packet_length_needed); 1603 return offset + remaining_packet_length; 1604 } 1605 1606 if(body_length > 0 && signature != NULL && signature_length > 0) { 1607 offset = handle_message_body_parameters(tvb, 1608 pinfo, 1609 message_tree, 1610 encoding, 1611 offset, 1612 body_length, 1613 signature, 1614 signature_length); 1615 } 1616 1617 return offset; 1618 } 1619 1620 /* Test to see if this buffer contains something that might be an AllJoyn message. 1621 * @param tvb is the incoming network data buffer. 1622 * @param offset where to start parsing the buffer. 1623 * @param is_ardp If true then this is an ARDP packet which needs special treatment. 1624 * @returns TRUE if probably an AllJoyn message. 1625 * FALSE if probably not an AllJoyn message. 1626 */ 1627 static gboolean 1628 protocol_is_alljoyn_message(tvbuff_t *tvb, gint offset, gboolean is_ardp) 1629 { 1630 gint length = tvb_captured_length(tvb); 1631 1632 if(length < offset + 1) 1633 return FALSE; 1634 1635 /* There is no initial connect byte or SASL when using ARDP. */ 1636 if(!is_ardp) { 1637 /* initial byte for a connect message. */ 1638 if(tvb_get_guint8(tvb, offset) == 0) 1639 return TRUE; 1640 1641 if(find_sasl_command(tvb, offset) != NULL) 1642 return TRUE; 1643 } 1644 1645 if(get_message_header_endianness(tvb, offset) == ENC_ALLJOYN_BAD_ENCODING) 1646 return FALSE; 1647 1648 if((length < offset + 2) || (try_val_to_str(tvb_get_guint8(tvb, offset + 1), message_header_encoding_vals) == NULL)) 1649 return FALSE; 1650 1651 return TRUE; 1652 } 1653 1654 /* This is called by Wireshark for packet types that are registered 1655 * in the proto_reg_handoff_AllJoyn() function. This function handles 1656 * the packets for the traffic on port 9955. 1657 * @param tvb is the incoming network data buffer. 1658 * @param pinfo contains information about the incoming packet which 1659 * we update as we dissect the packet. 1660 * @param tree is the tree data items should be added to. 1661 * @param offset is the offset into the already partial dissected buffer 1662 * from dissect_AllJoyn_ardp() or 0 because this is just a bare 1663 * AllJoyn message. 1664 * @return 0 if not AllJoyn message protocol, or 1665 * the offset into the buffer we have successfully dissected (which 1666 * should normally be the packet length), or 1667 * the offset into the buffer we have dissected with 1668 * pinfo->desegment_len == additional bytes needed from the next packet 1669 * before we can dissect, or 1670 * 0 with pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT if another 1671 * segment is needed, or 1672 * packet_length if "really bad" parameters come in. 1673 */ 1674 static gint 1675 dissect_AllJoyn_message(tvbuff_t *tvb, 1676 packet_info *pinfo, 1677 proto_tree *tree, 1678 gint offset) 1679 { 1680 proto_item *message_item; 1681 proto_tree *message_tree; 1682 gint last_offset = -1; 1683 gint packet_length; 1684 gboolean is_ardp = FALSE; 1685 1686 /* If called after dissecting the ARDP protocol. This is the only time the offset will not be zero. */ 1687 if(offset != 0) { 1688 is_ardp = TRUE; 1689 } 1690 1691 pinfo->desegment_len = 0; 1692 packet_length = tvb_reported_length(tvb); 1693 1694 col_clear(pinfo->cinfo, COL_INFO); 1695 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN"); 1696 1697 /* Add a subtree covering the remainder of the packet */ 1698 message_item = proto_tree_add_item(tree, proto_AllJoyn_mess, tvb, offset, -1, ENC_NA); 1699 message_tree = proto_item_add_subtree(message_item, ett_alljoyn_mess); 1700 1701 /* Continue as long as we are making progress and we haven't finished with the packet. */ 1702 while(offset < packet_length && offset > last_offset) { 1703 last_offset = offset; 1704 1705 /* There is no initial connect byte or SASL when using ARDP. */ 1706 if(!is_ardp) { 1707 offset = handle_message_connect(tvb, pinfo, offset, message_tree); 1708 1709 if(offset >= packet_length) { 1710 break; 1711 } 1712 1713 offset = handle_message_sasl(tvb, pinfo, offset, message_tree); 1714 1715 if(offset >= packet_length) { 1716 break; 1717 } 1718 } 1719 1720 offset = handle_message_header_body(tvb, pinfo, offset, message_tree, is_ardp); 1721 } 1722 1723 return offset; 1724 } 1725 1726 static void 1727 ns_parse_questions(tvbuff_t *tvb, gint* offset, proto_tree* alljoyn_tree, guint8 questions, guint message_version) 1728 { 1729 while(questions--) { 1730 proto_item *alljoyn_questions_ti; 1731 proto_tree *alljoyn_questions_tree; 1732 gint count; 1733 1734 alljoyn_questions_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_ns_whohas, tvb, *offset, 2, ENC_NA); /* "Who-Has Message" */ 1735 alljoyn_questions_tree = proto_item_add_subtree(alljoyn_questions_ti, ett_alljoyn_whohas); 1736 1737 if(0 == message_version) { 1738 proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_t_flag, tvb, *offset, 1, ENC_NA); 1739 proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_u_flag, tvb, *offset, 1, ENC_NA); 1740 proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_s_flag, tvb, *offset, 1, ENC_NA); 1741 proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_f_flag, tvb, *offset, 1, ENC_NA); 1742 } 1743 1744 (*offset) += 1; 1745 1746 proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_count, tvb, *offset, 1, ENC_NA); 1747 count = tvb_get_guint8(tvb, *offset); 1748 (*offset) += 1; 1749 1750 while(count--) { 1751 proto_item *alljoyn_bus_name_ti; 1752 proto_tree *alljoyn_bus_name_tree; 1753 gint bus_name_size = 0; 1754 1755 bus_name_size = tvb_get_guint8(tvb, *offset); 1756 1757 alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_string, tvb, 1758 *offset, 1 + bus_name_size, ENC_NA); 1759 alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_ns_string); 1760 1761 proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); 1762 (*offset) += 1; 1763 1764 proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII|ENC_NA); 1765 (*offset) += bus_name_size; 1766 } 1767 1768 } 1769 } 1770 1771 /* The version 0 protocol looks like this: 1772 * Byte 0: 1773 * Bit 0 (ISAT_F): If '1' indicates the daemon is listening on an IPv4 1774 * address and that an IPv4 address is present in the message. If '0' 1775 * there is no IPv4 address present. 1776 * 1777 * Bit 1 (ISAT_S): If '1' the responding daemon is listening on an IPv6 1778 * address and that an IPv6 address is present in the message. If '0' 1779 * there is no IPv6 address present. 1780 * 1781 * Bit 2 (ISAT_U): If '1' the daemon is listening on UDP. 1782 * 1783 * Bit 3 (ISAT_T): If '1' the daemon is listening on TCP. 1784 * 1785 * Bit 4 (ISAT_C): If '1' the list of StringData records is a complete 1786 * list of all well-known names exported by the daemon. 1787 * 1788 * Bit 5 (ISAT_G): If '1' a variable length daemon GUID string is present. 1789 * 1790 * Bits 6-7: The message type of the IS-AT message. Defined to be '01' (1). 1791 * 1792 * Byte 1 (Count): The number of StringData items. Each StringData item 1793 * describes one well-known bus name supported by the daemon. 1794 * 1795 * Bytes 2-3 (Port): The port on which the daemon is listening. 1796 * 1797 * If the ISAT_F bit is set then the next four bytes is the IPv4 address on 1798 * which the daemon is listening. 1799 * 1800 * If the ISAT_S bit is set then the next 16 bytes is the IPv6 address on 1801 * which the daemon is listening. 1802 * 1803 * If the ISAT_G bit is set then the next data is daemon GUID StringData. 1804 * 1805 * The next data is a variable number of StringData records. 1806 */ 1807 static void 1808 ns_parse_answers_v0(tvbuff_t *tvb, gint* offset, proto_tree* alljoyn_tree, guint8 answers) 1809 { 1810 while(answers--) { 1811 proto_item *alljoyn_answers_ti; 1812 proto_tree *alljoyn_answers_tree; 1813 gint flags; 1814 gint count; 1815 1816 alljoyn_answers_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_answer, tvb, *offset, 2, ENC_NA); 1817 alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns_answers); 1818 1819 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, *offset, 1, ENC_NA); 1820 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, *offset, 1, ENC_NA); 1821 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_t_flag, tvb, *offset, 1, ENC_NA); 1822 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u_flag, tvb, *offset, 1, ENC_NA); 1823 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_s_flag, tvb, *offset, 1, ENC_NA); 1824 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_f_flag, tvb, *offset, 1, ENC_NA); 1825 flags = tvb_get_guint8(tvb, *offset); 1826 (*offset) += 1; 1827 1828 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_count, tvb, *offset, 1, ENC_NA); 1829 count = tvb_get_guint8(tvb, *offset); 1830 (*offset) += 1; 1831 1832 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN); 1833 (*offset) += 2; 1834 1835 if(flags & ISAT_S) { 1836 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA); 1837 (*offset) += 16; 1838 } 1839 1840 if(flags & ISAT_F) { 1841 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_BIG_ENDIAN); 1842 (*offset) += 4; 1843 } 1844 1845 if(flags & ISAT_G) { 1846 proto_item *alljoyn_string_ti; 1847 proto_tree *alljoyn_string_tree; 1848 gint guid_size = 0; 1849 1850 guid_size = tvb_get_guint8(tvb, *offset); 1851 1852 alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_guid_string, tvb, 1853 *offset, 1 + guid_size, ENC_NA); 1854 alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns_guid_string); 1855 1856 proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); 1857 (*offset) += 1; 1858 1859 proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, *offset, guid_size, ENC_ASCII|ENC_NA); 1860 (*offset) += guid_size; 1861 } 1862 1863 while(count--) { 1864 proto_item *alljoyn_entry_ti; 1865 proto_tree *alljoyn_entry_tree; 1866 proto_item *alljoyn_bus_name_ti; 1867 proto_tree *alljoyn_bus_name_tree; 1868 gint bus_name_size = tvb_get_guint8(tvb, *offset); 1869 1870 alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_entry, tvb, 1871 *offset, 1 + bus_name_size, ENC_NA); 1872 alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_ns_isat_entry); 1873 1874 alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, hf_alljoyn_string, tvb, *offset, 1875 1 + bus_name_size, ENC_NA); 1876 alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_string); 1877 1878 proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); 1879 (*offset) += 1; 1880 1881 proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII|ENC_NA); 1882 (*offset) += bus_name_size; 1883 } 1884 } 1885 } 1886 1887 /* The version 1 protocol looks like this: 1888 * Byte 0: 1889 * Bit 0 (ISAT_U6): If '1' then the IPv6 endpoint of an unreliable method 1890 * (UDP) transport (IP address and port) is present. 1891 * 1892 * Bit 1 (ISAT_R6): If '1' the the IPv6 endpoint of a reliable method 1893 * (TCP) transport (IP address and port) is present. 1894 * 1895 * Bit 2 (ISAT_U4): If '1' then the IPv4 endpoint of an unreliable method 1896 * (UDP) transport (IP address and port) is present. 1897 * 1898 * Bit 3 (ISAT_R4): If '1' then the IPv4 endpoint of a reliable method 1899 * (TCP) transport (IP address and port) is present. 1900 * 1901 * Bit 4 (ISAT_C): If '1' the list of StringData records is a complete 1902 * list of all well-known names exported by the daemon. 1903 * 1904 * Bit 5 (ISAT_G): If '1' a variable length daemon GUID string is present. 1905 * 1906 * Bits 6-7: The message type of the IS-AT message. Defined to be '01' (1). 1907 * 1908 * Byte 1 (Count): The number of StringData items. Each StringData item 1909 * describes one well-known bus name supported by the daemon. 1910 * 1911 * Bytes 2-3 (TransportMask): The bit mask of transport identifiers that 1912 * indicates which AllJoyn transport is making the advertisement. 1913 * 1914 * If the ISAT_R4 bit is set then the next four bytes is the IPv4 address on 1915 * which the daemon is listening. 1916 * 1917 * If the ISAT_R4 bit is set then the next two bytes is the IPv4 port on 1918 * which the daemon is listening. 1919 * 1920 * If the ISAT_R6 bit is set then the next 16 bytes is the IPv6 address on 1921 * which the daemon is listening for TCP traffic. 1922 * 1923 * If the ISAT_R6 bit is set then the next two bytes is the IPv6 port on 1924 * which the daemon is listening for TCP traffic. 1925 * 1926 * If the ISAT_U6 bit is set then the next 16 bytes is the IPv6 address on 1927 * which the daemon is listening for UDP traffic. 1928 * 1929 * If the ISAT_U6 bit is set then the next two bytes is the IPv6 port on 1930 * which the daemon is listening for UDP traffic. 1931 * 1932 * If the ISAT_G bit is set then the next data is daemon GUID StringData. 1933 * 1934 * The next data is a variable number of StringData records. 1935 */ 1936 static void 1937 ns_parse_answers_v1(tvbuff_t *tvb, gint* offset, proto_tree* alljoyn_tree, guint8 answers) 1938 { 1939 while(answers--) { 1940 proto_item *alljoyn_answers_ti; 1941 proto_tree *alljoyn_answers_tree; 1942 gint flags; 1943 gint count; 1944 1945 alljoyn_answers_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_answer, tvb, *offset, 2, ENC_NA); 1946 alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns_answers); 1947 1948 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, *offset, 1, ENC_NA); 1949 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, *offset, 1, ENC_NA); 1950 1951 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r4_flag, tvb, *offset, 1, ENC_NA); 1952 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u4_flag, tvb, *offset, 1, ENC_NA); 1953 1954 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r6_flag, tvb, *offset, 1, ENC_NA); 1955 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u6_flag, tvb, *offset, 1, ENC_NA); 1956 1957 flags = tvb_get_guint8(tvb, *offset); 1958 (*offset) += 1; 1959 1960 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_count, tvb, *offset, 1, ENC_NA); 1961 count = tvb_get_guint8(tvb, *offset); 1962 (*offset) += 1; 1963 1964 /* The entire transport mask. */ 1965 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask, tvb, *offset, 2, ENC_BIG_ENDIAN); 1966 1967 /* The individual bits of the transport mask. */ 1968 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wfd, tvb, *offset, 2, ENC_NA); 1969 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_ice, tvb, *offset, 2, ENC_NA); 1970 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_lan, tvb, *offset, 2, ENC_NA); 1971 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wwan, tvb, *offset, 2, ENC_NA); 1972 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_tcp, tvb, *offset, 2, ENC_NA); 1973 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_bluetooth, tvb, *offset, 2, ENC_NA); 1974 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_local, tvb, *offset, 2, ENC_NA); 1975 1976 (*offset) += 2; 1977 1978 if(flags & ISAT_R4) { 1979 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_BIG_ENDIAN); 1980 (*offset) += 4; 1981 1982 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN); 1983 (*offset) += 2; 1984 } 1985 1986 if(flags & ISAT_U4) { 1987 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_BIG_ENDIAN); 1988 (*offset) += 4; 1989 1990 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN); 1991 (*offset) += 2; 1992 } 1993 1994 if(flags & ISAT_R6) { 1995 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA); 1996 (*offset) += 16; 1997 1998 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN); 1999 (*offset) += 2; 2000 } 2001 2002 if(flags & ISAT_U6) { 2003 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA); 2004 (*offset) += 16; 2005 2006 proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN); 2007 (*offset) += 2; 2008 } 2009 2010 if(flags & ISAT_G) { 2011 proto_item *alljoyn_string_ti; 2012 proto_tree *alljoyn_string_tree; 2013 gint guid_size; 2014 2015 guid_size = tvb_get_guint8(tvb, *offset); 2016 2017 alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_guid_string, tvb, 2018 *offset, 1 + guid_size, ENC_NA); 2019 alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns_guid_string); 2020 2021 proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); 2022 (*offset) += 1; 2023 2024 proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, *offset, guid_size, ENC_ASCII|ENC_NA); 2025 (*offset) += guid_size; 2026 } 2027 2028 /* The string data records. */ 2029 while(count--) { 2030 proto_item *alljoyn_entry_ti; 2031 proto_tree *alljoyn_entry_tree; 2032 2033 proto_tree *alljoyn_bus_name_ti; 2034 proto_tree *alljoyn_bus_name_tree; 2035 gint bus_name_size = tvb_get_guint8(tvb, *offset); 2036 2037 alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_entry, tvb, 2038 *offset, 1 + bus_name_size, ENC_NA); 2039 alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_isat_entry); 2040 2041 alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, hf_alljoyn_string, tvb, *offset, 2042 1 + bus_name_size, ENC_NA); 2043 alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_string); 2044 2045 proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA); 2046 (*offset) += 1; 2047 2048 proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII|ENC_NA); 2049 (*offset) += bus_name_size; 2050 } 2051 } 2052 } 2053 2054 /* This is called by Wireshark for packet types that are registered 2055 in the proto_reg_handoff_AllJoyn() function. This function handles 2056 the packets for the name server traffic. 2057 * @param tvb is the incoming network data buffer. 2058 * @param pinfo contains information about the incoming packet which 2059 * we update as we dissect the packet. 2060 * @param tree is the tree data items should be added to. 2061 */ 2062 static int 2063 dissect_AllJoyn_name_server(tvbuff_t *tvb, 2064 packet_info *pinfo, 2065 proto_tree *tree, 2066 void *data _U_) 2067 { 2068 proto_item *alljoyn_item, *header_item; 2069 proto_tree *alljoyn_tree, *header_tree; 2070 guint8 questions, answers; 2071 guint8 version; 2072 int offset = 0; 2073 2074 /* This is name service traffic. Mark it as such at the top level. */ 2075 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN-NS"); 2076 col_clear(pinfo->cinfo, COL_INFO); 2077 2078 /* Add a subtree covering the remainder of the packet */ 2079 alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ns, tvb, 0, -1, ENC_NA); 2080 alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ns); 2081 2082 /* Add the "header protocol" as a subtree from the AllJoyn Name Service Protocol. */ 2083 header_item = proto_tree_add_item(alljoyn_tree, hf_alljoyn_ns_header, tvb, offset, 4, ENC_NA); 2084 header_tree = proto_item_add_subtree(header_item, ett_alljoyn_ns_header); 2085 2086 /* The the sender and message versions as fields for the header protocol. */ 2087 proto_tree_add_item(header_tree, hf_alljoyn_ns_sender_version, tvb, offset, 1, ENC_NA); 2088 proto_tree_add_item(header_tree, hf_alljoyn_ns_message_version, tvb, offset, 1, ENC_NA); 2089 version = tvb_get_guint8(tvb, offset) & 0xF; 2090 offset += 1; 2091 2092 col_add_fstr(pinfo->cinfo, COL_INFO, "VERSION %u", version); 2093 if(version > 1) 2094 col_append_str(pinfo->cinfo, COL_INFO, " (UNSUPPORTED)"); 2095 2096 proto_tree_add_item(header_tree, hf_alljoyn_ns_questions, tvb, offset, 1, ENC_NA); 2097 questions = tvb_get_guint8(tvb, offset); 2098 offset += 1; 2099 2100 proto_tree_add_item(header_tree, hf_alljoyn_ns_answers, tvb, offset, 1, ENC_NA); 2101 answers = tvb_get_guint8(tvb, offset); 2102 offset += 1; 2103 2104 if(answers > 0) 2105 col_append_str(pinfo->cinfo, COL_INFO, " ISAT"); 2106 2107 if(questions > 0) 2108 col_append_str(pinfo->cinfo, COL_INFO, " WHOHAS"); 2109 2110 proto_tree_add_item(header_tree, hf_alljoyn_ns_timer, tvb, offset, 1, ENC_NA); 2111 offset += 1; 2112 2113 2114 if(tree) { /* we are being asked for details */ 2115 ns_parse_questions(tvb, &offset, alljoyn_tree, questions, version); 2116 2117 switch(version) { 2118 case 0: 2119 ns_parse_answers_v0(tvb, &offset, alljoyn_tree, answers); 2120 break; 2121 case 1: 2122 ns_parse_answers_v1(tvb, &offset, alljoyn_tree, answers); 2123 break; 2124 default: 2125 /* XXX - expert info */ 2126 /* This case being unsupported is reported in the column info by 2127 * the caller of this function. */ 2128 break; 2129 } 2130 } 2131 2132 return tvb_reported_length(tvb); 2133 } 2134 2135 /* This is a container for the ARDP info and Wireshark tree information. 2136 */ 2137 typedef struct _alljoyn_ardp_tree_data 2138 { 2139 gint offset; 2140 gboolean syn; 2141 gboolean ack; 2142 gboolean eak; 2143 gboolean rst; 2144 gboolean nul; 2145 guint sequence; 2146 guint start_sequence; 2147 guint16 fragment_count; 2148 gint acknowledge; 2149 proto_tree *alljoyn_tree; 2150 } alljoyn_ardp_tree_data; 2151 2152 /* This is called by dissect_AllJoyn_ardp() to read the header 2153 * and fill out most of tree_data. 2154 * @param tvb is the incoming network data buffer. 2155 * @param pinfo contains information about the incoming packet which 2156 * we update as we dissect the packet. 2157 * @param tree_data is the destination of the data.. 2158 */ 2159 static void 2160 ardp_parse_header(tvbuff_t *tvb, 2161 packet_info *pinfo, 2162 alljoyn_ardp_tree_data *tree_data) 2163 { 2164 guint8 flags, header_length; 2165 gint eaklen, packet_length; 2166 guint16 data_length; 2167 2168 packet_length = tvb_reported_length(tvb); 2169 2170 flags = tvb_get_guint8(tvb, 0); 2171 2172 tree_data->syn = (flags & ARDP_SYN) != 0; 2173 tree_data->ack = (flags & ARDP_ACK) != 0; 2174 tree_data->eak = (flags & ARDP_EAK) != 0; 2175 tree_data->rst = (flags & ARDP_RST) != 0; 2176 tree_data->nul = (flags & ARDP_NUL) != 0; 2177 2178 /* The packet length has to be ARDP_HEADER_LEN_OFFSET long or protocol_is_ardp() would 2179 have returned false. Length is expressed in words so multiply by 2. */ 2180 header_length = 2 * tvb_get_guint8(tvb, ARDP_HEADER_LEN_OFFSET); 2181 2182 if(packet_length < ARDP_DATA_LENGTH_OFFSET + 2) { 2183 /* If we need more data before dissecting then communicate the number of additional bytes needed. */ 2184 set_pinfo_desegment(pinfo, 0, ARDP_DATA_LENGTH_OFFSET + 2 - packet_length); 2185 2186 /* Inform the caller we made it this far. Returning zero means we made no progress. 2187 This is the offset just past the last byte we successfully retrieved. */ 2188 tree_data->offset = ARDP_HEADER_LEN_OFFSET + 1; 2189 2190 return; 2191 } 2192 2193 data_length = tvb_get_ntohs(tvb, ARDP_DATA_LENGTH_OFFSET); 2194 2195 if(packet_length < header_length + data_length) { 2196 /* If we need more data before dissecting then communicate the number of additional bytes needed. */ 2197 set_pinfo_desegment(pinfo, 0, header_length + data_length - packet_length); 2198 2199 /* Inform the caller we made it this far. Returning zero it means we made no progress. 2200 This is the offset just past the last byte we successfully retrieved. */ 2201 tree_data->offset = ARDP_DATA_LENGTH_OFFSET + 2; 2202 return; 2203 } 2204 2205 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_syn_flag, tvb, tree_data->offset, 1, ENC_NA); 2206 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ack_flag, tvb, tree_data->offset, 1, ENC_NA); 2207 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_eak_flag, tvb, tree_data->offset, 1, ENC_NA); 2208 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_rst_flag, tvb, tree_data->offset, 1, ENC_NA); 2209 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_nul_flag, tvb, tree_data->offset, 1, ENC_NA); 2210 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_unused_flag, tvb, tree_data->offset, 1, ENC_NA); 2211 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_version_field, tvb, tree_data->offset, 1, ENC_NA); 2212 2213 tree_data->offset += 1; 2214 2215 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_hlen, tvb, tree_data->offset, 1, ENC_NA); 2216 tree_data->offset += 1; 2217 2218 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_src, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2219 tree_data->offset += 2; 2220 2221 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dst, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2222 tree_data->offset += 2; 2223 2224 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dlen, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2225 tree_data->offset += 2; 2226 2227 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_seq, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2228 tree_data->sequence = tvb_get_ntohl(tvb, tree_data->offset); 2229 tree_data->offset += 4; 2230 2231 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ack, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2232 tree_data->acknowledge = tvb_get_ntohl(tvb, tree_data->offset); 2233 tree_data->offset += 4; 2234 2235 if(tree_data->syn) { 2236 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_segmax, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2237 tree_data->offset += 2; 2238 2239 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_segbmax, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2240 tree_data->offset += 2; 2241 2242 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dackt, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2243 tree_data->offset += 4; 2244 2245 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_options, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2246 tree_data->offset += 2; 2247 } else { 2248 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ttl, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2249 tree_data->offset += 4; 2250 2251 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_lcs, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2252 tree_data->offset += 4; 2253 2254 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_nsa, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2255 tree_data->offset += 4; 2256 2257 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_fss, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN); 2258 tree_data->start_sequence = tvb_get_ntohl(tvb, tree_data->offset); 2259 tree_data->offset += 4; 2260 2261 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_fcnt, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN); 2262 tree_data->fragment_count = tvb_get_ntohs(tvb, tree_data->offset); 2263 tree_data->offset += 2; 2264 2265 eaklen = header_length - ARDP_FIXED_HDR_LEN; 2266 2267 /* In the case of a corrupted packet eaklen could be < 0 and bad things could happen. */ 2268 if(eaklen > 0) { 2269 if(tree_data->eak) { 2270 proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_bmp, tvb, tree_data->offset, eaklen, ENC_NA); 2271 } 2272 2273 tree_data->offset += eaklen; 2274 } 2275 2276 /* The data_length bytes, if any, will be passed on to the dissect_AllJoyn_message() handler. */ 2277 } 2278 } 2279 2280 /* Test to see if this buffer contains something that might be the AllJoyn ARDP protocol. 2281 * @param tvb is the incoming network data buffer. 2282 * @returns TRUE if probably the AllJoyn ARDP protocol. 2283 * FALSE if probably not the AllJoyn ARDP protocol. 2284 */ 2285 static gboolean 2286 protocol_is_ardp(tvbuff_t *tvb) 2287 { 2288 guint8 flags, header_length; 2289 gint length = tvb_captured_length(tvb); 2290 2291 /* We must be able to get the byte value at this offset to determine if it is an ARDP protocol. */ 2292 if(length < ARDP_HEADER_LEN_OFFSET + 1) { 2293 return FALSE; 2294 } 2295 2296 /* Length is expressed in words. */ 2297 header_length = 2 * tvb_get_guint8(tvb, ARDP_HEADER_LEN_OFFSET); 2298 2299 flags = tvb_get_guint8(tvb, 0); 2300 2301 if((flags & ARDP_SYN) && header_length != ARDP_SYN_FIXED_HDR_LEN) { 2302 return FALSE; 2303 } 2304 2305 if(!(flags & ARDP_SYN) && header_length < ARDP_FIXED_HDR_LEN) { 2306 return FALSE; 2307 } 2308 2309 return TRUE; 2310 } 2311 2312 /* This is called by Wireshark for packet types that are registered 2313 in the proto_reg_handoff_AllJoyn() function. This function handles 2314 the packets for the ARDP and bare AllJoyn message protocols. A test 2315 for bare AllJoyn message protocol is done first. If it is an AllJoyn 2316 packet then only dissect_AllJoyn_message() is called to dissect the 2317 data. If protocol_is_alljoyn_message() returns FALSE then a test for 2318 the ARDP protocol is performed. If it succeeds then ARDP dissection 2319 proceeds and may call dissect_AllJoyn_message() with the offset just 2320 past the ARDP protocol. 2321 * @param tvb is the incoming network data buffer. 2322 * @param pinfo contains information about the incoming packet which 2323 * we update as we dissect the packet. 2324 * @param tree is the tree data items should be added to. 2325 * @return 0 if not AllJoyn ARDP protocol, or 2326 * the offset into the buffer we have dissected (which should normally 2327 * be the packet length), or 2328 * the offset into the buffer we have dissected with 2329 * pinfo->desegment_len == additional bytes needed from the next packet 2330 * before we can dissect. 2331 */ 2332 static int 2333 dissect_AllJoyn_ardp(tvbuff_t *tvb, 2334 packet_info *pinfo, 2335 proto_tree *tree, 2336 void *data _U_) 2337 { 2338 alljoyn_ardp_tree_data tree_data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 2339 gint packet_length = tvb_reported_length(tvb); 2340 proto_item *alljoyn_item = NULL; 2341 gboolean fragmentedPacket = FALSE; 2342 2343 if(protocol_is_alljoyn_message(tvb, 0, FALSE)) { 2344 return dissect_AllJoyn_message(tvb, pinfo, tree, 0); 2345 } 2346 2347 if(!protocol_is_ardp(tvb)) { 2348 return 0; 2349 } 2350 2351 pinfo->desegment_len = 0; 2352 2353 /* Add a subtree covering the remainder of the packet */ 2354 alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ardp, tvb, 0, -1, ENC_NA); 2355 tree_data.alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ardp); 2356 2357 ardp_parse_header(tvb, pinfo, &tree_data); 2358 2359 /* Is desegmention needed? */ 2360 if(pinfo->desegment_len != 0) { 2361 return tree_data.offset; 2362 } 2363 2364 if(tree_data.offset != 0) { 2365 /* This is ARDP traffic. Mark it as such at the top level. */ 2366 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN-ARDP"); 2367 } 2368 2369 if(tree_data.offset < packet_length) { 2370 gint return_value = 0; 2371 2372 /* We have dissected the ARDP portion. Is the remainder an AllJoyn message? */ 2373 if(protocol_is_alljoyn_message(tvb, tree_data.offset, TRUE)) { 2374 return_value = dissect_AllJoyn_message(tvb, pinfo, tree, tree_data.offset); 2375 } 2376 else { 2377 fragmentedPacket = !tree_data.syn && (tree_data.sequence > tree_data.start_sequence); 2378 } 2379 2380 /* return_value will be the offset into the successfully parsed 2381 * buffer, the requested length of a reassembled packet (with pinfo->desegment_len 2382 * and pinfo->desegment_offset set appropriately), 0 if desegmentation is needed but 2383 * isn't available, or the initial value (tree_data.offset) if no progress was made. 2384 * If dissect_AllJoyn_message() made progress or is requesting desegmentation then 2385 * return leaving the column info as handled by the AllJoyn message dissector. If 2386 * not then we fall through to set the column info in this dissector. 2387 */ 2388 if(return_value > tree_data.offset) { 2389 return return_value; 2390 } 2391 } 2392 2393 col_clear(pinfo->cinfo, COL_INFO); 2394 2395 col_append_str(pinfo->cinfo, COL_INFO, "flags:"); 2396 if(tree_data.syn) { 2397 col_append_str(pinfo->cinfo, COL_INFO, " SYN"); 2398 } 2399 if(tree_data.ack) { 2400 col_append_str(pinfo->cinfo, COL_INFO, " ACK"); 2401 } 2402 if(tree_data.eak) { 2403 col_append_str(pinfo->cinfo, COL_INFO, " EAK"); 2404 } 2405 if(tree_data.rst) { 2406 col_append_str(pinfo->cinfo, COL_INFO, " RST"); 2407 } 2408 if(tree_data.nul) { 2409 col_append_str(pinfo->cinfo, COL_INFO, " NUL"); 2410 } 2411 2412 col_append_fstr(pinfo->cinfo, COL_INFO, " SEQ: %10u", tree_data.sequence); 2413 col_append_fstr(pinfo->cinfo, COL_INFO, " ACK: %10u", tree_data.acknowledge); 2414 2415 if(fragmentedPacket) { 2416 guint fragment = (tree_data.sequence - tree_data.start_sequence) + 1; 2417 2418 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Fragment %d of %d for a previous ALLJOYN message", fragment, tree_data.fragment_count); 2419 } 2420 2421 return tree_data.offset; 2422 } 2423 2424 void 2425 proto_register_AllJoyn(void) 2426 { 2427 expert_module_t* expert_alljoyn; 2428 2429 /* A header field is something you can search/filter on. 2430 * 2431 * We create a structure to register our fields. It consists of an 2432 * array of hf_register_info structures, each of which are of the format 2433 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}. 2434 * The array below defines what elements we will be displaying. These 2435 * declarations are simply a definition Wireshark uses to determine the data 2436 * type, when we later dissect the packet. 2437 */ 2438 static hf_register_info hf[] = { 2439 /****************** 2440 * Wireshark header fields for the name service protocol. 2441 ******************/ 2442 {&hf_alljoyn_ns_header, 2443 {"Header", "alljoyn.header", 2444 FT_NONE, BASE_NONE, NULL, 0x0, 2445 NULL, HFILL} 2446 }, 2447 {&hf_alljoyn_ns_sender_version, 2448 {"Sender Version", "alljoyn.header.sendversion", 2449 FT_UINT8, BASE_DEC, NULL, 0xF0, 2450 NULL, HFILL} 2451 }, 2452 {&hf_alljoyn_ns_message_version, 2453 {"Message Version", "alljoyn.header.messageversion", 2454 FT_UINT8, BASE_DEC, NULL, 0x0F, 2455 NULL, HFILL} 2456 }, 2457 {&hf_alljoyn_ns_questions, 2458 {"Questions", "alljoyn.header.questions", 2459 FT_UINT8, BASE_DEC, NULL, 0x0, 2460 NULL, HFILL} 2461 }, 2462 {&hf_alljoyn_ns_answers, 2463 {"Answers", "alljoyn.header.answers", 2464 FT_UINT8, BASE_DEC, NULL, 0x0, 2465 NULL, HFILL} 2466 }, 2467 {&hf_alljoyn_ns_timer, 2468 {"Timer", "alljoyn.header.timer", 2469 FT_UINT8, BASE_DEC, NULL, 0x0, 2470 NULL, HFILL} 2471 }, 2472 2473 {&hf_alljoyn_ns_whohas, 2474 {"Who-Has Message", "alljoyn.whohas", 2475 FT_NONE, BASE_NONE, NULL, 0x0, 2476 NULL, HFILL} 2477 }, 2478 {&hf_alljoyn_ns_whohas_t_flag, 2479 {"TCP", "alljoyn.whohas.T", 2480 FT_BOOLEAN, 8, NULL, WHOHAS_T, 2481 NULL, HFILL} 2482 }, 2483 {&hf_alljoyn_ns_whohas_u_flag, 2484 {"UDP", "alljoyn.whohas.U", 2485 FT_BOOLEAN, 8, NULL, WHOHAS_U, 2486 NULL, HFILL} 2487 }, 2488 {&hf_alljoyn_ns_whohas_s_flag, 2489 {"IPv6", "alljoyn.whohas.S", 2490 FT_BOOLEAN, 8, NULL, WHOHAS_S, 2491 NULL, HFILL} 2492 }, 2493 {&hf_alljoyn_ns_whohas_f_flag, 2494 {"IPv4", "alljoyn.whohas.F", 2495 FT_BOOLEAN, 8, NULL, WHOHAS_F, 2496 NULL, HFILL} 2497 }, 2498 {&hf_alljoyn_ns_whohas_count, 2499 {"Count", "alljoyn.whohas.count", 2500 FT_UINT8, BASE_DEC, NULL, 0x0, 2501 NULL, HFILL} 2502 }, 2503 2504 {&hf_alljoyn_answer, 2505 {"Is-At Message", "alljoyn.isat", 2506 FT_NONE, BASE_NONE, NULL, 0x0, 2507 NULL, HFILL} 2508 }, 2509 {&hf_alljoyn_isat_entry, 2510 {"Advertisement Entry", "alljoyn.isat_entry", 2511 FT_NONE, BASE_NONE, NULL, 0x0, 2512 NULL, HFILL} 2513 }, 2514 {&hf_alljoyn_isat_guid_string, 2515 {"GUID String", "alljoyn.isat_guid_string", 2516 FT_NONE, BASE_NONE, NULL, 0x0, 2517 NULL, HFILL} 2518 }, 2519 2520 /* Common to V0 and V1 IS-AT messages. */ 2521 {&hf_alljoyn_ns_isat_g_flag, 2522 {"GUID", "alljoyn.isat.G", 2523 FT_BOOLEAN, 8, NULL, ISAT_G, 2524 NULL, HFILL} 2525 }, 2526 {&hf_alljoyn_ns_isat_c_flag, 2527 {"Complete", "alljoyn.isat.C", 2528 FT_BOOLEAN, 8, NULL, ISAT_C, 2529 NULL, HFILL} 2530 }, 2531 {&hf_alljoyn_ns_isat_count, 2532 {"Count", "alljoyn.isat.count", 2533 FT_UINT8, BASE_DEC, NULL, 0x0, 2534 NULL, HFILL} 2535 }, 2536 {&hf_alljoyn_ns_isat_ipv6, 2537 {"IPv6 Address", "alljoyn.isat.ipv6", 2538 FT_IPv6, BASE_NONE, NULL, 0x0, 2539 NULL, HFILL} 2540 }, 2541 {&hf_alljoyn_ns_isat_ipv4, 2542 {"IPv4 Address", "alljoyn.isat.ipv4", 2543 FT_IPv4, BASE_NONE, NULL, 0x0, 2544 NULL, HFILL} 2545 }, 2546 2547 /* Version 0 IS-AT messages. */ 2548 {&hf_alljoyn_ns_isat_t_flag, 2549 {"TCP", "alljoyn.isat.T", 2550 FT_BOOLEAN, 8, NULL, ISAT_T, 2551 NULL, HFILL} 2552 }, 2553 {&hf_alljoyn_ns_isat_u_flag, 2554 {"UDP", "alljoyn.isat.U", 2555 FT_BOOLEAN, 8, NULL, ISAT_U, 2556 NULL, HFILL} 2557 }, 2558 {&hf_alljoyn_ns_isat_s_flag, 2559 {"IPv6", "alljoyn.isat.S", 2560 FT_BOOLEAN, 8, NULL, ISAT_S, 2561 NULL, HFILL} 2562 }, 2563 {&hf_alljoyn_ns_isat_f_flag, 2564 {"IPv4", "alljoyn.isat.F", 2565 FT_BOOLEAN, 8, NULL, ISAT_F, 2566 NULL, HFILL} 2567 }, 2568 {&hf_alljoyn_ns_isat_port, 2569 {"Port", "alljoyn.isat.port", 2570 FT_UINT16, BASE_DEC, NULL, 0x0, 2571 NULL, HFILL} 2572 }, 2573 2574 /* Version 1 IS-AT messages. */ 2575 {&hf_alljoyn_ns_isat_u6_flag, 2576 {"IPv6 UDP", "alljoyn.isat.U6", 2577 FT_BOOLEAN, 8, NULL, ISAT_U6, 2578 NULL, HFILL} 2579 }, 2580 {&hf_alljoyn_ns_isat_r6_flag, 2581 {"IPv6 TCP", "alljoyn.isat.R6", 2582 FT_BOOLEAN, 8, NULL, ISAT_R6, 2583 NULL, HFILL} 2584 }, 2585 {&hf_alljoyn_ns_isat_u4_flag, 2586 {"IPv4 UDP", "alljoyn.isat.U4", 2587 FT_BOOLEAN, 8, NULL, ISAT_U4, 2588 NULL, HFILL} 2589 }, 2590 {&hf_alljoyn_ns_isat_r4_flag, 2591 {"IPv4 TCP", "alljoyn.isat.R4", 2592 FT_BOOLEAN, 8, NULL, ISAT_R4, 2593 NULL, HFILL} 2594 }, 2595 2596 {&hf_alljoyn_ns_isat_transport_mask, 2597 {"Transport Mask", "alljoyn.isat.TransportMask", 2598 FT_UINT16, BASE_HEX, NULL, 0x0, 2599 NULL, HFILL} 2600 }, 2601 2602 {&hf_alljoyn_ns_isat_transport_mask_local, 2603 {"Local Transport", "alljoyn.isat.TransportMask.Local", 2604 FT_BOOLEAN, 16, NULL, TRANSPORT_LOCAL, 2605 NULL, HFILL} 2606 }, 2607 {&hf_alljoyn_ns_isat_transport_mask_bluetooth, 2608 {"Bluetooth Transport", "alljoyn.isat.TransportMask.Bluetooth", 2609 FT_BOOLEAN, 16, NULL, TRANSPORT_BLUETOOTH, 2610 NULL, HFILL} 2611 }, 2612 {&hf_alljoyn_ns_isat_transport_mask_tcp, 2613 {"TCP Transport", "alljoyn.isat.TransportMask.TCP", 2614 FT_BOOLEAN, 16, NULL, TRANSPORT_TCP, 2615 NULL, HFILL} 2616 }, 2617 {&hf_alljoyn_ns_isat_transport_mask_wwan, 2618 {"Wireless WAN Transport", "alljoyn.isat.TransportMask.WWAN", 2619 FT_BOOLEAN, 16, NULL, TRANSPORT_WWAN, 2620 NULL, HFILL} 2621 }, 2622 {&hf_alljoyn_ns_isat_transport_mask_lan, 2623 {"Wired LAN Transport", "alljoyn.isat.TransportMask.LAN", 2624 FT_BOOLEAN, 16, NULL, TRANSPORT_LAN, 2625 NULL, HFILL} 2626 }, 2627 {&hf_alljoyn_ns_isat_transport_mask_ice, 2628 {"ICE protocol Transport", "alljoyn.isat.TransportMask.ICE", 2629 FT_BOOLEAN, 16, NULL, TRANSPORT_ICE, 2630 NULL, HFILL} 2631 }, 2632 {&hf_alljoyn_ns_isat_transport_mask_wfd, 2633 {"Wi-Fi Direct Transport", "alljoyn.isat.TransportMask.WFD", 2634 FT_BOOLEAN, 16, NULL, TRANSPORT_WFD, 2635 NULL, HFILL} 2636 }, 2637 2638 /****************** 2639 * Wireshark header fields for the message protocol. 2640 ******************/ 2641 {&hf_alljoyn_connect_byte_value, 2642 {"Connect Initial Byte", "alljoyn.InitialByte", 2643 FT_UINT8, BASE_HEX, NULL, 0x0, 2644 NULL, HFILL} 2645 }, 2646 2647 /* 2648 * Wireshark header fields for the SASL messages. 2649 */ 2650 {&hf_alljoyn_sasl_command, 2651 {"SASL command", "alljoyn.SASL.command", 2652 FT_STRING, BASE_NONE, NULL, 0x0, 2653 NULL, HFILL} 2654 }, 2655 {&hf_alljoyn_sasl_parameter, 2656 {"SASL parameter", "alljoyn.SASL.parameter", 2657 FT_STRING, BASE_NONE, NULL, 0x0, 2658 NULL, HFILL} 2659 }, 2660 2661 /* 2662 * Wireshark header fields for the AllJoyn message header. 2663 */ 2664 {&hf_alljoyn_mess_header, 2665 {"Message Header", "alljoyn.mess_header", 2666 FT_BYTES, BASE_NONE, NULL, 0x0, 2667 NULL, HFILL} 2668 }, 2669 {&hf_alljoyn_mess_header_endian, 2670 {"Endianness", "alljoyn.mess_header.endianness", 2671 FT_CHAR, BASE_HEX, VALS(endian_encoding_vals), 0x0, 2672 NULL, HFILL} 2673 }, 2674 {&hf_alljoyn_mess_header_type, 2675 {"Message type", "alljoyn.mess_header.type", 2676 FT_UINT8, BASE_DEC, VALS(message_header_encoding_vals), 0x0, 2677 NULL, HFILL} 2678 }, 2679 {&hf_alljoyn_mess_header_flags, 2680 {"Flags", "alljoyn.mess_header.flags", 2681 FT_UINT8, BASE_HEX, NULL, 0x0, 2682 NULL, HFILL} 2683 }, 2684 2685 /* Individual fields of the flags byte. */ 2686 {&hf_alljoyn_mess_header_flags_no_reply, 2687 {"No reply expected", "alljoyn.mess_header.flags.noreply", 2688 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_NO_REPLY_EXPECTED, 2689 NULL, HFILL} 2690 }, 2691 {&hf_alljoyn_mess_header_flags_no_auto_start, 2692 {"No auto start", "alljoyn.mess_header.flags.noautostart", 2693 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_NO_AUTO_START, 2694 NULL, HFILL} 2695 }, 2696 {&hf_alljoyn_mess_header_flags_allow_remote_msg, 2697 {"Allow remote messages", "alljoyn.mess_header.flags.allowremotemessages", 2698 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_ALLOW_REMOTE_MSG, 2699 NULL, HFILL} 2700 }, 2701 {&hf_alljoyn_mess_header_flags_sessionless, 2702 {"Sessionless", "alljoyn.mess_header.flags.sessionless", 2703 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_SESSIONLESS, 2704 NULL, HFILL} 2705 }, 2706 {&hf_alljoyn_mess_header_flags_global_broadcast, 2707 {"Allow global broadcast", "alljoyn.mess_header.flags.globalbroadcast", 2708 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_GLOBAL_BROADCAST, 2709 NULL, HFILL} 2710 }, 2711 {&hf_alljoyn_mess_header_flags_compressed, 2712 {"Compressed", "alljoyn.mess_header.flags.compressed", 2713 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_COMPRESSED, 2714 NULL, HFILL} 2715 }, 2716 {&hf_alljoyn_mess_header_flags_encrypted, 2717 {"Encrypted", "alljoyn.mess_header.flags.encrypted", 2718 FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_ENCRYPTED, 2719 NULL, HFILL} 2720 }, 2721 2722 {&hf_alljoyn_mess_header_majorversion, 2723 {"Major version", "alljoyn.mess_header.majorversion", 2724 FT_UINT8, BASE_DEC, NULL, 0, 2725 NULL, HFILL} 2726 }, 2727 {&hf_alljoyn_mess_header_body_length, 2728 {"Body length", "alljoyn.mess_header.bodylength", 2729 FT_UINT32, BASE_DEC, NULL, 0, 2730 NULL, HFILL} 2731 }, 2732 {&hf_alljoyn_mess_header_serial, 2733 {"Serial number", "alljoyn.mess_header.serial", 2734 FT_UINT32, BASE_DEC, NULL, 0, 2735 NULL, HFILL} 2736 }, 2737 {&hf_alljoyn_mess_header_header_length, 2738 {"Header length", "alljoyn.mess_header.headerlength", 2739 FT_UINT32, BASE_DEC, NULL, 0, 2740 NULL, HFILL} 2741 }, 2742 2743 {&hf_alljoyn_mess_header_fields, 2744 {"Header fields", "alljoyn.mess_header.fields", 2745 FT_BYTES, BASE_NONE, NULL, 0, 2746 NULL, HFILL} 2747 }, 2748 {&hf_alljoyn_mess_header_field, 2749 {"Header field", "alljoyn.mess_header.field", 2750 FT_UINT8, BASE_HEX, VALS(mess_header_field_encoding_vals), 0, 2751 NULL, HFILL} 2752 }, 2753 {&hf_alljoyn_mess_body_header_fieldcode, 2754 {"Field code", "alljoyn.message.fieldcode", 2755 FT_UINT8, BASE_HEX, NULL, 0, 2756 NULL, HFILL} 2757 }, 2758 {&hf_alljoyn_mess_body_header_typeid, 2759 {"Type ID", "alljoyn.message.typeid", 2760 FT_UINT8, BASE_CUSTOM, CF_FUNC(alljoyn_typeid), 0, 2761 NULL, HFILL} 2762 }, 2763 2764 {&hf_alljoyn_mess_body_parameters, 2765 {"Parameters", "alljoyn.parameters", 2766 FT_NONE, BASE_NONE, NULL, 0, 2767 NULL, HFILL} 2768 }, 2769 {&hf_alljoyn_mess_body_array, 2770 {"Array", "alljoyn.array", 2771 FT_NONE, BASE_NONE, NULL, 0, 2772 NULL, HFILL} 2773 }, 2774 {&hf_alljoyn_mess_body_structure, 2775 {"struct", "alljoyn.structure", 2776 FT_NONE, BASE_NONE, NULL, 0, 2777 NULL, HFILL} 2778 }, 2779 {&hf_alljoyn_mess_body_dictionary_entry, 2780 {"dictionary entry", "alljoyn.dictionary_entry", 2781 FT_NONE, BASE_NONE, NULL, 0, 2782 NULL, HFILL} 2783 }, 2784 {&hf_alljoyn_mess_body_variant, 2785 {"Variant '", "alljoyn.variant", 2786 FT_NONE, BASE_NONE, NULL, 0, 2787 NULL, HFILL} 2788 }, 2789 {&hf_alljoyn_mess_body_signature_length, 2790 {"Signature length", "alljoyn.parameter.signature_length", 2791 FT_UINT8, BASE_DEC, NULL, 0, 2792 NULL, HFILL} 2793 }, 2794 {&hf_alljoyn_mess_body_signature, 2795 {"Signature", "alljoyn.parameter.signature", 2796 FT_STRING, BASE_NONE, NULL, 0x0, 2797 NULL, HFILL} 2798 }, 2799 2800 {&hf_alljoyn_boolean, 2801 {"Boolean", "alljoyn.boolean", 2802 FT_BOOLEAN, BASE_NONE, NULL, 0, 2803 NULL, HFILL} 2804 }, 2805 {&hf_alljoyn_uint8, 2806 {"Unsigned byte", "alljoyn.uint8", 2807 FT_UINT8, BASE_DEC, NULL, 0, 2808 NULL, HFILL} 2809 }, 2810 {&hf_alljoyn_int16, 2811 {"Signed int16", "alljoyn.int16", 2812 FT_INT16, BASE_DEC, NULL, 0, 2813 NULL, HFILL} 2814 }, 2815 {&hf_alljoyn_uint16, 2816 {"Unsigned int16", "alljoyn.uint16", 2817 FT_UINT16, BASE_DEC, NULL, 0, 2818 NULL, HFILL} 2819 }, 2820 {&hf_alljoyn_handle, 2821 {"Handle", "alljoyn.handle", 2822 FT_UINT32, BASE_HEX, NULL, 0, 2823 NULL, HFILL} 2824 }, 2825 {&hf_alljoyn_int32, 2826 {"Signed int32", "alljoyn.int32", 2827 FT_INT32, BASE_DEC, NULL, 0, 2828 NULL, HFILL} 2829 }, 2830 {&hf_alljoyn_uint32, 2831 {"Unsigned int32", "alljoyn.uint32", 2832 FT_UINT32, BASE_DEC, NULL, 0, 2833 NULL, HFILL} 2834 }, 2835 {&hf_alljoyn_int64, 2836 {"Signed int64", "alljoyn.int64", 2837 FT_INT64, BASE_DEC, NULL, 0, 2838 NULL, HFILL} 2839 }, 2840 {&hf_alljoyn_uint64, 2841 {"Unsigned int64", "alljoyn.uint64", 2842 FT_UINT64, BASE_DEC, NULL, 0, 2843 NULL, HFILL} 2844 }, 2845 {&hf_alljoyn_double, 2846 {"Double", "alljoyn.double", 2847 FT_DOUBLE, BASE_NONE, NULL, 0, 2848 NULL, HFILL} 2849 }, 2850 {&hf_padding, 2851 {"Padding", "alljoyn.padding", 2852 FT_BYTES, BASE_NONE, NULL, 0, 2853 NULL, HFILL} 2854 }, 2855 2856 /* 2857 * Strings are composed of a size and a data array. 2858 */ 2859 {&hf_alljoyn_string, 2860 {"Bus Name", "alljoyn.string", 2861 FT_NONE, BASE_NONE, NULL, 0x0, 2862 NULL, HFILL} 2863 }, 2864 {&hf_alljoyn_string_size_8bit, 2865 {"String Size 8-bit", "alljoyn.string.size8bit", 2866 FT_UINT8, BASE_DEC, NULL, 0x0, 2867 NULL, HFILL} 2868 }, 2869 {&hf_alljoyn_string_size_32bit, 2870 {"String Size 32-bit", "alljoyn.string.size32bit", 2871 FT_UINT32, BASE_DEC, NULL, 0x0, 2872 NULL, HFILL} 2873 }, 2874 {&hf_alljoyn_string_data, 2875 {"String Data", "alljoyn.string.data", 2876 FT_STRING, BASE_NONE, NULL, 0x0, 2877 NULL, HFILL} 2878 }, 2879 /****************** 2880 * Wireshark header fields for the AllJoyn Reliable Data Protocol. 2881 ******************/ 2882 {&hf_ardp_syn_flag, 2883 {"SYN", "ardp.hdr.SYN", 2884 FT_BOOLEAN, 8, NULL, ARDP_SYN, 2885 NULL, HFILL} 2886 }, 2887 {&hf_ardp_ack_flag, 2888 {"ACK", "ardp.hdr.ACK", 2889 FT_BOOLEAN, 8, NULL, ARDP_ACK, 2890 NULL, HFILL}}, 2891 {&hf_ardp_eak_flag, 2892 {"EAK", "ardp.hdr.EAK", 2893 FT_BOOLEAN, 8, NULL, ARDP_EAK, 2894 NULL, HFILL}}, 2895 {&hf_ardp_rst_flag, 2896 {"RST", "ardp.hdr.RST", 2897 FT_BOOLEAN, 8, NULL, ARDP_RST, 2898 NULL, HFILL}}, 2899 {&hf_ardp_nul_flag, 2900 {"NUL", "ardp.hdr.NUL", 2901 FT_BOOLEAN, 8, NULL, ARDP_NUL, 2902 NULL, HFILL}}, 2903 {&hf_ardp_unused_flag, 2904 {"UNUSED", "ardp.hdr.UNUSED", 2905 FT_BOOLEAN, 8, NULL, ARDP_UNUSED, 2906 NULL, HFILL}}, 2907 {&hf_ardp_version_field, 2908 {"VER", "ardp.hdr.ver", 2909 FT_UINT8, BASE_HEX, NULL, ARDP_VER, 2910 NULL, HFILL}}, 2911 {&hf_ardp_hlen, 2912 {"Header Length", "ardp.hdr.hlen", 2913 FT_UINT8, BASE_DEC, NULL, 0x0, 2914 NULL, HFILL}}, 2915 {&hf_ardp_src, 2916 {"Source Port", "ardp.hdr.src", 2917 FT_UINT16, BASE_DEC, NULL, 0x0, 2918 NULL, HFILL}}, 2919 {&hf_ardp_dst, 2920 {"Destination Port", "ardp.hdr.dst", 2921 FT_UINT16, BASE_DEC, NULL, 0x0, 2922 NULL, HFILL}}, 2923 {&hf_ardp_dlen, 2924 {"Data Length", "ardp.hdr.dlen", 2925 FT_UINT16, BASE_DEC, NULL, 0x0, 2926 NULL, HFILL}}, 2927 {&hf_ardp_seq, 2928 {"Sequence", "ardp.hdr.seq", 2929 FT_UINT32, BASE_DEC, NULL, 0x0, 2930 NULL, HFILL}}, 2931 {&hf_ardp_ack, 2932 {"Acknowledge", "ardp.hdr.ack", 2933 FT_UINT32, BASE_DEC, NULL, 0x0, 2934 NULL, HFILL}}, 2935 {&hf_ardp_ttl, 2936 {"Time to Live", "ardp.hdr.ttl", 2937 FT_UINT32, BASE_DEC, NULL, 0x0, 2938 NULL, HFILL}}, 2939 {&hf_ardp_lcs, 2940 {"Last Consumed Sequence", "ardp.hdr.lcs", 2941 FT_UINT32, BASE_DEC, NULL, 0x0, 2942 NULL, HFILL}}, 2943 {&hf_ardp_nsa, 2944 {"Next Sequence to ACK", "ardp.hdr.nsa", 2945 FT_UINT32, BASE_DEC, NULL, 0x0, 2946 NULL, HFILL}}, 2947 {&hf_ardp_fss, 2948 {"Fragment Starting Sequence", "ardp.hdr.fss", 2949 FT_UINT32, BASE_DEC, NULL, 0x0, 2950 NULL, HFILL}}, 2951 {&hf_ardp_fcnt, 2952 {"Fragment Count", "ardp.hdr.fcnt", 2953 FT_UINT16, BASE_HEX, NULL, 0x0, 2954 NULL, HFILL}}, 2955 {&hf_ardp_bmp, 2956 {"EACK Bitmap", "ardp.hdr.bmp", 2957 FT_UINT8, BASE_HEX, NULL, 0x0, 2958 NULL, HFILL}}, 2959 {&hf_ardp_segmax, 2960 {"Segment Max", "ardp.hdr.segmentmax", 2961 FT_UINT16, BASE_DEC, NULL, 0x0, 2962 NULL, HFILL}}, 2963 {&hf_ardp_segbmax, 2964 {"Segment Buffer Max", "ardp.hdr.segmentbmax", 2965 FT_UINT32, BASE_DEC, NULL, 0x0, 2966 NULL, HFILL}}, 2967 {&hf_ardp_dackt, 2968 {"Receiver's delayed ACK timeout", "ardp.hdr.dackt", 2969 FT_UINT16, BASE_DEC, NULL, 0x0, 2970 NULL, HFILL}}, 2971 {&hf_ardp_options, 2972 {"Options", "ardp.hdr.options", 2973 FT_UINT16, BASE_HEX, NULL, 0x0, 2974 NULL, HFILL}}, 2975 }; 2976 2977 static gint *ett[] = { 2978 &ett_alljoyn_ns, 2979 &ett_alljoyn_ns_header, 2980 &ett_alljoyn_ns_answers, 2981 &ett_alljoyn_ns_guid_string, 2982 &ett_alljoyn_ns_isat_entry, 2983 &ett_alljoyn_ns_string, 2984 &ett_alljoyn_whohas, 2985 &ett_alljoyn_string, 2986 &ett_alljoyn_isat_entry, 2987 &ett_alljoyn_mess, 2988 &ett_alljoyn_header, 2989 &ett_alljoyn_header_flags, 2990 &ett_alljoyn_mess_header_field, 2991 &ett_alljoyn_mess_header, 2992 &ett_alljoyn_mess_body_parameters, 2993 &ett_alljoyn_ardp 2994 }; 2995 2996 static ei_register_info ei[] = { 2997 { &ei_alljoyn_empty_arg, 2998 { "alljoyn.empty_arg", PI_MALFORMED, PI_ERROR, 2999 "Argument is empty", EXPFILL }} 3000 }; 3001 3002 /* The following are protocols as opposed to data within a protocol. These appear 3003 * in Wireshark a divider/header between different groups of data. 3004 */ 3005 3006 /* Name service protocols. */ /* name, short name, abbrev */ 3007 proto_AllJoyn_ns = proto_register_protocol("AllJoyn Name Service Protocol", "AllJoyn NS", "ajns"); 3008 3009 /* Message protocols */ 3010 proto_AllJoyn_mess = proto_register_protocol("AllJoyn Message Protocol", "AllJoyn", "aj"); 3011 3012 proto_register_field_array(proto_AllJoyn_ns, hf, array_length(hf)); 3013 proto_register_subtree_array(ett, array_length(ett)); 3014 expert_alljoyn = expert_register_protocol(proto_AllJoyn_mess); 3015 expert_register_field_array(expert_alljoyn, ei, array_length(ei)); 3016 3017 /* ARDP */ /* name, short name, abbrev */ 3018 proto_AllJoyn_ardp = proto_register_protocol("AllJoyn Reliable Datagram Protocol", "AllJoyn ARDP", "ardp"); 3019 } 3020 3021 void 3022 proto_reg_handoff_AllJoyn(void) 3023 { 3024 dissector_handle_t alljoyn_handle_ns; 3025 dissector_handle_t alljoyn_handle_ardp; 3026 3027 alljoyn_handle_ns = create_dissector_handle(dissect_AllJoyn_name_server, proto_AllJoyn_ns); 3028 alljoyn_handle_ardp = create_dissector_handle(dissect_AllJoyn_ardp, proto_AllJoyn_ardp); 3029 dissector_add_uint_with_preference("tcp.port", ALLJOYN_NAME_SERVER_PORT, alljoyn_handle_ns); 3030 dissector_add_uint_with_preference("tcp.port", ALLJOYN_MESSAGE_PORT, alljoyn_handle_ardp); 3031 3032 dissector_add_uint_with_preference("udp.port", ALLJOYN_NAME_SERVER_PORT, alljoyn_handle_ns); 3033 3034 /* The ARDP dissector will directly call the AllJoyn message dissector if needed. 3035 * This includes the case where there is no ARDP data. */ 3036 dissector_add_uint_with_preference("udp.port", ALLJOYN_MESSAGE_PORT, alljoyn_handle_ardp); 3037 } 3038 3039 /* 3040 * Editor modelines - https://www.wireshark.org/tools/modelines.html 3041 * 3042 * Local variables: 3043 * c-basic-offset: 4 3044 * tab-width: 8 3045 * indent-tabs-mode: nil 3046 * End: 3047 * 3048 * vi: set shiftwidth=4 tabstop=8 expandtab: 3049 * :indentSize=4:tabSize=8:noTabs=true: 3050 */ 3051