Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ixiatrailer.c
blobc4f41c123097c577bcb77aa605ced4032a2dbee4
1 /* packet-ixiatrailer.c
2 * Routines for Ixia trailer parsing
4 * Dissector for Ixia Network Visibility Solutions trailer
5 * Copyright Ixia 2012
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@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 <wsutil/pint.h>
18 #include <epan/prefs.h>
19 #include <epan/in_cksum.h>
20 #include <epan/expert.h>
22 void proto_register_ixiatrailer(void);
23 void proto_reg_handoff_ixiatrailer(void);
25 /* Trailer "magic number". */
26 #define IXIA_PATTERN 0xAF12
28 /* Trailer TLV types.
30 TODO: which of these typestamp types are currently supported?
31 Should lose the rest!! */
32 #define IXIATRAILER_FTYPE_ORIGINAL_PACKET_SIZE 1
33 #define IXIATRAILER_FTYPE_TIMESTAMP_LOCAL 3
34 #define IXIATRAILER_FTYPE_TIMESTAMP_NTP 4
35 #define IXIATRAILER_FTYPE_TIMESTAMP_GPS 5
36 #define IXIATRAILER_FTYPE_TIMESTAMP_1588 6 /* PTP */
37 #define IXIATRAILER_FTYPE_TIMESTAMP_HOLDOVER 7
39 static const value_string ixiatrailer_ftype_timestamp[] = {
40 { IXIATRAILER_FTYPE_TIMESTAMP_LOCAL, "Local" },
41 { IXIATRAILER_FTYPE_TIMESTAMP_NTP, "NTP" },
42 { IXIATRAILER_FTYPE_TIMESTAMP_GPS, "GPS" },
43 { IXIATRAILER_FTYPE_TIMESTAMP_1588, "PTP" },
44 { IXIATRAILER_FTYPE_TIMESTAMP_HOLDOVER, "Holdover" },
45 { 0, NULL }
48 /* Preference settings */
49 static bool ixiatrailer_summary_in_tree = true;
51 static int proto_ixiatrailer;
52 static int ett_ixiatrailer;
54 static int hf_ixiatrailer_packetlen;
55 static int hf_ixiatrailer_timestamp;
56 static int hf_ixiatrailer_generic;
58 static expert_field ei_ixiatrailer_field_length_invalid;
60 /* The trailer begins with a sequence of TLVs, each of which has a
61 1-byte type, a 1-byte value length (not TLV length, so the TLV
62 length is the value length + 2), and a variable-length value.
64 Following the sequence of TLVs is:
66 a 1-byte field giving the length of the sequence of TLVs;
67 a 2-byte big-endian signature field with the value 0xAF12;
68 a 2-byte big-endian checksum field, covering the sequence
69 of TLVs, the sequence length, and the signature.
71 static int
72 dissect_ixiatrailer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
74 proto_tree *ti;
75 unsigned tvblen, trailer_length, field_length;
76 bool matched_without_fcs, matched_with_fcs;
77 proto_tree *ixiatrailer_tree = NULL;
78 unsigned offset = 0;
79 uint16_t cksum, comp_cksum;
80 vec_t vec;
81 uint8_t field_type;
83 /* A trailer must, at minimum, include:
85 a "original packet size" TLV, with 1 byte of type, 1 byte of
86 value length, and 2 bytes of original packet ize;
88 1 byte of trailer length;
90 2 bytes of signature;
92 2 bytes of trailer checksum;
94 for a total of 9 bytes. */
95 tvblen = tvb_reported_length(tvb);
96 if (tvblen != tvb_captured_length(tvb)) {
97 /* The heuristic check includes a checksum check, so we need the
98 *entire* trailer to have been captured; if it wasn't, we don't
99 try to check it. */
100 return 0;
102 if (tvblen < 9) {
103 /* This is too short, so it cannot be a valid Ixia trailer. */
104 return 0;
107 /* Depending upon the ethernet preference "Assume packets have FCS", we
108 may be given those 4 bytes too.
110 Try checking two locations for our pattern. */
112 if (tvblen == 23) {
113 tvblen = 19;
116 /* 3rd & 4th bytes from the end must match our pattern.
117 First, try under the assumption that the tvbuff doesn't include
118 the FCS. */
119 matched_without_fcs = (tvb_get_ntohs(tvb, tvblen-4) == IXIA_PATTERN);
121 /* If that didn't match, is the tvbuff big enough to include an Ixia
122 trailer *and* an FCS? If so, try under that assumption. */
123 if (!matched_without_fcs && tvblen >= 13)
124 matched_with_fcs = (tvb_get_ntohs(tvb, tvblen-(4+4)) == IXIA_PATTERN);
125 else
126 matched_with_fcs = false;
127 if (!matched_without_fcs) {
128 if (!matched_with_fcs) {
129 /* Neither matched, so no Ixia trailer. */
130 return 0;
133 /* Matched under the assumption that we have an FCS, so let's
134 act as if that's the case. Remove the FCS length from the
135 tvbuff. */
136 tvblen -= 4;
139 /* Read Trailer-length field */
140 trailer_length = tvb_get_uint8(tvb, tvblen-5);
141 /* Should match overall length of trailer */
142 if ((tvblen-5) != trailer_length) {
143 return 0;
146 /* Last 2 bytes are the checksum */
147 cksum = tvb_get_ntohs(tvb, tvblen-2);
149 /* Verify the checksum; if not valid, it means that the trailer is not valid */
150 SET_CKSUM_VEC_TVB(vec, tvb, offset, trailer_length + 3);
151 comp_cksum = in_cksum(&vec, 1);
152 if (pntoh16(&comp_cksum) != cksum) {
153 return 0;
156 /* OK: We have our trailer - create protocol root */
157 ti = proto_tree_add_item(tree, proto_ixiatrailer, tvb, offset, trailer_length + 5, ENC_NA);
159 /* Append summary to item, if configured to */
160 if (ixiatrailer_summary_in_tree) {
161 proto_item_append_text(ti, ", Length: %u, Checksum: 0x%x", trailer_length, cksum);
164 /* Create subtree */
165 ixiatrailer_tree = proto_item_add_subtree(ti, ett_ixiatrailer);
167 while (offset < trailer_length - 2)
169 field_type = tvb_get_uint8(tvb, offset++);
170 field_length = tvb_get_uint8(tvb, offset++);
171 switch (field_type) {
172 case IXIATRAILER_FTYPE_ORIGINAL_PACKET_SIZE:
173 if (field_length != 2){
174 expert_add_info_format(pinfo, ti, &ei_ixiatrailer_field_length_invalid, "Field length %u invalid", field_length);
175 break;
177 ti = proto_tree_add_item(ixiatrailer_tree, hf_ixiatrailer_packetlen, tvb, offset, field_length, ENC_BIG_ENDIAN);
178 proto_item_append_text(ti, " bytes");
179 break;
180 case IXIATRAILER_FTYPE_TIMESTAMP_LOCAL:
181 case IXIATRAILER_FTYPE_TIMESTAMP_NTP:
182 case IXIATRAILER_FTYPE_TIMESTAMP_GPS:
183 case IXIATRAILER_FTYPE_TIMESTAMP_1588:
184 case IXIATRAILER_FTYPE_TIMESTAMP_HOLDOVER:
185 if (field_length != 8) {
186 expert_add_info_format(pinfo, ti, &ei_ixiatrailer_field_length_invalid, "Field length %u invalid", field_length);
187 break;
189 /* Timestamp */
190 ti = proto_tree_add_item(ixiatrailer_tree, hf_ixiatrailer_timestamp, tvb, offset, field_length, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
191 proto_item_append_text(ti, "; Source: %s", val_to_str_const(field_type, ixiatrailer_ftype_timestamp, "Unknown"));
192 break;
193 default:
194 /* Not a recognized time format - just show as bytes */
195 ti = proto_tree_add_item(ixiatrailer_tree, hf_ixiatrailer_generic, tvb, offset, field_length, ENC_NA);
196 proto_item_append_text(ti, " [Id: %u, Length: %u bytes]", field_type, field_length);
197 break;
199 offset += field_length;
201 /* We are claiming all of the bytes */
202 return tvblen;
205 static bool
206 dissect_ixiatrailer_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
208 return dissect_ixiatrailer(tvb, pinfo, tree, data) > 0;
211 void
212 proto_register_ixiatrailer(void)
215 static hf_register_info hf[] = {
216 { &hf_ixiatrailer_packetlen, {
217 "Original packet length", "ixiatrailer.packetlen", FT_UINT16, BASE_DEC,
218 NULL, 0x0, NULL, HFILL }},
219 { &hf_ixiatrailer_timestamp, {
220 "Time Stamp", "ixiatrailer.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
221 NULL, 0x0, NULL, HFILL }},
222 { &hf_ixiatrailer_generic, {
223 "Generic Field", "ixiatrailer.generic", FT_BYTES, BASE_NONE,
224 NULL, 0x0, NULL, HFILL }},
227 static int *ixiatrailer_ett[] = {
228 &ett_ixiatrailer
231 static ei_register_info ei[] = {
232 { &ei_ixiatrailer_field_length_invalid, { "ixiatrailer.field_length_invalid", PI_MALFORMED, PI_ERROR, "Field length invalid", EXPFILL }},
235 module_t *ixiatrailer_module;
236 expert_module_t* expert_ixiatrailer;
238 proto_ixiatrailer = proto_register_protocol("Ixia Trailer", "IXIATRAILER", "ixiatrailer");
239 proto_register_field_array(proto_ixiatrailer, hf, array_length(hf));
240 proto_register_subtree_array(ixiatrailer_ett, array_length(ixiatrailer_ett));
241 expert_ixiatrailer = expert_register_protocol(proto_ixiatrailer);
242 expert_register_field_array(expert_ixiatrailer, ei, array_length(ei));
244 ixiatrailer_module = prefs_register_protocol(proto_ixiatrailer, NULL);
245 prefs_register_bool_preference(ixiatrailer_module, "summary_in_tree",
246 "Show trailer summary in protocol tree",
247 "Whether the trailer summary line should be shown in the protocol tree",
248 &ixiatrailer_summary_in_tree);
252 void
253 proto_reg_handoff_ixiatrailer(void)
255 /* Check for Ixia format in the ethernet trailer */
256 heur_dissector_add("eth.trailer", dissect_ixiatrailer_heur, "Ixia Trailer", "ixiatrailer_eth", proto_ixiatrailer, HEURISTIC_ENABLE);
260 * Editor modelines - https://www.wireshark.org/tools/modelines.html
262 * Local Variables:
263 * c-basic-offset: 2
264 * tab-width: 8
265 * indent-tabs-mode: nil
266 * End:
268 * ex: set shiftwidth=2 tabstop=8 expandtab:
269 * :indentSize=2:tabSize=8:noTabs=true: