1 /* packet-acn.c
2  * Routines for ACN packet disassembly
3  *
4  * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
5  * Copyright (c) 2006 by Electronic Theatre Controls, Inc.
6  *                    Bill Florac <bflorac@etcconnect.com>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1999 Gerald Combs
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
14 
15  /*
16     Todo:
17       Add reading of DDL files so we can futher explode DMP packets
18       For some of the Set/Get properties where we have a range of data
19       it would be better to show the block of data rather and
20       address-data pair on each line...
21 
22       Build CID to "Name" table from file so we can display real names
23       rather than CIDs
24  */
25 
26 /* Include files */
27 
28 #include "config.h"
29 
30 #include <epan/packet.h>
31 #include <epan/prefs.h>
32 #include <epan/strutil.h>
33 #include <epan/to_str.h>
34 #include <epan/expert.h>
35 
36 #include "packet-rdm.h"
37 #include "packet-tcp.h"
38 
39 /* Forward declarations */
40 void proto_register_acn(void);
41 void proto_reg_handoff_acn(void);
42 
43 /* pdu flags */
44 #define ACN_PDU_FLAG_L     0x80
45 #define ACN_PDU_FLAG_V     0x40
46 #define ACN_PDU_FLAG_H     0x20
47 #define ACN_PDU_FLAG_D     0x10
48 
49 #define ACN_DMX_OPTION_P   0x80
50 #define ACN_DMX_OPTION_S   0x40
51 
52 #define ACN_DMP_ADT_FLAG_V 0x80 /* V = Specifies whether address is a virtual address or not. */
53 #define ACN_DMP_ADT_FLAG_R 0x40 /* R = Specifies whether address is relative to last valid address in packet or not. */
54 #define ACN_DMP_ADT_FLAG_D 0x30 /* D1, D0 = Specify non-range or range address, single data, equal size
55                                    or mixed size data array */
56 #define ACN_DMP_ADT_EXTRACT_D(f)        (((f) & ACN_DMP_ADT_FLAG_D) >> 4)
57 
58 #define ACN_DMP_ADT_FLAG_X 0x0c /* X1, X0 = These bits are reserved and their values shall be set to 0
59                                    when encoded. Their values shall be ignored when decoding. */
60 
61 #define ACN_DMP_ADT_FLAG_A 0x03 /* A1, A0 = Size of Address elements */
62 #define ACN_DMP_ADT_EXTRACT_A(f)        ((f) & ACN_DMP_ADT_FLAG_A)
63 
64 #define ACN_DMP_ADT_V_ACTUAL    0
65 #define ACN_DMP_ADT_V_VIRTUAL   1
66 
67 #define ACN_DMP_ADT_R_ABSOLUTE  0
68 #define ACN_DMP_ADT_R_RELATIVE  1
69 
70 #define ACN_DMP_ADT_D_NS        0
71 #define ACN_DMP_ADT_D_RS        1
72 #define ACN_DMP_ADT_D_RE        2
73 #define ACN_DMP_ADT_D_RM        3
74 
75 #define ACN_DMP_ADT_A_1         0
76 #define ACN_DMP_ADT_A_2         1
77 #define ACN_DMP_ADT_A_4         2
78 #define ACN_DMP_ADT_A_R         3
79 
80 #define ACN_PROTOCOL_ID_SDT           0x00000001
81 #define ACN_PROTOCOL_ID_DMP           0x00000002
82 #define ACN_PROTOCOL_ID_DMX           0x00000003
83 #define ACN_PROTOCOL_ID_DMX_2         0x00000004
84 #define ACN_PROTOCOL_ID_RPT           0x00000005
85 #define ACN_PROTOCOL_ID_BROKER        0x00000009
86 #define ACN_PROTOCOL_ID_LLRP          0x0000000A
87 #define ACN_PROTOCOL_ID_EPT           0x0000000B
88 #define ACN_PROTOCOL_ID_DMX_3         0x50430001
89 
90 #define ACN_ADDR_NULL                 0
91 #define ACN_ADDR_IPV4                 1
92 #define ACN_ADDR_IPV6                 2
93 #define ACN_ADDR_IPPORT               3
94 
95 /* SDT Messages */
96 #define ACN_SDT_VECTOR_UNKNOWN          0
97 #define ACN_SDT_VECTOR_REL_WRAP         1
98 #define ACN_SDT_VECTOR_UNREL_WRAP       2
99 #define ACN_SDT_VECTOR_CHANNEL_PARAMS   3
100 #define ACN_SDT_VECTOR_JOIN             4
101 #define ACN_SDT_VECTOR_JOIN_REFUSE      5
102 #define ACN_SDT_VECTOR_JOIN_ACCEPT      6
103 #define ACN_SDT_VECTOR_LEAVE            7
104 #define ACN_SDT_VECTOR_LEAVING          8
105 #define ACN_SDT_VECTOR_CONNECT          9
106 #define ACN_SDT_VECTOR_CONNECT_ACCEPT  10
107 #define ACN_SDT_VECTOR_CONNECT_REFUSE  11
108 #define ACN_SDT_VECTOR_DISCONNECT      12
109 #define ACN_SDT_VECTOR_DISCONNECTING   13
110 #define ACN_SDT_VECTOR_ACK             14
111 #define ACN_SDT_VECTOR_NAK             15
112 #define ACN_SDT_VECTOR_GET_SESSION     16
113 #define ACN_SDT_VECTOR_SESSIONS        17
114 
115 #define ACN_REFUSE_CODE_NONSPECIFIC     1
116 #define ACN_REFUSE_CODE_ILLEGAL_PARAMS  2
117 #define ACN_REFUSE_CODE_LOW_RESOURCES   3
118 #define ACN_REFUSE_CODE_ALREADY_MEMBER  4
119 #define ACN_REFUSE_CODE_BAD_ADDR_TYPE   5
120 #define ACN_REFUSE_CODE_NO_RECIP_CHAN   6
121 
122 #define ACN_REASON_CODE_NONSPECIFIC          1
123 /*#define ACN_REASON_CODE_                   2 */
124 /*#define ACN_REASON_CODE_                   3 */
125 /*#define ACN_REASON_CODE_                   4 */
126 /*#define ACN_REASON_CODE_                   5 */
127 #define ACN_REASON_CODE_NO_RECIP_CHAN        6
128 #define ACN_REASON_CODE_CHANNEL_EXPIRED      7
129 #define ACN_REASON_CODE_LOST_SEQUENCE        8
130 #define ACN_REASON_CODE_SATURATED            9
131 #define ACN_REASON_CODE_TRANS_ADDR_CHANGING 10
132 #define ACN_REASON_CODE_ASKED_TO_LEAVE      11
133 #define ACN_REASON_CODE_NO_RECIPIENT        12
134 
135 /* Blob Information */
136 #define ACN_BLOB_FIELD_TYPE1             1
137 #define ACN_BLOB_FIELD_TYPE2             2
138 #define ACN_BLOB_FIELD_TYPE3             3
139 #define ACN_BLOB_FIELD_TYPE4             4
140 #define ACN_BLOB_FIELD_TYPE5             5
141 #define ACN_BLOB_FIELD_TYPE6             6
142 #define ACN_BLOB_FIELD_TYPE7             7
143 #define ACN_BLOB_FIELD_TYPE8             8
144 #define ACN_BLOB_FIELD_TYPE9             9
145 #define ACN_BLOB_FIELD_TYPE10            10
146 #define ACN_BLOB_FIELD_TYPE11            11
147 #define ACN_BLOB_FIELD_TYPE12            12
148 
149 #define ACN_BLOB_RANGE_MID               0
150 #define ACN_BLOB_RANGE_START             1
151 #define ACN_BLOB_RANGE_END               2
152 #define ACN_BLOB_RANGE_SINGLE            3
153 
154 #define ACN_BLOB_IPV4                               1
155 #define ACN_BLOB_IPV6                               2
156 #define ACN_BLOB_ERROR1                             3
157 #define ACN_BLOB_ERROR2                             4
158 #define ACN_BLOB_METADATA                           5
159 #define ACN_BLOB_METADATA_DEVICES                   6
160 #define ACN_BLOB_METADATA_TYPES                     7
161 #define ACN_BLOB_TIME1                              8
162 #define ACN_BLOB_DIMMER_PROPERTIES                  9
163 #define ACN_BLOB_DIMMER_LOAD_PROPERTIES             10
164 #define ACN_BLOB_DIMMING_RACK_PROPERTIES            11
165 #define ACN_BLOB_DIMMING_RACK_STATUS_PROPERTIES     12
166 #define ACN_BLOB_DIMMER_STATUS_PROPERTIES           13
167 #define ACN_BLOB_SET_LEVELS_OPERATION               14
168 #define ACN_BLOB_PRESET_OPERATION                   15
169 #define ACN_BLOB_ADVANCED_FEATURES_OPERATION        16
170 #define ACN_BLOB_DIRECT_CONTROL_OPERATION           17
171 #define ACN_BLOB_GENERATE_CONFIG_OPERATION          18
172 #define ACN_BLOB_ERROR3                             19
173 #define ACN_BLOB_DIMMER_PROPERTIES2                 20
174 #define ACN_BLOB_DIMMER_LOAD_PROPERTIES2            21
175 #define ACN_BLOB_DIMMER_RACK_PROPERTIES2            22
176 #define ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2     23
177 #define ACN_BLOB_DIMMER_STATUS_PROPERTIES2          24
178 #define ACN_BLOB_TIME2                              25
179 #define ACN_BLOB_RPC                                26
180 #define ACN_BLOB_DHCP_CONFIG_SUBNET                 27
181 #define ACN_BLOB_DHCP_CONFIG_STATIC_ROUTE           28
182 #define ACN_BLOB_ENERGY_MANAGEMENT                  29
183 #define ACN_BLOB_TIME3                              30
184 #define ACN_BLOB_ENERGY_COST                        31
185 #define ACN_BLOB_SEQUENCE_OPERATIONS                32
186 #define ACN_BLOB_SEQUENCE_STEP_PROPERTIES           33
187 
188 #define ACN_BLOB_PRESET_PROPERTIES                  250
189 
190 #define ACN_DMP_VECTOR_UNKNOWN               0
191 #define ACN_DMP_VECTOR_GET_PROPERTY          1
192 #define ACN_DMP_VECTOR_SET_PROPERTY          2
193 #define ACN_DMP_VECTOR_GET_PROPERTY_REPLY    3
194 #define ACN_DMP_VECTOR_EVENT                 4
195 #define ACN_DMP_VECTOR_MAP_PROPERTY          5
196 #define ACN_DMP_VECTOR_UNMAP_PROPERTY        6
197 #define ACN_DMP_VECTOR_SUBSCRIBE             7
198 #define ACN_DMP_VECTOR_UNSUBSCRIBE           8
199 #define ACN_DMP_VECTOR_GET_PROPERTY_FAIL     9
200 #define ACN_DMP_VECTOR_SET_PROPERTY_FAIL    10
201 #define ACN_DMP_VECTOR_MAP_PROPERTY_FAIL    11
202 #define ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT     12
203 #define ACN_DMP_VECTOR_SUBSCRIBE_REJECT     13
204 #define ACN_DMP_VECTOR_ALLOCATE_MAP         14
205 #define ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY   15
206 #define ACN_DMP_VECTOR_DEALLOCATE_MAP       16
207 #define ACN_DMP_VECTOR_SYNC_EVENT           17
208 
209 #define ACN_DMP_REASON_CODE_NONSPECIFIC                  1
210 #define ACN_DMP_REASON_CODE_NOT_A_PROPERTY               2
211 #define ACN_DMP_REASON_CODE_WRITE_ONLY                   3
212 #define ACN_DMP_REASON_CODE_NOT_WRITABLE                 4
213 #define ACN_DMP_REASON_CODE_DATA_ERROR                   5
214 #define ACN_DMP_REASON_CODE_MAPS_NOT_SUPPORTED           6
215 #define ACN_DMP_REASON_CODE_SPACE_NOT_AVAILABLE          7
216 #define ACN_DMP_REASON_CODE_PROP_NOT_MAPPABLE            8
217 #define ACN_DMP_REASON_CODE_MAP_NOT_ALLOCATED            9
218 #define ACN_DMP_REASON_CODE_SUBSCRIPTION_NOT_SUPPORTED  10
219 #define ACN_DMP_REASON_CODE_NO_SUBSCRIPTIONS_SUPPORTED  11
220 
221 #define ACN_DMX_VECTOR      2
222 
223 #define ACN_PREF_DMX_DISPLAY_HEX  0
224 #define ACN_PREF_DMX_DISPLAY_DEC  1
225 #define ACN_PREF_DMX_DISPLAY_PER  2
226 
227 #define ACN_PREF_DMX_DISPLAY_20PL 0
228 #define ACN_PREF_DMX_DISPLAY_16PL 1
229 
230 
231 #define MAGIC_V1           0    /* 1.0 default version */
232 #define MAGIC_COMMAND      1    /* 2.0 command         */
233 #define MAGIC_REPLY        2    /* 2.0 reply           */
234 #define MAGIC_REPLY_TYPE_3 3    /* 2.0 reply type 3    */
235 
236 #define V1_SWITCH_TO_NET1       1
237 #define V1_SWITCH_TO_NET2       2
238 #define V1_BOOTP          1114467
239 
240 #define V2_CMD_SWITCH_TO_NET1               1
241 #define V2_CMD_SWITCH_TO_NET2               2
242 #define V2_CMD_DOWNLOAD                     3
243 #define V2_CMD_SOFTBOOT                     4
244 #define V2_CMD_PHYSICAL_BEACON              5
245 #define V2_CMD_NETWORK_BEACON               6
246 #define V2_CMD_SWITCH_TO_ACN                7
247 #define V2_CMD_SWITCH_TO_DYNAMIC_IP         8
248 #define V2_CMD_EXTENDED_NETWORK_BEACON      9
249 #define V2_CMD_IP_CONFIGURATION            10
250 #define V2_CMD_RESTORE_FACTORY_DEFAULT     11
251 #define V2_CMD_PHYSICAL_BEACON_BY_CID      12
252 #define V2_CMD_NET2_DOWNLOAD           110163
253 
254 #define MAGIC_SWITCH_TO_DYNAMIC_MAINTAIN_LEASE 0
255 #define MAGIC_SWITCH_TO_DYNAMIC_RESET_LEASE    1
256 
257 #define MAGIC_DYNAMIC_IP_MAINTAIN_LEASE 0
258 #define MAGIC_DYNAMIC_IP_RESET_LEASE    1
259 #define MAGIC_STATIC_IP                 2
260 
261 /* E1.33 Table A-1  Broadcast UID Defines */
262 #define ACN_RPT_ALL_CONTROLLERS                    0xFFFCFFFFFFFF
263 #define ACN_RPT_ALL_DEVICES                        0xFFFDFFFFFFFF
264 #define ACN_RPT_ALL_MID_DEVICES                    0xFFFDmmmmFFFF /*Addresses all Devices with the specific Manufacturer ID 0xmmmm*/
265 
266 /* E1.33 Table A-2  LLRP Constants */
267 #define ACN_LLRP_MULTICAST_IPV4_ADDRESS_REQUEST    239.255.250.133
268 #define ACN_LLRP_MULTICAST_IPV4_ADDRESS_RESPONSE   239.255.250.134
269 #define ACN_LLRP_MULTICAST_IPV6_ADDRESS_REQUEST    ff18::85:0:0:85
270 #define ACN_LLRP_MULTICAST_IPV6_ADDRESS_RESPONSE   ff18::85:0:0:86
271 #define ACN_LLRP_PORT                              5569
272 #define ACN_LLRP_TIMEOUT                           2  /*seconds*/
273 #define ACN_LLRP_TARGET_TIMEOUT                    500 /*milliseconds*/
274 #define ACN_LLRP_MAX_BACKOFF                       1.5 /*seconds*/
275 #define ACN_LLRP_KNOWN_UID_SIZE                    200
276 #define ACN_LLRP_BROADCAST_CID                     FBAD822C-BD0C-4D4C-BDC8-7EABEBC85AFF
277 
278 /* E1.33 Table A-3  Vector Defines for Root Layer PDU */
279 /* (already defined above)
280  * #define ACN_PDU_VECTOR_ROOT_LLRP        0x0000000A
281  * #define ACN_PDU_VECTOR_ROOT_RPT         0x00000005
282  * #define ACN_PDU_VECTOR_ROOT_BROKER      0x00000009
283  * #define ACN_PDU_VECTOR_ROOT_EPT         0x0000000B
284  */
285 
286 /* E1.33 Table A-4  LLRP Messages */
287 #define RDMNET_LLRP_VECTOR_PROBE_REQUEST   0x00000001
288 #define RDMNET_LLRP_VECTOR_PROBE_REPLY     0x00000002
289 #define RDMNET_LLRP_VECTOR_RDM_CMD         0x00000003
290 
291 #define RDMNET_LLRP_VECTOR_PROBE_REQUEST_CLIENT_TCP_INACTIVE  0x01
292 #define RDMNET_LLRP_VECTOR_PROBE_REQUEST_BROKERS_ONLY         0x02
293 
294 #define RDMNET_LLRP_VECTOR_RDM_CMD_START_CODE                 0xCC
295 
296 /* E1.33 Table A-5  LLRP Probe Request Messages */
297 #define VECTOR_PROBE_REQUEST_DATA   0x01
298 
299 /* E1.33 Table A-6  LLRP Probe Reply Messages */
300 #define VECTOR_PROBE_REPLY_DATA     0x01
301 
302 /* E1.33 Table A-7  Broker Messages */
303 #define RDMNET_BROKER_VECTOR_CONNECT                 0x0001
304 #define RDMNET_BROKER_VECTOR_CONNECT_REPLY           0x0002
305 #define RDMNET_BROKER_VECTOR_CLIENT_ENTRY_UPDATE     0x0003
306 #define RDMNET_BROKER_VECTOR_REDIRECT_V4             0x0004
307 #define RDMNET_BROKER_VECTOR_REDIRECT_V6             0x0005
308 #define RDMNET_BROKER_VECTOR_FETCH_CLIENT_LIST       0x0006
309 #define RDMNET_BROKER_VECTOR_CONNECTED_CLIENT_LIST   0x0007
310 #define RDMNET_BROKER_VECTOR_CLIENT_ADD              0x0008
311 #define RDMNET_BROKER_VECTOR_CLIENT_REMOVE           0x0009
312 #define RDMNET_BROKER_VECTOR_CLIENT_ENTRY_CHANGE     0x000A
313 #define RDMNET_BROKER_VECTOR_REQUEST_DYNAMIC_UIDS    0x000B
314 #define RDMNET_BROKER_VECTOR_ASSIGNED_DYNAMIC_UIDS   0x000C
315 #define RDMNET_BROKER_VECTOR_FETCH_DYNAMIC_UID_LIST  0x000D
316 #define RDMNET_BROKER_VECTOR_DISCONNECT              0x000E
317 #define RDMNET_BROKER_VECTOR_NULL                    0x000F
318 
319 #define RDMNET_BROKER_VECTOR_CONNECT_INCREMENTAL_UPDATES  0x01
320 
321 /* E1.33 Table A-8  RPT Messages */
322 #define RDMNET_RPT_VECTOR_REQUEST        0x00000001
323 #define RDMNET_RPT_VECTOR_STATUS         0x00000002
324 #define RDMNET_RPT_VECTOR_NOTIFICATION   0x00000003
325 
326 /* E1.33 Table A-9  RPT Request PDUs */
327 #define RDMNET_RPT_VECTOR_REQUEST_RDM_CMD   0x01
328 
329 /* E1.33 Table A-10  RPT Status PDUs */
330 #define RDMNET_RPT_VECTOR_STATUS_UNKNOWN_RPT_UID         0x0001
331 #define RDMNET_RPT_VECTOR_STATUS_RDM_TIMEOUT             0x0002
332 #define RDMNET_RPT_VECTOR_STATUS_RDM_INVALID_RESPONSE    0x0003
333 #define RDMNET_RPT_VECTOR_STATUS_UNKNOWN_RDM_UID         0x0004
334 #define RDMNET_RPT_VECTOR_STATUS_UNKNOWN_ENDPOINT        0x0005
335 #define RDMNET_RPT_VECTOR_STATUS_BROADCAST_COMPLETE      0x0006
336 #define RDMNET_RPT_VECTOR_STATUS_UNKNOWN_VECTOR          0x0007
337 #define RDMNET_RPT_VECTOR_STATUS_INVALID_MESSAGE         0x0008
338 #define RDMNET_RPT_VECTOR_STATUS_INVALID_COMMAND_CLASS   0x0009
339 
340 /* E1.33 Table A-11  RPT Notification PDUs */
341 #define RDMNET_RPT_VECTOR_NOTIFICATION_RDM_CMD   0x01
342 
343 /* E1.33 Table A-12  RDM Command PDUs */
344 #define RDMNET_RPT_VECTOR_RDM_CMD_RD_DATA   0xCC
345 
346 /* E1.33 Table A-13  EPT PDUs */
347 #define RDMNET_EPT_VECTOR_DATA     0x00000001
348 #define RDMNET_EPT_VECTOR_STATUS   0x00000002
349 
350 /* E1.33 Table A-14  EPT Status PDUs */
351 #define RDMNET_EPT_VECTOR_UNKNOWN_CID      0x0001
352 #define RDMNET_EPT_VECTOR_UNKNOWN_VECTOR   0x0002
353 
354 /* E1.33 Table A-15  RDM Parameter IDs (only used in packet-rdm.c) */
355 
356 /* E1.33 Table A-16  RDM NACK Reason Codes (only used in packet-rdm.c) */
357 
358 /* E1.33 Table A-17 Static Config Types for Component Scope Messages (only used in packet-rdm.c) */
359 
360 /* E1.33 Table A-18 Broker States for Broker Status Messages (only used in packet-rdm.c) */
361 
362 /* E1.33 Table A-19 Connection Status Codes for Broker Connect */
363 #define RDMNET_BROKER_CONNECT_OK                     0x0000
364 #define RDMNET_BROKER_CONNECT_SCOPE_MISMATCH         0x0001
365 #define RDMNET_BROKER_CONNECT_CAPACITY_EXCEEDED      0x0002
366 #define RDMNET_BROKER_CONNECT_DUPLICATE_UID          0x0003
367 #define RDMNET_BROKER_CONNECT_INVALID_CLIENT_ENTRY   0x0004
368 #define RDMNET_BROKER_CONNECT_INVALID_UID            0x0005
369 
370 /* E1.33 Table A-20 Status Codes for Dynamic UID Mapping*/
371 #define RDMNET_DYNAMIC_UID_STATUS_OK                  0x0000
372 #define RDMNET_DYNAMIC_UID_STATUS_INVALID_REQUEST     0x0001
373 #define RDMNET_DYNAMIC_UID_STATUS_UID_NOT_FOUND       0x0002
374 #define RDMNET_DYNAMIC_UID_STATUS_DUPLICATE_RID       0x0003
375 #define RDMNET_DYNAMIC_UID_STATUS_CAPACITY_EXHAUSTED  0x0004
376 
377 /* E1.33 Table A-21 Client Protocol Codes */
378 #define RDMNET_CLIENT_PROTOCOL_RPT          0x00000005
379 #define RDMNET_CLIENT_PROTOCOL_EPT          0x0000000B
380 
381 /* E1.33 Table A-22 RPT Client Type Codes */
382 #define RDMNET_RPT_CLIENT_TYPE_DEVICE       0x00
383 #define RDMNET_RPT_CLIENT_TYPE_CONTROLLER   0x01
384 
385 /* E1.33 Table A-23 LLRP Component Type Codes - LLRP TARGETS */
386 #define RDMNET_LLRP_COMPONENT_TYPE_RPT_DEVICE       0x00 /* Target is a Device */
387 #define RDMNET_LLRP_COMPONENT_TYPE_RPT_CONTROLLER   0x01 /* Target is a Controller */
388 #define RDMNET_LLRP_COMPONENT_TYPE_BROKER           0x02 /* Target is a Broker */
389 #define RDMNET_LLRP_COMPONENT_TYPE_NON_RDMNET       0xFF /* Target does not implement RDMnet other than LLRP */
390 
391 /* E1.33 Table A-24 RPT Client Disconnect Reason Codes */
392 #define RDMNET_RPT_DISCONNECT_SHUTDOWN                   0x0000  /* Sent by Components to indicate that they are  */
393                                                                  /* about to shut down.                           */
394 #define RDMNET_RPT_DISCONNECT_CAPACITY_EXHAUSTED         0x0001  /* Sent by Components when they do not           */
395                                                                  /* have the ability to support this connection.  */
396                                                                  /* Note that a Component must reserve certain    */
397                                                                  /* resources to be able to send this message     */
398                                                                  /* when it is in such a state.                   */
399 #define RDMNET_RPT_DISCONNECT_HARDWARE_FAULT             0x0002  /* Sent by Components which must terminate a     */
400                                                                  /* connection due to an internal hardware fault  */
401 #define RDMNET_RPT_DISCONNECT_SOFTWARE_FAULT             0x0003  /* Sent by Components which must terminate a     */
402                                                                  /* connection due to a software fault.           */
403 #define RDMNET_RPT_DISCONNECT_SOFTWARE_RESET             0x0004  /* Sent by Components which must terminate a     */
404                                                                  /* connection because of a software reset.       */
405                                                                  /* This message should not be sent in the case   */
406                                                                  /* of a reboot, as the Shutdown message          */
407                                                                  /* is preferred.                                 */
408 #define RDMNET_RPT_DISCONNECT_INCORRECT_SCOPE            0x0005  /* Sent by Brokers that are not on the           */
409                                                                  /* desired Scope.                                */
410 #define RDMNET_RPT_DISCONNECT_RPT_RECONFIGURE            0x0006  /* Sent by components which must terminate a     */
411                                                                  /* connection because they were reconfigured     */
412                                                                  /* using RPT                                     */
413 #define RDMNET_RPT_DISCONNECT_LLRP_RECONFIGURE           0x0007  /* Sent by Components which must terminate a     */
414                                                                  /* connection because they were reconfigured     */
415                                                                  /* using LLRP.                                   */
416 #define RDMNET_RPT_DISCONNECT_USER_RECONFIGURE           0x0008  /* Sent by Components which must terminate a     */
417                                                                  /* connection because they were reconfigured     */
418                                                                  /* through some means outside the scope of this  */
419                                                                  /* standard (i.e. front panel configuration)     */
420 
421 typedef struct
422 {
423   guint32 start;
424   guint32 vector;
425   guint32 header;
426   guint32 data;
427   guint32 data_length;
428 } acn_pdu_offsets;
429 
430 typedef struct
431 {
432   guint8  flags;
433   guint32 address;  /* or first address */
434   guint32 increment;
435   guint32 count;
436   guint32 size;
437   guint32 data_length;
438 } acn_dmp_adt_type;
439 
440 /*
441  * See
442  * ANSI BSR E1.17 Architecture for Control Networks
443  * ANSI BSR E1.31
444  * ANSI BSR E1.33 RDMnet
445  */
446 
447 #define ACTUAL_ADDRESS  0
448 /* forward reference */
449 static guint32 acn_add_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, const char *label);
450 static int     dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
451 static int     dissect_rdmnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 data_offset, gboolean is_udp);
452 
453 /* Global variables */
454 static int proto_acn = -1;
455 static gint ett_acn = -1;
456 static gint ett_acn_channel_owner_info_block = -1;
457 static gint ett_acn_channel_member_info_block = -1;
458 static gint ett_acn_channel_parameter = -1;
459 static gint ett_acn_address = -1;
460 static gint ett_acn_address_type = -1;
461 static gint ett_acn_blob = -1;
462 static gint ett_acn_pdu_flags = -1;
463 static gint ett_acn_dmp_pdu = -1;
464 static gint ett_acn_sdt_pdu = -1;
465 static gint ett_acn_sdt_client_pdu = -1;
466 static gint ett_acn_sdt_base_pdu = -1;
467 static gint ett_acn_root_pdu = -1;
468 
469 static gint ett_acn_dmx_address = -1;
470 static gint ett_acn_dmx_2_options = -1;
471 static gint ett_acn_dmx_data_pdu = -1;
472 static gint ett_acn_dmx_pdu = -1;
473 
474 static gint ett_rdmnet_pdu_flags = -1;
475 static gint ett_rdmnet_llrp_base_pdu = -1;
476 static gint ett_rdmnet_llrp_probe_request_pdu = -1;
477 static gint ett_rdmnet_llrp_probe_request_filter_flags = -1;
478 static gint ett_rdmnet_llrp_probe_reply_pdu = -1;
479 static gint ett_rdmnet_llrp_rdm_command_pdu = -1;
480 
481 static gint ett_rdmnet_broker_base_pdu = -1;
482 static gint ett_rdmnet_broker_client_entry_pdu = -1;
483 static gint ett_rdmnet_broker_client_entry_manufacturer_protocol_ids = -1;
484 static gint ett_rdmnet_broker_connect_connection_flags = -1;
485 static gint ett_rdmnet_broker_client_entry_update_connection_flags = -1;
486 
487 static gint ett_rdmnet_rpt_base_pdu = -1;
488 static gint ett_rdmnet_rpt_request_pdu = -1;
489 static gint ett_rdmnet_rpt_status_pdu = -1;
490 static gint ett_rdmnet_rpt_notification_pdu = -1;
491 
492 static gint ett_rdmnet_ept_base_pdu = -1;
493 static gint ett_rdmnet_ept_data_pdu = -1;
494 static gint ett_rdmnet_ept_data_vector_pdu = -1;
495 static gint ett_rdmnet_ept_status_pdu = -1;
496 
497 /*  Register fields */
498 /* In alphabetical order */
499 static int hf_acn_association = -1;
500 static int hf_acn_blob = -1;
501 /* static int hf_acn_blob_dimmer_load_properties2_type = -1; */
502 static int hf_acn_blob_field_length = -1;
503 static int hf_acn_blob_field_type = -1;
504 static int hf_acn_blob_field_value_number = -1;
505 static int hf_acn_blob_field_value_number64 = -1;
506 static int hf_acn_blob_field_value_ipv4 = -1;
507 static int hf_acn_blob_field_value_ipv6 = -1;
508 static int hf_acn_blob_field_value_float = -1;
509 static int hf_acn_blob_field_value_double = -1;
510 static int hf_acn_blob_field_value_guid = -1;
511 static int hf_acn_blob_field_value_string = -1;
512 /* static int hf_acn_blob_metadata_types_type = -1; */
513 static int hf_acn_blob_range_number = -1;
514 /* static int hf_acn_blob_range_start = -1; */
515 static int hf_acn_blob_range_type = -1;
516 static int hf_acn_blob_tree_field_type = -1;
517 static int hf_acn_blob_type = -1;
518 static int hf_acn_blob_version = -1;
519 static int hf_acn_blob_time_zone = -1;
520 static int hf_acn_blob_dst_type = -1;
521 static int hf_acn_blob_dst_start_day = -1;
522 static int hf_acn_blob_dst_stop_day = -1;
523 static int hf_acn_blob_dst_start_locality = -1;
524 static int hf_acn_blob_dst_stop_locality = -1;
525 static int hf_acn_channel_number = -1;
526 static int hf_acn_cid = -1;
527 /* static int hf_acn_client_protocol_id = -1; */
528 static int hf_acn_data = -1;
529 static int hf_acn_data8 = -1;
530 static int hf_acn_data16 = -1;
531 static int hf_acn_data24 = -1;
532 static int hf_acn_data32 = -1;
533 /* static int hf_acn_dmp_adt = -1; */ /* address and data type*/
534 static int hf_acn_dmp_adt_a = -1;
535 static int hf_acn_dmp_adt_v = -1;
536 static int hf_acn_dmp_adt_r = -1;
537 static int hf_acn_dmp_adt_d = -1;
538 static int hf_acn_dmp_adt_x = -1;
539 static int hf_acn_dmp_reason_code = -1;
540 static int hf_acn_dmp_vector = -1;
541 static int hf_acn_dmp_actual_address = -1;
542 static int hf_acn_dmp_virtual_address = -1;
543 static int hf_acn_dmp_actual_address_first = -1;
544 static int hf_acn_dmp_virtual_address_first = -1;
545 static int hf_acn_expiry = -1;
546 static int hf_acn_first_member_to_ack = -1;
547 static int hf_acn_first_missed_sequence = -1;
548 static int hf_acn_ip_address_type = -1;
549 static int hf_acn_ipv4 = -1;
550 static int hf_acn_ipv6 = -1;
551 static int hf_acn_last_member_to_ack = -1;
552 static int hf_acn_last_missed_sequence = -1;
553 static int hf_acn_mak_threshold = -1;
554 static int hf_acn_member_id = -1;
555 static int hf_acn_nak_holdoff = -1;
556 static int hf_acn_nak_max_wait = -1;
557 static int hf_acn_nak_modulus = -1;
558 static int hf_acn_nak_outbound_flag = -1;
559 static int hf_acn_oldest_available_wrapper = -1;
560 static int hf_acn_packet_identifier = -1;
561 static int hf_acn_pdu = -1;
562 static int hf_acn_pdu_flag_d = -1;
563 static int hf_acn_pdu_flag_h = -1;
564 static int hf_acn_pdu_flag_l = -1;
565 static int hf_acn_pdu_flag_v = -1;
566 static int hf_acn_pdu_flags = -1;
567 static int hf_acn_pdu_length = -1;
568 static int hf_acn_port = -1;
569 static int hf_acn_postamble_size = -1;
570 static int hf_acn_preamble_size = -1;
571 static int hf_acn_protocol_id = -1;
572 static int hf_acn_reason_code = -1;
573 static int hf_acn_reciprocal_channel = -1;
574 static int hf_acn_refuse_code = -1;
575 static int hf_acn_reliable_sequence_number = -1;
576 static int hf_acn_adhoc_expiry = -1;
577 /* static int hf_acn_sdt_pdu = -1; */
578 static int hf_acn_sdt_vector = -1;
579 
580 static int hf_acn_dmx_vector = -1;
581 /* static int hf_acn_session_count = -1; */
582 static int hf_acn_total_sequence_number = -1;
583 static int hf_acn_dmx_source_name = -1;
584 static int hf_acn_dmx_priority = -1;
585 static int hf_acn_dmx_2_reserved = -1;
586 static int hf_acn_dmx_sequence_number = -1;
587 static int hf_acn_dmx_2_options = -1;
588 static int hf_acn_dmx_2_option_p = -1;
589 static int hf_acn_dmx_2_option_s = -1;
590 static int hf_acn_dmx_universe = -1;
591 
592 static int hf_acn_dmx_start_code = -1;
593 static int hf_acn_dmx_2_first_property_address = -1;
594 static int hf_acn_dmx_increment = -1;
595 static int hf_acn_dmx_count = -1;
596 static int hf_acn_dmx_2_start_code = -1;
597 static int hf_acn_dmx_data = -1;
598 
599 static int hf_acn_postamble_key_fingerprint = -1;
600 static int hf_acn_postamble_seq_type = -1;
601 static int hf_acn_postamble_seq_hi = -1;
602 static int hf_acn_postamble_seq_low = -1;
603 static int hf_acn_postamble_message_digest = -1;
604 
605 /* static int hf_acn_dmx_dmp_vector = -1; */
606 
607 /* Try heuristic ACN decode */
608 static gboolean global_acn_dmx_enable = FALSE;
609 static gint     global_acn_dmx_display_view = 0;
610 static gint     global_acn_dmx_display_line_format = 0;
611 static gboolean global_acn_dmx_display_zeros = FALSE;
612 static gboolean global_acn_dmx_display_leading_zeros = FALSE;
613 
614 static int proto_magic = -1;
615 static gint ett_magic = -1;
616 
617 /* Register fields */
618 static int hf_magic_protocol_id = -1;
619 static int hf_magic_pdu_subtype = -1;
620 static int hf_magic_major_version = -1;
621 static int hf_magic_minor_version = -1;
622 
623 static int hf_magic_v1command_vals = -1;
624 
625 static int hf_magic_command_vals = -1;
626 static int hf_magic_command_beacon_duration = -1;
627 static int hf_magic_command_tftp = -1;
628 static int hf_magic_command_reset_lease = -1;
629 static int hf_magic_command_cid = -1;
630 static int hf_magic_command_ip_configuration = -1;
631 static int hf_magic_command_ip_address = -1;
632 static int hf_magic_command_subnet_mask = -1;
633 static int hf_magic_command_gateway = -1;
634 
635 static int hf_magic_reply_ip_address = -1;
636 static int hf_magic_reply_subnet_mask = -1;
637 static int hf_magic_reply_gateway = -1;
638 static int hf_magic_reply_tftp = -1;
639 
640 static int hf_magic_reply_version = -1;
641 static int hf_magic_reply_device_type_name = -1;
642 static int hf_magic_reply_default_name = -1;
643 static int hf_magic_reply_user_name = -1;
644 static int hf_magic_reply_cid = -1;
645 static int hf_magic_reply_dcid = -1;
646 
647 static expert_field ei_magic_reply_invalid_type = EI_INIT;
648 
649 
650 static int proto_rdmnet = -1;
651 static gint ett_rdmnet = -1;
652 
653 /* Register fields */
654 static int hf_rdmnet_cid = -1;
655 static int hf_rdmnet_packet_identifier = -1;
656 static int hf_rdmnet_pdu = -1;
657 static int hf_rdmnet_pdu_flag_d = -1;
658 static int hf_rdmnet_pdu_flag_h = -1;
659 static int hf_rdmnet_pdu_flag_l = -1;
660 static int hf_rdmnet_pdu_flag_v = -1;
661 static int hf_rdmnet_pdu_flags = -1;
662 static int hf_rdmnet_pdu_length = -1;
663 static int hf_rdmnet_postamble_size = -1;
664 static int hf_rdmnet_preamble_size = -1;
665 static int hf_rdmnet_protocol_id = -1;
666 static int hf_rdmnet_tcp_length = -1;
667 
668 static int hf_rdmnet_llrp_vector = -1;
669 static int hf_rdmnet_llrp_destination_cid = -1;
670 static int hf_rdmnet_llrp_transaction_number = -1;
671 static int hf_rdmnet_llrp_probe_request_vector = -1;
672 static int hf_rdmnet_llrp_probe_request_pdu_length = -1;
673 static int hf_rdmnet_llrp_probe_request_lower_uid = -1;
674 static int hf_rdmnet_llrp_probe_request_upper_uid = -1;
675 static int hf_rdmnet_llrp_probe_request_filter = -1;
676 static int hf_rdmnet_llrp_probe_request_filter_client_tcp_inactive = -1;
677 static int hf_rdmnet_llrp_probe_request_filter_brokers_only = -1;
678 static int hf_rdmnet_llrp_probe_request_known_uid = -1;
679 
680 static int hf_rdmnet_llrp_probe_reply_vector = -1;
681 static int hf_rdmnet_llrp_probe_reply_uid = -1;
682 static int hf_rdmnet_llrp_probe_reply_hardware_address = -1;
683 static int hf_rdmnet_llrp_probe_reply_component_type = -1;
684 static int hf_rdmnet_llrp_rdm_command_start_code = -1;
685 
686 static int hf_rdmnet_rpt_vector = -1;
687 static int hf_rdmnet_rpt_source_uid = -1;
688 static int hf_rdmnet_rpt_source_endpoint_id = -1;
689 static int hf_rdmnet_rpt_destination_uid = -1;
690 static int hf_rdmnet_rpt_destination_endpoint_id = -1;
691 static int hf_rdmnet_rpt_sequence_number = -1;
692 static int hf_rdmnet_rpt_reserved = -1;
693 static int hf_rdmnet_rpt_request_vector = -1;
694 static int hf_rdmnet_rpt_request_rdm_command = -1;
695 static int hf_rdmnet_rpt_status_vector = -1;
696 static int hf_rdmnet_rpt_status_unknown_rpt_uid_string = -1;
697 static int hf_rdmnet_rpt_status_rdm_timeout_string = -1;
698 static int hf_rdmnet_rpt_status_rdm_invalid_response_string = -1;
699 static int hf_rdmnet_rpt_status_unknown_rdm_uid_string = -1;
700 static int hf_rdmnet_rpt_status_unknown_endpoint_string = -1;
701 static int hf_rdmnet_rpt_status_broadcast_complete_string = -1;
702 static int hf_rdmnet_rpt_status_unknown_vector_string = -1;
703 static int hf_rdmnet_rpt_notification_vector = -1;
704 static int hf_rdmnet_rpt_notification_rdm_command = -1;
705 
706 static int hf_rdmnet_broker_vector = -1;
707 static int hf_rdmnet_broker_client_protocol_vector = -1;
708 static int hf_rdmnet_broker_client_protocol_cid = -1;
709 static int hf_rdmnet_broker_client_rpt_client_uid = -1;
710 static int hf_rdmnet_broker_client_rpt_client_type = -1;
711 static int hf_rdmnet_broker_client_rpt_binding_cid = -1;
712 static int hf_rdmnet_broker_client_ept_protocol_vector = -1;
713 static int hf_rdmnet_broker_client_ept_protocol_manufacturer_id = -1;
714 static int hf_rdmnet_broker_client_ept_protocol_protocol_id = -1;
715 static int hf_rdmnet_broker_client_ept_protocol_string = -1;
716 static int hf_rdmnet_broker_connect_client_scope = -1;
717 static int hf_rdmnet_broker_connect_e133_version = -1;
718 static int hf_rdmnet_broker_connect_search_domain = -1;
719 static int hf_rdmnet_broker_connect_connection_flags = -1;
720 static int hf_rdmnet_broker_connect_connection_flags_incremental_updates = -1;
721 static int hf_rdmnet_broker_connect_reply_connection_code = -1;
722 static int hf_rdmnet_broker_connect_reply_e133_version = -1;
723 static int hf_rdmnet_broker_connect_reply_broker_uid = -1;
724 static int hf_rdmnet_broker_connect_reply_client_uid = -1;
725 static int hf_rdmnet_broker_client_entry_update_connection_flags = -1;
726 static int hf_rdmnet_broker_client_entry_update_connection_flags_incremental_updates = -1;
727 static int hf_rdmnet_broker_redirect_ipv4_address = -1;
728 static int hf_rdmnet_broker_redirect_ipv4_tcp_port = -1;
729 static int hf_rdmnet_broker_redirect_ipv6_address = -1;
730 static int hf_rdmnet_broker_redirect_ipv6_tcp_port = -1;
731 static int hf_rdmnet_broker_disconnect_reason = -1;
732 static int hf_rdmnet_broker_dynamic_uid_request = -1;
733 static int hf_rdmnet_broker_rid = -1;
734 static int hf_rdmnet_broker_assigned_dynamic_uid = -1;
735 static int hf_rdmnet_broker_assigned_rid = -1;
736 static int hf_rdmnet_broker_assigned_status_code = -1;
737 static int hf_rdmnet_broker_fetch_dynamic_uid = -1;
738 
739 static int hf_rdmnet_ept_vector = -1;
740 static int hf_rdmnet_ept_destination_cid = -1;
741 static int hf_rdmnet_ept_data_pdu_length = -1;
742 static int hf_rdmnet_ept_data_vector = -1;
743 static int hf_rdmnet_ept_data_vector_manufacturer_id = -1;
744 static int hf_rdmnet_ept_data_vector_protocol_id = -1;
745 static int hf_rdmnet_ept_data_opaque_data = -1;
746 static int hf_rdmnet_ept_status_pdu_length = -1;
747 static int hf_rdmnet_ept_status_vector = -1;
748 static int hf_rdmnet_ept_status_unknown_cid = -1;
749 static int hf_rdmnet_ept_status_status_string = -1;
750 static int hf_rdmnet_ept_status_unknown_vector = -1;
751 static int hf_rdmnet_ept_status_vector_string = -1;
752 
753 static const value_string acn_protocol_id_vals[] = {
754   { ACN_PROTOCOL_ID_SDT,    "SDT Protocol" },
755   { ACN_PROTOCOL_ID_DMP,    "DMP Protocol" },
756   { ACN_PROTOCOL_ID_DMX,    "DMX Protocol" },
757   { ACN_PROTOCOL_ID_DMX_2,  "Ratified DMX Protocol" },
758   { ACN_PROTOCOL_ID_RPT,    "RDM Packet Transport Protocol" },
759   { ACN_PROTOCOL_ID_BROKER, "Broker Protocol" },
760   { ACN_PROTOCOL_ID_LLRP,   "Low Level Recovery Protocol" },
761   { ACN_PROTOCOL_ID_EPT,    "Extensible Packet Transport Protocol" },
762   { ACN_PROTOCOL_ID_DMX_3,  "Pathway Connectivity Secure DMX Protocol" },
763   { 0,       NULL },
764 };
765 
766 static const value_string acn_dmp_adt_r_vals[] = {
767   { ACN_DMP_ADT_R_RELATIVE, "Relative" },
768   { ACN_DMP_ADT_R_ABSOLUTE, "Absolute" },
769   { 0,       NULL },
770 };
771 
772 static const value_string acn_dmp_adt_v_vals[] = {
773   { ACN_DMP_ADT_V_ACTUAL,  "Actual" },
774   { ACN_DMP_ADT_V_VIRTUAL, "Virtual" },
775   { 0,       NULL },
776 };
777 
778 static const value_string acn_dmp_adt_d_vals[] = {
779   { ACN_DMP_ADT_D_NS, "Non-range, single data item" },
780   { ACN_DMP_ADT_D_RS, "Range, single data item" },
781   { ACN_DMP_ADT_D_RE, "Range, array of equal size data items" },
782   { ACN_DMP_ADT_D_RM, "Range, series of mixed size data items" },
783   { 0,       NULL },
784 };
785 
786 static const value_string acn_dmp_adt_a_vals[] = {
787   { ACN_DMP_ADT_A_1, "1 octet" },
788   { ACN_DMP_ADT_A_2, "2 octets" },
789   { ACN_DMP_ADT_A_4, "4 octets" },
790   { ACN_DMP_ADT_A_R, "reserved" },
791   { 0,       NULL },
792 };
793 
794 
795 static const value_string acn_sdt_vector_vals[] = {
796   { ACN_SDT_VECTOR_UNKNOWN,        "Unknown"},
797   { ACN_SDT_VECTOR_REL_WRAP,       "Reliable Wrapper"},
798   { ACN_SDT_VECTOR_UNREL_WRAP,     "Unreliable Wrapper"},
799   { ACN_SDT_VECTOR_CHANNEL_PARAMS, "Channel Parameters"},
800   { ACN_SDT_VECTOR_JOIN,           "Join"},
801   { ACN_SDT_VECTOR_JOIN_REFUSE,    "Join Refuse"},
802   { ACN_SDT_VECTOR_JOIN_ACCEPT,    "Join Accept"},
803   { ACN_SDT_VECTOR_LEAVE,          "Leave"},
804   { ACN_SDT_VECTOR_LEAVING,        "Leaving"},
805   { ACN_SDT_VECTOR_CONNECT,        "Connect"},
806   { ACN_SDT_VECTOR_CONNECT_ACCEPT, "Connect Accept"},
807   { ACN_SDT_VECTOR_CONNECT_REFUSE, "Connect Refuse"},
808   { ACN_SDT_VECTOR_DISCONNECT,     "Disconnect"},
809   { ACN_SDT_VECTOR_DISCONNECTING,  "Disconnecting"},
810   { ACN_SDT_VECTOR_ACK,            "Ack"},
811   { ACN_SDT_VECTOR_NAK,            "Nak"},
812   { ACN_SDT_VECTOR_GET_SESSION,    "Get Session"},
813   { ACN_SDT_VECTOR_SESSIONS,       "Sessions"},
814   { 0,       NULL },
815 };
816 
817 static const value_string acn_dmx_vector_vals[] = {
818   { ACN_DMX_VECTOR,  "Streaming DMX"},
819   { 0,       NULL },
820 };
821 
822 static const value_string acn_blob_advanced_features_operation_field_name[] = {
823   { 1, "Operation Type" },
824   { 2, "Use Controlled Loads" },
825   { 3, "Start Dimmer Address" },
826   { 4, "End Dimmer Address" },
827   { 5, "Space" },
828   { 0, NULL }
829 };
830 
831 static const value_string acn_blob_dimmer_load_properties2_field_name[] = {
832   { 1, "System" },
833   { 2, "Processor" },
834   { 3, "Rack" },
835   { 4, "Lug" },
836   { 5, "Module" },
837   { 6, "Station" },
838   { 7, "Port" },
839   { 8, "Subdevice" },
840   { 9, "Space" },
841   { 10, "UDN" },
842   { 11, "Reserved" },
843   { 12, "Is Load Recorded" },
844   { 13, "Output Voltage Step 1" },
845   { 14, "Output Voltage Step 2" },
846   { 15, "Output Voltage Step 3" },
847   { 16, "Output Voltage Step 4" },
848   { 17, "Output Voltage Step 5" },
849   { 18, "Output Voltage Step 6" },
850   { 19, "Output Voltage Step 7" },
851   { 20, "Output Voltage Step 8" },
852   { 21, "Output Voltage Step 9" },
853   { 22, "Output Voltage Step 10" },
854   { 23, "Output Voltage Step 11" },
855   { 24, "Output Voltage Step 12" },
856   { 25, "Output Voltage Step 13" },
857   { 26, "Output Voltage Step 14" },
858   { 27, "Output Voltage Step 15" },
859   { 28, "Output Voltage Step 16" },
860   { 29, "Output Voltage Step 17" },
861   { 30, "Output Voltage Step 18" },
862   { 31, "Output Voltage Step 19" },
863   { 32, "Output Voltage Step 20" },
864   { 33, "Amperage Step 1" },
865   { 34, "Amperage Step 2" },
866   { 35, "Amperage Step 3" },
867   { 36, "Amperage Step 4" },
868   { 37, "Amperage Step 5" },
869   { 38, "Amperage Step 6" },
870   { 39, "Amperage Step 7" },
871   { 40, "Amperage Step 8" },
872   { 41, "Amperage Step 9" },
873   { 42, "Amperage Step 10" },
874   { 43, "Amperage Step 11" },
875   { 44, "Amperage Step 12" },
876   { 45, "Amperage Step 13" },
877   { 46, "Amperage Step 14" },
878   { 47, "Amperage Step 15" },
879   { 48, "Amperage Step 16" },
880   { 49, "Amperage Step 17" },
881   { 50, "Amperage Step 18" },
882   { 51, "Amperage Step 19" },
883   { 52, "Amperage Step 20" },
884   { 53, "Voltage Time Step 1" },
885   { 54, "Voltage Time Step 2" },
886   { 55, "Voltage Time Step 3" },
887   { 56, "Voltage Time Step 4" },
888   { 57, "Voltage Time Step 5" },
889   { 58, "Voltage Time Step 6" },
890   { 59, "Voltage Time Step 7" },
891   { 60, "Voltage Time Step 8" },
892   { 61, "Voltage Time Step 9" },
893   { 62, "Voltage Time Step 10" },
894   { 63, "Voltage Time Step 11" },
895   { 64, "Voltage Time Step 12" },
896   { 65, "Voltage Time Step 13" },
897   { 66, "Voltage Time Step 14" },
898   { 67, "Voltage Time Step 15" },
899   { 68, "Voltage Time Step 16" },
900   { 69, "Voltage Time Step 17" },
901   { 70, "Voltage Time Step 18" },
902   { 71, "Voltage Time Step 19" },
903   { 72, "Voltage Time Step 20" },
904   { 73, "Is Rig Check Recorded" },
905   { 74, "Recorded Level" },
906   { 75, "Recorded Current" },
907   { 0, NULL }
908 };
909 static value_string_ext acn_blob_dimmer_load_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_load_properties2_field_name);
910 
911 static const value_string acn_blob_dimmer_properties2_field_name[] = {
912   { 1, "System" },
913   { 2, "Processor" },
914   { 3, "Rack" },
915   { 4, "Lug" },
916   { 5, "Module" },
917   { 6, "Station" },
918   { 7, "Port" },
919   { 8, "Subdevice" },
920   { 9, "Space" },
921   { 10, "UDN" },
922   { 11, "Reserved" },
923   { 12, "Dimmer Name" },
924   { 13, "Dimmer Module" },
925   { 14, "Dimmer Mode" },
926   { 15, "Dimmer Control" },
927   { 16, "Dimmer Curve" },
928   { 17, "Off Level Percent" },
929   { 18, "On Level Percent" },
930   { 19, "On Time(sec)" },
931   { 20, "Off Time(sec)" },
932   { 21, "Dimmer AF Enabled" },
933   { 22, "Threshold" },
934   { 23, "Min Scale" },
935   { 24, "Unregulated Min Scale" },
936   { 25, "Max Scale" },
937   { 26, "Unregulated Max Scale" },
938   { 27, "Voltage Regulation" },
939   { 28, "Preheat Enable" },
940   { 29, "Preheat Time" },
941   { 30, "DC Output Prevent" },
942   { 31, "Inrush Protect" },
943   { 32, "AF Sensitivity" },
944   { 33, "AF Reaction Time" },
945   { 34, "Scale Load" },
946   { 35, "PTIO" },
947   { 36, "Allow In Preset" },
948   { 37, "Allow In Panic" },
949   { 38, "Allow In Panic DD" },
950   { 39, "Report No Loads" },
951   { 40, "Loads Error Reporting Enabled" },
952   { 41, "New Dimmer Space Number" },
953   { 42, "New Dimmer Number" },
954   { 43, "DMX A Patch" },
955   { 44, "DMX B Patch" },
956   { 45, "sACN Patch" },
957   { 46, "DMX A Patch DD" },
958   { 47, "DMX B Patch DD" },
959   { 48, "sACN Patch DD" },
960   { 49, "DMX A 16-bit Enable" },
961   { 40, "DMX B 16-bit Enable" },
962   { 51, "sACN 16-bit Enable" },
963   { 52, "Dimmer Zone" },
964   { 0, NULL }
965 };
966 static value_string_ext acn_blob_dimmer_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_properties2_field_name);
967 
968 static const value_string acn_blob_dimmer_rack_properties2_field_name[] = {
969   { 1, "System" },
970   { 2, "Processor" },
971   { 3, "Rack" },
972   { 4, "Lug" },
973   { 5, "Module" },
974   { 6, "Station" },
975   { 7, "Port" },
976   { 8, "Subdevice" },
977   { 9, "Space" },
978   { 10, "UDN" },
979   { 11, "Reserved" },
980   { 12, "Rack CID" },
981   { 13, "Rack Number" },
982   { 14, "Rack Name" },
983   { 15, "Rack Model" },
984   { 16, "Rack AF Enable" },
985   { 17, "Temperature Format" },
986   { 18, "Data Loss Behavior DMX A" },
987   { 19, "Data Loss Behavior DMX B" },
988   { 20, "Data Loss Behavior sACN" },
989   { 21, "Data Loss Cross/Wait Time DMX A" },
990   { 22, "Data Loss Cross/Wait Time DMX B" },
991   { 23, "Data Loss Wait Time sACN" },
992   { 24, "Data Loss Fade Time DMX A" },
993   { 25, "Data Loss Fade Time DMX B" },
994   { 26, "Data Loss Fade Time sACN" },
995   { 27, "Data Loss Preset DMX A" },
996   { 28, "Data Loss Preset DMX B" },
997   { 29, "Data Loss Preset sACN" },
998   { 20, "Data Port Priority DMX A" },
999   { 31, "Data Port Priority DMX B" },
1000   { 32, "Data Port Enabled DMX A" },
1001   { 33, "Data Port Enabled DMX B" },
1002   { 34, "Data Port Enabled sACN" },
1003   { 35, "16 Bit Enabled DMX A" },
1004   { 36, "16 Bit Enabled DMX B" },
1005   { 37, "16 Bit Enabled sACN" },
1006   { 38, "Patch From Home Screen" },
1007   { 39, "SCR Off Time" },
1008   { 30, "Time Mode" },
1009   { 41, "Offset from UTC" },
1010   { 42, "Universal Hold Last Look Time" },
1011   { 43, "Reactivate Presets On Boot" },
1012   { 44, "Voltage High Warning Level" },
1013   { 45, "Temperature High Warning Level" },
1014   { 46, "Fan Operation Timing" },
1015   { 47, "Allow Backplane Communication Errors" },
1016   { 48, "Activate Presets on Boot" },
1017   { 49, "SmartLink2 Power Supply Enable" },
1018   { 40, "Remote Record Enable" },
1019   { 51, "System Number" },
1020   { 52, "Architectural Priority" },
1021   { 53, "Data Loss Preset Space DMX A" },
1022   { 54, "Data Loss Preset Space DMX B" },
1023   { 55, "Arch. Off Behavior" },
1024   { 0, NULL }
1025 };
1026 static value_string_ext acn_blob_dimmer_rack_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_properties2_field_name);
1027 
1028 static const value_string acn_blob_dimmer_rack_status_properties2_field_name[] = {
1029   { 1, "System" },
1030   { 2, "Processor" },
1031   { 3, "Rack" },
1032   { 4, "Lug" },
1033   { 5, "Module" },
1034   { 6, "Station" },
1035   { 7, "Port" },
1036   { 8, "Subdevice" },
1037   { 9, "Space" },
1038   { 10, "UDN" },
1039   { 11, "Reserved" },
1040   { 12, "CPU Temperature" },
1041   { 13, "Time of Last Reboot" },
1042   { 14, "Time Now" },
1043   { 15, "Rack Phasing" },
1044   { 16, "Power Frequency" },
1045   { 17, "Phase A Voltage" },
1046   { 18, "Phase B Voltage" },
1047   { 19, "Phase C Voltage" },
1048   { 20, "DMX A Port Status" },
1049   { 21, "DMX B Port Status" },
1050   { 22, "Active Preset Group IDs" },
1051   { 23, "Active Preset Group ID[0]" },
1052   { 24, "Active Preset Group ID[1]" },
1053   { 25, "Active Preset Group ID[2]" },
1054   { 26, "Active Preset Group ID[3]" },
1055   { 27, "Active Preset Group ID[4]" },
1056   { 28, "Active Preset Group ID[5]" },
1057   { 29, "Active Preset Group ID[6]" },
1058   { 30, "Active Preset Group ID[7]" },
1059   { 31, "Active Preset Group ID[8]" },
1060   { 32, "Active Preset Group ID[9]" },
1061   { 33, "Active Preset Group ID[10]" },
1062   { 34, "Active Preset Group ID[11]" },
1063   { 35, "Active Preset Group ID[12]" },
1064   { 36, "Active Preset Group ID[13]" },
1065   { 37, "Active Preset Group ID[14]" },
1066   { 38, "Active Preset Group ID[15]" },
1067   { 39, "Active Preset Group ID[16]" },
1068   { 40, "Active Preset Group ID[17]" },
1069   { 41, "Active Preset Group ID[18]" },
1070   { 42, "Active Preset Group ID[19]" },
1071   { 43, "Active Preset Group ID[20]" },
1072   { 44, "Active Preset Group ID[21]" },
1073   { 45, "Active Preset Group ID[22]" },
1074   { 46, "Active Preset Group ID[23]" },
1075   { 47, "Active Preset Group ID[24]" },
1076   { 48, "Active Preset Group ID[25]" },
1077   { 49, "Active Preset Group ID[26]" },
1078   { 50, "Active Preset Group ID[27]" },
1079   { 51, "Active Preset Group ID[28]" },
1080   { 52, "Active Preset Group ID[29]" },
1081   { 53, "Active Preset Group ID[30]" },
1082   { 54, "Active Preset Group ID[31]" },
1083   { 55, "Active Preset Group ID[32]" },
1084   { 56, "Active Preset Group ID[33]" },
1085   { 57, "Active Preset Group ID[34]" },
1086   { 58, "Active Preset Group ID[35]" },
1087   { 59, "Active Preset Group ID[36]" },
1088   { 60, "Active Preset Group ID[37]" },
1089   { 61, "Active Preset Group ID[38]" },
1090   { 62, "Active Preset Group ID[39]" },
1091   { 63, "Active Preset Group ID[40]" },
1092   { 64, "Active Preset Group ID[41]" },
1093   { 65, "Active Preset Group ID[42]" },
1094   { 66, "Active Preset Group ID[43]" },
1095   { 67, "Active Preset Group ID[44]" },
1096   { 68, "Active Preset Group ID[45]" },
1097   { 69, "Active Preset Group ID[46]" },
1098   { 70, "Active Preset Group ID[47]" },
1099   { 71, "Active Preset Group ID[48]" },
1100   { 72, "Active Preset Group ID[49]" },
1101   { 73, "Active Preset Group ID[50]" },
1102   { 74, "Active Preset Group ID[51]" },
1103   { 75, "Active Preset Group ID[52]" },
1104   { 76, "Active Preset Group ID[53]" },
1105   { 77, "Active Preset Group ID[54]" },
1106   { 78, "Active Preset Group ID[55]" },
1107   { 79, "Active Preset Group ID[56]" },
1108   { 80, "Active Preset Group ID[57]" },
1109   { 81, "Active Preset Group ID[58]" },
1110   { 82, "Active Preset Group ID[59]" },
1111   { 83, "Active Preset Group ID[60]" },
1112   { 84, "Active Preset Group ID[61]" },
1113   { 85, "Active Preset Group ID[62]" },
1114   { 86, "Active Preset Group ID[63]" },
1115   { 87, "Rack AF State" },
1116   { 88, "Number of Stored Presets for This Rack" },
1117   { 89, "Number of Lugs in This Rack" },
1118   { 90, "DSP Version" },
1119   { 91, "AF Card Version Slot 1" },
1120   { 92, "AF Card Version Slot 2" },
1121   { 93, "AF Card Version Slot 3" },
1122   { 94, "AF Card Version Slot 4" },
1123   { 95, "HCS08 Version" },
1124   { 96, "FPGA Version" },
1125   { 97, "Upload Progress AF Card 1" },
1126   { 98, "Upload Progress AF Card 2" },
1127   { 99, "Upload Progress AF Card 3" },
1128   { 100, "Upload Progress AF Card 4" },
1129   { 0, NULL }
1130 };
1131 static value_string_ext acn_blob_dimmer_rack_status_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_status_properties2_field_name);
1132 
1133 static const value_string acn_blob_dimmer_status_properties2_field_name[] = {
1134   { 1, "System" },
1135   { 2, "Processor" },
1136   { 3, "Rack" },
1137   { 4, "Lug" },
1138   { 5, "Module" },
1139   { 6, "Station" },
1140   { 7, "Port" },
1141   { 8, "Subdevice" },
1142   { 9, "Space" },
1143   { 10, "UDN" },
1144   { 11, "Reserved" },
1145   { 12, "Source Winning Control" },
1146   { 13, "Priority of Winning Source" },
1147   { 14, "Winning Level" },
1148   { 15, "Winning DMX A Level" },
1149   { 16, "Winning DMX B Level" },
1150   { 17, "Winning sACN Level" },
1151   { 18, "Source Winning Control DD" },
1152   { 19, "Priority of Winning Source DD" },
1153   { 20, "Winning Level DD" },
1154   { 21, "Winning DMX A Level DD" },
1155   { 22, "Winning DMX B Level DD" },
1156   { 23, "Winning DMX sACN Level DD" },
1157   { 24, "Actual Load" },
1158   { 25, "Load Status" },
1159   { 0, NULL }
1160 };
1161 static value_string_ext acn_blob_dimmer_status_properties2_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_status_properties2_field_name);
1162 
1163 
1164 static const value_string acn_blob_direct_control_operation_field_name[] = {
1165   { 1, "Space" },
1166   { 2, "Dimmer Number" },
1167   { 3, "DD Side" },
1168   { 4, "Level" },
1169   { 5, "Priority" },
1170   { 0, NULL }
1171 };
1172 
1173 static const value_string acn_blob_error3_field_name[] = {
1174   { 1, "System" },
1175   { 2, "Processor" },
1176   { 3, "Rack" },
1177   { 4, "Lug" },
1178   { 5, "Module" },
1179   { 6, "Station" },
1180   { 7, "Port" },
1181   { 8, "Subdevice" },
1182   { 9, "Space" },
1183   { 10, "UDN" },
1184   { 11, "sACN Address" },
1185   { 12, "Error Type" },
1186   { 13, "Severity" },
1187   { 14, "Timestamp" },
1188   { 15, "Error Text" },
1189   { 0, NULL }
1190 };
1191 
1192 static const value_string acn_blob_field_type_vals[] = {
1193   { ACN_BLOB_FIELD_TYPE1, "1 Byte Signed Integer" },
1194   { ACN_BLOB_FIELD_TYPE2, "2 Bytes Signed Integer" },
1195   { ACN_BLOB_FIELD_TYPE3, "4 Bytes Signed Integer" },
1196   { ACN_BLOB_FIELD_TYPE4, "8 Bytes Signed Integer" },
1197   { ACN_BLOB_FIELD_TYPE5, "1 Byte Unsigned Integer" },
1198   { ACN_BLOB_FIELD_TYPE6, "2 Bytes Unsigned Integer" },
1199   { ACN_BLOB_FIELD_TYPE7, "4 Bytes Unsigned Integer" },
1200   { ACN_BLOB_FIELD_TYPE8, "8 Bytes Unsigned Integer" },
1201   { ACN_BLOB_FIELD_TYPE9, "Float" },
1202   { ACN_BLOB_FIELD_TYPE10, "Double" },
1203   { ACN_BLOB_FIELD_TYPE11, "Variblob" },
1204   { ACN_BLOB_FIELD_TYPE12, "Ignore" },
1205   { 0, NULL }
1206 };
1207 
1208 static const value_string acn_blob_generate_config_operation_field_name[] = {
1209   { 1, "First Dimmer" },
1210   { 2, "Numbering Style" },
1211   { 3, "Use Dimmer Doubling" },
1212   { 4, "Default Module Type" },
1213   { 0, NULL }
1214 };
1215 
1216 static const value_string acn_blob_ip_field_name[] = {
1217   { 1, "IP Address" },
1218   { 2, "Subnet Mask" },
1219   { 3, "Gateway" },
1220   { 0, NULL }
1221 };
1222 
1223 static const value_string acn_blob_error1_field_name[] = {
1224   { 1, "System" },
1225   { 2, "Processor" },
1226   { 3, "Rack" },
1227   { 4, "Lug" },
1228   { 5, "Module" },
1229   { 6, "Station" },
1230   { 7, "Port" },
1231   { 8, "Subdevice" },
1232   /*{9,  "Space"}, */
1233   { 9, "UDN" },
1234   { 10, "sACN Address" },
1235   { 11, "Error Type" },
1236   { 12, "Severity" },
1237   { 13, "Timestamp" },
1238   { 14, "Error Text" },
1239   { 0, NULL }
1240 };
1241 
1242 static const value_string acn_blob_error2_field_name[] = {
1243   { 1, "System" },
1244   { 2, "Processor" },
1245   { 3, "Rack" },
1246   { 4, "Lug" },
1247   { 5, "Module" },
1248   { 6, "Station" },
1249   { 7, "Port" },
1250   { 8, "Subdevice" },
1251   { 9, "Space" },
1252   { 10, "UDN" },
1253   { 11, "sACN Address" },
1254   { 12, "Error Type" },
1255   { 13, "Severity" },
1256   { 14, "Timestamp" },
1257   { 15, "Error Text" },
1258   { 0, NULL }
1259 };
1260 
1261 static const value_string acn_blob_metadata_devices_field_name[] = {
1262   { 1, "Device Type" },
1263   { 2, "Identifier Name 1" },
1264   { 3, "Identifier Name 2" },
1265   { 4, "Identifier Name 3" },
1266   { 5, "Identifier Name 4" },
1267   { 0, NULL }
1268 };
1269 
1270 static const value_string acn_blob_metadata_field_name[] = {
1271   { 1, "Device Type" },
1272   { 2, "Metadata Type" },
1273   { 3, "Identifier Name 1" },
1274   { 4, "Identifier Name 2" },
1275   { 5, "Identifier Name 3" },
1276   { 6, "Identifier Name 4" },
1277   { 7, "Metadata 1" },
1278   { 8, "Metadata 2" },
1279   { 9, "Metadata 3" },
1280   { 10, "Metadata 4" },
1281   { 11, "Metadata 5" },
1282   { 12, "Metadata 6" },
1283   { 13, "Metadata 7" },
1284   { 14, "Metadata 8" },
1285   { 15, "Device CID" },
1286   { 0, NULL }
1287 };
1288 
1289 static const value_string acn_blob_metadata_types_field_name[] = {
1290   { 1, "Metadata Type" },
1291   { 2, "Identifier Name 1" },
1292   { 3, "Identifier Name 2" },
1293   { 4, "Identifier Name 3" },
1294   { 5, "Identifier Name 4" },
1295   { 6, "Identifier Name 5" },
1296   { 7, "Identifier Name 6" },
1297   { 8, "Identifier Name 7" },
1298   { 9, "Identifier Name 8" },
1299   { 0, NULL }
1300 };
1301 
1302 static const value_string acn_blob_time1_field_name[] = {
1303   { 1, "Time" },
1304   { 2, "Time Zone Name" },
1305   { 3, "Time Zone Offset Hour" },
1306   { 4, "Time Zone Offset Min" },
1307   { 5, "Time Zone Offset Sec" },
1308   { 6, "DST Name" },
1309   { 7, "Start Month" },
1310   { 8, "Start Week" },
1311   { 9, "Start Day" },
1312   { 10, "End Month" },
1313   { 11, "End Week" },
1314   { 12, "End Day" },
1315   { 13, "Timed Event Update" },
1316   { 0, NULL }
1317 };
1318 
1319 static const value_string acn_blob_dimmer_properties1_field_name[] = {
1320   { 1, "System" },
1321   { 2, "Processor" },
1322   { 3, "Rack" },
1323   { 4, "Lug" },
1324   { 5, "Module" },
1325   { 6, "Station" },
1326   { 7, "Port" },
1327   { 8, "Subdevice" },
1328   { 9, "Space" },
1329   { 10, "UDN" },
1330   { 11, "Reserved" },
1331   { 12, "Dimmer Name" },
1332   { 13, "Dimmer Module" },
1333   { 14, "Dimmer Mode" },
1334   { 15, "Dimmer Control" },
1335   { 16, "Dimmer Curve" },
1336   { 17, "On Level Percent" },
1337   { 18, "Off Level Percent" },
1338   { 19, "On Time(sec)" },
1339   { 20, "Off Time(sec)" },
1340   { 21, "Dimmer AF Enabled" },
1341   { 22, "Threshold" },
1342   { 23, "Min Scale" },
1343   { 24, "Unregulated Min Scale" },
1344   { 25, "Max Scale" },
1345   { 26, "Unregulated Max Scale" },
1346   { 27, "Voltage Regulation" },
1347   { 28, "Preheat Enable" },
1348   { 29, "Preheat Time" },
1349   { 30, "DC Output Prevent" },
1350   { 31, "Inrush Protect" },
1351   { 32, "AF Sensitivity" },
1352   { 33, "AF Reaction Time" },
1353   { 34, "Scale Load" },
1354   { 35, "PTIO" },
1355   { 36, "Allow In Preset" },
1356   { 37, "Allow In Panic" },
1357   { 38, "Allow In Panic DD" },
1358   /*{39, "Loads Reporting Mode"},
1359   {40, "New Dimmer Space Number"}, */
1360   { 39, "Report No Loads Enable" },
1361   { 40, "Loads Error Reporting Enable" },
1362   { 41, "Dimmer Space" },
1363   { 42, "New Dimmer Number" },
1364   { 43, "DMX A Patch" },
1365   { 44, "DMX B Patch" },
1366   { 45, "sACN Patch" },
1367   { 46, "DMX A Patch DD" },
1368   { 47, "DMX B Patch DD" },
1369   { 48, "sACN Patch DD" },
1370   { 0, NULL }
1371 };
1372 static value_string_ext acn_blob_dimmer_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_properties1_field_name);
1373 
1374 static const value_string acn_blob_dimmer_load_properties1_field_name[] = {
1375   { 1, "System" },
1376   { 2, "Processor" },
1377   { 3, "Rack" },
1378   { 4, "Lug" },
1379   { 5, "Module" },
1380   { 6, "Station" },
1381   { 7, "Port" },
1382   { 8, "Subdevice" },
1383   { 9, "Space" },
1384   { 10, "UDN" },
1385   { 11, "Reserved" },
1386   { 12, "Is Load Recorded" },
1387   { 13, "Output Voltage Step 1" },
1388   { 14, "Output Voltage Step 2" },
1389   { 15, "Output Voltage Step 3" },
1390   { 16, "Output Voltage Step 4" },
1391   { 17, "Output Voltage Step 5" },
1392   { 18, "Output Voltage Step 6" },
1393   { 19, "Output Voltage Step 7" },
1394   { 20, "Output Voltage Step 8" },
1395   { 21, "Output Voltage Step 9" },
1396   { 22, "Output Voltage Step 10" },
1397   { 23, "Output Voltage Step 11" },
1398   { 24, "Output Voltage Step 12" },
1399   { 25, "Output Voltage Step 13" },
1400   { 26, "Output Voltage Step 14" },
1401   { 27, "Output Voltage Step 15" },
1402   { 28, "Output Voltage Step 16" },
1403   { 29, "Output Voltage Step 17" },
1404   { 30, "Output Voltage Step 18" },
1405   { 31, "Output Voltage Step 19" },
1406   { 32, "Output Voltage Step 20" },
1407   { 33, "Amperage Step 1" },
1408   { 34, "Amperage Step 2" },
1409   { 35, "Amperage Step 3" },
1410   { 36, "Amperage Step 4" },
1411   { 37, "Amperage Step 5" },
1412   { 38, "Amperage Step 6" },
1413   { 39, "Amperage Step 7" },
1414   { 40, "Amperage Step 8" },
1415   { 41, "Amperage Step 9" },
1416   { 42, "Amperage Step 10" },
1417   { 43, "Amperage Step 11" },
1418   { 44, "Amperage Step 12" },
1419   { 45, "Amperage Step 13" },
1420   { 46, "Amperage Step 14" },
1421   { 47, "Amperage Step 15" },
1422   { 48, "Amperage Step 16" },
1423   { 49, "Amperage Step 17" },
1424   { 50, "Amperage Step 18" },
1425   { 51, "Amperage Step 19" },
1426   { 52, "Amperage Step 20" },
1427   { 53, "Voltage Time Step 1" },
1428   { 54, "Voltage Time Step 2" },
1429   { 55, "Voltage Time Step 3" },
1430   { 56, "Voltage Time Step 4" },
1431   { 57, "Voltage Time Step 5" },
1432   { 58, "Voltage Time Step 6" },
1433   { 59, "Voltage Time Step 7" },
1434   { 60, "Voltage Time Step 8" },
1435   { 61, "Voltage Time Step 9" },
1436   { 62, "Voltage Time Step 10" },
1437   { 63, "Voltage Time Step 11" },
1438   { 64, "Voltage Time Step 12" },
1439   { 65, "Voltage Time Step 13" },
1440   { 66, "Voltage Time Step 14" },
1441   { 67, "Voltage Time Step 15" },
1442   { 68, "Voltage Time Step 16" },
1443   { 69, "Voltage Time Step 17" },
1444   { 70, "Voltage Time Step 18" },
1445   { 71, "Voltage Time Step 19" },
1446   { 72, "Voltage Time Step 20" },
1447   { 0, NULL }
1448 };
1449 static value_string_ext acn_blob_dimmer_load_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_load_properties1_field_name);
1450 
1451 static const value_string acn_blob_dimmer_rack_properties1_field_name[] = {
1452   { 1, "System" },
1453   { 2, "Processor" },
1454   { 3, "Rack" },
1455   { 4, "Lug" },
1456   { 5, "Module" },
1457   { 6, "Station" },
1458   { 7, "Port" },
1459   { 8, "Subdevice" },
1460   { 9, "Space" },
1461   { 10, "UDN" },
1462   { 11, "Reserved" },
1463   { 12, "Rack CID" },
1464   { 13, "Rack Number" },
1465   { 14, "Rack Name" },
1466   { 15, "Rack Model" },
1467   { 16, "Rack AF Enable" },
1468   { 17, "Temperature Format" },
1469   { 18, "Data Loss Behavior DMX A" },
1470   { 19, "Data Loss Behavior DMX B" },
1471   { 20, "Data Loss Behavior sACN" },
1472   { 21, "Data Loss Cross/Wait Time DMX A" },
1473   { 22, "Data Loss Cross/Wait Time DMX B" },
1474   { 23, "Data Loss Wait Time sACN" },
1475   { 24, "Data Loss Fade Time DMX A" },
1476   { 25, "Data Loss Fade Time DMX B" },
1477   { 26, "Data Loss Fade Time sACN" },
1478   { 27, "Data Loss Preset DMX A" },
1479   { 28, "Data Loss Preset DMX B" },
1480   { 29, "Data Port Priority DMX A" },
1481   { 30, "Data Port Priority DMX B" },
1482   { 31, "Data Port Enabled DMX A" },
1483   { 32, "Data Port Enabled DMX B" },
1484   { 33, "Data Port Enabled sACN" },
1485   { 34, "16 Bit Enabled DMX A" },
1486   { 35, "16 Bit Enabled DMX B" },
1487   { 36, "16 Bit Enabled sACN" },
1488   { 37, "Patch From Home Screen" },
1489   { 38, "SCR Off Time" },
1490   { 39, "Time Mode" },
1491   { 40, "Offset from UTC" },
1492   { 41, "Universal Hold Last Look Time" },
1493   { 42, "Reactivate Presets On Boot" },
1494   { 43, "Voltage High Warning Level" },
1495   { 44, "Temperature High Warning Level" },
1496   { 45, "Fan Operation Timing" },
1497   { 46, "Allow Backplane Communication Errors" },
1498   { 0, NULL }
1499 };
1500 static value_string_ext acn_blob_dimmer_rack_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_properties1_field_name);
1501 
1502 
1503 static const value_string acn_blob_dimmer_rack_status_properties1_field_name[] = {
1504   { 1, "System" },
1505   { 2, "Processor" },
1506   { 3, "Rack" },
1507   { 4, "Lug" },
1508   { 5, "Module" },
1509   { 6, "Station" },
1510   { 7, "Port" },
1511   { 8, "Subdevice" },
1512   { 9, "Space" },
1513   { 10, "UDN" },
1514   { 11, "Reserved" },
1515   { 12, "CPU Temperature" },
1516   { 13, "Time of Last Reboot" },
1517   { 14, "Time Now" },
1518   { 15, "Rack Phasing" },
1519   { 16, "Power Frequency" },
1520   { 17, "Phase A Voltage" },
1521   { 18, "Phase B Voltage" },
1522   { 19, "Phase C Voltage" },
1523   { 20, "DMX A Port Status" },
1524   { 21, "DMX B Port Status" },
1525   { 22, "Rack AF State" },
1526   { 23, "Number of Stored Presets for This Rack" },
1527   { 24, "Number of Lugs in This Rack" },
1528   { 25, "DSP Version" },
1529   { 26, "AF Card Version Slot 1" },
1530   { 27, "AF Card Version Slot 2" },
1531   { 28, "AF Card Version Slot 3" },
1532   { 29, "AF Card Version Slot 4" },
1533   { 30, "HCS08 Version" },
1534   { 31, "FPGA Version" },
1535   { 32, "Upload Progress AF Card 1" },
1536   { 33, "Upload Progress AF Card 2" },
1537   { 34, "Upload Progress AF Card 3" },
1538   { 35, "Upload Progress AF Card 4" },
1539   { 0, NULL }
1540 };
1541 static value_string_ext acn_blob_dimmer_rack_status_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_rack_status_properties1_field_name);
1542 
1543 static const value_string acn_blob_dimmer_status_properties1_field_name[] = {
1544   { 1, "System" },
1545   { 2, "Processor" },
1546   { 3, "Rack" },
1547   { 4, "Lug" },
1548   { 5, "Module" },
1549   { 6, "Station" },
1550   { 7, "Port" },
1551   { 8, "Subdevice" },
1552   { 9, "Space" },
1553   { 10, "UDN" },
1554   { 11, "Reserved" },
1555   { 12, "Source Winning Control" },
1556   { 13, "Priority of Winning Source" },
1557   { 14, "Winning Level" },
1558   { 15, "Winning DMX A Level" },
1559   { 16, "Winning DMX B Level" },
1560   { 17, "Winning sACN Level" },
1561   { 18, "Source Winning Control DD" },
1562   { 19, "Priority of Winning Source DD" },
1563   { 20, "Winning Level DD" },
1564   { 21, "Winning DMX A Level DD" },
1565   { 22, "Winning DMX B Level DD" },
1566   { 23, "Winning DMX sACN Level DD" },
1567   { 24, "Actual Load" },
1568   { 0, NULL }
1569 };
1570 static value_string_ext acn_blob_dimmer_status_properties1_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_dimmer_status_properties1_field_name);
1571 
1572 static const value_string acn_blob_preset_operation_field_name[] = {
1573   { 1, "Operation Type" },
1574   { 2, "Preset Number" },
1575   { 3, "Space" },
1576   { 0, NULL }
1577 };
1578 
1579 static const value_string acn_blob_preset_properties_field_name[] = {
1580   { 1, "System" },
1581   { 2, "Processor" },
1582   { 3, "Rack" },
1583   { 4, "Lug" },
1584   { 5, "Module" },
1585   { 6, "Station" },
1586   { 7, "Port" },
1587   { 8, "Subdevice" },
1588   { 9, "Space" },
1589   { 10, "UDN" },
1590   { 11, "Reserved" },
1591   { 12, "Preset Number" },
1592   { 13, "Preset Name" },
1593   { 14, "Fade In Time" },
1594   { 15, "Fade Out Time" },
1595   { 16, "Priority" },
1596   { 17, "Levels" },
1597   { 18, "Level[0]" },
1598   { 19, "Level[1]" },
1599   { 20, "Level[2]" },
1600   { 21, "Level[3]" },
1601   { 22, "Level[4]" },
1602   { 23, "Level[5]" },
1603   { 24, "Level[6]" },
1604   { 25, "Level[7]" },
1605   { 26, "Level[8]" },
1606   { 27, "Level[9]" },
1607   { 28, "Level[10]" },
1608   { 29, "Level[11]" },
1609   { 30, "Level[12]" },
1610   { 31, "Level[13]" },
1611   { 32, "Level[14]" },
1612   { 33, "Level[15]" },
1613   { 34, "Level[16]" },
1614   { 35, "Level[17]" },
1615   { 36, "Level[18]" },
1616   { 37, "Level[19]" },
1617   { 38, "Level[20]" },
1618   { 39, "Level[21]" },
1619   { 40, "Level[22]" },
1620   { 41, "Level[23]" },
1621   { 42, "Level[24]" },
1622   { 43, "Level[25]" },
1623   { 44, "Level[26]" },
1624   { 45, "Level[27]" },
1625   { 46, "Level[28]" },
1626   { 47, "Level[29]" },
1627   { 48, "Level[30]" },
1628   { 49, "Level[31]" },
1629   { 50, "Level[32]" },
1630   { 51, "Level[33]" },
1631   { 52, "Level[34]" },
1632   { 53, "Level[35]" },
1633   { 54, "Level[36]" },
1634   { 55, "Level[37]" },
1635   { 56, "Level[38]" },
1636   { 57, "Level[39]" },
1637   { 58, "Level[40]" },
1638   { 59, "Level[41]" },
1639   { 60, "Level[42]" },
1640   { 61, "Level[43]" },
1641   { 62, "Level[44]" },
1642   { 63, "Level[45]" },
1643   { 64, "Level[46]" },
1644   { 65, "Level[47]" },
1645   { 66, "Level[48]" },
1646   { 67, "Level[49]" },
1647   { 68, "Level[50]" },
1648   { 69, "Level[51]" },
1649   { 70, "Level[52]" },
1650   { 71, "Level[53]" },
1651   { 72, "Level[54]" },
1652   { 73, "Level[55]" },
1653   { 74, "Level[56]" },
1654   { 75, "Level[57]" },
1655   { 76, "Level[58]" },
1656   { 77, "Level[59]" },
1657   { 78, "Level[60]" },
1658   { 79, "Level[61]" },
1659   { 80, "Level[62]" },
1660   { 81, "Level[63]" },
1661   { 82, "Level[64]" },
1662   { 83, "Level[65]" },
1663   { 84, "Level[66]" },
1664   { 85, "Level[67]" },
1665   { 86, "Level[68]" },
1666   { 87, "Level[69]" },
1667   { 88, "Level[70]" },
1668   { 89, "Level[71]" },
1669   { 90, "Level[72]" },
1670   { 91, "Level[73]" },
1671   { 92, "Level[74]" },
1672   { 93, "Level[75]" },
1673   { 94, "Level[76]" },
1674   { 95, "Level[77]" },
1675   { 96, "Level[78]" },
1676   { 97, "Level[79]" },
1677   { 98, "Level[80]" },
1678   { 99, "Level[81]" },
1679   { 100, "Level[82]" },
1680   { 101, "Level[83]" },
1681   { 102, "Level[84]" },
1682   { 103, "Level[85]" },
1683   { 104, "Level[86]" },
1684   { 105, "Level[87]" },
1685   { 106, "Level[88]" },
1686   { 107, "Level[89]" },
1687   { 108, "Level[90]" },
1688   { 109, "Level[91]" },
1689   { 110, "Level[92]" },
1690   { 111, "Level[93]" },
1691   { 112, "Level[94]" },
1692   { 113, "Level[95]" },
1693   { 114, "Level[96]" },
1694   { 115, "Level[97]" },
1695   { 116, "Level[98]" },
1696   { 117, "Level[99]" },
1697   { 118, "Level[100]" },
1698   { 119, "Level[101]" },
1699   { 120, "Level[102]" },
1700   { 121, "Level[103]" },
1701   { 122, "Level[104]" },
1702   { 123, "Level[105]" },
1703   { 124, "Level[106]" },
1704   { 125, "Level[107]" },
1705   { 126, "Level[108]" },
1706   { 127, "Level[109]" },
1707   { 128, "Level[110]" },
1708   { 129, "Level[111]" },
1709   { 130, "Level[112]" },
1710   { 131, "Level[113]" },
1711   { 132, "Level[114]" },
1712   { 133, "Level[115]" },
1713   { 134, "Level[116]" },
1714   { 135, "Level[117]" },
1715   { 136, "Level[118]" },
1716   { 137, "Level[119]" },
1717   { 138, "Level[120]" },
1718   { 139, "Level[121]" },
1719   { 140, "Level[122]" },
1720   { 141, "Level[123]" },
1721   { 142, "Level[124]" },
1722   { 143, "Level[125]" },
1723   { 144, "Level[126]" },
1724   { 145, "Level[127]" },
1725   { 146, "Level[128]" },
1726   { 147, "Level[129]" },
1727   { 148, "Level[130]" },
1728   { 149, "Level[131]" },
1729   { 150, "Level[132]" },
1730   { 151, "Level[133]" },
1731   { 152, "Level[134]" },
1732   { 153, "Level[135]" },
1733   { 154, "Level[136]" },
1734   { 155, "Level[137]" },
1735   { 156, "Level[138]" },
1736   { 157, "Level[139]" },
1737   { 158, "Level[140]" },
1738   { 159, "Level[141]" },
1739   { 160, "Level[142]" },
1740   { 161, "Level[143]" },
1741   { 162, "Level[144]" },
1742   { 163, "Level[145]" },
1743   { 164, "Level[146]" },
1744   { 165, "Level[147]" },
1745   { 166, "Level[148]" },
1746   { 167, "Level[149]" },
1747   { 168, "Level[150]" },
1748   { 169, "Level[151]" },
1749   { 170, "Level[152]" },
1750   { 171, "Level[153]" },
1751   { 172, "Level[154]" },
1752   { 173, "Level[155]" },
1753   { 174, "Level[156]" },
1754   { 175, "Level[157]" },
1755   { 176, "Level[158]" },
1756   { 177, "Level[159]" },
1757   { 178, "Level[160]" },
1758   { 179, "Level[161]" },
1759   { 180, "Level[162]" },
1760   { 181, "Level[163]" },
1761   { 182, "Level[164]" },
1762   { 183, "Level[165]" },
1763   { 184, "Level[166]" },
1764   { 185, "Level[167]" },
1765   { 186, "Level[168]" },
1766   { 187, "Level[169]" },
1767   { 188, "Level[170]" },
1768   { 189, "Level[171]" },
1769   { 190, "Level[172]" },
1770   { 191, "Level[173]" },
1771   { 192, "Level[174]" },
1772   { 193, "Level[175]" },
1773   { 194, "Level[176]" },
1774   { 195, "Level[177]" },
1775   { 196, "Level[178]" },
1776   { 197, "Level[179]" },
1777   { 198, "Level[180]" },
1778   { 199, "Level[181]" },
1779   { 200, "Level[182]" },
1780   { 201, "Level[183]" },
1781   { 202, "Level[184]" },
1782   { 203, "Level[185]" },
1783   { 204, "Level[186]" },
1784   { 205, "Level[187]" },
1785   { 206, "Level[188]" },
1786   { 207, "Level[189]" },
1787   { 208, "Level[190]" },
1788   { 209, "Level[191]" },
1789   { 0, NULL }
1790 };
1791 static value_string_ext acn_blob_preset_properties_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_preset_properties_field_name);
1792 
1793 static const value_string acn_blob_range_type_vals[] = {
1794   { ACN_BLOB_RANGE_MID, "Middle range Blob" },
1795   { ACN_BLOB_RANGE_START, "Start range Blob" },
1796   { ACN_BLOB_RANGE_END, "End Range Blob" },
1797   { ACN_BLOB_RANGE_SINGLE, "Single Blob" },
1798   { 0, NULL }
1799 };
1800 
1801 static const value_string acn_blob_set_levels_operation_field_name[] = {
1802   { 1, "Start Dimmer Address" },
1803   { 2, "End Dimmer Address" },
1804   { 3, "DD Side" },
1805   { 4, "Space" },
1806   { 5, "Level" },
1807   { 0, NULL }
1808 };
1809 
1810 static const value_string acn_blob_time2_field_name[] = {
1811   { 1, "Time" },
1812   { 2, "Time Zone Name" },
1813   { 3, "Time Zone Offset Hour" },
1814   { 4, "Time Zone Offset Min" },
1815   { 5, "Time Zone Offset Sec" },
1816   { 6, "DST Name" },
1817   { 7, "Start Month" },
1818   { 8, "Start Week" },
1819   { 9, "Start Day" },
1820   { 10, "End Month" },
1821   { 11, "End Week" },
1822   { 12, "End Day" },
1823   { 13, "Timed Event Update" },
1824   { 14, "Unix Time Zone Environment-compatible Name" },
1825   { 0, NULL }
1826 };
1827 
1828 static const value_string acn_blob_rpc_field_name[] = {
1829   { 1, "Command" },
1830   { 2, "Transaction ID" },
1831   { 3, "Number of Arguments" },
1832   { 4, "Argument" },
1833   { 0, NULL }
1834 };
1835 
1836 static const value_string acn_blob_dhcp_config_subnet_field_name[] = {
1837   { 1, "Command" },
1838   { 2, "Subnet" },
1839   { 3, "Netmask" },
1840   { 4, "Given Next Server" },
1841   { 5, "Given Router" },
1842   { 6, "Given Netmask" },
1843   { 7, "Default Lease Time" },
1844   { 8, "Max Lease Time" },
1845   { 9, "Given Domain Name" },
1846   { 10, "Given DNS Servers" },
1847   { 11, "Given NTP Server" },
1848   { 12, "Given Time Zone Offset Hour" },
1849   { 13, "Given Time Zone Offset Minute" },
1850   { 14, "Given Time Zone Offset Second" },
1851   { 15, "Given Time Zone DST Name" },
1852   { 16, "Given Time Zone Start Month" },
1853   { 17, "Given Time Zone Start Week" },
1854   { 18, "Given Time Zone Start Day" },
1855   { 19, "Given Time Zone End Month" },
1856   { 20, "Given Time Zone End Week" },
1857   { 21, "Given Time Zone End Day" },
1858   { 22, "Given UNIX Timezone Name" },
1859   { 0, NULL }
1860 };
1861 
1862 static const value_string acn_blob_dhcp_config_static_route_field_name[] = {
1863   { 1, "Command" },
1864   { 2, "Subnet" },
1865   { 3, "Netmask" },
1866   { 4, "MAC Address" },
1867   { 5, "Host Name" },
1868   { 6, "Address" },
1869   { 0, NULL }
1870 };
1871 
1872 static const value_string acn_blob_energy_management_field_name[] = {
1873   { 1, "Project ID" },
1874   { 2, "Space" },
1875   { 3, "Circuit Power Count" },
1876   { 4, "Circuit" },
1877   { 5, "Power" },
1878   { 6, "Shed Actual" },
1879   { 7, "Shed Potential" },
1880   { 0, NULL }
1881 };
1882 
1883 static const value_string acn_blob_time3_field_name[] = {
1884   { 1, "Time" },
1885   { 2, "Time Zone Index" },
1886   { 3, "City" },
1887   { 4, "Country" },
1888   { 5, "Longitude" },
1889   { 6, "Latitude" },
1890   { 7, "UTC Offset Hours" },
1891   { 8, "UTC Offset Minutes" },
1892   { 9, "Time Zone Name" },
1893   { 10, "DST Type" },
1894   { 11, "DST Start Month" },
1895   { 12, "DST Start Week" },
1896   { 13, "DST Start Day" },
1897   { 14, "DST Start Hours" },
1898   { 15, "DST Start Minutes" },
1899   { 16, "DST Start Locality" },
1900   { 17, "DST Stop Month" },
1901   { 18, "DST Stop Week" },
1902   { 19, "DST Stop Day" },
1903   { 20, "DST Stop Hours" },
1904   { 21, "DST Stop Minutes" },
1905   { 22, "DST Stop Locality" },
1906   { 23, "Timed Event Update" },
1907   { 0, NULL }
1908 };
1909 
1910 static const value_string acn_blob_time3_time_zone_vals[] = {
1911   { 0, "Aalborg, Denmark - Central European Standard Time : (UTC+01:00)" },
1912   { 1, "Aberdeen, United Kingdom - Greenwich Mean Time : (UTC)" },
1913   { 2, "Abu Dhabi, United Arab Emirates - Gulf Standard Time : (UTC+04:00)" },
1914   { 3, "Abuja, Nigeria - West Africa Time : (UTC+01:00)" },
1915   { 4, "Accra, Ghana - Greenwich Mean Time : (UTC)" },
1916   { 5, "Addis Ababa, Ethiopia - Eastern Africa Standard Time : (UTC+03:00)" },
1917   { 6, "Adelaide, SA, Australia - Australian Central Standard Time : (UTC+09:30)" },
1918   { 7, "Agana, GU, Guam - Chamorro Standard Time : (UTC+10:00)" },
1919   { 8, "Ahmadabad, India - India Standard Time : (UTC+05:30)" },
1920   { 9, "Akita, Japan - Japan Standard Time : (UTC+09:00)" },
1921   { 10, "Akron, OH, USA - Eastern Standard Time : (UTC-05:00)" },
1922   { 11, "Albuquerque, NM, USA - Mountain Standard Time : (UTC-07:00)" },
1923   { 12, "Alexandria, VA, USA - Eastern Standard Time : (UTC-05:00)" },
1924   { 13, "Algiers, Algeria - Central European Standard Time : (UTC+01:00)" },
1925   { 14, "Allentown, PA, USA - Eastern Standard Time : (UTC-05:00)" },
1926   { 15, "Almaty, Kazakhstan - Alma-Ata Time : (UTC+06:00)" },
1927   { 16, "Amman, Jordan - Arabia Standard Time : (UTC+03:00)" },
1928   { 17, "Amsterdam, Netherlands - Central European Standard Time : (UTC+01:00)" },
1929   { 18, "Anaheim, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1930   { 19, "Anchorage, AK, USA - Alaska Standard Time : (UTC-09:00)" },
1931   { 20, "Andorra la Vella, Andorra - Central European Standard Time : (UTC+01:00)" },
1932   { 21, "Angers, France - Central European Standard Time : (UTC+01:00)" },
1933   { 22, "Ankara, Turkey - Eastern European Standard Time : (UTC+02:00)" },
1934   { 23, "Ann Arbor, MI, USA - Eastern Standard Time : (UTC-05:00)" },
1935   { 24, "Antananarivo, Madagascar - Eastern Africa Standard Time : (UTC+03:00)" },
1936   { 25, "Antwerp, Belgium - Central European Standard Time : (UTC+01:00)" },
1937   { 26, "Apia, Samoa - West Samoa Time : (UTC+14:00)" },
1938   { 27, "Ashgabat, Turkmenistan - Turkmenistan Time : (UTC+05:00)" },
1939   { 28, "Asmara, Eritrea - Eastern Africa Standard Time : (UTC+03:00)" },
1940   { 29, "Athens, Greece - Eastern European Standard Time : (UTC+02:00)" },
1941   { 30, "Atlanta, GA, USA - Eastern Standard Time : (UTC-05:00)" },
1942   { 31, "Auckland, New Zealand - New Zealand Standard Time : (UTC+12:00)" },
1943   { 32, "Austin, TX, USA - Central Standard Time : (UTC-06:00)" },
1944   { 33, "Badajoz, Spain - Central European Standard Time : (UTC+01:00)" },
1945   { 34, "Baghdad, Iraq - Arabia Standard Time : (UTC+03:00)" },
1946   { 35, "Bakersfield, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1947   { 36, "Baku, Azerbaijan - Azerbaijan Time : (UTC+04:00)" },
1948   { 37, "Baltimore, MD, USA - Eastern Standard Time : (UTC-05:00)" },
1949   { 38, "Bamako, Mali - Greenwich Mean Time : (UTC)" },
1950   { 39, "Bandar Seri Begawan, Brunei - Brunei Darussalam Time : (UTC+08:00)" },
1951   { 40, "Bangalore, India - India Standard Time : (UTC+05:30)" },
1952   { 41, "Bangkok, Thailand - Indochina Time : (UTC+07:00)" },
1953   { 42, "Bangui, Central African Republic - West Africa Time : (UTC+01:00)" },
1954   { 43, "Banjul, Gambia - Greenwich Mean Time : (UTC)" },
1955   { 44, "Barcelona, Spain - Central European Standard Time : (UTC+01:00)" },
1956   { 45, "Bari, Italy - Central European Standard Time : (UTC+01:00)" },
1957   { 46, "Baton Rouge, LA, USA - Central Standard Time : (UTC-06:00)" },
1958   { 47, "Beaumont, TX, USA - Central Standard Time : (UTC-06:00)" },
1959   { 48, "Beijing, China - China Standard Time : (UTC+08:00)" },
1960   { 49, "Beirut, Lebanon - Eastern European Standard Time : (UTC+02:00)" },
1961   { 50, "Belem, Brazil - Brasilia Time : (UTC-03:00)" },
1962   { 51, "Belfast, United Kingdom - Greenwich Mean Time : (UTC)" },
1963   { 52, "Belgrade, Serbia - Central European Standard Time : (UTC+01:00)" },
1964   { 53, "Belmopan, Belize - Central Standard Time : (UTC-06:00)" },
1965   { 54, "Belo Horizonte, Brazil - Brasilia Time : (UTC-03:00)" },
1966   { 55, "Bergen, Norway - Central European Standard Time : (UTC+01:00)" },
1967   { 56, "Berkeley, CA, USA - Pacific Standard Time : (UTC-08:00)" },
1968   { 57, "Berlin, Germany - Central European Standard Time : (UTC+01:00)" },
1969   { 58, "Bern, Switzerland - Central European Standard Time : (UTC+01:00)" },
1970   { 59, "Birmingham, AL, USA - Central Standard Time : (UTC-06:00)" },
1971   { 60, "Birmingham, United Kingdom - Greenwich Mean Time : (UTC)" },
1972   { 61, "Bishkek, Kyrgyzstan - Kyrgyzstan Time : (UTC+06:00)" },
1973   { 62, "Bissau, Guinea-Bissau - Greenwich Mean Time : (UTC)" },
1974   { 63, "Boise, ID, USA - Mountain Standard Time : (UTC-07:00)" },
1975   { 64, "Bologna, Italy - Central European Standard Time : (UTC+01:00)" },
1976   { 65, "Bonn, Germany - Central European Standard Time : (UTC+01:00)" },
1977   { 66, "Bordeaux, France - Central European Standard Time : (UTC+01:00)" },
1978   { 67, "Boston, MA, USA - Eastern Standard Time : (UTC-05:00)" },
1979   { 68, "Bournemouth, United Kingdom - Greenwich Mean Time : (UTC)" },
1980   { 69, "Brasilia, Brazil - Brasilia Time : (UTC-03:00)" },
1981   { 70, "Bratislava, Slovakia - Central European Standard Time : (UTC+01:00)" },
1982   { 71, "Brazzaville, Republic of the Congo - West Africa Time : (UTC+01:00)" },
1983   { 72, "Bremen, Germany - Central European Standard Time : (UTC+01:00)" },
1984   { 73, "Brest, France - Central European Standard Time : (UTC+01:00)" },
1985   { 74, "Bridgeport, CT, USA - Eastern Standard Time : (UTC-05:00)" },
1986   { 75, "Bridgetown, Barbados - Atlantic Standard Time : (UTC-04:00)" },
1987   { 76, "Brisbane, QLD, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
1988   { 77, "Brno, Czech Republic - Central European Standard Time : (UTC+01:00)" },
1989   { 78, "Brussels, Belgium - Central European Standard Time : (UTC+01:00)" },
1990   { 79, "Bucharest, Romania - Eastern European Standard Time : (UTC+02:00)" },
1991   { 80, "Budapest, Hungary - Central European Standard Time : (UTC+01:00)" },
1992   { 81, "Buenos Aires, Argentina - Argentina Time : (UTC-03:00)" },
1993   { 82, "Buffalo, NY, USA - Eastern Standard Time : (UTC-05:00)" },
1994   { 83, "Bujumbura, Burundi - South Africa Standard Time : (UTC+02:00)" },
1995   { 84, "Cagliari, Italy - Central European Standard Time : (UTC+01:00)" },
1996   { 85, "Cairo, Egypt - Eastern European Standard Time : (UTC+02:00)" },
1997   { 86, "Calgary, AB, Canada - Mountain Standard Time : (UTC-07:00)" },
1998   { 87, "Cali, Colombia - Colombia Time : (UTC-05:00)" },
1999   { 88, "Canberra, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
2000   { 89, "Cape Town, South Africa - South Africa Standard Time : (UTC+02:00)" },
2001   { 90, "Caracas, Venezuela - Venezuelan Standard Time : (UTC-04:30)" },
2002   { 91, "Cardiff, United Kingdom - Greenwich Mean Time : (UTC)" },
2003   { 92, "Cedar Rapids, IA, USA - Central Standard Time : (UTC-06:00)" },
2004   { 93, "Charlotte, NC, USA - Eastern Standard Time : (UTC-05:00)" },
2005   { 94, "Charlottetown, PE, Canada - Atlantic Standard Time : (UTC-04:00)" },
2006   { 95, "Chatham Islands, Chatham Islands, New Zealand - Chatham Island Standard Time : (UTC+12:45)" },
2007   { 96, "Chengdu, China - China Standard Time : (UTC+08:00)" },
2008   { 97, "Chennai, India - India Standard Time : (UTC+05:30)" },
2009   { 98, "Chiba, Japan - Japan Standard Time : (UTC+09:00)" },
2010   { 99, "Chicago, IL, USA - Central Standard Time : (UTC-06:00)" },
2011   { 100, "Chisinau, Moldova - Eastern European Standard Time : (UTC+02:00)" },
2012   { 101, "Chongqing, China - China Standard Time : (UTC+08:00)" },
2013   { 102, "Cincinnati, OH, USA - Eastern Standard Time : (UTC-05:00)" },
2014   { 103, "Cleveland, OH, USA - Eastern Standard Time : (UTC-05:00)" },
2015   { 104, "Colorado Springs, CO, USA - Mountain Standard Time : (UTC-07:00)" },
2016   { 105, "Columbus, GA, USA - Eastern Standard Time : (UTC-05:00)" },
2017   { 106, "Columbus, OH, USA - Eastern Standard Time : (UTC-05:00)" },
2018   { 107, "Conakry, Guinea - Greenwich Mean Time : (UTC)" },
2019   { 108, "Copenhagen, Denmark - Central European Standard Time : (UTC+01:00)" },
2020   { 109, "Cork, Ireland - Greenwich Mean Time : (UTC)" },
2021   { 110, "Corpus Christi, TX, USA - Central Standard Time : (UTC-06:00)" },
2022   { 111, "Curitiba, Brazil - Brasilia Time : (UTC-03:00)" },
2023   { 112, "Dakar, Senegal - Greenwich Mean Time : (UTC)" },
2024   { 113, "Dallas, TX, USA - Central Standard Time : (UTC-06:00)" },
2025   { 114, "Damascus, Syria - Eastern European Standard Time : (UTC+02:00)" },
2026   { 115, "Dar es Salaam, Tanzania - Eastern Africa Standard Time : (UTC+03:00)" },
2027   { 116, "Darwin, NT, Australia - Australian Central Standard Time : (UTC+09:30)" },
2028   { 117, "Dayton, OH, USA - Eastern Standard Time : (UTC-05:00)" },
2029   { 118, "Delhi, India - India Standard Time : (UTC+05:30)" },
2030   { 119, "Denver, CO, USA - Mountain Standard Time : (UTC-07:00)" },
2031   { 120, "Des Moines, IA, USA - Central Standard Time : (UTC-06:00)" },
2032   { 121, "Detroit, MI, USA - Eastern Standard Time : (UTC-05:00)" },
2033   { 122, "Dhaka, Bangladesh - Central Asia Standard Time : (UTC+06:00)" },
2034   { 123, "Dijon, France - Romance Standard Time : (UTC+01:00)" },
2035   { 124, "Djibouti, Djibouti - Eastern Africa Standard Time : (UTC+03:00)" },
2036   { 125, "Doha, Qatar - Arabia Standard Time : (UTC+03:00)" },
2037   { 126, "Dortmund, Germany - Central European Standard Time : (UTC+01:00)" },
2038   { 127, "Dresden, Germany - Central European Standard Time : (UTC+01:00)" },
2039   { 128, "Dublin, Ireland - Greenwich Mean Time : (UTC)" },
2040   { 129, "Dushanbe, Tajikistan - Tajikistan Time : (UTC+05:00)" },
2041   { 130, "Dusseldorf, Germany - Central European Standard Time : (UTC+01:00)" },
2042   { 131, "Edinburgh, United Kingdom - Greenwich Mean Time : (UTC)" },
2043   { 132, "Edmonton, AB, Canada - Mountain Standard Time : (UTC-07:00)" },
2044   { 133, "El Paso, TX, USA - Mountain Standard Time : (UTC-07:00)" },
2045   { 134, "Erfurt, Germany - Central European Standard Time : (UTC+01:00)" },
2046   { 135, "Eucla, WA, Australia - Australian Central Western Standard Time  : (UTC+08:45)" },
2047   { 136, "Eugene, OR, USA - Pacific Standard Time : (UTC-08:00)" },
2048   { 137, "Evansville, IN, USA - Eastern Standard Time : (UTC-05:00)" },
2049   { 138, "Florence, Italy - Central European Standard Time : (UTC+01:00)" },
2050   { 139, "Fort Defiance, AZ, USA - Mountain Standard Time : (UTC-07:00)" },
2051   { 140, "Fort Lauderdale, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2052   { 141, "Fort Wayne, IN, USA - Eastern Standard Time : (UTC-05:00)" },
2053   { 142, "Fort Worth, TX, USA - Central Standard Time : (UTC-06:00)" },
2054   { 143, "Fortaleza, Brazil - Brasilia Time : (UTC-03:00)" },
2055   { 144, "Frankfurt, Germany - Central European Standard Time : (UTC+01:00)" },
2056   { 145, "Freetown, Sierra Leone - Greenwich Mean Time : (UTC)" },
2057   { 146, "Freiburg, Germany - Central European Standard Time : (UTC+01:00)" },
2058   { 147, "Fremont, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2059   { 148, "Fresno, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2060   { 149, "Fukuoka, Japan - Japan Standard Time : (UTC+09:00)" },
2061   { 150, "Gaborone, Botswana - Central Africa Time : (UTC+02:00)" },
2062   { 151, "Galway, Ireland - Greenwich Mean Time : (UTC)" },
2063   { 152, "Geneva, Switzerland - Central European Standard Time : (UTC+01:00)" },
2064   { 153, "Genova, Italy - Central European Standard Time : (UTC+01:00)" },
2065   { 154, "George Town, Cayman Islands - Eastern Standard Time : (UTC-05:00)" },
2066   { 155, "Georgetown, Guyana - Guyana Time : (UTC-04:00)" },
2067   { 156, "Glasgow, United Kingdom - Greenwich Mean Time : (UTC)" },
2068   { 157, "Glendale, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2069   { 158, "Granada, Spain - Central European Standard Time : (UTC+01:00)" },
2070   { 159, "Grand Rapids, MI, USA - Eastern Standard Time : (UTC-05:00)" },
2071   { 160, "Guadalajara, Mexico - Central Standard Time : (UTC-06:00)" },
2072   { 161, "Guangzhou, China - China Standard Time : (UTC+08:00)" },
2073   { 162, "Guatemala City, Guatemala - Central Standard Time : (UTC-06:00)" },
2074   { 163, "Haikou, China - China Standard Time : (UTC+08:00)" },
2075   { 164, "Halifax, NS, Canada - Atlantic Standard Time : (UTC-04:00)" },
2076   { 165, "Hamburg, Germany - Central European Standard Time : (UTC+01:00)" },
2077   { 166, "Hamilton, Bermuda - Atlantic Standard Time : (UTC-04:00)" },
2078   { 167, "Hannover, Germany - Central European Standard Time : (UTC+01:00)" },
2079   { 168, "Hanoi, Vietnam - Indochina Time : (UTC+07:00)" },
2080   { 169, "Harare, Zimbabwe - Central Africa Time : (UTC+02:00)" },
2081   { 170, "Harbin, China - China Standard Time : (UTC+08:00)" },
2082   { 171, "Hartford, CT, USA - Eastern Standard Time : (UTC-05:00)" },
2083   { 172, "Havana, Cuba - Cuba Standard Time : (UTC-05:00)" },
2084   { 173, "Helsinki, Finland - Eastern European Standard Time : (UTC+02:00)" },
2085   { 174, "Hiroshima, Japan - Japan Standard Time : (UTC+09:00)" },
2086   { 175, "Hobart, TAS, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
2087   { 176, "Hong Kong SAR, China - China Standard Time : (UTC+08:00)" },
2088   { 177, "Honiara, Solomon Islands - Solomon Islands Time : (UTC+11:00)" },
2089   { 178, "Honolulu, HI, USA - Hawaii-Aleutian Standard Time : (UTC-10:00)" },
2090   { 179, "Houston, TX, USA - Central Standard Time : (UTC-06:00)" },
2091   { 180, "Hull, PQ, Canada - Eastern Standard Time : (UTC-05:00)" },
2092   { 181, "Huntsville, AL, USA - Central Standard Time : (UTC-06:00)" },
2093   { 182, "Indianapolis, IN, USA - Eastern Standard Time : (UTC-05:00)" },
2094   { 183, "Irkutsk, Russia - Irkutsk Time : (UTC+08:00)" },
2095   { 184, "Islamabad, Pakistan - Pakistan Standard Time : (UTC+05:00)" },
2096   { 185, "Istanbul, Turkey - Eastern European Standard Time : (UTC+02:00)" },
2097   { 186, "Jackson, MS, USA - Central Standard Time : (UTC-06:00)" },
2098   { 187, "Jacksonville, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2099   { 188, "Jakarta, Indonesia - Western Indonesian Time : (UTC+07:00)" },
2100   { 189, "Jerusalem, Israel - Israel Standard Time : (UTC+02:00)" },
2101   { 190, "Kabul, Afghanistan - Afghanistan Standard Time : (UTC+04:30)" },
2102   { 191, "Kampala, Uganda - Eastern Africa Standard Time : (UTC+03:00)" },
2103   { 192, "Kanazawa, Japan - Japan Standard Time : (UTC+09:00)" },
2104   { 193, "Kansas City, KS, USA - Central Standard Time : (UTC-06:00)" },
2105   { 194, "Kansas City, MO, USA - Central Standard Time : (UTC-06:00)" },
2106   { 195, "Karachi, Pakistan - Pakistan Standard Time : (UTC+05:00)" },
2107   { 196, "Kathmandu, Nepal - Nepal Standard Time : (UTC+05:45)" },
2108   { 197, "Kelowna, BC, Canada - Pacific Standard Time : (UTC-08:00)" },
2109   { 198, "Khartoum, Sudan - Eastern Africa Standard Time : (UTC+03:00)" },
2110   { 199, "Kiev, Ukraine - Eastern European Standard Time : (UTC+02:00)" },
2111   { 200, "Kigali, Rwanda - Central Africa Time : (UTC+02:00)" },
2112   { 201, "Kingston, Jamaica - Eastern Standard Time : (UTC-05:00)" },
2113   { 202, "Kingston, Norfolk Island - Norfolk Time : (UTC+11:30)" },
2114   { 203, "Kinshasa, Democratic Republic of the Congo - West Africa Time : (UTC+01:00)" },
2115   { 204, "Kiritimati, Christmas Island, Kiribati - Line Islands Time : (UTC+14:00)" },
2116   { 205, "Knoxville, TN, USA - Eastern Standard Time : (UTC-05:00)" },
2117   { 206, "Kobe, Japan - Japan Standard Time : (UTC+09:00)" },
2118   { 207, "Kochi, Japan - Japan Standard Time : (UTC+09:00)" },
2119   { 208, "Kolkata (Calcutta), India - India Standard Time : (UTC+05:30)" },
2120   { 209, "Krasnoyarsk, Russia - Krasnoyarsk Time : (UTC+07:00)" },
2121   { 210, "Kuala Lumpur, Malaysia - Singapore Standard Time : (UTC+08:00)" },
2122   { 211, "Kuwait, Kuwait - Arabia Standard Time : (UTC+03:00)" },
2123   { 212, "Kwangju, Korea - Korea Standard Time : (UTC+09:00)" },
2124   { 213, "Kyoto, Japan - Japan Standard Time : (UTC+09:00)" },
2125   { 214, "La Paz, Bolivia - Bolivia Time : (UTC-04:00)" },
2126   { 215, "Lansing, MI, USA - Eastern Standard Time : (UTC-05:00)" },
2127   { 216, "Laredo, TX, USA - Central Standard Time : (UTC-06:00)" },
2128   { 217, "Las Vegas, NV, USA - Pacific Standard Time : (UTC-08:00)" },
2129   { 218, "Leipzig, Germany - Central European Standard Time : (UTC+01:00)" },
2130   { 219, "Lexington, KY, USA - Eastern Standard Time : (UTC-05:00)" },
2131   { 220, "Lhasa, China - China Standard Time : (UTC+08:00)" },
2132   { 221, "Libreville, Gabon - West Africa Time : (UTC+01:00)" },
2133   { 222, "Lille, France - Central European Standard Time : (UTC+01:00)" },
2134   { 223, "Lilongwe, Malawi - Central Africa Time : (UTC+02:00)" },
2135   { 224, "Lima, Peru - Peru Time : (UTC-05:00)" },
2136   { 225, "Limerick, Ireland - Greenwich Mean Time : (UTC)" },
2137   { 226, "Limoges, France - Central European Standard Time : (UTC+01:00)" },
2138   { 227, "Lincoln, NE, USA - Central Standard Time : (UTC-06:00)" },
2139   { 228, "Lisbon, Portugal - Greenwich Mean Time : (UTC)" },
2140   { 229, "Little Rock, AR, USA - Central Standard Time : (UTC-06:00)" },
2141   { 230, "Liverpool, United Kingdom - Greenwich Mean Time : (UTC)" },
2142   { 231, "Ljubljana, Slovenia - Central European Standard Time : (UTC+01:00)" },
2143   { 232, "London, United Kingdom - Greenwich Mean Time : (UTC)" },
2144   { 233, "Londonderry, United Kingdom - Greenwich Mean Time : (UTC)" },
2145   { 234, "Long Beach, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2146   { 235, "Lord Howe Island, Lord Howe Island, Australia - Lord Howe Standard Time : (UTC+10:30)" },
2147   { 236, "Los Angeles, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2148   { 237, "Louisville, KY, USA - Eastern Standard Time : (UTC-05:00)" },
2149   { 238, "Luanda, Angola - West Africa Time : (UTC+01:00)" },
2150   { 239, "Lubbock, TX, USA - Central Standard Time : (UTC-06:00)" },
2151   { 240, "Lusaka, Zambia - Central Africa Time : (UTC+02:00)" },
2152   { 241, "Luxembourg, Luxembourg - Central European Standard Time : (UTC+01:00)" },
2153   { 242, "Lyon, France - Central European Standard Time : (UTC+01:00)" },
2154   { 243, "Madison, WI, USA - Central Standard Time : (UTC-06:00)" },
2155   { 244, "Madrid, Spain - Central European Standard Time : (UTC+01:00)" },
2156   { 245, "Malabo, Equatorial Guinea - West Africa Time : (UTC+01:00)" },
2157   { 246, "Malaga, Spain - Central European Standard Time : (UTC+01:00)" },
2158   { 247, "Managua, Nicaragua - Central Standard Time : (UTC-06:00)" },
2159   { 248, "Manama, Bahrain - Arabia Standard Time : (UTC+03:00)" },
2160   { 249, "Manaus, Brazil - Amazon Time : (UTC-04:00)" },
2161   { 250, "Manchester, United Kingdom - Greenwich Mean Time : (UTC)" },
2162   { 251, "Manila, Philippines - Philippine Time : (UTC+08:00)" },
2163   { 252, "Maputo, Mozambique - Central Africa Time : (UTC+02:00)" },
2164   { 253, "Maracaibo, Venezuela - Venezuelan Standard Time : (UTC-04:30)" },
2165   { 254, "Marseille, France - Central European Standard Time : (UTC+01:00)" },
2166   { 255, "Maseru, Lesotho - South Africa Standard Time : (UTC+02:00)" },
2167   { 256, "Masqat, Oman - Gulf Standard Time : (UTC+04:00)" },
2168   { 257, "Mbabane, Swaziland - South Africa Standard Time : (UTC+02:00)" },
2169   { 258, "Medellin, Colombia - Colombia Time : (UTC-05:00)" },
2170   { 259, "Melbourne, VIC, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
2171   { 260, "Memphis, TN, USA - Central Standard Time : (UTC-06:00)" },
2172   { 261, "Metz, France - Central European Standard Time : (UTC+01:00)" },
2173   { 262, "Mexico City, Mexico - Central Standard Time : (UTC-06:00)" },
2174   { 263, "Miami, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2175   { 264, "Milan, Italy - Central European Standard Time : (UTC+01:00)" },
2176   { 265, "Milwaukee, WI, USA - Central Standard Time : (UTC-06:00)" },
2177   { 266, "Minneapolis, MN, USA - Central Standard Time : (UTC-06:00)" },
2178   { 267, "Minsk, Belarus - Further-Eastern European Time : (UTC+03:00)" },
2179   { 268, "Mobile, AL, USA - Central Standard Time : (UTC-06:00)" },
2180   { 269, "Mogadishu, Somalia - Eastern Africa Standard Time : (UTC+03:00)" },
2181   { 270, "Monaco, Monaco - Central European Standard Time : (UTC+01:00)" },
2182   { 271, "Monrovia, Liberia - Greenwich Mean Time : (UTC)" },
2183   { 272, "Monterrey, Mexico - Central Standard Time : (UTC-06:00)" },
2184   { 273, "Montevideo, Uruguay - Uruguay Time : (UTC-03:00)" },
2185   { 274, "Montreal, PQ, Canada - Eastern Standard Time : (UTC-05:00)" },
2186   { 275, "Morioka, Japan - Japan Standard Time : (UTC+09:00)" },
2187   { 276, "Moscow, Russia - Moscow Standard Time : (UTC+03:00)" },
2188   { 277, "Mumbai, India - India Standard Time : (UTC+05:30)" },
2189   { 278, "Munich, Germany - Central European Standard Time : (UTC+01:00)" },
2190   { 279, "Murmansk, Russia - Moscow Standard Time : (UTC+03:00)" },
2191   { 280, "N'Djamena, Chad - West Africa Time : (UTC+01:00)" },
2192   { 281, "Nagano, Japan - Japan Standard Time : (UTC+09:00)" },
2193   { 282, "Nagasaki, Japan - Japan Standard Time : (UTC+09:00)" },
2194   { 283, "Nagoya, Japan - Japan Standard Time : (UTC+09:00)" },
2195   { 284, "Nairobi, Kenya - Eastern Africa Standard Time : (UTC+03:00)" },
2196   { 285, "Nanjing, China - China Standard Time : (UTC+08:00)" },
2197   { 286, "Naples, Italy - Central European Standard Time : (UTC+01:00)" },
2198   { 287, "Nashville, TN, USA - Central Standard Time : (UTC-06:00)" },
2199   { 288, "Nassau, Bahamas - Eastern Standard Time : (UTC-05:00)" },
2200   { 289, "New Orleans, LA, USA - Central Standard Time : (UTC-06:00)" },
2201   { 290, "New York, NY, USA - Eastern Standard Time : (UTC-05:00)" },
2202   { 291, "Newark, NJ, USA - Eastern Standard Time : (UTC-05:00)" },
2203   { 292, "Niamey, Niger - West Africa Time : (UTC+01:00)" },
2204   { 293, "Nicosia, Cyprus - Eastern European Standard Time : (UTC+02:00)" },
2205   { 294, "Norwich, United Kingdom - Greenwich Mean Time : (UTC)" },
2206   { 295, "Nouakchott, Mauritania - Greenwich Mean Time : (UTC)" },
2207   { 296, "Novosibirsk, Russia - Novosibirsk Time : (UTC+06:00)" },
2208   { 297, "Nuku'alofa, Tonga - Tonga Standard Time : (UTC+13:00)" },
2209   { 298, "Nuuk, Greenland - West Greenland Time : (UTC-03;00)" },
2210   { 299, "Oakland, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2211   { 300, "Oklahoma City, OK, USA - Central Standard Time : (UTC-06:00)" },
2212   { 301, "Omaha, NE, USA - Central Standard Time : (UTC-06:00)" },
2213   { 302, "Orlando, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2214   { 303, "Osaka, Japan - Japan Standard Time : (UTC+09:00)" },
2215   { 304, "Oshawa, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2216   { 305, "Oslo, Norway - Central European Standard Time : (UTC+01:00)" },
2217   { 306, "Ottawa, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2218   { 307, "Ouagadougou, Burkina Faso - Greenwich Mean Time : (UTC)" },
2219   { 308, "Overland Park, KS, USA - Central Standard Time : (UTC-06:00)" },
2220   { 309, "Oviedo, Spain - Central European Standard Time : (UTC+01:00)" },
2221   { 310, "Palermo, Italy - Central European Standard Time : (UTC+01:00)" },
2222   { 311, "Palma de Mallorca, Spain - Central European Standard Time : (UTC+01:00)" },
2223   { 312, "Panama City, Panama - Eastern Standard Time : (UTC-05:00)" },
2224   { 313, "Paramaribo, Surinam - Suriname Time : (UTC-03:00)" },
2225   { 314, "Paris, France - Central European Standard Time : (UTC+01:00)" },
2226   { 315, "Pasadena, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2227   { 316, "Pasadena, TX, USA - Central Standard Time : (UTC-06:00)" },
2228   { 317, "Peoria, IL, USA - Central Standard Time : (UTC-06:00)" },
2229   { 318, "Perth, WA, Australia - Australia Western Standard Time : (UTC+08:00)" },
2230   { 319, "Perugia, Italy - Central European Standard Time : (UTC+01:00)" },
2231   { 320, "Philadelphia, PA, USA - Eastern Standard Time : (UTC-05:00)" },
2232   { 321, "Phnom Penh, Cambodia - Indochina Time : (UTC+07:00)" },
2233   { 322, "Phoenix, AZ, USA - Mountain Standard Time : (UTC-07:00)" },
2234   { 323, "Pisa, Italy - Central European Standard Time : (UTC+01:00)" },
2235   { 324, "Pittsburgh, PA, USA - Eastern Standard Time : (UTC-05:00)" },
2236   { 325, "Plymouth, United Kingdom - Greenwich Mean Time : (UTC)" },
2237   { 326, "Port Louis, Mauritius - Mauritius Time : (UTC+04:00)" },
2238   { 327, "Port Moresby, Papua New Guinea - Papua New Guinea Time : (UTC+10:00)" },
2239   { 328, "Port-au-Prince, Haiti - Eastern Standard Time : (UTC-05:00)" },
2240   { 329, "Port-of-Spain, Trinidad and Tobago - Atlantic Standard Time : (UTC-04:00)" },
2241   { 330, "Portland, OR, USA - Pacific Standard Time : (UTC-08:00)" },
2242   { 331, "Porto Alegre, Brazil - Brasilia Time : (UTC-03:00)" },
2243   { 332, "Porto, Portugal - Western European Time : (UTC)" },
2244   { 333, "Porto-Novo, Benin - West Africa Time : (UTC+01:00)" },
2245   { 334, "Prague, Czech Republic - Central European Standard Time : (UTC+01:00)" },
2246   { 335, "Praia, Cape Verde - Cape Verde Time : (UTC-01:00)" },
2247   { 336, "Pretoria, South Africa - South Africa Standard Time : (UTC+02:00)" },
2248   { 337, "Providence, RI, USA - Eastern Standard Time : (UTC-05:00)" },
2249   { 338, "Puebla de Zaragoza, Mexico - Eastern Standard Time : (UTC-05:00)" },
2250   { 339, "Pusan, Korea - Korea Standard Time : (UTC+09:00)" },
2251   { 340, "Pyongyang, North Korea - Korea Standard Time : (UTC+09:00)" },
2252   { 341, "Quebec City, PQ, Canada - Eastern Standard Time : (UTC-05:00)" },
2253   { 342, "Quito, Ecuador - Ecuador Time : (UTC-05:00)" },
2254   { 343, "Rabat, Morocco - Western European Time : (UTC)" },
2255   { 344, "Raleigh, NC, USA - Eastern Standard Time : (UTC-05:00)" },
2256   { 345, "Recife, Brazil - Brasilia Time : (UTC-03:00)" },
2257   { 346, "Redmond, WA, USA - Pacific Standard Time : (UTC-08:00)" },
2258   { 347, "Reggio Calabria, Italy - Central European Standard Time : (UTC+01:00)" },
2259   { 348, "Regina, SK, Canada - Central Standard Time : (UTC-06:00)" },
2260   { 349, "Richmond, VA, USA - Eastern Standard Time : (UTC-05:00)" },
2261   { 350, "Riga, Latvia - Eastern European Standard Time : (UTC+02:00)" },
2262   { 351, "Rio de Janeiro, Brazil - Brasilia Time : (UTC-03:00)" },
2263   { 352, "Riyadh, Saudi Arabia - Arabia Standard Time : (UTC+03:00)" },
2264   { 353, "Rockford, IL, USA - Central Standard Time : (UTC-06:00)" },
2265   { 354, "Rome, Italy - Central European Standard Time : (UTC+01:00)" },
2266   { 355, "Roseau, Dominica - Atlantic Standard Time : (UTC-04:00)" },
2267   { 356, "Roswell, NM, USA - Mountain Standard Time : (UTC-07:00)" },
2268   { 357, "Rouen, France - Central European Standard Time : (UTC+01:00)" },
2269   { 358, "Sacramento, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2270   { 359, "Saint John, NB, Canada - Atlantic Standard Time : (UTC-04:00)" },
2271   { 360, "Saint Louis, MO, USA - Central Standard Time : (UTC-06:00)" },
2272   { 361, "Saint Paul, MN, USA - Central Standard Time : (UTC-06:00)" },
2273   { 362, "Salt Lake City, UT, USA - Mountain Standard Time : (UTC-07:00)" },
2274   { 363, "Salvador, Brazil - Brasilia Time : (UTC-03:00)" },
2275   { 364, "Salzburg, Austria - Central European Standard Time : (UTC+01:00)" },
2276   { 365, "San Antonio, TX, USA - Central Standard Time : (UTC-06:00)" },
2277   { 366, "San Bernardino, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2278   { 367, "San Diego, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2279   { 368, "San Francisco, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2280   { 369, "San Jose, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2281   { 370, "San Salvador, El Salvador - Central Standard Time : (UTC-06:00)" },
2282   { 371, "Sana'a, Yemen - Arabia Standard Time : (UTC+03:00)" },
2283   { 372, "Santa Ana, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2284   { 373, "Santa Rosa, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2285   { 374, "Santander, Spain - Central European Standard Time : (UTC+01:00)" },
2286   { 375, "Santiago, Chile - Chile Standard Time : (UTC-04:00)" },
2287   { 376, "Santo Domingo, Dominican Republic - Atlantic Standard Time : (UTC-04:00)" },
2288   { 377, "Sao Paulo, Brazil - Brasilia Time : (UTC-03:00)" },
2289   { 378, "Sapporo, Japan - Japan Standard Time : (UTC+09:00)" },
2290   { 379, "Sarajevo, Bosnia and Herzegovina - Central European Standard Time : (UTC+01:00)" },
2291   { 380, "Saskatoon, SK, Canada - Central Standard Time : (UTC-06:00)" },
2292   { 381, "Savannah, GA, USA - Eastern Standard Time : (UTC-05:00)" },
2293   { 382, "Seattle, WA, USA - Pacific Standard Time : (UTC-08:00)" },
2294   { 383, "Sendai, Japan - Japan Standard Time : (UTC+09:00)" },
2295   { 384, "Seoul, Korea - Korea Standard Time : (UTC+09:00)" },
2296   { 385, "Sevilla, Spain - Central European Standard Time : (UTC+01:00)" },
2297   { 386, "Shanghai, China - China Standard Time : (UTC+08:00)" },
2298   { 387, "Shreveport, LA, USA - Central Standard Time : (UTC-06:00)" },
2299   { 388, "Simi Valley, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2300   { 389, "Singapore, Singapore - Singapore Standard Time : (UTC+08:00)" },
2301   { 390, "Sioux Falls, SD, USA - Central Standard Time : (UTC-06:00)" },
2302   { 391, "Skopje, F.Y.R.O. Macedonia - Central European Standard Time : (UTC+01:00)" },
2303   { 392, "Sofia, Bulgaria - Eastern European Standard Time : (UTC+02:00)" },
2304   { 393, "South Bend, IN, USA - Eastern Standard Time : (UTC-05:00)" },
2305   { 394, "Spokane, WA, USA - Pacific Standard Time : (UTC-08:00)" },
2306   { 395, "Springfield, IL, USA - Central Standard Time : (UTC-06:00)" },
2307   { 396, "Springfield, MA, USA - Eastern Standard Time : (UTC-05:00)" },
2308   { 397, "Springfield, MO, USA - Central Standard Time : (UTC-06:00)" },
2309   { 398, "Sri Jayawardenepura, Sri Lanka - India Standard Time : (UTC+05:30)" },
2310   { 399, "St. Catharines, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2311   { 400, "St. John's, NF, Canada - Newfoundland Standard Time : (UTC-03:30)" },
2312   { 401, "St. Petersburg, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2313   { 402, "St. Petersburg, Russia - Moscow Standard Time : (UTC+03:00)" },
2314   { 403, "Stockholm, Sweden - Central European Standard Time : (UTC+01:00)" },
2315   { 404, "Stockton, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2316   { 405, "Strasbourg, France - Central European Standard Time : (UTC+01:00)" },
2317   { 406, "Stuttgart, Germany - Central European Standard Time : (UTC+01:00)" },
2318   { 407, "Sucre, Bolivia - Bolivia Time : (UTC-04:00)" },
2319   { 408, "Sunnyvale, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2320   { 409, "Suva, Fiji Islands - Fiji Standard Time : (UTC+12:00)" },
2321   { 410, "Sydney, NSW, Australia - Australian Eastern Standard Time : (UTC+10:00)" },
2322   { 411, "Syracuse, NY, USA - Eastern Standard Time : (UTC-05:00)" },
2323   { 412, "T'bilisi, Georgia - Georgia Standard Time : (UTC+04:00)" },
2324   { 413, "Taejon, Korea - Korea Standard Time : (UTC+09:00)" },
2325   { 414, "Taiohae, Marquesas Islands,  French Polynesia - Marquesas Time : (UTC-9:30)" },
2326   { 415, "Taipei, Taiwan - China Standard Time : (UTC+08:00)" },
2327   { 416, "Tallinn, Estonia - Eastern European Standard Time : (UTC+02:00)" },
2328   { 417, "Tampa, FL, USA - Eastern Standard Time : (UTC-05:00)" },
2329   { 418, "Taranto, Italy - Central European Standard Time : (UTC+01:00)" },
2330   { 419, "Tashkent, Uzbekistan - Uzbekistan Time : (UTC+05:00)" },
2331   { 420, "Tegucigalpa, Honduras - Central Standard Time : (UTC-06:00)" },
2332   { 421, "Tehran, Iran - Iran Standard Time : (UTC+03:30)" },
2333   { 422, "Tel Aviv, Israel - Israel Standard Time : (UTC+02:00)" },
2334   { 423, "The Hague, Netherlands - Central European Standard Time : (UTC+01:00)" },
2335   { 424, "Thimphu, Bhutan - Bhutan Time : (UTC+06:00)" },
2336   { 425, "Thunder Bay, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2337   { 426, "Tirana, Albania - Central European Standard Time : (UTC+01:00)" },
2338   { 427, "Tokyo, Japan - Japan Standard Time : (UTC+09:00)" },
2339   { 428, "Toledo, OH, USA - Eastern Standard Time : (UTC-05:00)" },
2340   { 429, "Torino, Italy - Central European Standard Time : (UTC+01:00)" },
2341   { 430, "Toronto, ON, Canada - Eastern Standard Time : (UTC-05:00)" },
2342   { 431, "Torrance, CA, USA - Pacific Standard Time : (UTC-08:00)" },
2343   { 432, "Toulouse, France - Central European Standard Time : (UTC+01:00)" },
2344   { 433, "Tripoli, Libya - Eastern European Standard Time : (UTC+02:00)" },
2345   { 434, "Tucson, AZ, USA - Mountain Standard Time : (UTC-07:00)" },
2346   { 435, "Tulsa, OK, USA - Central Standard Time : (UTC-06:00)" },
2347   { 436, "Tunis, Tunisia - West Africa Time : (UTC+01:00)" },
2348   { 437, "Ulaanbaatar, Mongolia - Ulaanbaatar Time : (UTC+08:00)" },
2349   { 438, "Urumqi, China - China Standard Time : (UTC+08:00)" },
2350   { 439, "Vaduz, Liechtenstein - Central European Standard Time : (UTC+01:00)" },
2351   { 440, "Valencia, Spain - Central European Standard Time : (UTC+01:00)" },
2352   { 441, "Valletta, Malta - Central European Standard Time : (UTC+01:00)" },
2353   { 442, "Vancouver, BC, Canada - Pacific Standard Time : (UTC-08:00)" },
2354   { 443, "Vatican City, Vatican City - Central European Standard Time : (UTC+01:00)" },
2355   { 444, "Venice, Italy - Central European Standard Time : (UTC+01:00)" },
2356   { 445, "Veracruz, Mexico - Central Standard Time : (UTC-06:00)" },
2357   { 446, "Victoria, Seychelles - Seychelles Time : (UTC+04:00)" },
2358   { 447, "Vienna, Austria - Central European Standard Time : (UTC+01:00)" },
2359   { 448, "Vientiane, Laos - Indochina Time : (UTC+07:00)" },
2360   { 449, "Vilnius, Lithuania - Eastern European Standard Time : (UTC+02:00)" },
2361   { 450, "Vladivostok, Russia - Vladivostok Standard Time : (UTC+10:00)" },
2362   { 451, "Volgograd, Russia - Moscow Standard Time : (UTC+03:00)" },
2363   { 452, "Waco, TX, USA - Central Standard Time : (UTC-06:00)" },
2364   { 453, "Warsaw, Poland - Central European Standard Time : (UTC+01:00)" },
2365   { 454, "Washington, DC, USA - Eastern Standard Time : (UTC-05:00)" },
2366   { 455, "Wellington, New Zealand - New Zealand Standard Time : (UTC+12:00)" },
2367   { 456, "Whitehorse, YT, Canada - Pacific Standard Time : (UTC-08:00)" },
2368   { 457, "Windhoek, Namibia - West Africa Time : (UTC+01:00)" },
2369   { 458, "Winnipeg, MB, Canada - Central Standard Time : (UTC-06:00)" },
2370   { 459, "Wuhan, China - China Standard Time : (UTC+08:00)" },
2371   { 460, "Xian, China - China Standard Time : (UTC+08:00)" },
2372   { 461, "Yakutsk, Russia - Yakutsk Standard Time : (UTC+09:00)" },
2373   { 462, "Yangon, Myanmar - Myanmar Standard Time : (UTC+06:30)" },
2374   { 463, "Yekaterinburg, Russia - Yekaterinburg Standard Time : (UTC+05:00)" },
2375   { 464, "Yellowknife, NT, Canada - Mountain Standard Time : (UTC-07:00)" },
2376   { 465, "Yerevan, Armenia - Armenia Time : (UTC+04:00)" },
2377   { 466, "Yokohama, Japan - Japan Standard Time : (UTC+09:00)" },
2378   { 467, "Zagreb, Croatia - Central European Standard Time : (UTC+01:00)" },
2379   { 468, "Zaragoza, Spain - Central European Standard Time : (UTC+01:00)" },
2380   { 469, "Zurich, Switzerland - Central European Standard Time : (UTC+01:00)" },
2381   { 0, NULL }
2382 };
2383 
2384 static const value_string acn_blob_time3_dst_vals[] = {
2385   { 0, "DST US" },
2386   { 1, "DST Europe" },
2387   { 2, "DST Funky" },
2388   { 3, "DST None" },
2389   { 0, NULL }
2390 };
2391 
2392 static const value_string acn_blob_time3_month_vals[] = {
2393   { 0, "None" },
2394   { 1, "January" },
2395   { 2, "February" },
2396   { 3, "March" },
2397   { 4, "April" },
2398   { 5, "May" },
2399   { 6, "June" },
2400   { 7, "July" },
2401   { 8, "August" },
2402   { 9, "September" },
2403   { 10, "October" },
2404   { 11, "November" },
2405   { 12, "December" },
2406   { 0, NULL }
2407 };
2408 
2409 static const value_string acn_blob_time3_week_vals[] = {
2410   { 0, "None" },
2411   { 1, "First" },
2412   { 2, "Second" },
2413   { 3, "Third" },
2414   { 4, "Fourth" },
2415   { 5, "Last" },
2416   { 0, NULL }
2417 };
2418 
2419 static const value_string acn_blob_time3_day_vals[] = {
2420   { 0, "Sunday" },
2421   { 1, "Monday" },
2422   { 2, "Tuesday" },
2423   { 3, "Wednesday" },
2424   { 4, "Thursday" },
2425   { 5, "Friday" },
2426   { 6, "Saturday" },
2427   { 0, NULL }
2428 };
2429 
2430 static const value_string acn_blob_time3_locality_vals[] = {
2431   { 0, "LOCAL" },
2432   { 1, "UTC" },
2433   { 0, NULL }
2434 };
2435 
2436 static const value_string acn_blob_energy_cost_field_name[] = {
2437   { 1, "Month" },
2438   { 2, "Day" },
2439   { 3, "Cost per Hour" },
2440   { 0, NULL }
2441 };
2442 
2443 static const value_string acn_blob_sequence_operation_field_name[] = {
2444   { 1, "Operation Type" },
2445   { 2, "Space" },
2446   { 3, "Sequence Number" },
2447   { 3, "Step Number" },
2448   { 0, NULL }
2449 };
2450 
2451 static const value_string acn_blob_sequence_step_properties_field_name[] = {
2452   { 1, "System" },
2453   { 2, "Processor" },
2454   { 3, "Rack" },
2455   { 4, "Lug" },
2456   { 5, "Module" },
2457   { 6, "Station" },
2458   { 7, "Port" },
2459   { 8, "Subdevice" },
2460   { 9, "Space" },
2461   { 10, "UDN" },
2462   { 11, "Reserved" },
2463   { 12, "Sequence Number" },
2464   { 13, "Step Number" },
2465   { 14, "Fade Time" },
2466   { 15, "Hold Time" },
2467   { 16, "Level[0]" },
2468   { 17, "Level[1]" },
2469   { 18, "Level[2]" },
2470   { 19, "Level[3]" },
2471   { 20, "Level[4]" },
2472   { 21, "Level[5]" },
2473   { 22, "Level[6]" },
2474   { 23, "Level[7]" },
2475   { 24, "Level[8]" },
2476   { 25, "Level[9]" },
2477   { 26, "Level[10]" },
2478   { 27, "Level[11]" },
2479   { 28, "Level[12]" },
2480   { 29, "Level[13]" },
2481   { 30, "Level[14]" },
2482   { 31, "Level[15]" },
2483   { 32, "Level[16]" },
2484   { 33, "Level[17]" },
2485   { 34, "Level[18]" },
2486   { 35, "Level[19]" },
2487   { 36, "Level[20]" },
2488   { 37, "Level[21]" },
2489   { 38, "Level[22]" },
2490   { 39, "Level[23]" },
2491   { 40, "Level[24]" },
2492   { 41, "Level[25]" },
2493   { 42, "Level[26]" },
2494   { 43, "Level[27]" },
2495   { 44, "Level[28]" },
2496   { 45, "Level[29]" },
2497   { 46, "Level[30]" },
2498   { 47, "Level[31]" },
2499   { 48, "Level[32]" },
2500   { 49, "Level[33]" },
2501   { 50, "Level[34]" },
2502   { 51, "Level[35]" },
2503   { 52, "Level[36]" },
2504   { 53, "Level[37]" },
2505   { 54, "Level[38]" },
2506   { 55, "Level[39]" },
2507   { 56, "Level[40]" },
2508   { 57, "Level[41]" },
2509   { 58, "Level[42]" },
2510   { 59, "Level[43]" },
2511   { 60, "Level[44]" },
2512   { 61, "Level[45]" },
2513   { 62, "Level[46]" },
2514   { 63, "Level[47]" },
2515   { 64, "Level[48]" },
2516   { 65, "Level[49]" },
2517   { 66, "Level[50]" },
2518   { 67, "Level[51]" },
2519   { 68, "Level[52]" },
2520   { 69, "Level[53]" },
2521   { 70, "Level[54]" },
2522   { 71, "Level[55]" },
2523   { 72, "Level[56]" },
2524   { 73, "Level[57]" },
2525   { 74, "Level[58]" },
2526   { 75, "Level[59]" },
2527   { 76, "Level[60]" },
2528   { 77, "Level[61]" },
2529   { 78, "Level[62]" },
2530   { 79, "Level[63]" },
2531   { 80, "Level[64]" },
2532   { 81, "Level[65]" },
2533   { 82, "Level[66]" },
2534   { 83, "Level[67]" },
2535   { 84, "Level[68]" },
2536   { 85, "Level[69]" },
2537   { 86, "Level[70]" },
2538   { 87, "Level[71]" },
2539   { 88, "Level[72]" },
2540   { 89, "Level[73]" },
2541   { 90, "Level[74]" },
2542   { 91, "Level[75]" },
2543   { 92, "Level[76]" },
2544   { 93, "Level[77]" },
2545   { 94, "Level[78]" },
2546   { 95, "Level[79]" },
2547   { 96, "Level[80]" },
2548   { 97, "Level[81]" },
2549   { 98, "Level[82]" },
2550   { 99, "Level[83]" },
2551   { 100, "Level[84]" },
2552   { 101, "Level[85]" },
2553   { 102, "Level[86]" },
2554   { 103, "Level[87]" },
2555   { 104, "Level[88]" },
2556   { 105, "Level[89]" },
2557   { 106, "Level[90]" },
2558   { 107, "Level[91]" },
2559   { 108, "Level[92]" },
2560   { 109, "Level[93]" },
2561   { 110, "Level[94]" },
2562   { 111, "Level[95]" },
2563   { 112, "Level[96]" },
2564   { 113, "Level[97]" },
2565   { 114, "Level[98]" },
2566   { 115, "Level[99]" },
2567   { 116, "Level[100]" },
2568   { 117, "Level[101]" },
2569   { 118, "Level[102]" },
2570   { 119, "Level[103]" },
2571   { 120, "Level[104]" },
2572   { 121, "Level[105]" },
2573   { 122, "Level[106]" },
2574   { 123, "Level[107]" },
2575   { 124, "Level[108]" },
2576   { 125, "Level[109]" },
2577   { 126, "Level[110]" },
2578   { 127, "Level[111]" },
2579   { 128, "Level[112]" },
2580   { 129, "Level[113]" },
2581   { 130, "Level[114]" },
2582   { 131, "Level[115]" },
2583   { 132, "Level[116]" },
2584   { 133, "Level[117]" },
2585   { 134, "Level[118]" },
2586   { 135, "Level[119]" },
2587   { 136, "Level[120]" },
2588   { 137, "Level[121]" },
2589   { 138, "Level[122]" },
2590   { 139, "Level[123]" },
2591   { 140, "Level[124]" },
2592   { 141, "Level[125]" },
2593   { 142, "Level[126]" },
2594   { 143, "Level[127]" },
2595   { 144, "Level[128]" },
2596   { 145, "Level[129]" },
2597   { 146, "Level[130]" },
2598   { 147, "Level[131]" },
2599   { 148, "Level[132]" },
2600   { 149, "Level[133]" },
2601   { 150, "Level[134]" },
2602   { 151, "Level[135]" },
2603   { 152, "Level[136]" },
2604   { 153, "Level[137]" },
2605   { 154, "Level[138]" },
2606   { 155, "Level[139]" },
2607   { 156, "Level[140]" },
2608   { 157, "Level[141]" },
2609   { 158, "Level[142]" },
2610   { 159, "Level[143]" },
2611   { 160, "Level[144]" },
2612   { 161, "Level[145]" },
2613   { 162, "Level[146]" },
2614   { 163, "Level[147]" },
2615   { 164, "Level[148]" },
2616   { 165, "Level[149]" },
2617   { 166, "Level[150]" },
2618   { 167, "Level[151]" },
2619   { 168, "Level[152]" },
2620   { 169, "Level[153]" },
2621   { 170, "Level[154]" },
2622   { 171, "Level[155]" },
2623   { 172, "Level[156]" },
2624   { 173, "Level[157]" },
2625   { 174, "Level[158]" },
2626   { 175, "Level[159]" },
2627   { 176, "Level[160]" },
2628   { 177, "Level[161]" },
2629   { 178, "Level[162]" },
2630   { 179, "Level[163]" },
2631   { 180, "Level[164]" },
2632   { 181, "Level[165]" },
2633   { 182, "Level[166]" },
2634   { 183, "Level[167]" },
2635   { 184, "Level[168]" },
2636   { 185, "Level[169]" },
2637   { 186, "Level[170]" },
2638   { 187, "Level[171]" },
2639   { 188, "Level[172]" },
2640   { 189, "Level[173]" },
2641   { 190, "Level[174]" },
2642   { 191, "Level[175]" },
2643   { 192, "Level[176]" },
2644   { 193, "Level[177]" },
2645   { 194, "Level[178]" },
2646   { 195, "Level[179]" },
2647   { 196, "Level[180]" },
2648   { 197, "Level[181]" },
2649   { 198, "Level[182]" },
2650   { 199, "Level[183]" },
2651   { 200, "Level[184]" },
2652   { 201, "Level[185]" },
2653   { 202, "Level[186]" },
2654   { 203, "Level[187]" },
2655   { 204, "Level[188]" },
2656   { 205, "Level[189]" },
2657   { 206, "Level[190]" },
2658   { 207, "Level[191]" },
2659   { 0, NULL }
2660 };
2661 static value_string_ext acn_blob_sequence_step_properties_field_name_ext = VALUE_STRING_EXT_INIT(acn_blob_sequence_step_properties_field_name);
2662 
2663 static const value_string acn_blob_type_vals[] = {
2664   { ACN_BLOB_IPV4,                           "IPv4 Blob" },
2665   { ACN_BLOB_IPV6,                           "IPv6 Blob" },
2666   { ACN_BLOB_ERROR1,                         "Error Blob v1" },
2667   { ACN_BLOB_ERROR2,                         "Error Blob v2" },
2668   { ACN_BLOB_METADATA,                       "Metadata" },
2669   { ACN_BLOB_METADATA_DEVICES,               "Metadata Devices" },
2670   { ACN_BLOB_METADATA_TYPES,                 "Metadata Types" },
2671   { ACN_BLOB_TIME1,                          "Time Blob (deprecated 1)" },
2672   { ACN_BLOB_DIMMER_PROPERTIES,              "Dimmer Properties Blob v1" },
2673   { ACN_BLOB_DIMMER_LOAD_PROPERTIES,         "Dimmer Load Properties Blob v1" },
2674   { ACN_BLOB_DIMMING_RACK_PROPERTIES,        "Dimming Rack Properties Blob v1" },
2675   { ACN_BLOB_DIMMING_RACK_STATUS_PROPERTIES, "Dimming Rack Status Properties Blob v1" },
2676   { ACN_BLOB_DIMMER_STATUS_PROPERTIES,       "Dimmer Status Properties Blob v1" },
2677   { ACN_BLOB_SET_LEVELS_OPERATION,           "Set Levels Operation Blob" },
2678   { ACN_BLOB_PRESET_OPERATION,               "Preset Operation Blob" },
2679   { ACN_BLOB_ADVANCED_FEATURES_OPERATION,    "Advanced Features Operation Blob" },
2680   { ACN_BLOB_DIRECT_CONTROL_OPERATION,       "Direct Control Operation Blob" },
2681   { ACN_BLOB_GENERATE_CONFIG_OPERATION,      "Generate Config Operation Blob" },
2682   { ACN_BLOB_ERROR3,                         "Error Blob v3" },
2683   { ACN_BLOB_DIMMER_PROPERTIES2,             "Dimmer Properties Blob v2" },
2684   { ACN_BLOB_DIMMER_LOAD_PROPERTIES2,        "Dimmer Load Properties Blob v2" },
2685   { ACN_BLOB_DIMMER_RACK_PROPERTIES2,        "Dimming Rack Properties Blob v2" },
2686   { ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2, "Dimming Rack Status Properties Blob v2" },
2687   { ACN_BLOB_DIMMER_STATUS_PROPERTIES2,      "Dimmer Status Properties Blob v2" },
2688   { ACN_BLOB_TIME2,                          "Time Blob (deprecated 2)" },
2689   { ACN_BLOB_RPC,                            "RPC Blob" },
2690   { ACN_BLOB_DHCP_CONFIG_SUBNET,             "DHCP Config Subnet Blob" },
2691   { ACN_BLOB_DHCP_CONFIG_STATIC_ROUTE,       "DHCP Config Static Route Blob" },
2692   { ACN_BLOB_ENERGY_MANAGEMENT,              "Energy Management Blob" },
2693   { ACN_BLOB_PRESET_PROPERTIES,              "Preset Properties Blob" },
2694   { ACN_BLOB_TIME3,                          "Time Blob v2" },
2695   { ACN_BLOB_ENERGY_COST,                    "Energy Cost Blob" },
2696   { ACN_BLOB_SEQUENCE_OPERATIONS,            "Sequence Operations Blob" },
2697   { ACN_BLOB_SEQUENCE_STEP_PROPERTIES,       "Sequence Step Properties Blob" },
2698   { 0, NULL }
2699 };
2700 
2701 static const value_string acn_dmp_vector_vals[] = {
2702   { ACN_DMP_VECTOR_UNKNOWN,            "Unknown"},
2703   { ACN_DMP_VECTOR_GET_PROPERTY,       "Get Property"},
2704   { ACN_DMP_VECTOR_SET_PROPERTY,       "Set Property"},
2705   { ACN_DMP_VECTOR_GET_PROPERTY_REPLY, "Get property reply"},
2706   { ACN_DMP_VECTOR_EVENT,              "Event"},
2707   { ACN_DMP_VECTOR_MAP_PROPERTY,       "Map Property"},
2708   { ACN_DMP_VECTOR_UNMAP_PROPERTY,     "Unmap Property"},
2709   { ACN_DMP_VECTOR_SUBSCRIBE,          "Subscribe"},
2710   { ACN_DMP_VECTOR_UNSUBSCRIBE,        "Unsubscribe"},
2711   { ACN_DMP_VECTOR_GET_PROPERTY_FAIL,  "Get Property Fail"},
2712   { ACN_DMP_VECTOR_SET_PROPERTY_FAIL,  "Set Property Fail"},
2713   { ACN_DMP_VECTOR_MAP_PROPERTY_FAIL,  "Map Property Fail"},
2714   { ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT,   "Subscribe Accept"},
2715   { ACN_DMP_VECTOR_SUBSCRIBE_REJECT,   "Subscribe Reject"},
2716   { ACN_DMP_VECTOR_ALLOCATE_MAP,       "Allocate Map"},
2717   { ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY, "Allocate Map Reply"},
2718   { ACN_DMP_VECTOR_DEALLOCATE_MAP,     "Deallocate Map" },
2719   { ACN_DMP_VECTOR_SYNC_EVENT,         "Sync Event" },
2720   { 0,       NULL },
2721 };
2722 
2723 static const value_string acn_ip_address_type_vals[] = {
2724   { ACN_ADDR_NULL,   "Null"},
2725   { ACN_ADDR_IPV4,   "IPv4"},
2726   { ACN_ADDR_IPV6,   "IPv6"},
2727   { ACN_ADDR_IPPORT, "Port"},
2728   { 0,       NULL },
2729 };
2730 
2731 static const value_string acn_refuse_code_vals[] = {
2732   { ACN_REFUSE_CODE_NONSPECIFIC,    "Nonspecific" },
2733   { ACN_REFUSE_CODE_ILLEGAL_PARAMS, "Illegal Parameters" },
2734   { ACN_REFUSE_CODE_LOW_RESOURCES,  "Low Resources" },
2735   { ACN_REFUSE_CODE_ALREADY_MEMBER, "Already Member" },
2736   { ACN_REFUSE_CODE_BAD_ADDR_TYPE,  "Bad Address Type" },
2737   { ACN_REFUSE_CODE_NO_RECIP_CHAN,  "No Reciprocal Channel" },
2738   { 0,       NULL },
2739 };
2740 
2741 static const value_string acn_reason_code_vals[] = {
2742   { ACN_REASON_CODE_NONSPECIFIC,         "Nonspecific" },
2743   { ACN_REASON_CODE_NO_RECIP_CHAN,       "No Reciprocal Channel" },
2744   { ACN_REASON_CODE_CHANNEL_EXPIRED,     "Channel Expired" },
2745   { ACN_REASON_CODE_LOST_SEQUENCE,       "Lost Sequence" },
2746   { ACN_REASON_CODE_SATURATED,           "Saturated" },
2747   { ACN_REASON_CODE_TRANS_ADDR_CHANGING, "Transport Address Changing" },
2748   { ACN_REASON_CODE_ASKED_TO_LEAVE,      "Asked to Leave" },
2749   { ACN_REASON_CODE_NO_RECIPIENT,        "No Recipient"},
2750   { 0,       NULL },
2751 };
2752 
2753 static const value_string acn_dmp_reason_code_vals[] = {
2754   { ACN_DMP_REASON_CODE_NONSPECIFIC,                "Nonspecific" },
2755   { ACN_DMP_REASON_CODE_NOT_A_PROPERTY,             "Not a Property" },
2756   { ACN_DMP_REASON_CODE_WRITE_ONLY,                 "Write Only" },
2757   { ACN_DMP_REASON_CODE_NOT_WRITABLE,               "Not Writable" },
2758   { ACN_DMP_REASON_CODE_DATA_ERROR,                 "Data Error" },
2759   { ACN_DMP_REASON_CODE_MAPS_NOT_SUPPORTED,         "Maps not Supported" },
2760   { ACN_DMP_REASON_CODE_SPACE_NOT_AVAILABLE,        "Space not Available" },
2761   { ACN_DMP_REASON_CODE_PROP_NOT_MAPPABLE,          "Property not Mappable"},
2762   { ACN_DMP_REASON_CODE_MAP_NOT_ALLOCATED,          "Map not Allocated"},
2763   { ACN_DMP_REASON_CODE_SUBSCRIPTION_NOT_SUPPORTED, "Subscription not Supported"},
2764   { ACN_DMP_REASON_CODE_NO_SUBSCRIPTIONS_SUPPORTED, "No Subscriptions Supported"},
2765   { 0,       NULL },
2766 };
2767 
2768 static const enum_val_t dmx_display_view[] = {
2769   { "hex"    , "Hex    ",     ACN_PREF_DMX_DISPLAY_HEX  },
2770   { "decimal", "Decimal",     ACN_PREF_DMX_DISPLAY_DEC  },
2771   { "percent", "Percent",     ACN_PREF_DMX_DISPLAY_PER  },
2772   { NULL, NULL, 0 }
2773 };
2774 
2775 static const enum_val_t dmx_display_line_format[] = {
2776   { "20 per line", "20 per line",     ACN_PREF_DMX_DISPLAY_20PL  },
2777   { "16 per line", "16 per line",     ACN_PREF_DMX_DISPLAY_16PL  },
2778   { NULL, NULL, 0 }
2779 };
2780 
2781 
2782 static const value_string magic_pdu_subtypes[] = {
2783   { MAGIC_V1,           "V1" },
2784   { MAGIC_COMMAND,      "V2 Command" },
2785   { MAGIC_REPLY,        "V2 Reply" },
2786   { MAGIC_REPLY_TYPE_3, "V2 Reply Type 3" },
2787   { 0, NULL }
2788 };
2789 
2790 static const value_string magic_v1command_vals[] = {
2791   { V1_SWITCH_TO_NET1, "Switch to Net1" },
2792   { V1_SWITCH_TO_NET2, "Switch to Net2" },
2793   { V1_BOOTP,          "bootp" },
2794   { 0, NULL }
2795 };
2796 
2797 static const value_string magic_command_vals[] = {
2798   { V2_CMD_SWITCH_TO_NET1,          "Switch to Net1 mode" },
2799   { V2_CMD_SWITCH_TO_NET2,          "Switch to Net2 mode" },
2800   { V2_CMD_DOWNLOAD,                "Code download" },
2801   { V2_CMD_SOFTBOOT,                "Soft reboot" },
2802   { V2_CMD_PHYSICAL_BEACON,         "Physical beacon" },
2803   { V2_CMD_NETWORK_BEACON,          "Network beacon" },
2804   { V2_CMD_SWITCH_TO_ACN,           "Switch to ACN mode" },
2805   { V2_CMD_SWITCH_TO_DYNAMIC_IP,    "Switch to dynamic IP address configuration" },
2806   { V2_CMD_EXTENDED_NETWORK_BEACON, "Extended network beacon" },
2807   { V2_CMD_IP_CONFIGURATION,        "IP configuration" },
2808   { V2_CMD_RESTORE_FACTORY_DEFAULT, "Restore factory default" },
2809   { V2_CMD_PHYSICAL_BEACON_BY_CID,  "Physical beacon by CID" },
2810   { V2_CMD_NET2_DOWNLOAD,           "NET2 code download and reboot" },
2811   { 0, NULL }
2812 };
2813 
2814 static const value_string magic_reset_lease_vals[] = {
2815   { MAGIC_SWITCH_TO_DYNAMIC_MAINTAIN_LEASE, "Maintain lease" },
2816   { MAGIC_SWITCH_TO_DYNAMIC_RESET_LEASE,    "Reset lease" },
2817   { 0, NULL }
2818 };
2819 
2820 static const value_string magic_ip_configuration_vals[] = {
2821   { MAGIC_DYNAMIC_IP_MAINTAIN_LEASE, "Dynamic IP, maintain lease" },
2822   { MAGIC_DYNAMIC_IP_RESET_LEASE,    "Dynamic IP, reset lease" },
2823   { MAGIC_STATIC_IP,                 "Static IP" },
2824   { 0, NULL }
2825 };
2826 
2827 static const value_string security_seq_type_vals[] = {
2828   { 0, "Time (ms since epoch)" },
2829   { 1, "Volatile" },
2830   { 2, "Non-volatile" },
2831   { 0, NULL }
2832 };
2833 
2834 static const value_string rdmnet_llrp_vector_vals[] = {
2835   { RDMNET_LLRP_VECTOR_PROBE_REQUEST, "LLRP probe request" },
2836   { RDMNET_LLRP_VECTOR_PROBE_REPLY,   "LLRP probe reply" },
2837   { RDMNET_LLRP_VECTOR_RDM_CMD,       "LLRP RDM command" },
2838   { 0, NULL }
2839 };
2840 
2841 static const value_string rdmnet_llrp_probe_request_vals[] = {
2842   { VECTOR_PROBE_REQUEST_DATA, "Vector probe request data" },
2843   { 0, NULL }
2844 };
2845 
2846 static const value_string rdmnet_llrp_probe_reply_vals[] = {
2847   { VECTOR_PROBE_REPLY_DATA, "Vector probe reply data" },
2848   { 0, NULL }
2849 };
2850 
2851 static const value_string rdmnet_llrp_probe_reply_component_type_vals[] = {
2852   { RDMNET_LLRP_COMPONENT_TYPE_RPT_DEVICE,      "Device target" },
2853   { RDMNET_LLRP_COMPONENT_TYPE_RPT_CONTROLLER,  "Controller target" },
2854   { RDMNET_LLRP_COMPONENT_TYPE_BROKER,          "Broker target" },
2855   { RDMNET_LLRP_COMPONENT_TYPE_NON_RDMNET,      "Non RDMnet target" },
2856   { 0, NULL }
2857 };
2858 
2859 static const value_string rdmnet_llrp_rdm_command_start_code_vals[] = {
2860   { RDMNET_LLRP_VECTOR_RDM_CMD_START_CODE,  "RDM Start Code" },
2861   { 0, NULL }
2862 };
2863 
2864 static const value_string rdmnet_broker_disconnect_reason_vals[] = {
2865   { RDMNET_RPT_DISCONNECT_SHUTDOWN,               "Component shut down" },
2866   { RDMNET_RPT_DISCONNECT_CAPACITY_EXHAUSTED,     "Component capacity exhausted" },
2867   { RDMNET_RPT_DISCONNECT_HARDWARE_FAULT,         "Component hardware fault" },
2868   { RDMNET_RPT_DISCONNECT_SOFTWARE_FAULT,         "Component software fault" },
2869   { RDMNET_RPT_DISCONNECT_SOFTWARE_RESET,         "Component software reset" },
2870   { RDMNET_RPT_DISCONNECT_INCORRECT_SCOPE,        "Broker incorrect scope" },
2871   { RDMNET_RPT_DISCONNECT_LLRP_RECONFIGURE,       "Component reconfigured by LLRP" },
2872   { RDMNET_RPT_DISCONNECT_RPT_RECONFIGURE,        "Component reconfigured by RPT" },
2873   { RDMNET_RPT_DISCONNECT_USER_RECONFIGURE,       "Component reconfigured by user" },
2874   { 0, NULL }
2875 };
2876 
2877 static const value_string rdmnet_rpt_vector_vals[] = {
2878   { RDMNET_RPT_VECTOR_REQUEST,       "Request" },
2879   { RDMNET_RPT_VECTOR_STATUS,        "Status" },
2880   { RDMNET_RPT_VECTOR_NOTIFICATION,  "Notification" },
2881   { 0, NULL }
2882 };
2883 
2884 static const value_string rdmnet_rpt_request_vals[] = {
2885   { RDMNET_RPT_VECTOR_REQUEST_RDM_CMD,  "RDM Command" },
2886   { 0, NULL }
2887 };
2888 
2889 static const value_string rdmnet_rpt_status_vector_vals[] = {
2890   { RDMNET_RPT_VECTOR_STATUS_UNKNOWN_RPT_UID,        "Unknown RPT UID" },
2891   { RDMNET_RPT_VECTOR_STATUS_RDM_TIMEOUT,            "RDM Timeout" },
2892   { RDMNET_RPT_VECTOR_STATUS_RDM_INVALID_RESPONSE,   "Invalid RDM Response" },
2893   { RDMNET_RPT_VECTOR_STATUS_UNKNOWN_RDM_UID,        "Unknown RDM UID" },
2894   { RDMNET_RPT_VECTOR_STATUS_UNKNOWN_ENDPOINT,       "Unknown Endpoint" },
2895   { RDMNET_RPT_VECTOR_STATUS_BROADCAST_COMPLETE,     "Broadcast Complete" },
2896   { RDMNET_RPT_VECTOR_STATUS_UNKNOWN_VECTOR,         "Unknown Vector" },
2897   { RDMNET_RPT_VECTOR_STATUS_INVALID_MESSAGE,        "Invalid Message" },
2898   { RDMNET_RPT_VECTOR_STATUS_INVALID_COMMAND_CLASS,  "Invalid Command Class" },
2899   { 0, NULL }
2900 };
2901 
2902 static const value_string rdmnet_rpt_notification_vals[] = {
2903   { RDMNET_RPT_VECTOR_NOTIFICATION_RDM_CMD,  "RDM Command" },
2904   { 0, NULL }
2905 };
2906 
2907 static const value_string rdmnet_rpt_request_rdm_command_start_code_vals[] = {
2908   { RDMNET_RPT_VECTOR_RDM_CMD_RD_DATA,  "RDM Start Code" },
2909   { 0, NULL }
2910 };
2911 
2912 static const value_string rdmnet_broker_vector_vals[] = {
2913   { RDMNET_BROKER_VECTOR_FETCH_CLIENT_LIST,       "Fetch client list" },
2914   { RDMNET_BROKER_VECTOR_CONNECTED_CLIENT_LIST,   "Connected client list" },
2915   { RDMNET_BROKER_VECTOR_CLIENT_ADD,              "Add client" },
2916   { RDMNET_BROKER_VECTOR_CLIENT_REMOVE,           "Remove client" },
2917   { RDMNET_BROKER_VECTOR_CLIENT_ENTRY_CHANGE,     "Change client entry" },
2918   { RDMNET_BROKER_VECTOR_CONNECT,                 "Connect" },
2919   { RDMNET_BROKER_VECTOR_CONNECT_REPLY,           "Connect reply" },
2920   { RDMNET_BROKER_VECTOR_CLIENT_ENTRY_UPDATE,     "Update client entry" },
2921   { RDMNET_BROKER_VECTOR_REDIRECT_V4,             "Redirect IP v4" },
2922   { RDMNET_BROKER_VECTOR_REDIRECT_V6,             "Redirect IP v6" },
2923   { RDMNET_BROKER_VECTOR_DISCONNECT,              "Disconnect" },
2924   { RDMNET_BROKER_VECTOR_NULL,                    "Null" },
2925   { RDMNET_BROKER_VECTOR_REQUEST_DYNAMIC_UIDS,    "Request Dynamic UIDs" },
2926   { RDMNET_BROKER_VECTOR_ASSIGNED_DYNAMIC_UIDS,   "Assigned Dynamic UIDs" },
2927   { RDMNET_BROKER_VECTOR_FETCH_DYNAMIC_UID_LIST,  "Fetch dynamic UID List" },
2928   { 0, NULL }
2929 };
2930 
2931 static const value_string rdmnet_broker_status_code_vals[] = {
2932   { RDMNET_BROKER_CONNECT_OK,                    "Ok" },
2933   { RDMNET_BROKER_CONNECT_SCOPE_MISMATCH,        "Scope mismatch" },
2934   { RDMNET_BROKER_CONNECT_CAPACITY_EXCEEDED,     "Capacity exceeded" },
2935   { RDMNET_BROKER_CONNECT_DUPLICATE_UID,         "Duplicate UID" },
2936   { RDMNET_BROKER_CONNECT_INVALID_CLIENT_ENTRY,  "Invalid client entry" },
2937   { RDMNET_BROKER_CONNECT_INVALID_UID,           "Invalid UID" },
2938   { 0, NULL }
2939 };
2940 
2941 static const value_string dynamic_uid_mapping_status_code_vals[] = {
2942   { RDMNET_DYNAMIC_UID_STATUS_OK,                 "Dynamic UID Status Ok" },
2943   { RDMNET_DYNAMIC_UID_STATUS_INVALID_REQUEST,    "Dynamic UID Status Invalid Request" },
2944   { RDMNET_DYNAMIC_UID_STATUS_UID_NOT_FOUND,      "Dynamic UID Status UID Not Found" },
2945   { RDMNET_DYNAMIC_UID_STATUS_DUPLICATE_RID,      "Dynamic UID Status Duplicate RID" },
2946   { RDMNET_DYNAMIC_UID_STATUS_CAPACITY_EXHAUSTED, "Dynamic UID Status Capacity Exhausted" },
2947   { 0, NULL }
2948 };
2949 
2950 static const value_string broker_client_protocol_vals[] = {
2951   { RDMNET_CLIENT_PROTOCOL_RPT,  "Client Protocol RPT" },
2952   { RDMNET_CLIENT_PROTOCOL_EPT,  "Client Protocol EPT" },
2953   { 0, NULL }
2954 };
2955 
2956 static const value_string broker_client_rpt_client_type_vals[] = {
2957   { RDMNET_RPT_CLIENT_TYPE_DEVICE,      "Device" },
2958   { RDMNET_RPT_CLIENT_TYPE_CONTROLLER,  "Controller" },
2959   { 0, NULL }
2960 };
2961 
2962 static const value_string rdmnet_ept_vector_vals[] = {
2963   { RDMNET_EPT_VECTOR_DATA,    "Data" },
2964   { RDMNET_EPT_VECTOR_STATUS,  "Status" },
2965   { 0, NULL }
2966 };
2967 
2968 static dissector_handle_t rdm_handle;
2969 
2970 /******************************************************************************/
2971 /* Test to see if it is a Magic Bullet Packet                                 */
2972 static gboolean
is_magic(tvbuff_t * tvb)2973 is_magic(tvbuff_t *tvb)
2974 {
2975   static const guint8 magic_protocol_id = 15;
2976 
2977   if (tvb_get_guint8(tvb, 0) == magic_protocol_id)
2978     return TRUE;
2979 
2980   return FALSE;
2981 }
2982 
2983 /******************************************************************************/
2984 /* Dissect Magic Bullet                                                       */
2985 static int
dissect_magic(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)2986 dissect_magic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2987 {
2988   guint8 pdu_subtype;
2989   gint offset = 0;
2990   const char *pdu_subtype_string;
2991   proto_tree *ti, *subtype_item;
2992   proto_tree *magic_tree;
2993   guint32 command;
2994   gint32 str_len;
2995   guint32 major, minor, patch, aud, crit, build;
2996   gchar *buffer;
2997 
2998   /* Set the protocol column */
2999   col_set_str(pinfo->cinfo, COL_PROTOCOL, "MAGIC");
3000 
3001   /* Create our tree */
3002   ti = proto_tree_add_item(tree, proto_magic, tvb, offset, -1, ENC_NA);
3003   magic_tree = proto_item_add_subtree(ti, ett_magic);
3004 
3005   /* Protocol ID */
3006   proto_tree_add_item(magic_tree, hf_magic_protocol_id, tvb, offset, 1, ENC_BIG_ENDIAN);
3007   offset++;
3008 
3009   /* PDU Type */
3010   pdu_subtype = tvb_get_guint8(tvb, offset);
3011   pdu_subtype_string = val_to_str(pdu_subtype, magic_pdu_subtypes, "Unknown (0x%02x)");
3012 
3013   /* Adjust info column */
3014   col_clear(pinfo->cinfo, COL_INFO);
3015   col_add_fstr(pinfo->cinfo, COL_INFO, "MAGIC - %s", pdu_subtype_string);
3016 
3017   /* Append subtype description */
3018   proto_item_append_text(ti, ": %s", pdu_subtype_string);
3019 
3020   subtype_item = proto_tree_add_item(magic_tree, hf_magic_pdu_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
3021   offset++;
3022   proto_tree_add_item(magic_tree, hf_magic_major_version, tvb, offset, 1, ENC_BIG_ENDIAN);
3023   offset++;
3024   proto_tree_add_item(magic_tree, hf_magic_minor_version, tvb, offset, 1, ENC_BIG_ENDIAN);
3025   offset++;
3026 
3027   switch (pdu_subtype) {
3028     case MAGIC_V1:
3029       proto_tree_add_item(magic_tree, hf_magic_v1command_vals, tvb, offset, 4, ENC_LITTLE_ENDIAN);
3030       offset += 4;
3031       break;
3032 
3033     case MAGIC_COMMAND:
3034       /* note, v2 is big-endian */
3035       proto_tree_add_item_ret_uint(magic_tree, hf_magic_command_vals, tvb, offset, 4, ENC_BIG_ENDIAN, &command);
3036       offset += 4;
3037       /* deal with variable parameter */
3038       switch (command) {
3039         case V2_CMD_DOWNLOAD:
3040           proto_tree_add_item(magic_tree, hf_magic_command_tftp, tvb, offset, 4, ENC_BIG_ENDIAN);
3041           offset += 4;
3042           break;
3043         case V2_CMD_PHYSICAL_BEACON:
3044           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
3045           offset += 4;
3046           break;
3047         case V2_CMD_NETWORK_BEACON:
3048           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
3049           offset += 4;
3050           break;
3051         case V2_CMD_SWITCH_TO_DYNAMIC_IP:
3052           proto_tree_add_item(magic_tree, hf_magic_command_reset_lease, tvb, offset, 4, ENC_BIG_ENDIAN);
3053           offset += 4;
3054           break;
3055         case V2_CMD_EXTENDED_NETWORK_BEACON:
3056           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
3057           offset += 4;
3058           break;
3059         case V2_CMD_IP_CONFIGURATION:
3060           proto_tree_add_item(magic_tree, hf_magic_command_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
3061           offset += 16;
3062           proto_tree_add_item(magic_tree, hf_magic_command_ip_configuration, tvb, offset, 4, ENC_BIG_ENDIAN);
3063           offset += 4;
3064           proto_tree_add_item(magic_tree, hf_magic_command_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
3065           offset += 4;
3066           proto_tree_add_item(magic_tree, hf_magic_command_subnet_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
3067           offset += 4;
3068           proto_tree_add_item(magic_tree, hf_magic_command_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
3069           offset += 4;
3070           break;
3071         case V2_CMD_RESTORE_FACTORY_DEFAULT:
3072           proto_tree_add_item(magic_tree, hf_magic_command_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
3073           offset += 16;
3074           break;
3075         case V2_CMD_PHYSICAL_BEACON_BY_CID:
3076           proto_tree_add_item(magic_tree, hf_magic_command_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
3077           offset += 16;
3078           proto_tree_add_item(magic_tree, hf_magic_command_beacon_duration, tvb, offset, 4, ENC_BIG_ENDIAN);
3079           offset += 4;
3080           break;
3081         /* case V2_CMD_SOFTBOOT:       */
3082         /* case V2_CMD_SWITCH_TO_NET1: */
3083         /* case V2_CMD_SWITCH_TO_NET2: */
3084         /* case V2_CMD_SWITCH_TO_ACN:  */
3085         /* case V2_CMD_NET2_DOWNLOAD:  */
3086       }
3087       break;
3088 
3089     case MAGIC_REPLY:
3090       /* note, v2 is big-endian */
3091       proto_tree_add_item(magic_tree, hf_magic_reply_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
3092       offset += 4;
3093       proto_tree_add_item(magic_tree, hf_magic_reply_subnet_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
3094       offset += 4;
3095       proto_tree_add_item(magic_tree, hf_magic_reply_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
3096       offset += 4;
3097       proto_tree_add_item(magic_tree, hf_magic_reply_tftp, tvb, offset, 4, ENC_BIG_ENDIAN);
3098       offset += 4;
3099 
3100       /* encoded and display version */
3101       major = tvb_get_guint8(tvb, offset++);
3102       minor = tvb_get_guint8(tvb, offset++);
3103       patch = tvb_get_guint8(tvb, offset++);
3104       aud = tvb_get_guint8(tvb, offset++);
3105       crit = tvb_get_guint8(tvb, offset++);
3106       build = tvb_get_ntohs(tvb, offset);
3107       offset += 2;
3108 
3109       offset -= 7;
3110       buffer = wmem_strdup_printf(pinfo->pool, "%d.%d.%d.%d.%d.%d", major, minor, patch, aud, crit, build);
3111       proto_tree_add_string(magic_tree, hf_magic_reply_version, tvb, offset, 7, buffer);
3112       offset += 7;
3113 
3114       /* Device Type Name string */
3115       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_device_type_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
3116       offset += str_len;
3117 
3118       /* Default Name string */
3119       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_default_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
3120       offset += str_len;
3121 
3122       /* User Name string */
3123       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_user_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
3124       offset += str_len;
3125       break;
3126 
3127     case MAGIC_REPLY_TYPE_3:
3128       command = tvb_get_ntohl(tvb, offset);
3129       proto_tree_add_item(magic_tree, hf_magic_command_vals, tvb, offset, 4, ENC_BIG_ENDIAN);
3130       offset += 4;
3131       proto_tree_add_item(magic_tree, hf_magic_reply_ip_address, tvb, offset, 4, ENC_BIG_ENDIAN);
3132       offset += 4;
3133       proto_tree_add_item(magic_tree, hf_magic_reply_subnet_mask, tvb, offset, 4, ENC_BIG_ENDIAN);
3134       offset += 4;
3135       proto_tree_add_item(magic_tree, hf_magic_reply_gateway, tvb, offset, 4, ENC_BIG_ENDIAN);
3136       offset += 4;
3137       proto_tree_add_item(magic_tree, hf_magic_reply_tftp, tvb, offset, 4, ENC_BIG_ENDIAN);
3138       offset += 4;
3139       proto_tree_add_item(magic_tree, hf_magic_reply_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
3140       offset += 16;
3141       proto_tree_add_item(magic_tree, hf_magic_reply_dcid, tvb, offset, 16, ENC_BIG_ENDIAN);
3142       offset += 16;
3143 
3144       /* encoded and display version */
3145       major = tvb_get_guint8(tvb, offset++);
3146       minor = tvb_get_guint8(tvb, offset++);
3147       patch = tvb_get_guint8(tvb, offset++);
3148       aud = tvb_get_guint8(tvb, offset++);
3149       crit = tvb_get_guint8(tvb, offset++);
3150       build = tvb_get_ntohs(tvb, offset);
3151       offset += 2;
3152 
3153       offset -= 7;
3154       buffer = wmem_strdup_printf(pinfo->pool, "%d.%d.%d.%d.%d.%d", major, minor, patch, aud, crit, build);
3155       proto_tree_add_string(magic_tree, hf_magic_reply_version, tvb, offset, 7, buffer);
3156       offset += 7;
3157 
3158       /* Device Type Name string */
3159       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_device_type_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
3160       offset += str_len;
3161 
3162       /* Default Name string */
3163       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_default_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
3164       offset += str_len;
3165 
3166       /* User Name string */
3167       proto_tree_add_item_ret_length(magic_tree, hf_magic_reply_user_name, tvb, offset, 1, ENC_NA|ENC_ASCII, &str_len);
3168       offset += str_len;
3169       break;
3170 
3171     default:
3172       expert_add_info(pinfo, subtype_item, &ei_magic_reply_invalid_type);
3173       offset = tvb_captured_length(tvb);
3174   }
3175   return offset;
3176 }
3177 
3178 /******************************************************************************/
3179 /* Test to see if it is an ACN or an RDMnet Packet over UDP                   */
3180 static gboolean
is_acn_or_rdmnet_over_udp(tvbuff_t * tvb,guint32 * protocol_id)3181 is_acn_or_rdmnet_over_udp(tvbuff_t *tvb, guint32 *protocol_id)
3182 {
3183   static const char acn_packet_id[] = "ASC-E1.17\0\0\0";  /* must be 12 bytes */
3184   guint32  offset;
3185   guint8   pdu_flags;
3186 
3187   if (tvb_captured_length(tvb) < (4+sizeof(acn_packet_id) + 6))
3188     return FALSE;
3189 
3190   /* Check the bytes in octets 4 - 16 */
3191   if (tvb_memeql(tvb, 4, (const guint8*)acn_packet_id, sizeof(acn_packet_id)-1) != 0)
3192     return FALSE;
3193 
3194   offset = 16;
3195   pdu_flags = tvb_get_guint8(tvb, offset) & 0xf0;
3196   if (pdu_flags & ACN_PDU_FLAG_L) {
3197     /* length bit is set: there are three length bytes */
3198     offset += 3;
3199   }
3200   else {
3201     /* length bit is clear: there are two length bytes */
3202     offset += 2;
3203   }
3204 
3205   *protocol_id = tvb_get_ntohl(tvb, offset);
3206   return TRUE;
3207 }
3208 
3209 /******************************************************************************/
3210 /* Test to see if it is an RDMnet Packet over TCP                             */
3211 static gboolean
is_rdmnet_over_tcp(tvbuff_t * tvb)3212 is_rdmnet_over_tcp(tvbuff_t *tvb)
3213 {
3214   static const char acn_packet_id[] = "ASC-E1.17\0\0\0";  /* must be 12 bytes */
3215   guint32  offset;
3216   guint32  protocol_id;
3217   guint8   pdu_flags;
3218 
3219   if (tvb_captured_length(tvb) < (4+sizeof(acn_packet_id))) {
3220     return FALSE;
3221   }
3222 
3223   /* Check the bytes in octets 0 - 12 */
3224   if (tvb_memeql(tvb, 0, (const guint8*)acn_packet_id, sizeof(acn_packet_id)-1) != 0) {
3225     return FALSE;
3226   }
3227 
3228   offset = 16;
3229   pdu_flags = tvb_get_guint8(tvb, offset) & 0xf0;
3230   if (pdu_flags & ACN_PDU_FLAG_L) {
3231     /* length bit is set: there are three length bytes */
3232     offset += 3;
3233   } else {
3234     /* length bit is clear: there are two length bytes */
3235     offset += 2;
3236   }
3237 
3238   protocol_id = tvb_get_ntohl(tvb, offset);
3239   if ((protocol_id == ACN_PROTOCOL_ID_BROKER) ||
3240       (protocol_id == ACN_PROTOCOL_ID_RPT) ||
3241       (protocol_id == ACN_PROTOCOL_ID_EPT)) {
3242     return TRUE;
3243   }
3244 
3245   return FALSE;
3246 }
3247 
3248 /******************************************************************************/
3249 /* Test to see if it is an ACN Packet                                         */
3250 static gboolean
is_acn(tvbuff_t * tvb)3251 is_acn(tvbuff_t *tvb)
3252 {
3253   guint32  protocol_id;
3254 
3255   if (is_acn_or_rdmnet_over_udp(tvb, &protocol_id)) {
3256     if ((protocol_id == ACN_PROTOCOL_ID_DMX) ||
3257         (protocol_id == ACN_PROTOCOL_ID_DMX_2) ||
3258         (protocol_id == ACN_PROTOCOL_ID_DMX_3) ||
3259         (protocol_id == ACN_PROTOCOL_ID_SDT))
3260       return TRUE;
3261   }
3262 
3263   return FALSE;
3264 }
3265 
3266 /******************************************************************************/
3267 /* Test to see if it is an ACN Packet                                         */
3268 static gboolean
is_rdmnet_over_udp(tvbuff_t * tvb)3269 is_rdmnet_over_udp(tvbuff_t *tvb)
3270 {
3271   guint32  protocol_id;
3272 
3273   if (is_acn_or_rdmnet_over_udp(tvb, &protocol_id) && (protocol_id == ACN_PROTOCOL_ID_LLRP)) {
3274       return TRUE;
3275   }
3276 
3277   return FALSE;
3278 }
3279 
3280 
3281 /******************************************************************************/
3282 /* Heuristic dissector                                                        */
3283 static gboolean
dissect_acn_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3284 dissect_acn_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3285 {
3286   /* This is a heuristic dissector, which means we get all the UDP
3287    * traffic not sent to a known dissector and not claimed by
3288    * a heuristic dissector called before us!
3289    */
3290 
3291   if (is_acn(tvb)) {
3292     dissect_acn(tvb, pinfo, tree);
3293     return TRUE;
3294   }
3295 
3296   if (is_magic(tvb)) {
3297     dissect_magic(tvb, pinfo, tree);
3298     return TRUE;
3299   }
3300 
3301   /* abort if it is NOT an ACN or Magic Bullet packet */
3302   return FALSE;
3303 }
3304 
3305 
3306 /******************************************************************************/
3307 /* Heuristic dissector                                                        */
3308 static gboolean
dissect_rdmnet_over_udp_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3309 dissect_rdmnet_over_udp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3310 {
3311   if (!is_rdmnet_over_udp(tvb)) {
3312     return FALSE;
3313   }
3314 
3315   dissect_rdmnet(tvb, pinfo, tree, 0, 1);
3316   return TRUE;
3317 }
3318 
3319 #define RDMNET_TCP_FRAME_HEADER_LENGTH  16
3320 
3321 static int
dissect_one_rdmnet_over_tcp_message(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3322 dissect_one_rdmnet_over_tcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3323 {
3324   if (!is_rdmnet_over_tcp(tvb)) {
3325     return 0;
3326   }
3327 
3328   dissect_rdmnet(tvb, pinfo, tree, 0, 0);
3329   return tvb_captured_length(tvb);
3330 }
3331 
3332 
3333 static guint
get_rdmnet_tcp_message_length(packet_info * pinfo _U_,tvbuff_t * tvb,int offset,void * data _U_)3334 get_rdmnet_tcp_message_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
3335 {
3336   return (guint)tvb_get_ntohl(tvb, offset + 12) + 16;
3337 }
3338 
3339 static int
dissect_rdmnet_over_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3340 dissect_rdmnet_over_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3341 {
3342   tcp_dissect_pdus(tvb, pinfo, tree, TRUE, RDMNET_TCP_FRAME_HEADER_LENGTH,
3343                    get_rdmnet_tcp_message_length, dissect_one_rdmnet_over_tcp_message, data);
3344   return tvb_captured_length(tvb);
3345 }
3346 
3347 
3348 /******************************************************************************/
3349 /* Heuristic dissector                                                        */
3350 static gboolean
dissect_rdmnet_over_tcp_heur(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3351 dissect_rdmnet_over_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3352 {
3353   dissect_rdmnet_over_tcp(tvb, pinfo, tree, data);
3354   return TRUE;
3355 }
3356 
3357 
3358 /******************************************************************************/
3359 /*  Adds tree branch for channel owner info block                             */
3360 static guint32
acn_add_channel_owner_info_block(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset)3361 acn_add_channel_owner_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
3362 {
3363   proto_item *pi;
3364   proto_tree *this_tree;
3365   guint32     session_count;
3366   guint32     x;
3367 
3368   this_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_acn_channel_owner_info_block, NULL,
3369                                     "Channel Owner Info Block");
3370 
3371   proto_tree_add_item(this_tree, hf_acn_member_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3372   offset += 2;
3373   proto_tree_add_item(this_tree, hf_acn_channel_number, tvb, offset, 2, ENC_BIG_ENDIAN);
3374   offset += 2;
3375   offset = acn_add_address(tvb, pinfo, this_tree, offset, "Destination Address:");
3376   offset = acn_add_address(tvb, pinfo, this_tree, offset, "Source Address:");
3377 
3378   session_count = tvb_get_ntohs(tvb, offset);
3379   for (x=0; x<session_count; x++) {
3380     pi = proto_tree_add_item(this_tree, hf_acn_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3381     proto_item_append_text(pi, " #%d",  x+1);
3382     offset += 4;
3383   }
3384   return offset;
3385 }
3386 
3387 /******************************************************************************/
3388 /*  Adds tree branch for channel member info block                            */
3389 static guint32
acn_add_channel_member_info_block(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset)3390 acn_add_channel_member_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
3391 {
3392   proto_item *pi;
3393   proto_tree *this_tree;
3394   guint32     session_count;
3395   guint32     x;
3396 
3397   this_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_acn_channel_member_info_block,
3398                                 NULL, "Channel Member Info Block");
3399 
3400   proto_tree_add_item(this_tree, hf_acn_member_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3401   offset += 2;
3402   proto_tree_add_item(this_tree, hf_acn_cid, tvb, offset, 16, ENC_BIG_ENDIAN);
3403   offset += 16;
3404   proto_tree_add_item(this_tree, hf_acn_channel_number, tvb, offset, 2, ENC_BIG_ENDIAN);
3405   offset += 2;
3406   offset = acn_add_address(tvb, pinfo, this_tree, offset, "Destination Address:");
3407   offset = acn_add_address(tvb, pinfo, this_tree, offset, "Source Address:");
3408   proto_tree_add_item(this_tree, hf_acn_reciprocal_channel, tvb, offset, 2, ENC_BIG_ENDIAN);
3409   offset += 2;
3410 
3411   session_count = tvb_get_ntohs(tvb, offset);
3412   for (x=0; x<session_count; x++) {
3413     pi = proto_tree_add_item(this_tree, hf_acn_protocol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
3414     proto_item_append_text(pi, " #%d",  x+1);
3415     offset += 4;
3416   }
3417   return offset;
3418 }
3419 
3420 
3421 /******************************************************************************/
3422 /* Add labeled expiry                                                         */
3423 static guint32
acn_add_expiry(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,int hf)3424 acn_add_expiry(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int hf)
3425 {
3426   proto_tree_add_item(tree, hf, tvb, offset, 1, ENC_NA);
3427   offset += 1;
3428   return offset;
3429 }
3430 
3431 
3432 /******************************************************************************/
3433 /*  Adds tree branch for channel parameters                                   */
3434 static guint32
acn_add_channel_parameter(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)3435 acn_add_channel_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
3436 {
3437   proto_tree *param_tree;
3438 
3439   param_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_acn_channel_parameter,
3440                             NULL, "Channel Parameter Block");
3441   proto_tree_add_item(param_tree, hf_acn_expiry, tvb, offset, 1, ENC_BIG_ENDIAN);
3442   offset += 1;
3443   proto_tree_add_item(param_tree, hf_acn_nak_outbound_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
3444   offset += 1;
3445   proto_tree_add_item(param_tree, hf_acn_nak_holdoff, tvb, offset, 2, ENC_BIG_ENDIAN);
3446   offset += 2;
3447   proto_tree_add_item(param_tree, hf_acn_nak_modulus, tvb, offset, 2, ENC_BIG_ENDIAN);
3448   offset += 2;
3449   proto_tree_add_item(param_tree, hf_acn_nak_max_wait, tvb, offset, 2, ENC_BIG_ENDIAN);
3450   offset += 2;
3451   return offset; /* bytes used */
3452 }
3453 
3454 
3455 /******************************************************************************/
3456 /* Add an address tree                                                        */
3457 static guint32
acn_add_address(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,const char * label)3458 acn_add_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, const char *label)
3459 {
3460   proto_item *pi;
3461   proto_tree *addr_tree = NULL;
3462   guint8      ip_address_type;
3463   guint32     port;
3464 
3465   /* Get type */
3466   ip_address_type = tvb_get_guint8(tvb, offset);
3467 
3468   switch (ip_address_type) {
3469     case ACN_ADDR_NULL:
3470       proto_tree_add_item(tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3471       offset    += 1;
3472       break;
3473     case ACN_ADDR_IPV4:
3474       /* Build tree and add type*/
3475       addr_tree = proto_tree_add_subtree(tree, tvb, offset, 7, ett_acn_address, &pi, label);
3476       proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3477       offset    += 1;
3478       /* Add port */
3479       port       = tvb_get_ntohs(tvb, offset);
3480       proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
3481       offset    += 2;
3482       /* Add Address */
3483       proto_tree_add_item(addr_tree, hf_acn_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
3484       /* Append port and address to tree item */
3485       proto_item_append_text(pi, " %s, Port %d", tvb_address_to_str(pinfo->pool, tvb, AT_IPv4, offset), port);
3486       offset    += 4;
3487       break;
3488     case ACN_ADDR_IPV6:
3489       /* Build tree and add type*/
3490       addr_tree = proto_tree_add_subtree(tree, tvb, offset, 19, ett_acn_address, &pi, label);
3491       proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3492       offset    += 1;
3493       /* Add port */
3494       port       = tvb_get_ntohs(tvb, offset);
3495       proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
3496       offset    += 2;
3497       /* Add Address */
3498       proto_tree_add_item(addr_tree, hf_acn_ipv6, tvb, offset, 16, ENC_NA);
3499       /* Append port and address to tree item */
3500       proto_item_append_text(pi, " %s, Port %d", tvb_address_to_str(pinfo->pool, tvb, AT_IPv6, offset), port);
3501       offset    += 16;
3502       break;
3503     case ACN_ADDR_IPPORT:
3504       /* Build tree and add type*/
3505       addr_tree = proto_tree_add_subtree(tree, tvb, offset, 3, ett_acn_address, &pi, label);
3506       proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3507       offset    += 1;
3508       /* Add port */
3509       port       = tvb_get_ntohs(tvb, offset);
3510       proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, ENC_BIG_ENDIAN);
3511       /* Append port to tree item */
3512       proto_item_append_text(pi, " Port %d", port);
3513       offset    += 2;
3514       break;
3515   }
3516   return offset;
3517 }
3518 
3519 /******************************************************************************/
3520 /*  Adds tree branch for address type                             */
3521 static guint32
acn_add_dmp_address_type(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,acn_dmp_adt_type * adt)3522 acn_add_dmp_address_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
3523 {
3524   proto_tree  *this_tree;
3525   guint8       D;
3526   const gchar *name;
3527 
3528   /* header contains address and data type */
3529   adt->flags = tvb_get_guint8(tvb, offset);
3530 
3531   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
3532   name = val_to_str(D, acn_dmp_adt_d_vals, "not valid (%d)");
3533   this_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1, ett_acn_address_type,
3534                                 NULL, "Address and Data Type: %s", name);
3535 
3536   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_v, tvb, offset, 1, adt->flags);
3537   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_r, tvb, offset, 1, adt->flags);
3538   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_d, tvb, offset, 1, adt->flags);
3539   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_x, tvb, offset, 1, adt->flags);
3540   proto_tree_add_uint(this_tree, hf_acn_dmp_adt_a, tvb, offset, 1, adt->flags);
3541   offset += 1;
3542 
3543   return offset; /* bytes used */
3544 }
3545 
3546 /******************************************************************************/
3547 /* Add an dmp address                                                         */
3548 static guint32
acn_add_dmp_address(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,acn_dmp_adt_type * adt)3549 acn_add_dmp_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
3550 {
3551   gint32 start_offset;
3552   gint32 bytes_used;
3553   guint8 D, A;
3554 
3555   start_offset = offset;
3556 
3557   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
3558   A = ACN_DMP_ADT_EXTRACT_A(adt->flags);
3559 
3560   switch (D) {
3561     case ACN_DMP_ADT_D_NS:      /* Non-range address, Single data item */
3562       adt->increment    = 1;
3563       adt->count        = 1;
3564       switch (A) {              /* address */
3565         case ACN_DMP_ADT_A_1:   /* One octet address, (range: one octet address, increment, and count). */
3566           adt->address  = tvb_get_guint8(tvb, offset);
3567           offset       += 1;
3568           bytes_used    = 1;
3569           break;
3570         case ACN_DMP_ADT_A_2:   /* Two octet address, (range: two octet address, increment, and count). */
3571           adt->address  = tvb_get_ntohs(tvb, offset);
3572           offset       += 2;
3573           bytes_used    = 2;
3574           break;
3575         case ACN_DMP_ADT_A_4:   /* Four octet address, (range: one octet address, increment, and count). */
3576           adt->address  = tvb_get_ntohl(tvb, offset);
3577           offset       += 4;
3578           bytes_used    = 4;
3579           break;
3580         default:                /* and ACN_DMP_ADT_A_R (Four octet address, (range: four octet address, increment, and count)*/
3581           return offset;
3582       }                         /* of switch (A)  */
3583 
3584       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
3585         proto_tree_add_uint(tree, hf_acn_dmp_virtual_address, tvb, start_offset, bytes_used, adt->address);
3586       } else {
3587         proto_tree_add_uint(tree, hf_acn_dmp_actual_address, tvb, start_offset, bytes_used, adt->address);
3588       }
3589       break;
3590 
3591     case ACN_DMP_ADT_D_RS:      /* Range address, Single data item */
3592       switch (A) {
3593         case ACN_DMP_ADT_A_1:   /* One octet address, (range: one octet address, increment, and count). */
3594           adt->address    = tvb_get_guint8(tvb, offset);
3595           offset         += 1;
3596           adt->increment  = tvb_get_guint8(tvb, offset);
3597           offset         += 1;
3598           adt->count      = tvb_get_guint8(tvb, offset);
3599           offset         += 1;
3600           bytes_used      = 3;
3601           break;
3602         case ACN_DMP_ADT_A_2:   /* Two octet address, (range: two octet address, increment, and count). */
3603           adt->address    = tvb_get_ntohs(tvb, offset);
3604           offset         += 2;
3605           adt->increment  = tvb_get_ntohs(tvb, offset);
3606           offset         += 2;
3607           adt->count      = tvb_get_ntohs(tvb, offset);
3608           offset         += 2;
3609           bytes_used      = 6;
3610           break;
3611         case ACN_DMP_ADT_A_4:   /* Four octet address, (range: four octet address, increment, and count). */
3612           adt->address    = tvb_get_ntohl(tvb, offset);
3613           offset         += 4;
3614           adt->increment  = tvb_get_ntohl(tvb, offset);
3615           offset         += 4;
3616           adt->count      = tvb_get_ntohl(tvb, offset);
3617           offset         += 4;
3618           bytes_used      = 12;
3619           break;
3620         default:                /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3621           return offset;
3622       }                         /* of switch (A)  */
3623 
3624       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
3625         proto_tree_add_uint_format_value(tree, hf_acn_dmp_virtual_address_first, tvb, start_offset, bytes_used,
3626                             adt->address, "0x%X, inc: %d, count: %d",
3627                             adt->address, adt->increment, adt->count);
3628       } else {
3629         proto_tree_add_uint_format_value(tree, hf_acn_dmp_actual_address_first, tvb, start_offset, bytes_used,
3630                             adt->address, "0x%X, inc: %d, count: %d",
3631                             adt->address, adt->increment, adt->count);
3632       }
3633       break;
3634 
3635     case ACN_DMP_ADT_D_RE:      /* Range address, Array of equal size data items */
3636       switch (A) {
3637         case ACN_DMP_ADT_A_1:   /* One octet address, (range: one octet address, increment, and count). */
3638           adt->address    = tvb_get_guint8(tvb, offset);
3639           offset         += 1;
3640           adt->increment  = tvb_get_guint8(tvb, offset);
3641           offset         += 1;
3642           adt->count      = tvb_get_guint8(tvb, offset);
3643           offset         += 1;
3644           bytes_used      = 3;
3645           break;
3646         case ACN_DMP_ADT_A_2:   /* Two octet address, (range: two octet address, increment, and count). */
3647           adt->address    = tvb_get_ntohs(tvb, offset);
3648           offset         += 2;
3649           adt->increment  = tvb_get_ntohs(tvb, offset);
3650           offset         += 2;
3651           adt->count      = tvb_get_ntohs(tvb, offset);
3652           offset         += 2;
3653           bytes_used      = 6;
3654           break;
3655         case ACN_DMP_ADT_A_4:   /* Four octet address, (range: four octet address, increment, and count). */
3656           adt->address    = tvb_get_ntohl(tvb, offset);
3657           offset         += 4;
3658           adt->increment  = tvb_get_ntohl(tvb, offset);
3659           offset         += 4;
3660           adt->count      = tvb_get_ntohl(tvb, offset);
3661           offset         += 4;
3662           bytes_used      = 12;
3663           break;
3664         default:                /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3665           return offset;
3666       }                         /* of switch (A)  */
3667 
3668       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
3669         proto_tree_add_uint_format_value(tree, hf_acn_dmp_virtual_address_first, tvb, start_offset, bytes_used,
3670                             adt->address, "0x%X, inc: %d, count: %d",
3671                             adt->address, adt->increment, adt->count);
3672       } else {
3673         proto_tree_add_uint_format_value(tree, hf_acn_dmp_actual_address_first, tvb, start_offset, bytes_used,
3674                             adt->address, "0x%X, inc: %d, count: %d",
3675                             adt->address, adt->increment, adt->count);
3676       }
3677       break;
3678 
3679     case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
3680       switch (A) {
3681         case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3682           adt->address =   tvb_get_guint8(tvb, offset);
3683           offset += 1;
3684           adt->increment =   tvb_get_guint8(tvb, offset);
3685           offset += 1;
3686           adt->count =   tvb_get_guint8(tvb, offset);
3687           offset += 1;
3688           bytes_used = 3;
3689           break;
3690         case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3691           adt->address =   tvb_get_ntohs(tvb, offset);
3692           offset += 2;
3693           adt->increment =   tvb_get_ntohs(tvb, offset);
3694           offset += 2;
3695           adt->count =   tvb_get_ntohs(tvb, offset);
3696           offset += 2;
3697           bytes_used = 6;
3698           break;
3699         case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3700           adt->address =   tvb_get_ntohl(tvb, offset);
3701           offset += 4;
3702           adt->increment =   tvb_get_ntohl(tvb, offset);
3703           offset += 4;
3704           adt->count =   tvb_get_ntohl(tvb, offset);
3705           offset += 4;
3706           bytes_used = 12;
3707           break;
3708         default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3709           return offset;
3710       } /* of switch (A)  */
3711 
3712       if (adt->flags & ACN_DMP_ADT_FLAG_V) {
3713         proto_tree_add_uint_format_value(tree, hf_acn_dmp_virtual_address_first, tvb, start_offset, bytes_used,
3714                             adt->address, "0x%X, inc: %d, count: %d",
3715                             adt->address, adt->increment, adt->count);
3716       } else {
3717         proto_tree_add_uint_format_value(tree, hf_acn_dmp_actual_address_first, tvb, start_offset, bytes_used,
3718                             adt->address, "0x%X, inc: %d, count: %d",
3719                             adt->address, adt->increment, adt->count);
3720       }
3721       break;
3722   } /* of switch (D) */
3723 
3724   return offset;
3725 }
3726 
3727 
3728 /*******************************************************************************/
3729 /* Display DMP Data                                                            */
3730 static guint32
acn_add_dmp_data(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,acn_dmp_adt_type * adt)3731 acn_add_dmp_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
3732 {
3733   guint8      D, A;
3734   guint32     data_size;
3735   guint32     data_value;
3736   guint32     data_address;
3737   guint32     x,y;
3738   gchar      *buffer;
3739   wmem_strbuf_t *default_buffer;
3740   proto_item *ti;
3741   guint32     ok_to_process = FALSE;
3742 
3743   /* We would like to rip through Property Address-Data pairs                 */
3744   /* but since we don't now how many there are nor how big the data size is,  */
3745   /* it not possible. So, we just show the whole thing as a block of date!    */
3746   /*                                                                          */
3747   /* There are a few exceptions however                                       */
3748   /* 1) if the address type is ACN_DMP_ADT_D_NS or ACN_DMP_ADT_D_RS and       */
3749   /*    or ACN_DMP_ADT_D_RE                                                   */
3750   /*    then number of bytes is <= count + 4. Each value is at least one byte */
3751   /*    and another address/data pair is at least 4 bytes so if the remaining */
3752   /*    bytes is less than the count plus 4 then the remaining data           */
3753   /*    must be all data                                                      */
3754   /*                                                                          */
3755   /* 2) if the address type is ACN_DMP_ADT_D_RE and the number of bytes       */
3756   /*    equals the number of bytes in remaining in the pdu then there is      */
3757   /*    a 1 to one match                                                      */
3758 
3759   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
3760   switch (D) {
3761     case ACN_DMP_ADT_D_NS:
3762     case ACN_DMP_ADT_D_RS:
3763       if (adt->data_length <= adt->count + 4) {
3764         ok_to_process = TRUE;
3765       }
3766       break;
3767     case ACN_DMP_ADT_D_RE:
3768       if (adt->count == 0) {
3769         break;
3770       }
3771       if (adt->data_length <= adt->count + 4) {
3772         ok_to_process = TRUE;
3773       }
3774       break;
3775   }
3776 
3777   if (!ok_to_process) {
3778     data_size  = adt->data_length;
3779     ti         = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3780     offset    += data_size;
3781     proto_item_set_text(ti, "Data and more Address-Data Pairs (further dissection not possible)");
3782     return offset;
3783   }
3784 
3785   A = ACN_DMP_ADT_EXTRACT_A(adt->flags);
3786 
3787   switch (D) {
3788     case ACN_DMP_ADT_D_NS:      /* Non-range address, Single data item */
3789       /* calculate data size */
3790       data_size    = adt->data_length;
3791       data_address = adt->address;
3792 
3793       switch (A) {
3794         case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3795           buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%2.2X ->", data_address);
3796           break;
3797         case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3798           buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%4.4X ->", data_address);
3799           break;
3800         case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3801           buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%8.8X ->", data_address);
3802           break;
3803         default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3804           offset += data_size;
3805           return offset;
3806       }
3807 
3808       switch (data_size) {
3809         case 1:
3810           data_value = tvb_get_guint8(tvb, offset);
3811           proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
3812           break;
3813         case 2:
3814           data_value = tvb_get_ntohs(tvb, offset);
3815           proto_tree_add_uint_format(tree, hf_acn_data16, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
3816           break;
3817         case 3:
3818           data_value = tvb_get_ntoh24(tvb, offset);
3819           proto_tree_add_uint_format(tree, hf_acn_data24, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
3820           break;
3821         case 4:
3822           data_value = tvb_get_ntohl(tvb, offset);
3823           proto_tree_add_uint_format(tree, hf_acn_data32, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
3824           break;
3825         default:
3826           default_buffer = wmem_strbuf_new(pinfo->pool, "");
3827           /* build string of values */
3828           for (y=0; y<20 && y<data_size; y++) {
3829             data_value = tvb_get_guint8(tvb, offset+y);
3830             wmem_strbuf_append_printf(default_buffer, " %2.2X", data_value);
3831           }
3832           /* add the item */
3833           ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3834           offset += data_size;
3835           /* change the text */
3836           proto_item_set_text(ti, "%s", wmem_strbuf_get_str(default_buffer));
3837           break;
3838       } /* of switch (data_size) */
3839       offset += data_size;
3840       break;
3841 
3842     case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
3843       /* calculate data size */
3844       data_size = adt->data_length;
3845       data_address = adt->address;
3846 
3847       for (x=0; x<adt->count; x++) {
3848         switch (A) {
3849           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3850             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%2.2X ->", data_address);
3851             break;
3852           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3853             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%4.4X ->", data_address);
3854             break;
3855           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3856             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%8.8X ->", data_address);
3857             break;
3858           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3859             return offset;
3860         }
3861 
3862         switch (data_size) {
3863           case 1:
3864             data_value = tvb_get_guint8(tvb, offset);
3865             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
3866             break;
3867           case 2:
3868             data_value = tvb_get_ntohs(tvb, offset);
3869             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
3870             break;
3871           case 3:
3872             data_value = tvb_get_ntoh24(tvb, offset);
3873             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
3874             break;
3875           case 4:
3876             data_value = tvb_get_ntohl(tvb, offset);
3877             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
3878             break;
3879           default:
3880             /* build string of values */
3881             default_buffer = wmem_strbuf_new(pinfo->pool, "");
3882             for (y=0; y<20 && y<data_size; y++) {
3883               data_value = tvb_get_guint8(tvb, offset+y);
3884               wmem_strbuf_append_printf(default_buffer, " %2.2X", data_value);
3885             }
3886             /* add the item */
3887             ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3888             /* change the text */
3889             proto_item_set_text(ti, "%s", wmem_strbuf_get_str(default_buffer));
3890             break;
3891         } /* of switch (data_size) */
3892         data_address += adt->increment;
3893       } /* of (x=0;x<adt->count;x++) */
3894       offset += data_size;
3895       break;
3896 
3897     case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
3898       /* calculate data size */
3899       data_size = adt->data_length / adt->count;
3900       data_address = adt->address;
3901 
3902       for (x=0; x<adt->count; x++) {
3903         switch (A) {
3904           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3905             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%2.2X ->", data_address);
3906             break;
3907           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3908             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%4.4X ->", data_address);
3909             break;
3910           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3911             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%8.8X ->", data_address);
3912             break;
3913           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3914             return offset;
3915         }
3916 
3917         switch (data_size) {
3918           case 1:
3919             data_value = tvb_get_guint8(tvb, offset);
3920             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
3921             break;
3922           case 2:
3923             data_value = tvb_get_ntohs(tvb, offset);
3924             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
3925             break;
3926           case 3:
3927             data_value = tvb_get_ntoh24(tvb, offset);
3928             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
3929             break;
3930           case 4:
3931             data_value = tvb_get_ntohl(tvb, offset);
3932             proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
3933             break;
3934           default:
3935             /* build string of values */
3936             default_buffer = wmem_strbuf_new(pinfo->pool, "");
3937             for (y=0; y<20 && y<data_size; y++) {
3938               data_value = tvb_get_guint8(tvb, offset+y);
3939               wmem_strbuf_append_printf(default_buffer, " %2.2X", data_value);
3940             }
3941             /* add the item */
3942             ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3943             /* change the text */
3944             proto_item_set_text(ti, "%s", wmem_strbuf_get_str(default_buffer));
3945             break;
3946         } /* of switch (data_size) */
3947 
3948         offset += data_size;
3949         data_address += adt->increment;
3950       } /* of (x=0;x<adt->count;x++) */
3951       break;
3952 
3953     case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
3954       data_size = adt->data_length;
3955       ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, ENC_NA);
3956       offset += data_size;
3957       /* change the text */
3958       proto_item_set_text(ti, "Mixed size data items");
3959       break;
3960   } /* of switch (D) */
3961   return offset;
3962 }
3963 
3964 /*******************************************************************************/
3965 /* Display DMP Reason codes                                                    */
3966 static guint32
acn_add_dmp_reason_codes(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset,acn_dmp_adt_type * adt)3967 acn_add_dmp_reason_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
3968 {
3969   guint8       D, A;
3970   guint32      data_value;
3971   guint32      data_address;
3972   guint32      x;
3973 
3974   gchar       *buffer;
3975   const gchar *name;
3976 
3977   D = ACN_DMP_ADT_EXTRACT_D(adt->flags);
3978   A = ACN_DMP_ADT_EXTRACT_A(adt->flags);
3979   switch (D) {
3980     case ACN_DMP_ADT_D_NS: /* Non-range address, Single data item */
3981       data_address = adt->address;
3982       switch (A) {
3983         case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
3984           buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%2.2X ->", data_address);
3985           break;
3986         case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
3987           buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%4.4X ->", data_address);
3988           break;
3989         case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
3990           buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%8.8X ->", data_address);
3991           break;
3992         default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
3993           return offset;
3994       }
3995 
3996       /* Get reason */
3997       data_value  = tvb_get_guint8(tvb, offset);
3998       name        = val_to_str(data_value, acn_dmp_reason_code_vals, "reason not valid (%d)");
3999       proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, name);
4000       offset     += 1;
4001       break;
4002 
4003     case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
4004       data_address = adt->address;
4005       for (x=0; x<adt->count; x++) {
4006         switch (A) {
4007           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
4008             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%2.2X ->", data_address);
4009             break;
4010           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
4011             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%4.4X ->", data_address);
4012             break;
4013           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
4014             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%8.8X ->", data_address);
4015             break;
4016           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
4017             return offset;
4018         }
4019 
4020         /* Get reason */
4021         data_value = tvb_get_guint8(tvb, offset);
4022         name       = val_to_str(data_value, acn_dmp_reason_code_vals, "reason not valid (%d)");
4023         proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, name);
4024 
4025         data_address += adt->increment;
4026       } /* of (x=0;x<adt->count;x++) */
4027       offset += 1;
4028       break;
4029 
4030     case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
4031     case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
4032       data_address = adt->address;
4033       for (x=0; x<adt->count; x++) {
4034         switch (A) {
4035           case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
4036             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%2.2X ->", data_address);
4037             break;
4038           case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
4039             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%4.4X ->", data_address);
4040             break;
4041           case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
4042             buffer = wmem_strdup_printf(pinfo->pool, "Addr 0x%8.8X ->", data_address);
4043             break;
4044           default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
4045             return offset;
4046         }
4047         /* Get reason */
4048         data_value    = tvb_get_guint8(tvb, offset);
4049         name          = val_to_str(data_value, acn_dmp_reason_code_vals, "reason not valid (%d)");
4050         proto_tree_add_uint_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, name);
4051         data_address += adt->increment;
4052         offset       += 1;
4053       } /* of (x=0;x<adt->count;x++) */
4054       break;
4055   } /* of switch (D) */
4056   return offset;
4057 }
4058 
4059 /******************************************************************************/
4060 /* Get Field Type Parameters */
4061 static void
get_field_type_parameters(tvbuff_t * tvb,int blob_offset,guint8 field_type,guint8 * field_length,guint8 * blob_offset1,guint8 * blob_offset2,guint8 * blob_offset3)4062 get_field_type_parameters(tvbuff_t *tvb, int blob_offset, guint8 field_type, guint8 *field_length, guint8 *blob_offset1, guint8 *blob_offset2, guint8 *blob_offset3)
4063 {
4064   /* Switch Over Field Type to Determine Data */
4065   switch (field_type) {
4066     case ACN_BLOB_FIELD_TYPE1:
4067     case ACN_BLOB_FIELD_TYPE5:
4068       /* Set field length and blob_offsets to use */
4069       *field_length = 1;
4070       *blob_offset1 = 0;
4071       *blob_offset2 = 1;
4072       *blob_offset3 = *field_length;
4073       break;
4074     case ACN_BLOB_FIELD_TYPE2:
4075     case ACN_BLOB_FIELD_TYPE6:
4076       /* Set field length and blob_offsets to use */
4077       *field_length = 2;
4078       *blob_offset1 = 0;
4079       *blob_offset2 = 1;
4080       *blob_offset3 = *field_length;
4081       break;
4082     case ACN_BLOB_FIELD_TYPE3:
4083     case ACN_BLOB_FIELD_TYPE7:
4084       /* Set field length and blob_offsets to use */
4085       *field_length = 4;
4086       *blob_offset1 = 0;
4087       *blob_offset2 = 1;
4088       *blob_offset3 = *field_length;
4089       break;
4090     case ACN_BLOB_FIELD_TYPE4:
4091     case ACN_BLOB_FIELD_TYPE8:
4092       /* Set field length and blob_offsets to use */
4093       *field_length = 8;
4094       *blob_offset1 = 0;
4095       *blob_offset2 = 1;
4096       *blob_offset3 = *field_length;
4097       break;
4098     case ACN_BLOB_FIELD_TYPE9:
4099       /* float */
4100       /* Set field length and blob_offsets to use */
4101       *field_length = 4;
4102       *blob_offset1 = 0;
4103       *blob_offset2 = 1;
4104       *blob_offset3 = *field_length;
4105       break;
4106     case ACN_BLOB_FIELD_TYPE10:
4107       /* double */
4108       /* Set field length and blob_offsets to use */
4109       *field_length = 8;
4110       *blob_offset1 = 0;
4111       *blob_offset2 = 1;
4112       *blob_offset3 = *field_length;
4113       break;
4114     case ACN_BLOB_FIELD_TYPE11:
4115       /* Set field length and blob_offsets to use */
4116       *field_length = tvb_get_guint8(tvb, blob_offset + 2);
4117       *blob_offset1 = 2;
4118       *blob_offset2 = 1;
4119       *blob_offset3 = (*field_length) - 2;
4120       break;
4121     case ACN_BLOB_FIELD_TYPE12:
4122       /* Set field length and blob_offsets to use for ignores */
4123       *field_length = 0;
4124       *blob_offset1 = 0;
4125       *blob_offset2 = 0;
4126       *blob_offset3 = 1;
4127       break;
4128     default:
4129       /* Set field length and blob_offsets to use for unknowns */
4130       *field_length = 0;
4131       *blob_offset1 = 0;
4132       *blob_offset2 = 0;
4133       *blob_offset3 = 1;
4134   }
4135 }
4136 
4137 /******************************************************************************/
4138 /* Get Field Name */
4139 static const gchar *
get_field_name(guint8 blob_type,guint16 field_number)4140 get_field_name(guint8 blob_type, guint16 field_number)
4141 {
4142   guint16 temp_field_number;
4143   const gchar *field_name;
4144 
4145   /*Find the field sub tree name depending on the blob type.*/
4146   switch (blob_type) {
4147     case ACN_BLOB_IPV4:
4148     case ACN_BLOB_IPV6:
4149       field_name = val_to_str(field_number, acn_blob_ip_field_name, "not valid (%d)");
4150       break;
4151     case ACN_BLOB_ERROR1:
4152       field_name = val_to_str(field_number, acn_blob_error1_field_name, "not valid (%d)");
4153       break;
4154     case ACN_BLOB_ERROR2:
4155       field_name = val_to_str(field_number, acn_blob_error2_field_name, "not valid (%d)");
4156       break;
4157     case ACN_BLOB_METADATA:
4158       field_name = val_to_str(field_number, acn_blob_metadata_field_name, "not valid (%d)");
4159       break;
4160     case ACN_BLOB_METADATA_DEVICES:
4161       field_name = val_to_str(field_number, acn_blob_metadata_devices_field_name, "not valid (%d)");
4162       break;
4163     case ACN_BLOB_METADATA_TYPES:
4164       field_name = val_to_str(field_number, acn_blob_metadata_types_field_name, "not valid (%d)");
4165       break;
4166     case ACN_BLOB_TIME1:
4167       field_name = val_to_str(field_number, acn_blob_time1_field_name, "not valid (%d)");
4168       break;
4169     case ACN_BLOB_DIMMER_PROPERTIES:
4170       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_properties1_field_name_ext, "not valid (%d)");
4171       break;
4172     case ACN_BLOB_DIMMER_LOAD_PROPERTIES:
4173       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_load_properties1_field_name_ext, "not valid (%d)");
4174       break;
4175     case ACN_BLOB_DIMMING_RACK_PROPERTIES:
4176       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_properties1_field_name_ext, "not valid (%d)");
4177       break;
4178     case ACN_BLOB_DIMMING_RACK_STATUS_PROPERTIES:
4179       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_status_properties1_field_name_ext, "not valid (%d)");
4180       break;
4181     case ACN_BLOB_DIMMER_STATUS_PROPERTIES:
4182       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_status_properties1_field_name_ext, "not valid (%d)");
4183       break;
4184     case ACN_BLOB_SET_LEVELS_OPERATION:
4185       field_name = val_to_str(field_number, acn_blob_set_levels_operation_field_name, "not valid (%d)");
4186       break;
4187     case ACN_BLOB_PRESET_OPERATION:
4188       field_name = val_to_str(field_number, acn_blob_preset_operation_field_name, "not valid (%d)");
4189       break;
4190     case ACN_BLOB_ADVANCED_FEATURES_OPERATION:
4191       field_name = val_to_str(field_number, acn_blob_advanced_features_operation_field_name, "not valid (%d)");
4192       break;
4193     case ACN_BLOB_DIRECT_CONTROL_OPERATION:
4194       field_name = val_to_str(field_number, acn_blob_direct_control_operation_field_name, "not valid (%d)");
4195       break;
4196     case ACN_BLOB_GENERATE_CONFIG_OPERATION:
4197       field_name = val_to_str(field_number, acn_blob_generate_config_operation_field_name, "not valid (%d)");
4198       break;
4199     case ACN_BLOB_ERROR3:
4200       field_name = val_to_str(field_number, acn_blob_error3_field_name, "not valid (%d)");
4201       break;
4202     case ACN_BLOB_DIMMER_PROPERTIES2:
4203       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_properties2_field_name_ext, "not valid (%d)");
4204       break;
4205     case ACN_BLOB_DIMMER_LOAD_PROPERTIES2:
4206       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_load_properties2_field_name_ext, "not valid (%d)");
4207       break;
4208     case ACN_BLOB_DIMMER_RACK_PROPERTIES2:
4209       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_properties2_field_name_ext, "not valid (%d)");
4210       break;
4211     case ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2:
4212       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_rack_status_properties2_field_name_ext, "not valid (%d)");
4213       break;
4214     case ACN_BLOB_DIMMER_STATUS_PROPERTIES2:
4215       field_name = val_to_str_ext(field_number, &acn_blob_dimmer_status_properties2_field_name_ext, "not valid (%d)");
4216       break;
4217     case ACN_BLOB_TIME2:
4218       field_name = val_to_str(field_number, acn_blob_time2_field_name, "not valid (%d)");
4219       break;
4220     case ACN_BLOB_RPC:
4221       {
4222         temp_field_number = field_number;
4223         /* field names 4 repeats: 1, 2, 3, 4, 4, 4, ... */
4224         if (temp_field_number > 3)
4225           temp_field_number = 4;
4226         field_name = val_to_str(temp_field_number, acn_blob_rpc_field_name, "not valid (%d)");
4227       }
4228       break;
4229     case ACN_BLOB_DHCP_CONFIG_SUBNET:
4230       field_name = val_to_str(field_number, acn_blob_dhcp_config_subnet_field_name, "not valid (%d)");
4231       break;
4232     case ACN_BLOB_DHCP_CONFIG_STATIC_ROUTE:
4233       field_name = val_to_str(field_number, acn_blob_dhcp_config_static_route_field_name, "not valid (%d)");
4234       break;
4235     case ACN_BLOB_ENERGY_MANAGEMENT:
4236       {
4237         temp_field_number = field_number;
4238         /* field names 4 through 7 repeat: 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, ... */
4239         if (temp_field_number > 3)
4240           temp_field_number = (field_number % 4) + 4;
4241         field_name = val_to_str(temp_field_number, acn_blob_energy_management_field_name, "not valid (%d)");
4242       }
4243       break;
4244     case ACN_BLOB_PRESET_PROPERTIES:
4245       field_name = val_to_str_ext(field_number, &acn_blob_preset_properties_field_name_ext, "not valid (%d)");
4246       break;
4247     case ACN_BLOB_TIME3:
4248       field_name = val_to_str(field_number, acn_blob_time3_field_name, "not valid (%d)");
4249       break;
4250     case ACN_BLOB_ENERGY_COST:
4251       field_name = val_to_str(field_number, acn_blob_energy_cost_field_name, "not valid (%d)");
4252       break;
4253     case ACN_BLOB_SEQUENCE_OPERATIONS:
4254       field_name = val_to_str(field_number, acn_blob_sequence_operation_field_name, "not valid (%d)");
4255       break;
4256     case ACN_BLOB_SEQUENCE_STEP_PROPERTIES:
4257       field_name = val_to_str_ext(field_number, &acn_blob_sequence_step_properties_field_name_ext, "not valid (%d)");
4258       break;
4259     default:
4260       field_name = "Unknown field";
4261       break;
4262   }
4263 
4264   return field_name;
4265 }
4266 
4267 /******************************************************************************/
4268 /* Display Blob Field Value */
4269 static void
display_blob_field_value(tvbuff_t * tvb,proto_tree * field_tree,guint16 field_number,guint8 blob_type,guint8 field_type,guint8 field_length,int blob_offset,guint8 blob_offset3,int display_variblob_as_CID)4270 display_blob_field_value(tvbuff_t *tvb, proto_tree *field_tree, guint16 field_number, guint8 blob_type, guint8 field_type, guint8 field_length, int blob_offset, guint8 blob_offset3, int display_variblob_as_CID)
4271 {
4272   gint8             field_value8;
4273   gint32            field_value32;
4274   const gchar      *field_string;
4275   proto_item       *ti;
4276 
4277   /* Add field value to field sub tree */
4278   if (field_type == ACN_BLOB_FIELD_TYPE12) {
4279     /* "ignore" always takes priority */
4280     proto_tree_add_string(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, field_length, "Ignore");
4281   }
4282   else if (blob_type == ACN_BLOB_IPV4) {
4283     proto_tree_add_item(field_tree, hf_acn_blob_field_value_ipv4, tvb, blob_offset, field_length-2, ENC_BIG_ENDIAN);
4284   }
4285   else if (blob_type == ACN_BLOB_IPV6) {
4286     proto_tree_add_item(field_tree, hf_acn_blob_field_value_ipv6, tvb, blob_offset, field_length-2, ENC_NA);
4287   }
4288   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 2)) {
4289     /* time zone index */
4290     field_value32 = (gint32)(tvb_get_ntohl(tvb, blob_offset));
4291     if (field_value32 == -1) {
4292       field_string = "Field Value: Custom";
4293     }
4294     else {
4295       field_string = val_to_str(field_value32, acn_blob_time3_time_zone_vals, "not valid (%d)");
4296     }
4297     proto_tree_add_int_format(field_tree, hf_acn_blob_time_zone, tvb, blob_offset, 4, field_value32, "%s", field_string);
4298   }
4299   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 10)) {
4300     /* DST type */
4301     field_value8 = tvb_get_guint8(tvb, blob_offset);
4302     field_string = val_to_str(field_value8, acn_blob_time3_dst_vals, "not valid (%d)");
4303     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
4304   }
4305   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 11)) {
4306     /* DST on month */
4307     field_value8 = tvb_get_guint8(tvb, blob_offset);
4308     field_string = val_to_str(field_value8, acn_blob_time3_month_vals, "not valid (%d)");
4309     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
4310   }
4311   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 12)) {
4312     /* DST on week */
4313     field_value8 = tvb_get_guint8(tvb, blob_offset);
4314     field_string = val_to_str(field_value8, acn_blob_time3_week_vals, "not valid (%d)");
4315     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
4316   }
4317   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 13)) {
4318     /* DST start day */
4319     field_value8 = tvb_get_guint8(tvb, blob_offset);
4320     field_string = val_to_str(field_value8, acn_blob_time3_day_vals, "not valid (%d)");
4321     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_start_day, tvb, blob_offset, 1, field_value8, "%s", field_string);
4322   }
4323   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 16)) {
4324     /* DST start locality */
4325     field_value8 = tvb_get_guint8(tvb, blob_offset);
4326     field_string = val_to_str(field_value8, acn_blob_time3_locality_vals, "not valid (%d)");
4327     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_start_locality, tvb, blob_offset, 1, field_value8, "%s", field_string);
4328   }
4329   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 17)) {
4330     /* DST off month */
4331     field_value8 = tvb_get_guint8(tvb, blob_offset);
4332     field_string = val_to_str(field_value8, acn_blob_time3_month_vals, "not valid (%d)");
4333     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
4334   }
4335   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 18)) {
4336     /* DST off week */
4337     field_value8 = tvb_get_guint8(tvb, blob_offset);
4338     field_string = val_to_str(field_value8, acn_blob_time3_week_vals, "not valid (%d)");
4339     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_type, tvb, blob_offset, 1, field_value8, "%s", field_string);
4340   }
4341   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 19)) {
4342     /* DST stop day */
4343     field_value8 = tvb_get_guint8(tvb, blob_offset);
4344     field_string = val_to_str(field_value8, acn_blob_time3_day_vals, "not valid (%d)");
4345     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_stop_day, tvb, blob_offset, 1, field_value8, "%s", field_string);
4346   }
4347   else if ((blob_type == ACN_BLOB_TIME3) && (field_number == 22)) {
4348     /* DST stop locality */
4349     field_value8 = tvb_get_guint8(tvb, blob_offset);
4350     field_string = val_to_str(field_value8, acn_blob_time3_locality_vals, "not valid (%d)");
4351     proto_tree_add_uint_format(field_tree, hf_acn_blob_dst_stop_locality, tvb, blob_offset, 1, field_value8, "%s", field_string);
4352   }
4353   else {
4354     switch (field_type) {
4355       case ACN_BLOB_FIELD_TYPE1:
4356         /* Need special code to display signed data */
4357         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 1, ENC_BIG_ENDIAN);
4358         proto_item_set_len(ti, blob_offset3);
4359         break;
4360       case ACN_BLOB_FIELD_TYPE2:
4361         /* Need special code to display signed data */
4362         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 2, ENC_BIG_ENDIAN);
4363         proto_item_set_len(ti, blob_offset3);
4364         break;
4365       case ACN_BLOB_FIELD_TYPE3:
4366         /* Need special code to display signed data */
4367         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, 3, ENC_BIG_ENDIAN);
4368         proto_item_set_len(ti, blob_offset3);
4369         break;
4370       case ACN_BLOB_FIELD_TYPE4:
4371         /* Need special code to display signed data */
4372         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number64, tvb, blob_offset, 8, ENC_BIG_ENDIAN);
4373         proto_item_set_len(ti, blob_offset3);
4374         break;
4375       case ACN_BLOB_FIELD_TYPE9:
4376         /* float */
4377         proto_tree_add_item(field_tree, hf_acn_blob_field_value_float, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
4378         break;
4379       case ACN_BLOB_FIELD_TYPE10:
4380         /* double */
4381         proto_tree_add_item(field_tree, hf_acn_blob_field_value_double, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
4382         break;
4383       case ACN_BLOB_FIELD_TYPE11:
4384         if (blob_offset3 == 0) {
4385           proto_tree_add_string(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, 0, "<none>");
4386         }
4387         else if (display_variblob_as_CID) {
4388           proto_tree_add_item(field_tree, hf_acn_blob_field_value_guid, tvb, blob_offset, field_length, ENC_BIG_ENDIAN);
4389         }
4390         else {
4391           proto_tree_add_item(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, blob_offset3, ENC_UTF_8 | ENC_NA);
4392         }
4393         break;
4394       /* "ignore", handled above */
4395       /* case ACN_BLOB_FIELD_TYPE12: */
4396       /*   proto_tree_add_string(field_tree, hf_acn_blob_field_value_string, tvb, blob_offset, field_length, "Field Value: Ignore"); */
4397       /*   break; */
4398       default:
4399         proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, blob_offset, blob_offset3, ENC_BIG_ENDIAN);
4400         break;
4401     }
4402   }
4403 }
4404 
4405 /******************************************************************************/
4406 /* Display Blob Field */
4407 static void
display_blob_field(tvbuff_t * tvb,proto_tree * blob_tree,guint8 blob_type,int * blob_offset,guint16 * field_number,int display_variblob_as_CID)4408 display_blob_field(tvbuff_t *tvb, proto_tree *blob_tree, guint8 blob_type, int *blob_offset, guint16 *field_number, int display_variblob_as_CID)
4409 {
4410   guint8            field_type;
4411   guint8            field_length;
4412   guint8            blob_offset1;
4413   guint8            blob_offset2;
4414   guint8            blob_offset3;
4415   guint16           temp_field_number;
4416 
4417   proto_item       *fi;
4418   proto_tree       *field_tree = NULL;
4419   proto_item       *ti;
4420 
4421   const gchar      *field_name;
4422 
4423   if ((blob_type == ACN_BLOB_ENERGY_MANAGEMENT) && (*field_number > 3)) {
4424     /* an exception to blob field rules: no "type" subfield, no "length" subfield */
4425 
4426     /* field names 4 through 7 repeat: 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, ... */
4427     temp_field_number = (*field_number % 4) + 4;
4428 
4429     switch (temp_field_number) {
4430       case 4:
4431         /* uint2 */
4432         field_length = 2;
4433         blob_offset3 = 2;
4434         field_name = get_field_name(blob_type, temp_field_number);
4435 
4436         /* Create Sub Tree for Field Type*/
4437         fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, *blob_offset, field_length, ENC_NA);
4438         field_tree = proto_item_add_subtree(fi, ett_acn_blob);
4439 
4440         /* Add the Field Name Found to Sub Tree */
4441         proto_item_append_text(fi, ": %s", field_name);
4442 
4443         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, *blob_offset, 2, ENC_BIG_ENDIAN);
4444         proto_item_set_len(ti, blob_offset3);
4445         break;
4446       case 5:
4447       case 6:
4448       case 7:
4449         /* uint4 */
4450         field_length = 4;
4451         blob_offset3 = 4;
4452         field_name = get_field_name(blob_type, temp_field_number);
4453 
4454         /* Create Sub Tree for Field Type*/
4455         fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, *blob_offset, field_length, ENC_NA);
4456         field_tree = proto_item_add_subtree(fi, ett_acn_blob);
4457 
4458         /* Add the Field Name Found to Sub Tree */
4459         proto_item_append_text(fi, ": %s", field_name);
4460         ti = proto_tree_add_item(field_tree, hf_acn_blob_field_value_number, tvb, *blob_offset, 4, ENC_BIG_ENDIAN);
4461         proto_item_set_len(ti, blob_offset3);
4462         break;
4463     }
4464   }
4465   else {
4466     /* Get field type*/
4467     field_type = tvb_get_guint8(tvb, *blob_offset);
4468     get_field_type_parameters(tvb, *blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
4469     field_name = get_field_name(blob_type, *field_number);
4470 
4471     /* Create Sub Tree for Field Type*/
4472     fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, *blob_offset, field_length + 1, ENC_NA);
4473     field_tree = proto_item_add_subtree(fi, ett_acn_blob);
4474 
4475     /* Add the Field Name Found to Sub Tree */
4476     proto_item_append_text(fi, ": %s", field_name);
4477 
4478     /* Add field type to field sub tree */
4479     proto_tree_add_uint(field_tree, hf_acn_blob_field_type, tvb, *blob_offset, 1, field_type);
4480     *blob_offset += blob_offset1;
4481 
4482     /* Add field length to field sub tree */
4483     proto_tree_add_uint(field_tree, hf_acn_blob_field_length, tvb, *blob_offset, 1, field_length);
4484     *blob_offset += blob_offset2;
4485 
4486     display_blob_field_value(tvb, field_tree, *field_number, blob_type, field_type, field_length, *blob_offset, blob_offset3, display_variblob_as_CID);
4487   }
4488 
4489   *blob_offset += blob_offset3;
4490   *field_number += 1;
4491 }
4492 
4493 /******************************************************************************/
4494 /* Dissect Blob Metadata */
4495 static guint32
dissect_acn_blob_metadata(tvbuff_t * tvb,proto_tree * blob_tree,int blob_offset,int end_offset)4496 dissect_acn_blob_metadata(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
4497 {
4498   guint8   blob_type = ACN_BLOB_METADATA;
4499   guint16  field_number = 1;
4500   gboolean display_variblob_as_CID;
4501 
4502   /* Loop though dissecting fields until the end is reached */
4503   while (blob_offset < end_offset) {
4504     if (field_number == 15) {
4505 
4506       display_variblob_as_CID = 1;
4507     }
4508     else {
4509       display_variblob_as_CID = 0;
4510 
4511     }
4512 
4513     display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, display_variblob_as_CID);
4514   }
4515   return 0;
4516 }
4517 
4518 /******************************************************************************/
4519 /* Dissect Blob Preset Properties */
4520 static guint32
dissect_acn_blob_preset_properties(tvbuff_t * tvb,proto_tree * blob_tree,int blob_offset,int end_offset)4521 dissect_acn_blob_preset_properties(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
4522 {
4523   guint8       blob_type = ACN_BLOB_PRESET_PROPERTIES;
4524   guint8       field_type;
4525   guint8       field_length;
4526   guint8       blob_offset1;
4527   guint8       blob_offset2;
4528   guint8       blob_offset3;
4529   guint8       sub_blob_index;
4530   guint16      field_number = 1;
4531   guint8       max_sub_blobs = 192;
4532   proto_item  *fi;
4533   proto_tree  *sub_blob_tree = NULL;
4534   const gchar *field_name;
4535 
4536   /* Loop though dissecting fields until the end is reached */
4537   while (blob_offset < end_offset) {
4538     if (field_number == 17) {
4539       /* Create subtree for "Levels" */
4540       field_type = tvb_get_guint8(tvb, blob_offset);
4541       get_field_type_parameters(tvb, blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
4542 
4543       field_name = get_field_name(blob_type, field_number);
4544       field_number += 1;
4545 
4546       /* Create Sub Tree for Field Type */
4547       fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, blob_offset, (field_length + 1) * max_sub_blobs, ENC_NA);
4548       sub_blob_tree = proto_item_add_subtree(fi, ett_acn_blob);
4549 
4550       proto_item_append_text(fi, ": %s", field_name);
4551       sub_blob_index = 0;
4552 
4553       while ((sub_blob_index < max_sub_blobs) && (blob_offset < end_offset)) {
4554         display_blob_field(tvb, sub_blob_tree, blob_type, &blob_offset, &field_number, 0);
4555 
4556         sub_blob_index += 1;
4557       }
4558 
4559     }
4560 
4561     else {
4562       display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, 0);
4563     }
4564 
4565   }
4566   return 0;
4567 }
4568 
4569 /******************************************************************************/
4570 /* Dissect Blob Dimming Rack Properties v2 */
4571 static guint32
dissect_acn_blob_dimming_rack_properties_v2(tvbuff_t * tvb,proto_tree * blob_tree,int blob_offset,int end_offset)4572 dissect_acn_blob_dimming_rack_properties_v2(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
4573 {
4574   guint8       blob_type = ACN_BLOB_DIMMER_RACK_PROPERTIES2;
4575   guint16      field_number = 1;
4576   gboolean     display_variblob_as_CID;
4577 
4578   /* Loop though dissecting fields until the end is reached */
4579   while (blob_offset < end_offset) {
4580     if (field_number == 12) {
4581 
4582       display_variblob_as_CID = 1;
4583 
4584     }
4585     else {
4586 
4587       display_variblob_as_CID = 0;
4588 
4589     }
4590 
4591     display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, display_variblob_as_CID);
4592   }
4593   return 0;
4594 }
4595 
4596 /******************************************************************************/
4597 /* Dissect Blob Dimming Rack Status Properties v2 */
4598 static guint32
dissect_acn_blob_dimming_rack_status_properties_v2(tvbuff_t * tvb,proto_tree * blob_tree,int blob_offset,int end_offset)4599 dissect_acn_blob_dimming_rack_status_properties_v2(tvbuff_t *tvb, proto_tree *blob_tree, int blob_offset, int end_offset)
4600 {
4601   guint8       blob_type;
4602   guint8       field_type;
4603   guint8       field_length;
4604   guint8       blob_offset1;
4605   guint8       blob_offset2;
4606   guint8       blob_offset3;
4607   guint8       sub_blob_index;
4608   guint16      field_number;
4609 
4610   int          number_of_sub_blobs;
4611 
4612   proto_item  *fi;
4613   proto_tree  *sub_blob_tree = NULL;
4614 
4615   const gchar *field_name;
4616 
4617   /*First Assignments*/
4618   blob_type = ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2;
4619   field_number = 1;
4620   number_of_sub_blobs = 64;
4621 
4622   /* Loop though dissecting fields until the end is reached */
4623   while (blob_offset < end_offset) {
4624     if (field_number == 22) {
4625       /* Create subtree for "Active Preset Group IDs" */
4626       field_type = tvb_get_guint8(tvb, blob_offset);
4627       get_field_type_parameters(tvb, blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
4628 
4629       field_name = get_field_name(blob_type, field_number);
4630       field_number += 1;
4631 
4632       /* Create Sub Tree for Field Type */
4633       fi = proto_tree_add_item(blob_tree, hf_acn_blob_tree_field_type, tvb, blob_offset, (field_length + 1) * number_of_sub_blobs, ENC_NA);
4634       sub_blob_tree = proto_item_add_subtree(fi, ett_acn_blob);
4635 
4636       proto_item_append_text(fi, ": %s", field_name);
4637 
4638       sub_blob_index = 0;
4639 
4640       while ((sub_blob_index < number_of_sub_blobs) && (blob_offset < end_offset)) {
4641         display_blob_field(tvb, sub_blob_tree, blob_type, &blob_offset, &field_number, 0);
4642 
4643         sub_blob_index += 1;
4644 
4645       }
4646 
4647     }
4648 
4649     else {
4650       display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, 0);
4651     }
4652 
4653   }
4654   return 0;
4655 }
4656 
4657 /******************************************************************************/
4658 /* Get Blob Type From Fields
4659 Both "Dimmer Properties v2" and "Preset Properties" ended up with blob type 20 */
4660 static guint8
get_blob_type_from_fields(tvbuff_t * tvb,int blob_offset,int end_offset)4661 get_blob_type_from_fields(tvbuff_t *tvb, int blob_offset, int end_offset)
4662 {
4663   guint8  field_type;
4664   guint8  field_length;
4665   guint8  blob_offset1;
4666   guint8  blob_offset2;
4667   guint8  blob_offset3;
4668   guint16 field_number = 1;
4669 
4670   while (blob_offset < end_offset) {
4671     field_type = tvb_get_guint8(tvb, blob_offset);
4672     if (field_number == 12) {
4673       if (field_type == ACN_BLOB_FIELD_TYPE11) {
4674         /* string: dimmer name field */
4675         return ACN_BLOB_DIMMER_PROPERTIES2;
4676       }
4677       /* number: preset number field */
4678       return ACN_BLOB_PRESET_PROPERTIES;
4679     }
4680     get_field_type_parameters(tvb, blob_offset, field_type, &field_length, &blob_offset1, &blob_offset2, &blob_offset3);
4681     blob_offset += blob_offset2 + blob_offset3;
4682     field_number += 1;
4683   }
4684 
4685   return ACN_BLOB_DIMMER_PROPERTIES2;
4686 }
4687 
4688 /******************************************************************************/
4689 /* Dissect Blob */
4690 static guint32
dissect_acn_blob(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * pdu_tree,int blob_offset,int end_offset)4691 dissect_acn_blob(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *pdu_tree, int blob_offset, int end_offset)
4692 {
4693   /* Declarations for blobs*/
4694   guint8     version;
4695   guint8     range;
4696   guint8     blob_type;
4697   guint8     range_number;
4698   guint16    field_number = 1;
4699   proto_item *bi;
4700   proto_tree *blob_tree = NULL;
4701   const gchar *blob_name;
4702   /* const gchar *range_type; */
4703 
4704   /* Add blob to tree */
4705   bi = proto_tree_add_item(pdu_tree, hf_acn_blob, tvb, blob_offset, end_offset, ENC_NA);
4706   blob_tree = proto_item_add_subtree(bi, 0);
4707   end_offset = blob_offset + end_offset;
4708   blob_offset += 4;
4709 
4710   /* Add Blob version item to tree */
4711   version = tvb_get_guint8(tvb, blob_offset);
4712   proto_tree_add_item(blob_tree, hf_acn_blob_version, tvb, blob_offset, 1, version);
4713   blob_offset += 1;
4714 
4715   /* Add Blob Start and End Range Info */
4716   range = tvb_get_guint8(tvb, blob_offset);
4717   proto_tree_add_item(blob_tree, hf_acn_blob_range_type, tvb, blob_offset, 1, range);
4718   /* range_type = val_to_str(range, acn_blob_range_type_vals, "not valid (%d)"); */
4719   blob_offset += 1;
4720 
4721   /* Add Blob Range Number */
4722   range_number = tvb_get_guint8(tvb, blob_offset);
4723   proto_tree_add_item(blob_tree, hf_acn_blob_range_number, tvb, blob_offset, 1, range_number);
4724   blob_offset += 1;
4725 
4726   /* Add Blob Meta-Type */
4727   blob_type = tvb_get_guint8(tvb, blob_offset);
4728   if (blob_type == ACN_BLOB_DIMMER_PROPERTIES2) {
4729     /* Dimmer  Properties v2 and Preset Properties have the same 'type' value (20) */
4730     blob_type = get_blob_type_from_fields(tvb, blob_offset + 1, end_offset);
4731   }
4732 
4733   proto_tree_add_item(blob_tree, hf_acn_blob_type, tvb, blob_offset, 1, blob_type);
4734 
4735   blob_name = val_to_str(blob_type, acn_blob_type_vals, "not valid (%d)");
4736   proto_item_append_text(bi, ": %s", blob_name);
4737   blob_offset += 1;
4738 
4739   if (blob_type == ACN_BLOB_METADATA) {
4740     return dissect_acn_blob_metadata(tvb, blob_tree, blob_offset, end_offset);
4741   }
4742   if (blob_type == ACN_BLOB_PRESET_PROPERTIES) {
4743     return dissect_acn_blob_preset_properties(tvb, blob_tree, blob_offset, end_offset);
4744   }
4745   if (blob_type == ACN_BLOB_DIMMER_RACK_PROPERTIES2) {
4746     return dissect_acn_blob_dimming_rack_properties_v2(tvb, blob_tree, blob_offset, end_offset);
4747   }
4748   if (blob_type == ACN_BLOB_DIMMER_RACK_STATUS_PROPERTIES2) {
4749     return dissect_acn_blob_dimming_rack_status_properties_v2(tvb, blob_tree, blob_offset, end_offset);
4750   }
4751 
4752   /* Loop though dissecting fields until the end is reached */
4753   while (blob_offset < end_offset) {
4754     display_blob_field(tvb, blob_tree, blob_type, &blob_offset, &field_number, 0);
4755   }
4756   return 0;
4757 }
4758 
4759 /******************************************************************************/
4760 /* Dissect PDU L bit flag                                                     */
4761 static void
dissect_pdu_bit_flag_l(tvbuff_t * tvb,int * offset,guint8 * pdu_flags,guint32 * pdu_length,guint32 * pdu_flvh_length)4762 dissect_pdu_bit_flag_l(tvbuff_t *tvb, int *offset, guint8 *pdu_flags, guint32 *pdu_length, guint32 *pdu_flvh_length)
4763 {
4764   guint8  octet;
4765   guint32 length1;
4766   guint32 length2;
4767   guint32 length3;
4768 
4769   /* get PDU flags and length flag */
4770   octet      = tvb_get_guint8(tvb, (*offset)++);
4771   *pdu_flags = octet & 0xf0;
4772   length1    = octet & 0x0f;     /* bottom 4 bits only */
4773   length2    = tvb_get_guint8(tvb, (*offset)++);
4774 
4775   /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
4776   /* flvh = flags, length, vector, header */
4777   if (*pdu_flags & ACN_PDU_FLAG_L) {
4778     length3 = tvb_get_guint8(tvb, *offset);
4779     *offset += 1;
4780     *pdu_length = length3 | (length2 << 8) | (length1 << 16);
4781     *pdu_flvh_length = 3;
4782   } else {
4783     *pdu_length = length2 | (length1 << 8);
4784     *pdu_flvh_length = 2;
4785   }
4786 }
4787 
4788 /******************************************************************************/
4789 /* Dissect PDU V bit flag                                                     */
4790 static void
dissect_pdu_bit_flag_v(int * offset,guint8 pdu_flags,guint32 * vector_offset,acn_pdu_offsets * last_pdu_offsets,guint32 * pdu_flvh_length,guint8 increment)4791 dissect_pdu_bit_flag_v(int *offset, guint8 pdu_flags, guint32 *vector_offset, acn_pdu_offsets *last_pdu_offsets, guint32 *pdu_flvh_length, guint8 increment)
4792 {
4793   /* Set vector offset */
4794   if (pdu_flags & ACN_PDU_FLAG_V) {
4795     /* use new values */
4796     *vector_offset            = *offset;
4797     last_pdu_offsets->vector  = *offset;
4798     *offset                   += increment;
4799     *pdu_flvh_length          += increment;
4800   } else {
4801     /* use last values */
4802     *vector_offset            = last_pdu_offsets->vector;
4803   }
4804 }
4805 
4806 /******************************************************************************/
4807 /* Dissect PDU H bit flag                                                     */
4808 static void
dissect_pdu_bit_flag_h(int * offset,guint8 pdu_flags,guint32 * header_offset,acn_pdu_offsets * last_pdu_offsets,guint32 * pdu_flvh_length,guint8 increment)4809 dissect_pdu_bit_flag_h(int *offset, guint8 pdu_flags, guint32 *header_offset, acn_pdu_offsets *last_pdu_offsets, guint32 *pdu_flvh_length, guint8 increment)
4810 {
4811   /* Set header offset */
4812   if (pdu_flags & ACN_PDU_FLAG_H) {
4813     /* use new values */
4814     *header_offset            = *offset;
4815     last_pdu_offsets->header  = *offset;
4816     *offset                   += increment;
4817     *pdu_flvh_length          += increment;
4818   } else {
4819     /* use last values */
4820     *header_offset            = last_pdu_offsets->header;
4821   }
4822 }
4823 
4824 /******************************************************************************/
4825 /* Dissect PDU D bit flag                                                     */
4826 static void
dissect_pdu_bit_flag_d(int offset,guint8 pdu_flags,guint32 pdu_length,guint32 * data_offset,guint32 * data_length,acn_pdu_offsets * last_pdu_offsets,guint32 pdu_flvh_length,gboolean set_last_value_length)4827 dissect_pdu_bit_flag_d(int offset, guint8 pdu_flags, guint32 pdu_length, guint32 *data_offset, guint32 *data_length, acn_pdu_offsets *last_pdu_offsets, guint32 pdu_flvh_length, gboolean set_last_value_length)
4828 {
4829   /* Adjust data */
4830   if (pdu_flags & ACN_PDU_FLAG_D) {
4831     /* use new values */
4832     *data_offset                  = offset;
4833     *data_length                  = pdu_length - pdu_flvh_length;
4834     last_pdu_offsets->data        = offset;
4835     last_pdu_offsets->data_length = *data_length;
4836   } else {
4837     /* use last values */
4838     *data_offset                  = last_pdu_offsets->data;
4839     if (set_last_value_length) {
4840       *data_length                = last_pdu_offsets->data_length;
4841     }
4842   }
4843 }
4844 
4845 /******************************************************************************/
4846 /* Add flag and flag tree                                                     */
4847 static void
begin_dissect_acn_pdu(proto_tree ** pdu_tree,tvbuff_t * tvb,proto_item ** ti,proto_tree * tree,guint32 * pdu_start,int * offset,guint8 * pdu_flags,guint32 * pdu_length,guint32 * pdu_flvh_length,gint ett_base_pdu,gboolean is_acn)4848 begin_dissect_acn_pdu(proto_tree **pdu_tree, tvbuff_t *tvb, proto_item **ti, proto_tree *tree, guint32 *pdu_start, int *offset, guint8 *pdu_flags, guint32 *pdu_length, guint32 *pdu_flvh_length, gint ett_base_pdu, gboolean is_acn)
4849 {
4850   proto_item  *pi;
4851   proto_tree  *flag_tree;
4852 
4853   /* save start of pdu block */
4854   *pdu_start        = *offset;
4855 
4856   dissect_pdu_bit_flag_l(tvb, offset, pdu_flags, pdu_length, pdu_flvh_length);
4857   /* offset should now be pointing to vector (if one exists) */
4858 
4859   /* add pdu item and tree */
4860   if (is_acn) {
4861     *ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, *pdu_start, *pdu_length, ENC_NA);
4862   } else {
4863     *ti = proto_tree_add_item(tree, hf_rdmnet_pdu, tvb, *pdu_start, *pdu_length, ENC_NA);
4864   }
4865   *pdu_tree = proto_item_add_subtree(*ti, ett_base_pdu);
4866 
4867   /* add flag item and tree */
4868   if (is_acn) {
4869     pi        = proto_tree_add_uint(*pdu_tree, hf_acn_pdu_flags, tvb, *pdu_start, 1, *pdu_flags);
4870     flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
4871     proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4872     proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4873     proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4874     proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4875   }
4876   else {
4877     pi        = proto_tree_add_uint(*pdu_tree, hf_rdmnet_pdu_flags, tvb, *pdu_start, 1, *pdu_flags);
4878     flag_tree = proto_item_add_subtree(pi, ett_rdmnet_pdu_flags);
4879     proto_tree_add_item(flag_tree, hf_rdmnet_pdu_flag_l, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4880     proto_tree_add_item(flag_tree, hf_rdmnet_pdu_flag_v, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4881     proto_tree_add_item(flag_tree, hf_rdmnet_pdu_flag_h, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4882     proto_tree_add_item(flag_tree, hf_rdmnet_pdu_flag_d, tvb, *pdu_start, 1, ENC_BIG_ENDIAN);
4883   }
4884 }
4885 
4886 /******************************************************************************/
4887 /* Dissect wrapped SDT PDU                                                    */
4888 static guint32
dissect_acn_dmp_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)4889 dissect_acn_dmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
4890 {
4891   /* common to all pdu */
4892   gboolean          blob_exists = 0;
4893   guint8            pdu_flags;
4894   guint32           pdu_start;
4895   guint32           pdu_length;
4896   guint32           pdu_flvh_length; /* flags, length, vector, header */
4897   guint8            D;
4898   guint32           vector_offset;
4899   guint32           header_offset;
4900   guint32           data_offset;
4901   guint32           old_offset;
4902   guint32           end_offset;
4903   guint32           data_length;
4904   guint32           address_count;
4905   guint32           blob_offset;
4906   guint32           blob_end_offset = 0;
4907 
4908   proto_item       *ti;
4909   proto_tree       *pdu_tree  = NULL;
4910 
4911   /* this pdu */
4912   const gchar      *name;
4913   acn_dmp_adt_type  adt       = {0,0,0,0,0,0};
4914   acn_dmp_adt_type  adt2      = {0,0,0,0,0,0};
4915   guint32           vector;
4916 
4917   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_acn_dmp_pdu, 1);
4918 
4919   /* Add PDU Length item */
4920   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
4921 
4922   dissect_pdu_bit_flag_v(&offset, pdu_flags, &vector_offset, last_pdu_offsets, &pdu_flvh_length, 1);
4923   /* offset should now be pointing to header (if one exists) */
4924 
4925   /* Add Vector item */
4926   vector = tvb_get_guint8(tvb, vector_offset);
4927   proto_tree_add_uint(pdu_tree, hf_acn_dmp_vector, tvb, vector_offset, 1, vector);
4928 
4929   /* Add Vector item to tree*/
4930   name = val_to_str(vector, acn_dmp_vector_vals, "not valid (%d)");
4931   proto_item_append_text(ti, ": ");
4932   proto_item_append_text(ti, "%s", name);
4933 
4934   dissect_pdu_bit_flag_h(&offset, pdu_flags, &header_offset, last_pdu_offsets, &pdu_flvh_length, 1);
4935   /* offset should now be pointing to data (if one exists) */
4936 
4937   /* header contains address and data type */
4938   acn_add_dmp_address_type(tvb, pinfo, pdu_tree, header_offset, &adt);
4939 
4940   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 1);
4941   end_offset = data_offset + data_length;
4942 
4943   /* Check if blob exists, find beginning offset */
4944   blob_offset = data_offset;
4945   blob_exists = 0;
4946   while ((blob_offset < (end_offset - 4)) && (blob_exists != 1)) {
4947     if (tvb_get_ntohl(tvb, blob_offset) == 0x426c6f62) {
4948       /* 0x426c6f62 == "Blob" */
4949       blob_exists = 1;
4950       break;
4951     }
4952     blob_offset += 1;
4953   }
4954 
4955   /* Fix the end_offset for finding Address-Data pair if blob exists*/
4956   if (blob_exists == 1) {
4957     blob_end_offset = end_offset - blob_offset;
4958     end_offset = blob_offset;
4959     data_length = blob_offset - data_offset;
4960   }
4961 
4962   switch (vector) {
4963     case ACN_DMP_VECTOR_UNKNOWN:
4964       break;
4965     case ACN_DMP_VECTOR_GET_PROPERTY:
4966       /* Rip through property address */
4967       while (data_offset < end_offset) {
4968         old_offset      = data_offset;
4969         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4970         if (old_offset == data_offset) break;
4971       }
4972       break;
4973     case ACN_DMP_VECTOR_SET_PROPERTY:
4974       /* Rip through Property Address-Data pairs                                 */
4975       /* But, in reality, this generally won't work as we have know way of       */
4976       /* calculating the next Address-Data pair                                  */
4977       while (data_offset < end_offset) {
4978         old_offset      = data_offset;
4979         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4980         if (old_offset == data_offset) break;
4981 
4982         adt.data_length = data_length - (data_offset - old_offset);
4983         old_offset      = data_offset;
4984         data_offset     = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
4985         if (old_offset == data_offset) break;
4986       }
4987       break;
4988     case ACN_DMP_VECTOR_GET_PROPERTY_REPLY:
4989       /* Rip through Property Address-Data pairs */
4990       /* But, in reality, this generally won't work as we have know way of       */
4991       /* calculating the next Address-Data pair                                  */
4992       while (data_offset < end_offset) {
4993         old_offset      = data_offset;
4994         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
4995         if (old_offset == data_offset) break;
4996 
4997         adt.data_length = data_length - (data_offset - old_offset);
4998         old_offset      = data_offset;
4999         data_offset     = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
5000         if (old_offset == data_offset) break;
5001       }
5002       break;
5003     case ACN_DMP_VECTOR_EVENT:
5004     case ACN_DMP_VECTOR_SYNC_EVENT:
5005       /* Rip through Property Address-Data pairs */
5006       /* But, in reality, this generally won't work as we have know way of       */
5007       /* calculating the next Address-Data pair                                  */
5008       while (data_offset < end_offset) {
5009         old_offset      = data_offset;
5010         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5011         if (old_offset == data_offset) break;
5012 
5013         adt.data_length = data_length - (data_offset - old_offset);
5014         old_offset      = data_offset;
5015         data_offset     = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
5016         if (old_offset == data_offset) break;
5017       }
5018       break;
5019     case ACN_DMP_VECTOR_MAP_PROPERTY:
5020       /* Virtual Address type */
5021       data_offset = acn_add_dmp_address_type(tvb, pinfo, pdu_tree, data_offset, &adt2);
5022       /* Rip through Actual-Virtual Address Pairs */
5023       while (data_offset < end_offset) {
5024         /* actual */
5025         old_offset      = data_offset;
5026         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5027         if (old_offset == data_offset) break;
5028         D = ACN_DMP_ADT_EXTRACT_D(adt.flags);
5029         switch (D) {
5030           case ACN_DMP_ADT_D_NS:
5031             address_count = 1;
5032             break;
5033           case ACN_DMP_ADT_D_RS:
5034             address_count = 1;
5035             break;
5036           case ACN_DMP_ADT_D_RE:
5037             address_count = adt.count;
5038             break;
5039             /*case ACN_DMP_ADT_D_RM: */
5040           default:
5041             /* OUCH */
5042             return pdu_start + pdu_length;
5043             break;
5044         }
5045 
5046         /* virtual */
5047         while (address_count > 0) {
5048           data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt2);
5049           address_count--;
5050         }
5051       }
5052       break;
5053     case ACN_DMP_VECTOR_UNMAP_PROPERTY:
5054       /* Rip through Actual Property Address */
5055       while (data_offset < end_offset) {
5056         old_offset      = data_offset;
5057         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5058         if (old_offset == data_offset) break;
5059       }
5060       break;
5061     case ACN_DMP_VECTOR_SUBSCRIBE:
5062       /* Rip through Property Address */
5063       while (data_offset < end_offset) {
5064         old_offset      = data_offset;
5065         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5066         if (old_offset == data_offset) break;
5067       }
5068       break;
5069     case ACN_DMP_VECTOR_UNSUBSCRIBE:
5070       /* Rip through Property Address */
5071       while (data_offset < end_offset) {
5072         old_offset      = data_offset;
5073         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5074         if (old_offset == data_offset) break;
5075       }
5076       break;
5077     case ACN_DMP_VECTOR_GET_PROPERTY_FAIL:
5078       /* Rip through Address-Reason Code Pairs */
5079       while (data_offset < end_offset) {
5080         old_offset      = data_offset;
5081         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5082         if (old_offset == data_offset) break;
5083 
5084         adt.data_length = data_length - (data_offset - old_offset);
5085         old_offset      = data_offset;
5086         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
5087         if (old_offset == data_offset) break;
5088       }
5089       break;
5090     case ACN_DMP_VECTOR_SET_PROPERTY_FAIL:
5091       /* Rip through Address-Reason Code Pairs */
5092       while (data_offset < end_offset) {
5093         old_offset      = data_offset;
5094         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5095         if (old_offset == data_offset) break;
5096 
5097         adt.data_length = data_length - (data_offset - old_offset);
5098         old_offset      = data_offset;
5099         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
5100         if (old_offset == data_offset) break;
5101       }
5102       break;
5103     case ACN_DMP_VECTOR_MAP_PROPERTY_FAIL:
5104       /* Rip through Address-Reason Code Pairs */
5105       while (data_offset < end_offset) {
5106         old_offset      = data_offset;
5107         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5108         if (old_offset == data_offset) break;
5109 
5110         adt.data_length = data_length - (data_offset - old_offset);
5111         old_offset      = data_offset;
5112         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
5113         if (old_offset == data_offset) break;
5114       }
5115       break;
5116     case ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT:
5117       /* Rip through Property Addresses */
5118       while (data_offset < end_offset) {
5119         old_offset      = data_offset;
5120         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5121         if (old_offset == data_offset) break;
5122       }
5123       break;
5124     case ACN_DMP_VECTOR_SUBSCRIBE_REJECT:
5125       /* Rip through Address-Reason Code Pairs */
5126       while (data_offset < end_offset) {
5127         old_offset      = data_offset;
5128         data_offset     = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
5129         if (old_offset == data_offset) break;
5130 
5131         adt.data_length = data_length - (data_offset - old_offset);
5132         old_offset      = data_offset;
5133         data_offset     = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
5134         if (old_offset == data_offset) break;
5135       }
5136       break;
5137     case ACN_DMP_VECTOR_ALLOCATE_MAP:
5138       /* No data for this */
5139       break;
5140     case ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY:
5141       /* Single reason code  */
5142       proto_tree_add_item(pdu_tree, hf_acn_dmp_reason_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5143       /* data_offset += 1; */
5144     case ACN_DMP_VECTOR_DEALLOCATE_MAP:
5145       /* No data for this */
5146       break;
5147   }
5148 
5149   /* If blob exists, call function to dissect blob*/
5150   if (blob_exists == 1) {
5151     dissect_acn_blob(tvb, pinfo, pdu_tree, blob_offset, blob_end_offset);
5152   }
5153 
5154   return pdu_start + pdu_length;
5155 }
5156 
5157 
5158 /******************************************************************************/
5159 /* Dissect wrapped SDT PDU                                                    */
5160 static guint32
dissect_acn_sdt_wrapped_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5161 dissect_acn_sdt_wrapped_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5162 {
5163   /* common to all pdu */
5164   guint8           pdu_flags;
5165   guint32          pdu_start;
5166   guint32          pdu_length;
5167   guint32          pdu_flvh_length; /* flags, length, vector, header */
5168   guint32          vector_offset;
5169   guint32          data_offset;
5170   guint32          data_length;
5171 
5172   proto_item  *ti;
5173   proto_tree  *pdu_tree  = NULL;
5174 
5175   /* this pdu */
5176   const gchar *name;
5177   guint32      vector;
5178 
5179   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_acn_sdt_pdu, 1);
5180 
5181   /* Add PDU Length item */
5182   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5183 
5184   dissect_pdu_bit_flag_v(&offset, pdu_flags, &vector_offset, last_pdu_offsets, &pdu_flvh_length, 1);
5185   /* offset should now be pointing to header (if one exists) */
5186 
5187   /* Add Vector item */
5188   vector = tvb_get_guint8(tvb, vector_offset);
5189   proto_tree_add_uint(pdu_tree, hf_acn_sdt_vector, tvb, vector_offset, 1, vector);
5190 
5191   /* Add Vector item to tree*/
5192   name = val_to_str(vector, acn_sdt_vector_vals, "not valid (%d)");
5193   proto_item_append_text(ti, ": ");
5194   proto_item_append_text(ti, "%s", name);
5195 
5196   /* NO HEADER DATA ON THESE* (at least so far) */
5197 
5198   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
5199 
5200   switch (vector) {
5201     case ACN_SDT_VECTOR_ACK:
5202       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5203       /*data_offset += 4;*/
5204       break;
5205     case ACN_SDT_VECTOR_CHANNEL_PARAMS:
5206       data_offset = acn_add_channel_parameter(tvb, pinfo, pdu_tree, data_offset);
5207       data_offset = acn_add_address(tvb, pinfo, pdu_tree, data_offset, "Ad-hoc Address:");
5208       /*data_offset =*/ acn_add_expiry(tvb, pinfo, pdu_tree, data_offset, hf_acn_adhoc_expiry);
5209       break;
5210     case ACN_SDT_VECTOR_LEAVE:
5211       /* nothing more */
5212       break;
5213     case ACN_SDT_VECTOR_CONNECT:
5214       /* Protocol ID item */
5215       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5216       /*data_offset += 4;*/
5217       break;
5218     case ACN_SDT_VECTOR_CONNECT_ACCEPT:
5219       /* Protocol ID item */
5220       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5221       /*data_offset += 4;*/
5222       break;
5223     case ACN_SDT_VECTOR_CONNECT_REFUSE:
5224       /* Protocol ID item */
5225       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5226       data_offset += 4;
5227       proto_tree_add_item(pdu_tree, hf_acn_refuse_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5228       /*data_offset += 1;*/
5229       break;
5230     case ACN_SDT_VECTOR_DISCONNECT:
5231       /* Protocol ID item */
5232       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5233       /*data_offset += 4;*/
5234       break;
5235     case ACN_SDT_VECTOR_DISCONNECTING:
5236       /* Protocol ID item */
5237       proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5238       data_offset += 4;
5239       proto_tree_add_item(pdu_tree, hf_acn_reason_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5240       /*data_offset += 1;*/
5241       break;
5242 
5243   }
5244 
5245   return pdu_start + pdu_length;
5246 }
5247 
5248 
5249 /******************************************************************************/
5250 /* Dissect SDT Client PDU                                                     */
5251 static guint32
dissect_acn_sdt_client_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5252 dissect_acn_sdt_client_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5253 {
5254   /* common to all pdu */
5255   guint8           pdu_flags;
5256   guint32          pdu_start;
5257   guint32          pdu_length;
5258   guint32          pdu_flvh_length; /* flags, length, vector, header */
5259   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
5260   guint32          vector_offset;
5261   guint32          header_offset;
5262   guint32          data_offset;
5263   guint32          data_length;
5264   guint32          old_offset;
5265   guint32          end_offset;
5266 
5267   proto_item      *ti;
5268   proto_tree      *pdu_tree    = NULL;
5269 
5270   /* this pdu */
5271   const gchar     *name;
5272   guint32          member_id;
5273   guint32          protocol_id;
5274   guint16          association;
5275 
5276   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_acn_sdt_client_pdu, 1);
5277 
5278   /* Add PDU Length item */
5279   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5280 
5281   dissect_pdu_bit_flag_v(&offset, pdu_flags, &vector_offset, last_pdu_offsets, &pdu_flvh_length, 2);
5282   /* offset should now be pointing to header (if one exists) */
5283 
5284   /* add Member ID item  */
5285   member_id = tvb_get_ntohs(tvb, vector_offset);
5286   proto_tree_add_uint(pdu_tree, hf_acn_member_id, tvb, vector_offset, 2, member_id);
5287 
5288   dissect_pdu_bit_flag_h(&offset, pdu_flags, &header_offset, last_pdu_offsets, &pdu_flvh_length, 6);
5289   /* offset should now be pointing to data (if one exists) */
5290 
5291   /* add Protocol ID item (Header)*/
5292   protocol_id = tvb_get_ntohl(tvb, header_offset);
5293   proto_tree_add_uint(pdu_tree, hf_acn_protocol_id, tvb, header_offset, 4, protocol_id);
5294   header_offset += 4;
5295 
5296   /* Add protocol to tree*/
5297   name = val_to_str(protocol_id, acn_protocol_id_vals, "id not valid (%d)");
5298   proto_item_append_text(ti, ": ");
5299   proto_item_append_text(ti, "%s", name);
5300 
5301   /* add association item */
5302   association = tvb_get_ntohs(tvb, header_offset);
5303   proto_tree_add_uint(pdu_tree, hf_acn_association, tvb, header_offset, 2, association);
5304   /*header_offset += 2;*/
5305 
5306   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 1);
5307   end_offset = data_offset + data_length;
5308 
5309   switch (protocol_id) {
5310     case ACN_PROTOCOL_ID_SDT:
5311       while (data_offset < end_offset) {
5312         old_offset  = data_offset;
5313         data_offset = dissect_acn_sdt_wrapped_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5314         if (old_offset == data_offset) break;
5315       }
5316       break;
5317     case ACN_PROTOCOL_ID_DMP:
5318       while (data_offset < end_offset) {
5319         old_offset  = data_offset;
5320         data_offset = dissect_acn_dmp_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5321         if (data_offset == old_offset) break;
5322       }
5323       break;
5324   }
5325   return pdu_start + pdu_length;
5326 }
5327 
5328 
5329 /******************************************************************************/
5330 /* level to string (ascii)                                                    */
5331 /*  level    : 8 bit value                                                    */
5332 /*  string   : pointer to buffer to fill                                      */
5333 /*  leading_char: character to buffer left of digits                          */
5334 /*  min_char : minimum number of characters (for filling, not including space)*/
5335 /*  show_zero: show zeros or dots                                             */
5336 /* also adds a space to right end                                             */
5337 /*                                                                            */
5338 /*  returns end of string                                                     */
5339 /*  faster than printf()                                                      */
5340 static char *
ltos(guint8 level,gchar * string,guint8 base,gchar leading_char,guint8 min_chars,gboolean show_zero)5341 ltos(guint8 level, gchar *string, guint8 base, gchar leading_char, guint8 min_chars, gboolean show_zero)
5342 {
5343   guint8 i;
5344   /* verify base */
5345   if (base < 2 || base > 16) {
5346     *string = '\0';
5347     return(string);
5348   }
5349   /* deal with zeros */
5350   if ((level == 0) && (!show_zero)) {
5351     for (i=0; i<min_chars; i++) {
5352       string[i] = '.';
5353     }
5354     string[i++] = ' ';
5355     string[i] = '\0';
5356     return(string + i);
5357   }
5358 
5359   i = 0;
5360   /* do our convert, comes out backwards! */
5361   do {
5362     string[i++] = "0123456789ABCDEF"[level % base];
5363   } while ((level /= base) > 0);
5364 
5365   /* expand to needed character */
5366   for (; i<min_chars; i++) {
5367     string[i] = leading_char;
5368   }
5369   /* terminate */
5370   string[i] = '\0';
5371 
5372   /* now reverse (and correct) the order */
5373   g_strreverse(string);
5374 
5375   /* add a space at the end (ok it's at the start but it will be at the end)*/
5376   string[i++] = ' ';
5377   string[i] = '\0';
5378   return(string + i);
5379 }
5380 
5381 
5382 /******************************************************************************/
5383 /* Dissect DMX data PDU                                                       */
5384 #define BUFFER_SIZE 128
5385 static guint32
dissect_acn_dmx_data_pdu(guint32 protocol_id,tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5386 dissect_acn_dmx_data_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5387 {
5388   /* common to all pdu */
5389   guint8            pdu_flags;
5390   guint32           pdu_start;
5391   guint32           pdu_length;
5392   guint32           pdu_flvh_length; /* flags, length, vector, header */
5393   guint32           vector_offset;
5394   guint32           data_offset;
5395   guint32           end_offset;
5396   guint32           data_length;
5397   guint32           header_offset;
5398   guint32           total_cnt;
5399   guint32           item_cnt;
5400 
5401   proto_item       *ti;
5402   proto_tree       *pdu_tree;
5403 
5404 /* this pdu */
5405   acn_dmp_adt_type  adt       = {0,0,0,0,0,0};
5406   const gchar      *name;
5407   guint32           vector;
5408   gchar            *buffer;
5409   char             *buf_ptr;
5410   guint             x;
5411   guint8            level;
5412   guint8            min_char;
5413   guint8            base;
5414   gchar             leading_char;
5415   guint             perline;
5416   guint             halfline;
5417   guint16           dmx_count;
5418   guint16           dmx_start_code;
5419   guint16           info_start_code;
5420   guint8            dmx_2_start_code;
5421 
5422   buffer = (gchar*)wmem_alloc(pinfo->pool, BUFFER_SIZE);
5423   buffer[0] = '\0';
5424 
5425   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_acn_dmx_data_pdu, 1);
5426 
5427   /* Add PDU Length item */
5428   proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5429 
5430   dissect_pdu_bit_flag_v(&offset, pdu_flags, &vector_offset, last_pdu_offsets, &pdu_flvh_length, 1);
5431   /* offset should now be pointing to header (if one exists) */
5432 
5433   /* Add Vector item */
5434   vector = tvb_get_guint8(tvb, vector_offset);
5435   proto_tree_add_uint(pdu_tree, hf_acn_dmp_vector, tvb, vector_offset, 1, vector);
5436 
5437   /* Add Vector item to tree*/
5438   name = val_to_str(vector, acn_dmp_vector_vals, "not valid (%d)");
5439   proto_item_append_text(ti, ": ");
5440   proto_item_append_text(ti, "%s", name);
5441 
5442   dissect_pdu_bit_flag_h(&offset, pdu_flags, &header_offset, last_pdu_offsets, &pdu_flvh_length, 1);
5443   /* offset should now be pointing to data (if one exists) */
5444 
5445   /* process based on vector */
5446   acn_add_dmp_address_type(tvb, pinfo, pdu_tree, header_offset, &adt);
5447 
5448   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 1);
5449   end_offset = data_offset + data_length;
5450 
5451   switch (vector) {
5452     case ACN_DMP_VECTOR_SET_PROPERTY:
5453       dmx_start_code = tvb_get_ntohs(tvb, data_offset);
5454       if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) {
5455         proto_tree_add_item(pdu_tree, hf_acn_dmx_2_first_property_address, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5456       } else {
5457         proto_tree_add_item(pdu_tree, hf_acn_dmx_start_code, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5458       }
5459       data_offset += 2;
5460       proto_tree_add_item(pdu_tree, hf_acn_dmx_increment, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5461       data_offset += 2;
5462       dmx_count    = tvb_get_ntohs(tvb, data_offset);
5463       proto_tree_add_item(pdu_tree, hf_acn_dmx_count, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5464       data_offset += 2;
5465 
5466       if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) {
5467         dmx_2_start_code = (guint8)tvb_get_ntohs(tvb, data_offset - 1);
5468         proto_tree_add_item(pdu_tree, hf_acn_dmx_2_start_code, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5469         data_offset += 1;
5470         dmx_count   -= 1;
5471       }
5472 
5473       buf_ptr = buffer;
5474 
5475       switch (global_acn_dmx_display_line_format) {
5476         case ACN_PREF_DMX_DISPLAY_16PL:
5477           perline  = 16;
5478           halfline = 8;
5479           break;
5480         default:
5481           perline  = 20;
5482           halfline = 10;
5483       }
5484 
5485       /* values base on display mode */
5486       switch ((guint)global_acn_dmx_display_view) {
5487         case ACN_PREF_DMX_DISPLAY_HEX:
5488           min_char = 2;
5489           base     = 16;
5490           break;
5491 /*      case ACN_PREF_DMX_DISPLAY_PER: */
5492         default:
5493           min_char = 3;
5494           base     = 10;
5495       }
5496 
5497       /* do we display leading zeros */
5498       if (global_acn_dmx_display_leading_zeros) {
5499         leading_char = '0';
5500       } else {
5501         leading_char = ' ';
5502       }
5503       /* add a snippet to info (this may be slow) */
5504       if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) {
5505         info_start_code = dmx_2_start_code;
5506       }
5507       else {
5508         info_start_code = dmx_start_code;
5509       }
5510       col_append_fstr(pinfo->cinfo,COL_INFO, ", Sc %02x, [%02x %02x %02x %02x %02x %02x...]",
5511         info_start_code,
5512         tvb_get_guint8(tvb, data_offset),
5513         tvb_get_guint8(tvb, data_offset+1),
5514         tvb_get_guint8(tvb, data_offset+2),
5515         tvb_get_guint8(tvb, data_offset+3),
5516         tvb_get_guint8(tvb, data_offset+4),
5517         tvb_get_guint8(tvb, data_offset+5));
5518 
5519       /* add a header line */
5520       *buf_ptr++ =  ' ';
5521       *buf_ptr++ =  ' ';
5522       *buf_ptr++ =  ' ';
5523       for (x=0; x<perline; x++) {
5524         buf_ptr = ltos((guint8)(x+1), buf_ptr, 10, ' ', min_char, FALSE);
5525         if ((x+1)==halfline) {
5526           *buf_ptr++ =  '|';
5527           *buf_ptr++ =  ' ';
5528         }
5529       }
5530       *buf_ptr = '\0';
5531       proto_tree_add_string(pdu_tree, hf_acn_dmx_data, tvb, data_offset, dmx_count, buffer);
5532 
5533       /* start our line */
5534       g_snprintf(buffer, BUFFER_SIZE, "001-%03d: ", perline);
5535       buf_ptr = buffer + 9;
5536 
5537       total_cnt = 0;
5538       item_cnt = 0;
5539       for (x=data_offset; x<end_offset; x++) {
5540         level = tvb_get_guint8(tvb, x);
5541         if (global_acn_dmx_display_view == ACN_PREF_DMX_DISPLAY_PER) {
5542           if ((level > 0) && (level < 3)) {
5543             level = 1;
5544           } else {
5545             level = level * 100 / 255;
5546           }
5547         }
5548         buf_ptr = ltos(level, buf_ptr, base, leading_char, min_char, global_acn_dmx_display_zeros);
5549         total_cnt++;
5550         item_cnt++;
5551 
5552         if (item_cnt == perline || x == (end_offset-1)) {
5553           /* add leader... */
5554           proto_tree_add_string_format(pdu_tree, hf_acn_dmx_data, tvb, data_offset, item_cnt, buffer, "%s", buffer);
5555           data_offset += perline;
5556           g_snprintf(buffer, BUFFER_SIZE, "%03d-%03d: ",total_cnt, total_cnt+perline);
5557           buf_ptr = buffer + 9;
5558           item_cnt = 0;
5559         } else {
5560           /* add separator character */
5561           if (item_cnt == halfline) {
5562             *buf_ptr++ = '|';
5563             *buf_ptr++ = ' ';
5564             *buf_ptr   = '\0';
5565           }
5566         }
5567       }
5568       /* NOTE:
5569       address data type                   (fixed at 0xA2)
5570       start code - 1 byte, reserved       (should be 0)
5571                  - 1 byte, start code     (0x255)
5572                  - 2 bytes, packet offset (should be 0000)
5573       address increment - 4 bytes         (ignore)
5574       number of dmx values - 4 bytes      (0-512)
5575       dmx values 0-512 bytes              (data)
5576       */
5577 
5578       break;
5579   }
5580   return pdu_start + pdu_length;
5581 }
5582 
5583 /******************************************************************************/
5584 /* Dissect Common Base PDU                                                    */
5585 static void
dissect_acn_common_base_pdu(tvbuff_t * tvb,proto_tree * tree,int * offset,acn_pdu_offsets * last_pdu_offsets,guint8 * pdu_flags,guint32 * pdu_start,guint32 * pdu_length,guint32 * pdu_flvh_length,guint32 * vector_offset,proto_item ** ti,proto_tree ** pdu_tree,gint ett_base_pdu,guint8 v_flag_increment,gboolean is_acn)5586 dissect_acn_common_base_pdu(tvbuff_t *tvb, proto_tree *tree, int *offset, acn_pdu_offsets *last_pdu_offsets, guint8 *pdu_flags, guint32 *pdu_start, guint32 *pdu_length, guint32 *pdu_flvh_length, guint32 *vector_offset, proto_item **ti, proto_tree **pdu_tree, gint ett_base_pdu, guint8 v_flag_increment, gboolean is_acn)
5587 {
5588   begin_dissect_acn_pdu(pdu_tree, tvb, ti, tree, pdu_start, offset, pdu_flags, pdu_length, pdu_flvh_length, ett_base_pdu, is_acn);
5589 
5590   /* Add PDU Length item */
5591   if (is_acn) {
5592     proto_tree_add_uint(*pdu_tree, hf_acn_pdu_length, tvb, *pdu_start, *pdu_flvh_length, *pdu_length);
5593   } else {
5594     proto_tree_add_uint(*pdu_tree, hf_rdmnet_pdu_length, tvb, *pdu_start, *pdu_flvh_length, *pdu_length);
5595   }
5596 
5597   dissect_pdu_bit_flag_v(offset, *pdu_flags, vector_offset, last_pdu_offsets, pdu_flvh_length, v_flag_increment);
5598   /* offset should now be pointing to header (if one exists) */
5599 }
5600 
5601 /******************************************************************************/
5602 /* Dissect DMX Base PDU                                                       */
5603 static guint32
dissect_acn_dmx_base_pdu(guint32 protocol_id,tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5604 dissect_acn_dmx_base_pdu(guint32 protocol_id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5605 {
5606   /* common to all pdu */
5607   guint8           pdu_flags;
5608   guint32          pdu_start;
5609   guint32          pdu_length;
5610   guint32          pdu_flvh_length; /* flags, length, vector, header */
5611   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
5612   guint8           option_flags;
5613   guint32          vector_offset;
5614   guint32          data_offset;
5615   guint32          data_length;
5616 
5617   proto_item      *ti, *pi;
5618   proto_tree      *pdu_tree;
5619   proto_tree      *flag_tree;
5620 
5621   /* this pdu */
5622   const char      *name;
5623   guint32          vector;
5624 
5625   guint32          universe;
5626   guint32          priority;
5627   guint32          sequence;
5628 
5629   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_acn_dmx_pdu, 4, 1);
5630 
5631   /* Add Vector item */
5632   vector = tvb_get_ntohl(tvb, vector_offset);
5633   proto_tree_add_item(pdu_tree, hf_acn_dmx_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
5634   /* vector_offset +=4; */
5635 
5636   /* Add Vector item to tree*/
5637   name = val_to_str(vector, acn_dmx_vector_vals, "not valid (%d)");
5638   proto_item_append_text(ti, ": %s", name);
5639 
5640   /* NO HEADER DATA ON THESE* (at least so far) */
5641 
5642   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
5643 
5644   /* process based on vector */
5645   switch (vector) {
5646     case ACN_DMP_VECTOR_SET_PROPERTY:
5647       if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) {
5648         proto_tree_add_item(pdu_tree, hf_acn_dmx_source_name, tvb, data_offset, 64, ENC_UTF_8|ENC_NA);
5649         data_offset += 64;
5650       } else {
5651         proto_tree_add_item(pdu_tree, hf_acn_dmx_source_name, tvb, data_offset, 32, ENC_UTF_8|ENC_NA);
5652         data_offset += 32;
5653       }
5654 
5655       priority = tvb_get_guint8(tvb, data_offset);
5656       proto_tree_add_item(pdu_tree, hf_acn_dmx_priority, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5657       data_offset += 1;
5658 
5659       if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) {
5660         proto_tree_add_item(pdu_tree, hf_acn_dmx_2_reserved, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5661         data_offset += 2;
5662       }
5663 
5664       sequence = tvb_get_guint8(tvb, data_offset);
5665       proto_tree_add_item(pdu_tree, hf_acn_dmx_sequence_number, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5666       data_offset += 1;
5667 
5668       if (protocol_id == ACN_PROTOCOL_ID_DMX_2 || protocol_id == ACN_PROTOCOL_ID_DMX_3) {
5669         option_flags = tvb_get_guint8(tvb, data_offset);
5670         pi = proto_tree_add_uint(pdu_tree, hf_acn_dmx_2_options, tvb, data_offset, 1, option_flags);
5671         flag_tree = proto_item_add_subtree(pi, ett_acn_dmx_2_options);
5672         proto_tree_add_item(flag_tree, hf_acn_dmx_2_option_p, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5673         proto_tree_add_item(flag_tree, hf_acn_dmx_2_option_s, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5674         data_offset += 1;
5675       }
5676 
5677       universe = tvb_get_ntohs(tvb, data_offset);
5678       proto_tree_add_item(pdu_tree, hf_acn_dmx_universe, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5679       data_offset += 2;
5680 
5681       /* add universe to info */
5682       col_append_fstr(pinfo->cinfo,COL_INFO, ", Universe %d, Seq %3d", universe, sequence );
5683       proto_item_append_text(ti, ", Universe: %d, Priority: %d", universe, priority);
5684 
5685       /*data_offset =*/ dissect_acn_dmx_data_pdu(protocol_id, tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5686 
5687       break;
5688   }
5689   return pdu_start + pdu_length;
5690 }
5691 
5692 /******************************************************************************/
5693 /* Dissect SDT Base PDU                                                       */
5694 static guint32
dissect_acn_sdt_base_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5695 dissect_acn_sdt_base_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5696 {
5697   /* common to all pdu */
5698   guint8           pdu_flags;
5699   guint32          pdu_start;
5700   guint32          pdu_length;
5701   guint32          pdu_flvh_length; /* flags, length, vector, header */
5702   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
5703   guint32          vector_offset;
5704   guint32          data_offset;
5705   guint32          end_offset;
5706   guint32          old_offset;
5707   guint32          data_length;
5708 
5709   proto_item      *ti, *pi;
5710   proto_tree      *pdu_tree;
5711 
5712   /* this pdu */
5713   const gchar     *name;
5714   guint32          vector;
5715   guint32          member_id;
5716 
5717   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_acn_sdt_base_pdu, 1, 1);
5718 
5719   /* Add Vector item */
5720   vector = tvb_get_guint8(tvb, vector_offset);
5721   proto_tree_add_uint(pdu_tree, hf_acn_sdt_vector, tvb, vector_offset, 1, vector);
5722 
5723   /* Add Vector item to tree*/
5724   name = val_to_str(vector, acn_sdt_vector_vals, "not valid (%d)");
5725   proto_item_append_text(ti, ": %s", name);
5726   /* proto_item_append_text(ti, "%s", name); */
5727 
5728   /* NO HEADER DATA ON THESE* (at least so far) */
5729 
5730   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 1);
5731   end_offset = data_offset + data_length;
5732 
5733   /* process based on vector */
5734   switch (vector) {
5735     case ACN_SDT_VECTOR_UNKNOWN:
5736       break;
5737     case ACN_SDT_VECTOR_REL_WRAP:
5738     case ACN_SDT_VECTOR_UNREL_WRAP:
5739       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5740       data_offset += 2;
5741       proto_tree_add_item(pdu_tree, hf_acn_total_sequence_number,    tvb, data_offset, 4, ENC_BIG_ENDIAN);
5742       data_offset += 4;
5743       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5744       data_offset += 4;
5745       proto_tree_add_item(pdu_tree, hf_acn_oldest_available_wrapper, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5746       data_offset += 4;
5747       proto_tree_add_item(pdu_tree, hf_acn_first_member_to_ack,      tvb, data_offset, 2, ENC_BIG_ENDIAN);
5748       data_offset += 2;
5749       proto_tree_add_item(pdu_tree, hf_acn_last_member_to_ack,       tvb, data_offset, 2, ENC_BIG_ENDIAN);
5750       data_offset += 2;
5751       proto_tree_add_item(pdu_tree, hf_acn_mak_threshold,            tvb, data_offset, 2, ENC_BIG_ENDIAN);
5752       data_offset += 2;
5753 
5754       while (data_offset < end_offset) {
5755         old_offset = data_offset;
5756         data_offset = dissect_acn_sdt_client_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
5757         if (data_offset == old_offset) break;
5758       }
5759       break;
5760     case ACN_SDT_VECTOR_CHANNEL_PARAMS:
5761       break;
5762     case ACN_SDT_VECTOR_JOIN:
5763       proto_tree_add_item(pdu_tree, hf_acn_cid,                      tvb, data_offset, 16, ENC_BIG_ENDIAN);
5764       data_offset += 16;
5765       proto_tree_add_item(pdu_tree, hf_acn_member_id,                tvb, data_offset, 2, ENC_BIG_ENDIAN);
5766       data_offset += 2;
5767       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5768       data_offset += 2;
5769       proto_tree_add_item(pdu_tree, hf_acn_reciprocal_channel,       tvb, data_offset, 2, ENC_BIG_ENDIAN);
5770       data_offset += 2;
5771       proto_tree_add_item(pdu_tree, hf_acn_total_sequence_number,    tvb, data_offset, 4, ENC_BIG_ENDIAN);
5772       data_offset += 4;
5773       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5774       data_offset += 4;
5775       data_offset = acn_add_address(tvb, pinfo, pdu_tree, data_offset, "Destination Address:");
5776       data_offset = acn_add_channel_parameter(tvb, pinfo, pdu_tree, data_offset);
5777       /*data_offset =*/ acn_add_expiry(tvb, pinfo, pdu_tree, data_offset, hf_acn_adhoc_expiry);
5778       break;
5779     case ACN_SDT_VECTOR_JOIN_REFUSE:
5780       pi = proto_tree_add_item(pdu_tree, hf_acn_cid,                  tvb, data_offset, 16, ENC_BIG_ENDIAN);
5781       data_offset += 16;
5782       proto_item_append_text(pi, "(Leader)");
5783       proto_tree_add_item(pdu_tree, hf_acn_channel_number,            tvb, data_offset, 2, ENC_BIG_ENDIAN);
5784       data_offset += 2;
5785       proto_tree_add_item(pdu_tree, hf_acn_member_id,                 tvb, data_offset, 2, ENC_BIG_ENDIAN);
5786       data_offset += 2;
5787       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number,  tvb, data_offset, 4, ENC_BIG_ENDIAN);
5788       data_offset += 4;
5789       proto_tree_add_item(pdu_tree, hf_acn_refuse_code,               tvb, data_offset, 1, ENC_BIG_ENDIAN);
5790       /*data_offset ++;*/
5791       break;
5792     case ACN_SDT_VECTOR_JOIN_ACCEPT:
5793       pi = proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, ENC_BIG_ENDIAN);
5794       data_offset += 16;
5795       proto_item_append_text(pi, "(Leader)");
5796       proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5797       data_offset += 2;
5798       proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5799       data_offset += 2;
5800       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5801       data_offset += 4;
5802       proto_tree_add_item(pdu_tree, hf_acn_reciprocal_channel, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5803       /*data_offset += 2;*/
5804       break;
5805     case ACN_SDT_VECTOR_LEAVE:
5806       break;
5807     case ACN_SDT_VECTOR_LEAVING:
5808       pi = proto_tree_add_item(pdu_tree, hf_acn_cid,                 tvb, data_offset, 16, ENC_BIG_ENDIAN);
5809       data_offset += 16;
5810       proto_item_append_text(pi, "(Leader)");
5811       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5812       data_offset += 2;
5813       proto_tree_add_item(pdu_tree, hf_acn_member_id,                tvb, data_offset, 2, ENC_BIG_ENDIAN);
5814       data_offset += 2;
5815       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5816       data_offset += 4;
5817       proto_tree_add_item(pdu_tree, hf_acn_reason_code,              tvb, data_offset, 1, ENC_BIG_ENDIAN);
5818       /* offset += 1; */
5819       break;
5820     case ACN_SDT_VECTOR_CONNECT:
5821       break;
5822     case ACN_SDT_VECTOR_CONNECT_ACCEPT:
5823       break;
5824     case ACN_SDT_VECTOR_CONNECT_REFUSE:
5825       break;
5826     case ACN_SDT_VECTOR_DISCONNECT:
5827       break;
5828     case ACN_SDT_VECTOR_DISCONNECTING:
5829       break;
5830     case ACN_SDT_VECTOR_ACK:
5831       break;
5832     case ACN_SDT_VECTOR_NAK:
5833       pi = proto_tree_add_item(pdu_tree, hf_acn_cid,                 tvb, data_offset, 16, ENC_BIG_ENDIAN);
5834       data_offset += 16;
5835       proto_item_append_text(pi, "(Leader)");
5836       proto_tree_add_item(pdu_tree, hf_acn_channel_number,           tvb, data_offset, 2, ENC_BIG_ENDIAN);
5837       data_offset += 2;
5838       proto_tree_add_item(pdu_tree, hf_acn_member_id,                tvb, data_offset, 2, ENC_BIG_ENDIAN);
5839       data_offset += 2;
5840       proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
5841       data_offset += 4;
5842       proto_tree_add_item(pdu_tree, hf_acn_first_missed_sequence,    tvb, data_offset, 4, ENC_BIG_ENDIAN);
5843       data_offset += 4;
5844       proto_tree_add_item(pdu_tree, hf_acn_last_missed_sequence,     tvb, data_offset, 4, ENC_BIG_ENDIAN);
5845       /*data_offset += 4;*/
5846       break;
5847     case ACN_SDT_VECTOR_GET_SESSION:
5848       proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, ENC_BIG_ENDIAN);
5849       /*data_offset += 16;*/
5850       break;
5851     case ACN_SDT_VECTOR_SESSIONS:
5852       member_id = tvb_get_ntohs(tvb, data_offset);
5853       switch (member_id) {
5854         case 0:
5855           /*data_offset =*/ acn_add_channel_owner_info_block(tvb, pinfo, pdu_tree, data_offset);
5856           break;
5857         case 1:
5858           /*data_offset =*/ acn_add_channel_member_info_block(tvb, pinfo, pdu_tree, data_offset);
5859           break;
5860       }
5861       break;
5862   }
5863 
5864   return pdu_start + pdu_length;
5865 }
5866 
5867 
5868 /******************************************************************************/
5869 /* Dissect LLRP Probe Request PDU                                             */
5870 static guint32
dissect_llrp_probe_request_pdu(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5871 dissect_llrp_probe_request_pdu(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5872 {
5873   /* common to all pdu */
5874   guint8           pdu_flags;
5875   guint8           vector;
5876   guint8           filter_flags;
5877   guint32          pdu_start;
5878   guint32          pdu_length;
5879   guint32          pdu_flvh_length; /* flags, length, vector, header */
5880   guint32          data_offset;
5881   guint32          end_offset;
5882 
5883   proto_item      *ti, *pi;
5884   proto_tree      *flag_tree;
5885   proto_tree      *pdu_tree;
5886 
5887   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_rdmnet_llrp_probe_request_pdu, 0);
5888 
5889   /* Add PDU Length item */
5890   proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_probe_request_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5891 
5892   dissect_pdu_bit_flag_v(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 2);
5893   /* offset should now be pointing to header (if one exists) */
5894 
5895   /* add vector item  */
5896   vector = tvb_get_guint8(tvb, data_offset);
5897   proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_probe_request_vector, tvb, data_offset, 1, vector);
5898 
5899   dissect_pdu_bit_flag_h(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 6);
5900   data_offset -= 1;
5901   /* offset should now be pointing to data (if one exists) */
5902 
5903   /* lower uid */
5904   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_probe_request_lower_uid, tvb, data_offset, 6, ENC_NA);
5905   data_offset += 6;
5906 
5907   /* upper uid */
5908   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_probe_request_upper_uid, tvb, data_offset, 6, ENC_NA);
5909   data_offset += 6;
5910 
5911   /* filter */
5912   filter_flags = tvb_get_guint8(tvb, data_offset);
5913   filter_flags = filter_flags & 0x03;
5914   pi = proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_probe_request_filter, tvb, data_offset, 1, filter_flags);
5915   flag_tree = proto_item_add_subtree(pi, ett_rdmnet_llrp_probe_request_filter_flags);
5916   proto_tree_add_item(flag_tree, hf_rdmnet_llrp_probe_request_filter_brokers_only, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5917   proto_tree_add_item(flag_tree, hf_rdmnet_llrp_probe_request_filter_client_tcp_inactive, tvb, data_offset, 2, ENC_BIG_ENDIAN);
5918   data_offset += 2;
5919 
5920   /* known uids */
5921   end_offset = pdu_start + pdu_length;
5922   while (data_offset + 6 <= end_offset) {
5923     proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_probe_request_known_uid, tvb, data_offset, 6, ENC_NA);
5924     data_offset += 6;
5925   }
5926 
5927   return pdu_start + pdu_length;
5928 }
5929 
5930 
5931 /******************************************************************************/
5932 /* Dissect LLRP Probe Reply PDU                                             */
5933 static guint32
dissect_llrp_probe_reply_pdu(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)5934 dissect_llrp_probe_reply_pdu(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
5935 {
5936   /* common to all pdu */
5937   guint8           pdu_flags;
5938   guint8           vector;
5939   guint32          pdu_start;
5940   guint32          pdu_length;
5941   guint32          pdu_flvh_length; /* flags, length, vector, header */
5942   guint32          data_offset;
5943 
5944   proto_item      *ti;
5945   proto_tree      *pdu_tree;
5946 
5947   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_rdmnet_llrp_probe_reply_pdu, 0);
5948 
5949   /* Add PDU Length item */
5950   proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_probe_request_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
5951 
5952   dissect_pdu_bit_flag_v(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 2);
5953   /* offset should now be pointing to header (if one exists) */
5954 
5955   /* add vector item  */
5956   vector = tvb_get_guint8(tvb, data_offset);
5957   proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_probe_reply_vector, tvb, data_offset, 1, vector);
5958 
5959   dissect_pdu_bit_flag_h(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 6);
5960   data_offset -= 1;
5961   /* offset should now be pointing to data (if one exists) */
5962 
5963   /* uid */
5964   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_probe_reply_uid, tvb, data_offset, 6, ENC_NA);
5965   data_offset += 6;
5966 
5967   /* hardware address */
5968   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_probe_reply_hardware_address, tvb, data_offset, 6, ENC_NA);
5969   data_offset += 6;
5970 
5971   /* component type */
5972   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_probe_reply_component_type, tvb, data_offset, 1, ENC_BIG_ENDIAN);
5973 
5974   return pdu_start + pdu_length;
5975 }
5976 
5977 
5978 /******************************************************************************/
5979 /* Dissect RDM Command                                                        */
5980 static guint32
dissect_rdm_command(tvbuff_t * tvb,packet_info * pinfo,proto_tree * pdu_tree,guint32 data_offset,guint32 length)5981 dissect_rdm_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdu_tree, guint32 data_offset, guint32 length)
5982 {
5983   gboolean         save_info;
5984   gboolean         save_protocol;
5985   guint32          data_end;
5986   tvbuff_t        *next_tvb;
5987 
5988   save_info     = col_get_writable(pinfo->cinfo, COL_INFO);
5989   save_protocol = col_get_writable(pinfo->cinfo, COL_PROTOCOL);
5990   col_set_writable(pinfo->cinfo, COL_INFO, FALSE);
5991   col_set_writable(pinfo->cinfo, COL_PROTOCOL, FALSE);
5992 
5993   data_end = data_offset + length;
5994   next_tvb = tvb_new_subset_length(tvb, data_offset, length);
5995   call_dissector(rdm_handle, next_tvb, pinfo, pdu_tree);
5996 
5997   col_set_writable(pinfo->cinfo, COL_INFO, save_info);
5998   col_set_writable(pinfo->cinfo, COL_PROTOCOL, save_protocol);
5999 
6000   return data_end;
6001 }
6002 
6003 
6004 /******************************************************************************/
6005 /* Dissect LLRP RDM Command PDU                                               */
6006 static guint32
dissect_llrp_rdm_command_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6007 dissect_llrp_rdm_command_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6008 {
6009   /* common to all pdu */
6010   guint8           pdu_flags;
6011   guint8           vector;
6012   guint32          pdu_start;
6013   guint32          pdu_length;
6014   guint32          pdu_end;
6015   guint32          pdu_flvh_length; /* flags, length, vector, header */
6016   guint32          data_offset;
6017 
6018   proto_item      *ti;
6019   proto_tree      *pdu_tree;
6020 
6021   /* this pdu */
6022   const gchar     *name;
6023 
6024   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_rdmnet_llrp_rdm_command_pdu, 0);
6025 
6026   /* Add PDU Length item */
6027   proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_probe_request_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
6028 
6029   dissect_pdu_bit_flag_v(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 2);
6030   /* offset should now be pointing to header (if one exists) */
6031 
6032   /* add vector item  */
6033   vector = tvb_get_guint8(tvb, data_offset);
6034   proto_tree_add_uint(pdu_tree, hf_rdmnet_llrp_rdm_command_start_code, tvb, data_offset, 1, vector);
6035 
6036   /* Add Vector item to tree */
6037   name = val_to_str(vector, rdmnet_llrp_rdm_command_start_code_vals, "unknown (%d)");
6038   proto_item_append_text(ti, ": %s", name);
6039 
6040   dissect_pdu_bit_flag_h(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 6);
6041   data_offset -= 1;
6042   /* offset should now be pointing to data (if one exists) */
6043 
6044   pdu_end = pdu_start + pdu_length;
6045   dissect_rdm_command(tvb, pinfo, pdu_tree, data_offset, (pdu_length-4));
6046 
6047   return pdu_end;
6048 }
6049 
6050 
6051 /******************************************************************************/
6052 /* Dissect LLRP Base PDU                                                      */
6053 static guint32
dissect_acn_llrp_base_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6054 dissect_acn_llrp_base_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6055 {
6056   guint8           pdu_flags;
6057   guint32          pdu_start;
6058   guint32          pdu_length;
6059   guint32          pdu_flvh_length; /* flags, length, vector, header */
6060   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
6061   guint32          vector_offset;
6062   guint32          data_offset;
6063   guint32          data_length;
6064   e_guid_t         guid;
6065 
6066   proto_item      *ti;
6067   proto_tree      *pdu_tree;
6068 
6069   /* this pdu */
6070   const gchar     *name;
6071   guint32          vector;
6072 
6073   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_llrp_base_pdu, 1, 0);
6074 
6075   /* Add Vector item */
6076   vector = tvb_get_ntohl(tvb, vector_offset);
6077   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
6078 
6079   /* Add Vector item to tree */
6080   name = val_to_str(vector, rdmnet_llrp_vector_vals, "unknown (%d)");
6081   proto_item_append_text(ti, ": %s", name);
6082 
6083   /* NO HEADER DATA ON THESE* (at least so far) */
6084 
6085   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6086   data_offset += 3;
6087 
6088   /* get destination (CID) 16 bytes */
6089   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_destination_cid, tvb, data_offset, 16, ENC_BIG_ENDIAN);
6090   tvb_get_guid(tvb, data_offset, &guid, ENC_BIG_ENDIAN);
6091   proto_item_append_text(ti, ", Dest: %s", guid_to_str(pinfo->pool, &guid));
6092   data_offset += 16;
6093 
6094   /* transaction number (4 bytes) */
6095   proto_tree_add_item(pdu_tree, hf_rdmnet_llrp_transaction_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
6096   data_offset += 4;
6097 
6098   /* process based on vector */
6099   switch (vector) {
6100     case RDMNET_LLRP_VECTOR_PROBE_REQUEST:
6101       dissect_llrp_probe_request_pdu(tvb, pdu_tree, data_offset, &pdu_offsets);
6102       break;
6103     case RDMNET_LLRP_VECTOR_PROBE_REPLY:
6104       dissect_llrp_probe_reply_pdu(tvb, pdu_tree, data_offset, &pdu_offsets);
6105       break;
6106     case RDMNET_LLRP_VECTOR_RDM_CMD:
6107       dissect_llrp_rdm_command_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
6108       break;
6109   }
6110 
6111   return pdu_start + pdu_length;
6112 }
6113 
6114 
6115 /******************************************************************************/
6116 /* Dissect Broker Client Entry PDU                                            */
6117 static guint32
dissect_broker_client_entry_pdu(tvbuff_t * tvb,proto_tree * tree,guint32 offset,acn_pdu_offsets * last_pdu_offsets)6118 dissect_broker_client_entry_pdu(tvbuff_t *tvb, proto_tree *tree, guint32 offset, acn_pdu_offsets *last_pdu_offsets)
6119 {
6120   guint8           pdu_flags;
6121   guint32          pdu_start;
6122   guint32          pdu_length;
6123   guint32          pdu_end;
6124   guint32          pdu_flvh_length; /* flags, length, vector, header */
6125   guint32          vector_offset;
6126   guint32          data_offset;
6127   guint32          data_length;
6128 
6129   proto_item      *ti;
6130   proto_item      *ti2;
6131   proto_tree      *pdu_tree;
6132   proto_tree      *pdu_tree2;
6133 
6134   /* this pdu */
6135   const gchar     *name;
6136   guint32          vector;
6137 
6138   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_broker_client_entry_pdu, 1, 0);
6139   pdu_end = pdu_start + pdu_length;
6140 
6141   /* Add Vector item */
6142   vector = tvb_get_ntohl(tvb, vector_offset);
6143   proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_protocol_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
6144 
6145   /* Add Vector item to tree */
6146   name = val_to_str(vector, broker_client_protocol_vals, "unknown (%d)");
6147   proto_item_append_text(ti, ": %s", name);
6148 
6149   /* NO HEADER DATA ON THESE* (at least so far) */
6150 
6151   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6152   data_offset += 3;
6153 
6154   /* client protocol cid */
6155   proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_protocol_cid, tvb, data_offset, 16, ENC_NA);
6156   data_offset += 16;
6157 
6158   /* process based on vector */
6159   switch (vector) {
6160   case RDMNET_CLIENT_PROTOCOL_RPT:
6161     /* client uid */
6162     proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_rpt_client_uid, tvb, data_offset, 6, ENC_NA);
6163     data_offset += 6;
6164 
6165     /* client type */
6166     proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_rpt_client_type, tvb, data_offset, 1, ENC_BIG_ENDIAN);
6167     data_offset += 1;
6168 
6169     /* binding cid */
6170     proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_rpt_binding_cid, tvb, data_offset, 16, ENC_NA);
6171     data_offset += 16;
6172     break;
6173   case RDMNET_CLIENT_PROTOCOL_EPT:
6174     while (offset + 36 < pdu_end) {
6175       /* protocol vector (manufacturer id + protocol id) */
6176       ti2 = proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_ept_protocol_vector, tvb, data_offset, 4, ENC_NA);
6177       pdu_tree2 = proto_item_add_subtree(ti2, ett_rdmnet_broker_client_entry_manufacturer_protocol_ids);
6178       proto_tree_add_item(pdu_tree2, hf_rdmnet_broker_client_ept_protocol_manufacturer_id, tvb, 0, 2, ENC_BIG_ENDIAN);
6179       proto_tree_add_item(pdu_tree2, hf_rdmnet_broker_client_ept_protocol_protocol_id, tvb, 2, 2, ENC_BIG_ENDIAN);
6180       offset += 4;
6181 
6182       /* protocol string */
6183       proto_tree_add_item(pdu_tree, hf_rdmnet_broker_client_ept_protocol_string, tvb, data_offset, 32, ENC_ASCII|ENC_NA);
6184       data_offset += 32;
6185     }
6186     break;
6187   }
6188 
6189   return pdu_end;
6190 }
6191 
6192 
6193 /******************************************************************************/
6194 /* Dissect Broker Connect                                                     */
6195 static guint32
dissect_broker_connect(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets,guint32 pdu_end)6196 dissect_broker_connect(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets, guint32 pdu_end)
6197 {
6198   guint8           connection_flags;
6199   proto_item      *pi;
6200   proto_tree      *flag_tree;
6201 
6202   /* client scope */
6203   proto_tree_add_item(tree, hf_rdmnet_broker_connect_client_scope, tvb, offset, 63, ENC_ASCII|ENC_NA);
6204   offset += 63;
6205 
6206   /* e133 version */
6207   proto_tree_add_item(tree, hf_rdmnet_broker_connect_e133_version, tvb, offset, 2, ENC_BIG_ENDIAN);
6208   offset += 2;
6209 
6210   /* search domain */
6211   proto_tree_add_item(tree, hf_rdmnet_broker_connect_search_domain, tvb, offset, 231, ENC_ASCII|ENC_NA);
6212   offset += 231;
6213 
6214   /* connection flags */
6215   connection_flags = tvb_get_guint8(tvb, offset);
6216   connection_flags = connection_flags & 0x01;
6217   pi = proto_tree_add_uint(tree, hf_rdmnet_broker_connect_connection_flags, tvb, offset, 1, connection_flags);
6218   flag_tree = proto_item_add_subtree(pi, ett_rdmnet_broker_connect_connection_flags);
6219   proto_tree_add_item(flag_tree, hf_rdmnet_broker_connect_connection_flags_incremental_updates, tvb, offset, 1, ENC_BIG_ENDIAN);
6220   offset += 1;
6221 
6222   /* client_entry_pdu */
6223   dissect_broker_client_entry_pdu(tvb, tree, offset, last_pdu_offsets);
6224 
6225   return pdu_end;
6226 }
6227 
6228 
6229 /******************************************************************************/
6230 /* Dissect Broker Connect Reply                                               */
6231 static guint32
dissect_broker_connect_reply(tvbuff_t * tvb,proto_tree * tree,int offset)6232 dissect_broker_connect_reply(tvbuff_t *tvb, proto_tree *tree, int offset)
6233 {
6234   /* connection code */
6235   proto_tree_add_item(tree, hf_rdmnet_broker_connect_reply_connection_code, tvb, offset, 2, ENC_BIG_ENDIAN);
6236   offset += 2;
6237 
6238   /* e133 version */
6239   proto_tree_add_item(tree, hf_rdmnet_broker_connect_reply_e133_version, tvb, offset, 2, ENC_BIG_ENDIAN);
6240   offset += 2;
6241 
6242   /* broker uid */
6243   proto_tree_add_item(tree, hf_rdmnet_broker_connect_reply_broker_uid, tvb, offset, 6, ENC_NA);
6244   offset += 6;
6245 
6246   /* client uid */
6247   proto_tree_add_item(tree, hf_rdmnet_broker_connect_reply_client_uid, tvb, offset, 6, ENC_NA);
6248 
6249   return 0;
6250 }
6251 
6252 
6253 /******************************************************************************/
6254 /* Dissect Broker Client Entry Update                                         */
6255 static guint32
dissect_broker_client_entry_update(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets,guint32 pdu_end)6256 dissect_broker_client_entry_update(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets, guint32 pdu_end)
6257 {
6258   guint8           connection_flags;
6259 
6260   proto_item      *pi;
6261   proto_tree      *flag_tree;
6262 
6263   /* connection flags */
6264   connection_flags = tvb_get_guint8(tvb, offset);
6265   connection_flags = connection_flags & 0x01;
6266   pi = proto_tree_add_uint(tree, hf_rdmnet_broker_client_entry_update_connection_flags, tvb, offset, 1, connection_flags);
6267   flag_tree = proto_item_add_subtree(pi, ett_rdmnet_broker_client_entry_update_connection_flags);
6268   proto_tree_add_item(flag_tree, hf_rdmnet_broker_client_entry_update_connection_flags_incremental_updates, tvb, offset, 1, ENC_BIG_ENDIAN);
6269   offset += 1;
6270 
6271   /* client_entry_pdu */
6272   dissect_broker_client_entry_pdu(tvb, tree, offset, last_pdu_offsets);
6273 
6274   return pdu_end;
6275 }
6276 
6277 
6278 /******************************************************************************/
6279 /* Dissect Broker Redirect V4                                                 */
6280 static guint32
dissect_broker_redirect_v4(tvbuff_t * tvb,proto_tree * tree,int offset)6281 dissect_broker_redirect_v4(tvbuff_t *tvb, proto_tree *tree, int offset)
6282 {
6283   /* ipv4 address */
6284   proto_tree_add_item(tree, hf_rdmnet_broker_redirect_ipv4_address, tvb, offset, 4, ENC_BIG_ENDIAN);
6285   offset += 4;
6286 
6287   /* tcp port */
6288   proto_tree_add_item(tree, hf_rdmnet_broker_redirect_ipv4_tcp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
6289 
6290   return 0;
6291 }
6292 
6293 
6294 /******************************************************************************/
6295 /* Dissect Broker Redirect V6                                                 */
6296 static guint32
dissect_broker_redirect_v6(tvbuff_t * tvb,proto_tree * tree,int offset)6297 dissect_broker_redirect_v6(tvbuff_t *tvb, proto_tree *tree, int offset)
6298 {
6299   /* ipv4 address */
6300   proto_tree_add_item(tree, hf_rdmnet_broker_redirect_ipv6_address, tvb, offset, 16, ENC_NA);
6301   offset += 16;
6302 
6303   /* tcp port */
6304   proto_tree_add_item(tree, hf_rdmnet_broker_redirect_ipv6_tcp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
6305 
6306   return 0;
6307 }
6308 
6309 
6310 /******************************************************************************/
6311 /* Dissect Broker Disconnect                                                  */
6312 static guint32
dissect_broker_disconnect(tvbuff_t * tvb,proto_tree * tree,int offset)6313 dissect_broker_disconnect(tvbuff_t *tvb, proto_tree *tree, int offset)
6314 {
6315   /* disconnect reason */
6316   proto_tree_add_item(tree, hf_rdmnet_broker_disconnect_reason, tvb, offset, 2, ENC_BIG_ENDIAN);
6317 
6318   return 0;
6319 }
6320 
6321 
6322 /******************************************************************************/
6323 /* Dissect Broker Request Dynamic UIDs                                        */
6324 static guint32
dissect_broker_request_dynamic_uids(tvbuff_t * tvb,proto_tree * tree,guint32 offset,guint32 pdu_end)6325 dissect_broker_request_dynamic_uids(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 pdu_end)
6326 {
6327   /* packed list of dynamic uid request (6 bytes) and rid (16 bytes) */
6328   while (offset + 22 < pdu_end) {
6329     /* dynamic uid request (6 bytes) */
6330     proto_tree_add_item(tree, hf_rdmnet_broker_dynamic_uid_request, tvb, offset, 6, ENC_NA);
6331     offset += 6;
6332 
6333     /* rid (16 bytes) */
6334     proto_tree_add_item(tree, hf_rdmnet_broker_rid, tvb, offset, 16, ENC_NA);
6335     offset += 16;
6336   }
6337 
6338   return 0;
6339 }
6340 
6341 
6342 /******************************************************************************/
6343 /* Dissect Broker Assigned Dynamic UIDs                                       */
6344 static guint32
dissect_broker_assigned_dynamic_uids(tvbuff_t * tvb,proto_tree * tree,guint32 offset,guint32 pdu_end)6345 dissect_broker_assigned_dynamic_uids(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 pdu_end)
6346 {
6347   /* packed list of dynamic uid request (6 bytes), rid (16 bytes), and status_code (2 bytes) */
6348   while (offset + 24 < pdu_end) {
6349     /* dynamic uid request (6 bytes) */
6350     proto_tree_add_item(tree, hf_rdmnet_broker_assigned_dynamic_uid, tvb, offset, 6, ENC_NA);
6351     offset += 6;
6352 
6353     /* rid (16 bytes) */
6354     proto_tree_add_item(tree, hf_rdmnet_broker_assigned_rid, tvb, offset, 16, ENC_NA);
6355     offset += 16;
6356 
6357     /* status code (2 bytes) */
6358     proto_tree_add_item(tree, hf_rdmnet_broker_assigned_status_code, tvb, offset, 2, ENC_NA);
6359     offset += 2;
6360   }
6361 
6362   return 0;
6363 }
6364 
6365 
6366 /******************************************************************************/
6367 /* Dissect Broker Fetch Dynamic UIDs                                       */
6368 static guint32
dissect_broker_fetch_dynamic_uids(tvbuff_t * tvb,proto_tree * tree,guint32 offset,guint32 pdu_end)6369 dissect_broker_fetch_dynamic_uids(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 pdu_end)
6370 {
6371   /* packed list of dynamic uid request (6 bytes) */
6372   while (offset + 6 < pdu_end) {
6373     /* dynamic uid request (6 bytes) */
6374     proto_tree_add_item(tree, hf_rdmnet_broker_fetch_dynamic_uid, tvb, offset, 6, ENC_NA);
6375     offset += 6;
6376   }
6377 
6378   return 0;
6379 }
6380 
6381 
6382 /******************************************************************************/
6383 /* Dissect Broker Base PDU                                                    */
6384 static guint32
dissect_acn_broker_base_pdu(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6385 dissect_acn_broker_base_pdu(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6386 {
6387   guint8           pdu_flags;
6388   guint32          pdu_start;
6389   guint32          pdu_length;
6390   guint32          pdu_end;
6391   guint32          pdu_flvh_length; /* flags, length, vector, header */
6392   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
6393   guint32          vector_offset;
6394   guint32          data_offset;
6395   guint32          old_offset;
6396   guint32          end_offset;
6397   guint32          data_length;
6398 
6399   proto_item      *ti;
6400   proto_tree      *pdu_tree;
6401 
6402   /* this pdu */
6403   const gchar     *name;
6404   guint16          vector;
6405 
6406   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_broker_base_pdu, 1, 0);
6407   pdu_end = pdu_start + pdu_length;
6408 
6409   /* Add Vector item */
6410   vector = tvb_get_ntohs(tvb, vector_offset);
6411   proto_tree_add_item(pdu_tree, hf_rdmnet_broker_vector, tvb, vector_offset, 2, ENC_BIG_ENDIAN);
6412 
6413   /* Add Vector item to tree */
6414   name = val_to_str(vector, rdmnet_broker_vector_vals, "unknown (%d)");
6415   proto_item_append_text(ti, ": %s", name);
6416 
6417   /* NO HEADER DATA ON THESE* (at least so far) */
6418 
6419   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6420   data_offset += 1;
6421 
6422   /* process based on vector */
6423   switch (vector) {
6424   case RDMNET_BROKER_VECTOR_FETCH_CLIENT_LIST:
6425   case RDMNET_BROKER_VECTOR_NULL:
6426     /* no data */
6427     break;
6428   case RDMNET_BROKER_VECTOR_CONNECTED_CLIENT_LIST:
6429   case RDMNET_BROKER_VECTOR_CLIENT_ADD:
6430   case RDMNET_BROKER_VECTOR_CLIENT_REMOVE:
6431   case RDMNET_BROKER_VECTOR_CLIENT_ENTRY_CHANGE:
6432     end_offset = pdu_start + pdu_length;
6433     while (data_offset < end_offset) {
6434       old_offset = data_offset;
6435       data_offset = dissect_broker_client_entry_pdu(tvb, pdu_tree, data_offset, &pdu_offsets);
6436       if (data_offset == old_offset) break;
6437     }
6438     break;
6439   case RDMNET_BROKER_VECTOR_CONNECT:
6440     dissect_broker_connect(tvb, pdu_tree, data_offset, &pdu_offsets, pdu_end);
6441     break;
6442   case RDMNET_BROKER_VECTOR_CONNECT_REPLY:
6443     dissect_broker_connect_reply(tvb, pdu_tree, data_offset);
6444     break;
6445   case RDMNET_BROKER_VECTOR_CLIENT_ENTRY_UPDATE:
6446     dissect_broker_client_entry_update(tvb, pdu_tree, data_offset, &pdu_offsets, pdu_end);
6447     break;
6448   case RDMNET_BROKER_VECTOR_REDIRECT_V4:
6449     dissect_broker_redirect_v4(tvb, pdu_tree, data_offset);
6450     break;
6451   case RDMNET_BROKER_VECTOR_REDIRECT_V6:
6452     dissect_broker_redirect_v6(tvb, pdu_tree, data_offset);
6453     break;
6454   case RDMNET_BROKER_VECTOR_DISCONNECT:
6455     dissect_broker_disconnect(tvb, pdu_tree, data_offset);
6456     break;
6457   case RDMNET_BROKER_VECTOR_REQUEST_DYNAMIC_UIDS:
6458     dissect_broker_request_dynamic_uids(tvb, pdu_tree, data_offset, pdu_end);
6459     break;
6460   case RDMNET_BROKER_VECTOR_ASSIGNED_DYNAMIC_UIDS:
6461     dissect_broker_assigned_dynamic_uids(tvb, pdu_tree, data_offset, pdu_end);
6462     break;
6463   case RDMNET_BROKER_VECTOR_FETCH_DYNAMIC_UID_LIST:
6464     dissect_broker_fetch_dynamic_uids(tvb, pdu_tree, data_offset, pdu_end);
6465     break;
6466   }
6467 
6468   return pdu_start + pdu_length;
6469 }
6470 
6471 
6472 /******************************************************************************/
6473 /* Dissect RPT Request RDM Command                                            */
6474 static guint32
dissect_rpt_request_rdm_command(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6475 dissect_rpt_request_rdm_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6476 {
6477   guint8           pdu_flags;
6478   guint32          pdu_start;
6479   guint32          pdu_length;
6480   guint32          pdu_end;
6481   guint32          pdu_flvh_length; /* flags, length, vector, header */
6482   guint32          vector_offset;
6483   guint32          data_offset;
6484   guint32          data_length;
6485 
6486   proto_item      *ti;
6487   proto_tree      *pdu_tree;
6488 
6489   /* this pdu */
6490   const gchar     *name;
6491   guint8           vector;
6492 
6493   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_rpt_request_pdu, 1, 0);
6494 
6495   /* Add Vector item */
6496   vector = tvb_get_guint8(tvb, vector_offset);
6497   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_request_rdm_command, tvb, vector_offset, 1, ENC_BIG_ENDIAN);
6498 
6499   /* Add Vector item to tree */
6500   name = val_to_str(vector, rdmnet_rpt_request_rdm_command_start_code_vals, "unknown (%d)");
6501   proto_item_append_text(ti, ": %s", name);
6502 
6503   /* NO HEADER DATA ON THESE* (at least so far) */
6504 
6505   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6506   /* data_offset += 3; */
6507 
6508   pdu_end = pdu_start + pdu_length;
6509   dissect_rdm_command(tvb, pinfo, pdu_tree, data_offset, (pdu_length-4));
6510 
6511   return pdu_end;
6512 }
6513 
6514 
6515 /******************************************************************************/
6516 /* Dissect RPT Request                                                        */
6517 static guint32
dissect_rpt_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6518 dissect_rpt_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6519 {
6520   guint8           pdu_flags;
6521   guint32          pdu_start;
6522   guint32          pdu_length;
6523   guint32          pdu_flvh_length; /* flags, length, vector, header */
6524   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
6525   guint32          vector_offset;
6526   guint32          data_offset;
6527   guint32          data_length;
6528 
6529   proto_item      *ti;
6530   proto_tree      *pdu_tree;
6531 
6532   /* this pdu */
6533   const gchar     *name;
6534   guint32          vector;
6535 
6536   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_rpt_request_pdu, 1, 0);
6537 
6538   /* Add Vector item */
6539   vector = tvb_get_ntohl(tvb, vector_offset);
6540   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_request_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
6541 
6542   /* Add Vector item to tree */
6543   name = val_to_str(vector, rdmnet_rpt_request_vals, "unknown (%d)");
6544   proto_item_append_text(ti, ": %s", name);
6545 
6546   /* NO HEADER DATA ON THESE* (at least so far) */
6547 
6548   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6549   data_offset += 3;
6550 
6551   /* rdm command */
6552   dissect_rpt_request_rdm_command(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
6553 
6554   return 0;
6555 }
6556 
6557 
6558 /******************************************************************************/
6559 /* Dissect RPT Status                                                         */
6560 static guint32
dissect_rpt_status(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6561 dissect_rpt_status(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6562 {
6563   guint8           pdu_flags;
6564   guint32          pdu_start;
6565   guint32          pdu_length;
6566   guint32          pdu_end;
6567   guint32          pdu_flvh_length; /* flags, length, vector, header */
6568   guint32          vector_offset;
6569   guint32          data_offset;
6570   guint32          data_length;
6571 
6572   proto_item      *ti;
6573   proto_tree      *pdu_tree;
6574 
6575   /* this pdu */
6576   const gchar     *name;
6577   guint16          vector;
6578 
6579   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_rpt_status_pdu, 1, 0);
6580 
6581   /* Add Vector item */
6582   vector = tvb_get_ntohs(tvb, vector_offset);
6583   proto_item_append_text(ti, ", vector = %u", vector);
6584   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_vector, tvb, vector_offset, 2, ENC_BIG_ENDIAN);
6585 
6586   /* Add Vector item to tree */
6587   name = val_to_str(vector, rdmnet_rpt_status_vector_vals, "unknown (%d)");
6588   proto_item_append_text(ti, ": %s", name);
6589 
6590   /* NO HEADER DATA ON THESE* (at least so far) */
6591 
6592   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6593   data_offset += 3;
6594 
6595   pdu_end = pdu_start + pdu_length;
6596   switch (vector) {
6597   case RDMNET_RPT_VECTOR_STATUS_UNKNOWN_RPT_UID:
6598     if (pdu_end > data_offset) {
6599       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_unknown_rpt_uid_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6600     }
6601     break;
6602   case RDMNET_RPT_VECTOR_STATUS_RDM_TIMEOUT:
6603     if (pdu_end > data_offset) {
6604       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_rdm_timeout_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6605     }
6606     break;
6607   case RDMNET_RPT_VECTOR_STATUS_RDM_INVALID_RESPONSE:
6608     if (pdu_end > data_offset) {
6609       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_rdm_invalid_response_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6610     }
6611     break;
6612   case RDMNET_RPT_VECTOR_STATUS_UNKNOWN_RDM_UID:
6613     if (pdu_end > data_offset) {
6614       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_unknown_rdm_uid_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6615     }
6616     break;
6617   case RDMNET_RPT_VECTOR_STATUS_UNKNOWN_ENDPOINT:
6618     if (pdu_end > data_offset) {
6619       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_unknown_endpoint_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6620     }
6621     break;
6622   case RDMNET_RPT_VECTOR_STATUS_BROADCAST_COMPLETE:
6623     if (pdu_end > data_offset) {
6624       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_broadcast_complete_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6625     }
6626     break;
6627   case RDMNET_RPT_VECTOR_STATUS_UNKNOWN_VECTOR:
6628     if (pdu_end > data_offset) {
6629       proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_status_unknown_vector_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6630     }
6631     break;
6632   case RDMNET_RPT_VECTOR_STATUS_INVALID_MESSAGE:
6633   case RDMNET_RPT_VECTOR_STATUS_INVALID_COMMAND_CLASS:
6634     /* no data */
6635     break;
6636   }
6637 
6638   return pdu_start + pdu_length;
6639 }
6640 
6641 
6642 /******************************************************************************/
6643 /* Dissect RPT Notification RDM Command                                       */
6644 static guint32
dissect_rpt_notification_rdm_command(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6645 dissect_rpt_notification_rdm_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6646 {
6647   guint8           pdu_flags;
6648   guint32          pdu_start;
6649   guint32          pdu_length;
6650   guint32          pdu_end;
6651   guint32          pdu_flvh_length; /* flags, length, vector, header */
6652   guint32          vector_offset;
6653   guint32          data_offset;
6654   guint32          data_length;
6655 
6656   proto_item      *ti;
6657   proto_tree      *pdu_tree;
6658 
6659   /* this pdu */
6660   const gchar     *name;
6661   guint8           vector;
6662 
6663   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_rpt_request_pdu, 1, 0);
6664 
6665   /* Add Vector item */
6666   vector = tvb_get_guint8(tvb, vector_offset);
6667   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_notification_rdm_command, tvb, vector_offset, 1, ENC_BIG_ENDIAN);
6668 
6669   /* Add Vector item to tree */
6670   name = val_to_str(vector, rdmnet_rpt_request_rdm_command_start_code_vals, "unknown (%d)");
6671   proto_item_append_text(ti, ": %s", name);
6672 
6673   /* NO HEADER DATA ON THESE* (at least so far) */
6674 
6675   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6676   /* data_offset += 3; */
6677 
6678   pdu_end = pdu_start + pdu_length;
6679   dissect_rdm_command(tvb, pinfo, pdu_tree, data_offset, (pdu_length-4));
6680 
6681   return pdu_end;
6682 }
6683 
6684 
6685 /******************************************************************************/
6686 /* Dissect RPT Notification                                                   */
6687 static guint32
dissect_rpt_notification(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6688 dissect_rpt_notification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6689 {
6690   guint8           pdu_flags;
6691   guint32          pdu_start;
6692   guint32          pdu_length;
6693   guint32          pdu_end;
6694   guint32          pdu_flvh_length; /* flags, length, vector, header */
6695   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
6696   guint32          vector_offset;
6697   guint32          data_offset;
6698   guint32          data_length;
6699   guint32          old_offset;
6700 
6701   proto_item      *ti;
6702   proto_tree      *pdu_tree;
6703 
6704   /* this pdu */
6705   const gchar     *name;
6706   guint32          vector;
6707 
6708   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_rpt_notification_pdu, 1, 0);
6709 
6710   /* Add Vector item */
6711   vector = tvb_get_ntohl(tvb, vector_offset);
6712   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_notification_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
6713 
6714   /* Add Vector item to tree  "RDM Command" */
6715   name = val_to_str(vector, rdmnet_rpt_notification_vals, "unknown (%d)");
6716   proto_item_append_text(ti, ": %s", name);
6717 
6718   /* NO HEADER DATA ON THESE* (at least so far) */
6719 
6720   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6721   data_offset += 3;
6722 
6723   /* rdm command */
6724   pdu_end = pdu_start + pdu_length;
6725   while (data_offset < pdu_end) {
6726     old_offset = data_offset;
6727     data_offset = dissect_rpt_notification_rdm_command(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
6728     if (data_offset == old_offset) break;
6729   }
6730 
6731   return pdu_end;
6732 }
6733 
6734 
6735 /******************************************************************************/
6736 /* Dissect RPT Base PDU                                                       */
6737 static guint32
dissect_acn_rpt_base_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6738 dissect_acn_rpt_base_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6739 {
6740   guint8           pdu_flags;
6741   guint32          pdu_start;
6742   guint32          pdu_length;
6743   guint32          pdu_flvh_length; /* flags, length, vector, header */
6744   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
6745   guint32          vector_offset;
6746   guint32          data_offset;
6747   guint32          data_length;
6748 
6749   proto_item      *ti;
6750   proto_tree      *pdu_tree;
6751 
6752   /* this pdu */
6753   const gchar     *name;
6754   guint32          vector;
6755 
6756   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_rpt_base_pdu, 1, 0);
6757 
6758   /* Add Vector item */
6759   vector = tvb_get_ntohl(tvb, vector_offset);
6760   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
6761 
6762   /* Add Vector item to tree */
6763   name = val_to_str(vector, rdmnet_rpt_vector_vals, "unknown (%d)");
6764   proto_item_append_text(ti, ": %s", name);
6765 
6766   /* NO HEADER DATA ON THESE* (at least so far) */
6767 
6768   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6769   data_offset += 3;
6770 
6771   /* source uid (6 bytes) */
6772   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_source_uid, tvb, data_offset, 6, ENC_NA);
6773   data_offset += 6;
6774 
6775   /* source endpoint id (2 bytes) */
6776   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_source_endpoint_id, tvb, data_offset, 2, ENC_BIG_ENDIAN);
6777   data_offset += 2;
6778 
6779   /* destination uid (6 bytes) */
6780   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_destination_uid, tvb, data_offset, 6, ENC_NA);
6781   data_offset += 6;
6782 
6783   /* destination endpoint id (2 bytes) */
6784   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_destination_endpoint_id, tvb, data_offset, 2, ENC_BIG_ENDIAN);
6785   data_offset += 2;
6786 
6787   /* sequence number (4 bytes) */
6788   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_sequence_number, tvb, data_offset, 4, ENC_BIG_ENDIAN);
6789   data_offset += 4;
6790 
6791   /* reserved (1 byte) */
6792   proto_tree_add_item(pdu_tree, hf_rdmnet_rpt_reserved, tvb, data_offset, 1, ENC_BIG_ENDIAN);
6793   data_offset += 1;
6794 
6795   /* process based on vector */
6796   switch (vector) {
6797   case RDMNET_RPT_VECTOR_REQUEST:
6798     dissect_rpt_request(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
6799     break;
6800   case RDMNET_RPT_VECTOR_STATUS:
6801     dissect_rpt_status(tvb, pdu_tree, data_offset, &pdu_offsets);
6802     break;
6803   case RDMNET_RPT_VECTOR_NOTIFICATION:
6804     dissect_rpt_notification(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
6805     break;
6806   }
6807 
6808   return pdu_start + pdu_length;
6809 }
6810 
6811 
6812 /******************************************************************************/
6813 /* Dissect EPT Data                                                           */
6814 static guint32
dissect_ept_data(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6815 dissect_ept_data(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6816 {
6817   guint8           pdu_flags;
6818   guint32          pdu_start;
6819   guint32          pdu_length;
6820   guint32          pdu_end;
6821   guint32          pdu_flvh_length; /* flags, length, vector, header */
6822   guint32          vector_offset;
6823   guint32          data_offset;
6824 
6825   proto_item      *ti;
6826   proto_item      *ti2;
6827   proto_tree      *pdu_tree;
6828   proto_tree      *pdu_tree2;
6829 
6830   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_ept_data_pdu, 1, 0);
6831 
6832   /* Add PDU Length item */
6833   proto_tree_add_uint(pdu_tree, hf_rdmnet_ept_data_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
6834 
6835   dissect_pdu_bit_flag_v(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 2);
6836   /* offset should now be pointing to header (if one exists) */
6837 
6838   /* esta manufacturer id + protocol id (4 bytes) */
6839   ti2 = proto_tree_add_item(pdu_tree, hf_rdmnet_ept_data_vector, tvb, data_offset, 4, ENC_BIG_ENDIAN);
6840   pdu_tree2 = proto_item_add_subtree(ti2, ett_rdmnet_ept_data_vector_pdu);
6841   proto_tree_add_item(pdu_tree2, hf_rdmnet_ept_data_vector_manufacturer_id, tvb, 0, 2, ENC_BIG_ENDIAN);
6842   proto_tree_add_item(pdu_tree2, hf_rdmnet_ept_data_vector_protocol_id, tvb, 2, 2, ENC_BIG_ENDIAN);
6843   data_offset += 4;
6844 
6845   /* opaque data */
6846   pdu_end = pdu_start + pdu_length;
6847   proto_tree_add_item(pdu_tree, hf_rdmnet_ept_data_opaque_data, tvb, data_offset, (pdu_end - data_offset), ENC_NA);
6848 
6849   return pdu_start + pdu_length;
6850 }
6851 
6852 
6853 /******************************************************************************/
6854 /* Dissect EPT Status                                                         */
6855 static guint32
dissect_ept_status(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6856 dissect_ept_status(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6857 {
6858   guint8           pdu_flags;
6859   guint16          vector;
6860   guint32          pdu_start;
6861   guint32          pdu_length;
6862   guint32          pdu_end;
6863   guint32          pdu_flvh_length; /* flags, length, vector, header */
6864   guint32          vector_offset;
6865   guint32          data_offset;
6866 
6867   proto_item      *ti;
6868   proto_tree      *pdu_tree;
6869 
6870   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_ept_status_pdu, 1, 0);
6871 
6872   /* Add PDU Length item */
6873   proto_tree_add_uint(pdu_tree, hf_rdmnet_ept_status_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
6874 
6875   dissect_pdu_bit_flag_v(&offset, pdu_flags, &data_offset, last_pdu_offsets, &pdu_flvh_length, 2);
6876   /* offset should now be pointing to header (if one exists) */
6877 
6878   vector = tvb_get_ntohs(tvb, data_offset);
6879   proto_tree_add_item(pdu_tree, hf_rdmnet_ept_status_vector, tvb, data_offset, 2, ENC_NA);
6880   data_offset += 2;
6881 
6882   /* process based on vector */
6883   switch (vector) {
6884   case RDMNET_EPT_VECTOR_UNKNOWN_CID:
6885       /* unknown cid (16 bytes) */
6886       proto_tree_add_item(pdu_tree, hf_rdmnet_ept_status_unknown_cid, tvb, data_offset, 16, ENC_NA);
6887       data_offset += 16;
6888 
6889       /* status string */
6890       pdu_end = pdu_start + pdu_length;
6891       proto_tree_add_item(pdu_tree, hf_rdmnet_ept_status_status_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6892       break;
6893   case RDMNET_EPT_VECTOR_UNKNOWN_VECTOR:
6894       /* unknown cid (4 bytes) */
6895       proto_tree_add_item(pdu_tree, hf_rdmnet_ept_status_unknown_vector, tvb, data_offset, 4, ENC_NA);
6896       data_offset += 4;
6897 
6898       /* vector string */
6899       pdu_end = pdu_start + pdu_length;
6900       proto_tree_add_item(pdu_tree, hf_rdmnet_ept_status_vector_string, tvb, data_offset, (pdu_end - data_offset), ENC_ASCII|ENC_NA);
6901       break;
6902   }
6903 
6904   return pdu_start + pdu_length;
6905 }
6906 
6907 
6908 /******************************************************************************/
6909 /* Dissect EPT Base PDU                                                       */
6910 static guint32
dissect_acn_ept_base_pdu(tvbuff_t * tvb,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets)6911 dissect_acn_ept_base_pdu(tvbuff_t *tvb, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
6912 {
6913   guint8           pdu_flags;
6914   guint32          pdu_start;
6915   guint32          pdu_length;
6916   guint32          pdu_flvh_length; /* flags, length, vector, header */
6917   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
6918   guint32          vector_offset;
6919   guint32          data_offset;
6920   guint32          data_length;
6921 
6922   proto_item      *ti;
6923   proto_tree      *pdu_tree;
6924 
6925   /* this pdu */
6926   const gchar     *name;
6927   guint32          vector;
6928 
6929   dissect_acn_common_base_pdu(tvb, tree, &offset, last_pdu_offsets, &pdu_flags, &pdu_start, &pdu_length, &pdu_flvh_length, &vector_offset, &ti, &pdu_tree, ett_rdmnet_ept_base_pdu, 1, 0);
6930 
6931   /* Add Vector item */
6932   vector = tvb_get_ntohl(tvb, vector_offset);
6933   proto_tree_add_item(pdu_tree, hf_rdmnet_ept_vector, tvb, vector_offset, 4, ENC_BIG_ENDIAN);
6934 
6935   /* Add Vector item to tree */
6936   name = val_to_str(vector, rdmnet_ept_vector_vals, "unknown (%d)");
6937   proto_item_append_text(ti, ": %s", name);
6938 
6939   /* NO HEADER DATA ON THESE* (at least so far) */
6940 
6941   dissect_pdu_bit_flag_d(offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, pdu_flvh_length, 0);
6942   data_offset += 3;
6943 
6944   /* destination cid (16 bytes) */
6945   proto_tree_add_item(pdu_tree, hf_rdmnet_ept_destination_cid, tvb, data_offset, 16, ENC_NA);
6946   data_offset += 16;
6947 
6948   /* process based on vector */
6949   switch (vector) {
6950   case RDMNET_EPT_VECTOR_DATA:
6951       dissect_ept_data(tvb, pdu_tree, data_offset, &pdu_offsets);
6952       break;
6953   case RDMNET_EPT_VECTOR_STATUS:
6954       dissect_ept_status(tvb, pdu_tree, data_offset, &pdu_offsets);
6955       break;
6956   }
6957 
6958   return pdu_start + pdu_length;
6959 }
6960 
6961 /******************************************************************************/
6962 /* Dissect Root PDU                                                           */
6963 static guint32
dissect_acn_root_pdu_header(tvbuff_t * tvb,packet_info * pinfo,proto_tree * pdu_tree,proto_item * ti,const char * title,int * offset,guint8 pdu_flags,guint32 pdu_length,guint32 * data_offset,guint32 * data_length,acn_pdu_offsets * last_pdu_offsets,gboolean add_cid_to_info,guint32 * pdu_flvh_length,gboolean is_acn)6964 dissect_acn_root_pdu_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdu_tree, proto_item *ti, const char *title, int *offset, guint8 pdu_flags, guint32 pdu_length, guint32 *data_offset, guint32 *data_length, acn_pdu_offsets *last_pdu_offsets, gboolean add_cid_to_info, guint32 *pdu_flvh_length, gboolean is_acn)
6965 {
6966   guint32   header_offset;
6967   e_guid_t  guid;
6968 
6969   /* Adjust header */
6970   proto_item_append_text(ti, "%s", title);
6971 
6972   dissect_pdu_bit_flag_h(offset, pdu_flags, &header_offset, last_pdu_offsets, pdu_flvh_length, 16);
6973   /* offset should now be pointing to data (if one exists) */
6974 
6975   /* get Header (CID) 16 bytes */
6976   tvb_get_guid(tvb, header_offset, &guid, ENC_BIG_ENDIAN);
6977   proto_item_append_text(ti, ", Src: %s", guid_to_str(pinfo->pool, &guid));
6978 
6979   if (add_cid_to_info) {
6980     /* add cid to info */
6981     col_add_fstr(pinfo->cinfo, COL_INFO, "CID %s", guid_to_str(pinfo->pool, &guid));
6982   }
6983 
6984   if (is_acn) {
6985     proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, header_offset, 16, ENC_BIG_ENDIAN);
6986   } else {
6987     proto_tree_add_item(pdu_tree, hf_rdmnet_cid, tvb, header_offset, 16, ENC_BIG_ENDIAN);
6988   }
6989   /* header_offset += 16; */
6990 
6991   dissect_pdu_bit_flag_d(*offset, pdu_flags, pdu_length, data_offset, data_length, last_pdu_offsets, *pdu_flvh_length, 1);
6992 
6993   return (*data_offset) + (*data_length);
6994 }
6995 
6996 /******************************************************************************/
6997 /* Dissect Root PDU                                                           */
6998 static guint32
dissect_acn_root_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,acn_pdu_offsets * last_pdu_offsets,gboolean is_acn)6999 dissect_acn_root_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets, gboolean is_acn)
7000 {
7001   /* common to all pdu */
7002   guint8           pdu_flags;
7003   guint32          pdu_start;
7004   guint32          pdu_length;
7005   guint32          pdu_flvh_length; /* flags, length, vector, header */
7006   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
7007   guint32          vector_offset;
7008   guint32          data_offset;
7009   guint32          end_offset;
7010   guint32          old_offset;
7011   guint32          data_length;
7012 
7013   proto_item      *ti;
7014   proto_tree      *pdu_tree;
7015 
7016   /* this pdu */
7017   guint32          protocol_id;
7018 
7019   begin_dissect_acn_pdu(&pdu_tree, tvb, &ti, tree, &pdu_start, &offset, &pdu_flags, &pdu_length, &pdu_flvh_length, ett_acn_root_pdu, is_acn);
7020 
7021   /* Add PDU Length item */
7022   if (is_acn) {
7023     proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
7024   } else {
7025     proto_tree_add_uint(pdu_tree, hf_rdmnet_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
7026   }
7027 
7028   dissect_pdu_bit_flag_v(&offset, pdu_flags, &vector_offset, last_pdu_offsets, &pdu_flvh_length, 4);
7029   /* offset should now be pointing to header (if one exists) */
7030 
7031   /* Get Protocol ID (vector) */
7032   protocol_id = tvb_get_ntohl(tvb, vector_offset);
7033   if (is_acn) {
7034     proto_tree_add_uint(pdu_tree, hf_acn_protocol_id, tvb, vector_offset, 4, protocol_id);
7035   } else {
7036     proto_tree_add_uint(pdu_tree, hf_rdmnet_protocol_id, tvb, vector_offset, 4, protocol_id);
7037   }
7038 
7039   /* process based on protocol_id */
7040   switch (protocol_id) {
7041     case ACN_PROTOCOL_ID_DMX:
7042     case ACN_PROTOCOL_ID_DMX_2:
7043     case ACN_PROTOCOL_ID_DMX_3:
7044       if (global_acn_dmx_enable) {
7045         end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root DMX", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 1, &pdu_flvh_length, 1);
7046 
7047         /* adjust for what we used */
7048         while (data_offset < end_offset) {
7049           old_offset = data_offset;
7050           data_offset = dissect_acn_dmx_base_pdu(protocol_id, tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
7051           if (data_offset == old_offset) break;
7052         }
7053       }
7054       break;
7055     case ACN_PROTOCOL_ID_SDT:
7056       end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root SDT", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 0, &pdu_flvh_length, 1);
7057 
7058       /* adjust for what we used */
7059       while (data_offset < end_offset) {
7060         old_offset = data_offset;
7061         data_offset = dissect_acn_sdt_base_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
7062         if (data_offset == old_offset) break;
7063       }
7064       break;
7065     case ACN_PROTOCOL_ID_RPT:
7066       end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root RPT", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 0, &pdu_flvh_length, 0);
7067 
7068       /* adjust for what we used */
7069       while (data_offset < end_offset) {
7070         old_offset = data_offset;
7071         data_offset = dissect_acn_rpt_base_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
7072         if (data_offset == old_offset) break;
7073       }
7074       break;
7075     case ACN_PROTOCOL_ID_BROKER:
7076       end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root Broker", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 0, &pdu_flvh_length, 0);
7077 
7078       /* adjust for what we used */
7079       while (data_offset < end_offset) {
7080         old_offset = data_offset;
7081         data_offset = dissect_acn_broker_base_pdu(tvb, pdu_tree, data_offset, &pdu_offsets);
7082         if (data_offset == old_offset) break;
7083       }
7084       break;
7085     case ACN_PROTOCOL_ID_LLRP:
7086       end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root LLRP", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 0, &pdu_flvh_length, 0);
7087 
7088       /* adjust for what we used */
7089       while (data_offset < end_offset) {
7090         old_offset = data_offset;
7091         data_offset = dissect_acn_llrp_base_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
7092         if (data_offset == old_offset) break;
7093       }
7094       break;
7095     case ACN_PROTOCOL_ID_EPT:
7096       end_offset = dissect_acn_root_pdu_header(tvb, pinfo, pdu_tree, ti, ": Root EPT", &offset, pdu_flags, pdu_length, &data_offset, &data_length, last_pdu_offsets, 0, &pdu_flvh_length, 0);
7097 
7098       /* adjust for what we used */
7099       while (data_offset < end_offset) {
7100         old_offset = data_offset;
7101         data_offset = dissect_acn_ept_base_pdu(tvb, pdu_tree, data_offset, &pdu_offsets);
7102         if (data_offset == old_offset) break;
7103       }
7104       break;
7105   }
7106 
7107   return pdu_start + pdu_length;
7108 }
7109 
7110 /******************************************************************************/
7111 /* Dissect ACN                                                                */
7112 static int
dissect_acn(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)7113 dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
7114 {
7115   proto_item      *ti;
7116   proto_tree      *acn_tree;
7117   guint32          data_offset = 0;
7118   guint32          old_offset;
7119   guint32          end_offset;
7120   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
7121   guint16          postamble_size;
7122 
7123 /*   if (!is_acn(tvb)) { */
7124 /*     return 0;         */
7125 /*   }                   */
7126 
7127   /* Set the protocol column */
7128   col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACN");
7129   col_add_fstr(pinfo->cinfo, COL_INFO, "ACN [Src Port: %d, Dst Port: %d]", pinfo->srcport, pinfo->destport );
7130 
7131   ti = proto_tree_add_item(tree, proto_acn, tvb, 0, -1, ENC_NA);
7132   acn_tree = proto_item_add_subtree(ti, ett_acn);
7133 
7134   /* add preamble, postamble and ACN Packet ID */
7135   proto_tree_add_item(acn_tree, hf_acn_preamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN);
7136   data_offset += 2;
7137   postamble_size = tvb_get_guint16(tvb, data_offset, ENC_BIG_ENDIAN);
7138   proto_tree_add_item(acn_tree, hf_acn_postamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN);
7139   data_offset += 2;
7140   proto_tree_add_item(acn_tree, hf_acn_packet_identifier, tvb, data_offset, 12, ENC_UTF_8 | ENC_NA);
7141   data_offset += 12;
7142 
7143   /* one past the last data byte, not including the postamble */
7144   end_offset = data_offset + tvb_reported_length_remaining(tvb, data_offset);
7145   while (data_offset < end_offset - postamble_size) {
7146     old_offset = data_offset;
7147     data_offset = dissect_acn_root_pdu(tvb, pinfo, acn_tree, data_offset, &pdu_offsets, 1);
7148     if (data_offset == old_offset) return tvb_reported_length(tvb);
7149   }
7150   /* one past the last postamble byte */
7151   while (data_offset < end_offset) {
7152     proto_tree_add_item(acn_tree, hf_acn_postamble_key_fingerprint, tvb, data_offset, 4, ENC_NA);
7153     data_offset += 4;
7154     proto_tree_add_item(acn_tree, hf_acn_postamble_seq_type, tvb, data_offset, 1, ENC_NA);
7155     data_offset += 1;
7156     proto_tree_add_item(acn_tree, hf_acn_postamble_seq_hi, tvb, data_offset, 3, ENC_BIG_ENDIAN);
7157     data_offset += 3;
7158     proto_tree_add_item(acn_tree, hf_acn_postamble_seq_low, tvb, data_offset, 4, ENC_BIG_ENDIAN);
7159     data_offset += 4;
7160     proto_tree_add_item(acn_tree, hf_acn_postamble_message_digest, tvb, data_offset, 16, ENC_NA);
7161     data_offset += 16;
7162   }
7163   return tvb_reported_length(tvb);
7164 }
7165 
7166 /******************************************************************************/
7167 /* Dissect RDMnet                                                             */
7168 static int
dissect_rdmnet(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint32 data_offset,gboolean is_udp)7169 dissect_rdmnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 data_offset, gboolean is_udp)
7170 {
7171   proto_item      *ti;
7172   proto_tree      *rdmnet_tree;
7173   /* guint32          data_offset = 0; */
7174   guint32          old_offset;
7175   guint32          end_offset;
7176   guint32          pdu_length;
7177   acn_pdu_offsets  pdu_offsets = {0,0,0,0,0};
7178 
7179   /* Set the protocol column */
7180   col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDMnet");
7181   col_add_fstr(pinfo->cinfo, COL_INFO, "RDMnet [Src Port: %d, Dst Port: %d]", pinfo->srcport, pinfo->destport );
7182 
7183   if (is_udp) {
7184     ti = proto_tree_add_item(tree, proto_rdmnet, tvb, data_offset, -1, ENC_NA);
7185   } else {
7186     pdu_length = tvb_get_ntohl(tvb, 12) + 16;
7187     ti = proto_tree_add_item(tree, proto_rdmnet, tvb, data_offset, pdu_length, ENC_NA);
7188   }
7189   rdmnet_tree = proto_item_add_subtree(ti, ett_rdmnet);
7190 
7191   if (is_udp) {
7192     /* UDP only: preamble and postamble */
7193     proto_tree_add_item(rdmnet_tree, hf_rdmnet_preamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN);
7194     data_offset += 2;
7195     proto_tree_add_item(rdmnet_tree, hf_rdmnet_postamble_size, tvb, data_offset, 2, ENC_BIG_ENDIAN);
7196     data_offset += 2;
7197   }
7198   /* add ACN Packet ID */
7199   proto_tree_add_item(rdmnet_tree, hf_rdmnet_packet_identifier, tvb, data_offset, 12, ENC_UTF_8 | ENC_NA);
7200   data_offset += 12;
7201 
7202   pdu_length = 0;
7203   if (!is_udp) {
7204     /* TCP only: data length (may be less than packet length) */
7205     proto_tree_add_item(rdmnet_tree, hf_rdmnet_tcp_length, tvb, data_offset, 4, ENC_BIG_ENDIAN);
7206     pdu_length = tvb_get_ntohl(tvb, data_offset);
7207     data_offset += 4;
7208   }
7209 
7210   /* one past the last byte */
7211   if (is_udp) {
7212     end_offset = data_offset + tvb_reported_length_remaining(tvb, data_offset);
7213   } else {
7214     end_offset = data_offset + pdu_length;
7215   }
7216   while (data_offset < end_offset) {
7217     old_offset = data_offset;
7218     data_offset = dissect_acn_root_pdu(tvb, pinfo, rdmnet_tree, data_offset, &pdu_offsets, 0);
7219     if (data_offset == old_offset) break;
7220   }
7221 
7222   return end_offset;
7223 }
7224 
7225 /******************************************************************************/
7226 /* Register protocol                                                          */
7227 void
proto_register_acn(void)7228 proto_register_acn(void)
7229 {
7230   static hf_register_info hf[] = {
7231     /**************************************************************************/
7232     /* In alphabetical order */
7233     /* Address Type */
7234     /* PDU flags*/
7235     { &hf_acn_ip_address_type,
7236       { "Addr Type", "acn.ip_address_type",
7237         FT_UINT8, BASE_DEC, VALS(acn_ip_address_type_vals), 0x0,
7238         NULL, HFILL }
7239     },
7240     /* Association */
7241     { &hf_acn_association,
7242       { "Association", "acn.association",
7243         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7244         NULL, HFILL }
7245     },
7246     /* Blob */
7247     { &hf_acn_blob,
7248       { "Blob", "acn.blob",
7249         FT_NONE, BASE_NONE, NULL, 0x0,
7250         NULL, HFILL }
7251     },
7252 #if 0
7253     /* Blob Dimmer Load Properties 2 Type */
7254     { &hf_acn_blob_dimmer_load_properties2_type,
7255       { "Blob Field", "acn.blob_dimmer_load_properties2_type",
7256         FT_NONE, BASE_NONE, NULL, 0x0,
7257         NULL, HFILL }
7258     },
7259 #endif
7260     /* Blob Field Length */
7261     { &hf_acn_blob_field_length,
7262       { "Field Length", "acn.blob_field_length",
7263         FT_UINT8, BASE_DEC, NULL, 0x0,
7264         NULL, HFILL }
7265     },
7266     /* Blob Field Type */
7267     { &hf_acn_blob_field_type,
7268       { "Field Type", "acn.blob_field_type",
7269         FT_UINT8, BASE_DEC, VALS(acn_blob_field_type_vals), 0x0,
7270         NULL, HFILL }
7271     },
7272     /* Blob Field Value Number */
7273     { &hf_acn_blob_field_value_number,
7274       { "Field Value", "acn.blob_field_value_number",
7275         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7276         NULL, HFILL }
7277     },
7278     { &hf_acn_blob_field_value_number64,
7279       { "Field Value", "acn.blob_field_value_number64",
7280         FT_UINT64, BASE_DEC_HEX, NULL, 0x0,
7281         NULL, HFILL }
7282     },
7283     { &hf_acn_blob_field_value_float,
7284       { "Field Value", "acn.blob_field_value_float",
7285         FT_FLOAT, BASE_NONE, NULL, 0x0,
7286         NULL, HFILL }
7287     },
7288     { &hf_acn_blob_field_value_double,
7289       { "Field Value", "acn.blob_field_value_double",
7290         FT_DOUBLE, BASE_NONE, NULL, 0x0,
7291         NULL, HFILL }
7292     },
7293     { &hf_acn_blob_field_value_guid,
7294       { "Field Value", "acn.blob_field_value_guid",
7295         FT_GUID, BASE_NONE, NULL, 0x0,
7296         NULL, HFILL }
7297     },
7298 
7299     /* Blob Field Value String*/
7300     { &hf_acn_blob_field_value_string,
7301       { "Field Value", "acn.blob_field_value_string",
7302         FT_STRING, BASE_NONE, NULL, 0x0,
7303         NULL, HFILL }
7304     },
7305     /* Blob Field Value IPV4 */
7306     { &hf_acn_blob_field_value_ipv4,
7307       { "Field Value", "acn.blob_field_value_ipv4",
7308         FT_IPv4, BASE_NONE, NULL, 0x0,
7309         NULL, HFILL }
7310     },
7311     /* Blob Field Value IPV6 */
7312     { &hf_acn_blob_field_value_ipv6,
7313       { "Field Value", "acn.blob_field_value_ipv6",
7314         FT_IPv6, BASE_NONE, NULL, 0x0,
7315         NULL, HFILL }
7316     },
7317     /* Blob Metadata Device Type */
7318     { &hf_acn_blob_tree_field_type,
7319       { "Blob Field", "acn.blob_tree_field_type",
7320         FT_NONE, BASE_NONE, NULL, 0x0,
7321         NULL, HFILL }
7322     },
7323 #if 0
7324     /* Blob Metadata Types Type */
7325     { &hf_acn_blob_metadata_types_type,
7326       { "Blob Field", "acn.blob_metadata_types_type",
7327         FT_NONE, BASE_NONE, NULL, 0x0,
7328         NULL, HFILL }
7329     },
7330 #endif
7331     /* Blob Range Number */
7332     { &hf_acn_blob_range_number,
7333       { "Blob Range Number", "acn.blob_range_number",
7334         FT_UINT8, BASE_DEC, NULL, 0x0,
7335         NULL, HFILL }
7336     },
7337     /* Blob Range Type */
7338     { &hf_acn_blob_range_type,
7339       { "Blob Range Type", "acn.blob_range_type",
7340         FT_UINT8, BASE_HEX, VALS(acn_blob_range_type_vals), 0x0,
7341         NULL, HFILL }
7342     },
7343 #if 0
7344     /* Blob Range Start */
7345     { &hf_acn_blob_range_start,
7346       { "Blob Range Start", "acn.blob_range_start",
7347         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
7348         NULL, HFILL }
7349     },
7350 #endif
7351     /* Blob Type */
7352     { &hf_acn_blob_type,
7353       { "Blob Type", "acn.blob_type",
7354         FT_UINT8, BASE_DEC, VALS(acn_blob_type_vals), 0x0,
7355         NULL, HFILL }
7356     },
7357     /* Blob Version */
7358     { &hf_acn_blob_version,
7359       { "Blob Version", "acn.blob_version",
7360         FT_UINT8, BASE_DEC, NULL, 0x0,
7361         NULL, HFILL }
7362     },
7363     { &hf_acn_blob_time_zone,
7364       { "Time Zone", "acn.blob_time_zone",
7365         FT_INT8, BASE_DEC, NULL, 0x0,
7366         NULL, HFILL }
7367     },
7368     { &hf_acn_blob_dst_type,
7369       { "DST Type", "acn.blob_dst_type",
7370         FT_UINT8, BASE_DEC, NULL, 0x0,
7371         NULL, HFILL }
7372     },
7373     { &hf_acn_blob_dst_start_day,
7374       { "DST Start Day", "acn.blob_dst_start_day",
7375         FT_UINT8, BASE_DEC, NULL, 0x0,
7376         NULL, HFILL }
7377     },
7378     { &hf_acn_blob_dst_stop_day,
7379       { "DST Stop Day", "acn.blob_dst_stop_day",
7380         FT_UINT8, BASE_DEC, NULL, 0x0,
7381         NULL, HFILL }
7382     },
7383     { &hf_acn_blob_dst_start_locality,
7384       { "DST Start Locality", "acn.blob_dst_start_locality",
7385         FT_UINT8, BASE_DEC, NULL, 0x0,
7386         NULL, HFILL }
7387     },
7388     { &hf_acn_blob_dst_stop_locality,
7389       { "DST Stop Locality", "acn.blob_dst_stop_locality",
7390         FT_UINT8, BASE_DEC, NULL, 0x0,
7391         NULL, HFILL }
7392     },
7393     /* Channel Number */
7394     { &hf_acn_channel_number,
7395       { "Channel Number", "acn.channel_number",
7396         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7397         NULL, HFILL }
7398     },
7399     /* CID */
7400     { &hf_acn_cid,
7401       { "CID", "acn.cid",
7402         FT_GUID, BASE_NONE, NULL, 0x0,
7403         NULL, HFILL }
7404     },
7405     /* Client Protocol ID */
7406 #if 0
7407     { &hf_acn_client_protocol_id,
7408       { "Client Protocol ID", "acn.client_protocol_id",
7409         FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
7410         NULL, HFILL }
7411     },
7412 #endif
7413     /* DMP data */
7414     { &hf_acn_data,
7415       { "Data", "acn.dmp_data",
7416         FT_BYTES, BASE_NONE, NULL, 0x0,
7417         NULL, HFILL }
7418     },
7419     { &hf_acn_data8,
7420       { "Addr", "acn.dmp_data8",
7421         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
7422         "Data8", HFILL }
7423     },
7424     { &hf_acn_data16,
7425       { "Addr", "acn.dmp_data16",
7426         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7427         "Data16", HFILL }
7428     },
7429     { &hf_acn_data24,
7430       { "Addr", "acn.dmp_data24",
7431         FT_UINT24, BASE_DEC_HEX, NULL, 0x0,
7432         "Data24", HFILL }
7433     },
7434     { &hf_acn_data32,
7435       { "Addr", "acn.dmp_data32",
7436         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7437         "Data32", HFILL }
7438     },
7439 
7440     /* DMP Address type*/
7441 #if 0
7442     { &hf_acn_dmp_adt,
7443       { "Address and Data Type", "acn.dmp_adt",
7444         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
7445         NULL, HFILL }
7446     },
7447 #endif
7448     { &hf_acn_dmp_adt_a,
7449       { "Size", "acn.dmp_adt_a",
7450         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_a_vals), 0x03,
7451         NULL, HFILL }
7452     },
7453     { &hf_acn_dmp_adt_d,
7454       { "Data Type", "acn.dmp_adt_d",
7455         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_d_vals), 0x30,
7456         NULL, HFILL }
7457     },
7458     { &hf_acn_dmp_adt_r,
7459       { "Relative", "acn.dmp_adt_r",
7460         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_r_vals), 0x40,
7461         NULL, HFILL }
7462     },
7463     { &hf_acn_dmp_adt_v,
7464       { "Virtual", "acn.dmp_adt_v",
7465         FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_v_vals), 0x80,
7466         NULL, HFILL }
7467     },
7468     { &hf_acn_dmp_adt_x,
7469       { "Reserved", "acn.dmp_adt_x",
7470         FT_UINT8, BASE_DEC, NULL, 0x0c,
7471         NULL, HFILL }
7472     },
7473 
7474     /* DMP Reason Code */
7475     { &hf_acn_dmp_reason_code,
7476       { "Reason Code", "acn.dmp_reason_code",
7477         FT_UINT8, BASE_DEC, VALS(acn_dmp_reason_code_vals), 0x0,
7478         NULL, HFILL }
7479     },
7480 
7481     /* DMP Vector */
7482     { &hf_acn_dmp_vector,
7483       { "DMP Vector", "acn.dmp_vector",
7484         FT_UINT8, BASE_DEC, VALS(acn_dmp_vector_vals), 0x0,
7485         NULL, HFILL }
7486     },
7487 
7488     { &hf_acn_dmp_actual_address,
7489       { "Actual Address", "acn.dmp_actual_address",
7490         FT_UINT32, BASE_HEX, NULL, 0x0,
7491         NULL, HFILL }
7492     },
7493 
7494     { &hf_acn_dmp_virtual_address,
7495       { "Virtual Address", "acn.dmp_virtual_address",
7496         FT_UINT32, BASE_HEX, NULL, 0x0,
7497         NULL, HFILL }
7498     },
7499 
7500     { &hf_acn_dmp_actual_address_first,
7501       { "Actual Address First", "acn.dmp_actual_address_first",
7502         FT_UINT32, BASE_HEX, NULL, 0x0,
7503         NULL, HFILL }
7504     },
7505 
7506     { &hf_acn_dmp_virtual_address_first,
7507       { "Virtual Address First", "acn.dmp_virtual_address_first",
7508         FT_UINT32, BASE_HEX, NULL, 0x0,
7509         NULL, HFILL }
7510     },
7511 
7512     /* Expiry */
7513     { &hf_acn_expiry,
7514       { "Expiry", "acn.expiry",
7515         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7516         NULL, HFILL }
7517     },
7518     /* First Member to ACK */
7519     { &hf_acn_first_member_to_ack,
7520       { "First Member to ACK", "acn.first_member_to_ack",
7521         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7522         NULL, HFILL }
7523     },
7524     /* First Missed Sequence */
7525     { &hf_acn_first_missed_sequence,
7526       { "First Missed Sequence", "acn.first_missed_sequence",
7527         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7528         NULL, HFILL }
7529     },
7530     /* IPV4 */
7531     { &hf_acn_ipv4,
7532       { "IPV4", "acn.ipv4",
7533         FT_IPv4, BASE_NONE, NULL, 0x0,
7534         NULL, HFILL }
7535     },
7536     /* IPV6 */
7537     { &hf_acn_ipv6,
7538       { "IPV6", "acn.ipv6",
7539         FT_IPv6, BASE_NONE, NULL, 0x0,
7540         NULL, HFILL }
7541     },
7542     /* Last Member to ACK */
7543     { &hf_acn_last_member_to_ack,
7544       { "Last Member to ACK", "acn.last_member_to_ack",
7545         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7546         NULL, HFILL }
7547     },
7548     /* Last Missed Sequence */
7549     { &hf_acn_last_missed_sequence,
7550       { "Last Missed Sequence", "acn.last_missed_sequence",
7551         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7552         NULL, HFILL }
7553     },
7554     /* MAK threshold */
7555     { &hf_acn_mak_threshold,
7556       { "MAK Threshold", "acn.mak_threshold",
7557         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7558         NULL, HFILL }
7559     },
7560     /* Member ID */
7561     { &hf_acn_member_id,
7562       { "Member ID", "acn.member_id",
7563         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7564         NULL, HFILL }
7565     },
7566     /* NAK Holdoff */
7567     { &hf_acn_nak_holdoff,
7568       { "NAK holdoff (ms)", "acn.nak_holdoff",
7569         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7570         NULL, HFILL }
7571     },
7572     /* NAK Max Wait */
7573     { &hf_acn_nak_max_wait,
7574       { "NAK Max Wait (ms)", "acn.nak_max_wait",
7575         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7576         NULL, HFILL }
7577     },
7578     /* NAK Modulus */
7579     { &hf_acn_nak_modulus,
7580       { "NAK Modulus", "acn.nak_modulus",
7581         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7582         NULL, HFILL }
7583     },
7584     /* NAK Outbound Flag */
7585     { &hf_acn_nak_outbound_flag,
7586       { "NAK Outbound Flag", "acn.nak_outbound_flag",
7587         FT_BOOLEAN, 8, NULL, 0x80,
7588         NULL, HFILL }
7589     },
7590     /* Oldest Available Wrapper */
7591     { &hf_acn_oldest_available_wrapper,
7592       { "Oldest Available Wrapper", "acn.oldest_available_wrapper",
7593         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7594         NULL, HFILL }
7595     },
7596     /* Preamble Size */
7597     { &hf_acn_preamble_size,
7598       { "Size of preamble", "acn.preamble_size",
7599         FT_UINT16, BASE_DEC, NULL, 0x0,
7600         "Preamble size in bytes", HFILL }
7601     },
7602     /* Packet Identifier */
7603     { &hf_acn_packet_identifier,
7604       { "Packet Identifier", "acn.packet_identifier",
7605         FT_STRING, BASE_NONE, NULL, 0x0,
7606         NULL, HFILL }
7607     },
7608     /* PDU */
7609     { &hf_acn_pdu,
7610       { "PDU", "acn.pdu",
7611         FT_NONE, BASE_NONE, NULL, 0x0,
7612         NULL, HFILL }
7613     },
7614     /* PDU flags*/
7615     { &hf_acn_pdu_flags,
7616       { "Flags", "acn.pdu.flags",
7617         FT_UINT8, BASE_HEX, NULL, 0x0,
7618         "PDU Flags", HFILL }
7619     },
7620     { &hf_acn_pdu_flag_d,
7621       { "Data", "acn.pdu.flag_d",
7622         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_D,
7623         "Data flag", HFILL }
7624     },
7625     { &hf_acn_pdu_flag_h,
7626       { "Header", "acn.pdu.flag_h",
7627         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_H,
7628         "Header flag", HFILL }
7629     },
7630     { &hf_acn_pdu_flag_l,
7631       { "Length", "acn.pdu.flag_l",
7632         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_L,
7633         "Length flag", HFILL }
7634     },
7635     { &hf_acn_pdu_flag_v,
7636       { "Vector", "acn.pdu.flag_v",
7637         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_V,
7638         "Vector flag", HFILL }
7639     },
7640     /* PDU Length */
7641     { &hf_acn_pdu_length,
7642       { "Length", "acn.pdu.length",
7643         FT_UINT32, BASE_DEC, NULL, 0x0,
7644         "PDU Length", HFILL }
7645     },
7646     /* Port */
7647     { &hf_acn_port,
7648       { "Port", "acn.port",
7649         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7650         NULL, HFILL }
7651     },
7652     /* Postamble Size */
7653     { &hf_acn_postamble_size,
7654       { "Size of postamble", "acn.postamble_size",
7655         FT_UINT16, BASE_DEC, NULL, 0x0,
7656         "Postamble size in bytes", HFILL }
7657     },
7658     /* Protocol ID */
7659     { &hf_acn_protocol_id,
7660       { "Protocol ID", "acn.protocol_id",
7661         FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
7662         NULL, HFILL }
7663     },
7664     /* Reason Code */
7665     { &hf_acn_reason_code,
7666       { "Reason Code", "acn.reason_code",
7667         FT_UINT8, BASE_DEC, VALS(acn_reason_code_vals), 0x0,
7668         NULL, HFILL }
7669     },
7670     /* Reciprocal Channel */
7671     { &hf_acn_reciprocal_channel,
7672       { "Reciprocal Channel Number", "acn.reciprocal_channel",
7673         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7674         "Reciprocal Channel", HFILL }
7675     },
7676     /* Refuse Code */
7677     { &hf_acn_refuse_code,
7678       { "Refuse Code", "acn.refuse_code",
7679         FT_UINT8, BASE_DEC, VALS(acn_refuse_code_vals), 0x0,
7680         NULL, HFILL }
7681     },
7682     /* Reliable Sequence Number */
7683     { &hf_acn_reliable_sequence_number,
7684       { "Reliable Sequence Number", "acn.reliable_sequence_number",
7685         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7686         NULL, HFILL }
7687     },
7688     /* Ad-hoc Expiry */
7689     { &hf_acn_adhoc_expiry,
7690       { "Ad-hoc Expiry", "acn.adhoc_expiry",
7691         FT_UINT8, BASE_DEC, NULL, 0x0,
7692         NULL, HFILL }
7693     },
7694     /* SDT Vector */
7695     { &hf_acn_sdt_vector,
7696       { "SDT Vector", "acn.sdt_vector",
7697         FT_UINT8, BASE_DEC, VALS(acn_sdt_vector_vals), 0x0,
7698         NULL, HFILL }
7699     },
7700 
7701     /* DMX Vector */
7702     { &hf_acn_dmx_vector,
7703       { "Vector", "acn.dmx_vector",
7704         FT_UINT32, BASE_DEC, VALS(acn_dmx_vector_vals), 0x0,
7705         "DMX Vector", HFILL }
7706     },
7707     /* DMX Source Name */
7708     { &hf_acn_dmx_source_name,
7709       { "Source", "acn.dmx.source_name",
7710         FT_STRING, BASE_NONE, NULL, 0x0,
7711         "DMX Source Name", HFILL }
7712     },
7713 
7714     /* DMX priority */
7715     { &hf_acn_dmx_priority,
7716       { "Priority", "acn.dmx.priority",
7717         FT_UINT8, BASE_DEC, NULL, 0x0,
7718         "DMX Priority", HFILL }
7719     },
7720 
7721     /* DMX 2 reserved */
7722     { &hf_acn_dmx_2_reserved,
7723       { "Reserved", "acn.dmx.reserved",
7724         FT_UINT16, BASE_DEC, NULL, 0x0,
7725         "DMX Reserved", HFILL }
7726     },
7727 
7728     /* DMX Sequence number */
7729     { &hf_acn_dmx_sequence_number,
7730       { "Seq No", "acn.dmx.seq_number",
7731         FT_UINT8, BASE_DEC, NULL, 0x0,
7732         "DMX Sequence Number", HFILL }
7733     },
7734 
7735     /* DMX 2 options */
7736     { &hf_acn_dmx_2_options,
7737       { "Options", "acn.dmx.options",
7738         FT_UINT8, BASE_DEC, NULL, 0x0,
7739         "DMX Options", HFILL }
7740     },
7741 
7742     { &hf_acn_dmx_2_option_p,
7743       { "Preview Data", "acn.dmx.option_p",
7744         FT_BOOLEAN, 8, NULL, ACN_DMX_OPTION_P,
7745         "Preview Data flag", HFILL }
7746     },
7747 
7748     { &hf_acn_dmx_2_option_s,
7749       { "Stream Terminated", "acn.dmx.option_s",
7750         FT_BOOLEAN, 8, NULL, ACN_DMX_OPTION_S,
7751         "Stream Terminated flag", HFILL }
7752     },
7753 
7754     /* DMX Universe */
7755     { &hf_acn_dmx_universe,
7756       { "Universe", "acn.dmx.universe",
7757         FT_UINT16, BASE_DEC, NULL, 0x0,
7758         "DMX Universe", HFILL }
7759     },
7760 
7761     /* DMX Start Code */
7762     { &hf_acn_dmx_start_code,
7763       { "Start Code", "acn.dmx.start_code",
7764         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7765         "DMX Start Code", HFILL }
7766     },
7767 
7768     /* DMX 2 First Property Address */
7769     { &hf_acn_dmx_2_first_property_address,
7770       { "First Property Address", "acn.dmx.first_property_address",
7771         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7772         "DMX First Property Address", HFILL }
7773     },
7774 
7775     /* DMX Address Increment */
7776     { &hf_acn_dmx_increment,
7777       { "Increment", "acn.dmx.increment",
7778         FT_UINT16, BASE_DEC, NULL, 0x0,
7779         "DMX Increment", HFILL }
7780     },
7781 
7782     /* DMX Packet Count */
7783     { &hf_acn_dmx_count,
7784       { "Count", "acn.dmx.count",
7785         FT_UINT16, BASE_DEC, NULL, 0x0,
7786         "DMX Count", HFILL }
7787     },
7788 
7789     /* DMX 2 Start Code */
7790     { &hf_acn_dmx_2_start_code,
7791       { "Start Code", "acn.dmx.start_code2",
7792         FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
7793         "DMX Start Code", HFILL }
7794     },
7795 
7796     /*
7797      * If you want the pretty-printed data in the field, for filtering
7798      * purposes, you have to make it an FT_STRING.
7799      *
7800      * If you want the raw data in the field, for filtering purposes,
7801      * you have to make it an FT_BYTES *AND* use "proto_tree_add_bytes_format()"
7802      * to put the pretty-printed data into the display but not the field.
7803      */
7804     { &hf_acn_dmx_data,
7805       { "Data", "acn.dmx.data",
7806         FT_STRING, BASE_NONE, NULL, 0x0,
7807         NULL, HFILL }
7808     },
7809 
7810     /* Session Count */
7811 #if 0
7812     { &hf_acn_session_count,
7813       { "Session Count", "acn.session_count",
7814         FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
7815         NULL, HFILL }
7816     },
7817 #endif
7818     /* Total Sequence Number */
7819     { &hf_acn_total_sequence_number,
7820       { "Total Sequence Number", "acn.total_sequence_number",
7821         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
7822         NULL, HFILL }
7823     }
7824   };
7825 
7826   static hf_register_info magic_hf[] = {
7827     /* Protocol ID */
7828     { &hf_magic_protocol_id,
7829       { "Protocol ID", "magic.protocol_id",
7830         FT_UINT8, BASE_DEC, NULL, 0x0,
7831         NULL, HFILL }
7832     },
7833 
7834     /* PDU Type */
7835     { &hf_magic_pdu_subtype,
7836       { "PDU type", "magic.type",
7837         FT_UINT8, BASE_DEC, VALS(magic_pdu_subtypes), 0x0,
7838         NULL, HFILL },
7839     },
7840 
7841     /* Major Version */
7842     { &hf_magic_major_version,
7843       { "Major Version", "magic.major_version",
7844         FT_UINT8, BASE_DEC, NULL, 0x0,
7845         NULL, HFILL }
7846     },
7847 
7848     /* Minor Version */
7849     { &hf_magic_minor_version,
7850       { "Minor Version", "magic.minor_version",
7851         FT_UINT8, BASE_DEC, NULL, 0x0,
7852         NULL, HFILL }
7853     },
7854 
7855     /* V1 Command */
7856     { &hf_magic_v1command_vals,
7857       { "Command", "magic.v1_command",
7858         FT_UINT32, BASE_DEC, VALS(magic_v1command_vals), 0x0,
7859         NULL, HFILL }
7860     },
7861 
7862     /* V2 Command */
7863     { &hf_magic_command_vals,
7864       { "Command", "magic.command",
7865         FT_UINT32, BASE_DEC, VALS(magic_command_vals), 0x0,
7866         NULL, HFILL }
7867     },
7868 
7869     /* Beacon Duration */
7870     { &hf_magic_command_beacon_duration,
7871       { "Duration", "magic.beacon_duration",
7872         FT_UINT32, BASE_DEC, NULL, 0x0,
7873         "Beacon Duration", HFILL }
7874     },
7875 
7876     /* TFTP */
7877     { &hf_magic_command_tftp,
7878       { "TFTP IP", "magic.tftp",
7879         FT_IPv4, BASE_NONE, NULL, 0x0,
7880         "IP of TFTP server", HFILL }
7881     },
7882 
7883     /* Reset Lease */
7884     { &hf_magic_command_reset_lease,
7885       { "Reset Lease", "magic.reset_lease",
7886         FT_UINT32, BASE_DEC, VALS(magic_reset_lease_vals), 0x0,
7887         NULL, HFILL }
7888     },
7889 
7890     /* CID */
7891     { &hf_magic_command_cid,
7892       { "CID", "magic.cid",
7893         FT_GUID, BASE_NONE, NULL, 0x0,
7894         NULL, HFILL }
7895     },
7896 
7897     /* Command IP Configuration */
7898     { &hf_magic_command_ip_configuration,
7899       { "IP Configuration", "magic.ip_configuration",
7900         FT_UINT32, BASE_DEC, VALS(magic_ip_configuration_vals), 0x0,
7901         NULL, HFILL }
7902     },
7903 
7904     /* Command IP Address */
7905     { &hf_magic_command_ip_address,
7906       { "IP Address", "magic.ip_address",
7907         FT_IPv4, BASE_NONE, NULL, 0x0,
7908         NULL, HFILL }
7909     },
7910 
7911     /* Command Subnet Mask */
7912     { &hf_magic_command_subnet_mask,
7913       { "Subnet Mask", "magic.subnet_mask",
7914         FT_IPv4, BASE_NONE, NULL, 0x0,
7915         NULL, HFILL }
7916     },
7917 
7918     /* Command Gateway */
7919     { &hf_magic_command_gateway,
7920       { "Gateway", "magic.gateway",
7921         FT_IPv4, BASE_NONE, NULL, 0x0,
7922         NULL, HFILL }
7923     },
7924 
7925     /* Reply IP Address */
7926     { &hf_magic_reply_ip_address,
7927       { "IP", "magic.reply.ip_address",
7928         FT_IPv4, BASE_NONE, NULL, 0x0,
7929         "Local IP Address", HFILL }
7930     },
7931 
7932     /* Reply Subnet Mask */
7933     { &hf_magic_reply_subnet_mask,
7934       { "Subnet Mask", "magic.reply.subnet_mask",
7935         FT_IPv4, BASE_NONE, NULL, 0x0,
7936         "Local Subnet Mask", HFILL }
7937     },
7938 
7939     /* Reply Gateway */
7940     { &hf_magic_reply_gateway,
7941       { "Gateway", "magic.reply.gateway",
7942         FT_IPv4, BASE_NONE, NULL, 0x0,
7943         "Local Gateway", HFILL }
7944     },
7945 
7946     /* Reply TFTP */
7947     { &hf_magic_reply_tftp,
7948       { "TFTP IP", "magic.reply.tftp",
7949         FT_IPv4, BASE_NONE, NULL, 0x0,
7950         "IP of TFTP server", HFILL }
7951     },
7952 
7953     /* Reply Version */
7954     { &hf_magic_reply_version,
7955       { "Reply Version", "magic.reply.version",
7956         FT_STRING, BASE_NONE, NULL, 0x0,
7957         NULL, HFILL }
7958     },
7959 
7960     /* Reply Device Type Name */
7961     { &hf_magic_reply_device_type_name,
7962       { "Device Type Name", "magic.reply.device_type_name",
7963         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
7964         "Reply Device Type Name", HFILL }
7965     },
7966 
7967     /* Reply Default Name */
7968     { &hf_magic_reply_default_name,
7969       { "Default Name", "magic.reply.default_name",
7970         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
7971         "Reply Default Name", HFILL }
7972     },
7973 
7974     /* Reply User Name */
7975     { &hf_magic_reply_user_name,
7976       { "User Name", "magic.reply.user_name",
7977         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
7978         "Reply User Name", HFILL }
7979     },
7980 
7981     /* CID */
7982     { &hf_magic_reply_cid,
7983       { "CID", "magic.reply.cid",
7984         FT_GUID, BASE_NONE, NULL, 0x0,
7985         "Reply CID", HFILL }
7986     },
7987 
7988     /* DCID */
7989     { &hf_magic_reply_dcid,
7990       { "DCID", "magic.reply.dcid",
7991         FT_GUID, BASE_NONE, NULL, 0x0,
7992         "Reply DCID", HFILL }
7993     },
7994 
7995     /* Key Fingerprint */
7996     { &hf_acn_postamble_key_fingerprint,
7997       { "Key Fingerprint", "acn.security.key_fingerprint",
7998         FT_BYTES, BASE_NONE, NULL, 0x0,
7999         "Security Key Fingerprint", HFILL }
8000     },
8001 
8002     /* Sequence type */
8003     { &hf_acn_postamble_seq_type,
8004       { "Sequence Type", "acn.security.seq_type",
8005         FT_UINT8, BASE_DEC, VALS(security_seq_type_vals), 0x0,
8006         "Security Sequence Type", HFILL }
8007     },
8008 
8009     /* Sequence High */
8010     { &hf_acn_postamble_seq_hi,
8011       { "Sequence High", "acn.security.seq_hi",
8012         FT_UINT24, BASE_HEX, NULL, 0x0,
8013         "Security Sequence High", HFILL }
8014     },
8015 
8016     /* Sequence Low */
8017     { &hf_acn_postamble_seq_low,
8018       { "Sequence Low", "acn.security.seq_low",
8019         FT_UINT32, BASE_HEX, NULL, 0x0,
8020         "Security Sequence Low", HFILL }
8021     },
8022 
8023     /* Message Digest */
8024     { &hf_acn_postamble_message_digest,
8025       { "Message Digest", "acn.security.digest",
8026         FT_BYTES, BASE_NONE, NULL, 0x0,
8027         "Security Message Digest", HFILL }
8028     },
8029 
8030   };
8031 
8032   static hf_register_info rdmnet_hf[] = {
8033     /* CID */
8034     { &hf_rdmnet_cid,
8035       { "CID", "rdmnet.cid",
8036         FT_GUID, BASE_NONE, NULL, 0x0,
8037         NULL, HFILL }
8038     },
8039     /* Packet Identifier */
8040     { &hf_rdmnet_packet_identifier,
8041       { "Packet Identifier", "rdmnet.packet_identifier",
8042         FT_STRING, BASE_NONE, NULL, 0x0,
8043         NULL, HFILL }
8044     },
8045     /* PDU */
8046     { &hf_rdmnet_pdu,
8047       { "PDU", "rdmnet.pdu",
8048         FT_NONE, BASE_NONE, NULL, 0x0,
8049         NULL, HFILL }
8050     },
8051     /* PDU flags*/
8052     { &hf_rdmnet_pdu_flags,
8053       { "Flags", "rdmnet.pdu.flags",
8054         FT_UINT8, BASE_HEX, NULL, 0x0,
8055         "PDU Flags", HFILL }
8056     },
8057     { &hf_rdmnet_pdu_flag_d,
8058       { "Data", "rdmnet.pdu.flag_d",
8059         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_D,
8060         "Data flag", HFILL }
8061     },
8062     { &hf_rdmnet_pdu_flag_h,
8063       { "Header", "rdmnet.pdu.flag_h",
8064         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_H,
8065         "Header flag", HFILL }
8066     },
8067     { &hf_rdmnet_pdu_flag_l,
8068       { "Length", "rdmnet.pdu.flag_l",
8069         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_L,
8070         "Length flag", HFILL }
8071     },
8072     { &hf_rdmnet_pdu_flag_v,
8073       { "Vector", "rdmnet.pdu.flag_v",
8074         FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_V,
8075         "Vector flag", HFILL }
8076     },
8077     /* PDU Length */
8078     { &hf_rdmnet_pdu_length,
8079       { "Length", "rdmnet.pdu.length",
8080         FT_UINT32, BASE_DEC, NULL, 0x0,
8081         "PDU Length", HFILL }
8082     },
8083     /* Postamble Size */
8084     { &hf_rdmnet_postamble_size,
8085       { "Size of postamble", "rdmnet.postamble_size",
8086         FT_UINT16, BASE_DEC, NULL, 0x0,
8087         "Postamble size in bytes", HFILL }
8088     },
8089     /* Preamble Size */
8090     { &hf_rdmnet_preamble_size,
8091       { "Size of preamble", "rdmnet.preamble_size",
8092         FT_UINT16, BASE_DEC, NULL, 0x0,
8093         "Preamble size in bytes", HFILL }
8094     },
8095     /* Protocol ID */
8096     { &hf_rdmnet_protocol_id,
8097       { "Protocol ID", "rdmnet.protocol_id",
8098         FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
8099         NULL, HFILL }
8100     },
8101     /* Postamble Size */
8102     { &hf_rdmnet_tcp_length,
8103       { "Data length", "rdmnet.tcp_length",
8104         FT_UINT32, BASE_DEC, NULL, 0x0,
8105         "TCP data size in bytes", HFILL }
8106     },
8107     /* LLRP Vector */
8108     { &hf_rdmnet_llrp_vector,
8109       { "LLRP Vector", "rdmnet.llrp_vector",
8110         FT_UINT32, BASE_DEC, VALS(rdmnet_llrp_vector_vals), 0x0,
8111         NULL, HFILL }
8112     },
8113     /* LLRP Destination CID */
8114     { &hf_rdmnet_llrp_destination_cid,
8115       { "CID", "rdmnet.llrp.destination_cid",
8116         FT_GUID, BASE_NONE, NULL, 0x0,
8117         NULL, HFILL }
8118     },
8119     /* LLRP Transaction Number */
8120     { &hf_rdmnet_llrp_transaction_number,
8121       { "Transaction Number", "rdmnet.llrp.transaction_number",
8122         FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
8123         NULL, HFILL }
8124     },
8125     /* LLRP Probe Request PDU Length */
8126     { &hf_rdmnet_llrp_probe_request_pdu_length,
8127       { "Length", "rdmnet.llrp.probe_request.pdu.length",
8128         FT_UINT24, BASE_DEC, NULL, 0x0,
8129         "PDU Length", HFILL }
8130     },
8131     /* LLRP Probe Request Vector */
8132     { &hf_rdmnet_llrp_probe_request_vector,
8133       { "LLRP Vector", "rdmnet.llrp.probe_request_vector",
8134         FT_UINT8, BASE_DEC, VALS(rdmnet_llrp_probe_request_vals), 0x0,
8135         NULL, HFILL }
8136     },
8137     /* LLRP Probe Request Lower UID */
8138     { &hf_rdmnet_llrp_probe_request_lower_uid,
8139       { "Lower UID", "rdmnet.llrp.probe_request.lower_uid",
8140         FT_BYTES, SEP_SPACE, NULL, 0x0,
8141         NULL, HFILL }
8142     },
8143     /* LLRP Probe Request Upper UID */
8144     { &hf_rdmnet_llrp_probe_request_upper_uid,
8145       { "Upper UID", "rdmnet.llrp.probe_request.upper_uid",
8146         FT_BYTES, SEP_SPACE, NULL, 0x0,
8147         NULL, HFILL }
8148     },
8149     /* LLRP Probe Request Filter */
8150     { &hf_rdmnet_llrp_probe_request_filter,
8151       { "Filter", "rdmnet.llrp.probe_request.filter",
8152         FT_UINT16, BASE_HEX, NULL, 0x0,
8153         NULL, HFILL }
8154     },
8155     { &hf_rdmnet_llrp_probe_request_filter_brokers_only,
8156       { "Brokers Only", "rdmnet.llrp.probe_request.filter_brokers_only",
8157         FT_BOOLEAN, 8, NULL, RDMNET_LLRP_VECTOR_PROBE_REQUEST_BROKERS_ONLY,
8158         "Brokers only flag", HFILL }
8159     },
8160     { &hf_rdmnet_llrp_probe_request_filter_client_tcp_inactive,
8161       { "Client TCP Inactive", "rdmnet.llrp.probe_request.filter_client_tcp_inactive",
8162         FT_BOOLEAN, 8, NULL, RDMNET_LLRP_VECTOR_PROBE_REQUEST_CLIENT_TCP_INACTIVE,
8163         "Client TCP inactive flag", HFILL }
8164     },
8165     /* LLRP Probe Request Unknown UID */
8166     { &hf_rdmnet_llrp_probe_request_known_uid,
8167       { "Known UID", "rdmnet.llrp.probe_request.known_uid",
8168         FT_BYTES, SEP_SPACE, NULL, 0x0,
8169         NULL, HFILL }
8170     },
8171     /* LLRP Probe Reply Vector */
8172     { &hf_rdmnet_llrp_probe_reply_vector,
8173       { "LLRP Vector", "rdmnet.llrp.probe_reply_vector",
8174         FT_UINT8, BASE_DEC, VALS(rdmnet_llrp_probe_reply_vals), 0x0,
8175         NULL, HFILL }
8176     },
8177     /* LLRP Probe Reply UID */
8178     { &hf_rdmnet_llrp_probe_reply_uid,
8179       { "UID", "rdmnet.llrp.probe_reply.uid",
8180         FT_BYTES, SEP_SPACE, NULL, 0x0,
8181         NULL, HFILL }
8182     },
8183     /* LLRP Probe Reply Hardware Address */
8184     { &hf_rdmnet_llrp_probe_reply_hardware_address,
8185       { "Hardware Address", "rdmnet.llrp.probe_reply.hardware_address",
8186         FT_BYTES, SEP_COLON, NULL, 0x0,
8187         NULL, HFILL }
8188     },
8189     /* LLRP Probe Reply Component Type */
8190     { &hf_rdmnet_llrp_probe_reply_component_type,
8191       { "Component Type", "rdmnet.llrp.probe_reply.component_type",
8192         FT_UINT8, BASE_DEC, VALS(rdmnet_llrp_probe_reply_component_type_vals), 0x0,
8193         NULL, HFILL }
8194     },
8195     /* LLRP RDM Command Start Code */
8196     { &hf_rdmnet_llrp_rdm_command_start_code,
8197       { "RDM Command", "rdmnet.llrp.rdm_command.start_code",
8198         FT_UINT8, BASE_DEC, VALS(rdmnet_llrp_rdm_command_start_code_vals), 0x0,
8199         NULL, HFILL }
8200     },
8201     /* RPT Vector */
8202     { &hf_rdmnet_rpt_vector,
8203       { "RPT Vector", "rdmnet.rpt_vector",
8204         FT_UINT8, BASE_DEC, VALS(rdmnet_rpt_vector_vals), 0x0,
8205         NULL, HFILL }
8206     },
8207     /* RPT Source UID */
8208     { &hf_rdmnet_rpt_source_uid,
8209       { "Source UID", "rdmnet.rpt.source_uid",
8210         FT_BYTES, SEP_SPACE, NULL, 0x0,
8211         NULL, HFILL }
8212     },
8213     /* RPT Source Endpoint ID */
8214     { &hf_rdmnet_rpt_source_endpoint_id,
8215       { "Source Endpoint ID", "rdmnet.rpt.source_endpoint_id",
8216         FT_UINT16, BASE_DEC, NULL, 0x0,
8217         NULL, HFILL }
8218     },
8219     /* RPT Destination UID */
8220     { &hf_rdmnet_rpt_destination_uid,
8221       { "Destination UID", "rdmnet.rpt.destination_uid",
8222         FT_BYTES, SEP_SPACE, NULL, 0x0,
8223         NULL, HFILL }
8224     },
8225     /* RPT Destination Endpoint ID */
8226     { &hf_rdmnet_rpt_destination_endpoint_id,
8227       { "Destination Endpoint ID", "rdmnet.rpt.destination_endpoint_id",
8228         FT_UINT16, BASE_DEC, NULL, 0x0,
8229         NULL, HFILL }
8230     },
8231     /* RPT Sequence Number */
8232     { &hf_rdmnet_rpt_sequence_number,
8233       { "Sequence Number", "rdmnet.rpt.sequence_number",
8234         FT_UINT32, BASE_DEC, NULL, 0x0,
8235         NULL, HFILL }
8236     },
8237     /* RPT Reserved */
8238     { &hf_rdmnet_rpt_reserved,
8239       { "Reserved", "rdmnet.rpt.reserved",
8240         FT_UINT8, BASE_DEC, NULL, 0x0,
8241         NULL, HFILL }
8242     },
8243     /* RPT Request Vector */
8244     { &hf_rdmnet_rpt_request_vector,
8245       { "RPT Request Vector", "rdmnet.rpt.request_vector",
8246         FT_UINT32, BASE_DEC, VALS(rdmnet_rpt_request_vals), 0x0,
8247         NULL, HFILL }
8248     },
8249     /* RPT Request RDM Command */
8250     { &hf_rdmnet_rpt_request_rdm_command,
8251       { "RDM Command", "rdmnet.rpt.request.rdm_command",
8252         FT_UINT8, BASE_DEC, VALS(rdmnet_rpt_request_rdm_command_start_code_vals), 0x0,
8253         NULL, HFILL }
8254     },
8255     /* RPT Status Vector */
8256     { &hf_rdmnet_rpt_status_vector,
8257       { "Status Vector", "rdmnet.rpt.status.vector",
8258         FT_UINT16, BASE_DEC, VALS(rdmnet_rpt_status_vector_vals), 0x0,
8259         NULL, HFILL }
8260     },
8261     /* RPT Status Unknown RPT UID String */
8262     { &hf_rdmnet_rpt_status_unknown_rpt_uid_string,
8263       { "Status", "rdmnet.rpt.status.unknown_rpt_uid_string",
8264         FT_STRING, BASE_NONE, NULL, 0x0,
8265         NULL, HFILL }
8266     },
8267     /* RPT Status RDM Timeout String */
8268     { &hf_rdmnet_rpt_status_rdm_timeout_string,
8269       { "Status", "rdmnet.rpt.status.rdm_timeout_string",
8270         FT_STRING, BASE_NONE, NULL, 0x0,
8271         NULL, HFILL }
8272     },
8273     /* RPT Status Invalid RDM Response String */
8274     { &hf_rdmnet_rpt_status_rdm_invalid_response_string,
8275       { "Status", "rdmnet.rpt.status.invalid_rdm_response_string",
8276         FT_STRING, BASE_NONE, NULL, 0x0,
8277         NULL, HFILL }
8278     },
8279     /* RPT Status Unknown RDM UID String */
8280     { &hf_rdmnet_rpt_status_unknown_rdm_uid_string,
8281       { "Status", "rdmnet.rpt.status.unknown_rdm_uid_string",
8282         FT_STRING, BASE_NONE, NULL, 0x0,
8283         NULL, HFILL }
8284     },
8285     /* RPT Status Unknown Endpoint String */
8286     { &hf_rdmnet_rpt_status_unknown_endpoint_string,
8287       { "Status", "rdmnet.rpt.status.unknown_endpoint_string",
8288         FT_STRING, BASE_NONE, NULL, 0x0,
8289         NULL, HFILL }
8290     },
8291     /* RPT Status Broadcast Complete String */
8292     { &hf_rdmnet_rpt_status_broadcast_complete_string,
8293       { "Status", "rdmnet.rpt.status.broadcast_complete_string",
8294         FT_STRING, BASE_NONE, NULL, 0x0,
8295         NULL, HFILL }
8296     },
8297     /* RPT Status Unknown Vector String */
8298     { &hf_rdmnet_rpt_status_unknown_vector_string,
8299       { "Status", "rdmnet.rpt.status.unknown_vector_string",
8300         FT_STRING, BASE_NONE, NULL, 0x0,
8301         NULL, HFILL }
8302     },
8303     /* RPT Notification Vector */
8304     { &hf_rdmnet_rpt_notification_vector,
8305       { "RPT Notification Vector", "rdmnet.rpt.notification_vector",
8306         FT_UINT32, BASE_DEC, VALS(rdmnet_rpt_notification_vals), 0x0,
8307         NULL, HFILL }
8308     },
8309     /* RPT Notification RDM Command */
8310     { &hf_rdmnet_rpt_notification_rdm_command,
8311       { "RDM Command", "rdmnet.rpt.notification.rdm_command",
8312         FT_UINT8, BASE_DEC, VALS(rdmnet_rpt_request_rdm_command_start_code_vals), 0x0,
8313         NULL, HFILL }
8314     },
8315     /* Broker Vector */
8316     { &hf_rdmnet_broker_vector,
8317       { "Broker Vector", "rdmnet.broker_vector",
8318         FT_UINT8, BASE_DEC, VALS(rdmnet_broker_vector_vals), 0x0,
8319         NULL, HFILL }
8320     },
8321     /* Broker Client Protocol Vector */
8322     { &hf_rdmnet_broker_client_protocol_vector,
8323       { "Client Protocol", "rdmnet.broker_client_protocol_vector",
8324         FT_UINT32, BASE_DEC, VALS(broker_client_protocol_vals), 0x0,
8325         NULL, HFILL }
8326     },
8327     /* Broker Client Protocol CID */
8328     { &hf_rdmnet_broker_client_protocol_cid,
8329       { "Client CID", "rdmnet.broker_client_cid",
8330         FT_BYTES, SEP_SPACE, NULL, 0x0,
8331         NULL, HFILL }
8332     },
8333     /* Broker Client RPT Client UID */
8334     { &hf_rdmnet_broker_client_rpt_client_uid,
8335       { "Client UID", "rdmnet.broker_client_rpt_client_uid",
8336         FT_BYTES, SEP_SPACE, NULL, 0x0,
8337         NULL, HFILL }
8338     },
8339     /* Broker Client RPT Client Type */
8340     { &hf_rdmnet_broker_client_rpt_client_type,
8341       { "RPT client type", "rdmnet.broker_client_rpt_client_type",
8342         FT_UINT8, BASE_DEC, VALS(broker_client_rpt_client_type_vals), 0x0,
8343         NULL, HFILL }
8344     },
8345     /* Broker Client RPT Binding CID */
8346     { &hf_rdmnet_broker_client_rpt_binding_cid,
8347       { "Binding CID", "rdmnet.broker_client_rpt_binding_cid",
8348         FT_BYTES, SEP_SPACE, NULL, 0x0,
8349         NULL, HFILL }
8350     },
8351     /* Broker Client EPT Protocol Vector */
8352     { &hf_rdmnet_broker_client_ept_protocol_vector,
8353       { "Protocol Vector", "rdmnet.broker_client_ept_vector",
8354         FT_BYTES, SEP_SPACE, NULL, 0x0,
8355         NULL, HFILL }
8356     },
8357     /* Broker Client EPT Manufacturer ID */
8358     { &hf_rdmnet_broker_client_ept_protocol_manufacturer_id,
8359       { "Manufacturer ID", "rdmnet.broker_client_ept_manufacturer_id",
8360         FT_UINT16, BASE_HEX, NULL, 0x0,
8361         NULL, HFILL }
8362     },
8363     /* Broker Client EPT Protocol ID */
8364     { &hf_rdmnet_broker_client_ept_protocol_protocol_id,
8365       { "Protocol ID", "rdmnet.broker_client_ept_protocol_id",
8366         FT_UINT16, BASE_HEX, NULL, 0x0,
8367         NULL, HFILL }
8368     },
8369     /* Broker Client EPT Protocol String */
8370     { &hf_rdmnet_broker_client_ept_protocol_string,
8371       { "Protocol String", "rdmnet.broker_client_ept_protocol_string",
8372         FT_STRING, BASE_NONE, NULL, 0x0,
8373         NULL, HFILL }
8374     },
8375     /* Broker Connect Scope */
8376     { &hf_rdmnet_broker_connect_client_scope,
8377       { "Client Scope", "rdmnet.broker.connect.client_scope",
8378         FT_STRING, BASE_NONE, NULL, 0x0,
8379         NULL, HFILL }
8380     },
8381     /* Broker Connect E1.33 Version */
8382     { &hf_rdmnet_broker_connect_e133_version,
8383       { "E1.33 Version", "rdmnet.broker.connect.e133_version",
8384         FT_UINT16, BASE_DEC, NULL, 0x0,
8385         NULL, HFILL }
8386     },
8387     /* Broker Connect Search Domain */
8388     { &hf_rdmnet_broker_connect_search_domain,
8389       { "Search Domain", "rdmnet.broker.connect.search_domain",
8390         FT_STRING, BASE_NONE, NULL, 0x0,
8391         NULL, HFILL }
8392     },
8393     /* Broker Connect Connection Flags */
8394     { &hf_rdmnet_broker_connect_connection_flags,
8395       { "Flags", "rdmnet.broker.connect.flags",
8396         FT_UINT8, BASE_HEX, NULL, 0x0,
8397         "Connection Flags", HFILL }
8398     },
8399     { &hf_rdmnet_broker_connect_connection_flags_incremental_updates,
8400       { "Incremental Updates", "rdmnet.broker.connect.flags_incremental_updates",
8401         FT_BOOLEAN, 8, NULL, RDMNET_BROKER_VECTOR_CONNECT_INCREMENTAL_UPDATES,
8402         "Incremental updates flag", HFILL }
8403     },
8404     /* Broker Connect Reply Connection Code */
8405     { &hf_rdmnet_broker_connect_reply_connection_code,
8406       { "Connection Code", "rdmnet.broker.connect_reply.connection_code",
8407         FT_UINT16, BASE_DEC, VALS(rdmnet_broker_status_code_vals), 0x0,
8408         NULL, HFILL }
8409     },
8410     /* Broker Connect Reply E1.33 Version */
8411     { &hf_rdmnet_broker_connect_reply_e133_version,
8412       { "E1.33 Version", "rdmnet.broker.connect_reply.e133_version",
8413         FT_UINT16, BASE_DEC, NULL, 0x0,
8414         NULL, HFILL }
8415     },
8416     /* Broker Connect Reply Broker UID */
8417     { &hf_rdmnet_broker_connect_reply_broker_uid,
8418       { "Broker UID", "rdmnet.broker.connect_reply.broker_uid",
8419         FT_BYTES, SEP_SPACE, NULL, 0x0,
8420         NULL, HFILL }
8421     },
8422     /* Broker Connect Reply Client UID */
8423     { &hf_rdmnet_broker_connect_reply_client_uid,
8424       { "Client UID", "rdmnet.broker.connect_reply.client_uid",
8425         FT_BYTES, SEP_SPACE, NULL, 0x0,
8426         NULL, HFILL }
8427     },
8428     /* Broker Client Entry Update Connection Flags */
8429     { &hf_rdmnet_broker_client_entry_update_connection_flags,
8430       { "Flags", "rdmnet.broker.client_entry_update.flags",
8431         FT_UINT8, BASE_HEX, NULL, 0x0,
8432         "Connection Flags", HFILL }
8433     },
8434     { &hf_rdmnet_broker_client_entry_update_connection_flags_incremental_updates,
8435       { "Incremental Updates", "rdmnet.broker.client_entry_update.flags_incremental_updates",
8436         FT_BOOLEAN, 8, NULL, RDMNET_BROKER_VECTOR_CONNECT_INCREMENTAL_UPDATES,
8437         "Incremental updates flag", HFILL }
8438     },
8439     /* Broker Redirect IPv4 Address */
8440     { &hf_rdmnet_broker_redirect_ipv4_address,
8441       { "IPv4 Address", "rdmnet.broker.redirect_ipv4.ipv4_address",
8442         FT_IPv4, BASE_NONE, NULL, 0x0,
8443         "Redirect IPv4 address", HFILL }
8444     },
8445     /* Broker Redirect IPv4 TCP Port */
8446     { &hf_rdmnet_broker_redirect_ipv4_tcp_port,
8447       { "IPv4 TCP Port", "rdmnet.broker.redirect_ipv4.tcp_port",
8448         FT_UINT16, BASE_DEC, NULL, 0x0,
8449         "Redirect IPv4 TCP port", HFILL }
8450     },
8451     /* Broker Redirect IPv6 Address */
8452     { &hf_rdmnet_broker_redirect_ipv6_address,
8453       { "IPv6 Address", "rdmnet.broker.redirect_ipv6.ipv4_address",
8454         FT_IPv6, BASE_NONE, NULL, 0x0,
8455         "Redirect IPv6 address", HFILL }
8456     },
8457     /* Broker Redirect IPv6 TCP Port */
8458     { &hf_rdmnet_broker_redirect_ipv6_tcp_port,
8459       { "TCP Port", "rdmnet.broker.redirect_ipv6.tcp_port",
8460         FT_UINT16, BASE_DEC, NULL, 0x0,
8461         "Redirect IPv6 TCP port", HFILL }
8462     },
8463     /* Broker Disconnect Reason */
8464     { &hf_rdmnet_broker_disconnect_reason,
8465       { "Reason", "rdmnet.broker.disconnect.reason",
8466         FT_UINT16, BASE_DEC, VALS(rdmnet_broker_disconnect_reason_vals), 0x0,
8467         "Disconnect reason", HFILL }
8468     },
8469     /* Broker Dynamic UID Request */
8470     { &hf_rdmnet_broker_dynamic_uid_request,
8471       { "Dynamic UID Request", "rdmnet.broker.request_dynamic_uids.dynamic_uid_request",
8472         FT_BYTES, SEP_DOT, NULL, 0x0,
8473         NULL, HFILL }
8474     },
8475     /* Broker RID */
8476     { &hf_rdmnet_broker_rid,
8477       { "RID", "rdmnet.broker.request_dynamic_uids.rid",
8478         FT_BYTES, SEP_DOT, NULL, 0x0,
8479         NULL, HFILL }
8480     },
8481     /* Broker Assigned Dynamic UID */
8482     { &hf_rdmnet_broker_assigned_dynamic_uid,
8483       { "Dynamic UID Request", "rdmnet.broker.assigned_dynamic_uids.dynamic_uid",
8484         FT_BYTES, SEP_DOT, NULL, 0x0,
8485         NULL, HFILL }
8486     },
8487     /* Broker Assigned RID */
8488     { &hf_rdmnet_broker_assigned_rid,
8489       { "RID", "rdmnet.broker.assigned_dynamic_uids.rid",
8490         FT_BYTES, SEP_DOT, NULL, 0x0,
8491         NULL, HFILL }
8492     },
8493     /* Broker_Assigned Status Code */
8494     { &hf_rdmnet_broker_assigned_status_code,
8495       { "Status Code", "rdmnet.broker.assigned_dynamic_uids.status_code",
8496         FT_UINT16, BASE_DEC, VALS(dynamic_uid_mapping_status_code_vals), 0x0,
8497         NULL, HFILL }
8498     },
8499     /* Broker Fetch Dynamic UID */
8500     { &hf_rdmnet_broker_fetch_dynamic_uid,
8501       { "Dynamic UID", "rdmnet.broker.fetch_dynamic_uids.dynamic_uid",
8502         FT_BYTES, SEP_DOT, NULL, 0x0,
8503         NULL, HFILL }
8504     },
8505     /* EPT Vector */
8506     { &hf_rdmnet_ept_vector,
8507       { "EPT Vector", "rdmnet.ept_vector",
8508         FT_UINT8, BASE_DEC, VALS(rdmnet_ept_vector_vals), 0x0,
8509         NULL, HFILL }
8510     },
8511     /* EPT Destination CID */
8512     { &hf_rdmnet_ept_destination_cid,
8513       { "Destination CID", "rdmnet.ept.destination_cid",
8514         FT_BYTES, SEP_SPACE, NULL, 0x0,
8515         NULL, HFILL }
8516     },
8517     /* EPT Data PDU Length */
8518     { &hf_rdmnet_ept_data_pdu_length,
8519       { "Length", "rdmnet.ept.data.pdu.length",
8520         FT_UINT24, BASE_DEC, NULL, 0x0,
8521         "PDU Length", HFILL }
8522     },
8523     /* EPT Data Vector */
8524     { &hf_rdmnet_ept_data_vector,
8525       { "Vector", "rdmnet.ept.data.vector",
8526         FT_UINT32, BASE_HEX, NULL, 0x0,
8527         "Data vector", HFILL }
8528     },
8529     /* EPT Data Vector Manufacturer ID */
8530     { &hf_rdmnet_ept_data_vector_manufacturer_id,
8531       { "Manufac. ID", "rdmnet.ept.data.vector.manufacturer_id",
8532         FT_UINT16, BASE_HEX, NULL, 0x0,
8533         "Manufacturer id", HFILL }
8534     },
8535     /* EPT Data Vector Protocol ID */
8536     { &hf_rdmnet_ept_data_vector_protocol_id,
8537       { "Protocol", "rdmnet.ept.data.vector.protocol_id",
8538         FT_UINT16, BASE_HEX, NULL, 0x0,
8539         "Protocol id", HFILL }
8540     },
8541     /* EPT Data Opaque Data */
8542     { &hf_rdmnet_ept_data_opaque_data,
8543       { "Data", "rdmnet.ept.data.opaque_data",
8544         FT_BYTES, SEP_SPACE, NULL, 0x0,
8545         NULL, HFILL }
8546     },
8547     /* EPT Status PDU Length */
8548     { &hf_rdmnet_ept_status_pdu_length,
8549       { "Length", "rdmnet.ept.status.pdu.length",
8550         FT_UINT24, BASE_DEC, NULL, 0x0,
8551         "PDU Length", HFILL }
8552     },
8553     /* EPT Status Unknown CID */
8554     { &hf_rdmnet_ept_status_unknown_cid,
8555       { "Unknown CID", "rdmnet.ept.status.unknown_cid",
8556         FT_BYTES, SEP_SPACE, NULL, 0x0,
8557         NULL, HFILL }
8558     },
8559     /* EPT Status Status String */
8560     { &hf_rdmnet_ept_status_status_string,
8561       { "Status String", "rdmnet.ept.status.status_string",
8562         FT_STRING, BASE_NONE, NULL, 0x0,
8563         NULL, HFILL }
8564     },
8565     /* EPT Status Vector */
8566     { &hf_rdmnet_ept_status_vector,
8567       { "Unknown Vector", "rdmnet.ept.status.vector",
8568         FT_BYTES, SEP_SPACE, NULL, 0x0,
8569         NULL, HFILL }
8570     },
8571     /* EPT Status Unknown Vector */
8572     { &hf_rdmnet_ept_status_unknown_vector,
8573       { "Unknown Vector", "rdmnet.ept.status.unknown_vector",
8574         FT_BYTES, SEP_SPACE, NULL, 0x0,
8575         NULL, HFILL }
8576     },
8577     /* EPT Status Vector String */
8578     { &hf_rdmnet_ept_status_vector_string,
8579       { "Vector String", "rdmnet.ept.status.vector_string",
8580         FT_STRING, BASE_NONE, NULL, 0x0,
8581         NULL, HFILL }
8582     }
8583   };
8584 
8585   /* Setup protocol subtree array */
8586   static gint *ett[] = {
8587     &ett_acn,
8588     &ett_acn_channel_owner_info_block,
8589     &ett_acn_channel_member_info_block,
8590     &ett_acn_channel_parameter,
8591     &ett_acn_address,
8592     &ett_acn_address_type,
8593     &ett_acn_pdu_flags,
8594     &ett_acn_dmp_pdu,
8595     &ett_acn_sdt_pdu,
8596     &ett_acn_sdt_client_pdu,
8597     &ett_acn_sdt_base_pdu,
8598     &ett_acn_root_pdu,
8599     &ett_acn_dmx_address,
8600     &ett_acn_dmx_2_options,
8601     &ett_acn_dmx_data_pdu,
8602     &ett_acn_dmx_pdu,
8603     &ett_acn_blob
8604   };
8605 
8606   /* Setup protocol subtree array */
8607   static gint *magic_ett[] = {
8608     &ett_magic
8609   };
8610 
8611   /* Setup protocol subtree array */
8612   static gint *rdmnet_ett[] = {
8613     &ett_rdmnet,
8614     &ett_rdmnet_pdu_flags,
8615     &ett_rdmnet_llrp_base_pdu,
8616     &ett_rdmnet_llrp_probe_request_pdu,
8617     &ett_rdmnet_llrp_probe_request_filter_flags,
8618     &ett_rdmnet_llrp_probe_reply_pdu,
8619     &ett_rdmnet_llrp_rdm_command_pdu,
8620     &ett_rdmnet_rpt_base_pdu,
8621     &ett_rdmnet_rpt_request_pdu,
8622     &ett_rdmnet_rpt_status_pdu,
8623     &ett_rdmnet_rpt_notification_pdu,
8624     &ett_rdmnet_broker_base_pdu,
8625     &ett_rdmnet_broker_client_entry_pdu,
8626     &ett_rdmnet_broker_client_entry_manufacturer_protocol_ids,
8627     &ett_rdmnet_broker_connect_connection_flags,
8628     &ett_rdmnet_broker_client_entry_update_connection_flags,
8629     &ett_rdmnet_ept_base_pdu,
8630     &ett_rdmnet_ept_data_pdu,
8631     &ett_rdmnet_ept_data_vector_pdu,
8632     &ett_rdmnet_ept_status_pdu
8633   };
8634 
8635   static ei_register_info ei[] = {
8636     { &ei_magic_reply_invalid_type, { "magic.reply.invalid_type", PI_PROTOCOL, PI_WARN, "Invalid type", EXPFILL }},
8637   };
8638 
8639   module_t *acn_module;
8640   expert_module_t* expert_acn;
8641 
8642   proto_acn = proto_register_protocol (
8643     "Architecture for Control Networks", /* name */
8644     "ACN",                               /* short name */
8645     "acn"                                /* abbrev */
8646     );
8647 
8648   proto_magic = proto_register_protocol(
8649     "Magic Bullet",                      /* name */
8650     "MAGIC",                             /* short name */
8651     "magic"                              /* abbrev */
8652     );
8653 
8654   proto_rdmnet = proto_register_protocol(
8655     "RDMnet",                            /* name */
8656     "RDMnet",                            /* short name */
8657     "rdmnet"                             /* abbrev */
8658     );
8659 
8660   proto_register_field_array(proto_acn, hf, array_length(hf));
8661   proto_register_subtree_array(ett, array_length(ett));
8662 
8663   acn_module = prefs_register_protocol(proto_acn, NULL);
8664   prefs_register_obsolete_preference(acn_module, "heuristic_acn");
8665 
8666   prefs_register_bool_preference(acn_module, "dmx_enable",
8667                                  "Streaming DMX",
8668                                  "Enable Streaming DMX extension dissector (ANSI BSR E1.31)",
8669                                  &global_acn_dmx_enable);
8670 
8671   prefs_register_enum_preference(acn_module, "dmx_display_view",
8672                                  "DMX, display format",
8673                                  "Display format",
8674                                  &global_acn_dmx_display_view,
8675                                  dmx_display_view,
8676                                  TRUE);
8677 
8678   prefs_register_bool_preference(acn_module, "dmx_display_zeros",
8679                                  "DMX, display zeros",
8680                                  "Display zeros instead of dots",
8681                                  &global_acn_dmx_display_zeros);
8682 
8683   prefs_register_bool_preference(acn_module, "dmx_display_leading_zeros",
8684                                  "DMX, display leading zeros",
8685                                  "Display leading zeros on levels",
8686                                  &global_acn_dmx_display_leading_zeros);
8687 
8688   prefs_register_enum_preference(acn_module, "dmx_display_line_format",
8689                                  "DMX, display line format",
8690                                  "Display line format",
8691                                  &global_acn_dmx_display_line_format,
8692                                  dmx_display_line_format,
8693                                  TRUE);
8694 
8695   proto_register_field_array(proto_magic, magic_hf, array_length(magic_hf));
8696   proto_register_subtree_array(magic_ett, array_length(magic_ett));
8697   expert_acn = expert_register_protocol(proto_magic);
8698   expert_register_field_array(expert_acn, ei, array_length(ei));
8699 
8700   proto_register_field_array(proto_rdmnet, rdmnet_hf, array_length(rdmnet_hf));
8701   proto_register_subtree_array(rdmnet_ett, array_length(rdmnet_ett));
8702 }
8703 
8704 
8705 /******************************************************************************/
8706 /* Register handoff                                                           */
8707 void
proto_reg_handoff_acn(void)8708 proto_reg_handoff_acn(void)
8709 {
8710   /* dissector_handle_t acn_handle; */
8711   /* acn_handle = create_dissector_handle(dissect_acn, proto_acn); */
8712   /* dissector_add_for_decode_as_with_preference("udp.port", acn_handle);                         */
8713 
8714   rdm_handle      = find_dissector_add_dependency("rdm", proto_acn);
8715 
8716   heur_dissector_add("udp", dissect_acn_heur, "ACN", "acn", proto_acn, HEURISTIC_DISABLE);
8717   heur_dissector_add("udp", dissect_rdmnet_over_udp_heur, "RDMnet over UDP (LLRP)", "rdmnet_udp", proto_acn, HEURISTIC_DISABLE);
8718   heur_dissector_add("tcp", dissect_rdmnet_over_tcp_heur, "RDMnet over TCP (Broker, RPT, EPT)", "rdmnet_tcp", proto_acn, HEURISTIC_DISABLE);
8719 }
8720 
8721 /*
8722  * Editor modelines
8723  *
8724  * Local Variables:
8725  * c-basic-offset: 2
8726  * tab-width: 8
8727  * indent-tabs-mode: nil
8728  * End:
8729  *
8730  * ex: set shiftwidth=2 tabstop=8 expandtab:
8731  * :indentSize=2:tabSize=8:noTabs=true:
8732  */
8733