2 * Routines for HSR dissection (IEC62439 Part 3)
3 * Copyright 2009, Florian Reichert <refl[AT]zhaw.ch>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald[AT]wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/etypes.h>
17 void proto_register_hsr(void);
18 void proto_reg_handoff_hsr(void);
20 static dissector_handle_t hsr_frame_handle
;
22 /**********************************************************/
23 /* Lengths of fields within a HSR packet. */
24 /**********************************************************/
25 #define HSR_LSDU_PATH_LENGTH 2
26 #define HSR_SEQUENZNR_LENGTH 2
28 #define HSR_TOTAL_LENGTH 4
30 /**********************************************************/
31 /* Offsets of fields within a HSR packet. */
32 /**********************************************************/
33 #define HSR_PATH_OFFSET 0
34 #define HSR_SEQUENZNR_OFFSET 2
36 static const value_string hsr_laneid_vals
[] = {
42 /**********************************************************/
43 /* Initialize the protocol and registered fields */
44 /**********************************************************/
48 /* Initialize supervision frame fields */
51 static int hf_hsr_path
;
52 static int hf_hsr_netid
;
53 static int hf_hsr_laneid
;
54 static int hf_hsr_lsdu_size
;
55 static int hf_hsr_sequence_nr
;
58 static dissector_table_t ethertype_subdissector_table
;
59 /* Initialize the subtree pointers */
60 static int ett_hsr_frame
;
62 /* Code to actually dissect the packets */
64 dissect_hsr_frame(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
70 uint16_t lsdu_size
, lsdu_size_correct
;
72 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "HSR");
74 col_set_str(pinfo
->cinfo
, COL_INFO
, "HSR-Data Frame");
76 /* create display subtree for the protocol */
78 ti
= proto_tree_add_item(tree
, proto_hsr
, tvb
, 0, HSR_TOTAL_LENGTH
, ENC_NA
);
80 hsr_tree
= proto_item_add_subtree(ti
, ett_hsr_frame
);
82 proto_tree_add_item(hsr_tree
, hf_hsr_path
,
83 tvb
, HSR_PATH_OFFSET
, HSR_LSDU_PATH_LENGTH
, ENC_BIG_ENDIAN
);
85 proto_tree_add_item(hsr_tree
, hf_hsr_netid
,
86 tvb
, HSR_PATH_OFFSET
, HSR_LSDU_PATH_LENGTH
, ENC_BIG_ENDIAN
);
88 proto_tree_add_item(hsr_tree
, hf_hsr_laneid
,
89 tvb
, HSR_PATH_OFFSET
, HSR_LSDU_PATH_LENGTH
, ENC_BIG_ENDIAN
);
92 lsdu_size
= tvb_get_ntohs(tvb
, HSR_PATH_OFFSET
) & 0x0fff;
93 lsdu_size_correct
= tvb_reported_length_remaining(tvb
, 0);
94 if (lsdu_size
== lsdu_size_correct
) {
95 proto_tree_add_uint_format_value(hsr_tree
, hf_hsr_lsdu_size
,
96 tvb
, HSR_PATH_OFFSET
, HSR_LSDU_PATH_LENGTH
, lsdu_size
,
97 "%d [correct]", lsdu_size
);
99 proto_tree_add_uint_format_value(hsr_tree
, hf_hsr_lsdu_size
,
100 tvb
, HSR_PATH_OFFSET
, HSR_LSDU_PATH_LENGTH
, lsdu_size
,
101 "%d [WRONG, should be %d]", lsdu_size
, lsdu_size_correct
);
104 proto_tree_add_item(hsr_tree
, hf_hsr_sequence_nr
,
105 tvb
, HSR_SEQUENZNR_OFFSET
,HSR_SEQUENZNR_LENGTH
, ENC_BIG_ENDIAN
);
107 proto_tree_add_item(hsr_tree
, hf_type
,
108 tvb
, HSR_TOTAL_LENGTH
,2, ENC_BIG_ENDIAN
);
110 next_tvb
= tvb_new_subset_remaining(tvb
, HSR_TOTAL_LENGTH
+ 2);
112 etype
= tvb_get_ntohs(tvb
, HSR_TOTAL_LENGTH
);
114 if (!dissector_try_uint(ethertype_subdissector_table
, etype
, next_tvb
, pinfo
, tree
))
115 call_data_dissector(next_tvb
, pinfo
, hsr_tree
);
117 return tvb_captured_length(tvb
);
122 /* Register the protocol with Wireshark */
123 void proto_register_hsr(void)
125 static hf_register_info hf
[] = {
127 { "Path", "hsr.path",
128 FT_UINT16
, BASE_DEC
, NULL
, 0xf000,
133 { "Network id", "hsr.netid",
134 FT_UINT16
, BASE_DEC
, NULL
, 0xe000,
139 { "Lane id", "hsr.laneid",
140 FT_UINT16
, BASE_DEC
, VALS(hsr_laneid_vals
), 0x1000,
145 { "LSDU size", "hsr.lsdu_size",
146 FT_UINT16
, BASE_DEC
, NULL
, 0x0fff,
150 { &hf_hsr_sequence_nr
,
151 { "Sequence number", "hsr.sequence_nr",
152 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
156 { "Type", "hsr.type",
157 FT_UINT16
, BASE_HEX
, VALS(etype_vals
), 0x00,
163 static int *ett
[] = {
167 /* Register the protocol name and description */
168 proto_hsr
= proto_register_protocol("High-availability Seamless Redundancy (IEC62439 Part 3 Chapter 5)",
171 /* Required function calls to register the header fields and subtree used */
172 proto_register_field_array(proto_hsr
, hf
, array_length(hf
));
173 proto_register_subtree_array(ett
, array_length(ett
));
175 hsr_frame_handle
= register_dissector("hsr", dissect_hsr_frame
, proto_hsr
);
179 void proto_reg_handoff_hsr(void)
181 dissector_add_uint("ethertype", ETHERTYPE_HSR
, hsr_frame_handle
);
183 ethertype_subdissector_table
= find_dissector_table("ethertype");
187 * Editor modelines - https://www.wireshark.org/tools/modelines.html
192 * indent-tabs-mode: nil
195 * vi: set shiftwidth=4 tabstop=8 expandtab:
196 * :indentSize=4:tabSize=8:noTabs=true: