diff options
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | Makefile.am | 12 | ||||
-rw-r--r-- | doc/ethereal.pod.template | 1 | ||||
-rw-r--r-- | gtk/main.c | 3 | ||||
-rw-r--r-- | packet-isis-clv.c | 333 | ||||
-rw-r--r-- | packet-isis-clv.h | 59 | ||||
-rw-r--r-- | packet-isis-hello.c | 580 | ||||
-rw-r--r-- | packet-isis-hello.h | 112 | ||||
-rw-r--r-- | packet-isis-lsp.c | 925 | ||||
-rw-r--r-- | packet-isis-lsp.h | 119 | ||||
-rw-r--r-- | packet-isis-snp.c | 486 | ||||
-rw-r--r-- | packet-isis-snp.h | 102 | ||||
-rw-r--r-- | packet-isis.c | 354 | ||||
-rw-r--r-- | packet-isis.h | 90 | ||||
-rw-r--r-- | packet-osi.c | 4 | ||||
-rw-r--r-- | packet.h | 3 |
16 files changed, 3181 insertions, 5 deletions
@@ -211,6 +211,9 @@ Bert Driehuis <driehuis@playbeing.org> { V.120 } +Stuart Stanley <stuarts@mxmail.net> { + ISIS on CLNP support +} Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to give his permission to use his version of snprintf.c. diff --git a/Makefile.am b/Makefile.am index c2fdd9f092..1ea918c28d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.134 1999/12/12 22:39:29 gram Exp $ +# $Id: Makefile.am,v 1.135 1999/12/15 04:34:17 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@zing.org> @@ -74,6 +74,16 @@ DISSECTOR_SOURCES = \ packet-ipx.h \ packet-irc.c \ packet-isakmp.c\ + packet-isis.h \ + packet-isis.c \ + packet-isis-clv.h \ + packet-isis-clv.c \ + packet-isis-hello.h \ + packet-isis-hello.c \ + packet-isis-lsp.h \ + packet-isis-lsp.c \ + packet-isis-snp.h \ + packet-isis-snp.c \ packet-lapb.c \ packet-lapd.c \ packet-ldap.c \ diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index c681e8b806..3e2d20aa22 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -752,6 +752,7 @@ B<http://ethereal.zing.org>. Dave Chapeskie <dchapes@ddm.on.ca> James Coe <jammer@cin.net> Bert Driehuis <driehuis@playbeing.org> + Stuart Stanley <stuarts@mxmail.net> Alain Magloire <alainm@rcsm.ece.mcgill.ca> was kind enough to give his permission to use his version of snprintf.c. diff --git a/gtk/main.c b/gtk/main.c index c7340088f0..831562d303 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1,6 +1,6 @@ /* main.c * - * $Id: main.c,v 1.71 1999/12/13 04:20:33 gram Exp $ + * $Id: main.c,v 1.72 1999/12/15 04:34:44 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -176,6 +176,7 @@ about_ethereal( GtkWidget *w, gpointer data ) { "Dave Chapeskie <dchapes@ddm.on.ca>\n" "James Coe <jammer@cin.net>\n" "Bert Driehuis <driehuis@playbeing.org>\n" + "Stuart Stanley <stuarts@mxmail.net>\n" "\nSee http://ethereal.zing.org for more information", VERSION, comp_info_str); diff --git a/packet-isis-clv.c b/packet-isis-clv.c new file mode 100644 index 0000000000..9658517604 --- /dev/null +++ b/packet-isis-clv.c @@ -0,0 +1,333 @@ +/* packet-isis-clv.c + * Common CLV decode routines. + * + * $Id: packet-isis-clv.c,v 1.1 1999/12/15 04:34:17 guy Exp $ + * 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" +#include "packet-isis.h" +#include "packet-isis-clv.h" + + +/* + * Name: isis_dissect_area_address_clv() + * + * Description: + * Take an area address CLV and display it pieces. An area address + * CLV is n, x byte hex strings. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_area_address_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ) { + char *sbuf; + int mylen; + + while ( length > 0 ) { + mylen = pd[offset]; + length--; + if (length<=0) { + isis_dissect_unknown( offset, length, tree, fd, + "short address (no length for payload)"); + return; + } + if ( mylen > length) { + isis_dissect_unknown(offset, length, tree, fd, + "short address, packet say %d, we have %d left", + mylen, length ); + return; + } + + /* + * Lets turn the area address into "standard" 0000.0000.etc + * format string. + */ + sbuf = isis_address_to_string ( pd, offset + 1, mylen ); + /* and spit it out */ + if ( tree ) { + proto_tree_add_text ( tree, offset, mylen + 1, + "Area address (%d): %s", mylen, sbuf ); + } + offset += mylen + 1; + length -= mylen; /* length already adjusted for len fld*/ + } +} + + +/* + * Name: isis_dissect_authentication_clv() + * + * Description: + * Take apart the CLV that hold authentication information. This + * is currently 1 octet auth type (which must be 1) and then + * the clear text password. + * + * An ISIS password has different meaning depending where it + * is found. Thus we support a passed in prefix string to + * use to name this. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * char * : Password meaning + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_authentication_clv(const u_char *pd, int offset, guint length, + frame_data *fd, proto_tree *tree, char *meaning) { + u_char pw_type; + char sbuf[300]; /* 255 + header info area */ + char *s = sbuf; + int use_cleartext; + + if ( length <= 0 ) { + return; + } + + pw_type = pd[offset++]; + length--; + use_cleartext = FALSE; + switch (pw_type) { + case 1: + s += sprintf ( s, "type 1, clear text" ); + use_cleartext = TRUE; + break; + default: + s += sprintf ( s, "type 0x%02x, (must be 1)", pw_type ); + break; + } + + s += sprintf ( s, " (0x%02x): ", length ); + + if ( use_cleartext ) { + if ( length > 0 ) { + strncpy(s, &pd[offset], length); + /* null terminate */ + s[length] = 0; + } else { + strcat(s, "<<no password found!!!>>" ); + } + /* NOTE, s no longer valid */ + } + proto_tree_add_text ( tree, offset - 1, length + 1, + "%s %s", meaning, sbuf ); + if ( !use_cleartext ) { + if ( length ) { + isis_dissect_unknown(offset, length, tree, fd, + "Unknown autheticion type" ); + } + } +} +/* + * Name: isis_dissect_ip_int_clv() + * + * Description: + * Take apart the CLV that lists all the IP interfaces. The + * meaning of which is slightly different for the different base packet + * types, but the display is not different. What we have is n ip + * addresses, plain and simple. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * gint : tree id to use for proto tree. + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_ip_int_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree, gint tree_id ) { + guint32 addr; + if ( length <= 0 ) { + return; + } + + while ( length > 0 ) { + if ( length < 4 ) { + isis_dissect_unknown(offset, length, tree, fd, + "Short ip interface address (%d vs 4)",length ); + return; + } + memcpy(&addr, &pd[offset], sizeof(addr)); + if ( tree ) { + proto_tree_add_item(tree, tree_id, offset, 4, addr); + } + offset += 4; + length -= 4; + } +} + +/* + * Name: isis_dissect_nlpid_clv() + * + * Description: + * Take apart a NLPID packet and display it. The NLPID (for intergrated + * ISIS, contains n network layer protocol IDs that the box supports. + * Our display buffer we use is upto 255 entries, 6 bytes per (0x00, ) + * plus 1 for zero termination. We just just 256*6 for simplicity. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_nlpid_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ) { + char sbuf[256*6]; + char *s = sbuf; + int hlen = length; + int old_offset = offset; + + if ( !tree ) return; /* nothing to do! */ + + while ( length-- > 0 ) { + if (s != sbuf ) { + s += sprintf ( s, ", " ); + } + s += sprintf ( s, "0x%02x", pd[offset++] ); + } + if ( hlen == 0 ) { + sprintf ( sbuf, "--none--" ); + } + + proto_tree_add_text ( tree, old_offset, hlen, + "NLPID: %s", sbuf ); +} + +/* + * Name: isis_dissect_clvs() + * + * Description: + * Dispatch routine to shred all the CLVs in a packet. We just + * walk through the clv entries in the packet. For each one, we + * search the passed in valid clv's for this protocol (opts) for + * a matching code. If found, we add to the display tree and + * then call the dissector. If it is not, we just post an + * "unknown" clv entrie using the passed in unknown clv tree id. + * + * Input: + * isis_clv_handle_t * : NULL dissector terminated array of codes + * and handlers (along with tree text and tree id's). + * int : length of CLV area. + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * gint : unknown clv tree id + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_clvs(const isis_clv_handle_t *opts, int len, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree, + gint unknown_tree_id ) { + guint8 code; + guint8 length; + int q; + proto_item *ti; + proto_tree *clv_tree; + char sbuf[255]; + int adj; + + while ( len > 0 ) { + code = pd[offset++]; + length = pd[offset++]; + adj = (sizeof(code) + sizeof(length) + length); + len -= adj; + if ( len < 0 ) { + isis_dissect_unknown(offset, adj, tree, fd, + "Short CLV header (%d vs %d)", + adj, len + adj ); + return; + } + q = 0; + while ((opts[q].dissect != NULL )&&( opts[q].optcode != code )){ + q++; + } + if ( opts[q].dissect ) { + if (tree) { + /* adjust by 2 for code/len octets */ + snprintf ( sbuf, sizeof(sbuf), "%s (%d)", + opts[q].tree_text, length ); + ti = proto_tree_add_text(tree, offset - 2, + length + 2, sbuf); + clv_tree = proto_item_add_subtree(ti, + *opts[q].tree_id ); + } else { + clv_tree = NULL; + } + opts[q].dissect(pd, offset, length, fd, clv_tree ); + } else { + if (tree) { + snprintf ( sbuf, sizeof(sbuf), + "Unknown code (%d:%d)", code, length ); + ti = proto_tree_add_text(tree, offset - 2, + length + 2, sbuf); + clv_tree = proto_item_add_subtree(ti, + unknown_tree_id ); + } else { + clv_tree = NULL; + } + } + offset += length; + } +} diff --git a/packet-isis-clv.h b/packet-isis-clv.h new file mode 100644 index 0000000000..a604364f2f --- /dev/null +++ b/packet-isis-clv.h @@ -0,0 +1,59 @@ +/* packet-isis-clv.h + * Declares for common clv decoding functions. + * + * $Id: packet-isis-clv.h,v 1.1 1999/12/15 04:34:17 guy Exp $ + * 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. + * + * + */ +#ifndef _PACKET_ISIS_CLV_H +#define _PACKET_ISIS_CLV_H + +/* + * Our sub-packet dismantle structure for CLV's + */ +typedef struct { + int optcode; /* code for option */ + char *tree_text; /* text for fold out */ + gint *tree_id; /* id for add_item */ + void (*dissect)(const u_char *pd, int offset, guint length, + frame_data *fd, proto_tree *tree ); +} isis_clv_handle_t; + +/* + * Published API functions. NOTE, this are "local" API functions and + * are only valid from with isis decodes. + */ +extern void isis_dissect_clvs(const isis_clv_handle_t *opts, int len, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree, + int unknown_ett_handle ); +extern void isis_dissect_area_address_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ); +extern void isis_dissect_metric(proto_tree *tree, int offset, guint8 value, + char *pstr, int force_supported, gint tree_id ); +extern void isis_dissect_authentication_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree, char *meaning); +extern void isis_dissect_ip_int_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree, gint tree_id ); +extern void isis_dissect_nlpid_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ); +#endif /* _PACKET_ISIS_CLV_H */ diff --git a/packet-isis-hello.c b/packet-isis-hello.c new file mode 100644 index 0000000000..00b530f342 --- /dev/null +++ b/packet-isis-hello.c @@ -0,0 +1,580 @@ +/* packet-isis-hello.c + * Routines for decoding isis hello packets and their CLVs + * + * $Id: packet-isis-hello.c,v 1.1 1999/12/15 04:34:17 guy Exp $ + * 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" +#include "packet-isis.h" +#include "packet-isis-clv.h" +#include "packet-isis-hello.h" + +/* hello packets */ +static int proto_isis_hello = -1; +static int hf_isis_hello_circuit_reserved = -1; +static int hf_isis_hello_source_id = -1; +static int hf_isis_hello_holding_timer = -1; +static int hf_isis_hello_pdu_length = -1; +static int hf_isis_hello_priority_reserved = -1; +static int hf_isis_hello_lan_id = -1; +static int hf_isis_hello_local_circuit_id = -1; +static int hf_isis_hello_clv_ipv4_int_addr = -1; + +static gint ett_isis_hello = -1; +static gint ett_isis_hello_clv_area_addr = -1; +static gint ett_isis_hello_clv_is_neighbors = -1; +static gint ett_isis_hello_clv_padding = -1; +static gint ett_isis_hello_clv_unknown = -1; +static gint ett_isis_hello_clv_nlpid = -1; +static gint ett_isis_hello_clv_auth = -1; +static gint ett_isis_hello_clv_ipv4_int_addr = -1; + +static const value_string isis_hello_circuit_type_vals[] = { + { ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"}, + { ISIS_HELLO_TYPE_LEVEL_1, "Level 1 only"}, + { ISIS_HELLO_TYPE_LEVEL_2, "Level 2 only"}, + { ISIS_HELLO_TYPE_LEVEL_12, "Level 1 and 2"}, + { 0, NULL} }; + +/* + * Predclare dissectors for use in clv dissection. + */ +static void dissect_hello_area_address_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_hello_is_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_hello_padding_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_hello_nlpid_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_hello_ip_int_addr_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_hello_auth_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); + +static const isis_clv_handle_t clv_l1_hello_opts[] = { + { + ISIS_CLV_L1H_AREA_ADDRESS, + "Area address(es)", + &ett_isis_hello_clv_area_addr, + dissect_hello_area_address_clv + }, + { + ISIS_CLV_L1H_IS_NEIGHBORS, + "IS Neighbor(s)", + &ett_isis_hello_clv_is_neighbors, + dissect_hello_is_neighbors_clv + }, + { + ISIS_CLV_L1H_PADDING, + "Padding", + &ett_isis_hello_clv_padding, + dissect_hello_padding_clv + }, + { + ISIS_CLV_L1H_NLPID, + "NLPID", + &ett_isis_hello_clv_nlpid, + dissect_hello_nlpid_clv + }, + { + ISIS_CLV_L1H_IP_INTERFACE_ADDR, + "IP Interface address(es)", + &ett_isis_hello_clv_ipv4_int_addr, + dissect_hello_ip_int_addr_clv + }, + { + ISIS_CLV_L1H_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_hello_clv_auth, + dissect_hello_auth_clv + }, + { + ISIS_CLV_L1H_AUTHENTICATION, + "Authentication", + &ett_isis_hello_clv_auth, + dissect_hello_auth_clv + }, + { + 0, + "", + NULL, + NULL + } +}; + +static const isis_clv_handle_t clv_l2_hello_opts[] = { + { + ISIS_CLV_L2H_AREA_ADDRESS, + "Area address(es)", + &ett_isis_hello_clv_area_addr, + dissect_hello_area_address_clv + }, + { + ISIS_CLV_L2H_IS_NEIGHBORS, + "IS Neighbor(s)", + &ett_isis_hello_clv_is_neighbors, + dissect_hello_is_neighbors_clv + }, + { + ISIS_CLV_L2H_PADDING, + "Padding", + &ett_isis_hello_clv_padding, + dissect_hello_padding_clv + }, + { + ISIS_CLV_L2H_NLPID, + "NLPID", + &ett_isis_hello_clv_nlpid, + dissect_hello_nlpid_clv + }, + { + ISIS_CLV_L2H_IP_INTERFACE_ADDR, + "IP Interface address(es)", + &ett_isis_hello_clv_ipv4_int_addr, + dissect_hello_ip_int_addr_clv + }, + { + ISIS_CLV_L2H_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_hello_clv_auth, + dissect_hello_auth_clv + }, + { + ISIS_CLV_L2H_AUTHENTICATION, + "Authentication", + &ett_isis_hello_clv_auth, + dissect_hello_auth_clv + }, + { + 0, + "", + NULL, + NULL + } +}; + +static const isis_clv_handle_t clv_ptp_hello_opts[] = { + { + ISIS_CLV_PTP_AREA_ADDRESS, + "Area address(es)", + &ett_isis_hello_clv_area_addr, + dissect_hello_area_address_clv + }, + { + ISIS_CLV_PTP_PADDING, + "Padding", + &ett_isis_hello_clv_padding, + dissect_hello_padding_clv + }, + { + ISIS_CLV_PTP_NLPID, + "NLPID", + &ett_isis_hello_clv_nlpid, + dissect_hello_nlpid_clv + }, + { + ISIS_CLV_PTP_IP_INTERFACE_ADDR, + "IP Interface address(es)", + &ett_isis_hello_clv_ipv4_int_addr, + dissect_hello_ip_int_addr_clv + }, + { + ISIS_CLV_PTP_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_hello_clv_auth, + dissect_hello_auth_clv + }, + { + ISIS_CLV_PTP_AUTHENTICATION, + "Authentication", + &ett_isis_hello_clv_auth, + dissect_hello_auth_clv + }, + { + 0, + "", + NULL, + NULL + } +}; + +/* + * Name: dissect_hello_nlpid_clv() + * + * Description: + * Decode for a hello packets NLPID clv. Calls into the + * clv common one. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_hello_nlpid_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_nlpid_clv(pd, offset, length, fd, tree ); +} + +/* + * Name: dissect_hello_ip_int_addr_clv() + * + * Description: + * Decode for a hello packets ip interface addr clv. Calls into the + * clv common one. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_hello_ip_int_addr_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_ip_int_clv(pd, offset, length, fd, tree, + hf_isis_hello_clv_ipv4_int_addr ); +} + +/* + * Name: dissect_hello_auth_clv() + * + * Description: + * Decode for a hello packets authenticaion clv. Calls into the + * clv common one. An auth inside a hello packet is a perlink + * password. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_hello_auth_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_authentication_clv(pd, offset, length, fd, tree, + "Per Link authentication" ); +} + +/* + * Name: dissect_hello_area_address_clv() + * + * Description: + * Decode for a hello packets area address clv. Calls into the + * clv common one. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_hello_area_address_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_area_address_clv(pd, offset, length, fd, tree ); +} + +/* + * Name: isis_dissect_is_neighbors_clv() + * + * Description: + * Take apart a IS neighbor packet. A neighbor is n 6 byte packets. + * (they tend to be an 802.3 MAC address, but its not required). + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * gint : tree id to use for proto tree. + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +dissect_hello_is_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ) { + while ( length > 0 ) { + if (length<6) { + isis_dissect_unknown(offset, length, tree, fd, + "short is neighbor (%d vs 6)", length ); + return; + } + /* + * Lets turn the area address into "standard" 0000.0000.etc + * format string. + */ + if ( tree ) { + proto_tree_add_text ( tree, offset, 6, + "IS Neighbor: %02x%02x.%02x%02x.%02x%02x", + pd[offset], pd[offset+1], pd[offset+2], + pd[offset+3], pd[offset+3], pd[offset+4] ); + } + offset += 6; + length -= 6; + } +} + + +/* + * Name: dissect_hello_padding_clv() + * + * Description: + * Decode for a hello packet's padding clv. Padding does nothing, + * so we just return. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void + */ +static void +dissect_hello_padding_clv(const u_char *pd, int offset, guint length, + frame_data *fd, proto_tree *tree) { + /* nothing to do here! */ +} + +/* + * Name: isis_dissect_isis_hello() + * + * Description: + * This procedure rips apart the various types of ISIS hellos. L1H and + * L2H's are identicle for the most part, while the PTP hello has + * a shorter header. + * + * Input: + * int : hello type, alla packet-isis.h ISIS_TYPE_* values + * int : header length of packet. + * u_char * : packet data + * int offset : our offset into packet data. + * frame_data * : frame data + * proto_tree * : protocol display tree to add to. May be NULL. + * + * Output: + * void, will modify proto_tree if not NULL. + */ +void +isis_dissect_isis_hello(int hello_type, int header_length, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree){ + isis_hello_t *ihp; + proto_item *ti; + proto_tree *hello_tree = NULL; + int len; + int hlen; + + if (hello_type == ISIS_TYPE_PTP_HELLO) { + hlen = sizeof(*ihp) - 6; /* make length correct */ + } else { + hlen = sizeof(*ihp); + } + + if (fd->cap_len < (offset + hlen)) { + isis_dissect_unknown(offset, hlen, tree, fd, + "not enough capture data for header (%d vs %d)", + hlen, offset - fd->cap_len); + return; + } + + ihp = (isis_hello_t *) &pd[offset]; + + if (tree) { + ti = proto_tree_add_item(tree, proto_isis_hello, + offset, fd->cap_len - offset, NULL); + hello_tree = proto_item_add_subtree(ti, ett_isis_hello); + proto_tree_add_item_format(hello_tree, + hf_isis_hello_circuit_reserved, + offset, 1, ihp->isis_hello_circuit_reserved, + "Circuit type: %s, reserved(0x%02x == 0)", + val_to_str(ihp->isis_hello_circuit, + isis_hello_circuit_type_vals, + "Unknown (0x%x)"), + ihp->isis_hello_creserved + ); + + proto_tree_add_item_format(hello_tree, hf_isis_hello_lan_id, + offset + 1, 6, ihp->isis_hello_source_id, + "Lan ID: %02x%02x.%02x%02x.%02x%02x", + ihp->isis_hello_lan_id[0], + ihp->isis_hello_lan_id[1], + ihp->isis_hello_lan_id[2], + ihp->isis_hello_lan_id[3], + ihp->isis_hello_lan_id[4], + ihp->isis_hello_lan_id[5]); + proto_tree_add_item(hello_tree, hf_isis_hello_holding_timer, + offset + 7, 2,pntohs(&ihp->isis_hello_holding_timer[0])); + proto_tree_add_item(hello_tree, hf_isis_hello_pdu_length, + offset + 9, 2,pntohs(&ihp->isis_hello_pdu_length[0])); + proto_tree_add_item_format(hello_tree, + hf_isis_hello_priority_reserved, + offset + 11, 1, ihp->isis_hello_priority_reserved, + "Priority: %d, reserved(0x%02x == 0)", + ihp->isis_hello_priority, + ihp->isis_hello_preserved ); + if (hello_type == ISIS_TYPE_PTP_HELLO) { + proto_tree_add_item_format(hello_tree, + hf_isis_hello_local_circuit_id, + offset + 12, 1, ihp->isis_hello_lan_id[0] ); + } else { + proto_tree_add_item_format(hello_tree, + hf_isis_hello_lan_id, offset + 12, 7, + ihp->isis_hello_lan_id, + "Lan ID: %02x%02x.%02x%02x.%02x%02x-%02d", + ihp->isis_hello_lan_id[0], + ihp->isis_hello_lan_id[1], + ihp->isis_hello_lan_id[2], + ihp->isis_hello_lan_id[3], + ihp->isis_hello_lan_id[4], + ihp->isis_hello_lan_id[5], + ihp->isis_hello_lan_id[6]); + } + } + + offset += hlen; + len = pntohs(&ihp->isis_hello_pdu_length[0]); + len -= header_length; + if (len < 0) { + isis_dissect_unknown(offset, header_length, tree, fd, + "packet header length %d went beyond packet", + header_length ); + return; + } + /* + * Now, we need to decode our CLVs. We need to pass in + * our list of valid ones! + */ + if (hello_type == ISIS_TYPE_L1_HELLO){ + isis_dissect_clvs ( clv_l1_hello_opts, len, pd, offset, fd, + hello_tree, ett_isis_hello_clv_unknown ); + } else if (hello_type == ISIS_TYPE_L2_HELLO) { + isis_dissect_clvs ( clv_l2_hello_opts, len, pd, offset, fd, + hello_tree, ett_isis_hello_clv_unknown ); + } else { + isis_dissect_clvs ( clv_ptp_hello_opts, len, pd, offset, fd, + hello_tree, ett_isis_hello_clv_unknown ); + } +} + +/* + * Name: proto_register_isis_hello() + * + * Description: + * Register our protocol sub-sets with protocol manager. + * NOTE: this procedure is autolinked by the makefile process that + * builds register.c + * + * Input: + * void + * + * Output: + * void + */ +void +proto_register_isis_hello(void) { + static hf_register_info hf[] = { + { &hf_isis_hello_circuit_reserved, + { "Circuit type", "", FT_UINT8, BASE_HEX, NULL, + 0x0, "" }}, + + { &hf_isis_hello_source_id, + { "Source ID", "isis_hello.source_id", FT_ETHER, + BASE_HEX, NULL, 0x0, "" }}, + + { &hf_isis_hello_holding_timer, + { "Holding timer", "isis_hello.holding_timer", + FT_UINT16, BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_hello_pdu_length, + { "PDU length", "isis_hello.pdu_length", FT_UINT16, + BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_hello_priority_reserved, + { "Priority", "",FT_UINT8, BASE_DEC, NULL, + ISIS_HELLO_P_RESERVED_MASK, "" }}, + + { &hf_isis_hello_lan_id, + { "LAN ID", "", FT_STRING, BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_hello_local_circuit_id, + { "Local circuit ID", "isis_hello.local_circuit_id", FT_UINT8, + BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_hello_clv_ipv4_int_addr, + { "IPv4 interface address", "", FT_IPv4, + BASE_NONE, NULL, 0x0, "" }}, + + }; + static gint *ett[] = { + &ett_isis_hello, + &ett_isis_hello_clv_area_addr, + &ett_isis_hello_clv_is_neighbors, + &ett_isis_hello_clv_padding, + &ett_isis_hello_clv_unknown, + &ett_isis_hello_clv_nlpid, + &ett_isis_hello_clv_auth, + &ett_isis_hello_clv_ipv4_int_addr, + }; + + proto_isis_hello = proto_register_protocol("ISIS hello", "ISIS-hello"); + proto_register_field_array(proto_isis_hello, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + diff --git a/packet-isis-hello.h b/packet-isis-hello.h new file mode 100644 index 0000000000..9fa0099253 --- /dev/null +++ b/packet-isis-hello.h @@ -0,0 +1,112 @@ +/* packet-isis-hello.h + * Declares for hello handling inside isis. + * + * $Id: packet-isis-hello.h,v 1.1 1999/12/15 04:34:18 guy Exp $ + * 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. + * + * + */ + +#ifndef _PACKET_ISIS_HELLO_H +#define _PACKET_ISIS_HELLO_H + +/* + * Declare L1/L2 hello base header. + */ +typedef struct { + guint8 isis_hello_circuit_reserved; /* circuit type & reserved */ +#define ISIS_HELLO_CTYPE_MASK 0x03 +#define ISIS_HELLO_CT_RESERVED_MASK 0xfc + guint8 isis_hello_source_id[6]; /* source id */ + guint8 isis_hello_holding_timer[2]; /* holding timer */ + guint8 isis_hello_pdu_length[2]; /* full length, including hdr */ + guint8 isis_hello_priority_reserved; /* priority & reserved */ +#define ISIS_HELLO_PRIORITY_MASK 0x7f +#define ISIS_HELLO_P_RESERVED_MASK 0x80 + guint8 isis_hello_lan_id[7]; /* LAN id */ +} isis_hello_t; + +#define isis_hello_circuit isis_hello_circuit_reserved&ISIS_HELLO_CTYPE_MASK +#define isis_hello_creserved \ + isis_hello_circuit_reserved&ISIS_HELLO_CT_RESERVED_MASK + +#define isis_hello_priority \ + isis_hello_priority_reserved&ISIS_HELLO_PRIORITY_MASK +#define isis_hello_preserved \ + isis_hello_priority_reserved&ISIS_HELLO_P_RESERVED_MASK + +#define ISIS_HELLO_TYPE_RESERVED 0 +#define ISIS_HELLO_TYPE_LEVEL_1 1 +#define ISIS_HELLO_TYPE_LEVEL_2 2 +#define ISIS_HELLO_TYPE_LEVEL_12 3 + +/* + * detail clv information on l1 hello packets + */ +#define ISIS_CLV_L1H_AREA_ADDRESS 1 +#define ISIS_CLV_L1H_IS_NEIGHBORS 6 +#define ISIS_CLV_L1H_PADDING 8 +#define ISIS_CLV_L1H_NLPID 129 +#define ISIS_CLV_L1H_IP_INTERFACE_ADDR 132 +/* + * Note, the spec say 133, but everyone seems to use 10. Any clue on why + * this is would be appreciated! + */ +#define ISIS_CLV_L1H_AUTHENTICATION_NS 10 /*non spec */ +#define ISIS_CLV_L1H_AUTHENTICATION 133 + +/* + * detail clv information on l2 hello packets + */ +#define ISIS_CLV_L2H_AREA_ADDRESS 1 +#define ISIS_CLV_L2H_IS_NEIGHBORS 6 +#define ISIS_CLV_L2H_PADDING 8 +#define ISIS_CLV_L2H_NLPID 129 +#define ISIS_CLV_L2H_IP_INTERFACE_ADDR 132 +/* + * Note, the spec say 133, but everyone seems to use 10. Any clue on why + * this is would be appreciated! + */ +#define ISIS_CLV_L2H_AUTHENTICATION_NS 10 /*non spec */ +#define ISIS_CLV_L2H_AUTHENTICATION 133 + +/* + * detail clv information on PTP hello packets + */ +#define ISIS_CLV_PTP_AREA_ADDRESS 1 +#define ISIS_CLV_PTP_PADDING 8 +#define ISIS_CLV_PTP_NLPID 129 +#define ISIS_CLV_PTP_IP_INTERFACE_ADDR 132 +/* + * Note, the spec say 133, but everyone seems to use 10. Any clue on why + * this is would be appreciated! + */ +#define ISIS_CLV_PTP_AUTHENTICATION_NS 10 /*non spec */ +#define ISIS_CLV_PTP_AUTHENTICATION 133 + +/* + * Published API functions. NOTE, this are "local" API functions and + * are only valid from with isis decodes. + */ +extern void isis_dissect_isis_hello(int hello_type, int header_length, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree); +#endif /* _PACKET_ISIS_HELLO_H */ diff --git a/packet-isis-lsp.c b/packet-isis-lsp.c new file mode 100644 index 0000000000..aa9352694c --- /dev/null +++ b/packet-isis-lsp.c @@ -0,0 +1,925 @@ +/* packet-isis-lsp.c + * Routines for decoding isis lsp packets and their CLVs + * + * $Id: packet-isis-lsp.c,v 1.1 1999/12/15 04:34:18 guy Exp $ + * 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 <netinet/in.h> +#include "packet.h" +#include "resolv.h" +#include "packet-isis.h" +#include "packet-isis-clv.h" +#include "packet-isis-lsp.h" + +/* lsp packets */ +static int proto_isis_lsp = -1; +static int hf_isis_lsp_pdu_length = -1; +static int hf_isis_lsp_remaining_life = -1; +static int hf_isis_lsp_sequence_number = -1; +static int hf_isis_lsp_checksum = -1; +static int hf_isis_lsp_clv_ipv4_int_addr = -1; + +static gint ett_isis_lsp = -1; +static gint ett_isis_lsp_clv_area_addr = -1; +static gint ett_isis_lsp_clv_is_neighbors = -1; +static gint ett_isis_lsp_clv_unknown = -1; +static gint ett_isis_lsp_clv_partition_dis = -1; +static gint ett_isis_lsp_clv_prefix_neighbors = -1; +static gint ett_isis_lsp_clv_nlpid = -1; +static gint ett_isis_lsp_clv_auth = -1; +static gint ett_isis_lsp_clv_ipv4_int_addr = -1; +static gint ett_isis_lsp_clv_ip_reachability = -1; + +static const char *isis_lsp_attached_bits[] = { + "error", "expense", "delay", "default" }; + +static const value_string isis_lsp_istype_vals[] = { + { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_1, "Level 1 IS"}, + { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_2, "Level 2 IS"}, + { 0, NULL } }; + +/* + * Predclare dissectors for use in clv dissection. + */ +static void dissect_lsp_area_address_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_l1_is_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_l1_es_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_l2_is_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_partition_dis_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_prefix_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_ip_reachability_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_nlpid_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_ip_int_addr_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_l1_auth_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); +static void dissect_lsp_l2_auth_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree); + +static const isis_clv_handle_t clv_l1_lsp_opts[] = { + { + ISIS_CLV_L1_LSP_AREA_ADDRESS, + "Area address(es)", + &ett_isis_lsp_clv_area_addr, + dissect_lsp_area_address_clv + }, + { + ISIS_CLV_L1_LSP_IS_NEIGHBORS, + "IS Neighbor(s)", + &ett_isis_lsp_clv_is_neighbors, + dissect_lsp_l1_is_neighbors_clv + }, + { + ISIS_CLV_L1_LSP_ES_NEIGHBORS, + "ES Neighbor(s)", + &ett_isis_lsp_clv_is_neighbors, + dissect_lsp_l1_es_neighbors_clv + }, + { + ISIS_CLV_L1_LSP_IP_INT_REACHABLE, + "IP Internal reachability", + &ett_isis_lsp_clv_ip_reachability, + dissect_lsp_ip_reachability_clv + }, + { + ISIS_CLV_L1_LSP_NLPID, + "NLPID", + &ett_isis_lsp_clv_nlpid, + dissect_lsp_nlpid_clv + }, + { + ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR, + "IP Interface address(es)", + &ett_isis_lsp_clv_ipv4_int_addr, + dissect_lsp_ip_int_addr_clv + }, + { + ISIS_CLV_L1_LSP_AUTHENTICATION_NS, + "Authentication(non-spec)", + &ett_isis_lsp_clv_auth, + dissect_lsp_l1_auth_clv + }, + { + ISIS_CLV_L1_LSP_AUTHENTICATION, + "Authentication", + &ett_isis_lsp_clv_auth, + dissect_lsp_l1_auth_clv + }, + { + 0, + "", + NULL, + NULL + } +}; + +static const isis_clv_handle_t clv_l2_lsp_opts[] = { + { + ISIS_CLV_L1_LSP_AREA_ADDRESS, + "Area address(es)", + &ett_isis_lsp_clv_area_addr, + dissect_lsp_area_address_clv + }, + { + ISIS_CLV_L2_LSP_IS_NEIGHBORS, + "IS Neighbor(s)", + &ett_isis_lsp_clv_is_neighbors, + dissect_lsp_l2_is_neighbors_clv + }, + { + ISIS_CLV_L2_LSP_PARTITION_DIS, + "Parition Designated Level 2 IS", + &ett_isis_lsp_clv_partition_dis, + dissect_lsp_partition_dis_clv + }, + { + ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS, + "Prefix neighbors", + &ett_isis_lsp_clv_prefix_neighbors, + dissect_lsp_prefix_neighbors_clv + }, + { + ISIS_CLV_L2_LSP_IP_INT_REACHABLE, + "IP Internal reachability", + &ett_isis_lsp_clv_ip_reachability, + dissect_lsp_ip_reachability_clv + }, + { + ISIS_CLV_L2_LSP_NLPID, + "NLPID", + &ett_isis_lsp_clv_nlpid, + dissect_lsp_nlpid_clv + }, + { + ISIS_CLV_L2_LSP_IP_EXT_REACHABLE, + "IP external reachability", + &ett_isis_lsp_clv_ip_reachability, + dissect_lsp_ip_reachability_clv + }, + { + ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR, + "IP Interface address(es)", + &ett_isis_lsp_clv_ipv4_int_addr, + dissect_lsp_ip_int_addr_clv + }, + { + ISIS_CLV_L2_LSP_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_lsp_clv_auth, + dissect_lsp_l2_auth_clv + }, + { + ISIS_CLV_L2_LSP_AUTHENTICATION, + "Authentication", + &ett_isis_lsp_clv_auth, + dissect_lsp_l2_auth_clv + }, + { + 0, + "", + NULL, + NULL + } +}; + + +/* + * Name: dissect_metric() + * + * Description: + * Display a metric prefix portion. ISIS has the concept of multple + * metric per prefix (default, delay, expense, and error). This + * routine assists other dissectors by adding a single one of + * these to the display tree.. + * + * The 8th(msbit) bit in the metric octet is the "supported" bit. The + * "default" support is required, so we support a "force_supported" + * flag that tells us that it MUST be zero (zero==supported, + * so it really should be a "not supported" in the boolean sense) + * and to display a protocol failure accordingly. Notably, + * Cisco IOS 12(6) blows this! + * The 7th bit must be zero (reserved). + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * int : force supported. True is the supported bit MUST be zero. + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_metric(proto_tree *tree, int offset, guint8 value, + char *pstr, int force_supported ) { + int s; + + if ( !tree ) return; + + s = ISIS_LSP_CLV_METRIC_SUPPORTED(value); + proto_tree_add_text ( tree, offset, 1, + "%s Metric: %s%s %s%d:%d", pstr, + s ? "Not supported" : "Supported", + (s && force_supported) ? "(but is required to be)":"", + ISIS_LSP_CLV_METRIC_RESERVED(value) ? "(reserved bit != 0)":"", + ISIS_LSP_CLV_METRIC_VALUE(value), value ); +} + + +/* + * Name: dissect_lsp_ip_reachabillityclv() + * + * Description: + * Decode an IP reachability CLV. This can be either internal or + * external (the clv format does not change and which type we are + * displaying is put there by the dispatcher). All of these + * are a metric block followed by an IP addr and mask. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_lsp_ip_reachability_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + proto_item *ti; + proto_tree *ntree = NULL; + guint32 src, mask; + + while ( length > 0 ) { + if (length<12) { + isis_dissect_unknown(offset, length, tree, fd, + "short IP reachability (%d vs 12)", length ); + return; + } + /* + * Gotta build a sub-tree for all our pieces + */ + if ( tree ) { + memcpy(&src, &pd[offset+4], 4); + memcpy(&mask, &pd[offset+8], 4); + ti = proto_tree_add_text ( tree, offset, 12, + "IP prefix: %s (%s) : %s", + get_hostname(src), ip_to_str((guint8*)&src), + ip_to_str((guint8*)&mask) ); + ntree = proto_item_add_subtree(ti, + ett_isis_lsp_clv_ip_reachability); + dissect_metric ( ntree, offset, pd[offset], "Default", + TRUE ); + dissect_metric ( ntree, offset + 1, pd[offset+1], + "Delay", FALSE ); + dissect_metric ( ntree, offset + 2, pd[offset+2], + "Expense",FALSE ); + dissect_metric ( ntree, offset + 3, pd[offset+3], + "Error", FALSE ); + } + offset += 12; + length -= 12; + } +} +/* + * Name: dissect_lsp_nlpid_clv() + * + * Description: + * Decode for a lsp packets NLPID clv. Calls into the + * clv common one. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_lsp_nlpid_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_nlpid_clv(pd, offset, length, fd, tree ); +} + +/* + * Name: dissect_lsp_ip_int_addr_clv() + * + * Description: + * Decode for a lsp packets ip interface addr clv. Calls into the + * clv common one. + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_lsp_ip_int_addr_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_ip_int_clv(pd, offset, length, fd, tree, + hf_isis_lsp_clv_ipv4_int_addr ); +} + +/* + * Name: dissect_lsp_L1_auth_clv() + * + * Description: + * Decode for a lsp packets authenticaion clv. Calls into the + * clv common one. An auth inside a L1 LSP is a per area password + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_lsp_l1_auth_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_authentication_clv(pd, offset, length, fd, tree, + "Per area authentication" ); +} + +/* + * Name: dissect_lsp_L2_auth_clv() + * + * Description: + * Decode for a lsp packets authenticaion clv. Calls into the + * clv common one. An auth inside a L2 LSP is a per domain password + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_lsp_l2_auth_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_authentication_clv(pd, offset, length, fd, tree, + "Per domain authentication" ); +} + +/* + * Name: dissect_lsp_area_address_clv() + * + * Description: + * Decode for a lsp packet's area address clv. Call into clv common + * one. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_area_address_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_area_address_clv(pd, offset, length, fd, tree ); +} + +/* + * Name: dissect_lsp_eis_neighbors_clv_inner() + * + * Description: + * Real work horse for showing neighbors. This means we decode the + * first octet as either virtual/!virtual (if show_virtual param is + * set), or as a must == 0 reserved value. + * + * Once past that, we decode n neighbor elements. Each neighbor + * is comprised of a metric block (is dissect_metric) and the + * addresses. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * int : set to decode first octet as virtual vs reserved == 0 + * int : set to indicate EIS instead of IS (6 octet per addr instead of 7) + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_eis_neighbors_clv_inner(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree, + int show_virtual, int is_eis) { + proto_item *ti; + proto_tree *ntree = NULL; + int tlen; + + if (is_eis) { + tlen = 10; + } else { + tlen = 11; + if ( tree ) { + if ( show_virtual ) { + /* virtual path flag */ + proto_tree_add_text ( tree, offset, 1, + &pd[offset] ? "IsNotVirtual" : "IsVirtual" ); + } else { + proto_tree_add_text ( tree, offset, 1, + "Reserved value 0x%02x, must == 0", + pd[offset] ); + } + } + offset++; + length--; + + } + + while ( length > 0 ) { + if (length<tlen) { + isis_dissect_unknown(offset, length, tree, fd, + "short E/IS reachability (%d vs %d)", length, + tlen ); + return; + } + /* + * Gotta build a sub-tree for all our pieces + */ + if ( tree ) { + if ( is_eis ) { + ti = proto_tree_add_text ( tree, offset, 11, + "ES Neighbor: %02x%02x.%02x%02x.%02x%02x", + pd[offset+4], pd[offset+5], + pd[offset+6], pd[offset+7], + pd[offset+8], pd[offset+9] ); + } else { + ti = proto_tree_add_text ( tree, offset, 11, + "IS Neighbor: %02x%02x.%02x%02x.%02x%02x-%02x", + pd[offset+4], pd[offset+5], + pd[offset+6], pd[offset+7], + pd[offset+8], pd[offset+9], + pd[offset+10] ); + } + ntree = proto_item_add_subtree(ti, + ett_isis_lsp_clv_is_neighbors); + dissect_metric ( ntree, offset, pd[offset], "Default", + TRUE ); + dissect_metric ( ntree, offset + 1, pd[offset+1], + "Delay", FALSE ); + dissect_metric ( ntree, offset + 2, pd[offset+2], + "Expense",FALSE ); + dissect_metric ( ntree, offset + 3, pd[offset+3], + "Error", FALSE ); + } + offset += tlen; + length -= tlen; + } +} + +/* + * Name: dissect_lsp_l1_is_neighbors_clv() + * + * Description: + * Dispatch a l1 intermediate system neighbor by calling + * the inner function with show virtual set to TRUE and is es set to FALSE. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_l1_is_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + dissect_lsp_eis_neighbors_clv_inner( pd, offset, length, fd, tree,TRUE, + FALSE ); +} + +/* + * Name: dissect_lsp_l1_es_neighbors_clv() + * + * Description: + * Dispatch a l1 end or intermediate system neighbor by calling + * the inner function with show virtual set to TRUE and es set to TRUE. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_l1_es_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + dissect_lsp_eis_neighbors_clv_inner( pd, offset, length, fd, tree, + TRUE, TRUE); +} + +/* + * Name: dissect_lsp_l2_is_neighbors_clv() + * + * Description: + * Dispatch a l2 intermediate system neighbor by calling + * the inner function with show virtual set to FALSE, and is es set + * to FALSE + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_l2_is_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + dissect_lsp_eis_neighbors_clv_inner(pd,offset, length, fd, tree, FALSE, + FALSE); +} + +/* + * Name: dissect_lsp_partition_dis_clv() + * + * Description: + * This CLV is used to indicate which system is the designated + * IS for partition repair. This means just putting out the 6 octet + * IS. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_partition_dis_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + + if ( length < 6 ) { + isis_dissect_unknown(offset, length, tree, fd, + "short lsp parition DIS(%d vs 6)", length ); + return; + } + /* + * Gotta build a sub-tree for all our pieces + */ + if ( tree ) { + proto_tree_add_text ( tree, offset+4, 6, + "Partition designated L2 IS: %02x%02x.%02x%02x.%02x%02x", + pd[offset], pd[offset+1], pd[offset+2], + pd[offset+3], pd[offset+4], pd[offset+5]); + } + length -= 6; + offset += 6; + if ( length > 0 ){ + isis_dissect_unknown(offset, length, tree, fd, + "Long lsp parition DIS, %d left over", length ); + return; + } +} + +/* + * Name: dissect_lsp_prefix_neighbors_clv() + * + * Description: + * The prefix CLV describes what other (OSI) networks we can reach + * and what their cost is. It is built from a metric block + * (see dissect_metric) followed by n addresses. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_lsp_prefix_neighbors_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + char *sbuf; + int mylen; + + if ( length < 4 ) { + isis_dissect_unknown(offset, length, tree, fd, + "Short lsp prefix neighbors (%d vs 4)", length ); + return; + } + if ( tree ) { + dissect_metric ( tree, offset, pd[offset], "Default", TRUE ); + dissect_metric ( tree, offset + 1, pd[offset+1], + "Delay", FALSE ); + dissect_metric ( tree, offset + 2, pd[offset+2], + "Expense", FALSE ); + dissect_metric ( tree, offset + 3, pd[offset+3], + "Error", FALSE ); + } + offset += 4; + length -= 4; + while ( length > 0 ) { + mylen = pd[offset]; + length--; + if (length<=0) { + isis_dissect_unknown(offset, length, tree, fd, + "Zero payload space after length in prefix neighbor" ); + return; + } + if ( mylen > length) { + isis_dissect_unknown(offset, length, tree, fd, + "Interal length of prefix neighbor too long (%d vs %d)", + mylen, length ); + return; + } + + /* + * Lets turn the area address into "standard" 0000.0000.etc + * format string. + */ + sbuf = isis_address_to_string ( pd, offset + 1, mylen ); + /* and spit it out */ + if ( tree ) { + proto_tree_add_text ( tree, offset, mylen + 1, + "Area address (%d): %s", mylen, sbuf ); + } + offset += mylen + 1; + length -= mylen; /* length already adjusted for len fld*/ + } +} + +/* + * Name: isis_lsp_decode_lsp_id() + * + * Description: + * Display a LSP id into the display tree. + * + * Input: + * char * : title string + * proto_tree * : tree to display into. REQUIRED + * int : offset into packet data where we are. + * isis_lsp_id_t * : id to display. + * + * Output: + * void, but we will add to proto tree + */ +void +isis_lsp_decode_lsp_id(char *tstr, proto_tree *tree, int offset, + isis_lsp_id_t *id ) { + proto_tree_add_text(tree, offset, 8, + "%s: %02x%02x.%02x%02x.%02x%02x.%02x-%02x", tstr, + id->source_id[0], + id->source_id[1], + id->source_id[2], + id->source_id[3], + id->source_id[4], + id->source_id[5], + id->psuodonode_id, + id->lsp_number ); +} + +/* + * Name: isis_dissect_isis_lsp() + * + * Description: + * Print out the LSP part of the main header and then call the CLV + * de-mangler with the right list of valid CLVs. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_isis_lsp(int lsp_type, int header_length, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree){ + isis_lsp_t *ilp; + proto_item *ti; + proto_tree *lsp_tree = NULL; + int hlen; + char sbuf[128]; + int inx, q, some, value, len; + + hlen = sizeof(*ilp); + + if (fd->cap_len < (offset + hlen)) { + isis_dissect_unknown(offset, hlen, tree, fd, + "not enough capture data for header (%d vs %d)", + hlen, offset - fd->cap_len); + return; + } + + ilp = (isis_lsp_t *) &pd[offset]; + + if (tree) { + ti = proto_tree_add_item(tree, proto_isis_lsp, + offset, fd->cap_len - offset, NULL); + lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp); + proto_tree_add_item(lsp_tree, hf_isis_lsp_pdu_length, + offset, 2, pntohs(&ilp->isis_lsp_pdu_length)); + proto_tree_add_item(lsp_tree, hf_isis_lsp_remaining_life, + offset + 2, 2, pntohs(&ilp->isis_lsp_remaining_life)); + isis_lsp_decode_lsp_id("LSP ID", lsp_tree, offset + 4, + &ilp->isis_lsp_id ); + proto_tree_add_item(lsp_tree, hf_isis_lsp_sequence_number, + offset + 12, 4, + pntohl(&ilp->isis_lsp_sequence_number)); + + /* XXX -> we could validate the cksum here! */ + proto_tree_add_item(lsp_tree, hf_isis_lsp_checksum, + offset + 16, 2, pntohs(&ilp->isis_lsp_checksum)); + + /* + * We need to build our type block values. + */ + sbuf[0] = 0; + some = 0; + value = ISIS_LSP_ATT(ilp->isis_lsp_type_block); + inx = 0; + for ( q = (1<<ISIS_LSP_ATT_SHIFT); q > 0; q = q >> 1 ){ + if (q & value) { + if (some++) { + strcat(sbuf, ", "); + } + strcat ( sbuf, isis_lsp_attached_bits[inx] ); + } + inx++; + } + if (!some) { + strcat ( sbuf, "<none set!>" ); + } + proto_tree_add_text(lsp_tree, offset + 18, 1, + "Type block(0x%02x): P:%d, Supported metric(s): %s, OL:%d, istype:%s", + ilp->isis_lsp_type_block, + ISIS_LSP_PARTITION(ilp->isis_lsp_type_block) ? 1 : 0, + sbuf, + ISIS_LSP_HIPPITY(ilp->isis_lsp_type_block) ? 1 : 0, + val_to_str(ISIS_LSP_IS_TYPE(ilp->isis_lsp_type_block), + isis_lsp_istype_vals, "Unknown (0x%x)") + ); + + } + + offset += hlen; + len = pntohs(&ilp->isis_lsp_pdu_length); + len -= header_length; + if (len < 0) { + isis_dissect_unknown(offset, header_length, tree, fd, + "packet header length %d went beyond packet", + header_length ); + return; + } + /* + * Now, we need to decode our CLVs. We need to pass in + * our list of valid ones! + */ + if (lsp_type == ISIS_TYPE_L1_LSP){ + isis_dissect_clvs ( clv_l1_lsp_opts, len, pd, offset, fd, + lsp_tree, ett_isis_lsp_clv_unknown ); + } else { + isis_dissect_clvs ( clv_l2_lsp_opts, len, pd, offset, fd, + lsp_tree, ett_isis_lsp_clv_unknown ); + } +} +/* + * Name: proto_register_isis_lsp() + * + * Description: + * Register our protocol sub-sets with protocol manager. + * NOTE: this procedure is autolinked by the makefile process that + * builds register.c + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +proto_register_isis_lsp(void) { + static hf_register_info hf[] = { + { &hf_isis_lsp_pdu_length, + { "PDU length", "isis_lsp.pdu_length", FT_UINT16, + BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_lsp_remaining_life, + { "Remaining life", "isis_lsp.remaining_life", FT_UINT16, + BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_lsp_sequence_number, + { "Sequence number", "isis_lsp.sequence_number", + FT_UINT32, BASE_HEX, NULL, 0x0, "" }}, + + { &hf_isis_lsp_checksum, + { "Checksum", "isis_lsp.checksum",FT_UINT16, + BASE_HEX, NULL, 0x0, "" }}, + + { &hf_isis_lsp_clv_ipv4_int_addr, + { "IPv4 interface address: ", "", FT_IPv4, + BASE_NONE, NULL, 0x0, "" }}, + }; + static gint *ett[] = { + &ett_isis_lsp, + &ett_isis_lsp_clv_area_addr, + &ett_isis_lsp_clv_is_neighbors, + &ett_isis_lsp_clv_unknown, + &ett_isis_lsp_clv_partition_dis, + &ett_isis_lsp_clv_prefix_neighbors, + &ett_isis_lsp_clv_auth, + &ett_isis_lsp_clv_nlpid, + &ett_isis_lsp_clv_ipv4_int_addr, + &ett_isis_lsp_clv_ip_reachability, + }; + + proto_isis_lsp = proto_register_protocol("ISIS lsp", "ISIS-lsp"); + proto_register_field_array(proto_isis_lsp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} diff --git a/packet-isis-lsp.h b/packet-isis-lsp.h new file mode 100644 index 0000000000..81be07a4ae --- /dev/null +++ b/packet-isis-lsp.h @@ -0,0 +1,119 @@ +/* packet-isis-lsp.h + * Defines and such for LSP and their CLV decodes + * + * $Id: packet-isis-lsp.h,v 1.1 1999/12/15 04:34:18 guy Exp $ + * 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. + * + * + */ + +#ifndef _PACKET_ISIS_LSP_H +#define _PACKET_ISIS_LSP_H + +/* + * Declare what an LSP id looks like (used by LSP and sequence number + * packets) + */ +typedef struct { + guint8 source_id[6]; /* source id part */ + guint8 psuodonode_id; /* psn id */ + guint8 lsp_number; /* frag number */ +} isis_lsp_id_t; + + +/* + * Declare L1/L2 LSP base header. + */ +typedef struct { + guint8 isis_lsp_pdu_length[2]; /* pdu length including hdr */ + guint8 isis_lsp_remaining_life[2]; /* seconds before expiration */ + isis_lsp_id_t isis_lsp_id; + guint8 isis_lsp_sequence_number[4]; + guint8 isis_lsp_checksum[2]; + guint8 isis_lsp_type_block; /* partition/att/hip/istype */ +} isis_lsp_t; + +#define ISIS_LSP_PARTITION_MASK 0x80 +#define ISIS_LSP_ATT_MASK 0x78 +#define ISIS_LSP_ATT_SHIFT 3 +#define ISIS_LSP_HIPPITY_MASK 0x04 +#define ISIS_LSP_IS_TYPE_MASK 0x03 + +#define ISIS_LSP_PARTITION(x) (x&ISIS_LSP_PARTITION_MASK) +#define ISIS_LSP_ATT(x) ((x&ISIS_LSP_ATT_MASK)>>ISIS_LSP_ATT_SHIFT) +#define ISIS_LSP_HIPPITY(x) (x&ISIS_LSP_HIPPITY_MASK) +#define ISIS_LSP_IS_TYPE(x) (x&ISIS_LSP_IS_TYPE_MASK) + +#define ISIS_LSP_TYPE_UNUSED0 0 +#define ISIS_LSP_TYPE_LEVEL_1 1 +#define ISIS_LSP_TYPE_UNUSED2 2 +#define ISIS_LSP_TYPE_LEVEL_2 3 + +#define ISIS_LSP_CLV_METRIC_SUPPORTED(x) ((x)&0xf0) +#define ISIS_LSP_CLV_METRIC_RESERVED(x) ((x)&0x40) +#define ISIS_LSP_CLV_METRIC_VALUE(x) ((x)&0x3f) + +/* + * detail clv information on L1 lsp packets + */ +#define ISIS_CLV_L1_LSP_AREA_ADDRESS 1 +#define ISIS_CLV_L1_LSP_IS_NEIGHBORS 2 +#define ISIS_CLV_L1_LSP_ES_NEIGHBORS 3 +#define ISIS_CLV_L1_LSP_IP_INT_REACHABLE 128 +#define ISIS_CLV_L1_LSP_NLPID 129 +#define ISIS_CLV_L1_LSP_IP_INTERFACE_ADDR 132 +/* + * Note, the spec say 133, but everyone seems to use 10. Any clue on why + * this is would be appreciated! + */ +#define ISIS_CLV_L1_LSP_AUTHENTICATION_NS 10 /* non spec */ +#define ISIS_CLV_L1_LSP_AUTHENTICATION 133 + +/* + * detail clv information on L2 lsp packets + */ +#define ISIS_CLV_L2_LSP_AREA_ADDRESS 1 +#define ISIS_CLV_L2_LSP_IS_NEIGHBORS 2 +#define ISIS_CLV_L2_LSP_PARTITION_DIS 4 +#define ISIS_CLV_L2_LSP_PREFIX_NEIGHBORS 5 +#define ISIS_CLV_L2_LSP_IP_INT_REACHABLE 128 +#define ISIS_CLV_L2_LSP_NLPID 129 +#define ISIS_CLV_L2_LSP_IP_EXT_REACHABLE 130 +#define ISIS_CLV_L2_LSP_IDRP_INFO 131 +#define ISIS_CLV_L2_LSP_IP_INTERFACE_ADDR 132 +/* + * Note, the spec say 133, but everyone seems to use 10. Any clue on why + * this is would be appreciated! + */ +#define ISIS_CLV_L2_LSP_AUTHENTICATION_NS 10 /*non spec */ +#define ISIS_CLV_L2_LSP_AUTHENTICATION 133 + +/* + * Published API functions. NOTE, this are "local" API functions and + * are only valid from with isis decodes. + */ +extern void isis_dissect_isis_lsp(int hello_type, int header_length, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree); +extern void isis_lsp_decode_lsp_id(char *tstr, proto_tree *tree, int offset, + isis_lsp_id_t *id ); + +#endif /* _PACKET_ISIS_LSP_H */ diff --git a/packet-isis-snp.c b/packet-isis-snp.c new file mode 100644 index 0000000000..a75af4c5d5 --- /dev/null +++ b/packet-isis-snp.c @@ -0,0 +1,486 @@ +/* packet-isis-snp.c + * Routines for decoding isis complete & partial SNP and their payload + * + * $Id: packet-isis-snp.c,v 1.1 1999/12/15 04:34:19 guy Exp $ + * 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" +#include "packet-isis.h" +#include "packet-isis-clv.h" +#include "packet-isis-lsp.h" +#include "packet-isis-snp.h" + +/* csnp packets */ +static int proto_isis_csnp = -1; +static int hf_isis_csnp_pdu_length = -1; +static gint ett_isis_csnp = -1; +static gint ett_isis_csnp_lsp_entries = -1; +static gint ett_isis_csnp_authentication = -1; +static gint ett_isis_csnp_clv_unknown = -1; + +/* psnp packets */ +static int proto_isis_psnp = -1; +static int hf_isis_psnp_pdu_length = -1; +static gint ett_isis_psnp = -1; +static gint ett_isis_psnp_lsp_entries = -1; +static gint ett_isis_psnp_authentication = -1; +static gint ett_isis_psnp_clv_unknown = -1; + +static void dissect_snp_lsp_entries(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ); +static void dissect_l1_snp_authentication_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ); +static void dissect_l2_snp_authentication_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree ); + +static const isis_clv_handle_t clv_l1_csnp_opts[] = { + { + ISIS_CLV_L1_CSNP_LSP_ENTRIES, + "LSP entries", + &ett_isis_csnp_lsp_entries, + dissect_snp_lsp_entries + }, + { + ISIS_CLV_L1_CSNP_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_csnp_authentication, + dissect_l1_snp_authentication_clv + }, + { + ISIS_CLV_L1_CSNP_AUTHENTICATION, + "Authentication", + &ett_isis_csnp_authentication, + dissect_l1_snp_authentication_clv + }, + { + 0, "", NULL, NULL + } +}; + +static const isis_clv_handle_t clv_l2_csnp_opts[] = { + { + ISIS_CLV_L2_CSNP_LSP_ENTRIES, + "LSP entries", + &ett_isis_csnp_lsp_entries, + dissect_snp_lsp_entries + }, + { + ISIS_CLV_L2_CSNP_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_csnp_authentication, + dissect_l2_snp_authentication_clv + }, + { + ISIS_CLV_L2_CSNP_AUTHENTICATION, + "Authentication", + &ett_isis_csnp_authentication, + dissect_l2_snp_authentication_clv + }, + { + 0, "", NULL, NULL + } +}; + +static const isis_clv_handle_t clv_l1_psnp_opts[] = { + { + ISIS_CLV_L1_PSNP_LSP_ENTRIES, + "LSP entries", + &ett_isis_psnp_lsp_entries, + dissect_snp_lsp_entries + }, + { + ISIS_CLV_L1_PSNP_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_psnp_authentication, + dissect_l1_snp_authentication_clv + }, + { + ISIS_CLV_L1_PSNP_AUTHENTICATION, + "Authentication", + &ett_isis_psnp_authentication, + dissect_l1_snp_authentication_clv + }, + { + 0, "", NULL, NULL + } +}; + +static const isis_clv_handle_t clv_l2_psnp_opts[] = { + { + ISIS_CLV_L2_PSNP_LSP_ENTRIES, + "LSP entries", + &ett_isis_psnp_lsp_entries, + dissect_snp_lsp_entries + }, + { + ISIS_CLV_L2_PSNP_AUTHENTICATION, + "Authentication", + &ett_isis_psnp_authentication, + dissect_l2_snp_authentication_clv + }, + { + ISIS_CLV_L2_PSNP_AUTHENTICATION_NS, + "Authentication(non spec)", + &ett_isis_psnp_authentication, + dissect_l2_snp_authentication_clv + }, + { + 0, "", NULL, NULL + } +}; +/* + * Name: dissect_snp_payload() + * + * Description: + * All the snp packets use a common payload format. We have up + * to n entries (based on length), which are made of: + * 2 : remaining life time + * 8 : lsp id + * 4 : sequence number + * 2 : checksum + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * int : length of payload to decode. + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +static void +dissect_snp_lsp_entries(const u_char *pd, int offset, guint length, + frame_data *fd, proto_tree *tree ) { + isis_snp_t *ps; + + ps = (isis_snp_t *) &pd[offset]; + while ( length > 0 ) { + if ( length < sizeof(isis_psnp_t) ) { + isis_dissect_unknown(offset, length, tree, fd, + "Short SNP header entry (%d vs %d)", length, + sizeof(isis_psnp_t) ); + return; + } + + proto_tree_add_text(tree, offset, 2, "Remaining life: %d", + pntohs(&ps->isis_snp_remaining_lifetime)); + isis_lsp_decode_lsp_id( "LSP ID", tree, offset + 2, + &ps->isis_snp_lsp_id ); + proto_tree_add_text(tree, offset+10, 4, + "LSP Sequence Number: 0x%04x", + pntohl(&ps->isis_snp_sequence_number)); + proto_tree_add_text(tree, offset+14, 2, + "LSP checksum: 0x%02x", + pntohl(&ps->isis_snp_checksum)); + length -= sizeof ( isis_snp_t ); + offset += sizeof ( isis_snp_t ); + ps++; + } + +} + +/* + * Name: isis_dissect_isis_csnp() + * + * Description: + * Tear apart a L1 or L2 CSNP header and then call into payload dissect + * to pull apart the lsp id payload. + * + * Input: + * int : type (l1 csnp, l2 csnp) + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_isis_csnp(int type, int header_length, const u_char *pd, + int offset, frame_data *fd, proto_tree *tree){ + isis_csnp_t *ilp; + proto_item *ti; + proto_tree *csnp_tree = NULL; + int hlen; + int len; + + hlen = sizeof(*ilp); + + if (fd->cap_len < (offset + hlen)) { + isis_dissect_unknown(offset, hlen, tree, fd, + "not enough capture data for header (%d vs %d)", + hlen, offset - fd->cap_len); + return; + } + + ilp = (isis_csnp_t *) &pd[offset]; + + if (tree) { + ti = proto_tree_add_item(tree, proto_isis_csnp, + offset, fd->cap_len - offset, NULL); + csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp); + proto_tree_add_item(csnp_tree, hf_isis_csnp_pdu_length, + offset, 2, pntohs(&ilp->isis_csnp_pdu_length)); + proto_tree_add_text(csnp_tree, offset + 2, 7, + "Source id: %02x%02x.%02x%02x.%02x%02x.%02x", + ilp->isis_csnp_source_id[0], + ilp->isis_csnp_source_id[1], + ilp->isis_csnp_source_id[2], + ilp->isis_csnp_source_id[3], + ilp->isis_csnp_source_id[4], + ilp->isis_csnp_source_id[5], + ilp->isis_csnp_source_id[6] ); + isis_lsp_decode_lsp_id( "Start LSP id", csnp_tree, offset + 9, + &ilp->isis_csnp_start_lsp_id ); + isis_lsp_decode_lsp_id( "End LSP id", csnp_tree, offset + 17, + &ilp->isis_csnp_start_lsp_id ); + } + + offset += hlen; + len = pntohs(&ilp->isis_csnp_pdu_length); + len -= header_length; + if (len < 0) { + return; + } + /* Call into payload dissector */ + if (type == ISIS_TYPE_L1_CSNP ) { + isis_dissect_clvs ( clv_l1_csnp_opts, len, pd, offset, fd, + csnp_tree, ett_isis_csnp_clv_unknown ); + } else { + isis_dissect_clvs ( clv_l2_csnp_opts, len, pd, offset, fd, + csnp_tree, ett_isis_csnp_clv_unknown ); + } +} + +/* + * Name: isis_dissect_isis_psnp() + * + * Description: + * Tear apart a L1 or L2 PSNP header and then call into payload dissect + * to pull apart the lsp id payload. + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +isis_dissect_isis_psnp(int type, int header_length, const u_char *pd, + int offset, frame_data *fd, proto_tree *tree){ + isis_psnp_t *ilp; + proto_item *ti; + proto_tree *psnp_tree = NULL; + int hlen; + int len; + + hlen = sizeof(*ilp); + + if (fd->cap_len < (offset + hlen)) { + isis_dissect_unknown(offset, hlen, tree, fd, + "not enough capture data for header (%d vs %d)", + hlen, offset - fd->cap_len); + return; + } + + ilp = (isis_psnp_t *) &pd[offset]; + + if (tree) { + ti = proto_tree_add_item(tree, proto_isis_psnp, + offset, fd->cap_len - offset, NULL); + psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp); + proto_tree_add_item(psnp_tree, hf_isis_psnp_pdu_length, + offset, 2, pntohs(&ilp->isis_psnp_pdu_length)); + proto_tree_add_text(psnp_tree, offset + 2, 7, + "Source id: %02x%02x.%02x%02x.%02x%02x.%02x", + ilp->isis_psnp_source_id[0], + ilp->isis_psnp_source_id[1], + ilp->isis_psnp_source_id[2], + ilp->isis_psnp_source_id[3], + ilp->isis_psnp_source_id[4], + ilp->isis_psnp_source_id[5], + ilp->isis_psnp_source_id[6] ); + } + + offset += hlen; + len = pntohs(&ilp->isis_psnp_pdu_length); + len -= header_length; + if (len < 0) { + isis_dissect_unknown(offset, header_length, tree, fd, + "packet header length %d went beyond packet", + header_length ); + return; + } + /* Call into payload dissector */ + if (type == ISIS_TYPE_L1_CSNP ) { + isis_dissect_clvs ( clv_l1_csnp_opts, len, pd, offset, fd, + psnp_tree, ett_isis_psnp_clv_unknown ); + } else { + isis_dissect_clvs ( clv_l2_csnp_opts, len, pd, offset, fd, + psnp_tree, ett_isis_psnp_clv_unknown ); + } +} + +/* + * Name: dissect_L1_snp_authentication_clv() + * + * Description: + * Decode for a lsp packets authenticaion clv. Calls into the + * clv common one. An auth inside a L1 SNP is a per area password + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_l1_snp_authentication_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_authentication_clv(pd, offset, length, fd, tree, + "Per area authentication" ); +} + +/* + * Name: dissect_l2_authentication_clv() + * + * Description: + * Decode for a lsp packets authenticaion clv. Calls into the + * clv common one. An auth inside a L2 LSP is a per domain password + * + * Input: + * u_char * : packet data + * int : current offset into packet data + * guint : length of this clv + * frame_data * : frame data + * proto_tree * : proto tree to build on (may be null) + * + * Output: + * void, will modify proto_tree if not null. + */ +static void +dissect_l2_snp_authentication_clv(const u_char *pd, int offset, + guint length, frame_data *fd, proto_tree *tree) { + isis_dissect_authentication_clv(pd, offset, length, fd, tree, + "Per domain authentication" ); +} + +/* + * Name: proto_register_isis_csnp() + * + * Description: + * Register our protocol sub-sets with protocol manager. + * NOTE: this procedure is autolinked by the makefile process that + * builds register.c + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +proto_register_isis_csnp(void) { + static hf_register_info hf[] = { + { &hf_isis_csnp_pdu_length, + { "PDU length", "isis_csnp.pdu_length", FT_UINT16, + BASE_DEC, NULL, 0x0, "" }}, + }; + static gint *ett[] = { + &ett_isis_csnp, + &ett_isis_csnp_lsp_entries, + &ett_isis_csnp_authentication, + &ett_isis_csnp_clv_unknown, + }; + + proto_isis_csnp = proto_register_protocol("ISIS csnp", "ISIS-csnp"); + proto_register_field_array(proto_isis_csnp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + + +/* + * Name: proto_register_isis_psnp() + * + * Description: + * Register our protocol sub-sets with protocol manager. + * NOTE: this procedure is autolinked by the makefile process that + * builds register.c + * + * Input: + * u_char * : packet data + * int : offset into packet data where we are. + * guint : length of clv we are decoding + * frame_data * : frame data (complete frame) + * proto_tree * : protocol display tree to fill out. May be NULL + * + * Output: + * void, but we will add to proto tree if !NULL. + */ +void +proto_register_isis_psnp(void) { + static hf_register_info hf[] = { + { &hf_isis_psnp_pdu_length, + { "PDU length", "isis_psnp.pdu_length", FT_UINT16, + BASE_DEC, NULL, 0x0, "" }}, + }; + static gint *ett[] = { + &ett_isis_psnp, + &ett_isis_psnp_lsp_entries, + &ett_isis_psnp_authentication, + &ett_isis_psnp_clv_unknown, + }; + + proto_isis_psnp = proto_register_protocol("ISIS psnp", "ISIS-psnp"); + proto_register_field_array(proto_isis_psnp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + diff --git a/packet-isis-snp.h b/packet-isis-snp.h new file mode 100644 index 0000000000..15b7a92e44 --- /dev/null +++ b/packet-isis-snp.h @@ -0,0 +1,102 @@ +/* packet-isis-snp.h + * Defines and such for CSNP, PSNP, and their payloads + * + * $Id: packet-isis-snp.h,v 1.1 1999/12/15 04:34:19 guy Exp $ + * 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. + * + * + */ + +#ifndef _PACKET_ISIS_SNP_H +#define _PACKET_ISIS_SNP_H + +/* + * Note, the spec say 133 for authentication, but everyone seems to use 10. + * Any clue on why this is would be appreciated! + */ + +/* + * detail cvls information for L1 CSNP packets + */ +#define ISIS_CLV_L1_CSNP_LSP_ENTRIES 9 +#define ISIS_CLV_L1_CSNP_AUTHENTICATION_NS 10 +#define ISIS_CLV_L1_CSNP_AUTHENTICATION 133 + +/* + * detail cvls information for L2 CSNP packets + */ +#define ISIS_CLV_L2_CSNP_LSP_ENTRIES 9 +#define ISIS_CLV_L2_CSNP_AUTHENTICATION_NS 10 +#define ISIS_CLV_L2_CSNP_AUTHENTICATION 133 + +/* + * detail cvls information for L1 PSNP packets + */ +#define ISIS_CLV_L1_PSNP_LSP_ENTRIES 9 +#define ISIS_CLV_L1_PSNP_AUTHENTICATION_NS 10 +#define ISIS_CLV_L1_PSNP_AUTHENTICATION 133 + +/* + * detail cvls information for L2 PSNP packets + */ +#define ISIS_CLV_L2_PSNP_LSP_ENTRIES 9 +#define ISIS_CLV_L2_PSNP_AUTHENTICATION_NS 10 +#define ISIS_CLV_L2_PSNP_AUTHENTICATION 133 + +/* + * Declare L1/L2 CSNP header + */ +typedef struct { + guint8 isis_csnp_pdu_length[2]; /* pdu length including hdr */ + guint8 isis_csnp_source_id[7]; /* source sysid */ + isis_lsp_id_t isis_csnp_start_lsp_id; /* start LSP id */ + isis_lsp_id_t isis_csnp_end_lsp_id; /* end LSP id */ +} isis_csnp_t; + +/* + * Declare L1/L2 PSNP header + */ +typedef struct { + guint8 isis_psnp_pdu_length[2]; /* pdu length including hdr */ + guint8 isis_psnp_source_id[7]; /* source sysid */ +} isis_psnp_t; + +/* + * Declare SNP payload element + */ +typedef struct { + guint8 isis_snp_remaining_lifetime[2]; /* lifetime of LSP */ + isis_lsp_id_t isis_snp_lsp_id; /* target LSP id */ + guint8 isis_snp_sequence_number[4]; /* sequence number of LSP */ + guint8 isis_snp_checksum[2]; /* checksum of LSP */ +} isis_snp_t; + +/* + * Published API functions. NOTE, this are "local" API functions and + * are only valid from with isis decodes. + */ +extern void isis_dissect_isis_csnp(int type, int header_length, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree); +extern void isis_dissect_isis_psnp(int type, int header_length, + const u_char *pd, int offset, frame_data *fd, proto_tree *tree); + +#endif /* _PACKET_ISIS_CSNP_H */ diff --git a/packet-isis.c b/packet-isis.c new file mode 100644 index 0000000000..c6b515214d --- /dev/null +++ b/packet-isis.c @@ -0,0 +1,354 @@ +/* packet-isis-core.c + * Routines for ISO/OSI network and transport protocol packet disassembly, core + * bits. + * + * $Id: packet-isis.c,v 1.1 1999/12/15 04:34:19 guy Exp $ + * 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" +#include "packet-isis.h" +#include "packet-isis-lsp.h" +#include "packet-isis-hello.h" +#include "packet-isis-snp.h" + +/* isis base header */ +static int proto_isis = -1; + +static int hf_isis_irpd = -1; +static int hf_isis_header_length = -1; +static int hf_isis_version = -1; +static int hf_isis_reserved = -1; +static int hf_isis_type = -1; +static int hf_isis_version2 = -1; +static int hf_isis_eco = -1; +static int hf_isis_user_eco = -1; + +static gint ett_isis = -1; + +static const value_string irpd_vals[] = { + { ISIS_IRPD, "correct(0x83)" }, + { 0, NULL} }; + +static const value_string isis_vals[] = { + { 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} }; + + +/* + * 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; + + if ( offset > fd->cap_len ) { + /* + * big oops They were off the end of the packet already. + * Just ignore this one. + */ + return; + } + if ( (offset + length) > fd->cap_len ) { + /* + * length will take us past eop. Truncate length. + */ + length = offset - fd->cap_len; + } + + va_start(ap, fmat); + proto_tree_add_text(tree, offset, length, fmat, ap); + va_end(ap); +} + +/* + * Name: isis_address_to_string() + * + * Description: + * Function for taking a byte string and turn it into a "0000.0000...." + * format ISIS address. + * + * Input: + * u_char * : Packet data + * unt offset : Current offset into packet data. + * int len : length of to dump. + * + * Output: + * static char * : print string + */ +char +*isis_address_to_string ( const u_char *pd, int offset, int len ) { + static char sbuf[768]; + char *s; + + sbuf[0] = 0; + s = sbuf; + while ( len > 0 ) { + /* special case: len is 1, put ending on it */ + if ( len == 1 ) { + s += sprintf ( s, "%02x", pd[offset++] ); + len--; + } else { + /* general case, just add 2 bytes */ + s+= sprintf ( s, "%02x%02x", pd[offset++], + pd[offset++] ); + len -= 2; + } + if ( len > 0 ) { + s += sprintf ( s, "." ); + } + } + return sbuf; +} + +/* + * 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. + */ +void +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; + + if (fd->cap_len < offset + sizeof(*ihdr)) { + isis_dissect_unknown(offset, sizeof(*ihdr), tree, fd, + "not enough capture data for header (%d vs %d)", + sizeof(*ihdr), offset - fd->cap_len); + return; + } + + ihdr = (isis_hdr_t *) &pd[offset]; + + if (ihdr->isis_version != ISIS_REQUIRED_VERSION){ + isis_dissect_unknown(offset, fd->cap_len, tree, fd, + "Unknown ISIS version (%d vs %d)", + ihdr->isis_version, ISIS_REQUIRED_VERSION ); + return; + } + + + if (tree) { + ti = proto_tree_add_item(tree, proto_isis, offset, + fd->cap_len - offset, NULL ); + isis_tree = proto_item_add_subtree(ti, ett_isis); + proto_tree_add_item_format(isis_tree, hf_isis_irpd, offset, 1, + ihdr->isis_irpd, + "Intradomain Routing Protocol Discrimintator: 0x%02x", + ihdr->isis_irpd ); + proto_tree_add_item(isis_tree, hf_isis_header_length, + offset + 1, 1, ihdr->isis_header_length ); + proto_tree_add_item(isis_tree, hf_isis_version, + offset + 2, 1, ihdr->isis_version ); + proto_tree_add_item(isis_tree, hf_isis_reserved, + offset + 3, 1, ihdr->isis_reserved ); + proto_tree_add_item_format(isis_tree, hf_isis_type, + offset + 4, 1, ihdr->isis_type, + "Type: %s (R:%s%s%s)", + val_to_str(ihdr->isis_type & ISIS_TYPE_MASK, isis_vals, + "Unknown (0x%x)"), + (ihdr->isis_type & ISIS_R8_MASK) ? "1" : "0", + (ihdr->isis_type & ISIS_R7_MASK) ? "1" : "0", + (ihdr->isis_type & ISIS_R6_MASK) ? "1" : "0"); + proto_tree_add_item(isis_tree, hf_isis_version2, + offset + 5, 1, ihdr->isis_version2 ); + proto_tree_add_item(isis_tree, hf_isis_eco, + offset + 6, 1, ihdr->isis_eco ); + proto_tree_add_item(isis_tree, hf_isis_user_eco, + offset + 7, 1, ihdr->isis_user_eco ); + } + + + /* + * 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)" ) ); + } + + /* + * 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, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L2_HELLO: + isis_dissect_isis_hello(ISIS_TYPE_L2_HELLO, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_PTP_HELLO: + isis_dissect_isis_hello(ISIS_TYPE_PTP_HELLO, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L1_LSP: + isis_dissect_isis_lsp(ISIS_TYPE_L1_LSP, ihdr->isis_header_length, + pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L2_LSP: + isis_dissect_isis_lsp(ISIS_TYPE_L2_LSP, ihdr->isis_header_length, + pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L1_CSNP: + isis_dissect_isis_csnp(ISIS_TYPE_L1_CSNP, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L2_CSNP: + isis_dissect_isis_csnp(ISIS_TYPE_L2_CSNP, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L1_PSNP: + isis_dissect_isis_psnp(ISIS_TYPE_L1_PSNP, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + case ISIS_TYPE_L2_PSNP: + isis_dissect_isis_psnp(ISIS_TYPE_L2_PSNP, + ihdr->isis_header_length, pd, offset, fd, isis_tree); + break; + default: + isis_dissect_unknown(offset, offset - fd->cap_len, tree, fd, + "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) { + static hf_register_info hf[] = { + { &hf_isis_irpd, + { "Intradomain Routing Protocol Discriminator", "isis.irpd", + FT_UINT8, BASE_DEC, VALS(irpd_vals), 0xff, "" }}, + + { &hf_isis_header_length, + { "HDR Length", "isis.hdr_len", FT_UINT8, BASE_DEC, + NULL, 0x0, "" }}, + + { &hf_isis_version, + { "Version (==1)", "isis.version", FT_UINT8, + BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_reserved, + { "Reserved(==0)", "isis.reserved", + FT_UINT8, BASE_DEC, NULL, 0x0, "" }}, + + { &hf_isis_type, + { "Type code", "isis.type", FT_UINT8, BASE_DEC, + VALS(isis_vals), 0xff, "" }}, + + { &hf_isis_version2, + { "Version2(==1)", "isis.version2", FT_UINT8, BASE_DEC, NULL, + 0x0, "" }}, + + { &hf_isis_eco, + { "ECO (==0)", "isis.eco",FT_UINT8, BASE_DEC, NULL, + 0x0, "" }}, + + { &hf_isis_user_eco, + { "User ECO (==0)", "isis.user_eco", 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, + }; + + proto_isis = proto_register_protocol("clnp ISIS", "ISIS"); + proto_register_field_array(proto_isis, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} diff --git a/packet-isis.h b/packet-isis.h new file mode 100644 index 0000000000..f40bf9e445 --- /dev/null +++ b/packet-isis.h @@ -0,0 +1,90 @@ +/* packet-isis.h + * Defines and such for core isis protcol decode. + * + * $Id: packet-isis.h,v 1.1 1999/12/15 04:34:19 guy Exp $ + * 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. + * + * + */ + +#ifndef _PACKET_ISIS_H +#define _PACKET_ISIS_H + +/* + * the IntraDomain Routing Protocol Descriminator is an achitectueral constant + * set to 0x83 for all packets. + */ +#define ISIS_IRPD 0x83 + +/* + * The version we support is 1 + */ +#define ISIS_REQUIRED_VERSION 1 + +/* + * ISIS type field values + */ +#define ISIS_TYPE_L1_HELLO 15 +#define ISIS_TYPE_L2_HELLO 16 +#define ISIS_TYPE_PTP_HELLO 17 +#define ISIS_TYPE_L1_LSP 18 +#define ISIS_TYPE_L2_LSP 20 +#define ISIS_TYPE_L1_CSNP 24 +#define ISIS_TYPE_L2_CSNP 25 +#define ISIS_TYPE_L1_PSNP 26 +#define ISIS_TYPE_L2_PSNP 27 + +/* + * The common first 8 octets of the ISIS protocol header. + */ +typedef struct { + guint8 isis_irpd; /* Intradomain Routing Protocol Descriminator. Must be 0x83 */ + guint8 isis_header_length; /* header length in octets */ + guint8 isis_version; /* isis version, must be 0x01 */ + guint8 isis_reserved; /* res byte, must be 0 */ + guint8 isis_type_reserved; /* packet type & reserved */ +#define ISIS_TYPE_MASK 0x1f +#define ISIS_R8_MASK 0x80 +#define ISIS_R7_MASK 0x40 +#define ISIS_R6_MASK 0x20 + guint8 isis_version2; /* another version(?!), must be 0x01 */ + + guint8 isis_eco; /* ECO, must be 0 */ + guint8 isis_user_eco; /* user ECO, must be 0 */ +} isis_hdr_t; + +#define isis_type isis_type_reserved&ISIS_TYPE_MASK +#define isis_r8 isis_type_reserved&ISIS_R8_MASK +#define isis_r7 isis_type_reserved&ISIS_R7_MASK +#define isis_r6 isis_type_reserved&ISIS_R6_MASK + +/* + * published API functions + */ +extern char *isis_address_to_string ( const u_char *pd, int offset, int len ); +extern void dissect_isis(const u_char *pd, int offset, frame_data *fd, + proto_tree *tree); +extern void proto_register_isis(void); +extern void isis_dissect_unknown(int offset,guint length,proto_tree *tree,frame_data *fd, + char *fmat, ...); + +#endif /* _PACKET_ISIS_H */ diff --git a/packet-osi.c b/packet-osi.c index f1246d5869..b79e781ab0 100644 --- a/packet-osi.c +++ b/packet-osi.c @@ -1,7 +1,7 @@ /* packet-osi.c * Routines for ISO/OSI network and transport protocol packet disassembly * - * $Id: packet-osi.c,v 1.12 1999/11/16 11:42:44 guy Exp $ + * $Id: packet-osi.c,v 1.13 1999/12/15 04:34:19 guy Exp $ * Laurent Deniel <deniel@worldnet.fr> * * Ethereal - Network traffic analyzer @@ -1618,7 +1618,7 @@ void dissect_osi(const u_char *pd, int offset, frame_data *fd, if (check_col(fd, COL_PROTOCOL)) { col_add_str(fd, COL_PROTOCOL, "ISIS"); } - dissect_data(pd, offset, fd, tree); + dissect_isis(pd, offset, fd, tree); break; default: if (check_col(fd, COL_PROTOCOL)) { @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.162 1999/12/12 22:39:30 gram Exp $ + * $Id: packet.h,v 1.163 1999/12/15 04:34:20 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -351,6 +351,7 @@ void dissect_ipp(const u_char *, int, frame_data *, proto_tree *); void dissect_ipv6(const u_char *, int, frame_data *, proto_tree *); void dissect_ipx(const u_char *, int, frame_data *, proto_tree *); void dissect_irc(const u_char *, int, frame_data *, proto_tree *); +void dissect_isis(const u_char *, int, frame_data *, proto_tree *); void dissect_ldap(const u_char *, int, frame_data *, proto_tree *); void dissect_llc(const u_char *, int, frame_data *, proto_tree *); void dissect_lpd(const u_char *, int, frame_data *, proto_tree *); |