Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-bier.c
blobf4ba0df1b3da37ff778eb8cd40f7c64a1ae362b0
1 /* @file
2 * Routines for Bit Index Explicit Replication (BIER) dissection
4 * Copyright 2024, John Thacker <johnthacker@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * RFC 8296: https://www.rfc-editor.org/rfc/rfc8296.html
15 #include "config.h"
17 #include <epan/packet.h>
19 void proto_register_bier(void);
20 void proto_reg_handoff_bier(void);
22 static int proto_bier;
24 static int hf_bier_nibble;
25 static int hf_bier_ver;
26 static int hf_bier_bsl;
27 static int hf_bier_entropy;
28 static int hf_bier_oam;
29 static int hf_bier_rsv;
30 static int hf_bier_dscp;
31 static int hf_bier_proto;
32 static int hf_bier_bfir_id;
33 static int hf_bier_bitstring;
35 static int ett_bier;
37 static dissector_table_t bier_subdissector_table;
39 static dissector_handle_t bier_handle;
41 static const value_string bier_bsl_vals[] = {
42 { 1, "64 bits" },
43 { 2, "128 bits" },
44 { 3, "256 bits" },
45 { 4, "512 bits" },
46 { 5, "1024 bits" },
47 { 6, "2048 bits" },
48 { 7, "4096 bits" },
49 { 0, NULL }
52 // https://www.iana.org/assignments/bier/bier.xhtml#bier-next-protocol-identifiers
53 static const value_string bier_proto_vals[] = {
54 { 0, "Reserved" },
55 { 1, "MPLS packet with downstream-assigned label at top of stack" },
56 { 2, "MPLS packet with upstream-assigned label at top of stack" },
57 { 3, "Ethernet frame" },
58 { 4, "IPv4 packet" },
59 { 5, "OAM packet" },
60 { 6, "IPv6 packet" },
61 { 7, "Payload is VXLAN encapsulated (no IP/UDP header)" },
62 { 8, "Payload is NVGRE encapsulated (no IP header)" },
63 { 9, "Payload is GENEVE encapsulated (no IP/UDP header)" },
64 { 63, "Reserved" },
65 { 0, NULL }
68 static int
69 dissect_bier(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
71 proto_item *ti;
72 proto_tree *bier_tree;
74 unsigned offset = 0;
75 uint32_t proto;
76 tvbuff_t *next_tvb;
78 if (tvb_reported_length(tvb) < 16) {
79 return 0;
82 if (tvb_captured_length(tvb) < 2) {
83 return 0;
86 /* This nibble is ignored in non-MPLS */
87 if (((tvb_get_uint8(tvb, 0) >> 4) & 0xF) != 0x5) {
88 return 0;
91 uint8_t bsl = (tvb_get_uint8(tvb, 1) >> 4) & 0xF;
92 if (bsl == 0 || bsl > 7) {
93 return 0;
96 int bitstring_length = 1 << (bsl + 2);
98 if (tvb_reported_length_remaining(tvb, 8) < bitstring_length) {
99 return 0;
102 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BIER");
103 col_clear(pinfo->cinfo, COL_INFO);
105 ti = proto_tree_add_item(tree, proto_bier, tvb, offset, 8 + bitstring_length, ENC_NA);
107 bier_tree = proto_item_add_subtree(ti, ett_bier);
109 proto_tree_add_item(bier_tree, hf_bier_nibble, tvb, offset, 1, ENC_NA);
110 proto_tree_add_item(bier_tree, hf_bier_ver, tvb, offset, 1, ENC_NA);
111 offset += 1;
113 proto_tree_add_item(bier_tree, hf_bier_bsl, tvb, offset, 1, ENC_NA);
114 proto_tree_add_item(bier_tree, hf_bier_entropy, tvb, offset, 3, ENC_BIG_ENDIAN);
115 offset += 3;
117 proto_tree_add_item(bier_tree, hf_bier_oam, tvb, offset, 1, ENC_NA);
118 proto_tree_add_item(bier_tree, hf_bier_rsv, tvb, offset, 1, ENC_NA);
119 /* DSCP field unused in MPLS; may be as IP DSCP in non-MPLS. */
120 proto_tree_add_item(bier_tree, hf_bier_dscp, tvb, offset, 2, ENC_BIG_ENDIAN);
121 offset += 1;
123 proto_tree_add_item_ret_uint(bier_tree, hf_bier_proto, tvb, offset, 1, ENC_NA, &proto);
124 col_add_str(pinfo->cinfo, COL_INFO, val_to_str_wmem(pinfo->pool, proto, bier_proto_vals, "Unknown (0x%02x)"));
125 offset += 1;
127 proto_tree_add_item(bier_tree, hf_bier_bfir_id, tvb, offset, 2, ENC_BIG_ENDIAN);
128 offset += 2;
130 proto_tree_add_item(bier_tree, hf_bier_bitstring, tvb, offset, bitstring_length, ENC_NA);
131 offset += bitstring_length;
133 next_tvb = tvb_new_subset_remaining(tvb, offset);
134 if (!dissector_try_uint(bier_subdissector_table, proto, next_tvb, pinfo, tree)) {
135 call_data_dissector(next_tvb, pinfo, tree);
138 return tvb_captured_length(tvb);
141 void
142 proto_register_bier(void)
144 static hf_register_info hf[] = {
146 &hf_bier_nibble,
148 "Nibble", "bier.nibble", FT_UINT8,
149 BASE_HEX, NULL, 0xF0, NULL, HFILL
153 &hf_bier_ver,
155 "Version", "bier.ver", FT_UINT8,
156 BASE_DEC, NULL, 0x0F, NULL, HFILL
160 &hf_bier_bsl,
162 "BitString Length", "bier.bsl", FT_UINT8,
163 BASE_DEC, VALS(bier_bsl_vals), 0xF0, NULL, HFILL
167 &hf_bier_entropy,
169 "Entropy", "bier.entropy", FT_UINT24,
170 BASE_HEX, NULL, 0x0FFFFF, NULL, HFILL
174 &hf_bier_oam,
176 "OAM", "bier.oam", FT_UINT8,
177 BASE_HEX, NULL, 0xC0, NULL, HFILL
181 &hf_bier_rsv,
183 "Rsv", "bier.rsv", FT_UINT8,
184 BASE_HEX, NULL, 0x30, NULL, HFILL
188 &hf_bier_dscp,
190 "DSCP", "bier.dscp", FT_UINT16,
191 BASE_HEX, NULL, 0x0FC0, NULL, HFILL
195 &hf_bier_proto,
197 "Next Protocol", "bier.proto", FT_UINT8,
198 BASE_HEX, VALS(bier_proto_vals), 0x3F, NULL, HFILL
202 &hf_bier_bfir_id,
204 "BFIR-id", "bier.bfir-id", FT_UINT16,
205 BASE_DEC, NULL, 0x0, NULL, HFILL
209 &hf_bier_bitstring,
211 "BitString", "bier.bitstring", FT_BYTES,
212 BASE_NONE, NULL, 0x0, NULL, HFILL
217 static int *ett[] = {
218 &ett_bier
221 proto_bier =
222 proto_register_protocol("Bit Index Explicit Replication", "BIER", "bier");
224 proto_register_field_array(proto_bier, hf, array_length(hf));
225 proto_register_subtree_array(ett, array_length(ett));
226 bier_handle = register_dissector_with_description("bier.mpls", "BIER encapsulated in MPLS", dissect_bier, proto_bier);
228 bier_subdissector_table = register_dissector_table("bier.proto",
229 "BIER Next Protocol", proto_bier, FT_UINT8, BASE_DEC);
232 void
233 proto_reg_handoff_bier(void)
235 dissector_handle_t mpls_handle = find_dissector_add_dependency("mpls", proto_bier);
237 dissector_add_for_decode_as("mpls.label", bier_handle);
239 dissector_add_uint("mpls.pfn", 5, bier_handle);
241 dissector_add_uint("bier.proto", 1, mpls_handle);
242 dissector_add_uint("bier.proto", 2, mpls_handle);
243 dissector_add_uint("bier.proto", 3, find_dissector_add_dependency("eth_maybefcs", proto_bier));
244 dissector_add_uint("bier.proto", 4, find_dissector_add_dependency("ip", proto_bier));
245 /* 5 is BIER OAM - https://datatracker.ietf.org/doc/draft-ietf-bier-ping/ */
246 dissector_add_uint("bier.proto", 6, find_dissector_add_dependency("ipv6", proto_bier));
247 dissector_add_uint("bier.proto", 7, find_dissector_add_dependency("vxlan", proto_bier));
248 dissector_add_uint("bier.proto", 8, find_dissector_add_dependency("gre", proto_bier));
249 dissector_add_uint("bier.proto", 9, find_dissector_add_dependency("geneve", proto_bier));