2 * Routines for ISO/OSI network and transport protocol packet disassembly, core
5 * $Id: packet-isis.c,v 1.16 2001/01/03 06:55:29 guy Exp $
6 * Stuart Stanley <stuarts@mxmail.net>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
43 #include "packet-osi.h"
44 #include "packet-isis.h"
45 #include "packet-isis-lsp.h"
46 #include "packet-isis-hello.h"
47 #include "packet-isis-snp.h"
50 /* isis base header */
51 static int proto_isis = -1;
53 static int hf_isis_irpd = -1;
54 static int hf_isis_header_length = -1;
55 static int hf_isis_version = -1;
56 static int hf_isis_system_id_length = -1;
57 static int hf_isis_type = -1;
58 static int hf_isis_version2 = -1;
59 static int hf_isis_reserved = -1;
60 static int hf_isis_max_area_adr = -1;
62 static gint ett_isis = -1;
64 static const value_string isis_vals[] = {
65 { ISIS_TYPE_L1_HELLO, "L1 HELLO"},
66 { ISIS_TYPE_L2_HELLO, "L2 HELLO"},
67 { ISIS_TYPE_PTP_HELLO, "P2P HELLO"},
68 { ISIS_TYPE_L1_LSP, "L1 LSP"},
69 { ISIS_TYPE_L2_LSP, "L2 LSP"},
70 { ISIS_TYPE_L1_CSNP, "L1 CSNP"},
71 { ISIS_TYPE_L2_CSNP, "L2 CSNP"},
72 { ISIS_TYPE_L1_PSNP, "L1 PSNP"},
73 { ISIS_TYPE_L2_PSNP, "L2 PSNP"},
77 * Name: dissect_isis_unknown()
80 * There was some error in the protocol and we are in unknown space
81 * here. Add a tree item to cover the error and go on. Note
82 * that we make sure we don't go off the end of the bleedin packet here!
85 * unt offset : Current offset into packet data.
86 * int len : length of to dump.
87 * proto_tree * : tree of display data. May be NULL.
88 * frame_data * fd : frame data
89 * char * : format text
92 * void (may modify proto tree)
95 isis_dissect_unknown(int offset,guint length,proto_tree *tree,frame_data *fd,
99 if ( !IS_DATA_IN_FRAME(offset) ) {
101 * big oops They were off the end of the packet already.
102 * Just ignore this one.
106 if ( !BYTES_ARE_IN_FRAME(offset, length) ) {
108 * length will take us past eop. Truncate length.
110 length = END_OF_FRAME;
114 proto_tree_add_text_valist(tree, NullTVB, offset, length, fmat, ap);
118 * Name: dissect_isis()
121 * Main entry area for isis de-mangling. This will build the
122 * main isis tree data and call the sub-protocols as needed.
125 * u_char * : packet data
126 * int : offset into packet where we are (packet_data[offset]== start
127 * of what we care about)
128 * frame_data * : frame data (whole packet with extra info)
129 * proto_tree * : tree of display data. May be NULL.
132 * void, but we will add to the proto_tree if it is not NULL.
135 dissect_isis(const u_char *pd, int offset, frame_data *fd,
139 proto_tree *isis_tree = NULL;
142 OLD_CHECK_DISPLAY_AS_DATA(proto_isis, pd, offset, fd, tree);
144 if (check_col(fd, COL_PROTOCOL))
145 col_set_str(fd, COL_PROTOCOL, "ISIS");
147 if (!BYTES_ARE_IN_FRAME(offset, sizeof(*ihdr))) {
148 isis_dissect_unknown(offset, sizeof(*ihdr), tree, fd,
149 "not enough capture data for header (%d vs %d)",
150 sizeof(*ihdr), END_OF_FRAME);
154 ihdr = (isis_hdr_t *) &pd[offset];
156 if (ihdr->isis_version != ISIS_REQUIRED_VERSION){
157 isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
158 "Unknown ISIS version (%d vs %d)",
159 ihdr->isis_version, ISIS_REQUIRED_VERSION );
165 ti = proto_tree_add_item(tree, proto_isis, NullTVB, offset,
166 END_OF_FRAME, FALSE );
167 isis_tree = proto_item_add_subtree(ti, ett_isis);
168 proto_tree_add_uint(isis_tree, hf_isis_irpd, NullTVB, offset, 1,
170 proto_tree_add_uint(isis_tree, hf_isis_header_length, NullTVB,
171 offset + 1, 1, ihdr->isis_header_length );
172 proto_tree_add_uint(isis_tree, hf_isis_version, NullTVB,
173 offset + 2, 1, ihdr->isis_version );
174 proto_tree_add_uint(isis_tree, hf_isis_system_id_length, NullTVB,
175 offset + 3, 1, ihdr->isis_system_id_len );
176 proto_tree_add_uint_format(isis_tree, hf_isis_type, NullTVB,
177 offset + 4, 1, ihdr->isis_type,
178 "Type : %s (R:%s%s%s)",
179 val_to_str(ihdr->isis_type & ISIS_TYPE_MASK, isis_vals,
181 (ihdr->isis_type & ISIS_R8_MASK) ? "1" : "0",
182 (ihdr->isis_type & ISIS_R7_MASK) ? "1" : "0",
183 (ihdr->isis_type & ISIS_R6_MASK) ? "1" : "0");
184 proto_tree_add_uint(isis_tree, hf_isis_version2, NullTVB,
185 offset + 5, 1, ihdr->isis_version2 );
186 proto_tree_add_uint(isis_tree, hf_isis_reserved, NullTVB,
187 offset + 6, 1, ihdr->isis_reserved );
188 proto_tree_add_uint(isis_tree, hf_isis_max_area_adr, NullTVB,
189 offset + 7, 1, ihdr->isis_max_area_adr );
194 * Let us make sure we use the same names for all our decodes
195 * here. First, dump the name into info column, and THEN
196 * dispatch the sub-type.
198 if (check_col(fd, COL_INFO)) {
199 col_add_str(fd, COL_INFO, val_to_str (
200 ihdr->isis_type&ISIS_TYPE_MASK, isis_vals,
201 "Unknown (0x%x)" ) );
205 * Interpret the system ID length.
207 id_length = ihdr->isis_system_id_len;
209 id_length = 6; /* zero means 6-octet ID field length */
210 else if (id_length == 255) {
211 id_length = 0; /* 255 means null ID field */
212 /* XXX - what about the LAN ID? */
214 /* XXX - otherwise, must be in the range 1 through 8 */
217 * Advance offset (we are past the header).
219 offset += sizeof(*ihdr);
220 switch (ihdr->isis_type) {
221 case ISIS_TYPE_L1_HELLO:
222 isis_dissect_isis_hello(ISIS_TYPE_L1_HELLO,
223 ihdr->isis_header_length, id_length,
224 pd, offset, fd, isis_tree);
226 case ISIS_TYPE_L2_HELLO:
227 isis_dissect_isis_hello(ISIS_TYPE_L2_HELLO,
228 ihdr->isis_header_length, id_length,
229 pd, offset, fd, isis_tree);
231 case ISIS_TYPE_PTP_HELLO:
232 isis_dissect_isis_hello(ISIS_TYPE_PTP_HELLO,
233 ihdr->isis_header_length, id_length,
234 pd, offset, fd, isis_tree);
236 case ISIS_TYPE_L1_LSP:
237 isis_dissect_isis_lsp(ISIS_TYPE_L1_LSP,
238 ihdr->isis_header_length, id_length,
239 pd, offset, fd, isis_tree);
241 case ISIS_TYPE_L2_LSP:
242 isis_dissect_isis_lsp(ISIS_TYPE_L2_LSP,
243 ihdr->isis_header_length, id_length,
244 pd, offset, fd, isis_tree);
246 case ISIS_TYPE_L1_CSNP:
247 isis_dissect_isis_csnp(ISIS_TYPE_L1_CSNP,
248 ihdr->isis_header_length, id_length,
249 pd, offset, fd, isis_tree);
251 case ISIS_TYPE_L2_CSNP:
252 isis_dissect_isis_csnp(ISIS_TYPE_L2_CSNP,
253 ihdr->isis_header_length, id_length,
254 pd, offset, fd, isis_tree);
256 case ISIS_TYPE_L1_PSNP:
257 isis_dissect_isis_psnp(ISIS_TYPE_L1_PSNP,
258 ihdr->isis_header_length, id_length,
259 pd, offset, fd, isis_tree);
261 case ISIS_TYPE_L2_PSNP:
262 isis_dissect_isis_psnp(ISIS_TYPE_L2_PSNP,
263 ihdr->isis_header_length, id_length,
264 pd, offset, fd, isis_tree);
267 isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
268 "unknown ISIS packet type" );
274 * Name: proto_register_isis()
277 * main register for isis protocol set. We register some display
278 * formats and the protocol module variables.
280 * NOTE: this procedure to autolinked by the makefile process that
290 proto_register_isis(void) {
291 static hf_register_info hf[] = {
293 { "Intra Domain Routing Protocol Discriminator", "isis.irpd",
294 FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, "" }},
296 { &hf_isis_header_length,
297 { "PDU Header Length ", "isis.len", FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
300 { "Version (==1) ", "isis.version", FT_UINT8,
301 BASE_DEC, NULL, 0x0, "" }},
303 { &hf_isis_system_id_length,
304 { "System ID Length ", "isis.sysid_len",
305 FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
308 { "PDU Type :", "isis.type", FT_UINT8, BASE_DEC,
309 VALS(isis_vals), 0xff, "" }},
312 { "Version2 (==1) ", "isis.version2", FT_UINT8, BASE_DEC, NULL,
316 { "Reserved (==0) ", "isis.reserved", FT_UINT8, BASE_DEC, NULL,
319 { &hf_isis_max_area_adr,
320 { "Max.AREAs: (0==3) ", "isis.max_area_adr", FT_UINT8, BASE_DEC, NULL,
325 * Note, we pull in the unknown CLV handler here, since it
326 * is used by all ISIS packet types.
328 static gint *ett[] = {
332 proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis");
333 proto_register_field_array(proto_isis, hf, array_length(hf));
334 proto_register_subtree_array(ett, array_length(ett));
338 proto_reg_handoff_isis(void)
340 old_dissector_add("osinl", NLPID_ISO10589_ISIS, dissect_isis);