/src/wireshark/epan/dissectors/packet-enttec.c
Line | Count | Source |
1 | | /* packet-enttec.c |
2 | | * Routines for ENTTEC packet disassembly |
3 | | * |
4 | | * Copyright (c) 2003,2004 by Erwin Rol <erwin@erwinrol.com> |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1999 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | */ |
12 | | |
13 | | /* Include files */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/prefs.h> |
19 | | /* |
20 | | * See |
21 | | * |
22 | | * http://www.enttec.com/docs/enttec_protocol.pdf |
23 | | */ |
24 | | |
25 | | /* Define UDP/TCP ports for ENTTEC */ |
26 | | |
27 | 16 | #define UDP_PORT_ENTTEC 0x0D05 /* Not IANA registered */ |
28 | 16 | #define TCP_PORT_ENTTEC 0x0D05 /* Not IANA registered */ |
29 | | |
30 | | |
31 | 0 | #define ENTTEC_HEAD_ESPR 0x45535052 |
32 | 0 | #define ENTTEC_HEAD_ESPP 0x45535050 |
33 | 0 | #define ENTTEC_HEAD_ESAP 0x45534150 |
34 | 0 | #define ENTTEC_HEAD_ESDD 0x45534444 |
35 | 1 | #define ENTTEC_HEAD_ESNC 0x45534E43 |
36 | 0 | #define ENTTEC_HEAD_ESZZ 0x45535A5A |
37 | | |
38 | | static const value_string enttec_head_vals[] = { |
39 | | { ENTTEC_HEAD_ESPR, "Poll Reply" }, |
40 | | { ENTTEC_HEAD_ESPP, "Poll" }, |
41 | | { ENTTEC_HEAD_ESAP, "Ack/nAck" }, |
42 | | { ENTTEC_HEAD_ESDD, "DMX Data" }, |
43 | | { ENTTEC_HEAD_ESNC, "Config" }, |
44 | | { ENTTEC_HEAD_ESZZ, "Reset" }, |
45 | | { 0, NULL } |
46 | | }; |
47 | | |
48 | 0 | #define ENTTEC_DATA_TYPE_DMX 0x01 |
49 | | #define ENTTEC_DATA_TYPE_CHAN_VAL 0x02 |
50 | 0 | #define ENTTEC_DATA_TYPE_RLE 0x04 |
51 | | |
52 | | static const value_string enttec_data_type_vals[] = { |
53 | | { ENTTEC_DATA_TYPE_DMX, "Uncompressed DMX" }, |
54 | | { ENTTEC_DATA_TYPE_CHAN_VAL, "Channel+Value" }, |
55 | | { ENTTEC_DATA_TYPE_RLE, "RLE Compressed DMX" }, |
56 | | { 0, NULL } |
57 | | }; |
58 | | |
59 | | void proto_register_enttec(void); |
60 | | void proto_reg_handoff_enttec(void); |
61 | | |
62 | | static dissector_handle_t enttec_udp_handle, enttec_tcp_handle; |
63 | | |
64 | | /* Define the enttec proto */ |
65 | | static int proto_enttec; |
66 | | |
67 | | /* general */ |
68 | | static int hf_enttec_head; |
69 | | |
70 | | /* poll */ |
71 | | static int hf_enttec_poll_type; |
72 | | |
73 | | /* poll reply */ |
74 | | static int hf_enttec_poll_reply_mac; |
75 | | static int hf_enttec_poll_reply_node_type; |
76 | | static int hf_enttec_poll_reply_version; |
77 | | static int hf_enttec_poll_reply_switch; |
78 | | static int hf_enttec_poll_reply_name; |
79 | | static int hf_enttec_poll_reply_option; |
80 | | static int hf_enttec_poll_reply_tos; |
81 | | static int hf_enttec_poll_reply_ttl; |
82 | | |
83 | | /* dmx data */ |
84 | | static int hf_enttec_dmx_data_universe; |
85 | | static int hf_enttec_dmx_data_start_code; |
86 | | static int hf_enttec_dmx_data_type; |
87 | | static int hf_enttec_dmx_data_size; |
88 | | static int hf_enttec_dmx_data_data; |
89 | | static int hf_enttec_dmx_data_data_filter; |
90 | | static int hf_enttec_dmx_data_dmx_data; |
91 | | |
92 | | /* Define the tree for enttec */ |
93 | | static int ett_enttec; |
94 | | |
95 | | /* |
96 | | * Here are the global variables associated with the preferences |
97 | | * for enttec |
98 | | */ |
99 | | |
100 | | static int global_disp_chan_val_type; |
101 | | static int global_disp_col_count = 16; |
102 | | static int global_disp_chan_nr_type; |
103 | | |
104 | | static int |
105 | | dissect_enttec_poll_reply(tvbuff_t *tvb, unsigned offset, proto_tree *tree) |
106 | 0 | { |
107 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_mac, tvb, |
108 | 0 | offset, 6, ENC_NA); |
109 | 0 | offset += 6; |
110 | |
|
111 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_node_type, tvb, |
112 | 0 | offset, 2, ENC_BIG_ENDIAN); |
113 | 0 | offset += 2; |
114 | |
|
115 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_version, tvb, |
116 | 0 | offset, 1, ENC_BIG_ENDIAN); |
117 | 0 | offset += 1; |
118 | |
|
119 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_switch, tvb, |
120 | 0 | offset, 1, ENC_BIG_ENDIAN); |
121 | 0 | offset += 1; |
122 | |
|
123 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_name, tvb, |
124 | 0 | offset, 10, ENC_ASCII); |
125 | 0 | offset += 10; |
126 | |
|
127 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_option, tvb, |
128 | 0 | offset, 1, ENC_BIG_ENDIAN); |
129 | 0 | offset += 1; |
130 | |
|
131 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_tos, tvb, |
132 | 0 | offset, 1, ENC_BIG_ENDIAN); |
133 | 0 | offset += 1; |
134 | |
|
135 | 0 | proto_tree_add_item(tree, hf_enttec_poll_reply_ttl, tvb, |
136 | 0 | offset, 1, ENC_BIG_ENDIAN); |
137 | 0 | offset += 1; |
138 | | |
139 | | /* data */ |
140 | |
|
141 | 0 | return offset; |
142 | 0 | } |
143 | | |
144 | | static int |
145 | | dissect_enttec_poll(tvbuff_t *tvb, unsigned offset, proto_tree *tree) |
146 | 0 | { |
147 | 0 | proto_tree_add_item(tree, hf_enttec_poll_type, tvb, |
148 | 0 | offset, 1, ENC_BIG_ENDIAN); |
149 | 0 | offset += 1; |
150 | |
|
151 | 0 | return offset; |
152 | 0 | } |
153 | | |
154 | | static int |
155 | | dissect_enttec_ack(tvbuff_t *tvb _U_, unsigned offset, proto_tree *tree _U_) |
156 | 0 | { |
157 | |
|
158 | 0 | return offset; |
159 | 0 | } |
160 | | |
161 | | static int |
162 | | dissect_enttec_dmx_data(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, proto_tree *tree) |
163 | 0 | { |
164 | 0 | static const char* chan_format[] = { |
165 | 0 | "%2u ", |
166 | 0 | "%02x ", |
167 | 0 | "%3u " |
168 | 0 | }; |
169 | 0 | static const char* string_format[] = { |
170 | 0 | "%03x: %s", |
171 | 0 | "%3u: %s" |
172 | 0 | }; |
173 | |
|
174 | 0 | uint8_t *dmx_data = (uint8_t *)wmem_alloc(pinfo->pool, 512 * sizeof(uint8_t)); |
175 | 0 | uint16_t *dmx_data_offset = (uint16_t *)wmem_alloc(pinfo->pool, 513 * sizeof(uint16_t)); /* 1 extra for last offset */ |
176 | 0 | wmem_strbuf_t *dmx_epstr; |
177 | |
|
178 | 0 | proto_tree *hi,*si; |
179 | 0 | proto_item *item; |
180 | 0 | uint16_t length,r,c,row_count; |
181 | 0 | uint8_t v,type,count; |
182 | 0 | uint16_t ci,ui,i,start_offset,end_offset; |
183 | |
|
184 | 0 | proto_tree_add_item(tree, hf_enttec_dmx_data_universe, tvb, |
185 | 0 | offset, 1, ENC_BIG_ENDIAN); |
186 | 0 | offset += 1; |
187 | |
|
188 | 0 | proto_tree_add_item(tree, hf_enttec_dmx_data_start_code, tvb, |
189 | 0 | offset, 1, ENC_BIG_ENDIAN); |
190 | 0 | offset += 1; |
191 | |
|
192 | 0 | type = tvb_get_uint8(tvb, offset); |
193 | 0 | proto_tree_add_item(tree, hf_enttec_dmx_data_type, tvb, |
194 | 0 | offset, 1, ENC_BIG_ENDIAN); |
195 | 0 | offset += 1; |
196 | |
|
197 | 0 | length = tvb_get_ntohs(tvb, offset); |
198 | 0 | proto_tree_add_item(tree, hf_enttec_dmx_data_size, tvb, |
199 | 0 | offset, 2, ENC_BIG_ENDIAN); |
200 | 0 | offset += 2; |
201 | | |
202 | | /* |
203 | | * XXX - we should handle a too-long length better. |
204 | | */ |
205 | 0 | if (length > 512) |
206 | 0 | length = 512; |
207 | |
|
208 | 0 | if (type == ENTTEC_DATA_TYPE_RLE) { |
209 | | /* uncompress the DMX data */ |
210 | 0 | ui = 0; |
211 | 0 | ci = 0; |
212 | 0 | while (ci < length && ui < 512) { |
213 | 0 | v = tvb_get_uint8(tvb, offset+ci); |
214 | 0 | if (v == 0xFE) { |
215 | 0 | ci++; |
216 | 0 | count = tvb_get_uint8(tvb, offset+ci); |
217 | 0 | ci++; |
218 | 0 | v = tvb_get_uint8(tvb, offset+ci); |
219 | 0 | ci++; |
220 | 0 | for (i=0;i < count && ui < 512;i++) { |
221 | 0 | dmx_data[ui] = v; |
222 | 0 | dmx_data_offset[ui] = ci-3; |
223 | 0 | ui++; |
224 | 0 | } |
225 | 0 | } else if (v == 0xFD) { |
226 | 0 | ci++; |
227 | 0 | v = tvb_get_uint8(tvb, offset+ci); |
228 | 0 | dmx_data[ui] = v; |
229 | 0 | dmx_data_offset[ui] = ci; |
230 | 0 | ci++; |
231 | 0 | ui++; |
232 | 0 | } else { |
233 | 0 | dmx_data[ui] = v; |
234 | 0 | dmx_data_offset[ui] = ci; |
235 | 0 | ui++; |
236 | 0 | ci++; |
237 | 0 | } |
238 | 0 | } |
239 | 0 | dmx_data_offset[ui] = ci; |
240 | 0 | } else { |
241 | 0 | for (ui=0; ui < length;ui++) { |
242 | 0 | dmx_data[ui] = tvb_get_uint8(tvb, offset+ui); |
243 | 0 | dmx_data_offset[ui] = ui; |
244 | 0 | } |
245 | 0 | dmx_data_offset[ui] = ui; |
246 | 0 | } |
247 | | |
248 | |
|
249 | 0 | if ((type == ENTTEC_DATA_TYPE_DMX || type == ENTTEC_DATA_TYPE_RLE) && global_disp_col_count > 0) { |
250 | 0 | hi = proto_tree_add_item(tree, |
251 | 0 | hf_enttec_dmx_data_data, |
252 | 0 | tvb, |
253 | 0 | offset, |
254 | 0 | length, |
255 | 0 | ENC_NA); |
256 | |
|
257 | 0 | si = proto_item_add_subtree(hi, ett_enttec); |
258 | |
|
259 | 0 | row_count = (ui/global_disp_col_count) + ((ui%global_disp_col_count) == 0 ? 0 : 1); |
260 | 0 | dmx_epstr = wmem_strbuf_create(pinfo->pool); |
261 | 0 | for (r=0; r < row_count;r++) { |
262 | 0 | for (c=0;(c < global_disp_col_count) && (((r*global_disp_col_count)+c) < ui);c++) { |
263 | 0 | if ((global_disp_col_count > 1) && (c % (global_disp_col_count/2)) == 0) { |
264 | 0 | wmem_strbuf_append_c(dmx_epstr, ' '); |
265 | 0 | } |
266 | 0 | v = dmx_data[(r*global_disp_col_count)+c]; |
267 | 0 | if (global_disp_chan_val_type == 0) { |
268 | 0 | v = (v * 100) / 255; |
269 | 0 | if (v == 100) { |
270 | 0 | wmem_strbuf_append(dmx_epstr, "FL "); |
271 | 0 | } else { |
272 | 0 | wmem_strbuf_append_printf(dmx_epstr, chan_format[global_disp_chan_val_type], v); |
273 | 0 | } |
274 | 0 | } else { |
275 | 0 | wmem_strbuf_append_printf(dmx_epstr, chan_format[global_disp_chan_val_type], v); |
276 | 0 | } |
277 | 0 | } |
278 | |
|
279 | 0 | start_offset = dmx_data_offset[(r*global_disp_col_count)]; |
280 | 0 | end_offset = dmx_data_offset[(r*global_disp_col_count)+c]; |
281 | |
|
282 | 0 | proto_tree_add_none_format(si,hf_enttec_dmx_data_dmx_data, tvb, |
283 | 0 | offset+start_offset, |
284 | 0 | end_offset-start_offset, |
285 | 0 | string_format[global_disp_chan_nr_type], (r*global_disp_col_count)+1, |
286 | 0 | wmem_strbuf_get_str(dmx_epstr)); |
287 | 0 | wmem_strbuf_truncate(dmx_epstr, 0); |
288 | 0 | } |
289 | |
|
290 | 0 | item = proto_tree_add_item(si, hf_enttec_dmx_data_data_filter, tvb, |
291 | 0 | offset, length, ENC_NA ); |
292 | 0 | proto_item_set_hidden(item); |
293 | |
|
294 | 0 | offset += length; |
295 | 0 | } |
296 | 0 | else { |
297 | 0 | proto_tree_add_item(tree, hf_enttec_dmx_data_data_filter, tvb, |
298 | 0 | offset, length, ENC_NA); |
299 | 0 | offset += length; |
300 | 0 | } |
301 | | |
302 | | |
303 | |
|
304 | 0 | return offset; |
305 | 0 | } |
306 | | |
307 | | static int |
308 | | dissect_enttec_reset(tvbuff_t *tvb _U_, unsigned offset, proto_tree *tree _U_) |
309 | 0 | { |
310 | |
|
311 | 0 | return offset; |
312 | 0 | } |
313 | | |
314 | | static int |
315 | | dissect_enttec_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
316 | 0 | { |
317 | 0 | unsigned offset = 0; |
318 | 0 | uint32_t head = 0; |
319 | 0 | proto_tree *ti, *enttec_tree; |
320 | | |
321 | | /* |
322 | | * If not enough bytes for the header word, not an ENTTEC packet. |
323 | | */ |
324 | 0 | if (!tvb_bytes_exist(tvb, offset, 4)) |
325 | 0 | return 0; |
326 | | |
327 | 0 | head = tvb_get_ntohl(tvb, offset); |
328 | 0 | switch (head) { |
329 | | |
330 | 0 | case ENTTEC_HEAD_ESPR: |
331 | 0 | case ENTTEC_HEAD_ESPP: |
332 | 0 | case ENTTEC_HEAD_ESAP: |
333 | 0 | case ENTTEC_HEAD_ESDD: |
334 | 0 | case ENTTEC_HEAD_ESZZ: |
335 | | /* |
336 | | * Valid packet type. |
337 | | */ |
338 | 0 | break; |
339 | | |
340 | 0 | default: |
341 | | /* |
342 | | * Not a known DMX-over-UDP packet type, so probably not ENTTEC. |
343 | | */ |
344 | 0 | return 0; |
345 | 0 | } |
346 | | |
347 | | /* Set the protocol column */ |
348 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ENTTEC"); |
349 | | |
350 | | /* Clear out stuff in the info column */ |
351 | 0 | col_add_str(pinfo->cinfo, COL_INFO, |
352 | 0 | val_to_str(pinfo->pool, head, enttec_head_vals, "Unknown (0x%08x)")); |
353 | |
|
354 | 0 | ti = proto_tree_add_item(tree, proto_enttec, tvb, offset, -1, ENC_NA); |
355 | 0 | enttec_tree = proto_item_add_subtree(ti, ett_enttec); |
356 | |
|
357 | 0 | proto_tree_add_item(enttec_tree, hf_enttec_head, tvb, |
358 | 0 | offset, 4, ENC_BIG_ENDIAN ); |
359 | 0 | offset += 4; |
360 | |
|
361 | 0 | switch (head) { |
362 | 0 | case ENTTEC_HEAD_ESPR: |
363 | 0 | offset = dissect_enttec_poll_reply( tvb, offset, enttec_tree); |
364 | 0 | break; |
365 | | |
366 | 0 | case ENTTEC_HEAD_ESPP: |
367 | 0 | offset = dissect_enttec_poll( tvb, offset, enttec_tree); |
368 | 0 | break; |
369 | | |
370 | 0 | case ENTTEC_HEAD_ESAP: |
371 | 0 | offset = dissect_enttec_ack( tvb, offset, enttec_tree); |
372 | 0 | break; |
373 | | |
374 | 0 | case ENTTEC_HEAD_ESDD: |
375 | 0 | offset = dissect_enttec_dmx_data( tvb, pinfo, offset, enttec_tree); |
376 | 0 | break; |
377 | | |
378 | 0 | case ENTTEC_HEAD_ESZZ: |
379 | 0 | offset = dissect_enttec_reset( tvb, offset, enttec_tree); |
380 | 0 | break; |
381 | 0 | } |
382 | | |
383 | 0 | return offset; |
384 | 0 | } |
385 | | |
386 | | static int |
387 | | dissect_enttec_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
388 | 2 | { |
389 | 2 | unsigned offset = 0; |
390 | 2 | uint32_t head = 0; |
391 | 2 | proto_tree *ti,*enttec_tree; |
392 | | |
393 | | /* |
394 | | * If not enough bytes for the header word, don't try to |
395 | | * reassemble to get 4 bytes of header word, as we don't |
396 | | * know whether this will be an ENTTEC Config packet. |
397 | | */ |
398 | 2 | if (!tvb_bytes_exist(tvb, offset, 4)) |
399 | 1 | return 0; |
400 | | |
401 | 1 | head = tvb_get_ntohl(tvb, offset); |
402 | 1 | if (head != ENTTEC_HEAD_ESNC) { |
403 | | /* |
404 | | * Not a config packet, so probably not ENTTEC. |
405 | | */ |
406 | 1 | return 0; |
407 | 1 | } |
408 | | |
409 | | /* XXX - reassemble to end of connection? */ |
410 | | |
411 | | /* Set the protocol column */ |
412 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ENTTEC"); |
413 | | |
414 | | /* Clear out stuff in the info column */ |
415 | 0 | col_add_str(pinfo->cinfo, COL_INFO, |
416 | 0 | val_to_str(pinfo->pool, head, enttec_head_vals, "Unknown (0x%08x)")); |
417 | |
|
418 | 0 | ti = proto_tree_add_item(tree, proto_enttec, tvb, offset, -1, ENC_NA); |
419 | 0 | enttec_tree = proto_item_add_subtree(ti, ett_enttec); |
420 | |
|
421 | 0 | proto_tree_add_item(enttec_tree, hf_enttec_head, tvb, |
422 | 0 | offset, 4, ENC_BIG_ENDIAN ); |
423 | | /* XXX - dissect the rest of the packet */ |
424 | |
|
425 | 0 | return tvb_captured_length(tvb); |
426 | 1 | } |
427 | | |
428 | | void |
429 | | proto_register_enttec(void) |
430 | 16 | { |
431 | 16 | static hf_register_info hf[] = { |
432 | | /* General */ |
433 | 16 | { &hf_enttec_head, |
434 | 16 | { "Head", "enttec.head", |
435 | 16 | FT_UINT32, BASE_HEX, VALS(enttec_head_vals), 0x0, |
436 | 16 | NULL, HFILL } }, |
437 | 16 | { &hf_enttec_poll_reply_mac, |
438 | 16 | { "MAC", "enttec.poll_reply.mac", |
439 | 16 | FT_ETHER, BASE_NONE, NULL, 0x0, |
440 | 16 | NULL, HFILL } }, |
441 | 16 | { &hf_enttec_poll_reply_node_type, |
442 | 16 | { "Node Type", "enttec.poll_reply.node_type", |
443 | 16 | FT_UINT16, BASE_HEX, NULL, 0x0, |
444 | 16 | NULL, HFILL } }, |
445 | 16 | { &hf_enttec_poll_reply_version, |
446 | 16 | { "Version", "enttec.poll_reply.version", |
447 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
448 | 16 | NULL, HFILL } }, |
449 | 16 | { &hf_enttec_poll_reply_switch, |
450 | 16 | { "Switch settings", "enttec.poll_reply.switch_settings", |
451 | 16 | FT_UINT8, BASE_HEX, NULL, 0x0, |
452 | 16 | NULL, HFILL } }, |
453 | 16 | { &hf_enttec_poll_reply_name, |
454 | 16 | { "Name", "enttec.poll_reply.name", |
455 | 16 | FT_STRING, BASE_NONE, NULL, 0x0, |
456 | 16 | NULL, HFILL } }, |
457 | 16 | { &hf_enttec_poll_reply_option, |
458 | 16 | { "Option Field", "enttec.poll_reply.option_field", |
459 | 16 | FT_UINT8, BASE_HEX, NULL, 0x0, |
460 | 16 | NULL, HFILL } }, |
461 | 16 | { &hf_enttec_poll_reply_tos, |
462 | 16 | { "TOS", "enttec.poll_reply.tos", |
463 | 16 | FT_UINT8, BASE_HEX, NULL, 0x0, |
464 | 16 | NULL, HFILL } }, |
465 | 16 | { &hf_enttec_poll_reply_ttl, |
466 | 16 | { "TTL", "enttec.poll_reply.ttl", |
467 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
468 | 16 | NULL, HFILL } }, |
469 | 16 | { &hf_enttec_dmx_data_universe, |
470 | 16 | { "Universe", "enttec.dmx_data.universe", |
471 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
472 | 16 | NULL, HFILL } }, |
473 | 16 | { &hf_enttec_dmx_data_start_code, |
474 | 16 | { "Start Code", "enttec.dmx_data.start_code", |
475 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
476 | 16 | NULL, HFILL } }, |
477 | 16 | { &hf_enttec_dmx_data_type, |
478 | 16 | { "Data Type", "enttec.dmx_data.type", |
479 | 16 | FT_UINT8, BASE_HEX, VALS(enttec_data_type_vals), 0x0, |
480 | 16 | NULL, HFILL } }, |
481 | 16 | { &hf_enttec_dmx_data_size, |
482 | 16 | { "Data Size", "enttec.dmx_data.size", |
483 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
484 | 16 | NULL, HFILL } }, |
485 | 16 | { &hf_enttec_dmx_data_data, |
486 | 16 | { "DMX Data", "enttec.dmx_data.data", |
487 | 16 | FT_NONE, BASE_NONE, NULL, 0x0, |
488 | 16 | NULL, HFILL } }, |
489 | 16 | { &hf_enttec_dmx_data_data_filter, |
490 | 16 | { "DMX Data", "enttec.dmx_data.data_filter", |
491 | 16 | FT_BYTES, BASE_NONE, NULL, 0x0, |
492 | 16 | NULL, HFILL } }, |
493 | 16 | { &hf_enttec_dmx_data_dmx_data, |
494 | 16 | { "DMX Data", "enttec.dmx_data.dmx_data", |
495 | 16 | FT_NONE, BASE_NONE, NULL, 0x0, |
496 | 16 | NULL, HFILL } }, |
497 | 16 | { &hf_enttec_poll_type, |
498 | 16 | { "Reply Type", "enttec.poll.reply_type", |
499 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
500 | 16 | NULL, HFILL } } |
501 | 16 | }; |
502 | | |
503 | 16 | static int *ett[] = { |
504 | 16 | &ett_enttec, |
505 | 16 | }; |
506 | | |
507 | 16 | module_t *enttec_module; |
508 | | |
509 | 16 | static const enum_val_t disp_chan_val_types[] = { |
510 | 16 | { "pro", "Percent", 0 }, |
511 | 16 | { "hex", "Hexadecimal", 1 }, |
512 | 16 | { "dec", "Decimal", 2 }, |
513 | 16 | { NULL, NULL, 0 } |
514 | 16 | }; |
515 | | |
516 | 16 | static const enum_val_t disp_chan_nr_types[] = { |
517 | 16 | { "hex", "Hexadecimal", 0 }, |
518 | 16 | { "dec", "Decimal", 1 }, |
519 | 16 | { NULL, NULL, 0 } |
520 | 16 | }; |
521 | | |
522 | 16 | static const enum_val_t col_count[] = { |
523 | 16 | { "6", "6", 6 }, |
524 | 16 | { "10", "10", 10 }, |
525 | 16 | { "12", "12", 12 }, |
526 | 16 | { "16", "16", 16 }, |
527 | 16 | { "24", "24", 24 }, |
528 | 16 | { NULL, NULL, 0 } |
529 | 16 | }; |
530 | | |
531 | 16 | proto_enttec = proto_register_protocol("ENTTEC", "ENTTEC","enttec"); |
532 | 16 | proto_register_field_array(proto_enttec,hf,array_length(hf)); |
533 | 16 | proto_register_subtree_array(ett,array_length(ett)); |
534 | | |
535 | 16 | enttec_udp_handle = register_dissector("enttec.udp", dissect_enttec_udp,proto_enttec); |
536 | 16 | enttec_tcp_handle = register_dissector("enttec.tcp", dissect_enttec_tcp,proto_enttec); |
537 | | |
538 | 16 | enttec_module = prefs_register_protocol(proto_enttec, NULL); |
539 | | |
540 | 16 | prefs_register_enum_preference(enttec_module, "dmx_disp_chan_val_type", |
541 | 16 | "DMX Display channel value type", |
542 | 16 | "The way DMX values are displayed", |
543 | 16 | &global_disp_chan_val_type, |
544 | 16 | disp_chan_val_types, false); |
545 | | |
546 | 16 | prefs_register_enum_preference(enttec_module, "dmx_disp_chan_nr_type", |
547 | 16 | "DMX Display channel nr. type", |
548 | 16 | "The way DMX channel numbers are displayed", |
549 | 16 | &global_disp_chan_nr_type, |
550 | 16 | disp_chan_nr_types, false); |
551 | | |
552 | 16 | prefs_register_enum_preference(enttec_module, "dmx_disp_col_count", |
553 | 16 | "DMX Display Column Count", |
554 | 16 | "The number of columns for the DMX display", |
555 | 16 | &global_disp_col_count, |
556 | 16 | col_count, false); |
557 | 16 | } |
558 | | |
559 | | /* The registration hand-off routing */ |
560 | | void |
561 | 16 | proto_reg_handoff_enttec(void) { |
562 | 16 | dissector_add_uint_with_preference("tcp.port",TCP_PORT_ENTTEC,enttec_tcp_handle); |
563 | 16 | dissector_add_uint_with_preference("udp.port",UDP_PORT_ENTTEC,enttec_udp_handle); |
564 | 16 | } |
565 | | |
566 | | /* |
567 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
568 | | * |
569 | | * Local variables: |
570 | | * c-basic-offset: 8 |
571 | | * tab-width: 8 |
572 | | * indent-tabs-mode: t |
573 | | * End: |
574 | | * |
575 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
576 | | * :indentSize=8:tabSize=8:noTabs=false: |
577 | | */ |