Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-prp.c
blob27f2d1820743da7c5755d8fbd9b1431a2135a2d9
1 /* packet-prp.c
2 * Routines for PRP (Parallel Redundancy Protocol; IEC62439 Part 3) dissection
3 * Copyright 2007, Sven Meier <msv[AT]zhwin.ch>
4 * Copyright 2011, Martin Renold <reld[AT]zhaw.ch>
5 * Copyright 2011, Florian Reichert <refl [AT] zhaw.ch>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald[AT]wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/etypes.h>
18 #include <epan/prefs.h>
20 #define PRP_LAN_A 10
21 #define PRP_LAN_B 11
23 static const value_string prp_lan_vals[] = {
24 {PRP_LAN_A, "LAN A"},
25 {PRP_LAN_B, "LAN B"},
26 {0, NULL}
29 /**********************************************************/
30 /* Initialize the protocol and registered fields */
31 /**********************************************************/
33 void proto_register_prp(void);
35 static int proto_prp;
38 /* Initialize trailer fields */
39 static int hf_prp_redundancy_control_trailer_sequence_nr;
40 static int hf_prp_redundancy_control_trailer_lan;
41 static int hf_prp_redundancy_control_trailer_size;
42 static int hf_prp_redundancy_control_trailer_suffix;
43 static int hf_prp_redundancy_control_trailer_version;
46 /* Initialize the subtree pointers */
47 static int ett_prp_redundancy_control_trailer;
50 /* Code to actually dissect the packets */
51 static int
52 dissect_prp_redundancy_control_trailer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data)
54 proto_item *ti;
55 proto_tree *prp_tree;
56 int i;
57 int length;
58 uint16_t lan_id;
59 uint16_t lsdu_size;
60 uint16_t prp1_suffix;
61 unsigned trailer_start;
62 unsigned trailer_length;
64 trailer_start = 0;
65 trailer_length = 0;
66 length = tvb_reported_length(tvb);
69 * Is there enough data in the packet to every try to search for a
70 * trailer?
72 if (!tvb_bytes_exist(tvb, (length-4)+2, 2))
73 return 0; /* no */
75 if (data == NULL) {
76 return 0;
79 int lsdu_size_correct = *(int*)data;
81 /* search for PRP-0 trailer */
82 /* If the frame is > 64 bytes, the PRP-0 trailer is always at the end. */
83 /* If the frame is <= 64 bytes, the PRP-0 trailer may be anywhere (before the padding) */
84 for(i = 0; i <= length - 4; i++)
86 lan_id = tvb_get_ntohs(tvb, length - 2 - i) >> 12;
87 lsdu_size = tvb_get_ntohs(tvb, length - 2 - i) & 0x0fff;
88 if(lsdu_size == (lsdu_size_correct - i) && (lan_id == 0xa || lan_id == 0xb))
90 trailer_start = length - 4 - i;
91 trailer_length = 4;
92 break;
96 /* check for PRP-1 trailer */
97 /* PRP-1 trailer is always at the end of the frame, after any padding. */
99 lan_id = tvb_get_ntohs(tvb, length-4) >> 12;
100 lsdu_size = tvb_get_ntohs(tvb, length-4) & 0x0fff;
101 prp1_suffix = tvb_get_ntohs(tvb, length-2);
103 if(prp1_suffix == ETHERTYPE_PRP && (lan_id == 0xa || lan_id == 0xb))
105 /* We don't check the lsdu_size, we just display whether
106 it's correct. Helpful for testing, because different
107 definitions of the lsdu_size did exist. */
108 trailer_start = length-6;
109 trailer_length = 6;
113 if(trailer_length != 0)
115 /* create display subtree for the protocol */
116 ti = proto_tree_add_item(tree, proto_prp, tvb, trailer_start,
117 trailer_length, ENC_NA);
119 prp_tree = proto_item_add_subtree(ti, ett_prp_redundancy_control_trailer);
121 if (trailer_length == 4) {
122 ti = proto_tree_add_string(prp_tree, hf_prp_redundancy_control_trailer_version,
123 tvb, trailer_start, trailer_length, "PRP-0");
124 } else {
125 ti = proto_tree_add_string(prp_tree, hf_prp_redundancy_control_trailer_version,
126 tvb, trailer_start, trailer_length, "PRP-1");
128 proto_item_set_generated(ti);
130 proto_tree_add_item(prp_tree, hf_prp_redundancy_control_trailer_sequence_nr,
131 tvb, trailer_start, 2, ENC_BIG_ENDIAN);
133 proto_tree_add_item(prp_tree, hf_prp_redundancy_control_trailer_lan,
134 tvb, trailer_start+2, 2, ENC_BIG_ENDIAN);
136 if (trailer_length == 4) {
137 /* PRP-0 */
138 proto_tree_add_item(prp_tree, hf_prp_redundancy_control_trailer_size,
139 tvb, trailer_start+2, 2, ENC_BIG_ENDIAN);
140 } else {
141 /* PRP-1 */
142 if (lsdu_size == lsdu_size_correct) {
143 proto_tree_add_uint_format(prp_tree, hf_prp_redundancy_control_trailer_size,
144 tvb, trailer_start+2, 2, lsdu_size,
145 "LSDU size: %d [correct]", lsdu_size);
146 } else {
147 proto_tree_add_uint_format(prp_tree, hf_prp_redundancy_control_trailer_size,
148 tvb, trailer_start+2, 2, lsdu_size,
149 "LSDU size: %d [WRONG, should be %d]", lsdu_size, lsdu_size_correct);
151 /* suffix */
152 proto_tree_add_item(prp_tree, hf_prp_redundancy_control_trailer_suffix,
153 tvb, trailer_start+4, 2, ENC_BIG_ENDIAN);
156 return trailer_length;
159 static bool dissect_prp_redundancy_control_trailer_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
161 return dissect_prp_redundancy_control_trailer(tvb, pinfo, parent_tree, data) > 0;
164 /* Register the protocol with Wireshark */
165 void proto_register_prp(void)
167 static hf_register_info hf[] = {
168 /*trailer*/
169 { &hf_prp_redundancy_control_trailer_sequence_nr,
170 { "Sequence number", "prp.trailer.prp_sequence_nr",
171 FT_UINT16, BASE_DEC, NULL, 0x00,
172 NULL, HFILL }
175 { &hf_prp_redundancy_control_trailer_lan,
176 { "LAN", "prp.trailer.prp_lan",
177 FT_UINT16, BASE_DEC, VALS(prp_lan_vals), 0xf000,
178 NULL, HFILL }
181 { &hf_prp_redundancy_control_trailer_size,
182 { "Size", "prp.trailer.prp_size",
183 FT_UINT16, BASE_DEC, NULL, 0x0fff,
184 NULL, HFILL }
187 { &hf_prp_redundancy_control_trailer_suffix,
188 { "Suffix", "prp.trailer.prp1_suffix",
189 FT_UINT16, BASE_HEX, NULL, 0x00,
190 NULL, HFILL }
193 { &hf_prp_redundancy_control_trailer_version,
194 { "PRP Version", "prp.trailer.version",
195 FT_STRING, BASE_NONE, NULL, 0x00,
196 NULL, HFILL }
200 static int *ett[] = {
201 &ett_prp_redundancy_control_trailer,
204 module_t *prp_module;
206 /* Register the protocol name and description */
207 proto_prp = proto_register_protocol("Parallel Redundancy Protocol (IEC62439 Part 3)", "PRP", "prp");
209 prp_module = prefs_register_protocol_obsolete(proto_prp);
211 prefs_register_obsolete_preference(prp_module, "enable");
213 /* Required function calls to register the header fields and subtree used */
214 proto_register_field_array(proto_prp, hf, array_length(hf));
215 proto_register_subtree_array(ett, array_length(ett));
217 heur_dissector_add("eth.trailer", dissect_prp_redundancy_control_trailer_heur,
218 "PRP Trailer", "prp_eth", proto_prp, HEURISTIC_ENABLE);
222 * Editor modelines - https://www.wireshark.org/tools/modelines.html
224 * Local variables:
225 * c-basic-offset: 4
226 * tab-width: 8
227 * indent-tabs-mode: nil
228 * End:
230 * vi: set shiftwidth=4 tabstop=8 expandtab:
231 * :indentSize=4:tabSize=8:noTabs=true: