Coverage Report

Created: 2026-07-12 07:10

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
30
#define ALLJOYN_NAME_SERVER_PORT      9956 /* IANA lists only UDP as being registered (dissector also uses TCP port) */
42
30
#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
15
#define MESSAGE_HEADER_FLAG_NO_REPLY_EXPECTED 0x01
107
15
#define MESSAGE_HEADER_FLAG_NO_AUTO_START     0x02
108
15
#define MESSAGE_HEADER_FLAG_ALLOW_REMOTE_MSG  0x04
109
15
#define MESSAGE_HEADER_FLAG_SESSIONLESS       0x10
110
15
#define MESSAGE_HEADER_FLAG_GLOBAL_BROADCAST  0x20
111
15
#define MESSAGE_HEADER_FLAG_COMPRESSED        0x40
112
15
#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
15
#define WHOHAS_T 0x08
131
15
#define WHOHAS_U 0x04
132
15
#define WHOHAS_S 0x02
133
15
#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
15
#define ISAT_C 0x10
146
1.01k
#define ISAT_G 0x20
147
148
/* Bitmasks for v0 IS-AT messages. */
149
506
#define ISAT_F 0x01
150
506
#define ISAT_S 0x02
151
15
#define ISAT_U 0x04
152
15
#define ISAT_T 0x08
153
154
/* Bitmasks for v1 IS-AT messages. */
155
524
#define ISAT_U6 0x01
156
524
#define ISAT_R6 0x02
157
524
#define ISAT_U4 0x04
158
524
#define ISAT_R4 0x08
159
160
/* Bitmasks for v1 transports. */
161
15
#define TRANSPORT_LOCAL     0x0001  /* Local (same device) transport. */
162
15
#define TRANSPORT_BLUETOOTH 0x0002  /* Bluetooth transport. */
163
15
#define TRANSPORT_TCP       0x0004  /* Transport using TCP (same as TRANSPORT_WLAN). */
164
15
#define TRANSPORT_WWAN      0x0008  /* Wireless wide-area network transport. */
165
15
#define TRANSPORT_LAN       0x0010  /* Wired local-area network transport. */
166
15
#define TRANSPORT_ICE       0x0020  /* Transport using ICE protocol. */
167
15
#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
9
#define ARDP_SYN_FIXED_HDR_LEN  28 /* Size of the fixed part for the ARDP connection packet header. */
209
65
#define ARDP_FIXED_HDR_LEN      34 /* Size of the fixed part for the ARDP header. */
210
156
#define ARDP_DATA_LENGTH_OFFSET  6 /* Offset into the ARDP header for the data length. */
211
208
#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
203
#define ARDP_SYN 0x01
216
72
#define ARDP_ACK 0x02
217
72
#define ARDP_EAK 0x04
218
72
#define ARDP_RST 0x08
219
72
#define ARDP_NUL 0x10
220
15
#define ARDP_UNUSED 0x20
221
15
#define ARDP_VER0 0x40
222
15
#define ARDP_VER1 0x80
223
15
#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
2
#define ROUND_TO_2BYTE(len) WS_ROUNDUP_2(len)
271
286
#define ROUND_TO_4BYTE(len) WS_ROUNDUP_4(len)
272
693
#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
706
#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
208
#define HDR_REPLY_SERIAL          0x05
309
#define HDR_DESTINATION           0x06
310
#define HDR_SENDER                0x07
311
3
#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
2
{
351
2
    int length = current_offset - starting_offset;
352
353
2
    return starting_offset + ROUND_TO_2BYTE(length);
354
2
}
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
286
{
367
286
    int length = current_offset - starting_offset;
368
369
286
    return starting_offset + ROUND_TO_4BYTE(length);
370
286
}
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
541
{
383
541
    unsigned length = current_offset - starting_offset;
384
385
541
    return starting_offset + ROUND_TO_8BYTE(length);
386
541
}
387
388
/* This is the maximum number of rounding bytes that is ever used.
389
 * This define is used for error checking. */
390
44
#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
40
{
411
40
    uint8_t the_one_byte;
412
413
40
    the_one_byte = tvb_get_uint8(tvb, offset);
414
415
40
    if(0 == the_one_byte) {
416
12
        col_set_str(pinfo->cinfo, COL_INFO, "CONNECT-initial byte");
417
418
        /* Now add the value as a subtree to the initial byte. */
419
12
        proto_tree_add_item(message_tree, hf_alljoyn_connect_byte_value, tvb, offset, 1, ENC_NA);
420
12
        offset += 1;
421
12
    }
422
423
40
    return offset;
424
40
}
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
132
{
460
132
    int command_index;
461
462
1.02k
    for(command_index = 0; command_index < sasl_commands_count; command_index++) {
463
908
        const sasl_cmd *cmd;
464
465
908
        cmd = &sasl_commands[command_index];
466
467
908
        if(0 == tvb_strneql(tvb, offset, cmd->text, cmd->length)) {
468
11
            return cmd;
469
11
        }
470
908
    }
471
472
121
    return NULL;
473
132
}
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
91
{
484
91
    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
91
    return false;
492
91
}
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
39
{
512
39
    int             return_value = offset;
513
39
    const sasl_cmd *command;
514
515
39
    command = find_sasl_command(tvb, offset);
516
517
39
    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
39
    return return_value;
548
39
}
549
550
326
#define ENC_ALLJOYN_BAD_ENCODING 0xBADF00D
551
552
293
#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
219
{
565
219
    uint8_t endianness;
566
219
    unsigned  encoding;
567
568
    /* The endianness field. */
569
219
    endianness = tvb_get_uint8(tvb, offset + ENDIANNESS_OFFSET);
570
571
219
    switch(endianness)
572
219
    {
573
2
    case 'l':
574
2
        encoding = ENC_LITTLE_ENDIAN;
575
2
        break;
576
110
    case 'B':
577
110
        encoding = ENC_BIG_ENDIAN;
578
110
        break;
579
107
    default:
580
107
        encoding = ENC_ALLJOYN_BAD_ENCODING;
581
107
        break;
582
219
    }
583
584
219
    return encoding;
585
219
}
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
416
{
600
416
    proto_item *item;
601
416
    uint8_t     byte_value;
602
603
416
    item = proto_tree_add_item(field_tree, hf_alljoyn_uint8, tvb, offset, 1, ENC_NA);
604
416
    byte_value = tvb_get_uint8(tvb, offset);
605
606
416
    if(expected_value == byte_value) {
607
75
        proto_item_set_text(item, "0x%02x byte", expected_value);
608
341
    } else {
609
341
        proto_item_set_text(item, "Expected '0x%02x byte' but found '0x%02x'", expected_value, byte_value);
610
341
    }
611
416
}
612
613
/*
614
 * Message argument types
615
 */
616
180
#define ARG_INVALID           '\0'
617
708
#define ARG_ARRAY             'a'    /* AllJoyn array container type */
618
0
#define ARG_BOOLEAN           'b'    /* AllJoyn boolean basic type */
619
0
#define ARG_DOUBLE            'd'    /* AllJoyn IEEE 754 double basic type */
620
4
#define ARG_SIGNATURE         'g'    /* AllJoyn signature basic type */
621
24
#define ARG_HANDLE            'h'    /* AllJoyn socket handle basic type */
622
259
#define ARG_INT32             'i'    /* AllJoyn 32-bit signed integer basic type */
623
1
#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
1
#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
1
#define ARG_UINT64            't'    /* AllJoyn 64-bit unsigned integer basic type */
628
1
#define ARG_UINT32            'u'    /* AllJoyn 32-bit unsigned integer basic type */
629
197
#define ARG_VARIANT           'v'    /* AllJoyn variant container type */
630
7
#define ARG_INT64             'x'    /* AllJoyn 64-bit signed integer basic type */
631
71
#define ARG_BYTE              'y'    /* AllJoyn 8-bit unsigned integer basic type */
632
302
#define ARG_STRUCT            '('    /* AllJoyn struct container type */
633
302
#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
153
{
660
153
    switch(type)
661
153
    {
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
151
    case ARG_DICT_ENTRY:
670
151
        offset = round_to_8byte(offset, field_starting_offset);
671
151
        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
153
    }
702
703
153
    if(offset > max_offset) {
704
0
        offset = max_offset;
705
0
    }
706
707
153
    return offset;
708
153
}
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
151
{
723
151
    int    depth            = 0;
724
151
    uint8_t type_start;
725
151
    int    signature_length = 0;
726
151
    char c;
727
728
151
    proto_item_append_text(item, "%c", ' ');
729
151
    type_start = *signature;
730
731
15.8k
    do {
732
15.8k
        if(type_start == *signature) {
733
2.96k
            depth++;
734
2.96k
        }
735
736
15.8k
        if(type_stop == *signature) {
737
0
            depth--;
738
0
        }
739
740
15.8k
        c = *signature++;
741
15.8k
        proto_item_append_text(item, "%c", g_ascii_isprint(c) ? c : '?');
742
15.8k
    } while(depth > 0 && ++signature_length < signature_max_length);
743
744
151
    if(signature_length >= signature_max_length) {
745
151
        proto_item_append_text(item, "... Invalid signature!");
746
151
    }
747
151
}
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
649
{
834
649
    if(padding_end > padding_start && padding_end < tvb_reported_length(tvb)) {
835
44
        int padding_length = padding_end - padding_start;
836
837
44
        if (padding_length <= MAX_ROUND_TO_BYTES) {
838
44
            proto_tree_add_item(tree, hf_padding, tvb, padding_start, padding_length, ENC_NA);
839
44
        }
840
44
    }
841
649
}
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
917
{
886
917
    unsigned length;
887
917
    int padding_start;
888
917
    unsigned saved_offset = offset;
889
890
917
    switch(type_id)
891
917
    {
892
180
    case ARG_INVALID:
893
180
        offset = round_to_8byte(offset + 1, field_starting_offset);
894
180
        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
0
    case ARG_DOUBLE:     /* AllJoyn IEEE 754 double basic type */
987
0
        padding_start = offset;
988
0
        offset = round_to_8byte(offset, field_starting_offset);
989
0
        add_padding_item(padding_start, offset, tvb, field_tree);
990
991
0
        proto_tree_add_item(field_tree, hf_alljoyn_double, tvb, offset, 8, encoding);
992
0
        offset += 8;
993
0
        break;
994
995
4
    case ARG_SIGNATURE:  /* AllJoyn signature basic type */
996
4
        length = tvb_get_uint8(tvb, offset);
997
998
4
        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
3
        length++;
1008
1009
3
        proto_tree_add_item(field_tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding);
1010
3
        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
3
        proto_tree_add_item_ret_string(field_tree, hf_alljoyn_mess_body_signature, tvb, offset, length, ENC_ASCII|ENC_NA, pinfo->pool, signature);
1015
3
        *signature_length = length;
1016
1017
3
        if(HDR_SIGNATURE == field_code) {
1018
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", *signature);
1019
0
        }
1020
1021
3
        offset += length;
1022
3
        break;
1023
1024
24
    case ARG_HANDLE:     /* AllJoyn socket handle basic type. */
1025
24
        padding_start = offset;
1026
24
        offset = round_to_4byte(offset, field_starting_offset);
1027
24
        add_padding_item(padding_start, offset, tvb, field_tree);
1028
1029
24
        proto_tree_add_item(field_tree, hf_alljoyn_handle, tvb, offset, 4, encoding);
1030
24
        offset += 4;
1031
24
        break;
1032
1033
259
    case ARG_INT32:      /* AllJoyn 32-bit signed integer basic type. */
1034
259
        padding_start = offset;
1035
259
        offset = round_to_4byte(offset, field_starting_offset);
1036
259
        add_padding_item(padding_start, offset, tvb, field_tree);
1037
1038
259
        proto_tree_add_item(field_tree, hf_alljoyn_int32, tvb, offset, 4, encoding);
1039
259
        offset += 4;
1040
259
        break;
1041
1042
1
    case ARG_INT16:      /* AllJoyn 16-bit signed integer basic type. */
1043
1
        padding_start = offset;
1044
1
        offset = round_to_2byte(offset, field_starting_offset);
1045
1
        add_padding_item(padding_start, offset, tvb, field_tree);
1046
1047
1
        proto_tree_add_item(field_tree, hf_alljoyn_int16, tvb, offset, 2, encoding);
1048
1
        offset += 2;
1049
1
        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
1
    case ARG_UINT16:     /* AllJoyn 16-bit unsigned integer basic type */
1070
1
        padding_start = offset;
1071
1
        offset = round_to_2byte(offset, field_starting_offset);
1072
1
        add_padding_item(padding_start, offset, tvb, field_tree);
1073
1074
1
        proto_tree_add_item(field_tree, hf_alljoyn_uint16, tvb, offset, 2, encoding);
1075
1
        offset += 2;
1076
1
        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
0
        proto_tree_add_item(field_tree, hf_alljoyn_string_size_32bit, tvb, offset, 4, encoding);
1087
1088
        /* Get the length so we can display the string. */
1089
0
        length = tvb_get_uint32(tvb, offset, encoding);
1090
1091
0
        if(length > tvb_reported_length_remaining(tvb, offset)) {
1092
0
            col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: String length is %d. Remaining packet length is %d.",
1093
0
                length, tvb_reported_length_remaining(tvb, offset));
1094
0
            return tvb_reported_length(tvb);
1095
0
        }
1096
1097
0
        length += 1;    /* Include the '\0'. */
1098
0
        offset += 4;
1099
1100
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);
1101
1102
0
        if(HDR_MEMBER == field_code) {
1103
0
            col_append_fstr(pinfo->cinfo, COL_INFO, " %s", member_name);
1104
0
        }
1105
1106
0
        offset += length;
1107
0
        }
1108
0
        break;
1109
1110
1
    case ARG_UINT64:     /* AllJoyn 64-bit unsigned integer basic type */
1111
1
        padding_start = offset;
1112
1
        offset = round_to_8byte(offset, field_starting_offset);
1113
1
        add_padding_item(padding_start, offset, tvb, field_tree);
1114
1115
1
        proto_tree_add_item(field_tree, hf_alljoyn_uint64, tvb, offset, 8, encoding);
1116
1
        offset += 8;
1117
1
        break;
1118
1119
1
    case ARG_UINT32:     /* AllJoyn 32-bit unsigned integer basic type */
1120
1
        padding_start = offset;
1121
1
        offset = round_to_4byte(offset, field_starting_offset);
1122
1
        add_padding_item(padding_start, offset, tvb, field_tree);
1123
1124
1
        if(is_reply_to) {
1125
0
            static const char format[] = " Replies to: %09u";
1126
0
            uint32_t replies_to;
1127
1128
0
            replies_to = tvb_get_uint32(tvb, offset, encoding);
1129
0
            col_append_fstr(pinfo->cinfo, COL_INFO, format, replies_to);
1130
1131
0
            if(header_item) {
1132
0
                proto_item *item;
1133
1134
0
                item = proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding);
1135
0
                proto_item_set_text(item, format + 1, replies_to);
1136
0
            }
1137
1
        } else {
1138
1
            proto_tree_add_item(field_tree, hf_alljoyn_uint32, tvb, offset, 4, encoding);
1139
1
        }
1140
1141
1
        offset += 4;
1142
1
        break;
1143
1144
197
    case ARG_VARIANT:    /* AllJoyn variant container type */
1145
197
        {
1146
197
            proto_item   *item;
1147
197
            proto_tree   *tree;
1148
197
            const uint8_t *sig_saved;
1149
197
            const uint8_t *sig_pointer;
1150
197
            uint8_t       variant_sig_length;
1151
1152
197
            variant_sig_length = tvb_get_uint8(tvb, offset);
1153
197
            length = variant_sig_length;
1154
1155
197
            if(length > tvb_reported_length_remaining(tvb, offset)) {
1156
4
                int bytes_left = tvb_reported_length_remaining(tvb, offset);
1157
1158
4
                col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Variant signature length is %d. Only %d bytes left in packet.",
1159
4
                             length, bytes_left);
1160
4
                offset = tvb_reported_length(tvb);
1161
4
            }
1162
1163
197
            length += 1;    /* Include the terminating '\0'. */
1164
1165
            /* This length (4) will be updated later with the length of the entire variant object. */
1166
197
            item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_variant, tvb, offset, 4, encoding);
1167
197
            tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters);
1168
1169
197
            proto_tree_add_item(tree, hf_alljoyn_mess_body_signature_length, tvb, offset, 1, encoding);
1170
1171
197
            offset += 1;
1172
1173
197
            tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters);
1174
197
            proto_tree_add_item_ret_string(tree, hf_alljoyn_mess_body_signature, tvb, offset, length, ENC_ASCII|ENC_NA, pinfo->pool, &sig_saved);
1175
1176
197
            offset += length;
1177
197
            sig_pointer = sig_saved;
1178
1179
197
            increment_dissection_depth(pinfo);
1180
1181
            /* The signature of the variant has now been taken care of.  So now take care of the variant data. */
1182
758
            while(((unsigned)(sig_pointer - sig_saved) < (length - 1)) && (tvb_reported_length_remaining(tvb, offset) > 0)) {
1183
561
                proto_item_append_text(item, "%c", g_ascii_isprint(*sig_pointer) ? *sig_pointer : '?');
1184
1185
561
                offset = parse_arg(tvb, pinfo, header_item, encoding, offset, tree, is_reply_to,
1186
561
                                   *sig_pointer, field_code, &sig_pointer, &variant_sig_length, field_starting_offset);
1187
1188
561
            }
1189
1190
197
            decrement_dissection_depth(pinfo);
1191
197
            proto_item_append_text(item, "'");
1192
197
            proto_item_set_end(item, tvb, offset);
1193
197
        }
1194
197
        break;
1195
1196
7
    case ARG_INT64:      /* AllJoyn 64-bit signed integer basic type */
1197
7
        padding_start = offset;
1198
7
        offset = round_to_8byte(offset, field_starting_offset);
1199
7
        add_padding_item(padding_start, offset, tvb, field_tree);
1200
1201
7
        proto_tree_add_item(field_tree, hf_alljoyn_int64, tvb, offset, 8, encoding);
1202
7
        offset += 8;
1203
7
        break;
1204
1205
71
    case ARG_BYTE:       /* AllJoyn 8-bit unsigned integer basic type */
1206
1207
71
        proto_tree_add_item(field_tree, hf_alljoyn_uint8, tvb, offset, 1, encoding);
1208
71
        offset += 1;
1209
71
        break;
1210
1211
151
    case ARG_DICT_ENTRY: /* AllJoyn dictionary or map container type - an array of key-value pairs */
1212
151
    case ARG_STRUCT:     /* AllJoyn struct container type */
1213
151
        {
1214
151
            proto_item *item;
1215
151
            proto_tree *tree;
1216
151
            int         hf;
1217
151
            uint8_t     type_stop;
1218
1219
151
            if(type_id == ARG_STRUCT) {
1220
0
                hf = hf_alljoyn_mess_body_structure;
1221
0
                type_stop = ')';
1222
151
            } else {
1223
151
                hf = hf_alljoyn_mess_body_dictionary_entry;
1224
151
                type_stop = '}';
1225
151
            }
1226
1227
151
            if(*signature == NULL || *signature_length < 1) {
1228
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"));
1229
0
                return tvb_reported_length(tvb);
1230
0
            }
1231
1232
            /* This length (4) will be updated later with the length of the entire struct. */
1233
151
            item = proto_tree_add_item(field_tree, hf, tvb, offset, 4, encoding);
1234
151
            append_struct_signature(item, *signature, *signature_length, type_stop);
1235
151
            tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters);
1236
1237
151
            padding_start = offset;
1238
151
            offset = pad_according_to_type(offset, field_starting_offset, tvb_reported_length(tvb), type_id);
1239
151
            add_padding_item(padding_start, offset, tvb, tree);
1240
1241
151
            (*signature)++; /* Advance past the '(' or '{'. */
1242
151
            (*signature_length)--;
1243
1244
151
            increment_dissection_depth(pinfo);
1245
1246
            /* *signature should never be NULL but just make sure to avoid potential issues. */
1247
298
            while(*signature && **signature && **signature != type_stop
1248
165
                    && tvb_reported_length_remaining(tvb, offset) > 0) {
1249
147
                offset = parse_arg(tvb,
1250
147
                                   pinfo,
1251
147
                                   header_item,
1252
147
                                   encoding,
1253
147
                                   offset,
1254
147
                                   tree,
1255
147
                                   is_reply_to,
1256
147
                                   **signature,
1257
147
                                   field_code,
1258
147
                                   signature,
1259
147
                                   signature_length,
1260
147
                                   field_starting_offset);
1261
147
            }
1262
1263
151
            decrement_dissection_depth(pinfo);
1264
1265
151
            proto_item_set_end(item, tvb, offset);
1266
151
        }
1267
0
        break;
1268
1269
17
    default:
1270
        /* Just say we are done with this packet. */
1271
17
        offset = tvb_reported_length(tvb);
1272
17
        break;
1273
917
    }
1274
1275
901
    if (*signature && *signature_length > 0 && ARG_ARRAY != type_id && HDR_INVALID == field_code) {
1276
2
        (*signature)++;
1277
2
        (*signature_length)--;
1278
2
    }
1279
1280
    /* Make sure we never return something longer than the buffer for an offset. */
1281
901
    if(offset > tvb_reported_length(tvb)) {
1282
4
        offset = tvb_reported_length(tvb);
1283
897
    } else if (offset == saved_offset) {
1284
        /* The argument has a null size. Let's report the packet length to avoid an infinite loop. */
1285
        /*expert_add_info(pinfo, header_item, &ei_alljoyn_empty_arg);*/
1286
4
        proto_tree_add_expert(field_tree, pinfo, &ei_alljoyn_empty_arg, tvb, offset, 0);
1287
4
        offset = tvb_reported_length(tvb);
1288
4
    }
1289
1290
901
    return offset;
1291
917
}
1292
1293
/* This is called by handle_message_header_fields() to handle a single
1294
 * message header field.
1295
 * @param tvb is the incoming network data buffer.
1296
 * @param pinfo contains information about the incoming packet which
1297
 *         we update as we dissect the packet.
1298
 * @param header_tree is the subtree that we connect data items to.
1299
 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN)
1300
 * @param offset is the offset into tvb to get the field from.
1301
 *         endianness.
1302
 * @param signature pointer to the signature of the parameters. This is a return
1303
 *         value for the caller to pass to the function that parses the parameters.
1304
 * @param signature_length pointer to the length of the signature. This is a return
1305
 *         value for the caller to pass to the function that parses the parameters.
1306
 * @return The new offset into the buffer after removing the field code and value.
1307
 *         the message.
1308
 */
1309
static unsigned
1310
handle_message_field(tvbuff_t      *tvb,
1311
                     packet_info   *pinfo,
1312
                     proto_item    *header_tree,
1313
                     unsigned       encoding,
1314
                     unsigned        offset,
1315
                     const uint8_t **signature,
1316
                     uint8_t       *signature_length)
1317
208
{
1318
208
    proto_tree *field_tree;
1319
208
    proto_item *item, *field_item;
1320
208
    uint8_t     field_code;
1321
208
    uint8_t     type_id;
1322
208
    bool        is_reply_to = false;
1323
208
    int         starting_offset = offset;
1324
208
    int         padding_start;
1325
1326
208
    field_code = tvb_get_uint8(tvb, offset);
1327
1328
208
    if(HDR_REPLY_SERIAL == field_code) {
1329
0
        is_reply_to = true;
1330
0
    }
1331
1332
208
    field_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_field, tvb, offset, 1, ENC_NA);
1333
208
    field_tree = proto_item_add_subtree(field_item, ett_alljoyn_mess_header_field);
1334
1335
208
    proto_tree_add_item(field_tree, hf_alljoyn_mess_body_header_fieldcode, tvb, offset, 1, ENC_NA);
1336
208
    offset += 1;
1337
1338
    /* We expect a byte of 0x01 here. */
1339
208
    handle_message_header_expected_byte(tvb, offset, field_tree, 0x01);
1340
208
    offset += 1;
1341
1342
208
    item = proto_tree_add_item(field_tree, hf_alljoyn_mess_body_header_typeid, tvb, offset, 1, ENC_ASCII);
1343
208
    type_id = tvb_get_uint8(tvb, offset);
1344
208
    offset += 1;
1345
1346
    /* We expect a byte of 0x00 here. */
1347
208
    handle_message_header_expected_byte(tvb, offset, field_tree, 0x00);
1348
208
    offset += 1;
1349
1350
208
    offset = parse_arg(tvb,
1351
208
                       pinfo,
1352
208
                       item,
1353
208
                       encoding,
1354
208
                       offset,
1355
208
                       field_tree,
1356
208
                       is_reply_to,
1357
208
                       type_id,
1358
208
                       field_code,
1359
208
                       signature,
1360
208
                       signature_length,
1361
208
                       starting_offset);
1362
1363
208
    padding_start = offset;
1364
208
    offset = round_to_8byte(offset, starting_offset);
1365
208
    add_padding_item(padding_start, offset, tvb, field_tree);
1366
1367
208
    if(offset > tvb_reported_length(tvb)) {
1368
26
        offset = tvb_reported_length(tvb);
1369
26
    }
1370
1371
208
    proto_item_set_end(field_tree, tvb, offset);
1372
1373
208
    return offset;
1374
208
}
1375
1376
/* This is called by handle_message() to handle the message body.
1377
 * @param tvb is the incoming network data buffer.
1378
 * @param pinfo contains information about the incoming packet which
1379
 *         we update as we dissect the packet.
1380
 * @param header_tree is the subtree that we connect data items to.
1381
 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN)
1382
 * @param offset contains the offset into tvb for the start of the header fields.
1383
 * @param header_length contains the length of the message fields.
1384
 * @param signature_length contains the signature field length.
1385
 */
1386
static const uint8_t *
1387
handle_message_header_fields(tvbuff_t    *tvb,
1388
                             packet_info *pinfo,
1389
                             proto_item  *header_tree,
1390
                             unsigned    encoding,
1391
                             int         offset,
1392
                             uint32_t    header_length,
1393
                             uint8_t     *signature_length)
1394
50
{
1395
50
    int         end_of_header;
1396
50
    proto_item *item;
1397
50
    proto_tree *tree;
1398
50
    const uint8_t *signature = NULL;
1399
1400
50
    item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_fields, tvb, offset, header_length, ENC_NA);
1401
50
    tree = proto_item_add_subtree(item, ett_alljoyn_mess_header);
1402
1403
50
    end_of_header = offset + header_length;
1404
1405
258
    while(offset < end_of_header) {
1406
208
        offset = handle_message_field(tvb, pinfo, tree, encoding, offset, &signature, signature_length);
1407
208
    }
