f2c4ee174fd4c5a0a607ff2c6fc7e3758bc5670a
[obnox/wireshark/wip.git] / plugins / artnet / packet-artnet.c
1 /* packet-artnet.c
2  * Routines for Art-Net packet disassembly
3  *
4  * $Id$
5  *
6  * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1999 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /* Include files */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "plugins/plugin_api.h"
34
35 #include "moduleinfo.h"
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <gmodule.h>
40 #include <ctype.h>
41 #include <time.h>
42 #include <string.h>
43 #include <epan/packet.h>
44 #include <epan/addr_resolv.h>
45 #include <epan/prefs.h>
46 #include <epan/strutil.h>
47
48 #include "plugins/plugin_api_defs.h"
49
50 /* Define version if we are not building ethereal statically */
51
52 #ifndef ENABLE_STATIC
53 G_MODULE_EXPORT const gchar version[] = VERSION;
54 #endif
55
56 /*
57  * See
58  *
59  *      http://www.artisticlicence.com/art-net.pdf
60  */
61
62 /* Define udp_port for ArtNET */
63
64 #define UDP_PORT_ARTNET 0x1936
65
66 #define ARTNET_HEADER_LENGTH                 10
67 #define ARTNET_POLL_LENGTH                   4
68 #define ARTNET_POLL_REPLY_LENGTH             197
69 #define ARTNET_POLL_REPLY_PORT_INFO_LENGTH   22
70 #define ARTNET_POLL_REPLY_PORT_TYPES_LENGTH  4
71 #define ARTNET_POLL_REPLY_GOOD_INPUT_LENGTH  4
72 #define ARTNET_POLL_REPLY_GOOD_OUTPUT_LENGTH 4
73 #define ARTNET_POLL_REPLY_SWIN_LENGTH        4
74 #define ARTNET_POLL_REPLY_SWOUT_LENGTH       4
75 #define ARTNET_ADDRESS_LENGTH                97
76 #define ARTNET_ADDRESS_SWIN_LENGTH           4
77 #define ARTNET_ADDRESS_SWOUT_LENGTH          4
78 #define ARTNET_OUTPUT_LENGTH                 1
79 #define ARTNET_INPUT_LENGTH                  10
80 #define ARTNET_INPUT_INPUT_LENGTH            4
81 #define ARTNET_FIRMWARE_MASTER_LENGTH        1035
82 #define ARTNET_FIRMWARE_REPLY_LENGTH         26
83 #define ARTNET_VIDEO_SETUP_LENGTH            74
84 #define ARTNET_VIDEO_PALETTE_LENGTH          55
85 #define ARTNET_VIDEO_DATA_LENGTH             8
86
87
88 #define ARTNET_OP_POLL               0x2000
89 #define ARTNET_OP_POLL_REPLY         0x2100
90 #define ARTNET_OP_POLL_SERVER_REPLY  0x2200
91 #define ARTNET_OP_OUTPUT             0x5000
92 #define ARTNET_OP_ADDRESS            0x6000
93 #define ARTNET_OP_INPUT              0x7000
94 #define ARTNET_OP_VIDEO_SETUP        0xa010
95 #define ARTNET_OP_VIDEO_PALETTE      0xa020
96 #define ARTNET_OP_VIDEO_DATA         0xa040
97
98 #define ARTNET_OP_TOD_REQUEST        0x8000
99 #define ARTNET_OP_TOD_DATA           0x8100
100 #define ARTNET_OP_TOD_CONTROL        0x8200
101 #define ARTNET_OP_RDM                0x8300
102
103 #define ARTNET_OP_MAC_MASTER         0xf000
104 #define ARTNET_OP_MAC_SLAVE          0xf100
105 #define ARTNET_OP_FIRMWARE_MASTER    0xf200
106 #define ARTNET_OP_FIRMWARE_REPLY     0xf300
107
108 #define ARTNET_OP_IP_PROG            0xf800
109 #define ARTNET_OP_IP_PROG_REPLY      0xf900
110
111 static const value_string artnet_opcode_vals[] = {
112   { ARTNET_OP_POLL,              "ArtPoll packet" },
113   { ARTNET_OP_POLL_REPLY,        "ArtPollReply packet" },
114   { ARTNET_OP_POLL_SERVER_REPLY, "ArtPollServerReply packet" },
115   { ARTNET_OP_OUTPUT,            "ArtDMX data packet" },
116   { ARTNET_OP_ADDRESS,           "ArtAddress packet" },
117   { ARTNET_OP_INPUT,             "ArtInput packet" },
118   { ARTNET_OP_VIDEO_SETUP,       "ArtVideoSetup packet" },
119   { ARTNET_OP_VIDEO_PALETTE,     "ArtVideoPalette packet" },
120   { ARTNET_OP_VIDEO_DATA,        "ArtVideoData packet" },
121   { ARTNET_OP_TOD_REQUEST,       "ArtTodRequest packet" },
122   { ARTNET_OP_TOD_DATA,          "ArtTodData packet" },
123   { ARTNET_OP_TOD_CONTROL,       "ArtTodControl packet" },
124   { ARTNET_OP_RDM,               "ArtRdm packet" },
125   { ARTNET_OP_MAC_MASTER,        "ArtMacMaster packet" },
126   { ARTNET_OP_MAC_SLAVE,         "ArtMacSlave packet" },
127   { ARTNET_OP_FIRMWARE_MASTER,   "ArtFirmwareMaster packet" },
128   { ARTNET_OP_FIRMWARE_REPLY,    "ArtFirmwareReply packet" },
129   { ARTNET_OP_IP_PROG,           "ArtIpProg packet" },
130   { ARTNET_OP_IP_PROG_REPLY,     "ArtIpProgReply packet" },
131   { 0,                           NULL }
132 };
133
134 static const value_string artnet_oem_code_vals[] = {
135   { 0x0000, "Artistic Licence:DMX-Hub:4x DMX in,4x DMX out" },
136   { 0x0001, "ADB:Netgate:4x DMX in,4x DMX out" },
137   { 0x0002, "MA Lighting:TBA:4x DMX in,4x DMX out" },
138   { 0x0003, "Artistic Licence:Ether-Lynx:2x DMX in,4x DMX out" },
139   { 0x0004, "LewLight:Capture v2:TBA" },
140   { 0x0005, "High End:TBA:TBA" },
141   { 0x0006, "Avolites:TBA:TBA" },
142   { 0x0010, "Artistic Licence:Down-Lynx:2x DMX out. Wall Panel." },
143   { 0x0011, "Artistic Licence:Up-Lynx:2x DMX in. Wall Panel" },
144   { 0x0014, "Artistic Licence:Net-Lynx O/P:2x DMX out. Boxed Product" },
145   { 0x0015, "Artistic Licence:Net-Lynx I/P:2x DMX in. Boxed Product" },
146   { 0x0030, "Doug Fleenor Design:TBA:2x DMX out" },
147   { 0x0031, "Doug Fleenor Design:TBA:2x DMX in" },
148   { 0x0050, "Goddard Design:DMX-Link (tm) O/P:2x DMX out" },
149   { 0x0051, "Goddard Design:DMX-Link (tm) I/P:2x DMX in" },
150   { 0x0070, "ADB:Net-Port O/P:2x DMX out" },
151   { 0x0071, "ADB:Net-Port I/P:2x DMX in" },
152   { 0x0072, "ADB:Reserved:" },
153   { 0x0073, "ADB:Reserved:" },
154   { 0x0074, "ADB:Reserved:" },
155   { 0x0075, "ADB:Reserved:" },
156   { 0x0076, "ADB:Reserved:" },
157   { 0x0077, "ADB:Reserved:" },
158   { 0x0078, "ADB:Reserved:" },
159   { 0x0079, "ADB:Reserved:" },
160   { 0x007A, "ADB:Reserved:" },
161   { 0x007B, "ADB:Reserved:" },
162   { 0x007C, "ADB:Reserved:" },
163   { 0x007D, "ADB:Reserved:" },
164   { 0x007E, "ADB:Reserved:" },
165   { 0x007F, "ADB:Reserved:" },
166   { 0x008C, "Zero 88:TBA:2x DMX out" },
167   { 0x008D, "Zero 88:TBA:2x DMX in" },
168   { 0x008E, "Flying Pig:TBA:2x DMX out" },
169   { 0x008F, "Flying Pig:TBA:2x DMX in" },
170   { 0x0090, "ELC:ELC 2:2x DMX out" },
171   { 0x0091, "ELC:ELC 4:4x DMX in. 4x DMX out" },
172   { 0x0180, "Martin:Maxxyz:4x DMX in. 4x DMX out" },
173   { 0x0190, "Enttec:Reserved:" },
174   { 0x0191, "Enttec:Reserved:" },
175   { 0x0192, "Enttec:Reserved:" },
176   { 0x0193, "Enttec:Reserved:" },
177   { 0x0194, "Enttec:Reserved:" },
178   { 0x0195, "Enttec:Reserved:" },
179   { 0x0196, "Enttec:Reserved:" },
180   { 0x0197, "Enttec:Reserved:" },
181   { 0x0198, "Enttec:Reserved:" },
182   { 0x0199, "Enttec:Reserved:" },
183   { 0x019A, "Enttec:Reserved:" },
184   { 0x019B, "Enttec:Reserved:" },
185   { 0x019C, "Enttec:Reserved:" },
186   { 0x019D, "Enttec:Reserved:" },
187   { 0x019E, "Enttec:Reserved:" },
188   { 0x019F, "Enttec:Reserved:" },
189   { 0x8000, "ADB:Netgate XT:Video output and trigger inputs" },
190   { 0x8001, "Artistic Licence:Net-Patch:TBA" },
191   { 0x8002, "Artistic Licence:DMX-Hub XT:Video output and trigger inputs" },
192   { 0x8003, "Artistic Licence:No-Worries XT:Real time data record - playback" },
193   { 0,      NULL }
194 };
195
196 static const value_string artnet_esta_man_vals[] = {
197   { 0x414C, "Artistic Licence" },
198   { 0,      NULL }
199 };
200
201 #define ARTNET_AC_NONE           0x00
202 #define ARTNET_AC_CANCEL_MERGE   0x01
203 #define ARTNET_AC_LED_NORMAL     0x02
204 #define ARTNET_AC_LED_MUTE       0x03
205 #define ARTNET_AC_LED_LOCATE     0x04
206 #define ARTNET_AC_RESET_RX_FLAGS 0x05
207 #define ARTNET_AC_MERGE_LTP0     0x10
208 #define ARTNET_AC_MERGE_LTP1     0x11
209 #define ARTNET_AC_MERGE_LTP2     0x12
210 #define ARTNET_AC_MERGE_LTP3     0x13
211 #define ARTNET_AC_MERGE_HTP0     0x50
212 #define ARTNET_AC_MERGE_HTP1     0x51
213 #define ARTNET_AC_MERGE_HTP2     0x52
214 #define ARTNET_AC_MERGE_HTP3     0x53
215 #define ARTNET_AC_CLEAR_OP0      0x90
216 #define ARTNET_AC_CLEAR_OP1      0x91
217 #define ARTNET_AC_CLEAR_OP2      0x92
218 #define ARTNET_AC_CLEAR_OP3      0x93
219
220 static const value_string artnet_address_command_vals[] = {
221   { ARTNET_AC_NONE,            "No Action" },
222   { ARTNET_AC_CANCEL_MERGE,    "Cancel merge" },
223   { ARTNET_AC_LED_NORMAL,      "LED Normal" },
224   { ARTNET_AC_LED_MUTE,        "LED Mute" },
225   { ARTNET_AC_LED_LOCATE,      "LED Locate" },
226   { ARTNET_AC_RESET_RX_FLAGS,  "Reset SIP text" },
227   { ARTNET_AC_MERGE_LTP0,      "DMX port 1 LTP" },
228   { ARTNET_AC_MERGE_LTP1,      "DMX port 2 LTP" },
229   { ARTNET_AC_MERGE_LTP2,      "DXM port 3 LTP" },
230   { ARTNET_AC_MERGE_LTP3,      "DMX port 4 LTP" },
231   { ARTNET_AC_MERGE_HTP0,      "DMX port 1 HTP" },
232   { ARTNET_AC_MERGE_HTP1,      "DMX port 2 HTP" },
233   { ARTNET_AC_MERGE_HTP2,      "DXM port 3 HTP" },
234   { ARTNET_AC_MERGE_HTP3,      "DMX port 4 HTP" },
235   { ARTNET_AC_CLEAR_OP0,       "Clear DMX port 1" },
236   { ARTNET_AC_CLEAR_OP1,       "Clear DMX port 2" },
237   { ARTNET_AC_CLEAR_OP2,       "Clear DXM port 3" },
238   { ARTNET_AC_CLEAR_OP3,       "Clear DMX port 4" },
239   { 0,                         NULL }
240 };
241
242 #define ARTNET_FT_FIRM_FIRST 0x00
243 #define ARTNET_FT_FIRM_CONT  0x01
244 #define ARTNET_FT_FIRM_LAST  0x02
245 #define ARTNET_FT_UBEA_FIRST 0x03
246 #define ARTNET_FT_UBEA_CONT  0x04
247 #define ARTNET_FT_UBEA_LAST  0x05
248
249 static const value_string artnet_firmware_master_type_vals[] = {
250   { ARTNET_FT_FIRM_FIRST, "FirmFirst" },
251   { ARTNET_FT_FIRM_CONT,  "FirmCont" },
252   { ARTNET_FT_FIRM_LAST,  "FirmLast" },
253   { ARTNET_FT_UBEA_FIRST, "UbeaFirst" },
254   { ARTNET_FT_UBEA_CONT,  "UbeaCont" },
255   { ARTNET_FT_UBEA_LAST,  "UbeaLast" },
256   { 0,                    NULL }
257 };
258
259 #define ARTNET_FRT_FIRM_BLOCK_GOOD 0x00
260 #define ARTNET_FRT_FIRM_ALL_GOOD   0x01
261 #define ARTNET_FRT_FIRM_FAIL       0xff
262
263 static const value_string artnet_firmware_reply_type_vals[] = {
264   { ARTNET_FRT_FIRM_BLOCK_GOOD, "FirmBlockGood" },
265   { ARTNET_FRT_FIRM_ALL_GOOD,   "FirmAllGood" },
266   { ARTNET_FRT_FIRM_FAIL,       "FirmFail" },
267   { 0,                          NULL }
268 };
269
270 static const value_string artnet_tod_request_command_vals[] = {
271   { 0,                   NULL }
272 };
273
274 #define ARTNET_TDC_TOD_FULL    0x00
275 #define ARTNET_TDC_TOD_NAK     0xFF
276
277 static const value_string artnet_tod_data_command_vals[] = {
278   { ARTNET_TDC_TOD_FULL,    "TodFull" },
279   { ARTNET_TDC_TOD_NAK,     "TodNak" },
280   { 0,                      NULL }
281 };
282
283 #define ARTNET_TCC_ATC_NONE  0x00
284 #define ARTNET_TCC_ATC_FLUSH 0x01
285
286 static const value_string artnet_tod_control_command_vals[] = {
287   { ARTNET_TCC_ATC_NONE,  "AtcNone" },
288   { ARTNET_TCC_ATC_FLUSH, "AtcFlush" },
289   { 0,                    NULL }
290 };
291
292 #define ARTNET_RC_AR_PROCESS  0x00
293
294 static const value_string artnet_rdm_command_vals[] = {
295   { ARTNET_RC_AR_PROCESS,  "ArProcess" },
296   { 0,                     NULL }
297 };
298
299 void proto_reg_handoff_artnet(void);
300
301 /* Define the artnet proto */
302 static int proto_artnet = -1;
303
304
305 /* general */
306 static int hf_artnet_filler = -1;
307 static int hf_artnet_spare = -1;
308
309 /* Header */
310 static int hf_artnet_header = -1;
311 static int hf_artnet_header_id = -1;
312 static int hf_artnet_header_opcode = -1;
313 static int hf_artnet_header_protver = -1;
314
315 /* ArtPoll */
316 static int hf_artnet_poll = -1;
317 static int hf_artnet_poll_talktome = -1;
318 static int hf_artnet_poll_talktome_reply_dest = -1;
319 static int hf_artnet_poll_talktome_reply_type = -1;
320 static int hf_artnet_poll_talktome_unused = -1;
321
322 /* ArtPollReply */
323 static int hf_artnet_poll_reply = -1;
324 static int hf_artnet_poll_reply_ip_address = -1;
325 static int hf_artnet_poll_reply_port_nr = -1;
326 static int hf_artnet_poll_reply_versinfo = -1;
327 static int hf_artnet_poll_reply_subswitch = -1;
328 static int hf_artnet_poll_reply_oem = -1;
329 static int hf_artnet_poll_reply_ubea_version = -1;
330 static int hf_artnet_poll_reply_status = -1;
331 static int hf_artnet_poll_reply_esta_man = -1;
332 static int hf_artnet_poll_reply_short_name = -1;
333 static int hf_artnet_poll_reply_long_name = -1;
334 static int hf_artnet_poll_reply_node_report = -1;
335 static int hf_artnet_poll_reply_port_info = -1;
336 static int hf_artnet_poll_reply_num_ports = -1;
337 static int hf_artnet_poll_reply_port_types = -1;
338 static int hf_artnet_poll_reply_port_types_1 = -1;
339 static int hf_artnet_poll_reply_port_types_2 = -1;
340 static int hf_artnet_poll_reply_port_types_3 = -1;
341 static int hf_artnet_poll_reply_port_types_4 = -1;
342 static int hf_artnet_poll_reply_good_input = -1;
343 static int hf_artnet_poll_reply_good_input_1 = -1;
344 static int hf_artnet_poll_reply_good_input_2 = -1;
345 static int hf_artnet_poll_reply_good_input_3 = -1;
346 static int hf_artnet_poll_reply_good_input_4 = -1;
347 static int hf_artnet_poll_reply_good_output = -1;
348 static int hf_artnet_poll_reply_good_output_1 = -1;
349 static int hf_artnet_poll_reply_good_output_2 = -1;
350 static int hf_artnet_poll_reply_good_output_3 = -1;
351 static int hf_artnet_poll_reply_good_output_4 = -1;
352 static int hf_artnet_poll_reply_swin = -1;
353 static int hf_artnet_poll_reply_swin_1 = -1;
354 static int hf_artnet_poll_reply_swin_2 = -1;
355 static int hf_artnet_poll_reply_swin_3 = -1;
356 static int hf_artnet_poll_reply_swin_4 = -1;
357 static int hf_artnet_poll_reply_swout = -1;
358 static int hf_artnet_poll_reply_swout_1 = -1;
359 static int hf_artnet_poll_reply_swout_2 = -1;
360 static int hf_artnet_poll_reply_swout_3 = -1;
361 static int hf_artnet_poll_reply_swout_4 = -1;
362 static int hf_artnet_poll_reply_swvideo = -1;
363 static int hf_artnet_poll_reply_swmacro = -1;
364 static int hf_artnet_poll_reply_swremote = -1;
365 static int hf_artnet_poll_reply_mac = -1;
366
367 /* ArtOutput */
368 static int hf_artnet_output = -1;
369 static int hf_artnet_output_sequence = -1;
370 static int hf_artnet_output_physical = -1;
371 static int hf_artnet_output_universe = -1;
372 static int hf_artnet_output_length = -1;
373 static int hf_artnet_output_data = -1;
374 static int hf_artnet_output_dmx_data = -1;
375 static int hf_artnet_output_data_filter = -1;
376
377 /* ArtAddress */
378 static int hf_artnet_address = -1;
379 static int hf_artnet_address_short_name = -1;
380 static int hf_artnet_address_long_name = -1;
381 static int hf_artnet_address_swin = -1;
382 static int hf_artnet_address_swin_1 = -1;
383 static int hf_artnet_address_swin_2 = -1;
384 static int hf_artnet_address_swin_3 = -1;
385 static int hf_artnet_address_swin_4 = -1;
386 static int hf_artnet_address_swout = -1;
387 static int hf_artnet_address_swout_1 = -1;
388 static int hf_artnet_address_swout_2 = -1;
389 static int hf_artnet_address_swout_3 = -1;
390 static int hf_artnet_address_swout_4 = -1;
391 static int hf_artnet_address_subswitch = -1;
392 static int hf_artnet_address_swvideo = -1;
393 static int hf_artnet_address_command = -1;
394
395 /* ArtInput */
396 static int hf_artnet_input = -1;
397 static int hf_artnet_input_num_ports = -1;
398 static int hf_artnet_input_input = -1;
399 static int hf_artnet_input_input_1 = -1;
400 static int hf_artnet_input_input_2 = -1;
401 static int hf_artnet_input_input_3 = -1;
402 static int hf_artnet_input_input_4 = -1;
403
404 /* ArtFirmwareMaster */
405 static int hf_artnet_firmware_master = -1;
406 static int hf_artnet_firmware_master_type = -1;
407 static int hf_artnet_firmware_master_block_id = -1;
408 static int hf_artnet_firmware_master_length = -1;
409 static int hf_artnet_firmware_master_data = -1;
410
411 /* ArtFirmwareReply */
412 static int hf_artnet_firmware_reply = -1;
413 static int hf_artnet_firmware_reply_type = -1;
414
415 /* ArtVideoSetup */
416 static int hf_artnet_video_setup = -1;
417 static int hf_artnet_video_setup_control = -1;
418 static int hf_artnet_video_setup_font_height = -1;
419 static int hf_artnet_video_setup_first_font = -1;
420 static int hf_artnet_video_setup_last_font = -1;
421 static int hf_artnet_video_setup_win_font_name = -1;
422 static int hf_artnet_video_setup_font_data = -1;
423
424 /* ArtVideoPalette */
425 static int hf_artnet_video_palette = -1;
426 static int hf_artnet_video_palette_colour_red = -1;
427 static int hf_artnet_video_palette_colour_green = -1;
428 static int hf_artnet_video_palette_colour_blue = -1;
429
430 /* ArtVideoData */
431 static int hf_artnet_video_data = -1;
432 static int hf_artnet_video_data_pos_x = -1;
433 static int hf_artnet_video_data_pos_y = -1;
434 static int hf_artnet_video_data_len_x = -1;
435 static int hf_artnet_video_data_len_y = -1;
436 static int hf_artnet_video_data_data = -1;
437
438 /* ArtPollServerReply */
439 static int hf_artnet_poll_server_reply = -1;
440
441 /* ArtTodRequest */
442 static int hf_artnet_tod_request = -1;
443 static int hf_artnet_tod_request_command = -1;
444 static int hf_artnet_tod_request_ad_count = -1;
445 static int hf_artnet_tod_request_address = -1;
446
447 /* ArtTodData */
448 static int hf_artnet_tod_data = -1;
449 static int hf_artnet_tod_data_port = -1;
450 static int hf_artnet_tod_data_command_response = -1;
451 static int hf_artnet_tod_data_address = -1;
452 static int hf_artnet_tod_data_uid_total = -1;
453 static int hf_artnet_tod_data_block_count = -1;
454 static int hf_artnet_tod_data_uid_count = -1;
455 static int hf_artnet_tod_data_tod = -1;
456
457 /* ArtTodControl */
458 static int hf_artnet_tod_control = -1;
459 static int hf_artnet_tod_control_command = -1;
460 static int hf_artnet_tod_control_address = -1;
461
462 /* ArtRdm */
463 static int hf_artnet_rdm = -1;
464 static int hf_artnet_rdm_command = -1;
465 static int hf_artnet_rdm_address = -1;
466
467 /* ArtIpProg */
468 static int hf_artnet_ip_prog = -1;
469 static int hf_artnet_ip_prog_command = -1;
470 static int hf_artnet_ip_prog_command_prog_port = -1;
471 static int hf_artnet_ip_prog_command_prog_sm = -1;
472 static int hf_artnet_ip_prog_command_prog_ip = -1;
473 static int hf_artnet_ip_prog_command_reset = -1;
474 static int hf_artnet_ip_prog_command_unused = -1;
475 static int hf_artnet_ip_prog_command_prog_enable = -1;
476 static int hf_artnet_ip_prog_ip = -1;
477 static int hf_artnet_ip_prog_sm = -1;
478 static int hf_artnet_ip_prog_port = -1;
479
480 /* ArtIpProgReply */
481 static int hf_artnet_ip_prog_reply = -1;
482 static int hf_artnet_ip_prog_reply_ip = -1;
483 static int hf_artnet_ip_prog_reply_sm = -1;
484 static int hf_artnet_ip_prog_reply_port = -1;
485
486 /* Define the tree for artnet */
487 static int ett_artnet = -1;
488
489 /*
490  * Here are the global variables associated with the preferences
491  * for artnet
492  */
493
494 static guint global_udp_port_artnet = UDP_PORT_ARTNET;
495 static guint udp_port_artnet = UDP_PORT_ARTNET;
496 static guint global_disp_chan_val_type = 0;
497 static guint global_disp_col_count = 16;
498 static guint global_disp_chan_nr_type = 0;
499
500 /* A static handle for the ip dissector */
501 static dissector_handle_t ip_handle;
502 static dissector_handle_t rdm_handle;
503
504 static guint
505 dissect_artnet_poll(tvbuff_t *tvb, guint offset, proto_tree *tree)
506 {
507   guint8 talktome;
508   proto_tree *flags_tree, *flags_item;
509
510   talktome = tvb_get_guint8(tvb, offset);
511   flags_item = proto_tree_add_uint(tree, hf_artnet_poll_talktome, tvb,
512                                    offset, 1, talktome);
513
514   flags_tree=proto_item_add_subtree(flags_item, ett_artnet);
515   proto_tree_add_item(flags_tree, hf_artnet_poll_talktome_reply_dest, tvb, offset, 1, FALSE);
516   proto_tree_add_item(flags_tree, hf_artnet_poll_talktome_reply_type, tvb, offset, 1, FALSE);
517   proto_tree_add_item(flags_tree, hf_artnet_poll_talktome_unused, tvb, offset, 1, FALSE);
518
519   offset += 1;
520
521   proto_tree_add_item(tree, hf_artnet_filler, tvb,
522                       offset, 1, FALSE);
523   offset += 1;
524
525   return offset;
526 }
527
528 static guint
529 dissect_artnet_poll_reply(tvbuff_t *tvb, guint offset, proto_tree *tree)
530 {
531   proto_tree *hi,*si,*ti;
532   guint8 swin,swout,swvideo,swmacro,swremote;
533   guint8 port_types,good_input,good_output;
534   guint16 num_ports;
535
536   proto_tree_add_item(tree, hf_artnet_poll_reply_ip_address, tvb,
537                       offset, 4, FALSE);
538   offset += 4;
539
540   proto_tree_add_item(tree, hf_artnet_poll_reply_port_nr, tvb,
541                       offset, 2, TRUE);
542   offset += 2;
543
544   proto_tree_add_item(tree, hf_artnet_poll_reply_versinfo, tvb,
545                       offset, 2, FALSE);
546   offset += 2;
547
548   proto_tree_add_item(tree, hf_artnet_poll_reply_subswitch, tvb,
549                       offset, 2, FALSE);
550   offset += 2;
551
552   proto_tree_add_item(tree, hf_artnet_poll_reply_oem, tvb,
553                       offset, 2, FALSE);
554   offset += 2;
555
556   proto_tree_add_item(tree, hf_artnet_poll_reply_ubea_version, tvb,
557                       offset, 1, FALSE);
558   offset += 1;
559
560   proto_tree_add_item(tree, hf_artnet_poll_reply_status, tvb,
561                       offset, 1, FALSE);
562   offset += 1;
563
564   proto_tree_add_item(tree, hf_artnet_poll_reply_esta_man, tvb,
565                       offset, 2, TRUE);
566   offset += 2;
567
568   proto_tree_add_item(tree, hf_artnet_poll_reply_short_name,
569                       tvb, offset, 18, FALSE);
570   offset += 18;
571
572   proto_tree_add_item(tree, hf_artnet_poll_reply_long_name,
573                       tvb, offset, 64, FALSE);
574   offset += 64;
575
576   proto_tree_add_item(tree, hf_artnet_poll_reply_node_report,
577                       tvb, offset, 64, FALSE);
578   offset += 64;
579
580
581   hi = proto_tree_add_item(tree,
582                            hf_artnet_poll_reply_port_info,
583                            tvb,
584                            offset,
585                            ARTNET_POLL_REPLY_PORT_INFO_LENGTH,
586                            FALSE);
587
588   si = proto_item_add_subtree(hi, ett_artnet);
589
590   num_ports = tvb_get_ntohs(tvb, offset);
591   proto_tree_add_uint(si, hf_artnet_poll_reply_num_ports, tvb,
592                       offset, 2, num_ports);
593   offset += 2;
594
595   hi = proto_tree_add_item(si,
596                            hf_artnet_poll_reply_port_types,
597                            tvb,
598                            offset,
599                            ARTNET_POLL_REPLY_PORT_TYPES_LENGTH,
600                            FALSE);
601
602   ti = proto_item_add_subtree(hi, ett_artnet);
603
604   port_types = tvb_get_guint8(tvb, offset);
605   proto_tree_add_uint(ti, hf_artnet_poll_reply_port_types_1, tvb,
606                       offset, 1, port_types);
607   offset += 1;
608
609   port_types = tvb_get_guint8(tvb, offset);
610   proto_tree_add_uint(ti, hf_artnet_poll_reply_port_types_2, tvb,
611                       offset, 1, port_types);
612   offset += 1;
613
614   port_types = tvb_get_guint8(tvb, offset);
615   proto_tree_add_uint(ti, hf_artnet_poll_reply_port_types_3, tvb,
616                       offset, 1, port_types);
617   offset += 1;
618
619   port_types = tvb_get_guint8(tvb, offset);
620   proto_tree_add_uint(ti, hf_artnet_poll_reply_port_types_4, tvb,
621                       offset, 1, port_types);
622   offset += 1;
623
624   hi = proto_tree_add_item(si,
625                            hf_artnet_poll_reply_good_input,
626                            tvb,
627                            offset,
628                            ARTNET_POLL_REPLY_GOOD_INPUT_LENGTH,
629                            FALSE);
630
631   ti = proto_item_add_subtree(hi, ett_artnet);
632
633   good_input = tvb_get_guint8(tvb, offset);
634   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_input_1, tvb,
635                       offset, 1, good_input);
636   offset += 1;
637
638   good_input = tvb_get_guint8(tvb, offset);
639   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_input_2, tvb,
640                       offset, 1, good_input);
641   offset += 1;
642
643   good_input = tvb_get_guint8(tvb, offset);
644   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_input_3, tvb,
645                       offset, 1, good_input);
646   offset += 1;
647
648   good_input = tvb_get_guint8(tvb, offset);
649   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_input_4, tvb,
650                       offset, 1, good_input);
651   offset += 1;
652
653   hi = proto_tree_add_item(si,
654                            hf_artnet_poll_reply_good_output,
655                            tvb,
656                            offset,
657                            ARTNET_POLL_REPLY_GOOD_OUTPUT_LENGTH,
658                            FALSE);
659
660   ti = proto_item_add_subtree(hi, ett_artnet);
661
662   good_output = tvb_get_guint8(tvb, offset);
663   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_output_1, tvb,
664                       offset, 1, good_output);
665   offset += 1;
666
667   good_output = tvb_get_guint8(tvb, offset);
668   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_output_2, tvb,
669                       offset, 1, good_output);
670   offset += 1;
671
672   good_output = tvb_get_guint8(tvb, offset);
673   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_output_3, tvb,
674                       offset, 1, good_output);
675   offset += 1;
676
677   good_output = tvb_get_guint8(tvb, offset);
678   proto_tree_add_uint(ti, hf_artnet_poll_reply_good_output_4, tvb,
679                       offset, 1, good_output);
680   offset += 1;
681
682   hi = proto_tree_add_item(si,
683                            hf_artnet_poll_reply_swin,
684                            tvb,
685                            offset,
686                            ARTNET_POLL_REPLY_SWIN_LENGTH,
687                            FALSE);
688
689   ti = proto_item_add_subtree(hi, ett_artnet);
690
691   swin = tvb_get_guint8(tvb, offset);
692   proto_tree_add_uint(ti, hf_artnet_poll_reply_swin_1, tvb,
693                       offset, 1, swin);
694   offset += 1;
695
696   swin = tvb_get_guint8(tvb, offset);
697   proto_tree_add_uint(ti, hf_artnet_poll_reply_swin_2, tvb,
698                       offset, 1, swin);
699   offset += 1;
700
701   swin = tvb_get_guint8(tvb, offset);
702   proto_tree_add_uint(ti, hf_artnet_poll_reply_swin_3, tvb,
703                       offset, 1, swin);
704   offset += 1;
705
706   swin = tvb_get_guint8(tvb, offset);
707   proto_tree_add_uint(ti, hf_artnet_poll_reply_swin_4, tvb,
708                       offset, 1, swin);
709   offset += 1;
710
711   hi = proto_tree_add_item(si,
712                            hf_artnet_poll_reply_swout,
713                            tvb,
714                            offset,
715                            ARTNET_POLL_REPLY_SWOUT_LENGTH,
716                            FALSE);
717
718   ti = proto_item_add_subtree(hi, ett_artnet);
719
720   swout = tvb_get_guint8(tvb, offset);
721   proto_tree_add_uint(ti, hf_artnet_poll_reply_swout_1, tvb,
722                       offset, 1, swout);
723   offset += 1;
724
725   swout = tvb_get_guint8(tvb, offset);
726   proto_tree_add_uint(ti, hf_artnet_poll_reply_swout_2, tvb,
727                       offset, 1, swout);
728   offset += 1;
729
730   swout = tvb_get_guint8(tvb, offset);
731   proto_tree_add_uint(ti, hf_artnet_poll_reply_swout_3, tvb,
732                       offset, 1, swout);
733   offset += 1;
734
735   swout = tvb_get_guint8(tvb, offset);
736   proto_tree_add_uint(ti, hf_artnet_poll_reply_swout_4, tvb,
737                       offset, 1, swout);
738   offset += 1;
739
740   swvideo = tvb_get_guint8(tvb, offset);
741   proto_tree_add_uint(tree, hf_artnet_poll_reply_swvideo, tvb,
742                       offset, 1, swvideo);
743   offset += 1;
744
745   swmacro = tvb_get_guint8(tvb, offset);
746   proto_tree_add_uint(tree, hf_artnet_poll_reply_swmacro, tvb,
747                       offset, 1, swmacro);
748   offset += 1;
749
750   swremote = tvb_get_guint8(tvb, offset);
751   proto_tree_add_uint(tree, hf_artnet_poll_reply_swremote, tvb,
752                       offset, 1, swremote);
753   offset += 1;
754
755   proto_tree_add_item(tree, hf_artnet_spare, tvb,
756                       offset, 4, FALSE);
757   offset += 4;
758
759   proto_tree_add_item(tree, hf_artnet_poll_reply_mac,
760                         tvb, offset, 6, FALSE);
761
762   offset += 6;
763
764   return offset;
765 }
766
767 static guint
768 dissect_artnet_output(tvbuff_t *tvb, guint offset, proto_tree *tree)
769 {
770   proto_tree *hi,*si;
771   guint16 length,r,c,row_count;
772   guint8 v;
773   static char string[255];
774   char* ptr;
775   const char* chan_format[] = {
776     "%2u ",
777     "%02x ",
778     "%3u "
779   };
780   const char* string_format[] = {
781     "%03x: %s",
782     "%3u: %s"
783   };
784
785   proto_tree_add_item(tree, hf_artnet_output_sequence, tvb,
786                       offset, 1, FALSE);
787   offset += 1;
788
789   proto_tree_add_item(tree, hf_artnet_output_physical, tvb,
790                       offset, 1, FALSE);
791   offset += 1;
792
793   proto_tree_add_item(tree, hf_artnet_output_universe, tvb,
794                       offset, 2, TRUE);
795   offset += 2;
796
797   length = tvb_get_ntohs(tvb, offset);
798   proto_tree_add_uint(tree, hf_artnet_output_length, tvb,
799                       offset, 2, length);
800   offset += 2;
801
802   hi = proto_tree_add_item(tree,
803                            hf_artnet_output_data,
804                            tvb,
805                            offset,
806                            length,
807                            FALSE);
808                                                                                                                 
809   si = proto_item_add_subtree(hi, ett_artnet);
810
811   row_count = (length/global_disp_col_count) + ((length%global_disp_col_count) == 0 ? 0 : 1);
812   ptr = string;
813   for (r=0; r < row_count;r++) {
814     for (c=0;(c < global_disp_col_count) && (((r*global_disp_col_count)+c) < length);c++) {
815       if ((c % (global_disp_col_count/2)) == 0) {
816         sprintf(ptr, " ");
817         ptr++;
818       }
819
820       v = tvb_get_guint8(tvb, (offset+(r*global_disp_col_count)+c));
821       if (global_disp_chan_val_type == 0) {
822         v = (v * 100) / 255;
823         if (v == 100) {
824           sprintf(ptr, "FL ");
825         } else {
826           sprintf(ptr, chan_format[global_disp_chan_val_type], v);
827         }
828       } else {
829         sprintf(ptr, chan_format[global_disp_chan_val_type], v);
830       }
831       ptr += strlen(ptr);
832     }
833     
834     proto_tree_add_none_format(si,hf_artnet_output_dmx_data, tvb,
835                                offset+(r*global_disp_col_count), c, 
836                                string_format[global_disp_chan_nr_type], (r*global_disp_col_count)+1, string);
837     ptr = string;
838   }
839
840   /* Add the real type hidden */
841   proto_tree_add_item_hidden(si, hf_artnet_output_data_filter, tvb,
842                       offset, length, FALSE );
843   offset += length;
844
845   return offset;
846 }
847
848 static guint
849 dissect_artnet_address(tvbuff_t *tvb, guint offset, proto_tree *tree) {
850   proto_tree *hi,*si,*ti;
851   guint8 swin,swout,swvideo,command;
852
853   proto_tree_add_item(tree, hf_artnet_filler, tvb,
854                       offset, 2, FALSE);
855   offset += 2;
856
857   proto_tree_add_item(tree, hf_artnet_address_short_name,
858                       tvb, offset, 18, FALSE);
859   offset += 18;
860
861   proto_tree_add_item(tree, hf_artnet_address_long_name,
862                       tvb, offset, 64, FALSE);
863   offset += 64;
864
865   hi = proto_tree_add_item(tree,
866                            hf_artnet_address_swin,
867                            tvb,
868                            offset,
869                            ARTNET_ADDRESS_SWIN_LENGTH,
870                            FALSE);
871
872   ti = proto_item_add_subtree(hi, ett_artnet);
873
874   swin = tvb_get_guint8(tvb, offset);
875   proto_tree_add_uint(ti, hf_artnet_address_swin_1, tvb,
876                       offset, 1, swin);
877   offset += 1;
878
879   swin = tvb_get_guint8(tvb, offset);
880   proto_tree_add_uint(ti, hf_artnet_address_swin_2, tvb,
881                       offset, 1, swin);
882   offset += 1;
883
884   swin = tvb_get_guint8(tvb, offset);
885   proto_tree_add_uint(ti, hf_artnet_address_swin_3, tvb,
886                       offset, 1, swin);
887   offset += 1;
888
889   swin = tvb_get_guint8(tvb, offset);
890   proto_tree_add_uint(ti, hf_artnet_address_swin_4, tvb,
891                       offset, 1, swin);
892   offset += 1;
893
894   hi = proto_tree_add_item(tree,
895                            hf_artnet_address_swout,
896                            tvb,
897                            offset,
898                            ARTNET_ADDRESS_SWOUT_LENGTH,
899                            FALSE);
900
901   si = proto_item_add_subtree(hi, ett_artnet);
902
903   swout = tvb_get_guint8(tvb, offset);
904   proto_tree_add_uint(si, hf_artnet_address_swout_1, tvb,
905                       offset, 1, swout);
906   offset += 1;
907
908   swout = tvb_get_guint8(tvb, offset);
909   proto_tree_add_uint(si, hf_artnet_address_swout_2, tvb,
910                       offset, 1, swout);
911   offset += 1;
912
913   swout = tvb_get_guint8(tvb, offset);
914   proto_tree_add_uint(si, hf_artnet_address_swout_3, tvb,
915                       offset, 1, swout);
916   offset += 1;
917
918   swout = tvb_get_guint8(tvb, offset);
919   proto_tree_add_uint(si, hf_artnet_address_swout_4, tvb,
920                       offset, 1, swout);
921   offset += 1;
922
923   swvideo = tvb_get_guint8(tvb, offset);
924   proto_tree_add_uint(tree, hf_artnet_address_swvideo, tvb,
925                       offset, 1, swvideo);
926   offset += 1;
927
928   command = tvb_get_guint8(tvb, offset);
929   proto_tree_add_uint(tree, hf_artnet_address_command, tvb,
930                       offset, 1, command);
931
932   offset += 1;
933
934   return offset;
935 }
936
937 static guint
938 dissect_artnet_input(tvbuff_t *tvb, guint offset, proto_tree *tree) {
939   proto_tree *hi,*si;
940   guint16 num_ports;
941   guint8 input;
942
943   proto_tree_add_item(tree, hf_artnet_filler, tvb,
944                       offset, 2, FALSE);
945   offset += 2;
946
947   num_ports = tvb_get_letohs(tvb, offset);
948   proto_tree_add_uint(tree, hf_artnet_input_num_ports, tvb,
949                       offset, 2, num_ports);
950   offset += 2;
951
952   hi = proto_tree_add_item(tree,
953                            hf_artnet_input_input,
954                            tvb,
955                            offset,
956                            ARTNET_INPUT_INPUT_LENGTH,
957                            FALSE);
958
959   si = proto_item_add_subtree(hi, ett_artnet);
960
961   input = tvb_get_guint8(tvb, offset);
962   proto_tree_add_uint(si, hf_artnet_input_input_1, tvb,
963                       offset, 1, input);
964   offset += 1;
965
966   input = tvb_get_guint8(tvb, offset);
967   proto_tree_add_uint(si, hf_artnet_input_input_2, tvb,
968                       offset, 1, input);
969   offset += 1;
970
971   input = tvb_get_guint8(tvb, offset);
972   proto_tree_add_uint(si, hf_artnet_input_input_3, tvb,
973                       offset, 1, input);
974   offset += 1;
975
976   input = tvb_get_guint8(tvb, offset);
977   proto_tree_add_uint(si, hf_artnet_input_input_4, tvb,
978                       offset, 1, input);
979   offset += 1;
980
981   return offset;
982 }
983
984 static guint
985 dissect_artnet_video_setup(tvbuff_t *tvb, guint offset, proto_tree *tree ) {
986   guint32 size;
987   guint8 control,font_height, last_font,first_font;
988
989   proto_tree_add_item(tree, hf_artnet_filler, tvb,
990                       offset, 4, FALSE);
991   offset += 4;
992
993   control = tvb_get_guint8(tvb, offset);
994   proto_tree_add_uint(tree, hf_artnet_video_setup_control, tvb,
995                       offset, 1, control);
996   offset += 1;
997
998   font_height = tvb_get_guint8(tvb, offset);
999   proto_tree_add_uint(tree, hf_artnet_video_setup_font_height, tvb,
1000                       offset, 1, font_height);
1001   offset += 1;
1002
1003   first_font = tvb_get_guint8(tvb, offset);
1004   proto_tree_add_uint(tree, hf_artnet_video_setup_first_font, tvb,
1005                       offset, 1, first_font);
1006   offset += 1;
1007
1008   last_font = tvb_get_guint8(tvb, offset);
1009   proto_tree_add_uint(tree, hf_artnet_video_setup_last_font, tvb,
1010                       offset, 1, last_font);
1011   offset += 1;
1012
1013   proto_tree_add_item(tree, hf_artnet_video_setup_win_font_name,
1014                       tvb, offset, 64, FALSE);
1015   offset += 64;
1016
1017   size = last_font * font_height;
1018
1019   proto_tree_add_item(tree, hf_artnet_video_setup_font_data, tvb,
1020                       offset, size, FALSE );
1021
1022   offset += size;
1023
1024   return offset;
1025 }
1026
1027 static guint
1028 dissect_artnet_video_palette(tvbuff_t *tvb, guint offset, proto_tree *tree)
1029 {
1030   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1031                       offset, 2, FALSE);
1032   offset += 2;
1033
1034   proto_tree_add_item(tree, hf_artnet_video_palette_colour_red, tvb,
1035                       offset, 17, FALSE );
1036   offset += 17;
1037
1038   proto_tree_add_item(tree, hf_artnet_video_palette_colour_green, tvb,
1039                       offset, 17, FALSE );
1040   offset += 17;
1041
1042   proto_tree_add_item(tree, hf_artnet_video_palette_colour_blue, tvb,
1043                       offset, 17, FALSE );
1044   offset += 17;
1045
1046   return offset;
1047 }
1048
1049 static guint
1050 dissect_artnet_video_data(tvbuff_t *tvb, guint offset, proto_tree *tree) {
1051   guint8 len_x, len_y;
1052   guint32 size;
1053
1054   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1055                       offset, 2, FALSE);
1056   offset += 2;
1057
1058   proto_tree_add_item(tree, hf_artnet_video_data_pos_x, tvb,
1059                       offset, 1, FALSE);
1060   offset += 1;
1061
1062   proto_tree_add_item(tree, hf_artnet_video_data_pos_y, tvb,
1063                       offset, 1, FALSE);
1064   offset += 1;
1065
1066   len_x = tvb_get_guint8(tvb, offset);
1067   proto_tree_add_uint(tree, hf_artnet_video_data_len_x, tvb,
1068                       offset, 1, len_x);
1069   offset += 1;
1070
1071   len_y = tvb_get_guint8(tvb, offset);
1072   proto_tree_add_uint(tree, hf_artnet_video_data_len_y, tvb,
1073                       offset, 1, len_y);
1074   offset += 1;
1075
1076   size = len_x * len_y * 2;
1077
1078   proto_tree_add_item(tree, hf_artnet_video_data_data, tvb,
1079                       offset, size, FALSE );
1080
1081   offset += size;
1082
1083   return offset;
1084 }
1085
1086 static guint
1087 dissect_artnet_firmware_master(tvbuff_t *tvb, guint offset, proto_tree *tree ) {
1088   guint8 type,block_id;
1089   guint32 length;
1090
1091   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1092                       offset, 2, FALSE);
1093   offset += 2;
1094
1095   type = tvb_get_guint8(tvb, offset);
1096   proto_tree_add_uint(tree, hf_artnet_firmware_master_type, tvb,
1097                       offset, 1, type);
1098   offset += 1;
1099
1100   block_id = tvb_get_guint8(tvb, offset);
1101   proto_tree_add_uint(tree, hf_artnet_firmware_master_block_id, tvb,
1102                       offset, 1, block_id);
1103   offset += 1;
1104
1105   length = tvb_get_ntohl(tvb, offset);
1106   proto_tree_add_uint(tree, hf_artnet_firmware_master_length, tvb,
1107                       offset, 4, length);
1108   offset += 4;
1109
1110   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1111                       offset, 20, FALSE );
1112
1113   offset += 20;
1114
1115   proto_tree_add_item(tree, hf_artnet_firmware_master_data, tvb,
1116                       offset, 1024, FALSE );
1117
1118   offset += 1024;
1119
1120   return offset;
1121 }
1122
1123 static guint
1124 dissect_artnet_firmware_reply(tvbuff_t *tvb, guint offset, proto_tree *tree) {
1125   guint8 type;
1126
1127   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1128                       offset, 2, FALSE);
1129   offset += 2;
1130
1131   type = tvb_get_guint8(tvb, offset);
1132   proto_tree_add_uint(tree, hf_artnet_firmware_reply_type, tvb,
1133                       offset, 1, type);
1134   offset += 1;
1135
1136   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1137                       offset, 21, FALSE );
1138
1139   offset += 21;
1140
1141   return offset;
1142 }
1143
1144 static guint
1145 dissect_artnet_tod_request(tvbuff_t *tvb, guint offset, proto_tree *tree)
1146 {
1147   guint8 ad_count;
1148
1149   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1150                       offset, 2, FALSE);
1151   offset += 2;
1152
1153   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1154                       offset, 8, FALSE);
1155   offset += 8;
1156
1157   proto_tree_add_item(tree, hf_artnet_tod_request_command, tvb,
1158                       offset, 1, FALSE);
1159   offset += 1;
1160
1161   ad_count = tvb_get_guint8(tvb, offset);
1162   proto_tree_add_uint(tree, hf_artnet_tod_request_ad_count, tvb,
1163                       offset, 1, ad_count);
1164   offset += 1;
1165
1166   proto_tree_add_item(tree, hf_artnet_tod_request_address, tvb,
1167                       offset, ad_count, FALSE);
1168   offset += ad_count;
1169
1170   return offset;
1171 }
1172
1173 static guint
1174 dissect_artnet_tod_data(tvbuff_t *tvb, guint offset, proto_tree *tree)
1175 {
1176   guint8 i,uid_count;
1177
1178   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1179                       offset, 1, FALSE);
1180   offset += 1;
1181
1182   proto_tree_add_item(tree, hf_artnet_tod_data_port, tvb,
1183                       offset, 1, FALSE);
1184   offset += 1;
1185
1186   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1187                       offset, 8, FALSE);
1188   offset += 8;
1189
1190   proto_tree_add_item(tree, hf_artnet_tod_data_command_response, tvb,
1191                       offset, 1, FALSE);
1192   offset += 1;
1193
1194   proto_tree_add_item(tree, hf_artnet_tod_data_address, tvb,
1195                       offset, 1, FALSE);
1196   offset += 1;
1197
1198   proto_tree_add_item(tree, hf_artnet_tod_data_uid_total, tvb,
1199                       offset, 2, FALSE);
1200   offset += 2;
1201
1202   proto_tree_add_item(tree, hf_artnet_tod_data_block_count, tvb,
1203                       offset, 1, FALSE);
1204   offset += 1;
1205
1206   uid_count = tvb_get_guint8(tvb, offset);
1207   proto_tree_add_uint(tree, hf_artnet_tod_data_uid_count, tvb,
1208                       offset, 1, uid_count);
1209   offset += 1;
1210
1211   for( i = 0; i < uid_count; i++)
1212   {
1213     proto_tree_add_item(tree, hf_artnet_tod_data_tod, tvb,
1214                         offset, 6, FALSE);
1215     offset += 6;
1216   }
1217
1218   return offset;
1219 }
1220
1221 static guint
1222 dissect_artnet_tod_control(tvbuff_t *tvb, guint offset, proto_tree *tree)
1223 {
1224   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1225                       offset, 2, FALSE);
1226   offset += 2;
1227
1228   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1229                       offset, 8, FALSE);
1230   offset += 8;
1231
1232   proto_tree_add_item(tree, hf_artnet_tod_control_command, tvb,
1233                       offset, 1, FALSE);
1234   offset += 1;
1235
1236   proto_tree_add_item(tree, hf_artnet_tod_control_address, tvb,
1237                       offset, 1, FALSE);
1238   offset += 1;
1239
1240   return offset;
1241 }
1242
1243 static guint
1244 dissect_artnet_rdm(tvbuff_t *tvb, guint offset, proto_tree *tree,  packet_info *pinfo)
1245 {
1246   guint size;
1247   gboolean save_info;
1248   tvbuff_t *next_tvb = NULL;
1249
1250   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1251                       offset, 2, FALSE);
1252   offset += 2;
1253
1254   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1255                       offset, 8, FALSE);
1256   offset += 8;
1257
1258   proto_tree_add_item(tree, hf_artnet_rdm_command, tvb,
1259                       offset, 1, FALSE);
1260   offset += 1;
1261
1262   proto_tree_add_item(tree, hf_artnet_rdm_address, tvb,
1263                       offset, 1, FALSE);
1264   offset += 1;
1265
1266   size = tvb_reported_length_remaining(tvb, offset);
1267
1268   save_info=col_get_writable(pinfo->cinfo); 
1269   col_set_writable(pinfo->cinfo, FALSE);
1270
1271   if (!next_tvb)
1272     next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1273  
1274   call_dissector(rdm_handle, next_tvb, pinfo, tree);
1275
1276   col_set_writable(pinfo->cinfo, save_info);
1277   
1278   size = tvb_reported_length_remaining(tvb, offset) - size;
1279
1280   return offset + size;
1281 }
1282
1283 static guint
1284 dissect_artnet_ip_prog(tvbuff_t *tvb, guint offset, proto_tree *tree) {
1285   guint8 command;
1286   proto_tree *flags_tree,*flags_item;
1287
1288   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1289                       offset, 2, FALSE);
1290   offset += 2;
1291
1292   command = tvb_get_guint8(tvb, offset);
1293   flags_item = proto_tree_add_uint(tree, hf_artnet_ip_prog_command, tvb,
1294                                    offset, 1, command);
1295
1296   flags_tree=proto_item_add_subtree(flags_item, ett_artnet);
1297   proto_tree_add_item(flags_tree, hf_artnet_ip_prog_command_prog_port, tvb, offset, 1, FALSE);
1298   proto_tree_add_item(flags_tree, hf_artnet_ip_prog_command_prog_sm, tvb, offset, 1, FALSE);
1299   proto_tree_add_item(flags_tree, hf_artnet_ip_prog_command_prog_ip, tvb, offset, 1, FALSE);
1300   proto_tree_add_item(flags_tree, hf_artnet_ip_prog_command_reset, tvb, offset, 1, FALSE);
1301   proto_tree_add_item(flags_tree, hf_artnet_ip_prog_command_unused, tvb, offset, 1, FALSE);
1302   proto_tree_add_item(flags_tree, hf_artnet_ip_prog_command_prog_enable, tvb, offset, 1, FALSE);
1303
1304   offset += 1;
1305
1306   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1307                       offset, 1, FALSE);
1308   offset += 1;
1309
1310   proto_tree_add_item(tree, hf_artnet_ip_prog_ip, tvb,
1311                       offset, 4, FALSE);
1312   offset += 4;
1313
1314   proto_tree_add_item(tree, hf_artnet_ip_prog_sm, tvb,
1315                       offset, 4, FALSE);
1316   offset += 4;
1317
1318   proto_tree_add_item(tree, hf_artnet_ip_prog_port, tvb,
1319                       offset, 2, FALSE);
1320   offset += 2;
1321
1322   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1323                       offset, 8, FALSE);
1324   offset += 8;
1325
1326   return offset;
1327 }
1328
1329 static guint
1330 dissect_artnet_ip_prog_reply(tvbuff_t *tvb, guint offset, proto_tree *tree)
1331 {
1332   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1333                       offset, 4, FALSE);
1334   offset += 4;
1335
1336   proto_tree_add_item(tree, hf_artnet_ip_prog_reply_ip, tvb,
1337                       offset, 4, FALSE);
1338   offset += 4;
1339
1340   proto_tree_add_item(tree, hf_artnet_ip_prog_reply_sm, tvb,
1341                       offset, 4, FALSE);
1342   offset += 4;
1343
1344   proto_tree_add_item(tree, hf_artnet_ip_prog_reply_port, tvb,
1345                       offset, 2, FALSE);
1346   offset += 2;
1347
1348   proto_tree_add_item(tree, hf_artnet_spare, tvb,
1349                       offset, 8, FALSE);
1350   offset += 8;
1351
1352   return offset;
1353 }
1354
1355 static guint
1356 dissect_artnet_poll_server_reply(tvbuff_t *tvb, guint offset, proto_tree *tree)
1357 {
1358   /* no spec released for this packet at the moment */
1359   proto_tree_add_item(tree, hf_artnet_filler, tvb,
1360                       offset, 182, FALSE);
1361   offset += 182;
1362
1363   return offset;
1364 }
1365
1366
1367 static void
1368 dissect_artnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
1369   gint offset = 0;
1370   guint size;
1371   guint16 opcode;
1372   proto_tree *ti,*hi,*si,*artnet_tree=NULL,*artnet_header_tree=NULL;
1373
1374   /* Set the protocol column */
1375   if(check_col(pinfo->cinfo,COL_PROTOCOL)){
1376     col_set_str(pinfo->cinfo,COL_PROTOCOL,"ARTNET");
1377   }
1378
1379   /* Clear out stuff in the info column */
1380   if(check_col(pinfo->cinfo,COL_INFO)){
1381     col_clear(pinfo->cinfo,COL_INFO);
1382   }
1383
1384   if (tree) {
1385     ti = proto_tree_add_item(tree, proto_artnet, tvb, offset, -1, FALSE);
1386     artnet_tree = proto_item_add_subtree(ti, ett_artnet);
1387
1388     hi = proto_tree_add_item(artnet_tree,
1389                              hf_artnet_header,
1390                              tvb,
1391                              offset,
1392                              ARTNET_HEADER_LENGTH ,
1393                              FALSE);
1394
1395     artnet_header_tree = proto_item_add_subtree(hi, ett_artnet);
1396   }
1397
1398   if (check_col(pinfo->cinfo, COL_INFO)) {
1399     col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
1400                     tvb_get_ptr(tvb, offset, 8));
1401   }
1402   if( tree ){
1403     proto_tree_add_item(artnet_header_tree, hf_artnet_header_id,
1404                         tvb, offset, 8, FALSE);
1405   }
1406   offset += 8;
1407
1408   opcode = tvb_get_letohs(tvb, offset);
1409   /* set the info column */
1410   if (check_col(pinfo->cinfo, COL_INFO)) {
1411     col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
1412       val_to_str(opcode, artnet_opcode_vals, "Unknown (0x%04x)"));
1413   }
1414
1415   if( tree ){
1416     proto_tree_add_uint(artnet_header_tree, hf_artnet_header_opcode, tvb,
1417                         offset, 2, opcode);
1418   }
1419   offset += 2;
1420
1421   if( opcode != ARTNET_OP_POLL_REPLY && opcode != ARTNET_OP_POLL_SERVER_REPLY ) {
1422     if( tree ){
1423       proto_tree_add_item(artnet_header_tree, hf_artnet_header_protver, tvb,
1424                           offset, 2, FALSE);
1425
1426       proto_item_set_len(artnet_header_tree, ARTNET_HEADER_LENGTH+2 );
1427     }
1428     offset += 2;
1429   }
1430
1431   switch( opcode ) {
1432     case ARTNET_OP_POLL:
1433       if (tree) {
1434         hi = proto_tree_add_item(artnet_tree,
1435                                  hf_artnet_poll,
1436                                  tvb,
1437                                  offset,
1438                                  ARTNET_POLL_LENGTH,
1439                                  FALSE);
1440
1441         si = proto_item_add_subtree(hi, ett_artnet);
1442
1443         size = dissect_artnet_poll( tvb, offset, si );
1444         size -= offset;
1445
1446         proto_item_set_len(si, size);
1447       }
1448       break;
1449
1450     case ARTNET_OP_POLL_REPLY:
1451       if (tree) {
1452         hi = proto_tree_add_item(artnet_tree,
1453                                  hf_artnet_poll_reply,
1454                                  tvb,
1455                                  offset,
1456                                  ARTNET_POLL_REPLY_LENGTH,
1457                                  FALSE);
1458
1459         si = proto_item_add_subtree(hi, ett_artnet);
1460
1461         size = dissect_artnet_poll_reply( tvb, offset, si);
1462         size -= offset;
1463
1464         proto_item_set_len(si, size);
1465       }
1466       break;
1467
1468     case ARTNET_OP_OUTPUT:
1469       if (tree) {
1470         hi = proto_tree_add_item(artnet_tree,
1471                                  hf_artnet_output,
1472                                  tvb,
1473                                  offset,
1474                                  ARTNET_OUTPUT_LENGTH,
1475                                  FALSE);
1476
1477         si = proto_item_add_subtree(hi, ett_artnet);
1478
1479         size = dissect_artnet_output( tvb, offset, si );
1480         size -= offset;
1481
1482         proto_item_set_len(si, size);
1483       }
1484       break;
1485
1486     case ARTNET_OP_ADDRESS:
1487       if (tree) {
1488         hi = proto_tree_add_item(artnet_tree,
1489                                  hf_artnet_address,
1490                                  tvb,
1491                                  offset,
1492                                  ARTNET_POLL_REPLY_LENGTH,
1493                                  FALSE);
1494
1495         si = proto_item_add_subtree(hi, ett_artnet);
1496
1497         size = dissect_artnet_address( tvb, offset, si );
1498         size -= offset;
1499
1500         proto_item_set_len(si, size); 
1501       } 
1502       break;
1503
1504     case ARTNET_OP_INPUT:
1505       if (tree) {
1506         hi = proto_tree_add_item(artnet_tree,
1507                                  hf_artnet_input,
1508                                  tvb,
1509                                  offset,
1510                                  ARTNET_INPUT_LENGTH,
1511                                  FALSE);
1512
1513         si = proto_item_add_subtree(hi, ett_artnet);
1514         
1515         size = dissect_artnet_input( tvb, offset, si );
1516         size -= offset;
1517
1518         proto_item_set_len(si, size);
1519       }
1520       break;
1521
1522     case ARTNET_OP_VIDEO_SETUP:
1523       if (tree) {
1524         hi = proto_tree_add_item(artnet_tree,
1525                                  hf_artnet_input,
1526                                  tvb,
1527                                  offset,
1528                                  ARTNET_VIDEO_SETUP_LENGTH,
1529                                  FALSE);
1530
1531         si = proto_item_add_subtree(hi, ett_artnet);
1532         
1533         size = dissect_artnet_video_setup( tvb, offset, si );
1534         size -= offset;
1535
1536         proto_item_set_len(si, size); 
1537       }
1538       break;
1539
1540     case ARTNET_OP_VIDEO_PALETTE:
1541       if (tree) {
1542         hi = proto_tree_add_item(artnet_tree,
1543                                  hf_artnet_input,
1544                                  tvb,
1545                                  offset,
1546                                  ARTNET_VIDEO_PALETTE_LENGTH,
1547                                  FALSE);
1548
1549         si = proto_item_add_subtree(hi, ett_artnet);
1550
1551         size = dissect_artnet_video_palette( tvb, offset, si );
1552         size -= offset;
1553
1554         proto_item_set_len(si, size);
1555       }
1556       break;
1557
1558     case ARTNET_OP_VIDEO_DATA:
1559       if (tree) {
1560         hi = proto_tree_add_item(artnet_tree,
1561                                  hf_artnet_input,
1562                                  tvb,
1563                                  offset,
1564                                  ARTNET_VIDEO_DATA_LENGTH,
1565                                  FALSE);
1566
1567         si = proto_item_add_subtree(hi, ett_artnet);
1568
1569         size = dissect_artnet_video_data( tvb, offset, si );
1570         size -= offset;
1571
1572         proto_item_set_len(si, size);
1573       }
1574       break;
1575
1576     case ARTNET_OP_FIRMWARE_MASTER:
1577       if (tree) {
1578         hi = proto_tree_add_item(artnet_tree,
1579                                  hf_artnet_firmware_master,
1580                                  tvb,
1581                                  offset,
1582                                  ARTNET_FIRMWARE_MASTER_LENGTH,
1583                                  FALSE);
1584
1585         si = proto_item_add_subtree(hi, ett_artnet);
1586
1587         size = dissect_artnet_firmware_master( tvb, offset, si );
1588         size -= offset;
1589
1590         proto_item_set_len(si, size);
1591       }
1592       break;
1593
1594     case ARTNET_OP_FIRMWARE_REPLY:
1595       if (tree) {
1596         hi = proto_tree_add_item(artnet_tree,
1597                                  hf_artnet_firmware_reply,
1598                                  tvb,
1599                                  offset,
1600                                  ARTNET_FIRMWARE_REPLY_LENGTH,
1601                                  FALSE);
1602
1603         si = proto_item_add_subtree(hi, ett_artnet);
1604
1605         size = dissect_artnet_firmware_reply( tvb, offset, si );
1606         size -= offset;
1607
1608         proto_item_set_len(si, size);
1609       }
1610       break;
1611     
1612     case ARTNET_OP_TOD_REQUEST:
1613       if (tree) {
1614         hi = proto_tree_add_item(artnet_tree,
1615                                  hf_artnet_tod_request,
1616                                  tvb,
1617                                  offset,
1618                                  0,
1619                                  FALSE);
1620
1621         si = proto_item_add_subtree(hi, ett_artnet);
1622
1623         size = dissect_artnet_tod_request( tvb, offset, si );
1624         size -= offset;
1625
1626         proto_item_set_len(si, size);
1627       }
1628       break;
1629
1630     case ARTNET_OP_TOD_DATA:
1631       if (tree) {
1632         hi = proto_tree_add_item(artnet_tree,
1633                                  hf_artnet_tod_data,
1634                                  tvb,
1635                                  offset,
1636                                  0,
1637                                  FALSE);
1638
1639         si = proto_item_add_subtree(hi, ett_artnet );
1640
1641         size = dissect_artnet_tod_data( tvb, offset, si );
1642         size -= offset;
1643
1644         proto_item_set_len(si, size );
1645       }
1646       break;
1647
1648     case ARTNET_OP_TOD_CONTROL:
1649       if (tree){
1650         hi = proto_tree_add_item(artnet_tree,
1651                                  hf_artnet_tod_control,
1652                                  tvb,
1653                                  offset,
1654                                  0,
1655                                  FALSE );
1656         si = proto_item_add_subtree(hi, ett_artnet );
1657
1658         size = dissect_artnet_tod_control( tvb, offset, si );
1659         size -= offset;
1660
1661         proto_item_set_len(si, size );
1662       }
1663       break;
1664
1665     case ARTNET_OP_RDM:
1666       if (tree) {
1667         hi = proto_tree_add_item(artnet_tree,
1668                                  hf_artnet_rdm,
1669                                  tvb,
1670                                  offset,
1671                                  0,
1672                                  FALSE);
1673         si = proto_item_add_subtree(hi,ett_artnet);
1674
1675         size = dissect_artnet_rdm( tvb, offset, si, pinfo );
1676         size -= offset;
1677
1678         proto_item_set_len( si, size );
1679       }
1680       break;
1681
1682     case ARTNET_OP_IP_PROG:
1683       if (tree) {
1684         hi = proto_tree_add_item(artnet_tree,
1685                                  hf_artnet_ip_prog,
1686                                  tvb,
1687                                  offset,
1688                                  0,
1689                                  FALSE);
1690         si = proto_item_add_subtree(hi, ett_artnet );
1691
1692         size = dissect_artnet_ip_prog( tvb, offset, si);
1693         size -= offset;
1694
1695         proto_item_set_len(si, size );
1696       }
1697       break;
1698
1699     case ARTNET_OP_IP_PROG_REPLY:
1700       if (tree) {
1701         hi = proto_tree_add_item(artnet_tree,
1702                                  hf_artnet_ip_prog_reply,
1703                                  tvb,
1704                                  offset,
1705                                  0,
1706                                  FALSE);
1707         si = proto_item_add_subtree(hi, ett_artnet );
1708
1709         size = dissect_artnet_ip_prog_reply( tvb, offset, si );
1710         size -= offset;
1711
1712         proto_item_set_len(si, size );
1713       }
1714       break;
1715
1716     case ARTNET_OP_POLL_SERVER_REPLY:
1717       if (tree) {
1718         hi = proto_tree_add_item(artnet_tree,
1719                                  hf_artnet_poll_server_reply,
1720                                  tvb,
1721                                  offset,
1722                                  0,
1723                                  FALSE );
1724         si = proto_item_add_subtree(hi, ett_artnet );
1725
1726         size = dissect_artnet_poll_server_reply( tvb, offset, si );
1727         size -= offset;
1728
1729         proto_item_set_len(si, size );
1730       }
1731       break;
1732
1733     default:
1734       if (tree) {
1735         proto_tree_add_text(artnet_tree, tvb, offset, -1,
1736           "Data (%d bytes)", tvb_reported_length_remaining(tvb, offset));
1737       }
1738       break;
1739   }
1740
1741
1742
1743 }
1744
1745 void
1746 proto_register_artnet(void) {
1747   static hf_register_info hf[] = {
1748
1749     /* General */
1750
1751     { &hf_artnet_filler,
1752       { "filler",
1753         "artnet.filler",
1754         FT_BYTES, BASE_HEX, NULL, 0x0,
1755         "filler", HFILL }},
1756
1757     { &hf_artnet_spare,
1758       { "spare",
1759         "artnet.spare",
1760         FT_BYTES, BASE_HEX, NULL, 0x0,
1761         "spare", HFILL }},
1762
1763     /* header */
1764
1765     { &hf_artnet_header,
1766       { "Descriptor Header",
1767         "artnet.header",
1768         FT_NONE, BASE_NONE, NULL, 0,
1769         "Art-Net Descriptor Header", HFILL }},
1770
1771     { &hf_artnet_header_id,
1772       { "ID",
1773         "artnet.header.id",
1774         FT_STRING, BASE_DEC, NULL, 0x0,
1775         "ArtNET ID", HFILL }},
1776
1777     { &hf_artnet_header_opcode,
1778       { "Opcode",
1779         "artnet.header.opcode",
1780         FT_UINT16, BASE_HEX, VALS(artnet_opcode_vals), 0x0,
1781         "Art-Net message type", HFILL }},
1782
1783     { &hf_artnet_header_protver,
1784       { "ProVer",
1785         "artnet.header.protver",
1786         FT_UINT16, BASE_DEC, NULL, 0x0,
1787         "Protcol revision number", HFILL }},
1788
1789     /* ArtPoll */
1790
1791     { &hf_artnet_poll,
1792       { "ArtPoll packet",
1793         "artnet.poll",
1794         FT_NONE, BASE_NONE, NULL, 0,
1795         "Art-Net ArtPoll packet", HFILL }},
1796
1797     { &hf_artnet_poll_talktome,
1798       { "TalkToMe",
1799         "artnet.poll.talktome",
1800         FT_UINT8, BASE_HEX, NULL, 0x0,
1801         "TalkToMe", HFILL }},
1802
1803     { &hf_artnet_poll_talktome_reply_dest,
1804       { "Reply destination",
1805         "artnet.poll.talktome_reply_dest",
1806         FT_UINT8, BASE_HEX, NULL, 0x01,
1807         "Reply destination", HFILL }},
1808
1809     { &hf_artnet_poll_talktome_reply_type,
1810       { "Reply type",
1811         "artnet.poll.talktome_reply_type",
1812         FT_UINT8, BASE_HEX, NULL, 0x02,
1813         "Reply type", HFILL }},
1814
1815     { &hf_artnet_poll_talktome_unused,
1816       { "unused",
1817         "artnet.poll.talktome_unused",
1818         FT_UINT8, BASE_HEX, NULL, 0xfc,
1819         "unused", HFILL }},
1820
1821     /* ArtPollReply */
1822
1823     { &hf_artnet_poll_reply,
1824       { "ArtPollReply packet",
1825         "artnet.poll_reply",
1826         FT_NONE, BASE_NONE, NULL, 0,
1827         "Art-Net ArtPollReply packet", HFILL }},
1828
1829     { &hf_artnet_poll_reply_ip_address,
1830       { "IP Address",
1831         "artnet.poll_reply.ip_address",
1832         FT_IPv4, BASE_DEC, NULL, 0x0,
1833         "IP Address", HFILL }},
1834
1835     { &hf_artnet_poll_reply_port_nr,
1836       { "Port number",
1837         "artnet.poll_reply.port_nr",
1838         FT_UINT16, BASE_DEC, NULL, 0x0,
1839         "Port Number", HFILL }},
1840
1841     { &hf_artnet_poll_reply_versinfo,
1842       { "Version Info",
1843         "artnet.poll_reply.versinfo",
1844         FT_UINT16, BASE_HEX, NULL, 0x0,
1845         "Version info", HFILL }},
1846
1847     { &hf_artnet_poll_reply_subswitch,
1848       { "SubSwitch",
1849         "artnet.poll_reply.subswitch",
1850         FT_UINT16, BASE_HEX, NULL, 0x0,
1851         "Subswitch version", HFILL }},
1852
1853     { &hf_artnet_poll_reply_oem,
1854       { "Oem",
1855         "artnet.poll_reply.oem",
1856         FT_UINT16, BASE_HEX, VALS(artnet_oem_code_vals), 0x0,
1857         "OEM", HFILL }},
1858
1859     { &hf_artnet_poll_reply_ubea_version,
1860       { "UBEA Version",
1861         "artnet.poll_reply.ubea_version",
1862         FT_UINT8, BASE_DEC, NULL, 0x0,
1863         "UBEA version number", HFILL }},
1864
1865     { &hf_artnet_poll_reply_status,
1866       { "Status",
1867         "artnet.poll_reply.status",
1868         FT_UINT8, BASE_HEX, NULL, 0x0,
1869         "Status", HFILL }},
1870
1871     { &hf_artnet_poll_reply_esta_man,
1872       { "ESTA Code",
1873         "artnet.poll_reply.esta_man",
1874         FT_UINT16, BASE_HEX, VALS(artnet_esta_man_vals), 0x0,
1875         "ESTA Code", HFILL }},
1876
1877     { &hf_artnet_poll_reply_short_name,
1878       { "Short Name",
1879         "artnet.poll_reply.short_name",
1880         FT_STRING, BASE_DEC, NULL, 0x0,
1881         "Short Name", HFILL }},
1882
1883     { &hf_artnet_poll_reply_long_name,
1884       { "Long Name",
1885         "artnet.poll_reply.long_name",
1886         FT_STRING, BASE_DEC, NULL, 0x0,
1887         "Long Name", HFILL }},
1888
1889     { &hf_artnet_poll_reply_node_report,
1890       { "Node Report",
1891         "artnet.poll_reply.node_report",
1892         FT_STRING, BASE_DEC, NULL, 0x0,
1893         "Node Report", HFILL }},
1894
1895     { &hf_artnet_poll_reply_port_info,
1896       { "Port Info",
1897         "artnet.poll_reply.port_info",
1898         FT_NONE, BASE_NONE, NULL, 0,
1899         "Port Info", HFILL }},
1900
1901     { &hf_artnet_poll_reply_num_ports,
1902       { "Number of Ports",
1903         "artnet.poll_reply.num_ports",
1904         FT_UINT16, BASE_DEC, NULL, 0x0,
1905         "Number of Ports", HFILL }},
1906
1907     { &hf_artnet_poll_reply_port_types,
1908       { "Port Types",
1909         "artnet.poll_reply.port_types",
1910         FT_NONE, BASE_NONE, NULL, 0,
1911         "Port Types", HFILL }},
1912
1913     { &hf_artnet_poll_reply_port_types_1,
1914       { "Type of Port 1",
1915         "artnet.poll_reply.port_types_1",
1916         FT_UINT8, BASE_HEX, NULL, 0x0,
1917         "Type of Port 1", HFILL }},
1918
1919     { &hf_artnet_poll_reply_port_types_2,
1920       { "Type of Port 2",
1921         "artnet.poll_reply.port_types_2",
1922         FT_UINT8, BASE_HEX, NULL, 0x0,
1923         "Type of Port 2", HFILL }},
1924
1925     { &hf_artnet_poll_reply_port_types_3,
1926       { "Type of Port 3",
1927         "artnet.poll_reply.port_types_3",
1928         FT_UINT8, BASE_HEX, NULL, 0x0,
1929         "Type of Port 3", HFILL }},
1930
1931     { &hf_artnet_poll_reply_port_types_4,
1932       { "Type of Port 4",
1933         "artnet.poll_reply.port_types_4",
1934         FT_UINT8, BASE_HEX, NULL, 0x0,
1935         "Type of Port 4", HFILL }},
1936
1937     { &hf_artnet_poll_reply_good_input,
1938       { "Input Status",
1939         "artnet.poll_reply.good_input",
1940         FT_NONE, BASE_NONE, NULL, 0,
1941         "Input Status", HFILL }},
1942
1943     { &hf_artnet_poll_reply_good_input_1,
1944       { "Input status of Port 1",
1945         "artnet.poll_reply.good_input_1",
1946         FT_UINT8, BASE_HEX, NULL, 0x0,
1947         "Input status of Port 1", HFILL }},
1948
1949     { &hf_artnet_poll_reply_good_input_2,
1950       { "Input status of Port 2",
1951         "artnet.poll_reply.good_input_2",
1952         FT_UINT8, BASE_HEX, NULL, 0x0,
1953         "Input status of Port 2", HFILL }},
1954
1955     { &hf_artnet_poll_reply_good_input_3,
1956       { "Input status of Port 3",
1957         "artnet.poll_reply.good_input_3",
1958         FT_UINT8, BASE_HEX, NULL, 0x0,
1959         "Input status of Port 3", HFILL }},
1960
1961     { &hf_artnet_poll_reply_good_input_4,
1962       { "Input status of Port 4",
1963         "artnet.poll_reply.good_input_4",
1964         FT_UINT8, BASE_HEX, NULL, 0x0,
1965         "Input status of Port 4", HFILL }},
1966
1967     { &hf_artnet_poll_reply_good_output,
1968       { "Output Status",
1969         "artnet.poll_reply.good_output",
1970         FT_NONE, BASE_NONE, NULL, 0,
1971         "Port output status", HFILL }},
1972
1973     { &hf_artnet_poll_reply_good_output_1,
1974       { "Output status of Port 1",
1975         "artnet.poll_reply.good_output_1",
1976         FT_UINT8, BASE_HEX, NULL, 0x0,
1977         "Output status of Port 1", HFILL }},
1978
1979     { &hf_artnet_poll_reply_good_output_2,
1980       { "Output status of Port 2",
1981         "artnet.poll_reply.good_output_2",
1982         FT_UINT8, BASE_HEX, NULL, 0x0,
1983         "Output status of Port 2", HFILL }},
1984
1985     { &hf_artnet_poll_reply_good_output_3,
1986       { "Output status of Port 3",
1987         "artnet.poll_reply.good_output_3",
1988         FT_UINT8, BASE_HEX, NULL, 0x0,
1989         "Output status of Port 3", HFILL }},
1990
1991     { &hf_artnet_poll_reply_good_output_4,
1992       { "Output status of Port 4",
1993         "artnet.poll_reply.good_output_4",
1994         FT_UINT8, BASE_HEX, NULL, 0x0,
1995         "Outpus status of Port 4", HFILL }},
1996
1997     { &hf_artnet_poll_reply_swin,
1998       { "Input Subswitch",
1999         "artnet.poll_reply.swin",
2000         FT_NONE, BASE_NONE, NULL, 0,
2001         "Input Subswitch", HFILL }},
2002
2003     { &hf_artnet_poll_reply_swin_1,
2004       { "Input Subswitch of Port 1",
2005         "artnet.poll_reply.swin_1",
2006         FT_UINT8, BASE_HEX, NULL, 0x0,
2007         "Input Subswitch of Port 1", HFILL }},
2008
2009     { &hf_artnet_poll_reply_swin_2,
2010       { "Input Subswitch of Port 2",
2011         "artnet.poll_reply.swin_2",
2012         FT_UINT8, BASE_HEX, NULL, 0x0,
2013         "Input Subswitch of Port 2", HFILL }},
2014
2015     { &hf_artnet_poll_reply_swin_3,
2016       { "Input Subswitch of Port 3",
2017         "artnet.poll_reply.swin_3",
2018         FT_UINT8, BASE_HEX, NULL, 0x0,
2019         "Input Subswitch of Port 3", HFILL }},
2020
2021     { &hf_artnet_poll_reply_swin_4,
2022       { "Input Subswitch of Port 4",
2023         "artnet.poll_reply.swin_4",
2024         FT_UINT8, BASE_HEX, NULL, 0x0,
2025         "Input Subswitch of Port 4", HFILL }},
2026
2027     { &hf_artnet_poll_reply_swout,
2028       { "Output Subswitch",
2029         "artnet.poll_reply.swout",
2030         FT_NONE, BASE_NONE, NULL, 0,
2031         "Output Subswitch", HFILL }},
2032
2033     { &hf_artnet_poll_reply_swout_1,
2034       { "Output Subswitch of Port 1",
2035         "artnet.poll_reply.swout_1",
2036         FT_UINT8, BASE_HEX, NULL, 0x0,
2037         "Output Subswitch of Port 1", HFILL }},
2038
2039     { &hf_artnet_poll_reply_swout_2,
2040       { "Output Subswitch of Port 2",
2041         "artnet.poll_reply.swout_2",
2042         FT_UINT8, BASE_HEX, NULL, 0x0,
2043         "Output Subswitch of Port 2", HFILL }},
2044
2045     { &hf_artnet_poll_reply_swout_3,
2046       { "Output Subswitch of Port 3",
2047         "artnet.poll_reply.swout_3",
2048         FT_UINT8, BASE_HEX, NULL, 0x0,
2049         "Output Subswitch of Port 3", HFILL }},
2050
2051     { &hf_artnet_poll_reply_swout_4,
2052       { "Output Subswitch of Port 4",
2053         "artnet.poll_reply.swout_4",
2054         FT_UINT8, BASE_HEX, NULL, 0x0,
2055         "Ouput Subswitch of Port 4", HFILL }},
2056
2057     { &hf_artnet_poll_reply_swvideo,
2058       { "SwVideo",
2059         "artnet.poll_reply.swvideo",
2060         FT_UINT8, BASE_HEX, NULL, 0x0,
2061         "SwVideo", HFILL }},
2062
2063     { &hf_artnet_poll_reply_swmacro,
2064       { "SwMacro",
2065         "artnet.poll_reply.swmacro",
2066         FT_UINT8, BASE_HEX, NULL, 0x0,
2067         "SwMacro", HFILL }},
2068
2069     { &hf_artnet_poll_reply_swremote,
2070       { "SwRemote",
2071         "artnet.poll_reply.swremote",
2072         FT_UINT8, BASE_HEX, NULL, 0x0,
2073         "SwRemote", HFILL }},
2074
2075     { &hf_artnet_poll_reply_mac,
2076       { "MAC",
2077         "artnet.poll_reply.mac",
2078         FT_ETHER, BASE_HEX, NULL, 0x0,
2079         "MAC", HFILL }},
2080
2081     /* ArtOutput */
2082
2083     { &hf_artnet_output,
2084       { "ArtDMX packet",
2085         "artnet.output",
2086         FT_NONE, BASE_NONE, NULL, 0,
2087         "Art-Net ArtDMX packet", HFILL }},
2088
2089     { &hf_artnet_output_sequence,
2090       { "Sequence",
2091         "artnet.output.sequence",
2092         FT_UINT8, BASE_DEC, NULL, 0x0,
2093         "Sequence", HFILL }},
2094
2095     { &hf_artnet_output_physical,
2096       { "Physical",
2097         "artnet.output.physical",
2098         FT_UINT8, BASE_DEC, NULL, 0x0,
2099         "Physical", HFILL }},
2100
2101     { &hf_artnet_output_universe,
2102       { "Universe",
2103         "artnet.output.universe",
2104         FT_UINT16, BASE_DEC, NULL, 0x0,
2105         "Universe", HFILL }},
2106
2107     { &hf_artnet_output_length,
2108       { "Length",
2109         "artnet.output.length",
2110         FT_UINT16, BASE_DEC, NULL, 0x0,
2111         "Length", HFILL }},
2112
2113     { &hf_artnet_output_data,
2114       { "DMX data",
2115         "artnet.output.data",
2116         FT_NONE, BASE_DEC, NULL, 0x0,
2117         "DMX Data", HFILL }},
2118
2119     { &hf_artnet_output_data_filter,
2120       { "DMX data filter",
2121         "artnet.output.data_filter",
2122         FT_BYTES, BASE_DEC, NULL, 0x0,
2123         "DMX Data Filter", HFILL }},
2124
2125     { &hf_artnet_output_dmx_data,
2126       { "DMX data",
2127         "artnet.output.dmx_data",
2128         FT_NONE, BASE_DEC, NULL, 0x0,
2129         "DMX Data", HFILL }},
2130
2131     /* ArtAddress */
2132
2133     { &hf_artnet_address,
2134       { "ArtAddress packet",
2135         "artnet.address",
2136         FT_NONE, BASE_NONE, NULL, 0,
2137         "Art-Net ArtAddress packet", HFILL }},
2138
2139     { &hf_artnet_address_short_name,
2140       { "Short Name",
2141         "artnet.address.short_name",
2142         FT_STRING, BASE_DEC, NULL, 0x0,
2143         "Short Name", HFILL }},
2144
2145     { &hf_artnet_address_long_name,
2146       { "Long Name",
2147         "artnet.address.long_name",
2148         FT_STRING, BASE_DEC, NULL, 0x0,
2149         "Long Name", HFILL }},
2150
2151     { &hf_artnet_address_swin,
2152       { "Input Subswitch",
2153         "artnet.address.swin",
2154         FT_NONE, BASE_NONE, NULL, 0,
2155         "Input Subswitch", HFILL }},
2156
2157     { &hf_artnet_address_swin_1,
2158       { "Input Subswitch of Port 1",
2159         "artnet.address.swin_1",
2160         FT_UINT8, BASE_HEX, NULL, 0x0,
2161         "Input Subswitch of Port 1", HFILL }},
2162
2163     { &hf_artnet_address_swin_2,
2164       { "Input Subswitch of Port 2",
2165         "artnet.address.swin_2",
2166         FT_UINT8, BASE_HEX, NULL, 0x0,
2167         "Input Subswitch of Port 2", HFILL }},
2168
2169     { &hf_artnet_address_swin_3,
2170       { "Input Subswitch of Port 3",
2171         "artnet.address.swin_3",
2172         FT_UINT8, BASE_HEX, NULL, 0x0,
2173         "Input Subswitch of Port 3", HFILL }},
2174
2175     { &hf_artnet_address_swin_4,
2176       { "Input Subswitch of Port 4",
2177         "artnet.address.swin_4",
2178         FT_UINT8, BASE_HEX, NULL, 0x0,
2179         "Input Subswitch of Port 4", HFILL }},
2180
2181     { &hf_artnet_address_swout,
2182       { "Output Subswitch",
2183         "artnet.address.swout",
2184         FT_NONE, BASE_NONE, NULL, 0,
2185         "Output Subswitch", HFILL }},
2186
2187     { &hf_artnet_address_swout_1,
2188       { "Output Subswitch of Port 1",
2189         "artnet.address.swout_1",
2190         FT_UINT8, BASE_HEX, NULL, 0x0,
2191         "Output Subswitch of Port 1", HFILL }},
2192
2193     { &hf_artnet_address_swout_2,
2194       { "Output Subswitch of Port 2",
2195         "artnet.address.swout_2",
2196         FT_UINT8, BASE_HEX, NULL, 0x0,
2197         "Output Subswitch of Port 2", HFILL }},
2198
2199     { &hf_artnet_address_swout_3,
2200       { "Output Subswitch of Port 3",
2201         "artnet.address.swout_3",
2202         FT_UINT8, BASE_HEX, NULL, 0x0,
2203         "Output Subswitch of Port 3", HFILL }},
2204
2205     { &hf_artnet_address_swout_4,
2206       { "Output Subswitch of Port 4",
2207         "artnet.address.swout_4",
2208         FT_UINT8, BASE_HEX, NULL, 0x0,
2209         "Ouput Subswitch of Port 4", HFILL }},
2210
2211     { &hf_artnet_address_subswitch,
2212       { "Subswitch",
2213         "artnet.address.subswitch",
2214         FT_UINT8, BASE_HEX, NULL, 0x0,
2215         "Subswitch", HFILL }},
2216
2217     { &hf_artnet_address_swvideo,
2218       { "SwVideo",
2219         "artnet.address.swvideo",
2220         FT_UINT8, BASE_HEX, NULL, 0x0,
2221         "SwVideo", HFILL }},
2222
2223     { &hf_artnet_address_command,
2224       { "Command",
2225         "artnet.address.command",
2226         FT_UINT8, BASE_HEX, VALS(artnet_address_command_vals), 0x0,
2227         "Command", HFILL }},
2228
2229     /* ArtInput */
2230
2231     { &hf_artnet_input,
2232       { "ArtInput packet",
2233         "artnet.input",
2234         FT_NONE, BASE_NONE, NULL, 0,
2235         "Art-Net ArtInput packet", HFILL }},
2236
2237     { &hf_artnet_input_num_ports,
2238       { "Number of Ports",
2239         "artnet.input.num_ports",
2240         FT_UINT16, BASE_DEC, NULL, 0x0,
2241         "Number of Ports", HFILL }},
2242
2243     { &hf_artnet_input_input,
2244       { "Port Status",
2245         "artnet.input.input",
2246         FT_NONE, BASE_NONE, NULL, 0,
2247         "Port Status", HFILL }},
2248
2249     { &hf_artnet_input_input_1,
2250       { "Status of Port 1",
2251         "artnet.input.input_1",
2252         FT_UINT8, BASE_HEX, NULL, 0x0,
2253         "Status of Port 1", HFILL }},
2254
2255     { &hf_artnet_input_input_2,
2256       { "Status of Port 2",
2257         "artnet.input.input_2",
2258         FT_UINT8, BASE_HEX, NULL, 0x0,
2259         "Status of Port 2", HFILL }},
2260
2261     { &hf_artnet_input_input_3,
2262       { "Status of Port 3",
2263         "artnet.input.input_3",
2264         FT_UINT8, BASE_HEX, NULL, 0x0,
2265         "Status of Port 3", HFILL }},
2266
2267     { &hf_artnet_input_input_4,
2268       { "Status of Port 4",
2269         "artnet.input.input_4",
2270         FT_UINT8, BASE_HEX, NULL, 0x0,
2271         "Status of Port 4", HFILL }},
2272
2273     /* ArtFirmwareMaster */
2274
2275     { &hf_artnet_firmware_master,
2276       { "ArtFirmwareMaster packet",
2277         "artnet.firmware_master",
2278         FT_NONE, BASE_NONE, NULL, 0,
2279         "Art-Net ArtFirmwareMaster packet", HFILL }},
2280
2281     { &hf_artnet_firmware_master_type,
2282       { "Type",
2283         "artnet.firmware_master.type",
2284         FT_UINT8, BASE_HEX, VALS(artnet_firmware_master_type_vals), 0x0,
2285         "Number of Ports", HFILL }},
2286
2287     { &hf_artnet_firmware_master_block_id,
2288       { "Block ID",
2289         "artnet.firmware_master.block_id",
2290         FT_UINT8, BASE_DEC, NULL, 0x0,
2291         "Block ID", HFILL }},
2292
2293     { &hf_artnet_firmware_master_length,
2294       { "Lentgh",
2295         "artnet.firmware_master.length",
2296         FT_UINT32, BASE_DEC, NULL, 0x0,
2297         "Length", HFILL }},
2298
2299     { &hf_artnet_firmware_master_data,
2300       { "data",
2301         "artnet.firmware_master.data",
2302         FT_BYTES, BASE_HEX, NULL, 0x0,
2303         "data", HFILL }},
2304
2305     /* ArtFirmwareReply */
2306
2307     { &hf_artnet_firmware_reply,
2308       { "ArtFirmwareReply packet",
2309         "artnet.firmware_reply",
2310         FT_NONE, BASE_NONE, NULL, 0,
2311         "Art-Net ArtFirmwareReply packet", HFILL }},
2312
2313     { &hf_artnet_firmware_reply_type,
2314       { "Type",
2315         "artnet.firmware_reply.type",
2316         FT_UINT8, BASE_HEX, VALS(artnet_firmware_reply_type_vals), 0x0,
2317         "Number of Ports", HFILL }},
2318
2319     /* ArtVideoSetup */
2320
2321     { &hf_artnet_video_setup,
2322       { "ArtVideoSetup packet",
2323         "artnet.video_setup",
2324         FT_NONE, BASE_NONE, NULL, 0,
2325         "ArtNET ArtVideoSetup packet", HFILL }},
2326
2327     { &hf_artnet_video_setup_control,
2328       { "control",
2329         "artnet.video_setup.control",
2330         FT_UINT8, BASE_HEX, NULL, 0x0,
2331         "control", HFILL }},
2332
2333     { &hf_artnet_video_setup_font_height,
2334       { "Font Height",
2335         "artnet.video_setup.font_height",
2336         FT_UINT8, BASE_DEC, NULL, 0x0,
2337         "Font Height", HFILL }},
2338
2339     { &hf_artnet_video_setup_first_font,
2340       { "First Font",
2341         "artnet.video_setup.first_font",
2342         FT_UINT8, BASE_DEC, NULL, 0x0,
2343         "First Font", HFILL }},
2344
2345     { &hf_artnet_video_setup_last_font,
2346       { "Last Font",
2347         "artnet.video_setup.last_font",
2348         FT_UINT8, BASE_DEC, NULL, 0x0,
2349         "Last Font", HFILL }},
2350
2351     { &hf_artnet_video_setup_win_font_name,
2352       { "Windows Font Name",
2353         "artnet.video_setup.win_font_name",
2354         FT_STRING, BASE_DEC, NULL, 0x0,
2355         "Windows Font Name", HFILL }},
2356
2357     { &hf_artnet_video_setup_font_data,
2358       { "Font data",
2359         "artnet.video_setup.font_data",
2360         FT_BYTES, BASE_HEX, NULL, 0x0,
2361         "Font Date", HFILL }},
2362
2363     /* ArtVideoPalette */
2364
2365     { &hf_artnet_video_palette,
2366       { "ArtVideoPalette packet",
2367         "artnet.video_palette",
2368         FT_NONE, BASE_NONE, NULL, 0,
2369         "Art-Net ArtVideoPalette packet", HFILL }},
2370
2371     { &hf_artnet_video_palette_colour_red,
2372       { "Colour Red",
2373         "artnet.video_palette.colour_red",
2374         FT_BYTES, BASE_HEX, NULL, 0x0,
2375         "Colour Red", HFILL }},
2376
2377     { &hf_artnet_video_palette_colour_green,
2378       { "Colour Green",
2379         "artnet.video_palette.colour_green",
2380         FT_BYTES, BASE_HEX, NULL, 0x0,
2381         "Colour Green", HFILL }},
2382
2383     { &hf_artnet_video_palette_colour_blue,
2384       { "Colour Blue",
2385         "artnet.video_palette.colour_blue",
2386         FT_BYTES, BASE_HEX, NULL, 0x0,
2387         "Colour Blue", HFILL }},
2388
2389     /* ArtVideoData */
2390
2391     { &hf_artnet_video_data,
2392       { "ArtVideoData packet",
2393         "artnet.video_data",
2394         FT_NONE, BASE_NONE, NULL, 0,
2395         "Art-Net ArtVideoData packet", HFILL }},
2396
2397     { &hf_artnet_video_data_pos_x,
2398       { "PosX",
2399         "artnet.video_data.pos_x",
2400         FT_UINT8, BASE_DEC, NULL, 0x0,
2401         "PosX", HFILL }},
2402
2403     { &hf_artnet_video_data_pos_y,
2404       { "PosY",
2405         "artnet.video_data.pos_y",
2406         FT_UINT8, BASE_DEC, NULL, 0x0,
2407         "PosY", HFILL }},
2408
2409     { &hf_artnet_video_data_len_x,
2410       { "LenX",
2411         "artnet.video_data.len_x",
2412         FT_UINT8, BASE_DEC, NULL, 0x0,
2413         "LenX", HFILL }},
2414
2415     { &hf_artnet_video_data_len_y,
2416       { "LenY",
2417         "artnet.video_data.len_y",
2418         FT_UINT8, BASE_DEC, NULL, 0x0,
2419         "LenY", HFILL }},
2420
2421     { &hf_artnet_video_data_data,
2422       { "Video Data",
2423         "artnet.video_data.data",
2424         FT_BYTES, BASE_HEX, NULL, 0x0,
2425         "Video Data", HFILL }},
2426
2427     /* ArtTodRequest */
2428     { &hf_artnet_tod_request,
2429       { "ArtTodRequest packet",
2430         "artnet.tod_request",
2431         FT_NONE, BASE_NONE, NULL, 0,
2432         "Art-Net ArtTodRequest packet", HFILL }},
2433
2434     { &hf_artnet_tod_request_command,
2435       { "Command",
2436         "artnet.tod_request.command",
2437         FT_UINT8, BASE_HEX, VALS(artnet_tod_request_command_vals), 0x0,
2438         "Command", HFILL }},
2439
2440     { &hf_artnet_tod_request_ad_count,
2441       { "Address Count",
2442         "artnet.tod_request.ad_count",
2443         FT_UINT8, BASE_DEC, NULL, 0x0,
2444         "Address Count", HFILL }},
2445
2446     { &hf_artnet_tod_request_address,
2447       { "Address",
2448         "artnet.tod_request.address",
2449         FT_BYTES, BASE_HEX, NULL, 0x0,
2450         "Address", HFILL }},
2451
2452     /* ArtTodData */
2453     { &hf_artnet_tod_data,
2454       { "ArtTodData packet",
2455         "artnet.tod_data",
2456         FT_NONE, BASE_NONE, NULL, 0,
2457         "Art-Net ArtTodData packet", HFILL }},
2458
2459     { &hf_artnet_tod_data_port,
2460       { "Port",
2461         "artnet.tod_data.port",
2462         FT_UINT8, BASE_DEC, NULL, 0x0,
2463         "Port", HFILL }},
2464
2465     { &hf_artnet_tod_data_command_response,
2466       { "Command Response",
2467         "artnet.tod_data.command_response",
2468         FT_UINT8, BASE_HEX, VALS(artnet_tod_data_command_vals), 0x0,
2469         "Command Response", HFILL }},
2470
2471     { &hf_artnet_tod_data_address,
2472       { "Address",
2473         "artnet.tod_data.address",
2474         FT_UINT8, BASE_HEX, NULL, 0x0,
2475         "Address", HFILL }},
2476
2477     { &hf_artnet_tod_data_uid_total,
2478       { "UID Total",
2479         "artnet.tod_data.uid_total",
2480         FT_UINT16, BASE_DEC, NULL, 0x0,
2481         "UID Total", HFILL }},
2482
2483     { &hf_artnet_tod_data_block_count,
2484       { "Block Count",
2485         "artnet.tod_data.block_count",
2486         FT_UINT8, BASE_DEC, NULL, 0x0,
2487         "Block Count", HFILL }},
2488
2489     { &hf_artnet_tod_data_uid_count,
2490       { "UID Count",
2491         "artnet.tod_data.uid_count",
2492         FT_UINT8, BASE_DEC, NULL, 0x0,
2493         "UID Count", HFILL }},
2494
2495     { &hf_artnet_tod_data_tod,
2496       { "TOD",
2497         "artnet.tod_data.tod",
2498         FT_BYTES, BASE_HEX, NULL, 0x0,
2499         "TOD", HFILL }},
2500
2501     /* ArtTodControl */
2502     { &hf_artnet_tod_control,
2503       { "ArtTodControl packet",
2504         "artner.tod_control",
2505         FT_NONE, BASE_NONE, NULL, 0,
2506         "Art-Net ArtTodControl packet", HFILL }},
2507
2508     { &hf_artnet_tod_control_command,
2509       { "Command",
2510         "artnet.tod_control.command",
2511         FT_UINT8, BASE_HEX, VALS(artnet_tod_control_command_vals), 0x0,
2512         "Command", HFILL }},
2513
2514     { &hf_artnet_tod_control_address,
2515       { "Address",
2516         "artnet.tod_request.address",
2517         FT_UINT8, BASE_HEX, NULL, 0x0,
2518         "Address", HFILL }},
2519
2520     /* ArtRdm */
2521     { &hf_artnet_rdm,
2522       { "ArtRdm packet",
2523         "artnet.rdm",
2524         FT_NONE, BASE_NONE, NULL, 0,
2525         "Art-Net ArtRdm packet", HFILL }},
2526
2527     { &hf_artnet_rdm_command,
2528       { "Command",
2529         "artnet.rdm.command",
2530         FT_UINT8, BASE_HEX, VALS(artnet_rdm_command_vals), 0x0,
2531         "Command", HFILL }},
2532
2533     { &hf_artnet_rdm_address,
2534       { "Address",
2535         "artnet.rdm.address",
2536         FT_UINT8, BASE_HEX, NULL, 0x0,
2537         "Address", HFILL }},
2538
2539     /* ArtIpProg */
2540     { &hf_artnet_ip_prog,
2541       { "ArtIpProg packet",
2542         "artnet.ip_prog",
2543         FT_NONE, BASE_NONE, NULL, 0,
2544         "ArtNET ArtIpProg packet", HFILL }},
2545
2546     { &hf_artnet_ip_prog_command,
2547       { "Command",
2548         "artnet.ip_prog.command",
2549         FT_UINT8, BASE_HEX, NULL, 0x0,
2550         "Command", HFILL }},
2551
2552     { &hf_artnet_ip_prog_command_prog_port,
2553       { "Program Port",
2554         "artnet.ip_prog.command_prog_port",
2555         FT_UINT8, BASE_HEX, NULL, 0x01,
2556         "Program Port", HFILL }},
2557
2558     { &hf_artnet_ip_prog_command_prog_sm,
2559       { "Program Subnet Mask",
2560         "artnet.ip_prog.command_prog_sm",
2561         FT_UINT8, BASE_HEX, NULL, 0x02,
2562         "Program Subnet Mask", HFILL }},
2563
2564     { &hf_artnet_ip_prog_command_prog_ip,
2565       { "Program IP",
2566         "artnet.ip_prog.command_prog_ip",
2567         FT_UINT8, BASE_HEX, NULL, 0x04,
2568         "Program IP", HFILL }},
2569
2570     { &hf_artnet_ip_prog_command_reset,
2571       { "Reset parameters",
2572         "artnet.ip_prog.command_reset",
2573         FT_UINT8, BASE_HEX, NULL, 0x08,
2574         "Reset parameters", HFILL }},
2575
2576     { &hf_artnet_ip_prog_command_unused,
2577       { "Unused",
2578         "artnet.ip_prog.command_unused",
2579         FT_UINT8, BASE_HEX, NULL, 0x70,
2580         "Unused", HFILL }},
2581
2582     { &hf_artnet_ip_prog_command_prog_enable,
2583       { "Enable Programming",
2584         "artnet.ip_prog.command_prog_enable",
2585         FT_UINT8, BASE_HEX, NULL, 0x80,
2586         "Enable Programming", HFILL }},
2587
2588     { &hf_artnet_ip_prog_ip,
2589       { "IP Address",
2590         "artnet.ip_prog.ip",
2591         FT_IPv4, BASE_DEC, NULL, 0x0,
2592         "IP Address", HFILL }},
2593
2594     { &hf_artnet_ip_prog_sm,
2595       { "Subnet mask",
2596         "artnet.ip_prog.sm",
2597         FT_IPv4, BASE_DEC, NULL, 0x0,
2598         "IP Subnet mask", HFILL }},
2599
2600     { &hf_artnet_ip_prog_port,
2601       { "Port",
2602         "artnet.ip_prog.port",
2603         FT_UINT16, BASE_DEC, NULL, 0x0,
2604         "Port", HFILL }},
2605
2606     /* ArtIpProgReply */
2607     { &hf_artnet_ip_prog_reply,
2608       { "ArtIpProgReplay packet",
2609         "artnet.ip_prog_reply",
2610         FT_NONE, BASE_NONE, NULL, 0,
2611         "Art-Net ArtIpProgReply packet", HFILL }},
2612
2613     { &hf_artnet_ip_prog_reply_ip,
2614       { "IP Address",
2615         "artnet.ip_prog_reply.ip",
2616         FT_IPv4, BASE_DEC, NULL, 0x0,
2617         "IP Address", HFILL }},
2618
2619     { &hf_artnet_ip_prog_reply_sm,
2620       { "Subnet mask",
2621         "artnet.ip_prog_reply.sm",
2622         FT_IPv4, BASE_DEC, NULL, 0x0,
2623         "IP Subnet mask", HFILL }},
2624
2625     { &hf_artnet_ip_prog_reply_port,
2626       { "Port",
2627         "artnet.ip_prog_reply.port",
2628         FT_UINT16, BASE_DEC, NULL, 0x0,
2629         "Port", HFILL }},
2630
2631     /* ArtPollServerReply */
2632     { &hf_artnet_poll_server_reply,
2633       { "ArtPollServerReply packet",
2634         "artnet.poll_server_reply",
2635         FT_NONE, BASE_NONE, NULL, 0,
2636         "Art-Net ArtPollServerReply packet", HFILL }}
2637
2638   };
2639
2640   static gint *ett[] = {
2641     &ett_artnet,
2642   };
2643
2644   module_t *artnet_module;
2645
2646   static enum_val_t disp_chan_val_types[] = {
2647      { "pro", "Percent", 0 },
2648      { "hex", "Hexadecimal", 1 },
2649      { "dec", "Decimal", 2 },
2650      { NULL, NULL, 0 }
2651   };
2652
2653   static enum_val_t disp_chan_nr_types[] = {
2654      { "hex", "Hexadecimal", 0 },
2655      { "dec", "Decimal", 1 },
2656      { NULL, NULL, 0 }
2657   };
2658
2659   static enum_val_t col_count[] = {
2660      { "6", "6", 6 },
2661      { "10", "10", 10 },
2662      { "12", "12", 12 },
2663      { "16", "16", 16 },
2664      { "24", "24", 24 },
2665      { NULL, NULL, 0 }
2666   };
2667
2668   proto_artnet = proto_register_protocol("Art-Net",
2669                                        "ARTNET","artnet");
2670   proto_register_field_array(proto_artnet,hf,array_length(hf));
2671   proto_register_subtree_array(ett,array_length(ett));
2672
2673   artnet_module = prefs_register_protocol(proto_artnet,
2674                                         proto_reg_handoff_artnet);
2675   prefs_register_uint_preference(artnet_module, "udp_port",
2676                                  "UDP Port",
2677                                  "The UDP port on which "
2678                                  "Art-Net "
2679                                  "packets will be sent",
2680                                  10,&global_udp_port_artnet);
2681
2682   prefs_register_enum_preference(artnet_module, "dmx_disp_chan_val_type",
2683             "DMX Display channel value type", 
2684             "The way DMX values are displayed", 
2685                                  &global_disp_chan_val_type,
2686                                  disp_chan_val_types, FALSE);
2687
2688   prefs_register_enum_preference(artnet_module, "dmx_disp_chan_nr_type",
2689             "DMX Display channel nr. type",
2690             "The way DMX channel numbers are displayed",
2691                                  &global_disp_chan_nr_type,
2692                                  disp_chan_nr_types, FALSE);
2693
2694   prefs_register_enum_preference(artnet_module, "dmx_disp_col_count",
2695             "DMX Display Column Count",
2696             "The number of columns for the DMX display",
2697                                  &global_disp_col_count,
2698                                  col_count, FALSE);
2699 }
2700
2701 /* The registration hand-off routing */
2702
2703 void
2704 proto_reg_handoff_artnet(void) {
2705   static int artnet_initialized = FALSE;
2706   static dissector_handle_t artnet_handle;
2707
2708   ip_handle = find_dissector("ip");
2709   rdm_handle = find_dissector("rdm");
2710
2711
2712   if(!artnet_initialized) {
2713     artnet_handle = create_dissector_handle(dissect_artnet,proto_artnet);
2714     artnet_initialized = TRUE;
2715   } else {
2716     dissector_delete("udp.port",udp_port_artnet,artnet_handle);
2717   }
2718
2719   udp_port_artnet = global_udp_port_artnet;
2720   
2721   dissector_add("udp.port",global_udp_port_artnet,artnet_handle);
2722 }
2723
2724 /* Start the functions we need for the plugin stuff */
2725
2726 #ifndef ENABLE_STATIC
2727
2728 G_MODULE_EXPORT void
2729 plugin_reg_handoff(void){
2730   proto_reg_handoff_artnet();
2731 }
2732
2733 G_MODULE_EXPORT void
2734 plugin_init(plugin_address_table_t *pat
2735 #ifndef PLUGINS_NEED_ADDRESS_TABLE
2736 _U_
2737 #endif
2738 ){
2739   /* initialise the table of pointers needed in Win32 DLLs */
2740   plugin_address_table_init(pat);
2741   /* register the new protocol, protocol fields, and subtrees */
2742   if (proto_artnet == -1) { /* execute protocol initialization only once */
2743     proto_register_artnet();
2744   }
2745 }
2746
2747 #endif
2748
2749 /* End the functions we need for plugin stuff */
2750