epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-elcom.c
blob4ba2fb766cd7c4acbab3268fb0ae4a911b436e56
1 /* packet-elcom.c
2 * Routines for elcom packet dissection
3 * Copyright 2008, 2011 juha.takala@iki.fi (Juha Takala)
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Copied from packet-imap.c
11 * SPDX-License-Identifier: GPL-2.0-or-later
13 * I found the protocol specification at
14 * http://www.sintef.no/upload/Energiforskning/Energisystemer/ELCOM%2090.pdf
17 #include "config.h"
19 #include <epan/packet.h>
21 #define TCP_PORT_ELCOM 5997 /* Not IANA registered */
23 /* Application level: */
24 #define A_CONRQ 0x04
25 #define A_CONRS 0x05
27 /* Presentation level: */
28 #define P_CONRQ 0x00
29 #define P_CONRS 0x10
30 #define P_RELRQ 0x20
31 #define P_RELRS 0x30
32 #define P_DATRQ 0x80
34 #define TC_REQ 0x40
35 #define TC_RSP 0x41
37 #define LOWADR_LEN 17
38 #define SUFFIX_LEN 2
39 #define TOTAL_LEN (LOWADR_LEN + SUFFIX_LEN + 2)
41 #if 0 /* ??? */
42 #define ELCOM_UNKNOWN_ENDIAN 0
43 #define ELCOM_LITTLE_ENDIAN 1
44 #define ELCOM_BIG_ENDIAN 2
45 #endif
47 void proto_register_elcom(void);
48 void proto_reg_handoff_elcom(void);
50 static dissector_handle_t elcom_handle;
52 static int proto_elcom;
53 static int hf_elcom_response;
54 static int hf_elcom_request;
56 static int hf_elcom_length;
57 static int hf_elcom_type;
59 static int hf_elcom_initiator;
60 static int hf_elcom_initiator_endian;
61 static int hf_elcom_initiator_ip;
62 static int hf_elcom_initiator_port;
63 static int hf_elcom_initiator_suff;
65 static int hf_elcom_responder;
66 static int hf_elcom_responder_endian;
67 static int hf_elcom_responder_ip;
68 static int hf_elcom_responder_port;
69 static int hf_elcom_responder_suff;
71 static int hf_elcom_userdata;
72 static int hf_elcom_userdata_length;
73 static int hf_elcom_userdata_pduid;
74 static int hf_elcom_userdata_version;
75 static int hf_elcom_userdata_result;
76 static int hf_elcom_userdata_restmark;
77 static int hf_elcom_userdata_cf;
79 static int hf_elcom_datarequest;
80 static int hf_elcom_datarequest_grouptype;
81 static int hf_elcom_datarequest_result;
82 static int hf_elcom_datarequest_groupnumber;
83 static int hf_elcom_datarequest_grouppriority;
84 static int hf_elcom_datarequest_groupsize;
85 static int hf_elcom_datarequest_groupindex1;
86 static int hf_elcom_datarequest_groupindex2;
87 static int hf_elcom_datarequest_oid;
89 static int hf_elcom_release_reason;
90 static int hf_elcom_release_result;
92 static int hf_elcom_strangeleftover;
94 static int ett_elcom;
95 static int ett_elcom_initiator;
96 static int ett_elcom_responder;
97 static int ett_elcom_userdata;
98 static int ett_elcom_datarequest;
100 static bool elcom_show_hex = true;
102 static const value_string endian_vals[] = {
103 {0x0002, "Big"},
104 {0x0200, "Little"},
105 {0, NULL }
108 static const value_string suffix_vals[] = {
109 {'A', "Control"},
110 {'B', "Unsolicited"},
111 {'C', "Periodic"},
112 {'D', "Requested, scheduling"},
113 {'E', "Requested, present/archived"},
114 {'G', "Supervisory"},
115 {'F', "Test"},
116 {0, NULL }
119 static const value_string userdata_pduid_vals[] = {
120 {0x04, "Connect Request"},
121 {0x05, "Connect Response"},
122 {0, NULL }
125 static const value_string userdata_version_vals[] = {
126 {0x00, "Class 0, v0"},
127 {0x01, "Class 1, v0"},
128 {0x02, "Class 2, v0"},
129 {0x12, "Class 2, v1"},
130 {0x13, "Class 3, v1"},
131 {0, NULL }
134 static const value_string userdata_result_vals[] = {
135 {0x00, "OK"},
136 {0, NULL }
139 static const value_string datarequest_grouptype_vals[] = {
140 {TC_REQ, "Test Connection Request"},
141 {TC_RSP, "Test Connection Response"},
142 {0, NULL }
145 static const value_string datarequest_result_vals[] = {
146 {0x00, "OK"},
147 {0, NULL }
150 static const value_string type_vals[] = {
151 {P_CONRQ, "Connect Request"},
152 {P_CONRS, "Connect Response"},
153 {P_RELRQ, "Release Request"},
154 {P_RELRS, "Release Response"},
155 {P_DATRQ, "Data Request"},
156 {0, NULL }
159 static int
160 dissect_lower_address(wmem_allocator_t *scope, proto_item *ti_arg, int ett_arg,
161 tvbuff_t *tvb, int arg_offset,
162 int hf_endian, int hf_ip, int hf_port, int hf_suff)
164 int offset = arg_offset;
165 uint8_t len1, len2;
166 uint8_t *suffix;
167 proto_tree *tree;
168 proto_item *ti;
170 tree = proto_item_add_subtree(ti_arg, ett_arg);
173 * Coding of address:
174 * ELCOM-90 TRA3825.02 User Element conventions, p. 5-2 and Appendix G
176 len1 = tvb_get_uint8(tvb, offset);
177 if (tvb_captured_length_remaining(tvb, offset+len1+1) <= 0)
178 return offset;
179 len2 = tvb_get_uint8(tvb, offset+len1+1);
180 if (tvb_reported_length_remaining(tvb, offset+len1+len2+2) <= 0)
181 return offset;
182 if ((len1 != LOWADR_LEN) || (len2 != SUFFIX_LEN)) {
183 proto_item_append_text(tree, " Invalid structure");
184 return offset;
188 /* Show pre stuff */
189 if (0x82 != tvb_get_uint8(tvb, offset+1)) {
190 proto_item_append_text(tree, " Not IPV4 address");
191 return offset;
193 offset += 2;
196 /* endian */
197 proto_tree_add_item(tree, hf_endian, tvb, offset, 2, ENC_BIG_ENDIAN);
198 offset += 2;
200 /* port */
201 proto_tree_add_item(tree, hf_port, tvb, offset, 2, ENC_BIG_ENDIAN);
202 offset += 2;
204 /* ip-addr */
205 proto_tree_add_item(tree, hf_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
206 offset += 4;
208 offset += 8; /* skip the zero bytes */
210 /* SUFFIX */
211 suffix = tvb_get_string_enc(scope, tvb, offset+1, len2, ENC_ASCII);
212 /* hf_suff FIELDTYPE must be FT_UINT_STRING */
213 ti = proto_tree_add_item(tree, hf_suff, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
214 offset += len2+1;
216 if (!(suffix[0] == 'A' || suffix[0] == 'B')) {
217 proto_item_append_text(ti, " (invalid)");
218 return offset;
221 proto_item_append_text(ti, " (%s)", val_to_str_const(suffix[1], suffix_vals, "<<-- WHAT?") );
222 return offset;
225 static int
226 dissect_userdata(proto_item *ti_arg, int ett_arg, tvbuff_t *tvb, int arg_offset)
228 int offset = arg_offset;
229 uint8_t flen, lenbytes;
230 uint8_t year, month, day, hour, min, sec;
231 uint16_t msec;
232 proto_tree *tree;
233 proto_item *ti;
235 tree = proto_item_add_subtree(ti_arg, ett_arg);
237 /* length of User Data, should be 1 byte field ... */
238 flen = tvb_get_uint8(tvb, offset);
239 lenbytes = 1;
241 /* ... but sometimes it seems to be 2 bytes; try to be clever */
242 if (flen == 0) {
243 flen = tvb_get_uint8(tvb, offset+1);
244 lenbytes = 2;
246 if (flen == 0 || flen > 79) /* invalid */
247 return offset;
249 ti = proto_tree_add_item(tree, hf_elcom_userdata_length, tvb, offset, lenbytes, ENC_BIG_ENDIAN);
250 offset += lenbytes;
251 if (lenbytes == 2) {
252 proto_item_append_text(ti, " (2 bytes, should be 1 byte)");
255 if (tvb_reported_length_remaining(tvb, offset) <= 0)
256 return offset;
258 proto_tree_add_item(tree, hf_elcom_userdata_pduid, tvb, offset, 1, ENC_BIG_ENDIAN);
259 offset++;
261 if (tvb_reported_length_remaining(tvb, offset) <= 0)
262 return offset;
264 proto_tree_add_item(tree, hf_elcom_userdata_version, tvb, offset, 1, ENC_BIG_ENDIAN);
265 offset++;
268 if (tvb_reported_length_remaining(tvb, offset) <= 0)
269 return offset;
271 proto_tree_add_item(tree, hf_elcom_userdata_result, tvb, offset, 1, ENC_BIG_ENDIAN);
272 offset++;
274 /* show the rest */
275 /* tree2 = proto_tree_add_subtree(tree, tvb, offset, -1, "User Data"); */
277 if (tvb_reported_length_remaining(tvb, offset) <= 0)
278 return offset;
279 ti = proto_tree_add_item(tree, hf_elcom_userdata_restmark, tvb, offset, 1, ENC_BIG_ENDIAN);
280 proto_item_append_text(ti, " <-- '0' = no restart etc.");
281 offset +=1;
283 if (tvb_reported_length_remaining(tvb, offset+8) <= 0)
284 return offset;
285 year = tvb_get_uint8(tvb, offset);
286 month = tvb_get_uint8(tvb, offset+1);
287 day = tvb_get_uint8(tvb, offset+2);
288 hour = tvb_get_uint8(tvb, offset+3);
289 min = tvb_get_uint8(tvb, offset+4);
290 sec = tvb_get_uint8(tvb, offset+5);
291 msec = tvb_get_ntohs(tvb, offset+6);
293 proto_tree_add_none_format(tree, hf_elcom_userdata_cf, tvb, offset, 8,
294 "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d",
295 year+1900, month, day, hour, min, sec, msec);
297 offset += 12;
298 if (tvb_reported_length_remaining(tvb, offset+12) > 0) {
299 proto_item_append_text(ti, " Security info: ");
301 /* security info field, if present */
302 while (tvb_reported_length_remaining(tvb, offset) > 0) {
303 proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o",
304 tvb_get_uint8(tvb, offset));
305 offset++;
308 return offset;
311 static int
312 dissect_datarequest(proto_item *ti_arg, int ett_arg, tvbuff_t *tvb, int arg_offset)
314 int offset = arg_offset;
315 uint8_t gtype, oidlen;
316 proto_tree *tree;
317 proto_item *ti;
319 tree = proto_item_add_subtree(ti_arg, ett_arg);
320 if (tvb_reported_length_remaining(tvb, offset) <= 0)
321 return offset;
323 gtype = tvb_get_uint8(tvb, offset);
324 ti = proto_tree_add_item(tree, hf_elcom_datarequest_grouptype,
325 tvb, offset, 1, ENC_BIG_ENDIAN);
326 offset += 1;
328 switch (gtype) {
330 case TC_REQ:
331 /* No more data for this type, suppress the error message */
332 break;
334 case TC_RSP:
336 proto_tree_add_item(tree, hf_elcom_datarequest_result,
337 tvb, offset, 1, ENC_BIG_ENDIAN);
338 offset++;
340 break;
342 default:
343 proto_item_append_text(ti, " <<--- meaning WHAT?");
344 return offset;
346 if (tvb_reported_length_remaining(tvb, offset) <= 0)
347 return offset;
349 proto_tree_add_item(tree, hf_elcom_datarequest_groupnumber, tvb, offset, 1, ENC_BIG_ENDIAN);
350 offset += 1;
351 if (tvb_reported_length_remaining(tvb, offset) <= 0)
352 return offset;
354 proto_tree_add_item(tree, hf_elcom_datarequest_grouppriority, tvb, offset, 1, ENC_BIG_ENDIAN);
355 offset += 1;
356 if (tvb_reported_length_remaining(tvb, offset) <= 0)
357 return offset;
359 proto_tree_add_item(tree, hf_elcom_datarequest_groupsize, tvb, offset, 1, ENC_BIG_ENDIAN);
360 offset += 1;
361 if (tvb_reported_length_remaining(tvb, offset) <= 0)
362 return offset;
364 proto_tree_add_item(tree, hf_elcom_datarequest_groupindex1, tvb, offset, 2, ENC_BIG_ENDIAN);
365 offset += 2;
366 if (tvb_reported_length_remaining(tvb, offset) <= 0)
367 return offset;
369 proto_tree_add_item(tree, hf_elcom_datarequest_groupindex2, tvb, offset, 2, ENC_BIG_ENDIAN);
370 offset += 2;
371 if (tvb_reported_length_remaining(tvb, offset) <= 0)
372 return offset;
374 while (1) {
375 oidlen = tvb_get_uint8(tvb, offset);
376 if (oidlen == 0) /* normal termination */
377 break;
378 if (tvb_reported_length_remaining(tvb, offset+oidlen+1) <= 0)
379 return offset;
380 proto_tree_add_item(tree, hf_elcom_datarequest_oid, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
381 offset += oidlen+1;
383 offset += 1; /* the loop exited at the 0 length byte */
384 if (tvb_reported_length_remaining(tvb, offset) <= 0)
385 return offset;
387 /* show the rest */
388 proto_tree_add_item(tree, hf_elcom_strangeleftover, tvb, offset, -1, ENC_NA);
389 return offset;
392 /* XXX: Are all the tests against tvb_reported_length() really the right way to handle invalid fields ?
393 * It seems to me that invalid fields should just add an expert item
394 * or cause a "Malformed" exception.
396 static int
397 dissect_elcom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
399 bool is_request, length_ok;
400 proto_tree *elcom_tree;
401 proto_item *ti, *hidden_item;
402 int offset = 0;
403 unsigned elcom_len;
404 uint8_t elcom_msg_type;
405 uint8_t *suffix;
407 /* Check that there's enough data */
408 if (tvb_captured_length(tvb) < 3)
409 return 0;
411 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ELCOM");
412 col_clear(pinfo->cinfo, COL_INFO);
414 is_request = (pinfo->match_uint == pinfo->destport);
415 elcom_len = tvb_get_ntohs(tvb, 0);
416 length_ok = (tvb_reported_length(tvb) == (elcom_len+2));
418 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Len=%d%s",
419 is_request ? "Request" : "Response",
420 elcom_len,
421 length_ok ? "" : " (incorrect)");
423 elcom_msg_type = tvb_get_uint8(tvb, 2);
424 switch (elcom_msg_type) {
425 case P_CONRQ:
426 case P_CONRS:
428 /* starting after elcom_len and elcom_msg_type,
429 initiator + responder + userdata fields must be there */
430 if (tvb_captured_length_remaining(tvb, 3+TOTAL_LEN+TOTAL_LEN+3) < 0) return 2;
431 /* check also that those field lengths are valid */
432 if (tvb_get_uint8(tvb, 3) != LOWADR_LEN) return 2;
433 if (tvb_get_uint8(tvb, 3+1+LOWADR_LEN) != SUFFIX_LEN) return 2;
434 if (tvb_get_uint8(tvb, 3+TOTAL_LEN) != LOWADR_LEN) return 2;
435 if (tvb_get_uint8(tvb, 3+1+TOTAL_LEN+LOWADR_LEN) != SUFFIX_LEN) return 2;
437 /* finally believe that there is valid suffix */
438 suffix = tvb_get_string_enc(pinfo->pool, tvb, 3+2+LOWADR_LEN, 2, ENC_ASCII);
439 col_append_fstr(pinfo->cinfo, COL_INFO, " %s Connect", suffix);
440 break;
442 case P_RELRQ:
443 case P_RELRS:
444 col_append_str(pinfo->cinfo, COL_INFO, " Release");
445 break;
447 case P_DATRQ:
448 col_append_str(pinfo->cinfo, COL_INFO, " Data");
449 break;
452 switch (elcom_msg_type) {
453 case P_CONRQ:
454 case P_RELRQ:
455 col_append_str(pinfo->cinfo, COL_INFO, " Request");
456 break;
458 case P_CONRS:
459 case P_RELRS:
460 col_append_str(pinfo->cinfo, COL_INFO, " Response");
461 break;
464 if (!tree)
465 return tvb_captured_length(tvb);
467 ti = proto_tree_add_item(tree, proto_elcom, tvb, offset, -1, ENC_NA);
468 elcom_tree = proto_item_add_subtree(ti, ett_elcom);
470 hidden_item = proto_tree_add_boolean(elcom_tree,
471 is_request ? hf_elcom_request : hf_elcom_response,
472 tvb, 0, 0, true);
473 proto_item_set_hidden(hidden_item);
475 /* 2 first bytes are the frame length */
476 offset = 0;
477 ti = proto_tree_add_item(elcom_tree, hf_elcom_length, tvb, offset, 2, ENC_BIG_ENDIAN);
478 offset = +2;
479 if (! length_ok) {
480 proto_item_append_text(ti, " (incorrect)");
483 elcom_msg_type = tvb_get_uint8(tvb, offset);
484 ti = proto_tree_add_item(elcom_tree, hf_elcom_type, tvb, offset, 1, ENC_BIG_ENDIAN);
485 proto_item_append_text(elcom_tree, " ( %s)", val_to_str(elcom_msg_type, type_vals, "Unknown %d"));
487 offset++;
488 if (tvb_reported_length_remaining(tvb, offset) <= 0)
489 return offset;
491 switch (elcom_msg_type) {
492 case P_CONRQ:
493 case P_CONRS:
495 * Connection request/release assiciated PDU's,
496 * /ELCOM-90 P Protocol spec/ p. 85...
499 /* We need the length here, hardcode the LOWADR_LEN = 21 */
500 ti = proto_tree_add_item(elcom_tree, hf_elcom_initiator, tvb, offset, TOTAL_LEN, ENC_NA);
501 offset = dissect_lower_address(pinfo->pool, ti, ett_elcom_initiator, tvb, offset,
502 hf_elcom_initiator_endian,
503 hf_elcom_initiator_ip,
504 hf_elcom_initiator_port,
505 hf_elcom_initiator_suff);
506 if (tvb_reported_length_remaining(tvb, offset) <= 0)
507 return offset;
509 ti = proto_tree_add_item(elcom_tree, hf_elcom_responder, tvb, offset, TOTAL_LEN, ENC_NA);
510 offset = dissect_lower_address(pinfo->pool, ti, ett_elcom_responder, tvb, offset,
511 hf_elcom_responder_endian,
512 hf_elcom_responder_ip,
513 hf_elcom_responder_port,
514 hf_elcom_responder_suff);
515 if (tvb_reported_length_remaining(tvb, offset) <= 0)
516 return offset;
518 /* Rest of the payload is USER-DATA, 0..82 bytes */
519 ti = proto_tree_add_item(elcom_tree, hf_elcom_userdata, tvb, offset, -1, ENC_NA);
520 offset = dissect_userdata(ti, ett_elcom_userdata, tvb, offset);
522 break;
524 case P_RELRQ:
526 proto_tree_add_item(elcom_tree, hf_elcom_release_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
527 offset += 1;
529 break;
530 case P_RELRS:
532 proto_tree_add_item(elcom_tree, hf_elcom_release_result, tvb, offset, 1, ENC_BIG_ENDIAN);
534 offset += 1;
536 break;
538 case P_DATRQ:
539 ti = proto_tree_add_item(elcom_tree, hf_elcom_datarequest, tvb, offset, -1, ENC_NA);
540 offset = dissect_datarequest(ti, ett_elcom_datarequest, tvb, offset);
541 break;
543 default:
544 proto_item_append_text(ti, " <<--- meaning WHAT??");
545 break;
548 if (tvb_reported_length_remaining(tvb, offset) > 0)
550 /* We should not get here, but if we do, show what is left over: */
551 proto_tree_add_item(elcom_tree, hf_elcom_strangeleftover, tvb, offset, -1, ENC_NA);
553 return tvb_captured_length(tvb);
556 void
557 proto_register_elcom(void)
559 /* Setup list of header fields See Section 1.6.1 for details*/
560 static hf_register_info hf[] = {
561 { &hf_elcom_response,
562 { "Response", "elcom.response",
563 FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }
566 { &hf_elcom_request,
567 { "Request", "elcom.request",
568 FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }
571 { &hf_elcom_length,
572 { "Length", "elcom.length",
573 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
576 { &hf_elcom_type,
577 { "Type", "elcom.type",
578 FT_UINT8, BASE_HEX, VALS(type_vals), 0, NULL, HFILL }
581 { &hf_elcom_initiator,
582 { "Initiator", "elcom.initiator",
583 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
586 { &hf_elcom_initiator_endian,
587 { "Endian", "elcom.initiator.endian",
588 FT_UINT16, BASE_HEX, VALS(endian_vals), 0, NULL, HFILL }
591 { &hf_elcom_initiator_ip,
592 { "IP", "elcom.initiator.ip",
593 FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
596 { &hf_elcom_initiator_port,
597 { "Port", "elcom.initiator.port",
598 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
601 { &hf_elcom_initiator_suff,
602 { "Suffix", "elcom.initiator.suffix",
603 FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
606 { &hf_elcom_responder,
607 { "Responder", "elcom.responder",
608 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
611 { &hf_elcom_responder_endian,
612 { "Endian", "elcom.responder.endian",
613 FT_UINT16, BASE_HEX, VALS(endian_vals), 0, NULL, HFILL }
616 { &hf_elcom_responder_ip,
617 { "IP", "elcom.responder.ip",
618 FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
621 { &hf_elcom_responder_port,
622 { "Port", "elcom.responder.port",
623 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
626 { &hf_elcom_responder_suff,
627 { "Suffix", "elcom.responder.suffix",
628 FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
631 { &hf_elcom_userdata,
632 { "User Data", "elcom.userdata",
633 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
636 { &hf_elcom_userdata_length,
637 { "Length", "elcom.userdata.length",
638 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
641 { &hf_elcom_userdata_pduid,
642 { "PDU-ID", "elcom.userdata.pduid",
643 FT_UINT8, BASE_DEC, VALS(userdata_pduid_vals), 0, NULL, HFILL }
646 { &hf_elcom_userdata_version,
647 { "Version", "elcom.userdata.version",
648 FT_UINT8, BASE_DEC, VALS(userdata_version_vals), 0, NULL, HFILL }
651 { &hf_elcom_userdata_result,
652 { "Result", "elcom.userdata.result",
653 FT_UINT8, BASE_DEC, VALS(userdata_result_vals), 0, NULL, HFILL }
656 { &hf_elcom_userdata_restmark,
657 { "Restart marking", "elcom.userdata.response.restartcode",
658 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
661 { &hf_elcom_userdata_cf,
662 { "Control Field", "elcom.userdata.response.controlfield",
663 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
666 { &hf_elcom_release_reason,
667 { "Reason", "elcom.release.reason",
668 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
671 { &hf_elcom_release_result,
672 { "Result", "elcom.release.result",
673 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
676 { &hf_elcom_datarequest,
677 { "Data Request", "elcom.datarequest",
678 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
681 { &hf_elcom_datarequest_grouptype,
682 { "Group Type", "elcom.datarequest.grouptype",
683 FT_UINT8, BASE_DEC, VALS(datarequest_grouptype_vals), 0, NULL, HFILL }
686 { &hf_elcom_datarequest_result,
687 { "Result", "elcom.datarequest.result",
688 FT_UINT8, BASE_DEC, VALS(datarequest_result_vals), 0, NULL, HFILL }
691 { &hf_elcom_datarequest_groupnumber,
692 { "Group Number", "elcom.datarequest.groupnumber",
693 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
696 { &hf_elcom_datarequest_grouppriority,
697 { "Group Priority", "elcom.datarequest.grouppriority",
698 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
701 { &hf_elcom_datarequest_groupsize,
702 { "Group Size", "elcom.datarequest.groupsize",
703 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
706 { &hf_elcom_datarequest_groupindex1,
707 { "Group Index1", "elcom.datarequest.groupindex1",
708 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
711 { &hf_elcom_datarequest_groupindex2,
712 { "Group Index2", "elcom.datarequest.groupindex2",
713 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
716 { &hf_elcom_datarequest_oid,
717 { "Object Name", "elcom.datarequest.oid",
718 FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
720 { &hf_elcom_strangeleftover,
721 { "Strange Leftover", "elcom.leftover",
722 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
726 /* Setup protocol subtree array */
727 static int *ett[] = {
728 &ett_elcom,
729 &ett_elcom_initiator,
730 &ett_elcom_responder,
731 &ett_elcom_userdata,
732 &ett_elcom_datarequest
735 /* Register the protocol name and description */
736 proto_elcom = proto_register_protocol (
737 "ELCOM Communication Protocol",
738 "ELCOM",
739 "elcom"
742 /* Required function calls to register the header fields and subtrees used */
743 proto_register_field_array(proto_elcom, hf, array_length(hf));
744 proto_register_subtree_array(ett, array_length(ett));
746 elcom_handle = register_dissector("elcom", dissect_elcom, proto_elcom);
749 void
750 proto_reg_handoff_elcom(void)
752 dissector_add_uint_with_preference("tcp.port", TCP_PORT_ELCOM, elcom_handle);
756 * Editor modelines
758 * Local Variables:
759 * c-basic-offset: 8
760 * tab-width: 8
761 * indent-tabs-mode: nil
762 * End:
764 * ex: set shiftwidth=8 tabstop=8 expandtab:
765 * :indentSize=8:tabSize=8:noTabs=true: