2 * Routines for ISO/OSI network and transport protocol packet disassembly, core
5 * $Id: packet-isis.c,v 1.10 2000/05/31 05:07:15 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(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;
141 if (check_col(fd, COL_PROTOCOL))
142 col_add_str(fd, COL_PROTOCOL, "ISIS");
144 if (!BYTES_ARE_IN_FRAME(offset, sizeof(*ihdr))) {
145 isis_dissect_unknown(offset, sizeof(*ihdr), tree, fd,
146 "not enough capture data for header (%d vs %d)",
147 sizeof(*ihdr), END_OF_FRAME);
151 ihdr = (isis_hdr_t *) &pd[offset];
153 if (ihdr->isis_version != ISIS_REQUIRED_VERSION){
154 isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
155 "Unknown ISIS version (%d vs %d)",
156 ihdr->isis_version, ISIS_REQUIRED_VERSION );
162 ti = proto_tree_add_item(tree, proto_isis, NullTVB, offset,
163 END_OF_FRAME, FALSE );
164 isis_tree = proto_item_add_subtree(ti, ett_isis);
165 proto_tree_add_uint(isis_tree, hf_isis_irpd, NullTVB, offset, 1,
167 proto_tree_add_uint(isis_tree, hf_isis_header_length, NullTVB,
168 offset + 1, 1, ihdr->isis_header_length );
169 proto_tree_add_uint(isis_tree, hf_isis_version, NullTVB,
170 offset + 2, 1, ihdr->isis_version );
171 proto_tree_add_uint(isis_tree, hf_isis_system_id_length, NullTVB,
172 offset + 3, 1, ihdr->isis_system_id_len );
173 proto_tree_add_uint_format(isis_tree, hf_isis_type, NullTVB,
174 offset + 4, 1, ihdr->isis_type,
175 "Type : %s (R:%s%s%s)",
176 val_to_str(ihdr->isis_type & ISIS_TYPE_MASK, isis_vals,
178 (ihdr->isis_type & ISIS_R8_MASK) ? "1" : "0",
179 (ihdr->isis_type & ISIS_R7_MASK) ? "1" : "0",
180 (ihdr->isis_type & ISIS_R6_MASK) ? "1" : "0");
181 proto_tree_add_uint(isis_tree, hf_isis_version2, NullTVB,
182 offset + 5, 1, ihdr->isis_version2 );
183 proto_tree_add_uint(isis_tree, hf_isis_reserved, NullTVB,
184 offset + 6, 1, ihdr->isis_reserved );
185 proto_tree_add_uint(isis_tree, hf_isis_max_area_adr, NullTVB,
186 offset + 7, 1, ihdr->isis_max_area_adr );
191 * Let us make sure we use the same names for all our decodes
192 * here. First, dump the name into info column, and THEN
193 * dispatch the sub-type.
195 if (check_col(fd, COL_INFO)) {
196 col_add_str(fd, COL_INFO, val_to_str (
197 ihdr->isis_type&ISIS_TYPE_MASK, isis_vals,
198 "Unknown (0x%x)" ) );
202 * Advance offset (we are past the header).
204 offset += sizeof(*ihdr);
205 switch (ihdr->isis_type) {
206 case ISIS_TYPE_L1_HELLO:
207 isis_dissect_isis_hello(ISIS_TYPE_L1_HELLO,
208 ihdr->isis_header_length, pd, offset, fd, isis_tree);
210 case ISIS_TYPE_L2_HELLO:
211 isis_dissect_isis_hello(ISIS_TYPE_L2_HELLO,
212 ihdr->isis_header_length, pd, offset, fd, isis_tree);
214 case ISIS_TYPE_PTP_HELLO:
215 isis_dissect_isis_hello(ISIS_TYPE_PTP_HELLO,
216 ihdr->isis_header_length, pd, offset, fd, isis_tree);
218 case ISIS_TYPE_L1_LSP:
219 isis_dissect_isis_lsp(ISIS_TYPE_L1_LSP, ihdr->isis_header_length,
220 pd, offset, fd, isis_tree);
222 case ISIS_TYPE_L2_LSP:
223 isis_dissect_isis_lsp(ISIS_TYPE_L2_LSP, ihdr->isis_header_length,
224 pd, offset, fd, isis_tree);
226 case ISIS_TYPE_L1_CSNP:
227 isis_dissect_isis_csnp(ISIS_TYPE_L1_CSNP,
228 ihdr->isis_header_length, pd, offset, fd, isis_tree);
230 case ISIS_TYPE_L2_CSNP:
231 isis_dissect_isis_csnp(ISIS_TYPE_L2_CSNP,
232 ihdr->isis_header_length, pd, offset, fd, isis_tree);
234 case ISIS_TYPE_L1_PSNP:
235 isis_dissect_isis_psnp(ISIS_TYPE_L1_PSNP,
236 ihdr->isis_header_length, pd, offset, fd, isis_tree);
238 case ISIS_TYPE_L2_PSNP:
239 isis_dissect_isis_psnp(ISIS_TYPE_L2_PSNP,
240 ihdr->isis_header_length, pd, offset, fd, isis_tree);
243 isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
244 "unknown ISIS packet type" );
250 * Name: proto_register_isis()
253 * main register for isis protocol set. We register some display
254 * formats and the protocol module variables.
256 * NOTE: this procedure to autolinked by the makefile process that
266 proto_register_isis(void) {
267 static hf_register_info hf[] = {
269 { "Intra Domain Routing Protocol Discriminator", "isis.irpd",
270 FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, "" }},
272 { &hf_isis_header_length,
273 { "PDU Header Length ", "isis.len", FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
276 { "Version (==1) ", "isis.version", FT_UINT8,
277 BASE_DEC, NULL, 0x0, "" }},
279 { &hf_isis_system_id_length,
280 { "System ID Length ", "isis.sysid_len",
281 FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
284 { "PDU Type :", "isis.type", FT_UINT8, BASE_DEC,
285 VALS(isis_vals), 0xff, "" }},
288 { "Version2 (==1) ", "isis.version2", FT_UINT8, BASE_DEC, NULL,
292 { "Reserved (==0) ", "isis.reserved", FT_UINT8, BASE_DEC, NULL,
295 { &hf_isis_max_area_adr,
296 { "Max.AREAs: (0==3) ", "isis.max_area_adr", FT_UINT8, BASE_DEC, NULL,
301 * Note, we pull in the unknown CLV handler here, since it
302 * is used by all ISIS packet types.
304 static gint *ett[] = {
308 proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "isis");
309 proto_register_field_array(proto_isis, hf, array_length(hf));
310 proto_register_subtree_array(ett, array_length(ett));
314 proto_reg_handoff_isis(void)
316 dissector_add("osinl", NLPID_ISO10589_ISIS, dissect_isis);