1408
1409
50
    return signature;
1410
50
}
1411
1412
/* This is called by handle_message() to handle the message body.
1413
 * @param tvb is the incoming network data buffer.
1414
 * @param header_tree is the subtree that we connect data items to.
1415
 * @param encoding indicates big (ENC_BIG_ENDIAN) or little (ENC_LITTLE_ENDIAN)
1416
 * @param offset contains the offset into tvb for the start of the parameters.
1417
 * @param body_length contains the length of the body parameters.
1418
 * @param signature the signature of the parameters.
1419
 * @param signature_length contains the signature field length.
1420
 */
1421
static int
1422
handle_message_body_parameters(tvbuff_t     *tvb,
1423
                               packet_info  *pinfo,
1424
                               proto_tree   *header_tree,
1425
                               unsigned      encoding,
1426
                               int           offset,
1427
                               int32_t       body_length,
1428
                               const uint8_t *signature,
1429
                               uint8_t       signature_length)
1430
1
{
1431
1
    int         packet_length, end_of_body;
1432
1
    proto_tree *tree;
1433
1
    proto_item *item;
1434
1
    const int   starting_offset = offset;
1435
1436
1
    packet_length = tvb_reported_length(tvb);
1437
1438
    /* Add a subtree/row for the message body parameters. */
1439
1
    item = proto_tree_add_item(header_tree, hf_alljoyn_mess_body_parameters, tvb, offset, body_length, ENC_NA);
1440
1
    tree = proto_item_add_subtree(item, ett_alljoyn_mess_body_parameters);
1441
1442
1
    end_of_body = offset + body_length;
1443
1444
1
    if(end_of_body > packet_length) {
1445
0
        end_of_body = packet_length;
1446
0
    }
1447
1448
2
    while(offset < end_of_body && signature_length > 0 && signature && *signature) {
1449
1
        offset = parse_arg(tvb,
1450
1
                           pinfo,
1451
1
                           NULL,
1452
1
                           encoding,
1453
1
                           offset,
1454
1
                           tree,    /* Add the args to the Parameters tree. */
1455
1
                           false,
1456
1
                           *signature,
1457
1
                           HDR_INVALID,
1458
1
                           &signature,
1459
1
                           &signature_length,
1460
1
                           starting_offset);
1461
1
    }
1462
1463
1
    return offset;
1464
1
}
1465
1466
260
#define MESSAGE_HEADER_LENGTH   16
1467
100
#define TYPE_OFFSET              1
1468
400
#define FLAGS_OFFSET             2
1469
50
#define MAJORVERSION_OFFSET      3
1470
102
#define BODY_LENGTH_OFFSET       4
1471
100
#define SERIAL_OFFSET            8
1472
102
#define HEADER_LENGTH_OFFSET    12
1473
1474
/* This is called by dissect_AllJoyn_message() to handle the actual message.
1475
 * If it was a message with valid header and optional body then return true.
1476
 * If not a valid message return false.
1477
 * @param tvb is the incoming network data buffer.
1478
 * @param pinfo contains information about the incoming packet.
1479
 * @param offset is the offset into the packet to start processing.
1480
 * @param message_tree is the subtree that any connect data items should be added to.
1481
 * @param is_ardp is true if this is an ARDP packet.
1482
 * @returns the offset into the packet that has successfully been handled or
1483
 *         the input offset value if it was not a message header body.
1484
 */
1485
static int
1486
handle_message_header_body(tvbuff_t    *tvb,
1487
                           packet_info *pinfo,
1488
                           int          offset,
1489
                           proto_item  *message_tree,
1490
                           bool        is_ardp)
1491
78
{
1492
78
    int           remaining_packet_length;
1493
78
    const uint8_t *signature;
1494
78
    uint8_t       signature_length = 0;
1495
78
    proto_tree   *header_tree, *flag_tree;
1496
78
    proto_item   *header_item, *flag_item;
1497
78
    unsigned      encoding;
1498
78
    int           packet_length_needed;
1499
78
    int           header_length = 0, body_length = 0;
1500
1501
78
    remaining_packet_length = tvb_reported_length_remaining(tvb, offset);
1502
78
    encoding = get_message_header_endianness(tvb, offset);
1503
1504
78
    if(ENC_ALLJOYN_BAD_ENCODING == encoding) {
1505
24
        col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Endian encoding '0x%0x'. Expected 'l' or 'B'",
1506
24
            tvb_get_uint8(tvb, offset + ENDIANNESS_OFFSET));
1507
1508
        /* We are done with everything in this packet don't try anymore. */
1509
24
        return offset + remaining_packet_length;
1510
24
    }
1511
1512
54
    if(remaining_packet_length < MESSAGE_HEADER_LENGTH) {
1513
2
        if(!set_pinfo_desegment(pinfo, offset, MESSAGE_HEADER_LENGTH - remaining_packet_length)) {
1514
2
            col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %d. Expected >= %d && <= %d",
1515
2
            remaining_packet_length, MESSAGE_HEADER_LENGTH, MAX_PACKET_LEN);
1516
2
        }
1517
1518
2
        return offset + remaining_packet_length;
1519
2
    }
1520
1521
52
    header_length = tvb_get_uint32(tvb, offset + HEADER_LENGTH_OFFSET, encoding);
1522
52
    body_length = tvb_get_uint32(tvb, offset + BODY_LENGTH_OFFSET, encoding);
1523
52
    packet_length_needed = ROUND_TO_8BYTE(header_length) + body_length + MESSAGE_HEADER_LENGTH;
1524
1525
    /* ARDP (UDP) packets can't be desegmented by Wireshark and it is normal to see them in
1526
     * fragments. Don't scare the user when they occur. Dissect as much as we easily can.
1527
     * It should be possible to desegment TCIP packets. If not then something is wrong so tell
1528
     * the user.
1529
     */
1530
52
    if(packet_length_needed > remaining_packet_length) {
1531
33
        if(!set_pinfo_desegment(pinfo, offset, packet_length_needed - remaining_packet_length)) {
1532
33
            if(!is_ardp) {
1533
1
                col_add_fstr(pinfo->cinfo, COL_INFO, "BAD DATA: Remaining packet length is %d. Expected %d",
1534
1
                    remaining_packet_length, packet_length_needed);
1535
1536
1
                return offset + remaining_packet_length;
1537
1
            }
1538
1539
            /* In this case we can't desegment but it is an ARDP message so we want to dissect
1540
             * at least the header. Therefore we fall through to the header parsing code if the packet size
1541
             * is greater than or equal to the header size. Otherwise we return and report what we know.
1542
             */
1543
32
            if (remaining_packet_length < header_length) {
1544
1
                col_add_fstr(pinfo->cinfo, COL_INFO, "Fragmented ARDP message: Remaining packet length is %d. Expected %d",
1545
1
                    remaining_packet_length, packet_length_needed);
1546
1
                return offset + remaining_packet_length;
1547
1
            }
1548
32
        }
1549
0
        else {
1550
            /* In this case we can desegment */
1551
0
            return offset + remaining_packet_length;
1552
0
        }
1553
33
    }
1554
1555
    /* Add a subtree/row for the header. */
1556
50
    header_item = proto_tree_add_item(message_tree, hf_alljoyn_mess_header, tvb, offset, MESSAGE_HEADER_LENGTH, ENC_NA);
1557
50
    header_tree = proto_item_add_subtree(header_item, ett_alljoyn_header);
1558
1559
50
    proto_tree_add_item(header_tree, hf_alljoyn_mess_header_endian, tvb, offset + ENDIANNESS_OFFSET, 1, ENC_ASCII);
1560
50
    proto_tree_add_item(header_tree, hf_alljoyn_mess_header_type, tvb, offset + TYPE_OFFSET, 1, ENC_NA);
1561
1562
    /* The flags byte. */
1563
50
    flag_item = proto_tree_add_item(header_tree, hf_alljoyn_mess_header_flags,    tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1564
50
    flag_tree = proto_item_add_subtree(flag_item, ett_alljoyn_header_flags);
1565
1566
    /* Now the individual bits. */
1567
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_encrypted,        tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1568
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_compressed,       tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1569
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_global_broadcast, tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1570
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_sessionless,      tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1571
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_allow_remote_msg, tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1572
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_no_auto_start,    tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1573
50
    proto_tree_add_item(flag_tree, hf_alljoyn_mess_header_flags_no_reply,         tvb, offset + FLAGS_OFFSET, 1, ENC_NA);
1574
1575
50
    proto_tree_add_item(header_tree, hf_alljoyn_mess_header_majorversion,         tvb, offset + MAJORVERSION_OFFSET, 1, ENC_NA);
1576
50
    proto_tree_add_item(header_tree, hf_alljoyn_mess_header_body_length,          tvb, offset + BODY_LENGTH_OFFSET, 4, encoding);
1577
1578
50
    proto_tree_add_item(header_tree, hf_alljoyn_mess_header_serial,               tvb, offset + SERIAL_OFFSET, 4, encoding);
1579
50
    col_add_fstr(pinfo->cinfo, COL_INFO, "Message %010u: '%s'", tvb_get_uint32(tvb, offset + SERIAL_OFFSET, encoding),
1580
50
            val_to_str_const(tvb_get_uint8(tvb, offset + TYPE_OFFSET), message_header_encoding_vals, "Unexpected message type"));
1581
1582
50
    proto_tree_add_item(header_tree, hf_alljoyn_mess_header_header_length, tvb, offset + HEADER_LENGTH_OFFSET, 4, encoding);
1583
50
    offset += MESSAGE_HEADER_LENGTH;
1584
50
    packet_length_needed -= MESSAGE_HEADER_LENGTH;
1585
1586
50
    signature = handle_message_header_fields(tvb, pinfo, message_tree, encoding,
1587
50
                                             offset, header_length, &signature_length);
1588
    /* No need to call add_padding_item() after the following operation. It's not needed
1589
     * because all message header fields widths are multiples of 8 and are padded as necessary.
1590
     * Because the padding is taken care of in the individual message header field there is no
1591
     * need for it here. The rounding here just gets the offset to the end of the last header
1592
     * field and its (possible) padding.
1593
     */
1594
50
    offset += ROUND_TO_8BYTE(header_length);
1595
50
    packet_length_needed -= ROUND_TO_8BYTE(header_length);
1596
50
    remaining_packet_length = tvb_reported_length_remaining(tvb, offset);
1597
1598
50
    if (packet_length_needed > remaining_packet_length) {
1599
24
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Fragmented ARDP message or bad data: Remaining packet length is %d. Expected %d",
1600
24
            remaining_packet_length, packet_length_needed);
1601
24
        return offset + remaining_packet_length;
1602
24
    }
1603
1604
26
    if(body_length > 0 && signature != NULL && signature_length > 0) {
1605
1
        offset = handle_message_body_parameters(tvb,
1606
1
                                                pinfo,
1607
1
                                                message_tree,
1608
1
                                                encoding,
1609
1
                                                offset,
1610
1
                                                body_length,
1611
1
                                                signature,
1612
1
                                                signature_length);
1613
1
    }
1614
1615
26
    return offset;
1616
50
}
1617
1618
/* Test to see if this buffer contains something that might be an AllJoyn message.
1619
 * @param tvb is the incoming network data buffer.
1620
 * @param offset where to start parsing the buffer.
1621
 * @param is_ardp If true then this is an ARDP packet which needs special treatment.
1622
 * @returns true if probably an AllJoyn message.
1623
 *          false if probably not an AllJoyn message.
1624
 */
1625
static bool
1626
protocol_is_alljoyn_message(tvbuff_t *tvb, int offset, bool is_ardp)
1627
152
{
1628
152
    int length = tvb_captured_length(tvb);
1629
1630
152
    if(length < offset + 1)
1631
0
        return false;
1632
1633
    /* There is no initial connect byte or SASL when using ARDP. */
1634
152
    if(!is_ardp) {
1635
        /* initial byte for a connect message. */
1636
99
        if(tvb_get_uint8(tvb, offset) == 0)
1637
6
            return true;
1638
1639
93
        if(find_sasl_command(tvb, offset) != NULL)
1640
5
            return true;
1641
93
    }
1642
1643
141
    if(get_message_header_endianness(tvb, offset) == ENC_ALLJOYN_BAD_ENCODING)
1644
83
        return false;
1645
1646
58
    if((length < offset + 2) || (try_val_to_str(tvb_get_uint8(tvb, offset + 1), message_header_encoding_vals) == NULL))
1647
5
        return false;
1648
1649
53
    return true;
1650
58
}
1651
1652
/* This is called by Wireshark for packet types that are registered
1653
 * in the proto_reg_handoff_AllJoyn() function. This function handles
1654
 * the packets for the traffic on port 9955.
1655
 * @param tvb is the incoming network data buffer.
1656
 * @param pinfo contains information about the incoming packet which
1657
 *         we update as we dissect the packet.
1658
 * @param tree is the tree data items should be added to.
1659
 * @param offset is the offset into the already partial dissected buffer
1660
 *         from dissect_AllJoyn_ardp() or 0 because this is just a bare
1661
 *         AllJoyn message.
1662
 * @return 0 if not AllJoyn message protocol, or
1663
 *         the offset into the buffer we have successfully dissected (which
1664
 *         should normally be the packet length), or
1665
 *         the offset into the buffer we have dissected with
1666
 *         pinfo->desegment_len == additional bytes needed from the next packet
1667
 *         before we can dissect, or
1668
 *         0 with pinfo->desegment_len == DESEGMENT_ONE_MORE_SEGMENT if another
1669
 *         segment is needed, or
1670
 *         packet_length if "really bad" parameters come in.
1671
 */
1672
static int
1673
dissect_AllJoyn_message(tvbuff_t    *tvb,
1674
                        packet_info *pinfo,
1675
                        proto_tree  *tree,
1676
                        int         offset)
1677
64
{
1678
64
    proto_item *message_item;
1679
64
    proto_tree *message_tree;
1680
64
    int         last_offset = -1;
1681
64
    int         packet_length;
1682
64
    bool        is_ardp = false;
1683
1684
    /* If called after dissecting the ARDP protocol. This is the only time the offset will not be zero. */
1685
64
    if(offset != 0) {
1686
37
        is_ardp = true;
1687
37
    }
1688
1689
64
    pinfo->desegment_len = 0;
1690
64
    packet_length = tvb_reported_length(tvb);
1691
1692
64
    col_clear(pinfo->cinfo, COL_INFO);
1693
64
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN");
1694
1695
    /* Add a subtree covering the remainder of the packet */
1696
64
    message_item = proto_tree_add_item(tree, proto_AllJoyn_mess, tvb, offset, -1, ENC_NA);
1697
64
    message_tree = proto_item_add_subtree(message_item, ett_alljoyn_mess);
1698
1699
    /* Continue as long as we are making progress and we haven't finished with the packet. */
1700
142
    while(offset < packet_length && offset > last_offset) {
1701
79
        last_offset = offset;
1702
1703
        /* There is no initial connect byte or SASL when using ARDP. */
1704
79
        if(!is_ardp) {
1705
40
            offset = handle_message_connect(tvb, pinfo, offset, message_tree);
1706
1707
40
            if(offset >= packet_length) {
1708
1
                break;
1709
1
            }
1710
1711
39
            offset = handle_message_sasl(tvb, pinfo, offset, message_tree);
1712
1713
39
            if(offset >= packet_length) {
1714
0
                break;
1715
0
            }
1716
39
        }
1717
1718
78
        offset = handle_message_header_body(tvb, pinfo, offset, message_tree, is_ardp);
1719
78
    }
1720
1721
64
    return offset;
1722
64
}
1723
1724
static void
1725
ns_parse_questions(tvbuff_t *tvb, int* offset, proto_tree* alljoyn_tree, uint8_t questions, unsigned message_version)
1726
147
{
1727
834
    while(questions--) {
1728
687
        proto_item *alljoyn_questions_ti;
1729
687
        proto_tree *alljoyn_questions_tree;
1730
687
        unsigned    count;
1731
1732
687
        alljoyn_questions_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_ns_whohas, tvb, *offset, 2, ENC_NA); /* "Who-Has Message" */
1733
687
        alljoyn_questions_tree = proto_item_add_subtree(alljoyn_questions_ti, ett_alljoyn_whohas);
1734
1735
687
        if(0 == message_version) {
1736
307
            proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_t_flag, tvb, *offset, 1, ENC_NA);
1737
307
            proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_u_flag, tvb, *offset, 1, ENC_NA);
1738
307
            proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_s_flag, tvb, *offset, 1, ENC_NA);
1739
307
            proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_ns_whohas_f_flag, tvb, *offset, 1, ENC_NA);
1740
307
        }
1741
1742
687
        (*offset) += 1;
1743
1744
687
        proto_tree_add_item_ret_uint(alljoyn_questions_tree, hf_alljoyn_ns_whohas_count, tvb, *offset, 1, ENC_NA, &count);
1745
687
        (*offset) += 1;
1746
1747
1.95k
        while(count--) {
1748
1.26k
            proto_item *alljoyn_bus_name_ti;
1749
1.26k
            proto_tree *alljoyn_bus_name_tree;
1750
1.26k
            int         bus_name_size = 0;
1751
1752
1.26k
            bus_name_size = tvb_get_uint8(tvb, *offset);
1753
1754
1.26k
            alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_questions_tree, hf_alljoyn_string, tvb,
1755
1.26k
                *offset, 1 + bus_name_size, ENC_NA);
1756
1.26k
            alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_ns_string);
1757
1758
1.26k
            proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA);
1759
1.26k
            (*offset) += 1;
1760
1761
1.26k
            proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII);
1762
1.26k
            (*offset) += bus_name_size;
1763
1.26k
        }
1764
1765
687
    }
1766
147
}
1767
1768
/* The version 0 protocol looks like this:
1769
 * Byte 0:
1770
 *      Bit 0 (ISAT_F): If '1' indicates the daemon is listening on an IPv4
1771
 *      address and that an IPv4 address is present in the message.  If '0'
1772
 *      there is no IPv4 address present.
1773
 *
1774
 *      Bit 1 (ISAT_S): If '1' the responding daemon is listening on an IPv6
1775
 *      address and that an IPv6 address is present in the message.  If '0'
1776
 *      there is no IPv6 address present.
1777
 *
1778
 *      Bit 2 (ISAT_U): If '1' the daemon is listening on UDP.
1779
 *
1780
 *      Bit 3 (ISAT_T): If '1' the daemon is listening on TCP.
1781
 *
1782
 *      Bit 4 (ISAT_C): If '1' the list of StringData records is a complete
1783
 *      list of all well-known names exported by the daemon.
1784
 *
1785
 *      Bit 5 (ISAT_G): If '1' a variable length daemon GUID string is present.
1786
 *
1787
 *      Bits 6-7: The message type of the IS-AT message.  Defined to be '01' (1).
1788
 *
1789
 * Byte 1 (Count): The number of StringData items.  Each StringData item
1790
 * describes one well-known bus name supported by the daemon.
1791
 *
1792
 * Bytes 2-3 (Port): The port on which the daemon is listening.
1793
 *
1794
 * If the ISAT_F bit is set then the next four bytes is the IPv4 address on
1795
 * which the daemon is listening.
1796
 *
1797
 * If the ISAT_S bit is set then the next 16 bytes is the IPv6 address on
1798
 * which the daemon is listening.
1799
 *
1800
 * If the ISAT_G bit is set then the next data is daemon GUID StringData.
1801
 *
1802
 * The next data is a variable number of StringData records.
1803
 */
1804
static void
1805
ns_parse_answers_v0(tvbuff_t *tvb, int* offset, proto_tree* alljoyn_tree, uint8_t answers)
1806
48
{
1807
539
    while(answers--) {
1808
491
        proto_item *alljoyn_answers_ti;
1809
491
        proto_tree *alljoyn_answers_tree;
1810
491
        int         flags;
1811
491
        unsigned    count;
1812
1813
491
        alljoyn_answers_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_answer, tvb, *offset, 2, ENC_NA);
1814
491
        alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns_answers);
1815
1816
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag, tvb, *offset, 1, ENC_NA);
1817
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag, tvb, *offset, 1, ENC_NA);
1818
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_t_flag, tvb, *offset, 1, ENC_NA);
1819
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u_flag, tvb, *offset, 1, ENC_NA);
1820
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_s_flag, tvb, *offset, 1, ENC_NA);
1821
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_f_flag, tvb, *offset, 1, ENC_NA);
1822
491
        flags = tvb_get_uint8(tvb, *offset);
1823
491
        (*offset) += 1;
1824
1825
491
        proto_tree_add_item_ret_uint(alljoyn_answers_tree, hf_alljoyn_ns_isat_count,  tvb, *offset, 1, ENC_NA, &count);
1826
491
        (*offset) += 1;
1827
1828
491
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port,   tvb, *offset, 2, ENC_BIG_ENDIAN);
1829
491
        (*offset) += 2;
1830
1831
491
        if(flags & ISAT_S) {
1832
57
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA);
1833
57
            (*offset) += 16;
1834
57
        }
1835
1836
491
        if(flags & ISAT_F) {
1837
56
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_BIG_ENDIAN);
1838
56
            (*offset) += 4;
1839
56
        }
1840
1841
491
        if(flags & ISAT_G) {
1842
42
            proto_item *alljoyn_string_ti;
1843
42
            proto_tree *alljoyn_string_tree;
1844
42
            int         guid_size = 0;
1845
1846
42
            guid_size = tvb_get_uint8(tvb, *offset);
1847
1848
42
            alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_guid_string, tvb,
1849
42
                *offset, 1 + guid_size, ENC_NA);
1850
42
            alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns_guid_string);
1851
1852
42
            proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA);
1853
42
            (*offset) += 1;
1854
1855
42
            proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, *offset, guid_size, ENC_ASCII);
1856
42
            (*offset) += guid_size;
1857
42
        }
1858
1859
1.23k
        while(count--) {
1860
742
            proto_item *alljoyn_entry_ti;
1861
742
            proto_tree *alljoyn_entry_tree;
1862
742
            proto_item *alljoyn_bus_name_ti;
1863
742
            proto_tree *alljoyn_bus_name_tree;
1864
742
            int         bus_name_size = tvb_get_uint8(tvb, *offset);
1865
1866
742
            alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_entry, tvb,
1867
742
                *offset, 1 + bus_name_size, ENC_NA);
1868
742
            alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_ns_isat_entry);
1869
1870
742
            alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, hf_alljoyn_string, tvb, *offset,
1871
742
                1 + bus_name_size, ENC_NA);
1872
742
            alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_string);
1873
1874
742
            proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA);
1875
742
            (*offset) += 1;
1876
1877
742
            proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII);
1878
742
            (*offset) += bus_name_size;
1879
742
        }
1880
491
    }
1881
48
}
1882
1883
/* The version 1 protocol looks like this:
1884
 * Byte 0:
1885
 *      Bit 0 (ISAT_U6): If '1' then the IPv6 endpoint of an unreliable method
1886
 *      (UDP) transport (IP address and port) is present.
1887
 *
1888
 *      Bit 1 (ISAT_R6): If '1' then the IPv6 endpoint of a reliable method
1889
 *      (TCP) transport (IP address and port) is present.
1890
 *
1891
 *      Bit 2 (ISAT_U4): If '1' then the IPv4 endpoint of an unreliable method
1892
 *      (UDP) transport (IP address and port) is present.
1893
 *
1894
 *      Bit 3 (ISAT_R4): If '1' then the IPv4 endpoint of a reliable method
1895
 *      (TCP) transport (IP address and port) is present.
1896
 *
1897
 *      Bit 4 (ISAT_C): If '1' the list of StringData records is a complete
1898
 *      list of all well-known names exported by the daemon.
1899
 *
1900
 *      Bit 5 (ISAT_G): If '1' a variable length daemon GUID string is present.
1901
 *
1902
 *      Bits 6-7: The message type of the IS-AT message.  Defined to be '01' (1).
1903
 *
1904
 * Byte 1 (Count): The number of StringData items.  Each StringData item
1905
 * describes one well-known bus name supported by the daemon.
1906
 *
1907
 * Bytes 2-3 (TransportMask): The bit mask of transport identifiers that
1908
 * indicates which AllJoyn transport is making the advertisement.
1909
 *
1910
 * If the ISAT_R4 bit is set then the next four bytes is the IPv4 address on
1911
 * which the daemon is listening.
1912
 *
1913
 * If the ISAT_R4 bit is set then the next two bytes is the IPv4 port on
1914
 * which the daemon is listening.
1915
 *
1916
 * If the ISAT_R6 bit is set then the next 16 bytes is the IPv6 address on
1917
 * which the daemon is listening for TCP traffic.
1918
 *
1919
 * If the ISAT_R6 bit is set then the next two bytes is the IPv6 port on
1920
 * which the daemon is listening for TCP traffic.
1921
 *
1922
 * If the ISAT_U6 bit is set then the next 16 bytes is the IPv6 address on
1923
 * which the daemon is listening for UDP traffic.
1924
 *
1925
 * If the ISAT_U6 bit is set then the next two bytes is the IPv6 port on
1926
 * which the daemon is listening for UDP traffic.
1927
 *
1928
 * If the ISAT_G bit is set then the next data is daemon GUID StringData.
1929
 *
1930
 * The next data is a variable number of StringData records.
1931
 */
1932
static void
1933
ns_parse_answers_v1(tvbuff_t *tvb, int* offset, proto_tree* alljoyn_tree, uint8_t answers)
1934
52
{
1935
561
    while(answers--) {
1936
509
        proto_item *alljoyn_answers_ti;
1937
509
        proto_tree *alljoyn_answers_tree;
1938
509
        int         flags;
1939
509
        unsigned    count;
1940
1941
509
        alljoyn_answers_ti = proto_tree_add_item(alljoyn_tree, hf_alljoyn_answer, tvb, *offset, 2, ENC_NA);
1942
509
        alljoyn_answers_tree = proto_item_add_subtree(alljoyn_answers_ti, ett_alljoyn_ns_answers);
1943
1944
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_g_flag,  tvb, *offset, 1, ENC_NA);
1945
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_c_flag,  tvb, *offset, 1, ENC_NA);
1946
1947
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r4_flag, tvb, *offset, 1, ENC_NA);
1948
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u4_flag, tvb, *offset, 1, ENC_NA);
1949
1950
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_r6_flag, tvb, *offset, 1, ENC_NA);
1951
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_u6_flag, tvb, *offset, 1, ENC_NA);
1952
1953
509
        flags = tvb_get_uint8(tvb, *offset);
1954
509
        (*offset) += 1;
1955
1956
509
        proto_tree_add_item_ret_uint(alljoyn_answers_tree, hf_alljoyn_ns_isat_count,   tvb, *offset, 1, ENC_NA, &count);
1957
509
        (*offset) += 1;
1958
1959
        /* The entire transport mask. */
1960
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask, tvb, *offset, 2, ENC_BIG_ENDIAN);
1961
1962
        /* The individual bits of the transport mask. */
1963
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wfd,       tvb, *offset, 2, ENC_BIG_ENDIAN);
1964
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_ice,       tvb, *offset, 2, ENC_BIG_ENDIAN);
1965
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_lan,       tvb, *offset, 2, ENC_BIG_ENDIAN);
1966
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_wwan,      tvb, *offset, 2, ENC_BIG_ENDIAN);
1967
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_tcp,       tvb, *offset, 2, ENC_BIG_ENDIAN);
1968
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_bluetooth, tvb, *offset, 2, ENC_BIG_ENDIAN);
1969
509
        proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_transport_mask_local,     tvb, *offset, 2, ENC_BIG_ENDIAN);
1970
1971
509
        (*offset) += 2;
1972
1973
509
        if(flags & ISAT_R4) {
1974
46
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_BIG_ENDIAN);
1975
46
            (*offset) += 4;
1976
1977
46
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
1978
46
            (*offset) += 2;
1979
46
        }
1980
1981
509
        if(flags & ISAT_U4) {
1982
53
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv4, tvb, *offset, 4, ENC_BIG_ENDIAN);
1983
53
            (*offset) += 4;
1984
1985
53
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
1986
53
            (*offset) += 2;
1987
53
        }
1988
1989
509
        if(flags & ISAT_R6) {
1990
49
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA);
1991
49
            (*offset) += 16;
1992
1993
49
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
1994
49
            (*offset) += 2;
1995
49
        }
1996
1997
509
        if(flags & ISAT_U6) {
1998
61
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_ipv6, tvb, *offset, 16, ENC_NA);
1999
61
            (*offset) += 16;
2000
2001
61
            proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_ns_isat_port, tvb, *offset, 2, ENC_BIG_ENDIAN);
2002
61
            (*offset) += 2;
2003
61
        }
2004
2005
509
        if(flags & ISAT_G) {
2006
40
            proto_item *alljoyn_string_ti;
2007
40
            proto_tree *alljoyn_string_tree;
2008
40
            int         guid_size;
2009
2010
40
            guid_size = tvb_get_uint8(tvb, *offset);
2011
2012
40
            alljoyn_string_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_guid_string, tvb,
2013
40
                *offset, 1 + guid_size, ENC_NA);
2014
40
            alljoyn_string_tree = proto_item_add_subtree(alljoyn_string_ti, ett_alljoyn_ns_guid_string);
2015
2016
40
            proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA);
2017
40
            (*offset) += 1;
2018
2019
40
            proto_tree_add_item(alljoyn_string_tree, hf_alljoyn_string_data, tvb, *offset, guid_size, ENC_ASCII);
2020
40
            (*offset) += guid_size;
2021
40
        }
2022
2023
        /* The string data records. */
2024
1.41k
        while(count--) {
2025
909
            proto_item *alljoyn_entry_ti;
2026
909
            proto_tree *alljoyn_entry_tree;
2027
2028
909
            proto_tree *alljoyn_bus_name_ti;
2029
909
            proto_tree *alljoyn_bus_name_tree;
2030
909
            int         bus_name_size = tvb_get_uint8(tvb, *offset);
2031
2032
909
            alljoyn_entry_ti = proto_tree_add_item(alljoyn_answers_tree, hf_alljoyn_isat_entry, tvb,
2033
909
                *offset, 1 + bus_name_size, ENC_NA);
2034
909
            alljoyn_entry_tree = proto_item_add_subtree(alljoyn_entry_ti, ett_alljoyn_isat_entry);
2035
2036
909
            alljoyn_bus_name_ti = proto_tree_add_item(alljoyn_entry_tree, hf_alljoyn_string, tvb, *offset,
2037
909
                1 + bus_name_size, ENC_NA);
2038
909
            alljoyn_bus_name_tree = proto_item_add_subtree(alljoyn_bus_name_ti, ett_alljoyn_string);
2039
2040
909
            proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_size_8bit, tvb, *offset, 1, ENC_NA);
2041
909
            (*offset) += 1;
2042
2043
909
            proto_tree_add_item(alljoyn_bus_name_tree, hf_alljoyn_string_data, tvb, *offset, bus_name_size, ENC_ASCII);
2044
909
            (*offset) += bus_name_size;
2045
909
        }
2046
509
    }
2047
52
}
2048
2049
/* This is called by Wireshark for packet types that are registered
2050
   in the proto_reg_handoff_AllJoyn() function. This function handles
2051
   the packets for the name server traffic.
2052
 * @param tvb is the incoming network data buffer.
2053
 * @param pinfo contains information about the incoming packet which
2054
 *         we update as we dissect the packet.
2055
 * @param tree is the tree data items should be added to.
2056
 */
2057
static int
2058
dissect_AllJoyn_name_server(tvbuff_t    *tvb,
2059
                            packet_info *pinfo,
2060
                            proto_tree  *tree,
2061
                            void *data   _U_)
2062
150
{
2063
150
    proto_item *alljoyn_item, *header_item;
2064
150
    proto_tree *alljoyn_tree, *header_tree;
2065
150
    uint8_t     questions, answers;
2066
150
    uint8_t     version;
2067
150
    int         offset = 0;
2068
2069
    /* This is name service traffic. Mark it as such at the top level. */
2070
150
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN-NS");
2071
150
    col_clear(pinfo->cinfo, COL_INFO);
2072
2073
    /* Add a subtree covering the remainder of the packet */
2074
150
    alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ns, tvb, 0, -1, ENC_NA);
2075
150
    alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ns);
2076
2077
    /* Add the "header protocol" as a subtree from the AllJoyn Name Service Protocol. */
2078
150
    header_item = proto_tree_add_item(alljoyn_tree, hf_alljoyn_ns_header, tvb, offset, 4, ENC_NA);
2079
150
    header_tree = proto_item_add_subtree(header_item, ett_alljoyn_ns_header);
2080
2081
    /* The the sender and message versions as fields for the header protocol. */
2082
150
    proto_tree_add_item(header_tree, hf_alljoyn_ns_sender_version, tvb, offset, 1, ENC_NA);
2083
150
    proto_tree_add_item_ret_uint8(header_tree, hf_alljoyn_ns_message_version, tvb, offset, 1, ENC_NA, &version);
2084
150
    offset += 1;
2085
2086
150
    col_add_fstr(pinfo->cinfo, COL_INFO, "VERSION %u", version);
2087
150
    if(version > 1)
2088
24
        col_append_str(pinfo->cinfo, COL_INFO, " (UNSUPPORTED)");
2089
2090
150
    proto_tree_add_item_ret_uint8(header_tree, hf_alljoyn_ns_questions, tvb, offset, 1, ENC_NA, &questions);
2091
150
    offset += 1;
2092
2093
150
    proto_tree_add_item_ret_uint8(header_tree, hf_alljoyn_ns_answers, tvb, offset, 1, ENC_NA, &answers);
2094
150
    offset += 1;
2095
2096
150
    if(answers > 0)
2097
131
        col_append_str(pinfo->cinfo, COL_INFO, " ISAT");
2098
2099
150
    if(questions > 0)
2100
58
        col_append_str(pinfo->cinfo, COL_INFO, " WHOHAS");
2101
2102
150
    proto_tree_add_item(header_tree, hf_alljoyn_ns_timer, tvb, offset, 1, ENC_NA);
2103
150
    offset += 1;
2104
2105
2106
150
    if(tree) {  /* we are being asked for details */
2107
147
        ns_parse_questions(tvb, &offset, alljoyn_tree, questions, version);
2108
2109
147
        switch(version) {
2110
48
        case 0:
2111
48
            ns_parse_answers_v0(tvb, &offset, alljoyn_tree, answers);
2112
48
            break;
2113
52
        case 1:
2114
52
            ns_parse_answers_v1(tvb, &offset, alljoyn_tree, answers);
2115
52
            break;
2116
3
        default:
2117
            /* XXX - expert info */
2118
            /* This case being unsupported is reported in the column info by
2119
             * the caller of this function. */
2120
3
            break;
2121
147
        }
2122
147
    }
2123
2124
16
    return tvb_reported_length(tvb);
2125
150
}
2126
2127
/* This is a container for the ARDP info and Wireshark tree information.
2128
 */
2129
typedef struct _alljoyn_ardp_tree_data
2130
{
2131
    int offset;
2132
    bool syn;
2133
    bool ack;
2134
    bool eak;
2135
    bool rst;
2136
    bool nul;
2137
    unsigned sequence;
2138
    unsigned start_sequence;
2139
    uint16_t fragment_count;
2140
    int acknowledge;
2141
    proto_tree *alljoyn_tree;
2142
} alljoyn_ardp_tree_data;
2143
2144
/* This is called by dissect_AllJoyn_ardp() to read the header
2145
 * and fill out most of tree_data.
2146
 * @param tvb is the incoming network data buffer.
2147
 * @param pinfo contains information about the incoming packet which
2148
 *         we update as we dissect the packet.
2149
 * @param tree_data is the destination of the data..
2150
 */
2151
static void
2152
ardp_parse_header(tvbuff_t *tvb,
2153
                  packet_info *pinfo,
2154
                  alljoyn_ardp_tree_data *tree_data)
2155
57
{
2156
57
    uint8_t     flags, header_length;
2157
57
    int         eaklen, packet_length;
2158
57
    uint16_t    data_length;
2159
2160
57
    packet_length = tvb_reported_length(tvb);
2161
2162
57
    flags = tvb_get_uint8(tvb, 0);
2163
2164
57
    tree_data->syn = (flags & ARDP_SYN) != 0;
2165
57
    tree_data->ack = (flags & ARDP_ACK) != 0;
2166
57
    tree_data->eak = (flags & ARDP_EAK) != 0;
2167
57
    tree_data->rst = (flags & ARDP_RST) != 0;
2168
57
    tree_data->nul = (flags & ARDP_NUL) != 0;
2169
2170
    /* The packet length has to be ARDP_HEADER_LEN_OFFSET long or protocol_is_ardp() would
2171
       have returned false. Length is expressed in words so multiply by 2. */
2172
57
    header_length = 2 * tvb_get_uint8(tvb, ARDP_HEADER_LEN_OFFSET);
2173
2174
57
    if(packet_length < ARDP_DATA_LENGTH_OFFSET + 2) {
2175
        /* If we need more data before dissecting then communicate the number of additional bytes needed. */
2176
10
        set_pinfo_desegment(pinfo, 0, ARDP_DATA_LENGTH_OFFSET + 2 - packet_length);
2177
2178
        /* Inform the caller we made it this far. Returning zero means we made no progress.
2179
           This is the offset just past the last byte we successfully retrieved. */
2180
10
        tree_data->offset = ARDP_HEADER_LEN_OFFSET + 1;
2181
2182
10
        return;
2183
10
    }
2184
2185
47
    data_length = tvb_get_ntohs(tvb, ARDP_DATA_LENGTH_OFFSET);
2186
2187
47
    if(packet_length < header_length + data_length) {
2188
        /* If we need more data before dissecting then communicate the number of additional bytes needed. */
2189
42
        set_pinfo_desegment(pinfo, 0, header_length + data_length - packet_length);
2190
2191
        /* Inform the caller we made it this far. Returning zero it means we made no progress.
2192
           This is the offset just past the last byte we successfully retrieved. */
2193
42
        tree_data->offset = ARDP_DATA_LENGTH_OFFSET + 2;
2194
42
        return;
2195
42
    }
2196
2197
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_syn_flag, tvb, tree_data->offset, 1, ENC_NA);
2198
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ack_flag, tvb, tree_data->offset, 1, ENC_NA);
2199
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_eak_flag, tvb, tree_data->offset, 1, ENC_NA);
2200
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_rst_flag, tvb, tree_data->offset, 1, ENC_NA);
2201
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_nul_flag, tvb, tree_data->offset, 1, ENC_NA);
2202
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_unused_flag, tvb, tree_data->offset, 1, ENC_NA);
2203
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_version_field, tvb, tree_data->offset, 1, ENC_NA);
2204
2205
5
    tree_data->offset += 1;
2206
2207
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_hlen, tvb, tree_data->offset, 1, ENC_NA);
2208
5
    tree_data->offset += 1;
2209
2210
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_src, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2211
5
    tree_data->offset += 2;
2212
2213
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dst, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2214
5
    tree_data->offset += 2;
2215
2216
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dlen, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2217
5
    tree_data->offset += 2;
2218
2219
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_seq, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2220
5
    tree_data->sequence = tvb_get_ntohl(tvb, tree_data->offset);
2221
5
    tree_data->offset += 4;
2222
2223
5
    proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ack, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2224
5
    tree_data->acknowledge = tvb_get_ntohl(tvb, tree_data->offset);
2225
5
    tree_data->offset += 4;
