1 /* packet-ixiatrailer.c
2 * Routines for Ixia trailer parsing
4 * Dissector for Ixia Network Visibility Solutions trailer
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
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
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" },
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.
72 dissect_ixiatrailer(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
)
75 unsigned tvblen
, trailer_length
, field_length
;
76 bool matched_without_fcs
, matched_with_fcs
;
77 proto_tree
*ixiatrailer_tree
= NULL
;
79 uint16_t cksum
, comp_cksum
;
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;
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
103 /* This is too short, so it cannot be a valid Ixia trailer. */
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. */
116 /* 3rd & 4th bytes from the end must match our pattern.
117 First, try under the assumption that the tvbuff doesn't include
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
);
126 matched_with_fcs
= false;
127 if (!matched_without_fcs
) {
128 if (!matched_with_fcs
) {
129 /* Neither matched, so no Ixia trailer. */
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
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
) {
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
) {
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
);
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
);
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");
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
);
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"));
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
);
199 offset
+= field_length
;
201 /* We are claiming all of the bytes */
206 dissect_ixiatrailer_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
208 return dissect_ixiatrailer(tvb
, pinfo
, tree
, data
) > 0;
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
[] = {
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
);
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
265 * indent-tabs-mode: nil
268 * ex: set shiftwidth=2 tabstop=8 expandtab:
269 * :indentSize=2:tabSize=8:noTabs=true: