2 * Routines for ISO/OSI network and transport protocol packet disassembly, core
5 * $Id: packet-isis.c,v 1.3 2000/01/24 03:33:31 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-isis.h"
44 #include "packet-isis-lsp.h"
45 #include "packet-isis-hello.h"
46 #include "packet-isis-snp.h"
48 /* isis base header */
49 static int proto_isis = -1;
51 static int hf_isis_irpd = -1;
52 static int hf_isis_header_length = -1;
53 static int hf_isis_version = -1;
54 static int hf_isis_reserved = -1;
55 static int hf_isis_type = -1;
56 static int hf_isis_version2 = -1;
57 static int hf_isis_eco = -1;
58 static int hf_isis_user_eco = -1;
60 static gint ett_isis = -1;
62 static const value_string isis_vals[] = {
63 { ISIS_TYPE_L1_HELLO, "L1 HELLO"},
64 { ISIS_TYPE_L2_HELLO, "L2 HELLO"},
65 { ISIS_TYPE_PTP_HELLO, "P2P HELLO"},
66 { ISIS_TYPE_L1_LSP, "L1 LSP"},
67 { ISIS_TYPE_L2_LSP, "L2 LSP"},
68 { ISIS_TYPE_L1_CSNP, "L1 CSNP"},
69 { ISIS_TYPE_L2_CSNP, "L2 CSNP"},
70 { ISIS_TYPE_L1_PSNP, "L1 PSNP"},
71 { ISIS_TYPE_L2_PSNP, "L2 PSNP"},
76 * Name: dissect_isis_unknown()
79 * There was some error in the protocol and we are in unknown space
80 * here. Add a tree item to cover the error and go on. Note
81 * that we make sure we don't go off the end of the bleedin packet here!
84 * unt offset : Current offset into packet data.
85 * int len : length of to dump.
86 * proto_tree * : tree of display data. May be NULL.
87 * frame_data * fd : frame data
88 * char * : format text
91 * void (may modify proto tree)
94 isis_dissect_unknown(int offset,guint length,proto_tree *tree,frame_data *fd,
98 if ( !IS_DATA_IN_FRAME(offset) ) {
100 * big oops They were off the end of the packet already.
101 * Just ignore this one.
105 if ( !BYTES_ARE_IN_FRAME(offset, length) ) {
107 * length will take us past eop. Truncate length.
109 length = END_OF_FRAME;
113 proto_tree_add_text(tree, offset, length, fmat, ap);
118 * Name: isis_address_to_string()
121 * Function for taking a byte string and turn it into a "0000.0000...."
122 * format ISIS address.
125 * u_char * : Packet data
126 * unt offset : Current offset into packet data.
127 * int len : length of to dump.
130 * static char * : print string
133 *isis_address_to_string ( const u_char *pd, int offset, int len ) {
134 static char sbuf[768];
140 /* special case: len is 1, put ending on it */
142 s += sprintf ( s, "%02x", pd[offset++] );
145 /* general case, just add 2 bytes */
146 s+= sprintf ( s, "%02x%02x", pd[offset++],
151 s += sprintf ( s, "." );
158 * Name: dissect_isis()
161 * Main entry area for isis de-mangling. This will build the
162 * main isis tree data and call the sub-protocols as needed.
165 * u_char * : packet data
166 * int : offset into packet where we are (packet_data[offset]== start
167 * of what we care about)
168 * frame_data * : frame data (whole packet with extra info)
169 * proto_tree * : tree of display data. May be NULL.
172 * void, but we will add to the proto_tree if it is not NULL.
175 dissect_isis(const u_char *pd, int offset, frame_data *fd,
179 proto_tree *isis_tree = NULL;
181 if (!BYTES_ARE_IN_FRAME(offset, sizeof(*ihdr))) {
182 isis_dissect_unknown(offset, sizeof(*ihdr), tree, fd,
183 "not enough capture data for header (%d vs %d)",
184 sizeof(*ihdr), END_OF_FRAME);
188 ihdr = (isis_hdr_t *) &pd[offset];
190 if (ihdr->isis_version != ISIS_REQUIRED_VERSION){
191 isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
192 "Unknown ISIS version (%d vs %d)",
193 ihdr->isis_version, ISIS_REQUIRED_VERSION );
199 ti = proto_tree_add_item(tree, proto_isis, offset,
200 END_OF_FRAME, NULL );
201 isis_tree = proto_item_add_subtree(ti, ett_isis);
202 proto_tree_add_item(isis_tree, hf_isis_irpd, offset, 1,
204 proto_tree_add_item(isis_tree, hf_isis_header_length,
205 offset + 1, 1, ihdr->isis_header_length );
206 proto_tree_add_item(isis_tree, hf_isis_version,
207 offset + 2, 1, ihdr->isis_version );
208 proto_tree_add_item(isis_tree, hf_isis_reserved,
209 offset + 3, 1, ihdr->isis_reserved );
210 proto_tree_add_item_format(isis_tree, hf_isis_type,
211 offset + 4, 1, ihdr->isis_type,
212 "Type: %s (R:%s%s%s)",
213 val_to_str(ihdr->isis_type & ISIS_TYPE_MASK, isis_vals,
215 (ihdr->isis_type & ISIS_R8_MASK) ? "1" : "0",
216 (ihdr->isis_type & ISIS_R7_MASK) ? "1" : "0",
217 (ihdr->isis_type & ISIS_R6_MASK) ? "1" : "0");
218 proto_tree_add_item(isis_tree, hf_isis_version2,
219 offset + 5, 1, ihdr->isis_version2 );
220 proto_tree_add_item(isis_tree, hf_isis_eco,
221 offset + 6, 1, ihdr->isis_eco );
222 proto_tree_add_item(isis_tree, hf_isis_user_eco,
223 offset + 7, 1, ihdr->isis_user_eco );
228 * Let us make sure we use the same names for all our decodes
229 * here. First, dump the name into info column, and THEN
230 * dispatch the sub-type.
232 if (check_col(fd, COL_INFO)) {
233 col_add_str(fd, COL_INFO, val_to_str (
234 ihdr->isis_type&ISIS_TYPE_MASK, isis_vals,
235 "Unknown (0x%x)" ) );
239 * Advance offset (we are past the header).
241 offset += sizeof(*ihdr);
242 switch (ihdr->isis_type) {
243 case ISIS_TYPE_L1_HELLO:
244 isis_dissect_isis_hello(ISIS_TYPE_L1_HELLO,
245 ihdr->isis_header_length, pd, offset, fd, isis_tree);
247 case ISIS_TYPE_L2_HELLO:
248 isis_dissect_isis_hello(ISIS_TYPE_L2_HELLO,
249 ihdr->isis_header_length, pd, offset, fd, isis_tree);
251 case ISIS_TYPE_PTP_HELLO:
252 isis_dissect_isis_hello(ISIS_TYPE_PTP_HELLO,
253 ihdr->isis_header_length, pd, offset, fd, isis_tree);
255 case ISIS_TYPE_L1_LSP:
256 isis_dissect_isis_lsp(ISIS_TYPE_L1_LSP, ihdr->isis_header_length,
257 pd, offset, fd, isis_tree);
259 case ISIS_TYPE_L2_LSP:
260 isis_dissect_isis_lsp(ISIS_TYPE_L2_LSP, ihdr->isis_header_length,
261 pd, offset, fd, isis_tree);
263 case ISIS_TYPE_L1_CSNP:
264 isis_dissect_isis_csnp(ISIS_TYPE_L1_CSNP,
265 ihdr->isis_header_length, pd, offset, fd, isis_tree);
267 case ISIS_TYPE_L2_CSNP:
268 isis_dissect_isis_csnp(ISIS_TYPE_L2_CSNP,
269 ihdr->isis_header_length, pd, offset, fd, isis_tree);
271 case ISIS_TYPE_L1_PSNP:
272 isis_dissect_isis_psnp(ISIS_TYPE_L1_PSNP,
273 ihdr->isis_header_length, pd, offset, fd, isis_tree);
275 case ISIS_TYPE_L2_PSNP:
276 isis_dissect_isis_psnp(ISIS_TYPE_L2_PSNP,
277 ihdr->isis_header_length, pd, offset, fd, isis_tree);
280 isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
281 "unknown ISIS packet type" );
287 * Name: proto_register_isis()
290 * main register for isis protocol set. We register some display
291 * formats and the protocol module variables.
293 * NOTE: this procedure to autolinked by the makefile process that
303 proto_register_isis(void) {
304 static hf_register_info hf[] = {
306 { "Intradomain Routing Protocol Discriminator", "isis.irpd",
307 FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, "" }},
309 { &hf_isis_header_length,
310 { "HDR Length", "isis.hdr_len", FT_UINT8, BASE_DEC,
314 { "Version (==1)", "isis.version", FT_UINT8,
315 BASE_DEC, NULL, 0x0, "" }},
318 { "Reserved(==0)", "isis.reserved",
319 FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
322 { "Type code", "isis.type", FT_UINT8, BASE_DEC,
323 VALS(isis_vals), 0xff, "" }},
326 { "Version2(==1)", "isis.version2", FT_UINT8, BASE_DEC, NULL,
330 { "ECO (==0)", "isis.eco",FT_UINT8, BASE_DEC, NULL,
334 { "User ECO (==0)", "isis.user_eco", FT_UINT8, BASE_DEC, NULL,
339 * Note, we pull in the unknown CLV handler here, since it
340 * is used by all ISIS packet types.
342 static gint *ett[] = {
346 proto_isis = proto_register_protocol("clnp ISIS", "ISIS");
347 proto_register_field_array(proto_isis, hf, array_length(hf));
348 proto_register_subtree_array(ett, array_length(ett));