2226
2227
5
    if(tree_data->syn) {
2228
0
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_segmax, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2229
0
        tree_data->offset += 2;
2230
2231
0
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_segbmax, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2232
0
        tree_data->offset += 2;
2233
2234
0
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_dackt, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2235
0
        tree_data->offset += 4;
2236
2237
0
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_options, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2238
0
        tree_data->offset += 2;
2239
5
    } else {
2240
5
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_ttl, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2241
5
        tree_data->offset += 4;
2242
2243
5
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_lcs, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2244
5
        tree_data->offset += 4;
2245
2246
5
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_nsa, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2247
5
        tree_data->offset += 4;
2248
2249
5
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_fss, tvb, tree_data->offset, 4, ENC_BIG_ENDIAN);
2250
5
        tree_data->start_sequence = tvb_get_ntohl(tvb, tree_data->offset);
2251
5
        tree_data->offset += 4;
2252
2253
5
        proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_fcnt, tvb, tree_data->offset, 2, ENC_BIG_ENDIAN);
2254
5
        tree_data->fragment_count = tvb_get_ntohs(tvb, tree_data->offset);
2255
5
        tree_data->offset += 2;
2256
2257
5
        eaklen = header_length - ARDP_FIXED_HDR_LEN;
2258
2259
        /* In the case of a corrupted packet eaklen could be < 0 and bad things could happen. */
2260
5
        if(eaklen > 0) {
2261
4
            if(tree_data->eak) {
2262
3
                proto_tree_add_item(tree_data->alljoyn_tree, hf_ardp_bmp, tvb, tree_data->offset, eaklen, ENC_NA);
2263
3
            }
2264
2265
4
            tree_data->offset += eaklen;
2266
4
        }
2267
2268
        /* The data_length bytes, if any, will be passed on to the dissect_AllJoyn_message() handler. */
2269
5
    }
2270
5
}
2271
2272
/* Test to see if this buffer contains something that might be the AllJoyn ARDP protocol.
2273
 * @param tvb is the incoming network data buffer.
2274
 * @returns true if probably the AllJoyn ARDP protocol.
2275
 *          false if probably not the AllJoyn ARDP protocol.
2276
 */
2277
static bool
2278
protocol_is_ardp(tvbuff_t *tvb)
2279
72
{
2280
72
    uint8_t     flags, header_length;
2281
72
    int length = tvb_captured_length(tvb);
2282
2283
    /* We must be able to get the byte value at this offset to determine if it is an ARDP protocol. */
2284
72
    if(length < ARDP_HEADER_LEN_OFFSET + 1) {
2285
3
        return false;
2286
3
    }
2287
2288
    /* Length is expressed in words. */
2289
69
    header_length = 2 * tvb_get_uint8(tvb, ARDP_HEADER_LEN_OFFSET);
2290
2291
69
    flags = tvb_get_uint8(tvb, 0);
2292
2293
69
    if((flags & ARDP_SYN) && header_length != ARDP_SYN_FIXED_HDR_LEN) {
2294
7
        return false;
2295
7
    }
2296
2297
62
    if(!(flags & ARDP_SYN) && header_length < ARDP_FIXED_HDR_LEN) {
2298
5
        return false;
2299
5
    }
2300
2301
57
    return true;
2302
62
}
2303
2304
/* This is called by Wireshark for packet types that are registered
2305
   in the proto_reg_handoff_AllJoyn() function. This function handles
2306
   the packets for the ARDP and bare AllJoyn message protocols. A test
2307
   for bare AllJoyn message protocol is done first. If it is an AllJoyn
2308
   packet then only dissect_AllJoyn_message() is called to dissect the
2309
   data. If protocol_is_alljoyn_message() returns false then a test for
2310
   the ARDP protocol is performed. If it succeeds then ARDP dissection
2311
   proceeds and may call dissect_AllJoyn_message() with the offset just
2312
   past the ARDP protocol.
2313
 * @param tvb is the incoming network data buffer.
2314
 * @param pinfo contains information about the incoming packet which
2315
 * we update as we dissect the packet.
2316
 * @param tree is the tree data items should be added to.
2317
 * @return 0 if not AllJoyn ARDP protocol, or
2318
 *         the offset into the buffer we have dissected (which should normally
2319
 *         be the packet length), or
2320
 *         the offset into the buffer we have dissected with
2321
 *         pinfo->desegment_len == additional bytes needed from the next packet
2322
 *         before we can dissect.
2323
 */
2324
static int
2325
dissect_AllJoyn_ardp(tvbuff_t    *tvb,
2326
                     packet_info *pinfo,
2327
                     proto_tree  *tree,
2328
                     void *data   _U_)
2329
99
{
2330
99
    alljoyn_ardp_tree_data tree_data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2331
99
    int packet_length = tvb_reported_length(tvb);
2332
99
    proto_item *alljoyn_item = NULL;
2333
99
    bool fragmentedPacket = false;
2334
2335
99
    if(protocol_is_alljoyn_message(tvb, 0, false)) {
2336
27
        return dissect_AllJoyn_message(tvb, pinfo, tree, 0);
2337
27
    }
2338
2339
72
    if(!protocol_is_ardp(tvb)) {
2340
15
        return 0;
2341
15
    }
2342
2343
57
    pinfo->desegment_len = 0;
2344
2345
    /* Add a subtree covering the remainder of the packet */
2346
57
    alljoyn_item = proto_tree_add_item(tree, proto_AllJoyn_ardp, tvb, 0, -1, ENC_NA);
2347
57
    tree_data.alljoyn_tree = proto_item_add_subtree(alljoyn_item, ett_alljoyn_ardp);
2348
2349
57
    ardp_parse_header(tvb, pinfo, &tree_data);
2350
2351
    /* Is desegmentation needed? */
2352
57
    if(pinfo->desegment_len != 0) {
2353
0
        return tree_data.offset;
2354
0
    }
2355
2356
57
    if(tree_data.offset != 0) {
2357
        /* This is ARDP traffic. Mark it as such at the top level. */
2358
57
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ALLJOYN-ARDP");
2359
57
    }
2360
2361
57
    if(tree_data.offset < packet_length) {
2362
53
        int return_value = 0;
2363
2364
        /* We have dissected the ARDP portion. Is the remainder an AllJoyn message? */
2365
53
        if(protocol_is_alljoyn_message(tvb, tree_data.offset, true)) {
2366
37
            return_value = dissect_AllJoyn_message(tvb, pinfo, tree, tree_data.offset);
2367
37
        }
2368
16
        else {
2369
16
            fragmentedPacket = !tree_data.syn && (tree_data.sequence > tree_data.start_sequence);
2370
16
        }
2371
2372
        /* return_value will be the offset into the successfully parsed
2373
         * buffer, the requested length of a reassembled packet (with pinfo->desegment_len
2374
         * and pinfo->desegment_offset set appropriately), 0 if desegmentation is needed but
2375
         * isn't available, or the initial value (tree_data.offset) if no progress was made.
2376
         * If dissect_AllJoyn_message() made progress or is requesting desegmentation then
2377
         * return leaving the column info as handled by the AllJoyn message dissector. If
2378
         * not then we fall through to set the column info in this dissector.
2379
         */
2380
53
        if(return_value > tree_data.offset) {
2381
30
            return return_value;
2382
30
        }
2383
53
    }
2384
2385
27
    col_clear(pinfo->cinfo, COL_INFO);
2386
2387
27
    col_append_str(pinfo->cinfo, COL_INFO, "flags:");
2388
27
    if(tree_data.syn) {
2389
2
        col_append_str(pinfo->cinfo, COL_INFO, " SYN");
2390
2
    }
2391
27
    if(tree_data.ack) {
2392
12
        col_append_str(pinfo->cinfo, COL_INFO, " ACK");
2393
12
    }
2394
27
    if(tree_data.eak) {
2395
10
        col_append_str(pinfo->cinfo, COL_INFO, " EAK");
2396
10
    }
2397
27
    if(tree_data.rst) {
2398
10
        col_append_str(pinfo->cinfo, COL_INFO, " RST");
2399
10
    }
2400
27
    if(tree_data.nul) {
2401
10
        col_append_str(pinfo->cinfo, COL_INFO, " NUL");
2402
10
    }
2403
2404
27
    col_append_fstr(pinfo->cinfo, COL_INFO, " SEQ: %10u", tree_data.sequence);
2405
27
    col_append_fstr(pinfo->cinfo, COL_INFO, " ACK: %10u", tree_data.acknowledge);
2406
2407
27
    if(fragmentedPacket) {
2408
3
        unsigned fragment = (tree_data.sequence - tree_data.start_sequence) + 1;
2409
2410
3
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Fragment %d of %d for a previous ALLJOYN message", fragment, tree_data.fragment_count);
2411
3
    }
2412
2413
27
    return tree_data.offset;
2414
57
}
2415
2416
void
2417
proto_register_AllJoyn(void)
2418
15
{
2419
15
    expert_module_t* expert_alljoyn;
2420
2421
    /* A header field is something you can search/filter on.
2422
     *
2423
     * We create a structure to register our fields. It consists of an
2424
     * array of hf_register_info structures, each of which are of the format
2425
     * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
2426
     * The array below defines what elements we will be displaying. These
2427
     * declarations are simply a definition Wireshark uses to determine the data
2428
     * type, when we later dissect the packet.
2429
     */
2430
15
    static hf_register_info hf[] = {
2431
        /******************
2432
         * Wireshark header fields for the name service protocol.
2433
         ******************/
2434
15
        {&hf_alljoyn_ns_header,
2435
15
         {"Header", "alljoyn.header",
2436
15
          FT_NONE, BASE_NONE, NULL, 0x0,
2437
15
          NULL, HFILL}
2438
15
        },
2439
15
        {&hf_alljoyn_ns_sender_version,
2440
15
         {"Sender Version", "alljoyn.header.sendversion",
2441
15
          FT_UINT8, BASE_DEC, NULL, 0xF0,
2442
15
          NULL, HFILL}
2443
15
        },
2444
15
        {&hf_alljoyn_ns_message_version,
2445
15
         {"Message Version", "alljoyn.header.messageversion",
2446
15
          FT_UINT8, BASE_DEC, NULL, 0x0F,
2447
15
          NULL, HFILL}
2448
15
        },
2449
15
        {&hf_alljoyn_ns_questions,
2450
15
         {"Questions", "alljoyn.header.questions",
2451
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2452
15
          NULL, HFILL}
2453
15
        },
2454
15
        {&hf_alljoyn_ns_answers,
2455
15
         {"Answers", "alljoyn.header.answers",
2456
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2457
15
          NULL, HFILL}
2458
15
        },
2459
15
        {&hf_alljoyn_ns_timer,
2460
15
         {"Timer", "alljoyn.header.timer",
2461
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2462
15
          NULL, HFILL}
2463
15
        },
2464
2465
15
        {&hf_alljoyn_ns_whohas,
2466
15
         {"Who-Has Message", "alljoyn.whohas",
2467
15
          FT_NONE, BASE_NONE, NULL, 0x0,
2468
15
          NULL, HFILL}
2469
15
        },
2470
15
        {&hf_alljoyn_ns_whohas_t_flag,
2471
15
         {"TCP", "alljoyn.whohas.T",
2472
15
          FT_BOOLEAN, 8, NULL, WHOHAS_T,
2473
15
          NULL, HFILL}
2474
15
        },
2475
15
        {&hf_alljoyn_ns_whohas_u_flag,
2476
15
         {"UDP", "alljoyn.whohas.U",
2477
15
          FT_BOOLEAN, 8, NULL, WHOHAS_U,
2478
15
          NULL, HFILL}
2479
15
        },
2480
15
        {&hf_alljoyn_ns_whohas_s_flag,
2481
15
         {"IPv6", "alljoyn.whohas.S",
2482
15
          FT_BOOLEAN, 8, NULL, WHOHAS_S,
2483
15
          NULL, HFILL}
2484
15
        },
2485
15
        {&hf_alljoyn_ns_whohas_f_flag,
2486
15
         {"IPv4", "alljoyn.whohas.F",
2487
15
          FT_BOOLEAN, 8, NULL, WHOHAS_F,
2488
15
          NULL, HFILL}
2489
15
        },
2490
15
        {&hf_alljoyn_ns_whohas_count,
2491
15
         {"Count", "alljoyn.whohas.count",
2492
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2493
15
          NULL, HFILL}
2494
15
        },
2495
2496
15
        {&hf_alljoyn_answer,
2497
15
         {"Is-At Message", "alljoyn.isat",
2498
15
          FT_NONE, BASE_NONE, NULL, 0x0,
2499
15
          NULL, HFILL}
2500
15
        },
2501
15
        {&hf_alljoyn_isat_entry,
2502
15
         {"Advertisement Entry", "alljoyn.isat_entry",
2503
15
          FT_NONE, BASE_NONE, NULL, 0x0,
2504
15
          NULL, HFILL}
2505
15
        },
2506
15
        {&hf_alljoyn_isat_guid_string,
2507
15
         {"GUID String", "alljoyn.isat_guid_string",
2508
15
          FT_NONE, BASE_NONE, NULL, 0x0,
2509
15
          NULL, HFILL}
2510
15
        },
2511
2512
        /* Common to V0 and V1 IS-AT messages. */
2513
15
        {&hf_alljoyn_ns_isat_g_flag,
2514
15
         {"GUID", "alljoyn.isat.G",
2515
15
          FT_BOOLEAN, 8, NULL, ISAT_G,
2516
15
          NULL, HFILL}
2517
15
        },
2518
15
        {&hf_alljoyn_ns_isat_c_flag,
2519
15
         {"Complete", "alljoyn.isat.C",
2520
15
          FT_BOOLEAN, 8, NULL, ISAT_C,
2521
15
          NULL, HFILL}
2522
15
        },
2523
15
        {&hf_alljoyn_ns_isat_count,
2524
15
         {"Count", "alljoyn.isat.count",
2525
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2526
15
          NULL, HFILL}
2527
15
        },
2528
15
        {&hf_alljoyn_ns_isat_ipv6,
2529
15
         {"IPv6 Address", "alljoyn.isat.ipv6",
2530
15
          FT_IPv6, BASE_NONE, NULL, 0x0,
2531
15
          NULL, HFILL}
2532
15
        },
2533
15
        {&hf_alljoyn_ns_isat_ipv4,
2534
15
         {"IPv4 Address", "alljoyn.isat.ipv4",
2535
15
          FT_IPv4, BASE_NONE, NULL, 0x0,
2536
15
          NULL, HFILL}
2537
15
        },
2538
2539
        /* Version 0 IS-AT messages. */
2540
15
        {&hf_alljoyn_ns_isat_t_flag,
2541
15
         {"TCP", "alljoyn.isat.T",
2542
15
          FT_BOOLEAN, 8, NULL, ISAT_T,
2543
15
          NULL, HFILL}
2544
15
        },
2545
15
        {&hf_alljoyn_ns_isat_u_flag,
2546
15
         {"UDP", "alljoyn.isat.U",
2547
15
          FT_BOOLEAN, 8, NULL, ISAT_U,
2548
15
          NULL, HFILL}
2549
15
        },
2550
15
        {&hf_alljoyn_ns_isat_s_flag,
2551
15
         {"IPv6", "alljoyn.isat.S",
2552
15
          FT_BOOLEAN, 8, NULL, ISAT_S,
2553
15
          NULL, HFILL}
2554
15
        },
2555
15
        {&hf_alljoyn_ns_isat_f_flag,
2556
15
         {"IPv4", "alljoyn.isat.F",
2557
15
          FT_BOOLEAN, 8, NULL, ISAT_F,
2558
15
          NULL, HFILL}
2559
15
        },
2560
15
        {&hf_alljoyn_ns_isat_port,
2561
15
         {"Port", "alljoyn.isat.port",
2562
15
          FT_UINT16, BASE_DEC, NULL, 0x0,
2563
15
          NULL, HFILL}
2564
15
        },
2565
2566
        /* Version 1 IS-AT messages. */
2567
15
        {&hf_alljoyn_ns_isat_u6_flag,
2568
15
         {"IPv6 UDP", "alljoyn.isat.U6",
2569
15
          FT_BOOLEAN, 8, NULL, ISAT_U6,
2570
15
          NULL, HFILL}
2571
15
        },
2572
15
        {&hf_alljoyn_ns_isat_r6_flag,
2573
15
         {"IPv6 TCP", "alljoyn.isat.R6",
2574
15
          FT_BOOLEAN, 8, NULL, ISAT_R6,
2575
15
          NULL, HFILL}
2576
15
        },
2577
15
        {&hf_alljoyn_ns_isat_u4_flag,
2578
15
         {"IPv4 UDP", "alljoyn.isat.U4",
2579
15
          FT_BOOLEAN, 8, NULL, ISAT_U4,
2580
15
          NULL, HFILL}
2581
15
        },
2582
15
        {&hf_alljoyn_ns_isat_r4_flag,
2583
15
         {"IPv4 TCP", "alljoyn.isat.R4",
2584
15
          FT_BOOLEAN, 8, NULL, ISAT_R4,
2585
15
          NULL, HFILL}
2586
15
        },
2587
2588
15
        {&hf_alljoyn_ns_isat_transport_mask,
2589
15
         {"Transport Mask", "alljoyn.isat.TransportMask",
2590
15
          FT_UINT16, BASE_HEX, NULL, 0x0,
2591
15
          NULL, HFILL}
2592
15
        },
2593
2594
15
        {&hf_alljoyn_ns_isat_transport_mask_local,
2595
15
         {"Local Transport", "alljoyn.isat.TransportMask.Local",
2596
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_LOCAL,
2597
15
          NULL, HFILL}
2598
15
        },
2599
15
        {&hf_alljoyn_ns_isat_transport_mask_bluetooth,
2600
15
         {"Bluetooth Transport", "alljoyn.isat.TransportMask.Bluetooth",
2601
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_BLUETOOTH,
2602
15
          NULL, HFILL}
2603
15
        },
2604
15
        {&hf_alljoyn_ns_isat_transport_mask_tcp,
2605
15
         {"TCP Transport", "alljoyn.isat.TransportMask.TCP",
2606
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_TCP,
2607
15
          NULL, HFILL}
2608
15
        },
2609
15
        {&hf_alljoyn_ns_isat_transport_mask_wwan,
2610
15
         {"Wireless WAN Transport", "alljoyn.isat.TransportMask.WWAN",
2611
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_WWAN,
2612
15
          NULL, HFILL}
2613
15
        },
2614
15
        {&hf_alljoyn_ns_isat_transport_mask_lan,
2615
15
         {"Wired LAN Transport", "alljoyn.isat.TransportMask.LAN",
2616
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_LAN,
2617
15
          NULL, HFILL}
2618
15
        },
2619
15
        {&hf_alljoyn_ns_isat_transport_mask_ice,
2620
15
         {"ICE protocol Transport", "alljoyn.isat.TransportMask.ICE",
2621
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_ICE,
2622
15
          NULL, HFILL}
2623
15
        },
2624
15
        {&hf_alljoyn_ns_isat_transport_mask_wfd,
2625
15
         {"Wi-Fi Direct Transport", "alljoyn.isat.TransportMask.WFD",
2626
15
          FT_BOOLEAN, 16, NULL, TRANSPORT_WFD,
2627
15
          NULL, HFILL}
2628
15
        },
2629
2630
        /******************
2631
         * Wireshark header fields for the message protocol.
2632
         ******************/
2633
15
        {&hf_alljoyn_connect_byte_value,
2634
15
         {"Connect Initial Byte", "alljoyn.InitialByte",
2635
15
          FT_UINT8, BASE_HEX, NULL, 0x0,
2636
15
          NULL, HFILL}
2637
15
        },
2638
2639
        /*
2640
         * Wireshark header fields for the SASL messages.
2641
         */
2642
15
        {&hf_alljoyn_sasl_command,
2643
15
         {"SASL command", "alljoyn.SASL.command",
2644
15
          FT_STRING, BASE_NONE, NULL, 0x0,
2645
15
          NULL, HFILL}
2646
15
        },
2647
15
        {&hf_alljoyn_sasl_parameter,
2648
15
         {"SASL parameter", "alljoyn.SASL.parameter",
2649
15
          FT_STRING, BASE_NONE, NULL, 0x0,
2650
15
          NULL, HFILL}
2651
15
        },
2652
2653
        /*
2654
         * Wireshark header fields for the AllJoyn message header.
2655
         */
2656
15
        {&hf_alljoyn_mess_header,
2657
15
         {"Message Header", "alljoyn.mess_header",
2658
15
          FT_BYTES, BASE_NONE, NULL, 0x0,
2659
15
          NULL, HFILL}
2660
15
        },
2661
15
        {&hf_alljoyn_mess_header_endian,
2662
15
         {"Endianness", "alljoyn.mess_header.endianness",
2663
15
          FT_CHAR, BASE_HEX, VALS(endian_encoding_vals), 0x0,
2664
15
          NULL, HFILL}
2665
15
        },
2666
15
        {&hf_alljoyn_mess_header_type,
2667
15
         {"Message type", "alljoyn.mess_header.type",
2668
15
          FT_UINT8, BASE_DEC, VALS(message_header_encoding_vals), 0x0,
2669
15
          NULL, HFILL}
2670
15
        },
2671
15
        {&hf_alljoyn_mess_header_flags,
2672
15
         {"Flags", "alljoyn.mess_header.flags",
2673
15
          FT_UINT8, BASE_HEX, NULL, 0x0,
2674
15
          NULL, HFILL}
2675
15
        },
2676
2677
        /* Individual fields of the flags byte. */
2678
15
        {&hf_alljoyn_mess_header_flags_no_reply,
2679
15
         {"No reply expected", "alljoyn.mess_header.flags.noreply",
2680
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_NO_REPLY_EXPECTED,
2681
15
          NULL, HFILL}
2682
15
        },
2683
15
        {&hf_alljoyn_mess_header_flags_no_auto_start,
2684
15
         {"No auto start", "alljoyn.mess_header.flags.noautostart",
2685
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_NO_AUTO_START,
2686
15
          NULL, HFILL}
2687
15
        },
2688
15
        {&hf_alljoyn_mess_header_flags_allow_remote_msg,
2689
15
         {"Allow remote messages", "alljoyn.mess_header.flags.allowremotemessages",
2690
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_ALLOW_REMOTE_MSG,
2691
15
          NULL, HFILL}
2692
15
        },
2693
15
        {&hf_alljoyn_mess_header_flags_sessionless,
2694
15
         {"Sessionless", "alljoyn.mess_header.flags.sessionless",
2695
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_SESSIONLESS,
2696
15
          NULL, HFILL}
2697
15
        },
2698
15
        {&hf_alljoyn_mess_header_flags_global_broadcast,
2699
15
         {"Allow global broadcast", "alljoyn.mess_header.flags.globalbroadcast",
2700
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_GLOBAL_BROADCAST,
2701
15
          NULL, HFILL}
2702
15
        },
2703
15
        {&hf_alljoyn_mess_header_flags_compressed,
2704
15
         {"Compressed", "alljoyn.mess_header.flags.compressed",
2705
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_COMPRESSED,
2706
15
          NULL, HFILL}
2707
15
        },
2708
15
        {&hf_alljoyn_mess_header_flags_encrypted,
2709
15
         {"Encrypted", "alljoyn.mess_header.flags.encrypted",
2710
15
          FT_BOOLEAN, 8, NULL, MESSAGE_HEADER_FLAG_ENCRYPTED,
2711
15
          NULL, HFILL}
2712
15
        },
2713
2714
15
        {&hf_alljoyn_mess_header_majorversion,
2715
15
         {"Major version", "alljoyn.mess_header.majorversion",
2716
15
          FT_UINT8, BASE_DEC, NULL, 0,
2717
15
          NULL, HFILL}
2718
15
        },
2719
15
        {&hf_alljoyn_mess_header_body_length,
2720
15
         {"Body length", "alljoyn.mess_header.bodylength",
2721
15
          FT_UINT32, BASE_DEC, NULL, 0,
2722
15
          NULL, HFILL}
2723
15
        },
2724
15
        {&hf_alljoyn_mess_header_serial,
2725
15
         {"Serial number", "alljoyn.mess_header.serial",
2726
15
          FT_UINT32, BASE_DEC, NULL, 0,
2727
15
          NULL, HFILL}
2728
15
        },
2729
15
        {&hf_alljoyn_mess_header_header_length,
2730
15
         {"Header length", "alljoyn.mess_header.headerlength",
2731
15
          FT_UINT32, BASE_DEC, NULL, 0,
2732
15
          NULL, HFILL}
2733
15
        },
2734
2735
15
        {&hf_alljoyn_mess_header_fields,
2736
15
         {"Header fields", "alljoyn.mess_header.fields",
2737
15
          FT_BYTES, BASE_NONE, NULL, 0,
2738
15
          NULL, HFILL}
2739
15
        },
2740
15
        {&hf_alljoyn_mess_header_field,
2741
15
         {"Header field", "alljoyn.mess_header.field",
2742
15
          FT_UINT8, BASE_HEX, VALS(mess_header_field_encoding_vals), 0,
2743
15
          NULL, HFILL}
2744
15
        },
2745
15
        {&hf_alljoyn_mess_body_header_fieldcode,
2746
15
         {"Field code", "alljoyn.message.fieldcode",
2747
15
          FT_UINT8, BASE_HEX, NULL, 0,
2748
15
          NULL, HFILL}
2749
15
        },
2750
15
        {&hf_alljoyn_mess_body_header_typeid,
2751
15
         {"Type ID", "alljoyn.message.typeid",
2752
15
          FT_CHAR, BASE_HEX, VALS(header_type_vals), 0,
2753
15
          NULL, HFILL}
2754
15
        },
2755
2756
15
        {&hf_alljoyn_mess_body_parameters,
2757
15
         {"Parameters", "alljoyn.parameters",
2758
15
          FT_NONE, BASE_NONE, NULL, 0,
2759
15
          NULL, HFILL}
2760
15
        },
2761
15
        {&hf_alljoyn_mess_body_array,
2762
15
         {"Array", "alljoyn.array",
2763
15
          FT_NONE, BASE_NONE, NULL, 0,
2764
15
          NULL, HFILL}
2765
15
        },
2766
15
        {&hf_alljoyn_mess_body_structure,
2767
15
         {"struct", "alljoyn.structure",
2768
15
          FT_NONE, BASE_NONE, NULL, 0,
2769
15
          NULL, HFILL}
2770
15
        },
2771
15
        {&hf_alljoyn_mess_body_dictionary_entry,
2772
15
         {"dictionary entry", "alljoyn.dictionary_entry",
2773
15
          FT_NONE, BASE_NONE, NULL, 0,
2774
15
          NULL, HFILL}
2775
15
        },
2776
15
        {&hf_alljoyn_mess_body_variant,
2777
15
         {"Variant '", "alljoyn.variant",
2778
15
          FT_NONE, BASE_NONE, NULL, 0,
2779
15
          NULL, HFILL}
2780
15
        },
2781
15
        {&hf_alljoyn_mess_body_signature_length,
2782
15
         {"Signature length", "alljoyn.parameter.signature_length",
2783
15
          FT_UINT8, BASE_DEC, NULL, 0,
2784
15
          NULL, HFILL}
2785
15
        },
2786
15
        {&hf_alljoyn_mess_body_signature,
2787
15
         {"Signature", "alljoyn.parameter.signature",
2788
15
          FT_STRING, BASE_NONE, NULL, 0x0,
2789
15
          NULL, HFILL}
2790
15
        },
2791
2792
15
        {&hf_alljoyn_boolean,
2793
15
         {"Boolean", "alljoyn.boolean",
2794
15
          FT_BOOLEAN, BASE_NONE, NULL, 0,
2795
15
          NULL, HFILL}
2796
15
        },
2797
15
        {&hf_alljoyn_uint8,
2798
15
         {"Unsigned byte", "alljoyn.uint8",
2799
15
          FT_UINT8, BASE_DEC, NULL, 0,
2800
15
          NULL, HFILL}
2801
15
        },
2802
15
        {&hf_alljoyn_int16,
2803
15
         {"Signed int16", "alljoyn.int16",
2804
15
          FT_INT16, BASE_DEC, NULL, 0,
2805
15
          NULL, HFILL}
2806
15
        },
2807
15
        {&hf_alljoyn_uint16,
2808
15
         {"Unsigned int16", "alljoyn.uint16",
2809
15
          FT_UINT16, BASE_DEC, NULL, 0,
2810
15
          NULL, HFILL}
2811
15
        },
2812
15
        {&hf_alljoyn_handle,
2813
15
         {"Handle", "alljoyn.handle",
2814
15
          FT_UINT32, BASE_HEX, NULL, 0,
2815
15
          NULL, HFILL}
2816
15
        },
2817
15
        {&hf_alljoyn_int32,
2818
15
         {"Signed int32", "alljoyn.int32",
2819
15
          FT_INT32, BASE_DEC, NULL, 0,
2820
15
          NULL, HFILL}
2821
15
        },
2822
15
        {&hf_alljoyn_uint32,
2823
15
         {"Unsigned int32", "alljoyn.uint32",
2824
15
          FT_UINT32, BASE_DEC, NULL, 0,
2825
15
          NULL, HFILL}
2826
15
        },
2827
15
        {&hf_alljoyn_int64,
2828
15
         {"Signed int64", "alljoyn.int64",
2829
15
          FT_INT64, BASE_DEC, NULL, 0,
2830
15
          NULL, HFILL}
2831
15
        },
2832
15
        {&hf_alljoyn_uint64,
2833
15
         {"Unsigned int64", "alljoyn.uint64",
2834
15
          FT_UINT64, BASE_DEC, NULL, 0,
2835
15
          NULL, HFILL}
2836
15
        },
2837
15
        {&hf_alljoyn_double,
2838
15
         {"Double", "alljoyn.double",
2839
15
          FT_DOUBLE, BASE_NONE, NULL, 0,
2840
15
          NULL, HFILL}
2841
15
        },
2842
15
        {&hf_padding,
2843
15
         {"Padding", "alljoyn.padding",
2844
15
          FT_BYTES, BASE_NONE, NULL, 0,
2845
15
          NULL, HFILL}
2846
15
        },
2847
2848
        /*
2849
         * Strings are composed of a size and a data array.
2850
         */
2851
15
        {&hf_alljoyn_string,
2852
15
         {"Bus Name", "alljoyn.string",
2853
15
          FT_NONE, BASE_NONE, NULL, 0x0,
2854
15
          NULL, HFILL}
2855
15
        },
2856
15
        {&hf_alljoyn_string_size_8bit,
2857
15
         {"String Size 8-bit", "alljoyn.string.size8bit",
2858
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2859
15
          NULL, HFILL}
2860
15
        },
2861
15
        {&hf_alljoyn_string_size_32bit,
2862
15
         {"String Size 32-bit", "alljoyn.string.size32bit",
2863
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2864
15
          NULL, HFILL}
2865
15
        },
2866
15
        {&hf_alljoyn_string_data,
2867
15
         {"String Data", "alljoyn.string.data",
2868
15
          FT_STRING, BASE_NONE, NULL, 0x0,
2869
15
          NULL, HFILL}
2870
15
        },
2871
        /******************
2872
         * Wireshark header fields for the AllJoyn Reliable Data Protocol.
2873
         ******************/
2874
15
        {&hf_ardp_syn_flag,
2875
15
         {"SYN", "ardp.hdr.SYN",
2876
15
          FT_BOOLEAN, 8, NULL, ARDP_SYN,
2877
15
          NULL, HFILL}
2878
15
        },
2879
15
        {&hf_ardp_ack_flag,
2880
15
         {"ACK", "ardp.hdr.ACK",
2881
15
          FT_BOOLEAN, 8, NULL, ARDP_ACK,
2882
15
          NULL, HFILL}},
2883
15
        {&hf_ardp_eak_flag,
2884
15
         {"EAK", "ardp.hdr.EAK",
2885
15
          FT_BOOLEAN, 8, NULL, ARDP_EAK,
2886
15
          NULL, HFILL}},
2887
15
        {&hf_ardp_rst_flag,
2888
15
         {"RST", "ardp.hdr.RST",
2889
15
          FT_BOOLEAN, 8, NULL, ARDP_RST,
2890
15
          NULL, HFILL}},
2891
15
        {&hf_ardp_nul_flag,
2892
15
         {"NUL", "ardp.hdr.NUL",
2893
15
          FT_BOOLEAN, 8, NULL, ARDP_NUL,
2894
15
          NULL, HFILL}},
2895
15
        {&hf_ardp_unused_flag,
2896
15
         {"UNUSED", "ardp.hdr.UNUSED",
2897
15
          FT_BOOLEAN, 8, NULL, ARDP_UNUSED,
2898
15
          NULL, HFILL}},
2899
15
        {&hf_ardp_version_field,
2900
15
         {"VER", "ardp.hdr.ver",
2901
15
          FT_UINT8, BASE_HEX, NULL, ARDP_VER,
2902
15
          NULL, HFILL}},
2903
15
        {&hf_ardp_hlen,
2904
15
         {"Header Length", "ardp.hdr.hlen",
2905
15
          FT_UINT8, BASE_DEC, NULL, 0x0,
2906
15
          NULL, HFILL}},
2907
15
        {&hf_ardp_src,
2908
15
         {"Source Port", "ardp.hdr.src",
2909
15
          FT_UINT16, BASE_DEC, NULL, 0x0,
2910
15
          NULL, HFILL}},
2911
15
        {&hf_ardp_dst,
2912
15
         {"Destination Port", "ardp.hdr.dst",
2913
15
          FT_UINT16, BASE_DEC, NULL, 0x0,
2914
15
          NULL, HFILL}},
2915
15
        {&hf_ardp_dlen,
2916
15
         {"Data Length", "ardp.hdr.dlen",
2917
15
          FT_UINT16, BASE_DEC, NULL, 0x0,
2918
15
          NULL, HFILL}},
2919
15
        {&hf_ardp_seq,
2920
15
         {"Sequence", "ardp.hdr.seq",
2921
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2922
15
          NULL, HFILL}},
2923
15
        {&hf_ardp_ack,
2924
15
         {"Acknowledge", "ardp.hdr.ack",
2925
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2926
15
          NULL, HFILL}},
2927
15
        {&hf_ardp_ttl,
2928
15
         {"Time to Live", "ardp.hdr.ttl",
2929
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2930
15
          NULL, HFILL}},
2931
15
        {&hf_ardp_lcs,
2932
15
         {"Last Consumed Sequence", "ardp.hdr.lcs",
2933
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2934
15
          NULL, HFILL}},
2935
15
        {&hf_ardp_nsa,
2936
15
         {"Next Sequence to ACK", "ardp.hdr.nsa",
2937
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2938
15
          NULL, HFILL}},
2939
15
        {&hf_ardp_fss,
2940
15
         {"Fragment Starting Sequence", "ardp.hdr.fss",
2941
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2942
15
          NULL, HFILL}},
2943
15
        {&hf_ardp_fcnt,
2944
15
         {"Fragment Count", "ardp.hdr.fcnt",
2945
15
          FT_UINT16, BASE_HEX, NULL, 0x0,
2946
15
          NULL, HFILL}},
2947
15
        {&hf_ardp_bmp,
2948
15
         {"EACK Bitmap", "ardp.hdr.bmp",
2949
15
          FT_UINT8, BASE_HEX, NULL, 0x0,
2950
15
          NULL, HFILL}},
2951
15
        {&hf_ardp_segmax,
2952
15
         {"Segment Max", "ardp.hdr.segmentmax",
2953
15
          FT_UINT16, BASE_DEC, NULL, 0x0,
2954
15
          NULL, HFILL}},
2955
15
        {&hf_ardp_segbmax,
2956
15
         {"Segment Buffer Max", "ardp.hdr.segmentbmax",
2957
15
          FT_UINT32, BASE_DEC, NULL, 0x0,
2958
15
          NULL, HFILL}},
2959
15
        {&hf_ardp_dackt,
2960
15
         {"Receiver's delayed ACK timeout", "ardp.hdr.dackt",
2961
15
          FT_UINT16, BASE_DEC, NULL, 0x0,
2962
15
          NULL, HFILL}},
2963
15
        {&hf_ardp_options,
2964
15
         {"Options", "ardp.hdr.options",
2965
15
          FT_UINT16, BASE_HEX, NULL, 0x0,
2966
15
          NULL, HFILL}},
2967
15
    };
2968
2969
15
    static int *ett[] = {
2970
15
        &ett_alljoyn_ns,
2971
15
        &ett_alljoyn_ns_header,
2972
15
        &ett_alljoyn_ns_answers,
2973
15
        &ett_alljoyn_ns_guid_string,
2974
15
        &ett_alljoyn_ns_isat_entry,
2975
15
        &ett_alljoyn_ns_string,
2976
15
        &ett_alljoyn_whohas,
2977
15
        &ett_alljoyn_string,
2978
15
        &ett_alljoyn_isat_entry,
2979
15
        &ett_alljoyn_mess,
2980
15
        &ett_alljoyn_header,
2981
15
        &ett_alljoyn_header_flags,
2982
15
        &ett_alljoyn_mess_header_field,
2983
15
        &ett_alljoyn_mess_header,
2984
15
        &ett_alljoyn_mess_body_parameters,
2985
15
        &ett_alljoyn_ardp
2986
15
    };
2987
2988
15
    static ei_register_info ei[] = {
2989
15
        { &ei_alljoyn_empty_arg,
2990
15
            { "alljoyn.empty_arg", PI_MALFORMED, PI_ERROR,
2991
15
                "Argument is empty", EXPFILL }}
2992
15
    };
2993
2994
    /* The following are protocols as opposed to data within a protocol. These appear
2995
     * in Wireshark a divider/header between different groups of data.
2996
     */
2997
2998
    /* Name service protocols. */                        /* name, short name, abbrev */
2999
15
    proto_AllJoyn_ns = proto_register_protocol("AllJoyn Name Service Protocol", "AllJoyn NS", "ajns");
3000
15
    alljoyn_handle_ns = register_dissector("ajns", dissect_AllJoyn_name_server, proto_AllJoyn_ns);
3001
3002
    /* Message protocols */
3003
15
    proto_AllJoyn_mess = proto_register_protocol("AllJoyn Message Protocol", "AllJoyn", "aj");
3004
3005
15
    proto_register_field_array(proto_AllJoyn_ns, hf, array_length(hf));
3006
15
    proto_register_subtree_array(ett, array_length(ett));
3007
15
    expert_alljoyn = expert_register_protocol(proto_AllJoyn_mess);
3008
15
    expert_register_field_array(expert_alljoyn, ei, array_length(ei));
3009
3010
    /* ARDP */                        /* name, short name, abbrev */
3011
15
    proto_AllJoyn_ardp = proto_register_protocol("AllJoyn Reliable Datagram Protocol", "AllJoyn ARDP", "ardp");
3012
15
    alljoyn_handle_ardp = register_dissector("ardp", dissect_AllJoyn_ardp, proto_AllJoyn_ardp);
3013
15
}
3014
3015
void
3016
proto_reg_handoff_AllJoyn(void)
3017
15
{
3018
15
    dissector_add_uint_with_preference("tcp.port", ALLJOYN_NAME_SERVER_PORT, alljoyn_handle_ns);
3019
15
    dissector_add_uint_with_preference("tcp.port", ALLJOYN_MESSAGE_PORT, alljoyn_handle_ardp);
3020
3021
15
    dissector_add_uint_with_preference("udp.port", ALLJOYN_NAME_SERVER_PORT, alljoyn_handle_ns);
3022
3023
    /* The ARDP dissector will directly call the AllJoyn message dissector if needed.
3024
     * This includes the case where there is no ARDP data. */
3025
15
    dissector_add_uint_with_preference("udp.port", ALLJOYN_MESSAGE_PORT, alljoyn_handle_ardp);
3026
15
}
3027
3028
/*
3029
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3030
 *
3031
 * Local variables:
3032
 * c-basic-offset: 4
3033
 * tab-width: 8
3034
 * indent-tabs-mode: nil
3035
 * End:
3036
 *
3037
 * vi: set shiftwidth=4 tabstop=8 expandtab:
3038
 * :indentSize=4:tabSize=8:noTabs=true:
3039
 */