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
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);
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 +---------------+---------------+---------------+---------------+
55 +---------------+---------------+---------------+---------------+
57 +---------------+---------------+---------------+---------------+
59 +---------------+---------------+---------------+---------------+
61 +---------------+---------------+---------------+---------------+
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},
104 static const enum_val_t metamako_trailer_present_vals
[] = {
105 {"heuristic", "According to heuristic", -1},
106 {"never", "Never", 0},
107 {"always", "Always", 1},
111 static const value_string tfs_pcs49_btf_vals
[] = {
112 { 0x0, "0x33 or 0x66" },
117 static const value_string tfs_orig_fcs_status_vals
[] = {
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
,
133 static expert_field ei_metamako_fcs_bad
;
136 sub_nanos_base_custom(char* result
, uint32_t value
)
139 temp_double
= ((double)value
) / (1ULL << 24);
140 snprintf(result
, ITEM_LABEL_LENGTH
, "%1.9fns", temp_double
);
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
)
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
))
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
)
164 if (pinfo
->abs_ts
.secs
- metamako_time
->secs
> (time_t)metamako_trailer_days_diff_limit
* SECS_IN_ONE_DAY
)
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
;
182 unsigned captured_trailer_bytes
;
183 unsigned metamako_trailer_bytes
;
184 unsigned trailer_min_length
;
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
;
204 /* The Metamako trailer is made up of:
205 4 bytes -- original FCS
206 N bytes -- trailer extensions
208 4 bytes -- nanoseconds
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)
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
238 if (captured_trailer_bytes
< trailer_min_length
)
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.
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
++) {
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;
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)) {
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) {
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? */
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
);
328 proto_tree_add_item(metamako_tree
, hf_metamako_origfcs
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
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
;
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. */
355 /* Skip over the data if this is not our destination. */
357 metamako_tlv_pos
-= (metamako_tlv_len
+ 1) * 4;
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
) {
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));
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));
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));
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);
389 proto_tree_add_item(extensions_tree
, hf_metamako_tagstring
, tvb
, metamako_tlv_pos
+ 4, metamako_tlv_len
* 4, ENC_ASCII
);
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
, "...");
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
--;
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
);
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
);
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
);
438 proto_tree_add_bitmask(metamako_tree
, tvb
, offset
, hf_metamako_flags
, ett_metamako_flags
, flags
, ENC_BIG_ENDIAN
);
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
);
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
);
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]");
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
);
474 dissect_metamako_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
476 return dissect_metamako(tvb
, pinfo
, tree
, data
) > 0;
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,
488 { &hf_metamako_trailerext
, {
489 "Trailer Extensions", "metamako.ext",
490 FT_NONE
, BASE_NONE
, NULL
, 0x0,
493 { &hf_metamako_unknownext
, {
494 "Unknown Tag", "metamako.unknown",
495 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
498 { &hf_metamako_seqnum
, {
499 "Sequence Number", "metamako.seqnum",
500 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
503 { &hf_metamako_fracns
, {
504 "Sub-nanoseconds", "metamako.subns",
505 FT_UINT24
, BASE_CUSTOM
, CF_FUNC(sub_nanos_base_custom
), 0x0,
508 { &hf_metamako_crchash
, {
509 "CRC64 ECMA Hash", "metamako.crchash",
510 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
513 { &hf_metamako_egress_seqnum
, {
514 "Egress Sequence Number", "metamako.egrseqnum",
515 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
518 { &hf_metamako_tagstring
, {
519 "Tag String", "metamako.tagstring",
520 FT_STRING
, BASE_NONE
, NULL
, 0x0,
523 { &hf_metamako_time_abs
, {
524 "Timestamp", "metamako.time.abs",
525 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
528 { &hf_metamako_time_rel
, {
529 "Timestamp", "metamako.time.rel",
530 FT_RELATIVE_TIME
, ENC_BIG_ENDIAN
, NULL
, 0x0,
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,
543 {&hf_metamako_reserved
, {
544 "Reserved", "metamako.reserved",
545 FT_UINT8
, BASE_HEX
, NULL
, 0xC8,
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,
553 {&hf_metamako_flags_ts_degraded
, {
554 "Timestamp degraded", "metamako.flags.ts_degraded",
555 FT_BOOLEAN
, 8, NULL
, 0x10,
558 {&hf_metamako_flags_duplicate
, {
559 "Duplicate Packet", "metamako.flags.is_duplicate",
560 FT_BOOLEAN
, 8, NULL
, 0x04,
563 {&hf_metamako_flags_has_ext
, {
564 "Has Trailer Extensions", "metamako.flags.has_extensions",
565 FT_BOOLEAN
, 8, NULL
, 0x02,
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,
573 { &hf_metamako_src_device
, {
574 "Source Device ID", "metamako.src.device_id",
575 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
578 { &hf_metamako_src_port
, {
579 "Source Port", "metamako.src.port",
580 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
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,
594 static int* ett
[] = {
596 &ett_metamako_extensions
,
597 &ett_metamako_timestamp
,
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
);
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
672 * indent-tabs-mode: nil
675 * ex: set shiftwidth=2 tabstop=8 expandtab:
676 * :indentSize=2:tabSize=8:noTabs=true: