Coverage Report

Created: 2026-09-28 06:52

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