2 * Routines for ISO/OSI network and transport protocol packet disassembly, core
5 * Stuart Stanley <stuarts@mxmail.net>
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/expert.h>
18 #include <epan/nlpid.h>
19 #include <epan/etypes.h>
20 #include "packet-osi.h"
21 #include "packet-isis.h"
23 void proto_register_isis(void);
24 void proto_reg_handoff_isis(void);
26 static dissector_table_t isis_dissector_table
;
28 /* isis base header */
29 static int proto_isis
;
31 static int hf_isis_irpd
;
32 static int hf_isis_header_length
;
33 static int hf_isis_version
;
34 static int hf_isis_system_id_length
;
35 static int hf_isis_type
;
36 static int hf_isis_type_reserved
;
37 static int hf_isis_version2
;
38 static int hf_isis_reserved
;
39 static int hf_isis_max_area_adr
;
40 int hf_isis_clv_key_id
;
44 static expert_field ei_isis_length_indicator_too_small
;
45 static expert_field ei_isis_version
;
46 static expert_field ei_isis_version2
;
47 static expert_field ei_isis_reserved
;
48 static expert_field ei_isis_type
;
50 static dissector_handle_t isis_handle
;
52 static const value_string isis_vals
[] = {
53 { ISIS_TYPE_L1_HELLO
, "L1 HELLO"},
54 { ISIS_TYPE_L2_HELLO
, "L2 HELLO"},
55 { ISIS_TYPE_PTP_HELLO
, "P2P HELLO"},
56 { ISIS_TYPE_L1_LSP
, "L1 LSP"},
57 { ISIS_TYPE_L2_LSP
, "L2 LSP"},
58 { ISIS_TYPE_L1_CSNP
, "L1 CSNP"},
59 { ISIS_TYPE_L2_CSNP
, "L2 CSNP"},
60 { ISIS_TYPE_L1_PSNP
, "L1 PSNP"},
61 { ISIS_TYPE_L2_PSNP
, "L2 PSNP"},
66 dissect_isis(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
68 proto_item
*ti
, *version_item
, *version2_item
, *reserved_item
;
69 proto_tree
*isis_tree
= NULL
;
71 uint8_t isis_version
, isis_version2
, isis_reserved
;
73 isis_data_t subdissector_data
;
75 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ISIS");
76 col_clear(pinfo
->cinfo
, COL_INFO
);
78 ti
= proto_tree_add_item(tree
, proto_isis
, tvb
, 0, -1, ENC_NA
);
79 isis_tree
= proto_item_add_subtree(ti
, ett_isis
);
81 proto_tree_add_item(isis_tree
, hf_isis_irpd
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
84 subdissector_data
.header_length
= tvb_get_uint8(tvb
, offset
);
85 subdissector_data
.header_length_item
=
86 proto_tree_add_uint(isis_tree
, hf_isis_header_length
, tvb
,
87 offset
, 1, subdissector_data
.header_length
);
89 if (subdissector_data
.header_length
< 8) {
90 /* Not large enough to include the part of the header that
92 expert_add_info(pinfo
, subdissector_data
.header_length_item
, &ei_isis_length_indicator_too_small
);
93 return tvb_captured_length(tvb
);
95 subdissector_data
.ei_bad_header_length
= &ei_isis_length_indicator_too_small
;
97 isis_version
= tvb_get_uint8(tvb
, offset
);
98 version_item
= proto_tree_add_uint(isis_tree
, hf_isis_version
, tvb
,
99 offset
, 1, isis_version
);
100 if (isis_version
!= ISIS_REQUIRED_VERSION
){
101 expert_add_info(pinfo
, version_item
, &ei_isis_version
);
105 subdissector_data
.system_id_len
= tvb_get_uint8(tvb
, offset
);
106 proto_tree_add_uint(isis_tree
, hf_isis_system_id_length
, tvb
,
107 offset
, 1, subdissector_data
.system_id_len
);
110 proto_tree_add_item(isis_tree
, hf_isis_type_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
112 isis_type
= tvb_get_uint8(tvb
, offset
) & ISIS_TYPE_MASK
;
113 col_add_str(pinfo
->cinfo
, COL_INFO
,
114 val_to_str ( isis_type
, isis_vals
, "Unknown (0x%x)" ) );
115 proto_tree_add_item(isis_tree
, hf_isis_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
118 isis_version2
= tvb_get_uint8(tvb
, offset
);
119 version2_item
= proto_tree_add_item(isis_tree
, hf_isis_version2
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
120 if (isis_version2
!= 1) {
121 expert_add_info(pinfo
, version2_item
, &ei_isis_version2
);
125 isis_reserved
= tvb_get_uint8(tvb
, offset
);
126 reserved_item
= proto_tree_add_item(isis_tree
, hf_isis_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
127 if (isis_reserved
!= 0) {
128 expert_add_info(pinfo
, reserved_item
, &ei_isis_reserved
);
132 proto_tree_add_item(isis_tree
, hf_isis_max_area_adr
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
136 * Interpret the system ID length.
138 if (subdissector_data
.system_id_len
== 0)
139 subdissector_data
.system_id_len
= 6; /* zero means 6-octet ID field length */
140 else if (subdissector_data
.system_id_len
== 255) {
141 subdissector_data
.system_id_len
= 0; /* 255 means null ID field */
142 /* XXX - what about the LAN ID? */
144 /* XXX - otherwise, must be in the range 1 through 8 */
147 * We must pass the entire ISIS PDU to the dissector, as some
148 * dissectors are for ISIS PDU types that might contain a
149 * checksum TLV, and that checksum is over the entire PDU.
151 if (!dissector_try_uint_with_data(isis_dissector_table
, isis_type
, tvb
,
152 pinfo
, tree
, true, &subdissector_data
))
154 proto_tree_add_expert(tree
, pinfo
, &ei_isis_type
, tvb
, offset
, -1);
156 return tvb_captured_length(tvb
);
160 proto_register_isis(void)
162 static hf_register_info hf
[] = {
164 { "Intradomain Routing Protocol Discriminator", "isis.irpd",
165 FT_UINT8
, BASE_HEX
, VALS(nlpid_vals
), 0x0, NULL
, HFILL
}},
167 { &hf_isis_header_length
,
168 { "Length Indicator", "isis.len", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
171 { "Version/Protocol ID Extension", "isis.version", FT_UINT8
,
172 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
174 { &hf_isis_system_id_length
,
175 { "ID Length", "isis.sysid_len",
176 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
179 { "PDU Type", "isis.type", FT_UINT8
, BASE_DEC
,
180 VALS(isis_vals
), ISIS_TYPE_MASK
, NULL
, HFILL
}},
182 { &hf_isis_type_reserved
,
183 { "Reserved", "isis.type.reserved", FT_UINT8
, BASE_HEX
,
184 NULL
, ISIS_TYPE_RESERVED_MASK
, NULL
, HFILL
}},
187 { "Version", "isis.version2", FT_UINT8
, BASE_DEC
, NULL
,
191 { "Reserved", "isis.reserved", FT_UINT8
, BASE_DEC
, NULL
,
194 { &hf_isis_max_area_adr
,
195 { "Maximum Area Addresses", "isis.max_area_adr", FT_UINT8
, BASE_DEC
, NULL
,
196 0x0, "Maximum Area Addresses, 0 means 3", HFILL
}},
198 { &hf_isis_clv_key_id
,
199 { "Key ID", "isis.clv.key_id", FT_UINT16
, BASE_DEC
, NULL
,
203 * Note, we pull in the unknown CLV handler here, since it
204 * is used by all ISIS packet types.
206 static int *ett
[] = {
210 static ei_register_info ei
[] = {
211 { &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
}},
212 { &ei_isis_version
, { "isis.version.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown ISIS version", EXPFILL
}},
213 { &ei_isis_version2
, { "isis.version2.notone", PI_PROTOCOL
, PI_WARN
, "Version must be 1", EXPFILL
}},
214 { &ei_isis_reserved
, { "isis.reserved.notzero", PI_PROTOCOL
, PI_WARN
, "Reserved must be 0", EXPFILL
}},
215 { &ei_isis_type
, { "isis.type.unknown", PI_PROTOCOL
, PI_WARN
, "Unknown ISIS packet type", EXPFILL
}},
218 expert_module_t
* expert_isis
;
220 proto_isis
= proto_register_protocol(PROTO_STRING_ISIS
, "ISIS", "isis");
221 proto_register_field_array(proto_isis
, hf
, array_length(hf
));
222 proto_register_subtree_array(ett
, array_length(ett
));
223 expert_isis
= expert_register_protocol(proto_isis
);
224 expert_register_field_array(expert_isis
, ei
, array_length(ei
));
226 isis_handle
= register_dissector("isis", dissect_isis
, proto_isis
);
228 isis_dissector_table
= register_dissector_table("isis.type",
229 "ISIS Type", proto_isis
, FT_UINT8
, BASE_DEC
);
233 proto_reg_handoff_isis(void)
235 dissector_add_uint("osinl.incl", NLPID_ISO10589_ISIS
, isis_handle
);
236 dissector_add_uint("ethertype", ETHERTYPE_L2ISIS
, isis_handle
);
240 * Editor modelines - https://www.wireshark.org/tools/modelines.html
245 * indent-tabs-mode: nil
248 * vi: set shiftwidth=4 tabstop=8 expandtab:
249 * :indentSize=4:tabSize=8:noTabs=true: