2 * Routines for elcom packet dissection
3 * Copyright 2008, 2011 juha.takala@iki.fi (Juha Takala)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-imap.c
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * I found the protocol specification at
28 * http://www.sintef.no/upload/Energiforskning/Energisystemer/ELCOM%2090.pdf
33 #include <epan/packet.h>
35 #define TCP_PORT_ELCOM 5997
37 /* Application level: */
41 /* Presentation level: */
53 #define TOTAL_LEN (LOWADR_LEN + SUFFIX_LEN + 2)
55 #define ELCOM_UNKNOWN_ENDIAN 0
56 #define ELCOM_LITTLE_ENDIAN 1
57 #define ELCOM_BIG_ENDIAN 2
59 void proto_register_elcom(void);
60 void proto_reg_handoff_elcom(void);
62 static int proto_elcom
= -1;
63 static int hf_elcom_response
= -1;
64 static int hf_elcom_request
= -1;
66 static int hf_elcom_length
= -1;
67 static int hf_elcom_type
= -1;
69 static int hf_elcom_initiator
= -1;
70 static int hf_elcom_initiator_endian
= -1;
71 static int hf_elcom_initiator_ip
= -1;
72 static int hf_elcom_initiator_port
= -1;
73 static int hf_elcom_initiator_suff
= -1;
75 static int hf_elcom_responder
= -1;
76 static int hf_elcom_responder_endian
= -1;
77 static int hf_elcom_responder_ip
= -1;
78 static int hf_elcom_responder_port
= -1;
79 static int hf_elcom_responder_suff
= -1;
81 static int hf_elcom_userdata
= -1;
82 static int hf_elcom_userdata_length
= -1;
83 static int hf_elcom_userdata_pduid
= -1;
84 static int hf_elcom_userdata_version
= -1;
85 static int hf_elcom_userdata_result
= -1;
86 static int hf_elcom_userdata_restmark
= -1;
87 static int hf_elcom_userdata_cf
= -1;
89 static int hf_elcom_datarequest
= -1;
90 static int hf_elcom_datarequest_grouptype
= -1;
91 static int hf_elcom_datarequest_result
= -1;
92 static int hf_elcom_datarequest_groupnumber
= -1;
93 static int hf_elcom_datarequest_grouppriority
= -1;
94 static int hf_elcom_datarequest_groupsize
= -1;
95 static int hf_elcom_datarequest_groupindex1
= -1;
96 static int hf_elcom_datarequest_groupindex2
= -1;
97 static int hf_elcom_datarequest_oid
= -1;
99 static int hf_elcom_release_reason
= -1;
100 static int hf_elcom_release_result
= -1;
102 static int hf_elcom_strangeleftover
= -1;
104 static gint ett_elcom
= -1;
105 static gint ett_elcom_initiator
= -1;
106 static gint ett_elcom_responder
= -1;
107 static gint ett_elcom_userdata
= -1;
108 static gint ett_elcom_datarequest
= -1;
110 static gboolean elcom_show_hex
= TRUE
;
112 static const value_string endian_vals
[] = {
118 static const value_string suffix_vals
[] = {
120 {'B', "Unsolicited"},
122 {'D', "Requested, scheduling"},
123 {'E', "Requested, present/archived"},
124 {'G', "Supervisory"},
129 static const value_string userdata_pduid_vals
[] = {
130 {0x04, "Connect Request"},
131 {0x05, "Connect Response"},
135 static const value_string userdata_version_vals
[] = {
136 {0x00, "Class 0, v0"},
137 {0x01, "Class 1, v0"},
138 {0x02, "Class 2, v0"},
139 {0x12, "Class 2, v1"},
140 {0x13, "Class 3, v1"},
144 static const value_string userdata_result_vals
[] = {
149 static const value_string datarequest_grouptype_vals
[] = {
150 {TC_REQ
, "Test Connection Request"},
151 {TC_RSP
, "Test Connection Response"},
155 static const value_string datarequest_result_vals
[] = {
160 static const value_string type_vals
[] = {
161 {P_CONRQ
, "Connect Request"},
162 {P_CONRS
, "Connect Response"},
163 {P_RELRQ
, "Release Request"},
164 {P_RELRS
, "Release Response"},
165 {P_DATRQ
, "Data Request"},
170 dissect_lower_address(proto_item
*ti_arg
, gint ett_arg
,
171 tvbuff_t
*tvb
, gint arg_offset
,
172 int hf_endian
, int hf_ip
, int hf_port
, int hf_suff
)
174 gint offset
= arg_offset
;
180 tree
= proto_item_add_subtree(ti_arg
, ett_arg
);
184 * ELCOM-90 TRA3825.02 User Element conventions, p. 5-2 and Appendix G
186 len1
= tvb_get_guint8(tvb
, offset
);
187 if (tvb_length_remaining(tvb
, offset
+len1
+1) <= 0)
189 len2
= tvb_get_guint8(tvb
, offset
+len1
+1);
190 if (tvb_length_remaining(tvb
, offset
+len1
+len2
+2) <= 0)
192 if ((len1
!= LOWADR_LEN
) || (len2
!= SUFFIX_LEN
)) {
193 proto_item_append_text(tree
, " Invalid structure");
199 if (0x82 != tvb_get_guint8(tvb
, offset
+1)) {
200 proto_item_append_text(tree
, " Not IPV4 address");
207 proto_tree_add_item(tree
, hf_endian
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
211 proto_tree_add_item(tree
, hf_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
215 proto_tree_add_item(tree
, hf_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
218 offset
+= 8; /* skip the zero bytes */
221 suffix
= tvb_get_string(wmem_packet_scope(), tvb
, offset
+1, len2
);
222 ti
= proto_tree_add_item(tree
, hf_suff
, tvb
, offset
, 1, ENC_ASCII
|ENC_LITTLE_ENDIAN
);
225 if (!(suffix
[0] == 'A' || suffix
[0] == 'B')) {
226 proto_item_append_text(ti
, " (invalid)");
230 proto_item_append_text(ti
, " (%s)", val_to_str_const(suffix
[1], suffix_vals
, "<<-- WHAT?") );
235 dissect_userdata(proto_item
*ti_arg
, gint ett_arg
, tvbuff_t
*tvb
, gint arg_offset
)
237 gint offset
= arg_offset
;
238 guint8 flen
, lenbytes
;
239 guint8 year
, month
, day
, hour
, min
, sec
;
244 tree
= proto_item_add_subtree(ti_arg
, ett_arg
);
246 /* length of User Data, should be 1 byte field ... */
247 flen
= tvb_get_guint8(tvb
, offset
);
250 /* ... but sometimes it seems to be 2 bytes; try to be clever */
252 flen
= tvb_get_guint8(tvb
, offset
+1);
255 if (flen
== 0 || flen
> 79) /* invalid */
258 ti
= proto_tree_add_item(tree
, hf_elcom_userdata_length
, tvb
, offset
, lenbytes
, ENC_BIG_ENDIAN
);
261 proto_item_append_text(ti
, " (2 bytes, should be 1 byte)");
264 if (tvb_length_remaining(tvb
, offset
) <= 0)
267 proto_tree_add_item(tree
, hf_elcom_userdata_pduid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
270 if (tvb_length_remaining(tvb
, offset
) <= 0)
273 proto_tree_add_item(tree
, hf_elcom_userdata_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
277 if (tvb_length_remaining(tvb
, offset
) <= 0)
280 proto_tree_add_item(tree
, hf_elcom_userdata_result
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
284 /* tree2 = proto_tree_add_text(tree, tvb, offset, -1, "User Data"); */
286 if (tvb_length_remaining(tvb
, offset
) <= 0)
288 ti
= proto_tree_add_item(tree
, hf_elcom_userdata_restmark
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
289 proto_item_append_text(ti
, " <-- '0' = no restart etc.");
292 if (tvb_length_remaining(tvb
, offset
+8) <= 0)
294 year
= tvb_get_guint8(tvb
, offset
);
295 month
= tvb_get_guint8(tvb
, offset
+1);
296 day
= tvb_get_guint8(tvb
, offset
+2);
297 hour
= tvb_get_guint8(tvb
, offset
+3);
298 min
= tvb_get_guint8(tvb
, offset
+4);
299 sec
= tvb_get_guint8(tvb
, offset
+5);
300 msec
= tvb_get_ntohs(tvb
, offset
+6);
302 proto_tree_add_none_format(tree
, hf_elcom_userdata_cf
, tvb
, offset
, 8,
303 "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d",
304 year
+1900, month
, day
, hour
, min
, sec
, msec
);
307 if (tvb_length_remaining(tvb
, offset
+12) > 0) {
308 proto_item_append_text(ti
, " Security info: ");
310 /* security info field, if present */
311 while (tvb_length_remaining(tvb
, offset
) > 0) {
312 proto_item_append_text(ti
, elcom_show_hex
? " %02x" : " %03o",
313 tvb_get_guint8(tvb
, offset
));
321 dissect_datarequest(proto_item
*ti_arg
, gint ett_arg
, tvbuff_t
*tvb
, gint arg_offset
)
323 gint offset
= arg_offset
;
324 guint8 gtype
, oidlen
;
325 proto_tree
*tree
, *tree2
;
328 tree
= proto_item_add_subtree(ti_arg
, ett_arg
);
329 if (tvb_length_remaining(tvb
, offset
) <= 0)
332 gtype
= tvb_get_guint8(tvb
, offset
);
333 ti
= proto_tree_add_item(tree
, hf_elcom_datarequest_grouptype
,
334 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
340 /* No more data for this type, suppress the error message */
345 proto_tree_add_item(tree
, hf_elcom_datarequest_result
,
346 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
352 proto_item_append_text(ti
, " <<--- meaning WHAT?");
355 if (tvb_length_remaining(tvb
, offset
) <= 0)
358 proto_tree_add_item(tree
, hf_elcom_datarequest_groupnumber
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
360 if (tvb_length_remaining(tvb
, offset
) <= 0)
363 proto_tree_add_item(tree
, hf_elcom_datarequest_grouppriority
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
365 if (tvb_length_remaining(tvb
, offset
) <= 0)
368 proto_tree_add_item(tree
, hf_elcom_datarequest_groupsize
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
370 if (tvb_length_remaining(tvb
, offset
) <= 0)
373 proto_tree_add_item(tree
, hf_elcom_datarequest_groupindex1
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
375 if (tvb_length_remaining(tvb
, offset
) <= 0)
378 proto_tree_add_item(tree
, hf_elcom_datarequest_groupindex2
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
380 if (tvb_length_remaining(tvb
, offset
) <= 0)
384 oidlen
= tvb_get_guint8(tvb
, offset
);
385 if (oidlen
== 0) /* normal termination */
387 if (tvb_length_remaining(tvb
, offset
+oidlen
+1) <= 0)
389 proto_tree_add_item(tree
, hf_elcom_datarequest_oid
, tvb
, offset
, 1, ENC_ASCII
|ENC_NA
);
392 offset
+= 1; /* the loop exited at the 0 length byte */
393 if (tvb_length_remaining(tvb
, offset
) <= 0)
397 tree2
= proto_tree_add_text(tree
, tvb
, offset
, -1, "leftover =");
398 while (tvb_length_remaining(tvb
, offset
) > 0) {
399 proto_item_append_text(tree2
, elcom_show_hex
? " %02x" : " %03o",
400 tvb_get_guint8(tvb
, offset
));
407 /* XXX: Are all the tests against tvb_length() really the right way to handle invalid fields ?
408 * It seems to me that invalid fields should just add an expert item
409 * or cause a "Malformed" exception.
412 dissect_elcom(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
414 gboolean is_request
, length_ok
;
415 proto_tree
*elcom_tree
;
416 proto_item
*ti
, *hidden_item
;
419 guint8 elcom_msg_type
;
422 /* Check that there's enough data */
423 if (tvb_length(tvb
) < 3)
426 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ELCOM");
427 col_clear(pinfo
->cinfo
, COL_INFO
);
429 is_request
= (pinfo
->match_uint
== pinfo
->destport
);
430 elcom_len
= tvb_get_ntohs(tvb
, 0);
431 length_ok
= (tvb_reported_length(tvb
) == (elcom_len
+2));
433 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s Len=%d%s",
434 is_request
? "Request" : "Response",
436 length_ok
? "" : " (incorrect)");
438 elcom_msg_type
= tvb_get_guint8(tvb
, 2);
439 switch (elcom_msg_type
) {
443 /* starting after elcom_len and elcom_msg_type,
444 initiator + responder + userdata fields must be there */
445 if (tvb_length_remaining(tvb
, 3+TOTAL_LEN
+TOTAL_LEN
+3) < 0) return;
446 /* check also that those field lengths are valid */
447 if (tvb_get_guint8(tvb
, 3) != LOWADR_LEN
) return;
448 if (tvb_get_guint8(tvb
, 3+1+LOWADR_LEN
) != SUFFIX_LEN
) return;
449 if (tvb_get_guint8(tvb
, 3+TOTAL_LEN
) != LOWADR_LEN
) return;
450 if (tvb_get_guint8(tvb
, 3+1+TOTAL_LEN
+LOWADR_LEN
) != SUFFIX_LEN
) return;
452 /* finally believe that there is valid suffix */
453 suffix
= tvb_get_string(wmem_packet_scope(), tvb
, 3+2+LOWADR_LEN
, 2);
454 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s Connect", suffix
);
459 col_append_str(pinfo
->cinfo
, COL_INFO
, " Release");
463 col_append_str(pinfo
->cinfo
, COL_INFO
, " Data");
467 switch (elcom_msg_type
) {
470 col_append_str(pinfo
->cinfo
, COL_INFO
, " Request");
475 col_append_str(pinfo
->cinfo
, COL_INFO
, " Response");
482 ti
= proto_tree_add_item(tree
, proto_elcom
, tvb
, offset
, -1, ENC_NA
);
483 elcom_tree
= proto_item_add_subtree(ti
, ett_elcom
);
485 hidden_item
= proto_tree_add_boolean(elcom_tree
,
486 is_request
? hf_elcom_request
: hf_elcom_response
,
488 PROTO_ITEM_SET_HIDDEN(hidden_item
);
490 /* 2 first bytes are the frame length */
492 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
495 proto_item_append_text(ti
, " (incorrect)");
498 elcom_msg_type
= tvb_get_guint8(tvb
, offset
);
499 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
500 proto_item_append_text(elcom_tree
, " ( %s)", val_to_str(elcom_msg_type
, type_vals
, "Unknown %d"));
503 if (tvb_length_remaining(tvb
, offset
) <= 0)
506 switch (elcom_msg_type
) {
510 * Connection request/release assiciated PDU's,
511 * /ELCOM-90 P Protocol spec/ p. 85...
514 /* We need the length here, hardcode the LOWADR_LEN = 21 */
515 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_initiator
, tvb
, offset
, TOTAL_LEN
, ENC_BIG_ENDIAN
);
516 offset
= dissect_lower_address(ti
, ett_elcom_initiator
, tvb
, offset
,
517 hf_elcom_initiator_endian
,
518 hf_elcom_initiator_ip
,
519 hf_elcom_initiator_port
,
520 hf_elcom_initiator_suff
);
521 if (tvb_length_remaining(tvb
, offset
) <= 0)
524 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_responder
, tvb
, offset
, TOTAL_LEN
, ENC_BIG_ENDIAN
);
525 offset
= dissect_lower_address(ti
, ett_elcom_responder
, tvb
, offset
,
526 hf_elcom_responder_endian
,
527 hf_elcom_responder_ip
,
528 hf_elcom_responder_port
,
529 hf_elcom_responder_suff
);
530 if (tvb_length_remaining(tvb
, offset
) <= 0)
533 /* Rest of the payload is USER-DATA, 0..82 bytes */
534 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_userdata
, tvb
, offset
, -1, ENC_NA
);
535 offset
= dissect_userdata(ti
, ett_elcom_userdata
, tvb
, offset
);
541 proto_tree_add_item(elcom_tree
, hf_elcom_release_reason
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
547 proto_tree_add_item(elcom_tree
, hf_elcom_release_result
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
554 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_datarequest
, tvb
, offset
, -1, ENC_NA
);
555 offset
= dissect_datarequest(ti
, ett_elcom_datarequest
, tvb
, offset
);
559 proto_item_append_text(ti
, " <<--- meaning WHAT??");
564 if (tvb_length_remaining(tvb
, offset
) <= 0)
567 /* We should not get here, but if we do, show what is left over: */
568 ti
= proto_tree_add_item(elcom_tree
, hf_elcom_strangeleftover
, tvb
, offset
, -1, ENC_NA
);
569 while (tvb_length_remaining(tvb
, offset
) > 0) {
570 proto_item_append_text(ti
, elcom_show_hex
? " %02x" : " %03o",
571 tvb_get_guint8(tvb
, offset
));
577 proto_register_elcom(void)
579 /* Setup list of header fields See Section 1.6.1 for details*/
580 static hf_register_info hf
[] = {
581 { &hf_elcom_response
,
582 { "Response", "elcom.response",
583 FT_BOOLEAN
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
587 { "Request", "elcom.request",
588 FT_BOOLEAN
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
592 { "Length", "elcom.length",
593 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
597 { "Type", "elcom.type",
598 FT_UINT8
, BASE_HEX
, VALS(type_vals
), 0, NULL
, HFILL
}
601 { &hf_elcom_initiator
,
602 { "Initiator", "elcom.initiator",
603 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
606 { &hf_elcom_initiator_endian
,
607 { "Endian", "elcom.initiator.endian",
608 FT_UINT16
, BASE_HEX
, VALS(endian_vals
), 0, NULL
, HFILL
}
611 { &hf_elcom_initiator_ip
,
612 { "IP", "elcom.initiator.ip",
613 FT_IPv4
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
616 { &hf_elcom_initiator_port
,
617 { "Port", "elcom.initiator.port",
618 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
621 { &hf_elcom_initiator_suff
,
622 { "Suffix", "elcom.initiator.suffix",
623 FT_UINT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
626 { &hf_elcom_responder
,
627 { "Responder", "elcom.responder",
628 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
631 { &hf_elcom_responder_endian
,
632 { "Endian", "elcom.responder.endian",
633 FT_UINT16
, BASE_HEX
, VALS(endian_vals
), 0, NULL
, HFILL
}
636 { &hf_elcom_responder_ip
,
637 { "IP", "elcom.responder.ip",
638 FT_IPv4
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
641 { &hf_elcom_responder_port
,
642 { "Port", "elcom.responder.port",
643 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
646 { &hf_elcom_responder_suff
,
647 { "Suffix", "elcom.responder.suffix",
648 FT_UINT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
651 { &hf_elcom_userdata
,
652 { "User Data", "elcom.userdata",
653 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
656 { &hf_elcom_userdata_length
,
657 { "Length", "elcom.userdata.length",
658 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
661 { &hf_elcom_userdata_pduid
,
662 { "PDU-ID", "elcom.userdata.pduid",
663 FT_UINT8
, BASE_DEC
, VALS(userdata_pduid_vals
), 0, NULL
, HFILL
}
666 { &hf_elcom_userdata_version
,
667 { "Version", "elcom.userdata.version",
668 FT_UINT8
, BASE_DEC
, VALS(userdata_version_vals
), 0, NULL
, HFILL
}
671 { &hf_elcom_userdata_result
,
672 { "Result", "elcom.userdata.result",
673 FT_UINT8
, BASE_DEC
, VALS(userdata_result_vals
), 0, NULL
, HFILL
}
676 { &hf_elcom_userdata_restmark
,
677 { "Restart marking", "elcom.userdata.response.restartcode",
678 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
681 { &hf_elcom_userdata_cf
,
682 { "Control Field", "elcom.userdata.response.controlfield",
683 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
686 { &hf_elcom_release_reason
,
687 { "Reason", "elcom.release.reason",
688 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
691 { &hf_elcom_release_result
,
692 { "Result", "elcom.release.result",
693 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
696 { &hf_elcom_datarequest
,
697 { "Data Request", "elcom.datarequest",
698 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
701 { &hf_elcom_datarequest_grouptype
,
702 { "Group Type", "elcom.datarequest.grouptype",
703 FT_UINT8
, BASE_DEC
, VALS(datarequest_grouptype_vals
), 0, NULL
, HFILL
}
706 { &hf_elcom_datarequest_result
,
707 { "Result", "elcom.datarequest.result",
708 FT_UINT8
, BASE_DEC
, VALS(datarequest_result_vals
), 0, NULL
, HFILL
}
711 { &hf_elcom_datarequest_groupnumber
,
712 { "Group Number", "elcom.datarequest.groupnumber",
713 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
716 { &hf_elcom_datarequest_grouppriority
,
717 { "Group Priority", "elcom.datarequest.grouppriority",
718 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
721 { &hf_elcom_datarequest_groupsize
,
722 { "Group Size", "elcom.datarequest.groupsize",
723 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
726 { &hf_elcom_datarequest_groupindex1
,
727 { "Group Index1", "elcom.datarequest.groupindex1",
728 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
731 { &hf_elcom_datarequest_groupindex2
,
732 { "Group Index2", "elcom.datarequest.groupindex2",
733 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
736 { &hf_elcom_datarequest_oid
,
737 { "Obkect Name", "elcom.datarequest.oid",
738 FT_UINT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
740 { &hf_elcom_strangeleftover
,
741 { "Strange Leftover", "elcom.leftover",
742 FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
746 /* Setup protocol subtree array */
747 static gint
*ett
[] = {
749 &ett_elcom_initiator
,
750 &ett_elcom_responder
,
752 &ett_elcom_datarequest
755 /* Register the protocol name and description */
756 proto_elcom
= proto_register_protocol (
757 "ELCOM Communication Protocol",
762 /* Required function calls to register the header fields and subtrees used */
763 proto_register_field_array(proto_elcom
, hf
, array_length(hf
));
764 proto_register_subtree_array(ett
, array_length(ett
));
769 proto_reg_handoff_elcom(void)
771 dissector_handle_t elcom_handle
;
773 elcom_handle
= create_dissector_handle(dissect_elcom
, proto_elcom
);
774 dissector_add_uint("tcp.port", TCP_PORT_ELCOM
, elcom_handle
);
783 * indent-tabs-mode: nil
786 * ex: set shiftwidth=8 tabstop=8 expandtab:
787 * :indentSize=8:tabSize=8:noTabs=true: