1999-12-15 04:34:44 +00:00
|
|
|
/* packet-isis-core.c
|
|
|
|
* Routines for ISO/OSI network and transport protocol packet disassembly, core
|
|
|
|
* bits.
|
|
|
|
*
|
2001-05-23 18:52:54 +00:00
|
|
|
* $Id: packet-isis.c,v 1.20 2001/05/23 18:52:54 guy Exp $
|
1999-12-15 04:34:44 +00:00
|
|
|
* Stuart Stanley <stuarts@mxmail.net>
|
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@zing.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include "packet.h"
|
2000-01-13 06:07:53 +00:00
|
|
|
#include "nlpid.h"
|
2000-04-15 22:11:26 +00:00
|
|
|
#include "packet-osi.h"
|
1999-12-15 04:34:44 +00:00
|
|
|
#include "packet-isis.h"
|
|
|
|
#include "packet-isis-lsp.h"
|
|
|
|
#include "packet-isis-hello.h"
|
|
|
|
#include "packet-isis-snp.h"
|
|
|
|
|
2000-04-15 22:11:26 +00:00
|
|
|
|
1999-12-15 04:34:44 +00:00
|
|
|
/* isis base header */
|
2000-04-15 22:11:26 +00:00
|
|
|
static int proto_isis = -1;
|
1999-12-15 04:34:44 +00:00
|
|
|
|
2000-04-15 22:11:26 +00:00
|
|
|
static int hf_isis_irpd = -1;
|
|
|
|
static int hf_isis_header_length = -1;
|
|
|
|
static int hf_isis_version = -1;
|
|
|
|
static int hf_isis_system_id_length = -1;
|
|
|
|
static int hf_isis_type = -1;
|
|
|
|
static int hf_isis_version2 = -1;
|
|
|
|
static int hf_isis_reserved = -1;
|
|
|
|
static int hf_isis_max_area_adr = -1;
|
1999-12-15 04:34:44 +00:00
|
|
|
|
2000-04-15 22:11:26 +00:00
|
|
|
static gint ett_isis = -1;
|
1999-12-15 04:34:44 +00:00
|
|
|
|
|
|
|
static const value_string isis_vals[] = {
|
2000-04-15 22:11:26 +00:00
|
|
|
{ ISIS_TYPE_L1_HELLO, "L1 HELLO"},
|
|
|
|
{ ISIS_TYPE_L2_HELLO, "L2 HELLO"},
|
|
|
|
{ ISIS_TYPE_PTP_HELLO, "P2P HELLO"},
|
|
|
|
{ ISIS_TYPE_L1_LSP, "L1 LSP"},
|
|
|
|
{ ISIS_TYPE_L2_LSP, "L2 LSP"},
|
|
|
|
{ ISIS_TYPE_L1_CSNP, "L1 CSNP"},
|
|
|
|
{ ISIS_TYPE_L2_CSNP, "L2 CSNP"},
|
|
|
|
{ ISIS_TYPE_L1_PSNP, "L1 PSNP"},
|
|
|
|
{ ISIS_TYPE_L2_PSNP, "L2 PSNP"},
|
|
|
|
{ 0, NULL} };
|
1999-12-15 04:34:44 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Name: dissect_isis_unknown()
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* There was some error in the protocol and we are in unknown space
|
|
|
|
* here. Add a tree item to cover the error and go on. Note
|
|
|
|
* that we make sure we don't go off the end of the bleedin packet here!
|
|
|
|
*
|
|
|
|
* Input
|
|
|
|
* unt offset : Current offset into packet data.
|
|
|
|
* int len : length of to dump.
|
|
|
|
* proto_tree * : tree of display data. May be NULL.
|
|
|
|
* frame_data * fd : frame data
|
|
|
|
* char * : format text
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* void (may modify proto tree)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
isis_dissect_unknown(int offset,guint length,proto_tree *tree,frame_data *fd,
|
|
|
|
char *fmat, ...){
|
|
|
|
va_list ap;
|
|
|
|
|
2000-01-24 03:33:35 +00:00
|
|
|
if ( !IS_DATA_IN_FRAME(offset) ) {
|
1999-12-15 04:34:44 +00:00
|
|
|
/*
|
|
|
|
* big oops They were off the end of the packet already.
|
|
|
|
* Just ignore this one.
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
2000-01-24 03:33:35 +00:00
|
|
|
if ( !BYTES_ARE_IN_FRAME(offset, length) ) {
|
1999-12-15 04:34:44 +00:00
|
|
|
/*
|
|
|
|
* length will take us past eop. Truncate length.
|
|
|
|
*/
|
2000-01-24 03:33:35 +00:00
|
|
|
length = END_OF_FRAME;
|
1999-12-15 04:34:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
va_start(ap, fmat);
|
2000-08-10 16:04:33 +00:00
|
|
|
proto_tree_add_text_valist(tree, NullTVB, offset, length, fmat, ap);
|
1999-12-15 04:34:44 +00:00
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Name: dissect_isis()
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Main entry area for isis de-mangling. This will build the
|
|
|
|
* main isis tree data and call the sub-protocols as needed.
|
|
|
|
*
|
|
|
|
* Input:
|
|
|
|
* u_char * : packet data
|
|
|
|
* int : offset into packet where we are (packet_data[offset]== start
|
|
|
|
* of what we care about)
|
|
|
|
* frame_data * : frame data (whole packet with extra info)
|
|
|
|
* proto_tree * : tree of display data. May be NULL.
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* void, but we will add to the proto_tree if it is not NULL.
|
|
|
|
*/
|
2000-04-17 01:36:31 +00:00
|
|
|
static void
|
1999-12-15 04:34:44 +00:00
|
|
|
dissect_isis(const u_char *pd, int offset, frame_data *fd,
|
|
|
|
proto_tree *tree) {
|
|
|
|
isis_hdr_t *ihdr;
|
|
|
|
proto_item *ti;
|
|
|
|
proto_tree *isis_tree = NULL;
|
2000-06-19 08:33:50 +00:00
|
|
|
int id_length;
|
1999-12-15 04:34:44 +00:00
|
|
|
|
Add the "Edit:Protocols..." feature which currently only implements
the following:
It is now possible to enable/disable a particular protocol decoding
(i.e. the protocol dissector is void or not). When a protocol
is disabled, it is displayed as Data and of course, all linked
sub-protocols are disabled as well.
Disabling a protocol could be interesting:
- in case of buggy dissectors
- in case of wrong heuristics
- for performance reasons
- to decode the data as another protocol (TODO)
Currently (if I am not wrong), all dissectors but NFS can be disabled
(and dissectors that do not register protocols :-)
I do not like the way the RPC sub-dissectors are disabled (in the
sub-dissectors) since this could be done in the RPC dissector itself,
knowing the sub-protocol hfinfo entry (this is why, I've not modified
the NFS one yet).
Two functions are added in proto.c :
gboolean proto_is_protocol_enabled(int n);
void proto_set_decoding(int n, gboolean enabled);
and two MACROs which can be used in dissectors:
OLD_CHECK_DISPLAY_AS_DATA(index, pd, offset, fd, tree)
CHECK_DISPLAY_AS_DATA(index, tvb, pinfo, tree)
See also the XXX in proto_dlg.c and proto.c around the new functions.
svn path=/trunk/; revision=2267
2000-08-13 14:09:15 +00:00
|
|
|
OLD_CHECK_DISPLAY_AS_DATA(proto_isis, pd, offset, fd, tree);
|
|
|
|
|
2000-04-13 08:14:35 +00:00
|
|
|
if (check_col(fd, COL_PROTOCOL))
|
2000-11-19 08:54:37 +00:00
|
|
|
col_set_str(fd, COL_PROTOCOL, "ISIS");
|
2000-04-13 08:14:35 +00:00
|
|
|
|
2000-01-24 03:33:35 +00:00
|
|
|
if (!BYTES_ARE_IN_FRAME(offset, sizeof(*ihdr))) {
|
1999-12-15 04:34:44 +00:00
|
|
|
isis_dissect_unknown(offset, sizeof(*ihdr), tree, fd,
|
|
|
|
"not enough capture data for header (%d vs %d)",
|
2000-01-24 03:33:35 +00:00
|
|
|
sizeof(*ihdr), END_OF_FRAME);
|
1999-12-15 04:34:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ihdr = (isis_hdr_t *) &pd[offset];
|
|
|
|
|
|
|
|
if (ihdr->isis_version != ISIS_REQUIRED_VERSION){
|
2000-01-24 03:33:35 +00:00
|
|
|
isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
|
1999-12-15 04:34:44 +00:00
|
|
|
"Unknown ISIS version (%d vs %d)",
|
|
|
|
ihdr->isis_version, ISIS_REQUIRED_VERSION );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tree) {
|
2000-05-11 08:18:09 +00:00
|
|
|
ti = proto_tree_add_item(tree, proto_isis, NullTVB, offset,
|
2000-05-31 05:09:07 +00:00
|
|
|
END_OF_FRAME, FALSE );
|
1999-12-15 04:34:44 +00:00
|
|
|
isis_tree = proto_item_add_subtree(ti, ett_isis);
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_irpd, NullTVB, offset, 1,
|
1999-12-15 04:34:44 +00:00
|
|
|
ihdr->isis_irpd );
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_header_length, NullTVB,
|
1999-12-15 04:34:44 +00:00
|
|
|
offset + 1, 1, ihdr->isis_header_length );
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_version, NullTVB,
|
1999-12-15 04:34:44 +00:00
|
|
|
offset + 2, 1, ihdr->isis_version );
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_system_id_length, NullTVB,
|
2000-04-15 22:11:26 +00:00
|
|
|
offset + 3, 1, ihdr->isis_system_id_len );
|
2000-05-11 08:18:09 +00:00
|
|
|
proto_tree_add_uint_format(isis_tree, hf_isis_type, NullTVB,
|
1999-12-15 04:34:44 +00:00
|
|
|
offset + 4, 1, ihdr->isis_type,
|
2001-05-23 18:52:54 +00:00
|
|
|
"PDU Type : %s (R:%s%s%s)",
|
1999-12-15 04:34:44 +00:00
|
|
|
val_to_str(ihdr->isis_type & ISIS_TYPE_MASK, isis_vals,
|
2000-04-15 22:11:26 +00:00
|
|
|
"Unknown (0x%x)"),
|
1999-12-15 04:34:44 +00:00
|
|
|
(ihdr->isis_type & ISIS_R8_MASK) ? "1" : "0",
|
|
|
|
(ihdr->isis_type & ISIS_R7_MASK) ? "1" : "0",
|
|
|
|
(ihdr->isis_type & ISIS_R6_MASK) ? "1" : "0");
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_version2, NullTVB,
|
1999-12-15 04:34:44 +00:00
|
|
|
offset + 5, 1, ihdr->isis_version2 );
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_reserved, NullTVB,
|
2000-04-15 22:11:26 +00:00
|
|
|
offset + 6, 1, ihdr->isis_reserved );
|
2000-05-31 05:09:07 +00:00
|
|
|
proto_tree_add_uint(isis_tree, hf_isis_max_area_adr, NullTVB,
|
2000-04-15 22:11:26 +00:00
|
|
|
offset + 7, 1, ihdr->isis_max_area_adr );
|
1999-12-15 04:34:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Let us make sure we use the same names for all our decodes
|
|
|
|
* here. First, dump the name into info column, and THEN
|
|
|
|
* dispatch the sub-type.
|
|
|
|
*/
|
|
|
|
if (check_col(fd, COL_INFO)) {
|
|
|
|
col_add_str(fd, COL_INFO, val_to_str (
|
|
|
|
ihdr->isis_type&ISIS_TYPE_MASK, isis_vals,
|
|
|
|
"Unknown (0x%x)" ) );
|
|
|
|
}
|
|
|
|
|
2000-06-19 08:33:50 +00:00
|
|
|
/*
|
|
|
|
* Interpret the system ID length.
|
|
|
|
*/
|
|
|
|
id_length = ihdr->isis_system_id_len;
|
|
|
|
if (id_length == 0)
|
|
|
|
id_length = 6; /* zero means 6-octet ID field length */
|
|
|
|
else if (id_length == 255) {
|
|
|
|
id_length = 0; /* 255 means null ID field */
|
|
|
|
/* XXX - what about the LAN ID? */
|
|
|
|
}
|
|
|
|
/* XXX - otherwise, must be in the range 1 through 8 */
|
|
|
|
|
1999-12-15 04:34:44 +00:00
|
|
|
/*
|
|
|
|
* Advance offset (we are past the header).
|
|
|
|
*/
|
|
|
|
offset += sizeof(*ihdr);
|
|
|
|
switch (ihdr->isis_type) {
|
|
|
|
case ISIS_TYPE_L1_HELLO:
|
|
|
|
isis_dissect_isis_hello(ISIS_TYPE_L1_HELLO,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L2_HELLO:
|
|
|
|
isis_dissect_isis_hello(ISIS_TYPE_L2_HELLO,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
case ISIS_TYPE_PTP_HELLO:
|
|
|
|
isis_dissect_isis_hello(ISIS_TYPE_PTP_HELLO,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L1_LSP:
|
2000-06-19 08:33:50 +00:00
|
|
|
isis_dissect_isis_lsp(ISIS_TYPE_L1_LSP,
|
|
|
|
ihdr->isis_header_length, id_length,
|
1999-12-15 04:34:44 +00:00
|
|
|
pd, offset, fd, isis_tree);
|
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L2_LSP:
|
2000-06-19 08:33:50 +00:00
|
|
|
isis_dissect_isis_lsp(ISIS_TYPE_L2_LSP,
|
|
|
|
ihdr->isis_header_length, id_length,
|
1999-12-15 04:34:44 +00:00
|
|
|
pd, offset, fd, isis_tree);
|
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L1_CSNP:
|
|
|
|
isis_dissect_isis_csnp(ISIS_TYPE_L1_CSNP,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L2_CSNP:
|
|
|
|
isis_dissect_isis_csnp(ISIS_TYPE_L2_CSNP,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L1_PSNP:
|
|
|
|
isis_dissect_isis_psnp(ISIS_TYPE_L1_PSNP,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
case ISIS_TYPE_L2_PSNP:
|
|
|
|
isis_dissect_isis_psnp(ISIS_TYPE_L2_PSNP,
|
2000-06-19 08:33:50 +00:00
|
|
|
ihdr->isis_header_length, id_length,
|
|
|
|
pd, offset, fd, isis_tree);
|
1999-12-15 04:34:44 +00:00
|
|
|
break;
|
|
|
|
default:
|
2000-01-24 03:33:35 +00:00
|
|
|
isis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
|
1999-12-15 04:34:44 +00:00
|
|
|
"unknown ISIS packet type" );
|
|
|
|
}
|
|
|
|
} /* dissect_isis */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Name: proto_register_isis()
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* main register for isis protocol set. We register some display
|
|
|
|
* formats and the protocol module variables.
|
|
|
|
*
|
|
|
|
* NOTE: this procedure to autolinked by the makefile process that
|
|
|
|
* builds register.c
|
|
|
|
*
|
|
|
|
* Input:
|
|
|
|
* void
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* void
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
proto_register_isis(void) {
|
2000-04-15 22:11:26 +00:00
|
|
|
static hf_register_info hf[] = {
|
|
|
|
{ &hf_isis_irpd,
|
|
|
|
{ "Intra Domain Routing Protocol Discriminator", "isis.irpd",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(nlpid_vals), 0x0, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_header_length,
|
|
|
|
{ "PDU Header Length ", "isis.len", FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_version,
|
|
|
|
{ "Version (==1) ", "isis.version", FT_UINT8,
|
|
|
|
BASE_DEC, NULL, 0x0, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_system_id_length,
|
|
|
|
{ "System ID Length ", "isis.sysid_len",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_type,
|
2001-05-23 18:52:54 +00:00
|
|
|
{ "PDU Type ", "isis.type", FT_UINT8, BASE_DEC,
|
2000-04-15 22:11:26 +00:00
|
|
|
VALS(isis_vals), 0xff, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_version2,
|
|
|
|
{ "Version2 (==1) ", "isis.version2", FT_UINT8, BASE_DEC, NULL,
|
|
|
|
0x0, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_reserved,
|
|
|
|
{ "Reserved (==0) ", "isis.reserved", FT_UINT8, BASE_DEC, NULL,
|
|
|
|
0x0, "" }},
|
|
|
|
|
|
|
|
{ &hf_isis_max_area_adr,
|
|
|
|
{ "Max.AREAs: (0==3) ", "isis.max_area_adr", FT_UINT8, BASE_DEC, NULL,
|
|
|
|
0x0, "" }},
|
|
|
|
|
|
|
|
};
|
|
|
|
/*
|
|
|
|
* Note, we pull in the unknown CLV handler here, since it
|
|
|
|
* is used by all ISIS packet types.
|
|
|
|
*/
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_isis,
|
|
|
|
};
|
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis");
|
2000-04-15 22:11:26 +00:00
|
|
|
proto_register_field_array(proto_isis, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
1999-12-15 04:34:44 +00:00
|
|
|
}
|
2000-04-17 01:36:31 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_isis(void)
|
|
|
|
{
|
2001-01-09 06:32:10 +00:00
|
|
|
old_dissector_add("osinl", NLPID_ISO10589_ISIS, dissect_isis, proto_isis);
|
2000-04-17 01:36:31 +00:00
|
|
|
}
|