Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-trill.c
blob9a93e02f4d8f98302745661442b8279c372cb368
1 /* packet-trill.c
2 * Routines for TRILL (TRansparent Interconnection of Lots of Links) dissection
3 * Copyright 2010, David Bond <mokon@mokon.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 * See: RFC6325
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/etypes.h>
20 #include <epan/tfs.h>
21 #include <wsutil/array.h>
23 void proto_register_trill(void);
24 void proto_reg_handoff_trill(void);
26 static dissector_handle_t trill_handle;
28 static int proto_trill;
29 static int ett_trill;
31 static int hf_trill_version;
32 static int hf_trill_reserved;
33 static int hf_trill_multi_dst;
34 static int hf_trill_op_len;
35 static int hf_trill_hop_cnt;
36 static int hf_trill_egress_nick;
37 static int hf_trill_ingress_nick;
38 /* TODO For now we will just add all the options into a byte field.
39 Later this should be parsed out into a sub-tree with all the option
40 details. */
41 static int hf_trill_options;
43 static dissector_handle_t eth_dissector ;
45 #define TRILL_VERSION_MASK 0xC000
46 #define TRILL_RESERVED_MASK 0x3000
47 #define TRILL_MULTI_DST_MASK 0x0800
48 #define TRILL_OP_LEN_MASK 0x07C0
49 #define TRILL_HOP_CNT_MASK 0x003F
51 #define TRILL_PROTO_COL_NAME "TRILL"
52 #define TRILL_PROTO_COL_INFO "TRILL Encapsulated Frame"
54 #define TRILL_MIN_FRAME_LENGTH 6
55 #define TRILL_BIT_FIELDS_LEN 2
56 #define TRILL_NICKNAME_LEN 2
57 #define TRILL_OP_LENGTH_BYTE_UNITS 0x4
59 static const true_false_string multi_dst_strings = {
60 "Multi-Destination TRILL Frame",
61 "Known Unicast TRILL Frame"
62 } ;
64 static const range_string version_strings[] = {
65 { 0, 0, "RFC6325 Version" },
66 { 1, 3, "Unallocated Version" },
67 { 0, 0, NULL }
68 } ;
70 static const range_string reserved_strings[] = {
71 { 0, 0, "Legal Value" },
72 { 1, 3, "Illegal Value" },
73 { 0, 0, NULL }
74 } ;
76 static const range_string nickname_strings[] = {
77 { 0x0000, 0x0000, "Nickname Not Specified" },
78 { 0x0001, 0xFFBF, "Valid Nickname" },
79 { 0xFFC0, 0xFFC0, "Any RBridge" },
80 { 0xFFC1, 0xFFC1, "OOMF" },
81 { 0xFFC2, 0xFFFE, "Reserved for Future Specification" },
82 { 0xFFFF, 0xFFFF, "Permanently Reserved" },
83 { 0, 0, NULL }
84 } ;
86 /* Trill Dissector */
87 static int
88 dissect_trill( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
90 proto_item *ti ;
91 proto_tree *trill_tree ;
92 uint32_t op_len ;
93 tvbuff_t *next_tvb ;
94 int offset = 0 ;
96 col_set_str( pinfo->cinfo, COL_PROTOCOL, TRILL_PROTO_COL_NAME ) ;
97 col_set_str( pinfo->cinfo, COL_INFO, TRILL_PROTO_COL_INFO ) ;
99 op_len = tvb_get_bits( tvb, 5, 5, ENC_BIG_ENDIAN ) * TRILL_OP_LENGTH_BYTE_UNITS ;
100 if (tree) {
101 ti = proto_tree_add_item( tree, proto_trill, tvb, 0,
102 TRILL_MIN_FRAME_LENGTH + op_len, ENC_NA ) ;
103 trill_tree = proto_item_add_subtree( ti, ett_trill ) ;
105 /* Parse the bit fields, i.e. V, R, M, Op-Length, Hop Count. */
106 proto_tree_add_item( trill_tree, hf_trill_version, tvb, offset,
107 TRILL_BIT_FIELDS_LEN, ENC_BIG_ENDIAN ) ;
108 proto_tree_add_item( trill_tree, hf_trill_reserved, tvb, offset,
109 TRILL_BIT_FIELDS_LEN, ENC_BIG_ENDIAN ) ;
110 proto_tree_add_item( trill_tree, hf_trill_multi_dst, tvb, offset,
111 TRILL_BIT_FIELDS_LEN, ENC_BIG_ENDIAN ) ;
112 proto_tree_add_item( trill_tree, hf_trill_op_len, tvb, offset,
113 TRILL_BIT_FIELDS_LEN, ENC_BIG_ENDIAN ) ;
114 proto_tree_add_item( trill_tree, hf_trill_hop_cnt, tvb, offset,
115 TRILL_BIT_FIELDS_LEN, ENC_BIG_ENDIAN ) ;
117 /* Parse the egress nickname. */
118 offset += TRILL_BIT_FIELDS_LEN ;
119 proto_tree_add_item( trill_tree, hf_trill_egress_nick, tvb, offset,
120 TRILL_NICKNAME_LEN, ENC_BIG_ENDIAN ) ;
122 /* Parse the ingress nickname. */
123 offset += TRILL_NICKNAME_LEN ;
124 proto_tree_add_item( trill_tree, hf_trill_ingress_nick, tvb, offset,
125 TRILL_NICKNAME_LEN , ENC_BIG_ENDIAN ) ;
127 /* Parse the options field. */
128 offset += TRILL_NICKNAME_LEN ;
129 if( op_len != 0 ) {
130 proto_tree_add_item( trill_tree, hf_trill_options, tvb,
131 offset, op_len, ENC_NA ) ;
135 /* call the eth dissector */
136 next_tvb = tvb_new_subset_remaining( tvb, TRILL_MIN_FRAME_LENGTH + op_len ) ;
137 call_dissector( eth_dissector, next_tvb, pinfo, tree ) ;
139 return tvb_reported_length( tvb ) ;
142 /* Register the protocol with Wireshark */
143 void
144 proto_register_trill(void)
146 static hf_register_info hf[] = {
147 { &hf_trill_version,
148 { "Version", "trill.version",
149 FT_UINT16, BASE_DEC_HEX|BASE_RANGE_STRING, RVALS(version_strings),
150 TRILL_VERSION_MASK, "The TRILL version number.", HFILL }},
151 { &hf_trill_reserved,
152 { "Reserved", "trill.reserved",
153 FT_UINT16, BASE_DEC_HEX|BASE_RANGE_STRING, RVALS(reserved_strings),
154 TRILL_RESERVED_MASK, "Bits reserved for future specification.", HFILL }},
155 { &hf_trill_multi_dst,
156 { "Multi Destination", "trill.multi_dst",
157 FT_BOOLEAN, 16, TFS(&multi_dst_strings), TRILL_MULTI_DST_MASK,
158 "A boolean specifying if this is a multi-destination frame.", HFILL }},
159 { &hf_trill_op_len,
160 { "Option Length", "trill.op_len",
161 FT_UINT16, BASE_DEC_HEX, NULL, TRILL_OP_LEN_MASK,
162 "The length of the options field of this frame.", HFILL }},
163 { &hf_trill_hop_cnt,
164 { "Hop Count", "trill.hop_cnt",
165 FT_UINT16, BASE_DEC_HEX, NULL, TRILL_HOP_CNT_MASK,
166 "The remaining hop count for this frame.", HFILL }},
167 { &hf_trill_egress_nick,
168 { "Egress/Root RBridge Nickname", "trill.egress_nick",
169 FT_UINT16, BASE_DEC_HEX|BASE_RANGE_STRING, RVALS(nickname_strings), 0x0,
170 "The Egress or Distribution Tree Root RBridge Nickname.", HFILL }},
171 { &hf_trill_ingress_nick,
172 { "Ingress RBridge Nickname", "trill.ingress_nick",
173 FT_UINT16, BASE_DEC_HEX|BASE_RANGE_STRING, RVALS(nickname_strings), 0x0,
174 "The Ingress RBridge Nickname.", HFILL }},
175 { &hf_trill_options,
176 { "Options", "trill.options",
177 FT_BYTES, BASE_NONE, NULL, 0x0,
178 "The TRILL Options field.", HFILL }}
181 static int *ett[] = {
182 &ett_trill
185 proto_trill = proto_register_protocol("TRILL", "TRILL", "trill");
186 proto_register_field_array(proto_trill, hf, array_length(hf));
187 proto_register_subtree_array(ett, array_length(ett));
188 trill_handle = register_dissector("trill", dissect_trill, proto_trill);
191 void
192 proto_reg_handoff_trill(void)
194 dissector_add_uint("ethertype", ETHERTYPE_TRILL, trill_handle);
197 * RFC 6325, section 4.1.4 "Frame Check Sequence (FCS)", says
199 * "Thus, when a frame is encapsulated, the original FCS is not
200 * included but is discarded."
202 * meaning that the inner Ethernet frame does *not* include an
203 * FCS.
205 eth_dissector = find_dissector_add_dependency( "eth_withoutfcs", proto_trill );
209 * Editor modelines - https://www.wireshark.org/tools/modelines.html
211 * Local Variables:
212 * c-basic-offset: 2
213 * tab-width: 8
214 * indent-tabs-mode: nil
215 * End:
217 * ex: set shiftwidth=2 tabstop=8 expandtab:
218 * :indentSize=2:tabSize=8:noTabs=true: