2 * Routines for Gigamon header disassembly (modified from packet-vlan.c)
4 * Dissector for Gigamon Header and Trailer
5 * Copyright Gigamon 2010
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 <epan/etypes.h>
18 #include <epan/prefs.h>
19 #include <epan/in_cksum.h>
20 #include <epan/crc32-tvb.h>
21 #include <wsutil/crc32.h>
22 #include <wsutil/pint.h>
23 #include <epan/expert.h>
25 #include "packet-ieee8023.h"
27 void proto_register_gmhdr(void);
28 void proto_reg_handoff_gmhdr(void);
30 static dissector_handle_t gmhdr_handle
;
32 #define GMHDR_FTYPE_PKTSIZE 1
33 #define GMHDR_FTYPE_SRCPORT_G 2
34 #define GMHDR_FTYPE_TIMESTAMP_LOCAL 3
35 #define GMHDR_FTYPE_TIMESTAMP_NTP 4
36 #define GMHDR_FTYPE_TIMESTAMP_GPS 5
37 #define GMHDR_FTYPE_TIMESTAMP_1588 6
38 #define GMHDR_FTYPE_FCS 7
39 #define GMHDR_FTYPE_SRCPORT_H 8
41 static const value_string gmhdr_ftype_timestamp
[] = {
42 { GMHDR_FTYPE_TIMESTAMP_LOCAL
, "Local" },
43 { GMHDR_FTYPE_TIMESTAMP_NTP
, "NTP" },
44 { GMHDR_FTYPE_TIMESTAMP_GPS
, "GPS" },
45 { GMHDR_FTYPE_TIMESTAMP_1588
, "1588" },
49 #define GMHDR_SRCPORT_G_PLFM_MASK 0xf80000
50 #define GMHDR_SRCPORT_G_GID_MASK 0x078000
51 #define GMHDR_SRCPORT_G_BID_MASK 0x007c00
52 #define GMHDR_SRCPORT_G_PID_MASK 0x0003ff
53 #define GMHDR_SRCPORT_G_PLFM_SHFT 19
54 #define GMHDR_SRCPORT_G_GID_SHFT 15
55 #define GMHDR_SRCPORT_G_BID_SHFT 10
56 #define GMHDR_SRCPORT_G_PID_SHFT 0
58 #define GMHDR_SRCPORT_H_PLFM_MASK 0xFC000000
59 #define GMHDR_SRCPORT_H_GID_MASK 0x03C00000
60 #define GMHDR_SRCPORT_H_BID_MASK 0x003F0000
61 #define GMHDR_SRCPORT_H_SID_MASK 0x0000FC00
62 #define GMHDR_SRCPORT_H_PID_MASK 0x000003FF
63 #define GMHDR_SRCPORT_H_PLFM_SHFT 26
64 #define GMHDR_SRCPORT_H_GID_SHFT 20
65 #define GMHDR_SRCPORT_H_BID_SHFT 16
66 #define GMHDR_SRCPORT_H_SID_SHFT 10
67 #define GMHDR_SRCPORT_H_PID_SHFT 0
69 static const value_string gmhdr_plfm_str
[] = {
90 static dissector_handle_t ethertype_handle
;
92 static bool gmhdr_summary_in_tree
= true;
93 static bool gmtrailer_summary_in_tree
= true;
94 static bool gmhdr_decode_timestamp_trailer
= true;
96 static int proto_gmhdr
;
97 static int proto_gmtrailer
;
98 static int hf_gmhdr_srcport_g
;
99 static int hf_gmhdr_srcport_g_plfm
;
100 static int hf_gmhdr_srcport_g_gid
;
101 static int hf_gmhdr_srcport_g_bid
;
102 static int hf_gmhdr_srcport_g_pid
;
103 static int hf_gmhdr_pktsize
;
104 static int hf_gmhdr_timestamp
;
105 static int hf_gmhdr_generic
;
106 static int hf_gmhdr_etype
;
107 static int hf_gmhdr_len
;
108 static int hf_gmhdr_trailer
;
109 static int hf_gmhdr_origcrc
;
110 static int hf_gmhdr_srcport_h
;
111 static int hf_gmhdr_srcport_h_plfm
;
112 static int hf_gmhdr_srcport_h_gid
;
113 static int hf_gmhdr_srcport_h_bid
;
114 static int hf_gmhdr_srcport_h_sid
;
115 static int hf_gmhdr_srcport_h_pid
;
117 static int hf_gmtrailer_origcrc
;
118 static int hf_gmtrailer_portid
;
119 static int hf_gmtrailer_timestamp
;
121 static int ett_gmhdr
;
122 static int ett_srcport
;
123 static int ett_gmtrailer
;
125 static expert_field ei_gmhdr_field_length_invalid
;
126 static expert_field ei_gmhdr_len
;
129 dissect_gmtlv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*gmhdr_tree
, unsigned offset
, uint16_t length
)
132 proto_tree
*srcport_tree
;
136 uint16_t tl
= tvb_get_ntohs(tvb
, offset
);
137 offset
+= 2; /* type + len */
142 case GMHDR_FTYPE_SRCPORT_G
: {
144 uint32_t tv
= tvb_get_ntohl(tvb
, offset
) >> 8; /* Only 24-bit field */
147 expert_add_info_format(pinfo
, gmhdr_tree
, &ei_gmhdr_field_length_invalid
, "Field length %u invalid", fl
);
150 ti
= proto_tree_add_item(gmhdr_tree
, hf_gmhdr_srcport_g
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
151 srcport_tree
= proto_item_add_subtree(ti
, ett_srcport
);
152 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_g_plfm
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
153 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_g_gid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
154 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_g_bid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
155 ti
= proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_g_pid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
156 /* If not GV-2404, we need different formula here */
157 pid
= ((tv
& GMHDR_SRCPORT_G_PID_MASK
) >> GMHDR_SRCPORT_G_PID_SHFT
) - 24;
158 if (pid
>= 1 && pid
<= 4) {
159 proto_item_append_text(ti
, " (g%d)", pid
);
163 case GMHDR_FTYPE_PKTSIZE
:
165 expert_add_info_format(pinfo
, gmhdr_tree
, &ei_gmhdr_field_length_invalid
, "Field length %u invalid", fl
);
168 proto_tree_add_item(gmhdr_tree
, hf_gmhdr_pktsize
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
170 case GMHDR_FTYPE_TIMESTAMP_LOCAL
:
171 case GMHDR_FTYPE_TIMESTAMP_NTP
:
172 case GMHDR_FTYPE_TIMESTAMP_GPS
:
173 case GMHDR_FTYPE_TIMESTAMP_1588
:
175 expert_add_info_format(pinfo
, gmhdr_tree
, &ei_gmhdr_field_length_invalid
, "Field length %u invalid", fl
);
178 ti
= proto_tree_add_item(gmhdr_tree
, hf_gmhdr_timestamp
, tvb
, offset
, fl
, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
179 proto_item_append_text(ti
, "; Source: %s", val_to_str_const(tl
>>8, gmhdr_ftype_timestamp
, "Unknown"));
181 case GMHDR_FTYPE_FCS
: {
183 expert_add_info_format(pinfo
, gmhdr_tree
, &ei_gmhdr_field_length_invalid
, "Field length %u invalid", fl
);
186 ti
= proto_tree_add_item(gmhdr_tree
, hf_gmhdr_origcrc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
187 proto_item_append_text(ti
, ", CRC (Not Verified)");
190 case GMHDR_FTYPE_SRCPORT_H
: {
192 expert_add_info_format(pinfo
, gmhdr_tree
, &ei_gmhdr_field_length_invalid
, "Field length %u invalid", fl
);
195 ti
= proto_tree_add_item(gmhdr_tree
, hf_gmhdr_srcport_h
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
196 srcport_tree
= proto_item_add_subtree(ti
, ett_srcport
);
197 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_h_plfm
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
198 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_h_gid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
199 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_h_bid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
200 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_h_sid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
201 proto_tree_add_item(srcport_tree
, hf_gmhdr_srcport_h_pid
, tvb
, offset
, fl
, ENC_BIG_ENDIAN
);
205 ti
= proto_tree_add_item(gmhdr_tree
, hf_gmhdr_generic
, tvb
, offset
, fl
, ENC_NA
);
206 proto_item_append_text(ti
, " [Id: %u, Length: %u]", tl
>> 8, fl
);
209 /* Adjust for the field length */
218 dissect_gmhdr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
222 uint16_t encap_proto
;
224 proto_tree
*gmhdr_tree
= NULL
;
227 length
= tvb_get_uint8(tvb
, offset
); /* Length of the Gigamon header */
230 ti
= proto_tree_add_item(tree
, proto_gmhdr
, tvb
, offset
, length
, ENC_NA
);
232 if (gmhdr_summary_in_tree
) {
233 proto_item_append_text(ti
, ", Length: %u", length
);
236 gmhdr_tree
= proto_item_add_subtree(ti
, ett_gmhdr
);
237 dissect_gmtlv(tvb
, pinfo
, gmhdr_tree
, offset
+1, length
-1);
242 encap_proto
= tvb_get_ntohs(tvb
, offset
);
244 if (encap_proto
<= IEEE_802_3_MAX_LEN
) {
245 /* Is there an 802.2 layer? I can tell by looking at the first 2
246 bytes after the GMHDR header. If they are 0xffff, then what
247 follows the GMHDR header is an IPX payload, meaning no 802.2.
248 (IPX/SPX is they only thing that can be contained inside a
249 straight 802.3 packet, so presumably the same applies for
250 Ethernet GMHDR packets). A non-0xffff value means that there's an
251 802.2 layer inside the GMHDR layer */
254 /* Don't throw an exception for this check (even a BoundsError) */
255 if (tvb_captured_length_remaining(tvb
, offset
) >= 2) {
256 if (tvb_get_ntohs(tvb
, offset
) == 0xffff) {
261 dissect_802_3(encap_proto
, is_802_2
, tvb
, offset
, pinfo
, tree
, gmhdr_tree
,
262 hf_gmhdr_len
, hf_gmhdr_trailer
, &ei_gmhdr_len
, 0);
264 ethertype_data_t ethertype_data
;
266 proto_tree_add_uint(gmhdr_tree
, hf_gmhdr_etype
, tvb
, offset
- 2, 2,
269 ethertype_data
.etype
= encap_proto
;
270 ethertype_data
.payload_offset
= offset
;
271 ethertype_data
.fh_tree
= gmhdr_tree
;
272 ethertype_data
.trailer_id
= hf_gmhdr_trailer
;
273 ethertype_data
.fcs_len
= 0;
275 call_dissector_with_data(ethertype_handle
, tvb
, pinfo
, tree
, ðertype_data
);
277 return tvb_captured_length(tvb
);
281 dissect_gmtimestamp_trailer(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void *data _U_
)
284 unsigned tvblen
, trailer_len
= 18;
285 proto_tree
*gmtrailer_tree
= NULL
;
287 uint32_t orig_crc
, new_crc
, comp_crc
;
291 struct tm
*tm
= NULL
;
293 if ( ! gmhdr_decode_timestamp_trailer
)
296 /* See if this packet has a Gigamon trailer, if yes, then decode it */
297 /* (Don't throw any exceptions while checking for the trailer). */
298 tvblen
= tvb_captured_length(tvb
); /* end+1 */
299 if (tvblen
< trailer_len
)
302 orig_crc
= tvb_get_ntohl(tvb
, offset
);
303 new_crc
= tvb_get_ntohl(tvb
, tvblen
- 4);
305 /* Verify the checksum; if not valid, it means that the trailer is not valid */
306 comp_crc
= CRC32C_SWAP(crc32_ccitt_tvb_seed(tvb
, 14, CRC32C_SWAP(~orig_crc
)));
307 if (comp_crc
!= new_crc
)
310 /* OK: We appear to have a Gigamon trailer */
312 ti
= proto_tree_add_item(tree
, proto_gmtrailer
, tvb
, offset
, trailer_len
- 4, ENC_NA
);
314 if (gmtrailer_summary_in_tree
) {
316 port_num
= tvb_get_ntohs(tvb
, offset
);
317 proto_item_append_text(ti
, ", Port: %d, Timestamp: ", port_num
);
320 gmtimev
.secs
= tvb_get_ntohl(tvb
, offset
);
322 gmtimev
.nsecs
= tvb_get_ntohl(tvb
, offset
);
324 tm
= localtime(&gmtimev
.secs
);
326 proto_item_append_text(ti
, "%d:%02d:%02d.%09d", tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
, gmtimev
.nsecs
);
328 proto_item_append_text(ti
, "<Not representable>");
332 gmtrailer_tree
= proto_item_add_subtree(ti
, ett_gmtrailer
);
333 proto_tree_add_item(gmtrailer_tree
, hf_gmtrailer_origcrc
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
334 proto_tree_add_item(gmtrailer_tree
, hf_gmtrailer_portid
, tvb
, offset
+4, 2, ENC_BIG_ENDIAN
);
335 proto_tree_add_item(gmtrailer_tree
, hf_gmtrailer_timestamp
, tvb
, offset
+6, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
342 dissect_gmtimestamp_trailer_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
344 return dissect_gmtimestamp_trailer(tvb
, pinfo
, tree
, data
) > 0;
348 dissect_gmtrailer(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
351 unsigned tvblen
, length
;
352 proto_tree
*gmhdr_tree
= NULL
;
354 uint16_t cksum
, comp_cksum
, extra_trailer
;
356 /* See if this packet has a Gigamon trailer, if yes, then decode it */
357 /* (Don't throw any exceptions while checking for the trailer). */
358 tvblen
= tvb_captured_length(tvb
); /* end+1 */
362 if (tvb_get_ntohs(tvb
, tvblen
-4) != ETHERTYPE_GIGAMON
) {
366 if (tvb_get_ntohs(tvb
, tvblen
-8) == ETHERTYPE_GIGAMON
) {
372 length
= tvb_get_uint8(tvb
, tvblen
-extra_trailer
-5); /* length of Gigamon header */
373 if ((tvblen
-extra_trailer
-5) != length
)
376 offset
= tvblen
- extra_trailer
- 5 - length
;
378 cksum
= tvb_get_ntohs(tvb
, tvblen
-extra_trailer
-2);
380 /* Verify the checksum; if not valid, it means that the trailer is not valid */
384 SET_CKSUM_VEC_TVB(vec
, tvb
, offset
, length
+ 3);
386 comp_cksum
= in_cksum(&vec
, 1);
387 if (pntoh16(&comp_cksum
) != cksum
) {
392 /* OK: We appear to have a Gigamon trailer */
394 ti
= proto_tree_add_item(tree
, proto_gmhdr
, tvb
, offset
, length
+ 5, ENC_NA
);
396 if (gmhdr_summary_in_tree
) {
397 proto_item_append_text(ti
, ", Length: %u, Checksum: 0x%x", length
, cksum
);
400 gmhdr_tree
= proto_item_add_subtree(ti
, ett_gmhdr
);
402 dissect_gmtlv(tvb
, pinfo
, gmhdr_tree
, offset
, length
);
404 proto_tree_add_item(tree
, hf_gmhdr_trailer
, tvb
, length
+ 5, extra_trailer
, ENC_NA
);
411 dissect_gmtrailer_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
413 return dissect_gmtrailer(tvb
, pinfo
, tree
, data
) > 0;
417 proto_register_gmhdr(void)
419 static hf_register_info hf
[] = {
420 { &hf_gmhdr_srcport_g
, {
421 "Src Port", "gmhdr.srcport_g", FT_UINT24
, BASE_HEX
,
422 NULL
, 0, "Original Source Port", HFILL
}},
423 { &hf_gmhdr_srcport_g_plfm
, {
424 "Platform Id", "gmhdr.srcport_g_plfm", FT_UINT24
, BASE_DEC
,
425 VALS(gmhdr_plfm_str
), GMHDR_SRCPORT_G_PLFM_MASK
, "Original Platform Id", HFILL
}},
426 { &hf_gmhdr_srcport_g_gid
, {
427 "Group Id", "gmhdr.srcport_g_gid", FT_UINT24
, BASE_DEC
,
428 NULL
, GMHDR_SRCPORT_G_GID_MASK
, "Original Source Group Id", HFILL
}},
429 { &hf_gmhdr_srcport_g_bid
, {
430 "Box Id", "gmhdr.srcport_g_bid", FT_UINT24
, BASE_DEC
,
431 NULL
, GMHDR_SRCPORT_G_BID_MASK
, "Original Source Box Id", HFILL
}},
432 { &hf_gmhdr_srcport_g_pid
, {
433 "Port Id", "gmhdr.srcport_g_pid", FT_UINT24
, BASE_DEC
,
434 NULL
, GMHDR_SRCPORT_G_PID_MASK
, "Original Source Port Id", HFILL
}},
435 { &hf_gmhdr_pktsize
, {
436 "Original Packet Size", "gmhdr.pktsize", FT_UINT16
, BASE_DEC
,
437 NULL
, 0, NULL
, HFILL
}},
438 { &hf_gmhdr_timestamp
, {
439 "Time Stamp", "gmhdr.timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
440 NULL
, 0x0, NULL
, HFILL
}},
441 { &hf_gmhdr_generic
, {
442 "Generic Field", "gmhdr.generic", FT_BYTES
, BASE_NONE
,
443 NULL
, 0x0, NULL
, HFILL
}},
445 "Type", "gmhdr.etype", FT_UINT16
, BASE_HEX
,
446 VALS(etype_vals
), 0x0, "Ethertype", HFILL
}},
448 "Length", "gmhdr.len", FT_UINT16
, BASE_DEC
,
449 NULL
, 0x0, NULL
, HFILL
}},
450 { &hf_gmhdr_origcrc
, {
451 "Original CRC", "gmhdr.crc", FT_UINT32
, BASE_HEX
,
452 NULL
, 0x0, "Original Packet CRC", HFILL
}},
453 { &hf_gmhdr_srcport_h
, {
454 "Src Port", "gmhdr.srcport", FT_UINT32
, BASE_HEX
,
455 NULL
, 0, "Original Source Port", HFILL
}},
456 { &hf_gmhdr_srcport_h_plfm
, {
457 "Platform Id", "gmhdr.srcport_plfm", FT_UINT32
, BASE_DEC
,
458 VALS(gmhdr_plfm_str
), GMHDR_SRCPORT_H_PLFM_MASK
, "Original Platform Id", HFILL
}},
459 { &hf_gmhdr_srcport_h_gid
, {
460 "Group Id", "gmhdr.srcport_gid", FT_UINT32
, BASE_DEC
,
461 NULL
, GMHDR_SRCPORT_H_GID_MASK
, "Original Source Group Id", HFILL
}},
462 { &hf_gmhdr_srcport_h_bid
, {
463 "Box Id", "gmhdr.srcport_bid", FT_UINT32
, BASE_DEC
,
464 NULL
, GMHDR_SRCPORT_H_BID_MASK
, "Original Source Box Id", HFILL
}},
465 { &hf_gmhdr_srcport_h_sid
, {
466 "Slot Id", "gmhdr.srcport_sid", FT_UINT32
, BASE_DEC
,
467 NULL
, GMHDR_SRCPORT_H_SID_MASK
, "Original Source Slot Id", HFILL
}},
468 { &hf_gmhdr_srcport_h_pid
, {
469 "Port Id", "gmhdr.srcport_pid", FT_UINT32
, BASE_DEC
,
470 NULL
, GMHDR_SRCPORT_H_PID_MASK
, "Original Source Port Id", HFILL
}},
471 { &hf_gmhdr_trailer
, {
472 "Trailer", "gmhdr.trailer", FT_BYTES
, BASE_NONE
,
473 NULL
, 0x0, "GMHDR Trailer", HFILL
}},
475 static hf_register_info gmtrailer_hf
[] = {
476 { &hf_gmtrailer_origcrc
, {
477 "Original CRC", "gmtrailer.crc", FT_UINT32
, BASE_HEX
,
478 NULL
, 0x0, "Original Packet CRC", HFILL
}},
479 { &hf_gmtrailer_portid
, {
480 "Src Port", "gmtrailer.portid", FT_UINT16
, BASE_HEX
,
481 NULL
, 0x0, "Origin Source Port", HFILL
}},
482 { &hf_gmtrailer_timestamp
, {
483 "Time Stamp", "gmtrailer.timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
,
484 NULL
, 0x0, NULL
, HFILL
}},
486 static int *ett
[] = {
490 static int *gmtrailer_ett
[] = {
493 static ei_register_info ei
[] = {
494 { &ei_gmhdr_field_length_invalid
, { "gmhdr.field_length_invalid", PI_MALFORMED
, PI_ERROR
, "Field length invalid", EXPFILL
}},
495 { &ei_gmhdr_len
, { "gmhdr.len.past_end", PI_MALFORMED
, PI_ERROR
, "Length field value goes past the end of the payload", EXPFILL
}},
498 module_t
*gmhdr_module
;
499 module_t
*gmtrailer_module
;
500 expert_module_t
* expert_gmhdr
;
502 proto_gmhdr
= proto_register_protocol("Gigamon Header", "GMHDR", "gmhdr");
503 proto_register_field_array(proto_gmhdr
, hf
, array_length(hf
));
504 proto_register_subtree_array(ett
, array_length(ett
));
505 expert_gmhdr
= expert_register_protocol(proto_gmhdr
);
506 expert_register_field_array(expert_gmhdr
, ei
, array_length(ei
));
507 gmhdr_handle
= register_dissector("gmhdr", dissect_gmhdr
, proto_gmhdr
);
509 proto_gmtrailer
= proto_register_protocol("Gigamon Trailer", "GMTRAILER", "gmtrailer");
510 proto_register_field_array(proto_gmtrailer
, gmtrailer_hf
, array_length(gmtrailer_hf
));
511 proto_register_subtree_array(gmtrailer_ett
, array_length(gmtrailer_ett
));
513 gmhdr_module
= prefs_register_protocol(proto_gmhdr
, NULL
);
514 prefs_register_bool_preference(gmhdr_module
, "summary_in_tree",
515 "Show Gigamon header summary in protocol tree",
516 "Whether the Gigamon header summary line should be shown in the protocol tree",
517 &gmhdr_summary_in_tree
);
519 gmtrailer_module
= prefs_register_protocol(proto_gmtrailer
, NULL
);
520 prefs_register_bool_preference(gmtrailer_module
, "summary_in_tree",
521 "Show Gigamon Trailer summary in protocol tree",
522 "Whether the Gigamon Trailer summary line should be shown in the protocol tree",
523 &gmtrailer_summary_in_tree
);
524 prefs_register_bool_preference(gmtrailer_module
, "decode_trailer_timestamp",
525 "Decode Gigamon HW timestamp and source id in trailer",
526 "Whether the Gigamon trailer containing HW timestamp, source id and original CRC should be decoded",
527 &gmhdr_decode_timestamp_trailer
);
531 proto_reg_handoff_gmhdr(void)
533 ethertype_handle
= find_dissector_add_dependency("ethertype", proto_gmhdr
);
535 dissector_add_uint("ethertype", ETHERTYPE_GIGAMON
, gmhdr_handle
);
536 heur_dissector_add("eth.trailer", dissect_gmtrailer_heur
, "Gigamon Ethernet header", "gmhdr_eth", proto_gmhdr
, HEURISTIC_ENABLE
);
538 heur_dissector_add("eth.trailer", dissect_gmtimestamp_trailer_heur
, "Gigamon Ethernet trailer", "gmtrailer_eth", proto_gmtrailer
, HEURISTIC_ENABLE
);
542 * Editor modelines - https://www.wireshark.org/tools/modelines.html
547 * indent-tabs-mode: nil
550 * ex: set shiftwidth=2 tabstop=8 expandtab:
551 * :indentSize=2:tabSize=8:noTabs=true: