Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-metamako.c
blob845e04e25b0dc584c2e36e1ff07ac31e5460ba5e
1 /* packet-metamako.c
2 * Routines for dissection of Metamako trailers. Forked from
3 * packet-vssmonitoring.c on 20th December, 2015.
4 * See https://www.metamako.com for further details.
6 * Copyright VSS-Monitoring 2011
7 * Copyright Metamako LP 2015
9 * 20111205 - First edition by Sake Blok (sake.blok@SYN-bit.nl)
10 * 20151220 - Forked to become packet-metamako.c
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include "config.h"
21 #include <epan/packet.h>
22 #include <epan/etypes.h>
23 #include <epan/expert.h>
24 #include <epan/crc32-tvb.h>
26 #include <glib/gprintf.h>
28 #define TRAILER_MIN_LENGTH_NO_FCS 16
29 #define TRAILER_NS_UPPER_BOUND 1000000000
30 #define TRAILER_SECS_BOUNDS_DFLT "3600-"
31 #define TRAILER_DAYS_DIFF_LIMIT_DFLT 30
32 #define SECS_IN_ONE_DAY (60 * 60 * 24)
34 void proto_register_metamako(void);
35 void proto_reg_handoff_metamako(void);
37 /* FCS Options */
38 static bool metamako_check_fcs = true;
39 static int metamako_fcs_len = -1; /* By default, try to autodetect the FCS. */
40 /* Heuristic Options */
41 static int metamako_trailer_present = -1; /* By default, try to autodetect the trailer. */
42 static range_t* metamako_trailer_secs_bounds;
43 static unsigned metamako_trailer_days_diff_limit = TRAILER_DAYS_DIFF_LIMIT_DFLT;
45 /* Protocols and Header Fields */
46 static int proto_metamako;
49 Metamako trailer format
50 0.............7...............15..............23..............31
51 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 | Original FCS |
53 +---------------+---------------+---------------+---------------+
54 | ... |
55 +---------------+---------------+---------------+---------------+
56 | TLV Extensions |
57 +---------------+---------------+---------------+---------------+
58 | ... |
59 +---------------+---------------+---------------+---------------+
60 | Seconds |
61 +---------------+---------------+---------------+---------------+
62 | Nanoseconds |
63 +---------------+---------------+---------------+---------------+
64 | Flags | Device ID | Port ID |
65 +---------------+---------------+---------------+---------------+
68 static int hf_metamako_origfcs;
69 static int hf_metamako_trailerext;
70 static int hf_metamako_unknownext;
71 static int hf_metamako_seqnum;
72 static int hf_metamako_tagstring;
73 static int hf_metamako_fracns;
74 static int hf_metamako_crchash;
75 static int hf_metamako_egress_seqnum;
76 static int hf_metamako_time_abs;
77 static int hf_metamako_time_rel;
78 static int hf_metamako_flags;
79 static int hf_metamako_src_port;
80 static int hf_metamako_src_device;
81 static int hf_metamako_time_diff;
82 static int hf_metamako_fcs;
83 static int hf_metamako_fcs_status;
85 static int hf_metamako_flags_orig_fcs_vld;
86 static int hf_metamako_flags_has_ext;
87 static int hf_metamako_flags_duplicate;
88 static int hf_metamako_flags_ts_degraded;
89 static int hf_metamako_flags_control_block_type;
90 static int hf_metamako_reserved;
92 static int ett_metamako;
93 static int ett_metamako_timestamp;
94 static int ett_metamako_extensions;
95 static int ett_metamako_flags;
97 static const enum_val_t metamako_fcs_vals[] = {
98 {"heuristic", "According to heuristic", -1},
99 {"never", "Never", 0},
100 {"always", "Always", 4},
101 {NULL, NULL, 0}
104 static const enum_val_t metamako_trailer_present_vals[] = {
105 {"heuristic", "According to heuristic", -1},
106 {"never", "Never", 0},
107 {"always", "Always", 1},
108 {NULL, NULL, 0}
111 static const value_string tfs_pcs49_btf_vals[] = {
112 { 0x0, "0x33 or 0x66" },
113 { 0x1, "0x78"},
114 { 0, NULL }
117 static const value_string tfs_orig_fcs_status_vals[] = {
118 { 0x0, "Bad" },
119 { 0x1, "Good"},
120 { 0, NULL }
123 static int* const flags[] = {
124 &hf_metamako_flags_control_block_type,
125 &hf_metamako_flags_ts_degraded,
126 &hf_metamako_flags_duplicate,
127 &hf_metamako_flags_has_ext,
128 &hf_metamako_flags_orig_fcs_vld,
129 &hf_metamako_reserved,
130 NULL
133 static expert_field ei_metamako_fcs_bad;
135 static void
136 sub_nanos_base_custom(char* result, uint32_t value)
138 double temp_double;
139 temp_double = ((double)value) / (1ULL << 24);
140 snprintf(result, ITEM_LABEL_LENGTH, "%1.9fns", temp_double);
143 static int
144 validate_metamako_timestamp(nstime_t* metamako_time, packet_info* pinfo)
147 /* Check that we have a valid nanoseconds field. */
148 if (metamako_time->nsecs >= TRAILER_NS_UPPER_BOUND)
149 return 0;
151 /* Check that the seconds in the trailer timestamp are in the user-specified bounds. */
152 if (!value_is_in_range(metamako_trailer_secs_bounds, (uint32_t)metamako_time->secs))
153 return 0;
155 /* Check that the number of days between the trailer timestamp
156 and the capture timestamp are within the user-specified bounds.
157 Don't use the abs() function because it is not supported on all
158 platforms and has type ambiguity. */
159 if (metamako_time->secs > pinfo->abs_ts.secs) {
160 if (metamako_time->secs - pinfo->abs_ts.secs > (time_t)metamako_trailer_days_diff_limit * SECS_IN_ONE_DAY)
161 return 0;
163 else {
164 if (pinfo->abs_ts.secs - metamako_time->secs > (time_t)metamako_trailer_days_diff_limit * SECS_IN_ONE_DAY)
165 return 0;
168 return 1;
171 static int
172 dissect_metamako(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
174 unsigned i, i_start, i_end, j;
176 proto_tree* ti, * parent, * item;
177 proto_tree* metamako_tree, * timestamp_tree;
178 proto_tree* extensions_tree;
180 unsigned offset = 0;
182 unsigned captured_trailer_bytes;
183 unsigned metamako_trailer_bytes;
184 unsigned trailer_min_length;
185 bool trailer_valid;
186 bool has_fcs;
188 nstime_t metamako_time, time_diff, time_rel;
189 unsigned metamako_meta;
191 unsigned metamako_tlv_count;
192 unsigned metamako_tlv_firstword;
193 unsigned metamako_tlv_len;
194 unsigned metamako_tlv_tag;
195 unsigned metamako_tlv_pos;
196 unsigned metamako_tlv_bytes;
198 uint8_t metamako_srcport;
199 uint16_t metamako_srcdevice;
200 uint8_t metamako_flags;
202 struct tm* tmp;
204 /* The Metamako trailer is made up of:
205 4 bytes -- original FCS
206 N bytes -- trailer extensions
207 4 bytes -- seconds
208 4 bytes -- nanoseconds
209 1 byte -- flags
210 2 bytes -- device ID
211 1 byte -- port ID
213 The new FCS is not a part of the trailer specification,
214 but it may be passed to this dissector in the course of
215 dissecting the Ethernet trailer.
216 If `metamako_fcs_len` is 0, we know it's not present;
217 if `metamako_fcs_len` is 4, we know it's present;
218 if `metamako_fcs_len` is -1, we need some heuristics to
219 determine whether it's present.
221 4 bytes -- New (valid) FCS (may or may not have been captured)
224 /* If the user has told us that the Metamako trailer is not present,
225 then exit immediately. */
226 if (metamako_trailer_present == 0)
227 return 0;
229 /* First get the captured length of the trailer. */
230 captured_trailer_bytes = tvb_captured_length(tvb);
232 /* Determine the minimum trailer length required, based on the user's
233 setting of the assumed FCS capture. */
234 trailer_min_length = metamako_fcs_len == 4 ? TRAILER_MIN_LENGTH_NO_FCS + 4 : TRAILER_MIN_LENGTH_NO_FCS;
236 /* If we have less than `trailer_min_length` bytes captured, we can't
237 read the trailer. */
238 if (captured_trailer_bytes < trailer_min_length)
239 return 0;
241 /* Adjust the state of the loop variables to account for the user options. */
242 trailer_valid = false;
243 i_start = metamako_fcs_len == 4 ? 1 : 0;
244 i_end = metamako_fcs_len == 0 ? 1 : 2;
246 /* Loop through the trailer bytes, trying to find a valid trailer.
247 * When:
248 * i == 0, we assume there IS NO trailing FCS
249 * i == 1, we assume there IS a trailing FCS
251 for (i = i_start; i < i_end && !trailer_valid; i++) {
252 has_fcs = i == 1;
253 captured_trailer_bytes -= 4 * i;
254 metamako_trailer_bytes = captured_trailer_bytes;
255 /* Start at the tail of the trailer and work inwards. */
256 metamako_meta = tvb_get_ntohl(tvb, metamako_trailer_bytes - 4);
257 metamako_flags = (metamako_meta >> 24) & 0xFF;
258 metamako_trailer_bytes -= 4;
259 metamako_time.nsecs = tvb_get_ntohl(tvb, metamako_trailer_bytes - 4);
260 metamako_trailer_bytes -= 4;
261 metamako_time.secs = tvb_get_ntohl(tvb, metamako_trailer_bytes - 4);
262 metamako_trailer_bytes -= 4;
264 /* Check the validity of the candidate timestamp. */
265 if ((metamako_trailer_present == 1) || validate_metamako_timestamp(&metamako_time, pinfo)) {
266 metamako_tlv_bytes = 0;
267 metamako_tlv_count = 0;
268 /* If the trailer has TLV extensions, "walk" them backwards to the Orig FCS field. */
269 if (metamako_flags & 0x2) {
270 /* Extensions are flagged as included, check if there is bytes
271 * to support this, and try to decode.
273 while (metamako_trailer_bytes >= 4) {
274 /* Bytes are here, decode as TLVs. */
275 metamako_tlv_firstword = tvb_get_ntohl(tvb, metamako_trailer_bytes - 4);
276 metamako_tlv_count++;
277 metamako_tlv_bytes += 4;
278 metamako_trailer_bytes -= 4;
280 /* Extract length */
281 metamako_tlv_len = (metamako_tlv_firstword >> 6) & 0x3;
283 /* If it's a secondary tag header, extract the extended length. */
284 if ((metamako_tlv_firstword & 0x1F) == 0x1F)
285 metamako_tlv_len = ((metamako_tlv_firstword >> 6) & 0x3FF) + 1;
287 /* Skip over the data and find the next tag. We do this in a loop
288 rather than subtracting `4 * metamako_tlv_len` in case the
289 dissection has picked up an invalid TLV length in its
290 heuristic search. This prevents the "walk" from going past the
291 original length of the trailer. */
292 while ((metamako_tlv_len > 0) && (metamako_trailer_bytes >= 4)) {
293 metamako_tlv_len--;
294 metamako_tlv_bytes += 4;
295 metamako_trailer_bytes -= 4;
298 /* If this is flagged as the last TLV, stop. */
299 if ((metamako_tlv_firstword >> 5) & 0x1) {
300 break;
305 /* There should be at least enough bytes for the Orig FCS field.
306 * Any bytes before this are padding. */
307 if (metamako_trailer_bytes >= 4) {
308 /* Decrement by the number of bytes in the Orig FCS field. */
309 metamako_trailer_bytes -= 4;
310 /* This byte offset is the beginning of the Metamako trailer. */
311 offset = metamako_trailer_bytes;
312 /* If we've made it this far, it appears we've got a valid trailer. */
313 trailer_valid = true;
318 /* Did we find a valid trailer? */
319 if (!trailer_valid)
320 return 0;
322 /* Everything looks good! Now dissect the trailer. */
323 col_append_str(pinfo->cinfo, COL_INFO, " with Metamako trailer");
324 ti = proto_tree_add_item(tree, proto_metamako, tvb, offset, (captured_trailer_bytes - offset), ENC_NA);
325 metamako_tree = proto_item_add_subtree(ti, ett_metamako);
327 /* Original FCS */
328 proto_tree_add_item(metamako_tree, hf_metamako_origfcs, tvb, offset, 4, ENC_BIG_ENDIAN);
329 offset += 4;
331 /* TLV Extensions */
332 if (metamako_tlv_bytes > 0) {
333 parent = proto_tree_add_item(metamako_tree, hf_metamako_trailerext, tvb, captured_trailer_bytes - 12 - metamako_tlv_bytes, metamako_tlv_bytes, ENC_NA);
334 extensions_tree = proto_item_add_subtree(parent, ett_metamako_extensions);
335 while (metamako_tlv_count > 0) {
336 metamako_tlv_pos = captured_trailer_bytes - 16;
337 i = metamako_tlv_count;
338 do {
339 /* Read TLV word and decode. */
340 metamako_tlv_firstword = tvb_get_ntohl(tvb, metamako_tlv_pos);
341 metamako_tlv_len = (metamako_tlv_firstword >> 6) & 0x3;
342 metamako_tlv_bytes = (metamako_tlv_len * 4) + 3;
343 metamako_tlv_tag = (metamako_tlv_firstword & 0x1F);
345 /* If this is a Secondary Tag Header, decode the tag extensions. */
346 if ((metamako_tlv_firstword & 0x1F) == 0x1F) {
347 metamako_tlv_len = ((metamako_tlv_firstword >> 6) & 0x3FF) + 1;
348 metamako_tlv_bytes = (metamako_tlv_len * 4);
349 metamako_tlv_tag += ((metamako_tlv_firstword >> 16) & 0xFFFF);
352 /* Decrement TLV count. */
353 i--;
355 /* Skip over the data if this is not our destination. */
356 if (i != 0)
357 metamako_tlv_pos -= (metamako_tlv_len + 1) * 4;
358 } while (i > 0);
360 metamako_tlv_pos -= (metamako_tlv_len + 1) * 4;
361 /* We've skipped to the i-th TLV, decode it. */
362 switch (metamako_tlv_tag) {
363 case 0x00:
364 /* Ingress Sequence Number */
365 proto_tree_add_item(extensions_tree, hf_metamako_seqnum, tvb, metamako_tlv_pos + 5, 2, ENC_BIG_ENDIAN);
366 proto_item_append_text(parent, ", Sequence No: %d", tvb_get_ntohs(tvb, metamako_tlv_pos + 5));
367 break;
369 case 0x01:
370 /* Sub-nanoseconds */
371 proto_tree_add_item(extensions_tree, hf_metamako_fracns, tvb, metamako_tlv_pos + 4, 3, ENC_BIG_ENDIAN);
372 proto_item_append_text(parent, ", Sub-nanoseconds: %1.9fns", ((double)(tvb_get_ntohl(tvb, metamako_tlv_pos + 3) & 0x00FFFFFF)) / (1ULL << 24));
373 break;
375 case 0x02:
376 /* Deduplication CRC64 Hash */
377 proto_tree_add_item(extensions_tree, hf_metamako_crchash, tvb, metamako_tlv_pos + 4, 8, ENC_BIG_ENDIAN);
378 proto_item_append_text(parent, ", CRC64 ECMA Hash: 0x%" PRIx64, tvb_get_ntoh64(tvb, metamako_tlv_pos + 4));
379 break;
381 case 0x03:
382 /* Egress Sequence Number */
383 proto_tree_add_item(extensions_tree, hf_metamako_egress_seqnum, tvb, metamako_tlv_pos + 4, 3, ENC_BIG_ENDIAN);
384 proto_item_append_text(parent, ", Egress Sequence No: %d", tvb_get_ntohl(tvb, metamako_tlv_pos + 3) & 0x000FFFFF);
385 break;
387 case 0x1F:
388 /* Tag String */
389 proto_tree_add_item(extensions_tree, hf_metamako_tagstring, tvb, metamako_tlv_pos + 4, metamako_tlv_len * 4, ENC_ASCII);
390 break;
392 default:
393 /* Unknown tag: just print it's ID and Data. */
394 item = proto_tree_add_item(extensions_tree, hf_metamako_unknownext, tvb, metamako_tlv_pos + 4, metamako_tlv_bytes, ENC_NA);
395 /* Start with the Tag */
396 proto_item_set_text(item, "Unknown Tag [0x%05" PRIx32 "]: ", metamako_tlv_tag);
397 /* Iterate through the data appending as we go */
398 for (j = 0; j < metamako_tlv_bytes; j++) {
399 proto_item_append_text(item, "%02" PRIx8, tvb_get_uint8(tvb, metamako_tlv_pos + 4 + j));
400 if ((28 + j * 2) >= ITEM_LABEL_LENGTH) {
401 proto_item_append_text(item, "...");
402 break;
405 break;
408 /* Increment the offset by the Data + Tag size */
409 offset += (metamako_tlv_len + 1) * 4;
410 /* Decrement count as we've just decoded a TLV */
411 metamako_tlv_count--;
415 /* Timestamp */
416 item = proto_tree_add_time(metamako_tree, hf_metamako_time_abs, tvb, offset, 8, &metamako_time);
417 timestamp_tree = proto_item_add_subtree(item, ett_metamako_timestamp);
419 tmp = localtime(&metamako_time.secs);
420 if (tmp)
421 proto_item_append_text(ti, ", Timestamp: %02d:%02d:%02d.%09ld",
422 tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (long)metamako_time.nsecs);
423 else
424 proto_item_append_text(ti, ", Timestamp: <Not representable>");
426 /* [Timestamp in seconds] */
427 item = proto_tree_add_time_item(timestamp_tree, hf_metamako_time_rel, tvb, offset, 8,
428 ENC_BIG_ENDIAN, &time_rel, NULL, NULL);
429 proto_item_set_generated(item);
431 /* [Timestamp difference - capture timestamp minus trailer timestamp] */
432 nstime_delta(&time_diff, &pinfo->abs_ts, &metamako_time);
433 item = proto_tree_add_time(timestamp_tree, hf_metamako_time_diff, tvb, offset, 8, &time_diff);
434 proto_item_set_generated(item);
435 offset += 8;
437 /* Flags */
438 proto_tree_add_bitmask(metamako_tree, tvb, offset, hf_metamako_flags, ett_metamako_flags, flags, ENC_BIG_ENDIAN);
439 offset++;
441 /* Source device */
442 metamako_srcdevice = tvb_get_ntohs(tvb, offset);
443 proto_tree_add_item(metamako_tree, hf_metamako_src_device, tvb, offset, 2, ENC_BIG_ENDIAN);
444 proto_item_append_text(ti, ", Source Device: %d", metamako_srcdevice);
445 offset += 2;
447 /* Source port */
448 metamako_srcport = tvb_get_uint8(tvb, offset);
449 proto_tree_add_item(metamako_tree, hf_metamako_src_port, tvb, offset, 1, ENC_BIG_ENDIAN);
450 proto_item_append_text(ti, ", Source Port: %d", metamako_srcport);
451 offset++;
453 if (has_fcs) {
454 uint32_t sent_fcs = tvb_get_ntohl(tvb, offset);
455 if (metamako_check_fcs) {
456 tvbuff_t* parent_tvb = tvb_get_ds_tvb(tvb);
457 uint32_t fcs = crc32_802_tvb(parent_tvb, tvb_captured_length(parent_tvb) - 4);
458 proto_tree_add_checksum(tree, tvb, offset, hf_metamako_fcs, hf_metamako_fcs_status, &ei_metamako_fcs_bad, pinfo, fcs, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
460 if (fcs != sent_fcs) {
461 col_append_str(pinfo->cinfo, COL_INFO, " [ETHERNET FRAME CHECK SEQUENCE INCORRECT]");
464 else {
465 proto_tree_add_checksum(tree, tvb, offset, hf_metamako_fcs, hf_metamako_fcs_status, &ei_metamako_fcs_bad, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
467 offset += 4;
470 return offset;
473 static bool
474 dissect_metamako_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
476 return dissect_metamako(tvb, pinfo, tree, data) > 0;
479 void
480 proto_register_metamako(void)
482 static hf_register_info hf[] = {
483 { &hf_metamako_origfcs, {
484 "Original FCS", "metamako.orig_fcs",
485 FT_UINT32, BASE_HEX, NULL, 0x0,
486 NULL, HFILL }},
488 { &hf_metamako_trailerext, {
489 "Trailer Extensions", "metamako.ext",
490 FT_NONE, BASE_NONE, NULL, 0x0,
491 NULL, HFILL }},
493 { &hf_metamako_unknownext, {
494 "Unknown Tag", "metamako.unknown",
495 FT_BYTES, BASE_NONE, NULL, 0x0,
496 NULL, HFILL }},
498 { &hf_metamako_seqnum, {
499 "Sequence Number", "metamako.seqnum",
500 FT_UINT16, BASE_DEC, NULL, 0x0,
501 NULL, HFILL }},
503 { &hf_metamako_fracns, {
504 "Sub-nanoseconds", "metamako.subns",
505 FT_UINT24, BASE_CUSTOM, CF_FUNC(sub_nanos_base_custom), 0x0,
506 NULL, HFILL }},
508 { &hf_metamako_crchash, {
509 "CRC64 ECMA Hash", "metamako.crchash",
510 FT_UINT64, BASE_HEX, NULL, 0x0,
511 NULL, HFILL }},
513 { &hf_metamako_egress_seqnum, {
514 "Egress Sequence Number", "metamako.egrseqnum",
515 FT_UINT32, BASE_DEC, NULL, 0x0,
516 NULL, HFILL }},
518 { &hf_metamako_tagstring, {
519 "Tag String", "metamako.tagstring",
520 FT_STRING, BASE_NONE, NULL, 0x0,
521 NULL, HFILL }},
523 { &hf_metamako_time_abs, {
524 "Timestamp", "metamako.time.abs",
525 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
526 NULL, HFILL }},
528 { &hf_metamako_time_rel, {
529 "Timestamp", "metamako.time.rel",
530 FT_RELATIVE_TIME, ENC_BIG_ENDIAN, NULL, 0x0,
531 NULL, HFILL }},
533 { &hf_metamako_time_diff, {
534 "Time Difference", "metamako.time.diff",
535 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
536 "Capture timestamp minus trailer timestamp", HFILL }},
538 {&hf_metamako_flags, {
539 "Flags", "metamako.flags",
540 FT_UINT8, BASE_HEX, NULL, 0x0,
541 NULL, HFILL}},
543 {&hf_metamako_reserved, {
544 "Reserved", "metamako.reserved",
545 FT_UINT8, BASE_HEX, NULL, 0xC8,
546 NULL, HFILL}},
548 {&hf_metamako_flags_control_block_type, {
549 "Clause 49 BTF", "metamako.flags.pcs49_btf",
550 FT_UINT8, BASE_HEX, VALS(tfs_pcs49_btf_vals), 0x20,
551 NULL, HFILL}},
553 {&hf_metamako_flags_ts_degraded, {
554 "Timestamp degraded", "metamako.flags.ts_degraded",
555 FT_BOOLEAN, 8, NULL, 0x10,
556 NULL, HFILL}},
558 {&hf_metamako_flags_duplicate, {
559 "Duplicate Packet", "metamako.flags.is_duplicate",
560 FT_BOOLEAN, 8, NULL, 0x04,
561 NULL, HFILL}},
563 {&hf_metamako_flags_has_ext, {
564 "Has Trailer Extensions", "metamako.flags.has_extensions",
565 FT_BOOLEAN, 8, NULL, 0x02,
566 NULL, HFILL}},
568 {&hf_metamako_flags_orig_fcs_vld, {
569 "Original FCS Status", "metamako.flags.orig_fcs_status",
570 FT_UINT8, BASE_HEX, VALS(tfs_orig_fcs_status_vals), 0x01,
571 NULL, HFILL}},
573 { &hf_metamako_src_device, {
574 "Source Device ID", "metamako.src.device_id",
575 FT_UINT16, BASE_DEC, NULL, 0x0,
576 NULL, HFILL }},
578 { &hf_metamako_src_port, {
579 "Source Port", "metamako.src.port",
580 FT_UINT16, BASE_DEC, NULL, 0x0,
581 NULL, HFILL }},
583 { &hf_metamako_fcs, {
584 "Frame check sequence", "metamako.fcs",
585 FT_UINT32, BASE_HEX, NULL, 0x0,
586 "Ethernet checksum", HFILL }},
588 { &hf_metamako_fcs_status, {
589 "FCS Status", "metamako.fcs.status",
590 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
591 NULL, HFILL }},
594 static int* ett[] = {
595 &ett_metamako,
596 &ett_metamako_extensions,
597 &ett_metamako_timestamp,
598 &ett_metamako_flags
601 static ei_register_info ei[] = {
602 { &ei_metamako_fcs_bad, { "metamako.fcs_bad", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
605 module_t* metamako_module;
607 /* Register the Metamako trailer. */
608 proto_metamako = proto_register_protocol("Metamako ethernet trailer", "Metamako", "metamako");
610 /* Register header fields. */
611 proto_register_field_array(proto_metamako, hf, array_length(hf));
613 /* Register subtree types. */
614 proto_register_subtree_array(ett, array_length(ett));
616 /* Register the expert module. */
617 expert_register_field_array(expert_register_protocol(proto_metamako), ei, array_length(ei));
619 /* Register configuration preferences */
620 metamako_module = prefs_register_protocol(proto_metamako, NULL);
622 range_convert_str(wmem_epan_scope(), &metamako_trailer_secs_bounds, TRAILER_SECS_BOUNDS_DFLT, 0xffffffff);
623 prefs_register_range_preference(metamako_module, "secs_bounds",
624 "Heuristic: Bounds of the seconds value in the trailer timestamp",
625 "If the trailer is found using heuristics, then the trailer may or may not be added "
626 "and the FCS may or may not be captured. One of the heuristics is the timestamp seconds "
627 "value being within specified bounds. "
628 "Set ranges of valid seconds to adjust this particular heuristic.",
629 &metamako_trailer_secs_bounds, 0xffffffff);
631 prefs_register_uint_preference(metamako_module, "days_diff_limit",
632 "Heuristic: Max. number of days difference between capture and trailer timestamps",
633 "If the trailer is found using heuristics, then the trailer may or may not be added "
634 "and the FCS may or may not be captured. One of the heuristics is the number of days "
635 "difference between the capture (PCAP) timestamp and the Ethernet trailer timestamp. "
636 "Set an upper bound (in days) to adjust this particular heuristic.",
637 10, &metamako_trailer_days_diff_limit);
639 prefs_register_enum_preference(metamako_module, "trailer_present",
640 "Assume packets have a Metamako trailer",
641 "This option can override the trailer detection heuristic so that the Metamako "
642 "trailer is either never or always present.",
643 &metamako_trailer_present, metamako_trailer_present_vals, false);
645 prefs_register_enum_preference(metamako_module, "fcs",
646 "Assume packets have FCS",
647 "Some Ethernet adapters and drivers include the FCS at the end of a packet, others do not. "
648 "Some capture file formats and protocols do not indicate whether or not the FCS is included. "
649 "The Metamako dissector attempts to guess whether a captured packet has an FCS, "
650 "but it cannot always guess correctly. This option can override that heuristic "
651 "and assume that the FCS is either never or always present.",
652 &metamako_fcs_len, metamako_fcs_vals, false);
654 prefs_register_bool_preference(metamako_module, "check_fcs",
655 "Validate the Ethernet checksum if possible",
656 "Whether to validate the Frame Check Sequence",
657 &metamako_check_fcs);
660 void
661 proto_reg_handoff_metamako(void)
663 heur_dissector_add("eth.trailer", dissect_metamako_heur, "Metamako ethernet trailer", "metamako_eth", proto_metamako, HEURISTIC_DISABLE);
667 * Editor modelines - https://www.wireshark.org/tools/modelines.html
669 * Local Variables:
670 * c-basic-offset: 2
671 * tab-width: 8
672 * indent-tabs-mode: nil
673 * End:
675 * ex: set shiftwidth=2 tabstop=8 expandtab:
676 * :indentSize=2:tabSize=8:noTabs=true: