/src/wireshark/epan/dissectors/packet-isis.c
Line | Count | Source |
1 | | /* packet-isis.c |
2 | | * Routines for ISO/OSI network and transport protocol packet disassembly, core |
3 | | * bits. |
4 | | * |
5 | | * Stuart Stanley <stuarts@mxmail.net> |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1998 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | #include "config.h" |
15 | | |
16 | | #include <epan/packet.h> |
17 | | #include <epan/expert.h> |
18 | | #include <epan/etypes.h> |
19 | | #include "packet-osi.h" |
20 | | #include "packet-isis.h" |
21 | | |
22 | | void proto_register_isis(void); |
23 | | void proto_reg_handoff_isis(void); |
24 | | |
25 | | static dissector_table_t isis_dissector_table; |
26 | | |
27 | | /* isis base header */ |
28 | | static int proto_isis; |
29 | | |
30 | | static int hf_isis_irpd; |
31 | | static int hf_isis_header_length; |
32 | | static int hf_isis_version; |
33 | | static int hf_isis_system_id_length; |
34 | | static int hf_isis_type; |
35 | | static int hf_isis_type_reserved; |
36 | | static int hf_isis_version2; |
37 | | static int hf_isis_reserved; |
38 | | static int hf_isis_max_area_adr; |
39 | | int hf_isis_clv_key_id; |
40 | | |
41 | | static int ett_isis; |
42 | | |
43 | | static expert_field ei_isis_length_indicator_too_small; |
44 | | static expert_field ei_isis_version; |
45 | | static expert_field ei_isis_version2; |
46 | | static expert_field ei_isis_reserved; |
47 | | static expert_field ei_isis_type; |
48 | | |
49 | | static dissector_handle_t isis_handle; |
50 | | |
51 | | static const value_string isis_vals[] = { |
52 | | { ISIS_TYPE_L1_HELLO, "L1 HELLO"}, |
53 | | { ISIS_TYPE_L2_HELLO, "L2 HELLO"}, |
54 | | { ISIS_TYPE_PTP_HELLO, "P2P HELLO"}, |
55 | | { ISIS_TYPE_L1_LSP, "L1 LSP"}, |
56 | | { ISIS_TYPE_L2_LSP, "L2 LSP"}, |
57 | | { ISIS_TYPE_L1_CSNP, "L1 CSNP"}, |
58 | | { ISIS_TYPE_L2_CSNP, "L2 CSNP"}, |
59 | | { ISIS_TYPE_L1_PSNP, "L1 PSNP"}, |
60 | | { ISIS_TYPE_L2_PSNP, "L2 PSNP"}, |
61 | | { 0, NULL} |
62 | | }; |
63 | | |
64 | | static int |
65 | | dissect_isis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
66 | 2.01k | { |
67 | 2.01k | proto_item *ti, *version_item, *version2_item, *reserved_item; |
68 | 2.01k | proto_tree *isis_tree = NULL; |
69 | 2.01k | unsigned offset = 0; |
70 | 2.01k | uint8_t isis_version, isis_version2, isis_reserved; |
71 | 2.01k | uint8_t isis_type; |
72 | 2.01k | isis_data_t subdissector_data; |
73 | | |
74 | 2.01k | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS"); |
75 | 2.01k | col_clear(pinfo->cinfo, COL_INFO); |
76 | | |
77 | 2.01k | ti = proto_tree_add_item(tree, proto_isis, tvb, 0, -1, ENC_NA); |
78 | 2.01k | isis_tree = proto_item_add_subtree(ti, ett_isis); |
79 | | |
80 | 2.01k | proto_tree_add_item(isis_tree, hf_isis_irpd, tvb, offset, 1, ENC_BIG_ENDIAN ); |
81 | 2.01k | offset += 1; |
82 | | |
83 | 2.01k | subdissector_data.header_length = tvb_get_uint8(tvb, offset); |
84 | 2.01k | subdissector_data.header_length_item = |
85 | 2.01k | proto_tree_add_uint(isis_tree, hf_isis_header_length, tvb, |
86 | 2.01k | offset, 1, subdissector_data.header_length ); |
87 | 2.01k | offset += 1; |
88 | 2.01k | if (subdissector_data.header_length < 8) { |
89 | | /* Not large enough to include the part of the header that |
90 | | we dissect here. */ |
91 | 5 | expert_add_info(pinfo, subdissector_data.header_length_item, &ei_isis_length_indicator_too_small); |
92 | 5 | return tvb_captured_length(tvb); |
93 | 5 | } |
94 | 2.01k | subdissector_data.ei_bad_header_length = &ei_isis_length_indicator_too_small; |
95 | | |
96 | 2.01k | version_item = proto_tree_add_item_ret_uint8(isis_tree, hf_isis_version, tvb, |
97 | 2.01k | offset, 1, ENC_NA, &isis_version ); |
98 | 2.01k | if (isis_version != ISIS_REQUIRED_VERSION){ |
99 | 2.01k | expert_add_info(pinfo, version_item, &ei_isis_version); |
100 | 2.01k | } |
101 | 2.01k | offset += 1; |
102 | | |
103 | 2.01k | subdissector_data.system_id_len = tvb_get_uint8(tvb, offset); |
104 | 2.01k | proto_tree_add_uint(isis_tree, hf_isis_system_id_length, tvb, |
105 | 2.01k | offset, 1, subdissector_data.system_id_len ); |
106 | 2.01k | offset += 1; |
107 | | |
108 | 2.01k | proto_tree_add_item(isis_tree, hf_isis_type_reserved, tvb, offset, 1, ENC_BIG_ENDIAN ); |
109 | | |
110 | 2.01k | isis_type = tvb_get_uint8(tvb, offset) & ISIS_TYPE_MASK; |
111 | 2.01k | col_add_str(pinfo->cinfo, COL_INFO, |
112 | 2.01k | val_to_str(pinfo->pool, isis_type, isis_vals, "Unknown (0x%x)" ) ); |
113 | 2.01k | proto_tree_add_item(isis_tree, hf_isis_type, tvb, offset, 1, ENC_BIG_ENDIAN ); |
114 | 2.01k | offset += 1; |
115 | | |
116 | 2.01k | version2_item = proto_tree_add_item_ret_uint8(isis_tree, hf_isis_version2, tvb, offset, 1, ENC_BIG_ENDIAN, &isis_version2 ); |
117 | 2.01k | if (isis_version2 != 1) { |
118 | 1.86k | expert_add_info(pinfo, version2_item, &ei_isis_version2); |
119 | 1.86k | } |
120 | 2.01k | offset += 1; |
121 | | |
122 | 2.01k | reserved_item = proto_tree_add_item_ret_uint8(isis_tree, hf_isis_reserved, tvb, offset, 1, ENC_BIG_ENDIAN, &isis_reserved ); |
123 | 2.01k | if (isis_reserved != 0) { |
124 | 1.77k | expert_add_info(pinfo, reserved_item, &ei_isis_reserved); |
125 | 1.77k | } |
126 | 2.01k | offset += 1; |
127 | | |
128 | 2.01k | proto_tree_add_item(isis_tree, hf_isis_max_area_adr, tvb, offset, 1, ENC_BIG_ENDIAN ); |
129 | 2.01k | offset += 1; |
130 | | |
131 | | /* |
132 | | * Interpret the system ID length. |
133 | | */ |
134 | 2.01k | if (subdissector_data.system_id_len == 0) |
135 | 154 | subdissector_data.system_id_len = 6; /* zero means 6-octet ID field length */ |
136 | 1.85k | else if (subdissector_data.system_id_len == 255) { |
137 | 633 | subdissector_data.system_id_len = 0; /* 255 means null ID field */ |
138 | | /* XXX - what about the LAN ID? */ |
139 | 633 | } |
140 | | /* XXX - otherwise, must be in the range 1 through 8 */ |
141 | | |
142 | | /* |
143 | | * We must pass the entire ISIS PDU to the dissector, as some |
144 | | * dissectors are for ISIS PDU types that might contain a |
145 | | * checksum TLV, and that checksum is over the entire PDU. |
146 | | */ |
147 | 2.01k | if (!dissector_try_uint_with_data(isis_dissector_table, isis_type, tvb, |
148 | 2.01k | pinfo, tree, true, &subdissector_data)) |
149 | 30 | { |
150 | 30 | proto_tree_add_expert_remaining(tree, pinfo, &ei_isis_type, tvb, offset); |
151 | 30 | } |
152 | 2.01k | return tvb_captured_length(tvb); |
153 | 2.01k | } /* dissect_isis */ |
154 | | |
155 | | void |
156 | | proto_register_isis(void) |
157 | 15 | { |
158 | 15 | static hf_register_info hf[] = { |
159 | 15 | { &hf_isis_irpd, |
160 | 15 | { "Intradomain Routing Protocol Discriminator", "isis.irpd", |
161 | 15 | FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, NULL, HFILL }}, |
162 | | |
163 | 15 | { &hf_isis_header_length, |
164 | 15 | { "Length Indicator", "isis.len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
165 | | |
166 | 15 | { &hf_isis_version, |
167 | 15 | { "Version/Protocol ID Extension", "isis.version", FT_UINT8, |
168 | 15 | BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
169 | | |
170 | 15 | { &hf_isis_system_id_length, |
171 | 15 | { "ID Length", "isis.sysid_len", |
172 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
173 | | |
174 | 15 | { &hf_isis_type, |
175 | 15 | { "PDU Type", "isis.type", FT_UINT8, BASE_DEC, |
176 | 15 | VALS(isis_vals), ISIS_TYPE_MASK, NULL, HFILL }}, |
177 | | |
178 | 15 | { &hf_isis_type_reserved, |
179 | 15 | { "Reserved", "isis.type.reserved", FT_UINT8, BASE_HEX, |
180 | 15 | NULL, ISIS_TYPE_RESERVED_MASK, NULL, HFILL }}, |
181 | | |
182 | 15 | { &hf_isis_version2, |
183 | 15 | { "Version", "isis.version2", FT_UINT8, BASE_DEC, NULL, |
184 | 15 | 0x0, NULL, HFILL }}, |
185 | | |
186 | 15 | { &hf_isis_reserved, |
187 | 15 | { "Reserved", "isis.reserved", FT_UINT8, BASE_DEC, NULL, |
188 | 15 | 0x0, NULL, HFILL }}, |
189 | | |
190 | 15 | { &hf_isis_max_area_adr, |
191 | 15 | { "Maximum Area Addresses", "isis.max_area_adr", FT_UINT8, BASE_DEC, NULL, |
192 | 15 | 0x0, "Maximum Area Addresses, 0 means 3", HFILL }}, |
193 | | |
194 | 15 | { &hf_isis_clv_key_id, |
195 | 15 | { "Key ID", "isis.clv.key_id", FT_UINT16, BASE_DEC, NULL, |
196 | 15 | 0x0, NULL, HFILL }}, |
197 | 15 | }; |
198 | | /* |
199 | | * Note, we pull in the unknown CLV handler here, since it |
200 | | * is used by all ISIS packet types. |
201 | | */ |
202 | 15 | static int *ett[] = { |
203 | 15 | &ett_isis, |
204 | 15 | }; |
205 | | |
206 | 15 | static ei_register_info ei[] = { |
207 | 15 | { &ei_isis_length_indicator_too_small, { "isis.length_indicator_too_small", PI_MALFORMED, PI_ERROR, "ISIS length indicator value smaller than the fixed length header size", EXPFILL }}, |
208 | 15 | { &ei_isis_version, { "isis.version.unknown", PI_PROTOCOL, PI_WARN, "Unknown ISIS version", EXPFILL }}, |
209 | 15 | { &ei_isis_version2, { "isis.version2.notone", PI_PROTOCOL, PI_WARN, "Version must be 1", EXPFILL }}, |
210 | 15 | { &ei_isis_reserved, { "isis.reserved.notzero", PI_PROTOCOL, PI_WARN, "Reserved must be 0", EXPFILL }}, |
211 | 15 | { &ei_isis_type, { "isis.type.unknown", PI_PROTOCOL, PI_WARN, "Unknown ISIS packet type", EXPFILL }}, |
212 | 15 | }; |
213 | | |
214 | 15 | expert_module_t* expert_isis; |
215 | | |
216 | 15 | proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis"); |
217 | 15 | proto_register_field_array(proto_isis, hf, array_length(hf)); |
218 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
219 | 15 | expert_isis = expert_register_protocol(proto_isis); |
220 | 15 | expert_register_field_array(expert_isis, ei, array_length(ei)); |
221 | | |
222 | 15 | isis_handle = register_dissector("isis", dissect_isis, proto_isis); |
223 | | |
224 | 15 | isis_dissector_table = register_dissector_table("isis.type", |
225 | 15 | "ISIS Type", proto_isis, FT_UINT8, BASE_DEC); |
226 | 15 | } |
227 | | |
228 | | void |
229 | | proto_reg_handoff_isis(void) |
230 | 15 | { |
231 | 15 | dissector_add_uint("osinl.incl", NLPID_ISO10589_ISIS, isis_handle); |
232 | 15 | dissector_add_uint("ethertype", ETHERTYPE_L2ISIS, isis_handle); |
233 | 15 | } |
234 | | |
235 | | /* |
236 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
237 | | * |
238 | | * Local variables: |
239 | | * c-basic-offset: 4 |
240 | | * tab-width: 8 |
241 | | * indent-tabs-mode: nil |
242 | | * End: |
243 | | * |
244 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
245 | | * :indentSize=4:tabSize=8:noTabs=true: |
246 | | */ |