Overhaul the ISIS dissectors

1. Make real dissectors and call dissector_try_uint_new for each "isis.type"
2. Use make_register script for dissector initialization
3. Replace isis_dissect_unknown() with real expert info
4. Use convert_proto_tree_add_text.pl to make many more filterable items and gets some files off of the checkAPIs.pl naughty list.
5. Remove (now unnecessary) dissector specific header files
6. Do some reordering of functions to eliminate the need for function declarations.

Additional whitespace formatting and modelines should probably be applied to all of these dissectors.

Used capture files from bug 5354 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5354) and bug 1792 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1792) for fuzztesting.

svn path=/trunk/; revision=54367
This commit is contained in:
Michael Mann 2013-12-22 18:18:12 +00:00
parent 302a4cf1c0
commit 89786cc8c7
12 changed files with 3458 additions and 3799 deletions

View File

@ -1445,9 +1445,6 @@ DISSECTOR_INCLUDES = \
packet-isakmp.h \
packet-isis.h \
packet-isis-clv.h \
packet-isis-hello.h \
packet-isis-lsp.h \
packet-isis-snp.h \
packet-isl.h \
packet-isup.h \
packet-jxta.h \

View File

@ -28,6 +28,7 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include "packet-osi.h"
#include "packet-isis.h"
#include "packet-isis-clv.h"
@ -50,8 +51,8 @@
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int length)
isis_dissect_area_address_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
expert_field* expert, int offset, int length)
{
int arealen,area_idx;
@ -59,12 +60,12 @@ isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
arealen = tvb_get_guint8(tvb, offset);
length--;
if (length<=0) {
isis_dissect_unknown(tvb, tree, offset,
proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
"short address (no length for payload)");
return;
}
if ( arealen > length) {
isis_dissect_unknown(tvb, tree, offset,
proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
"short address, packet says %d, we have %d left",
arealen, length );
return;
@ -85,7 +86,7 @@ isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
/*
* Lets turn the area address into "standard"
* xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx format string.
* this is a private routine as the print_nsap_net in
* this is a private routine as the print_nsap_net in
* epan/osi_utils.c is incomplete and we need only
* a subset - actually some nice placing of dots ....
*/
@ -124,8 +125,8 @@ isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int length)
isis_dissect_authentication_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
expert_field* auth_expert, int offset, int length)
{
guchar pw_type;
int auth_unsupported;
@ -176,9 +177,8 @@ isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
break;
}
if ( auth_unsupported ) {
isis_dissect_unknown(tvb, tree, offset,
"Unknown authentication type" );
if ( auth_unsupported ) {
proto_tree_add_expert(tree, pinfo, auth_expert, tvb, offset, -1);
}
}
@ -300,8 +300,8 @@ isis_dissect_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length,
"malformed MT-ID");
break;
}
length=length-2;
offset=offset+2;
length -= 2;
offset += 2;
}
}
@ -326,8 +326,8 @@ isis_dissect_mt_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length,
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int length, int tree_id)
isis_dissect_ip_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
int offset, int length, int tree_id)
{
if ( length <= 0 ) {
return;
@ -335,7 +335,7 @@ isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
while ( length > 0 ) {
if ( length < 4 ) {
isis_dissect_unknown(tvb, tree, offset,
proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
"Short IP interface address (%d vs 4)",length );
return;
}
@ -368,8 +368,8 @@ isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int length, int tree_id)
isis_dissect_ipv6_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
int offset, int length, int tree_id)
{
guint8 addr [16];
@ -379,7 +379,7 @@ isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
while ( length > 0 ) {
if ( length < 16 ) {
isis_dissect_unknown(tvb, tree, offset,
proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
"Short IPv6 interface address (%d vs 16)",length );
return;
}
@ -412,21 +412,20 @@ isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int length, int tree_id)
isis_dissect_te_router_id_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
int offset, int length, int tree_id)
{
if ( length <= 0 ) {
return;
}
if ( length <= 0 ) {
return;
}
if ( length != 4 ) {
isis_dissect_unknown(tvb, tree, offset,
"malformed Traffic Engineering Router ID (%d vs 4)",length );
return;
}
if ( tree ) {
proto_tree_add_item(tree, tree_id, tvb, offset, 4, ENC_BIG_ENDIAN);
}
if ( length != 4 ) {
proto_tree_add_expert_format(tree, pinfo, expert, tvb, offset, -1,
"malformed Traffic Engineering Router ID (%d vs 4)",length );
return;
}
proto_tree_add_item(tree, tree_id, tvb, offset, 4, ENC_BIG_ENDIAN);
}
/*
@ -479,8 +478,7 @@ isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length)
*/
(tvb_get_guint8(tvb, offset) == NLPID_IEEE_8021AQ
? "IEEE 802.1aq (SPB)"
: val_to_str_const(tvb_get_guint8(tvb, offset), nlpid_vals,
"Unknown")),
: val_to_str_const(tvb_get_guint8(tvb, offset), nlpid_vals, "Unknown")),
tvb_get_guint8(tvb, offset));
offset++;
first = FALSE;
@ -513,8 +511,8 @@ isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int offset, int length)
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
const isis_clv_handle_t *opts, int len, int id_length,
isis_dissect_clvs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
const isis_clv_handle_t *opts, expert_field* expert_short_len, int len, int id_length,
int unknown_tree_id _U_)
{
guint8 code;
@ -537,7 +535,7 @@ isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
break;
if ( len < length ) {
isis_dissect_unknown(tvb, tree, offset,
proto_tree_add_expert_format(tree, pinfo, expert_short_len, tvb, offset, -1,
"Short CLV header (%d vs %d)",
length, len );
return;
@ -557,7 +555,7 @@ isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
} else {
clv_tree = NULL;
}
opts[q].dissect(tvb, clv_tree, offset,
opts[q].dissect(tvb, pinfo, clv_tree, offset,
id_length, length);
} else {
#if 0 /* XXX: Left as commented out in case info about "unknown code" is ever to be displayed under a sub-tree */

View File

@ -85,7 +85,7 @@ typedef struct {
int optcode; /* code for option */
const char *tree_text; /* text for fold out */
gint *tree_id; /* id for add_item */
void (*dissect)(tvbuff_t *tvb, proto_tree *tree,
void (*dissect)(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
int offset, int id_length, int length);
} isis_clv_handle_t;
@ -93,28 +93,28 @@ typedef struct {
* Published API functions. NOTE, this are "local" API functions and
* are only valid from with isis decodes.
*/
extern void isis_dissect_clvs(tvbuff_t *tvb, proto_tree *tree, int offset,
const isis_clv_handle_t *opts, int len, int id_length,
extern void isis_dissect_clvs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
const isis_clv_handle_t *opts, expert_field* expert_short_len, int len, int id_length,
int unknown_tree_id);
extern void isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree,
int offset, int length);
extern void isis_dissect_te_router_id_clv(tvbuff_t *tvb, proto_tree *tree,
extern void isis_dissect_te_router_id_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
int offset, int length, int tree_id);
extern void isis_dissect_ipv6_int_clv(tvbuff_t *tvb, proto_tree *tree,
extern void isis_dissect_ipv6_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
int offset, int length, int tree_id);
extern void isis_dissect_ip_int_clv(tvbuff_t *tvb, proto_tree *tree,
extern void isis_dissect_ip_int_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, expert_field* expert,
int offset, int length, int tree_id);
extern void isis_dissect_mt_clv(tvbuff_t *tvb, proto_tree *tree,
int offset, int length, int tree_id);
extern void isis_dissect_hostname_clv(tvbuff_t *tvb, proto_tree *tree,
int offset, int length, int tree_id);
extern void isis_dissect_authentication_clv(tvbuff_t *tvb, proto_tree *tree,
int offset, int length);
extern void isis_dissect_authentication_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
expert_field* auth_expert, int offset, int length);
extern void isis_dissect_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree,
int offset, int length);
extern void isis_dissect_area_address_clv(tvbuff_t *tvb, proto_tree *tree,
int offset, int length);
extern void isis_dissect_area_address_clv(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb,
expert_field* expert, int offset, int length);
extern void isis_dissect_metric(tvbuff_t *tvb, proto_tree *tree, int offset,
guint8 value, char *pstr, int force_supported);

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/* packet-isis-hello.h
* Declares for hello handling inside isis.
*
* $Id$
* Stuart Stanley <stuarts@mxmail.net>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _PACKET_ISIS_HELLO_H
#define _PACKET_ISIS_HELLO_H
/*
* Declarations for L1/L2 hello base header.
*/
#define ISIS_HELLO_CTYPE_MASK 0x03
#define ISIS_HELLO_CT_RESERVED_MASK 0xfc
#define ISIS_HELLO_PRIORITY_MASK 0x7f
#define ISIS_HELLO_P_RESERVED_MASK 0x80
#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
/*
* misc. bittest macros
*/
#define ISIS_RESTART_RR 0x01
#define ISIS_RESTART_RA 0x02
#define ISIS_RESTART_SA 0x04
#define ISIS_MASK_RESTART_RR(x) ((x)&ISIS_RESTART_RR)
#define ISIS_MASK_RESTART_RA(x) ((x)&ISIS_RESTART_RA)
#define ISIS_MASK_RESTART_SA(x) ((x)&ISIS_RESTART_SA)
/*
* Published API functions. NOTE, this are "local" API functions and
* are only valid from with isis decodes.
*/
extern void isis_dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, int hello_type, int header_length,int id_length);
extern void isis_register_hello(int proto_isis);
#endif /* _PACKET_ISIS_HELLO_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
/* packet-isis-lsp.h
* Defines and such for LSP and their CLV decodes
*
* $Id$
* Stuart Stanley <stuarts@mxmail.net>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _PACKET_ISIS_LSP_H
#define _PACKET_ISIS_LSP_H
/*
* Declarations for L1/L2 LSP base header.
*/
/* P | ATT | HIPPITY | DS FIELD description */
#define ISIS_LSP_PARTITION_MASK 0x80
#define ISIS_LSP_PARTITION_SHIFT 7
#define ISIS_LSP_PARTITION(info) (((info) & ISIS_LSP_PARTITION_MASK) >> ISIS_LSP_PARTITION_SHIFT)
#define ISIS_LSP_ATT_MASK 0x78
#define ISIS_LSP_ATT_SHIFT 3
#define ISIS_LSP_ATT(info) (((info) & ISIS_LSP_ATT_MASK) >> ISIS_LSP_ATT_SHIFT)
#define ISIS_LSP_ATT_ERROR(info) ((info) >> 3)
#define ISIS_LSP_ATT_EXPENSE(info) (((info) >> 2) & 1)
#define ISIS_LSP_ATT_DELAY(info) (((info) >> 1) & 1)
#define ISIS_LSP_ATT_DEFAULT(info) ((info) & 1)
#define ISIS_LSP_HIPPITY_MASK 0x04
#define ISIS_LSP_HIPPITY_SHIFT 2
#define ISIS_LSP_HIPPITY(info) (((info) & ISIS_LSP_HIPPITY_MASK) >> ISIS_LSP_HIPPITY_SHIFT)
#define ISIS_LSP_IS_TYPE_MASK 0x03
#define ISIS_LSP_IS_TYPE(info) ((info) & ISIS_LSP_IS_TYPE_MASK)
#define ISIS_LSP_MT_MSHIP_RES_MASK 4
#define ISIS_LSP_MT_MSHIP_RES_SHIFT 12
#define ISIS_LSP_MT_MSHIP_RES(info) (((info) >> ISIS_LSP_MT_MSHIP_RES_SHIFT) & ISIS_LSP_MT_MSHIP_RES_MASK)
#define ISIS_LSP_MT_MSHIP_ID_MASK 0x0FFF
#define ISIS_LSP_MT_MSHIP_ID(info) ((info) & ISIS_LSP_MT_MSHIP_ID_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_ATTACHED_NONE 0
#define ISIS_LSP_ATTACHED_DEFAULT 1
#define ISIS_LSP_ATTACHED_DELAY 2
#define ISIS_LSP_ATTACHED_EXPENSE 4
#define ISIS_LSP_ATTACHED_ERROR 8
#define ISIS_LSP_CLV_METRIC_SUPPORTED(x) ((x)&0x80)
#define ISIS_LSP_CLV_METRIC_IE(x) ((x)&0x40)
#define ISIS_LSP_CLV_METRIC_RESERVED(x) ((x)&0x40)
#define ISIS_LSP_CLV_METRIC_UPDOWN(x) ((x)&0x80)
#define ISIS_LSP_CLV_METRIC_VALUE(x) ((x)&0x3f)
/*
* Published API functions. NOTE, this are "local" API functions and
* are only valid from with isis decodes.
*/
extern void isis_dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, int hello_type, int header_length, int id_length);
extern void isis_register_lsp(int proto_isis);
#endif /* _PACKET_ISIS_LSP_H */

View File

@ -27,14 +27,24 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include "packet-osi.h"
#include "packet-isis.h"
#include "packet-isis-clv.h"
#include "packet-isis-lsp.h"
#include "packet-isis-snp.h"
static int proto_isis_csnp = -1;
static int proto_isis_psnp = -1;
/* csnp packets */
static int hf_isis_csnp_pdu_length = -1;
static int hf_isis_csnp_source_id = -1;
static int hf_isis_csnp_start_lsp_id = -1;
static int hf_isis_csnp_end_lsp_id = -1;
static int hf_isis_csnp_lsp_id = -1;
static int hf_isis_csnp_lsp_seq_num = -1;
static int hf_isis_csnp_lsp_remain_life = -1;
static int hf_isis_csnp_lsp_checksum = -1;
static int hf_isis_csnp_checksum = -1;
static gint ett_isis_csnp = -1;
static gint ett_isis_csnp_clv_lsp_entries = -1;
static gint ett_isis_csnp_lsp_entry = -1;
@ -43,8 +53,13 @@ static gint ett_isis_csnp_clv_ip_authentication = -1;
static gint ett_isis_csnp_clv_checksum = -1;
static gint ett_isis_csnp_clv_unknown = -1;
static expert_field ei_isis_csnp_short_packet = EI_INIT;
static expert_field ei_isis_csnp_long_packet = EI_INIT;
static expert_field ei_isis_csnp_authentication = EI_INIT;
/* psnp packets */
static int hf_isis_psnp_pdu_length = -1;
static int hf_isis_psnp_source_id = -1;
static gint ett_isis_psnp = -1;
static gint ett_isis_psnp_clv_lsp_entries = -1;
static gint ett_isis_psnp_lsp_entry = -1;
@ -53,14 +68,114 @@ static gint ett_isis_psnp_clv_ip_authentication = -1;
static gint ett_isis_psnp_clv_checksum = -1;
static gint ett_isis_psnp_clv_unknown = -1;
static void dissect_snp_authentication_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static void dissect_snp_ip_authentication_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static void dissect_snp_checksum_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static void dissect_snp_lsp_entries_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length, int length);
static expert_field ei_isis_psnp_short_packet = EI_INIT;
static expert_field ei_isis_psnp_long_packet = EI_INIT;
static void
dissect_snp_authentication_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length _U_, int length)
{
isis_dissect_authentication_clv(tree, pinfo, tvb, &ei_isis_csnp_authentication, offset, length);
}
static void
dissect_snp_ip_authentication_clv(tvbuff_t *tvb, packet_info* pinfo _U_, proto_tree *tree, int offset,
int id_length _U_, int length)
{
isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
}
/*
* Name: dissect_snp_checksum_clv()
*
* Description:
* dump and verify the optional checksum in TLV 12
*/
static void
dissect_snp_checksum_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *tree, int offset, int id_length _U_, int length) {
guint16 pdu_length,checksum, cacl_checksum=0;
proto_item* ti;
if ( length != 2 ) {
proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_packet, tvb, offset, -1,
"incorrect checksum length (%u), should be (2)", length );
return;
}
ti = proto_tree_add_item( tree, hf_isis_csnp_checksum, tvb, offset, length, ENC_BIG_ENDIAN);
checksum = tvb_get_ntohs(tvb, offset);
/* the check_and_get_checksum() function needs to know how big
* the packet is. we can either pass through the pdu-len through several layers
* of dissectors and wrappers or extract the PDU length field from the PDU specific header
* which is offseted 8 bytes (relative to the beginning of the IS-IS packet) in SNPs */
pdu_length = tvb_get_ntohs(tvb, 8);
/* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
{
case NO_CKSUM :
proto_item_append_text(ti, " [unused]");
break;
case DATA_MISSING :
expert_add_info_format(pinfo, ti, &ei_isis_csnp_long_packet,
"Packet length %d went beyond packet", tvb_length(tvb));
break;
case CKSUM_NOT_OK :
proto_item_append_text(ti, " [incorrect, should be 0x%04x]", cacl_checksum);
break;
case CKSUM_OK :
proto_item_append_text(ti, " [correct]");
break;
}
}
/*
* Name: dissect_snp_lsp_entries_clv()
*
* 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
* id_length : lsp id
* 4 : sequence number
* 2 : checksum
*/
static void
dissect_snp_lsp_entries_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length, int length)
{
proto_item *ti;
proto_tree *subtree;
const guint8 *source_id;
while ( length > 0 ) {
if ( length < 2+id_length+2+4+2 ) {
proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_packet, tvb, offset, -1,
"Short SNP header entry (%d vs %d)", length, 2+id_length+2+4+2 );
return;
}
ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2, "LSP Entry");
subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);
source_id = tvb_get_ptr(tvb, offset+2, id_length+2);
proto_tree_add_bytes_format_value(tree, hf_isis_csnp_lsp_id, tvb,
offset+2, 8, source_id, "%s", print_system_id(source_id, id_length+2));
proto_tree_add_item(subtree, hf_isis_csnp_lsp_seq_num, tvb, offset+2+id_length+2, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_isis_csnp_lsp_remain_life, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_isis_csnp_lsp_checksum, tvb, offset+2+id_length+2+4, 2, ENC_BIG_ENDIAN);
length -= 2+id_length+2+4+2;
offset += 2+id_length+2+4+2;
}
}
static const isis_clv_handle_t clv_l1_csnp_opts[] = {
{
@ -182,356 +297,173 @@ static const isis_clv_handle_t clv_l2_psnp_opts[] = {
}
};
/*
* Name: dissect_snp_lsp_entries_clv()
*
* 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
* id_length : lsp id
* 4 : sequence number
* 2 : checksum
*
* Input:
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : protocol display tree to fill out. May be NULL
* int : offset into packet data where we are.
* int : length of IDs in packet.
* int : length of payload to decode.
*
* Output:
* void, but we will add to proto tree if !NULL.
*/
static void
dissect_snp_lsp_entries_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int id_length, int length)
{
proto_tree *subtree,*ti;
while ( length > 0 ) {
if ( length < 2+id_length+2+4+2 ) {
isis_dissect_unknown(tvb, tree, offset,
"Short SNP header entry (%d vs %d)", length,
2+id_length+2+4+2 );
return;
}
ti = proto_tree_add_text(tree, tvb, offset, 2+id_length+2+4+2,
"LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x",
print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ),
tvb_get_ntohl(tvb, offset+2+id_length+2),
tvb_get_ntohs(tvb, offset),
tvb_get_ntohs(tvb, offset+2+id_length+2+4));
subtree = proto_item_add_subtree(ti,ett_isis_csnp_lsp_entry);
proto_tree_add_text(subtree, tvb, offset+2, 8,
"LSP-ID: : %s",
print_system_id( tvb_get_ptr(tvb, offset+2, id_length+2), id_length+2 ));
proto_tree_add_text(subtree, tvb, offset+2+id_length+2, 4,
"LSP Sequence Number : 0x%08x",
tvb_get_ntohl(tvb, offset+2+id_length+2));
proto_tree_add_text(subtree, tvb, offset, 2,
"Remaining Lifetime : %us",
tvb_get_ntohs(tvb, offset));
proto_tree_add_text(subtree, tvb, offset+2+id_length+2+4, 2,
"LSP checksum : 0x%04x",
tvb_get_ntohs(tvb, offset+2+id_length+2+4));
length -= 2+id_length+2+4+2;
offset += 2+id_length+2+4+2;
}
}
/*
* 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:
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : protocol display tree to add to. May be NULL.
* int offset : our offset into packet data.
* int : type (l1 csnp, l2 csnp)
* int : header length of packet.
* int : length of IDs in packet.
*
* Output:
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
int type, int header_length, int id_length)
dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
const isis_clv_handle_t *opts, int header_length, int id_length)
{
proto_item *ti;
proto_tree *csnp_tree = NULL;
guint16 pdu_length;
int len;
const guint8 *source_id;
gchar* system_id;
if (tree) {
ti = proto_tree_add_text(tree, tvb, offset, -1,
PROTO_STRING_CSNP);
csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
}
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS CSNP");
ti = proto_tree_add_item(tree, proto_isis_csnp, tvb, offset, -1, ENC_NA);
csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
pdu_length = tvb_get_ntohs(tvb, offset);
if (tree) {
proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
offset, 2, pdu_length);
}
offset += 2;
if (tree) {
proto_tree_add_text(csnp_tree, tvb, offset, id_length + 1,
"Source-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
}
col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
source_id = tvb_get_ptr(tvb, offset, id_length);
system_id = print_system_id( source_id, id_length );
proto_tree_add_bytes_format_value(csnp_tree, hf_isis_csnp_source_id, tvb,
offset, id_length, source_id,
"%s", system_id);
col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s", system_id);
offset += id_length + 1;
proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2, "Start LSP-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
source_id = tvb_get_ptr(tvb, offset, id_length+2);
system_id = print_system_id( source_id, id_length+2 );
proto_tree_add_bytes_format_value(csnp_tree, hf_isis_csnp_start_lsp_id, tvb,
offset, id_length + 2, source_id,
"%s", system_id);
col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP-ID: %s", system_id);
offset += id_length + 2;
proto_tree_add_text(csnp_tree, tvb, offset, id_length + 2, "End LSP-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+2), id_length+2 ) );
source_id = tvb_get_ptr(tvb, offset, id_length+2);
system_id = print_system_id( source_id, id_length+2 );
proto_tree_add_bytes_format_value(csnp_tree, hf_isis_csnp_end_lsp_id, tvb,
offset, id_length + 2, source_id,
"%s", system_id);
col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP-ID: %s", system_id);
offset += id_length + 2;
len = pdu_length - header_length;
if (len < 0) {
proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_packet, tvb, offset, -1,
"packet header length %d went beyond packet", header_length );
return;
}
/* Call into payload dissector */
if (type == ISIS_TYPE_L1_CSNP ) {
isis_dissect_clvs(tvb, csnp_tree, offset,
clv_l1_csnp_opts, len, id_length,
ett_isis_csnp_clv_unknown );
} else {
isis_dissect_clvs(tvb, csnp_tree, offset,
clv_l2_csnp_opts, len, id_length,
ett_isis_csnp_clv_unknown );
}
isis_dissect_clvs(tvb, pinfo, csnp_tree, offset,
opts, &ei_isis_csnp_short_packet, len, id_length, 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:
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : protocol display tree to add to. May be NULL.
* int : our offset into packet data
* int : type (l1 psnp, l2 psnp)
* int : header length of packet.
* int : length of IDs in packet.
*
* Output:
* void, but we will add to proto tree if !NULL.
*/
void
isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
int type, int header_length, int id_length)
static int
dissect_isis_l1_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
isis_data_t* isis = (isis_data_t*)data;
dissect_isis_csnp(tvb, pinfo, tree, 0,
clv_l1_csnp_opts, isis->header_length, isis->system_id_len);
return tvb_length(tvb);
}
static int
dissect_isis_l2_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
isis_data_t* isis = (isis_data_t*)data;
dissect_isis_csnp(tvb, pinfo, tree, 0,
clv_l2_csnp_opts, isis->header_length, isis->system_id_len);
return tvb_length(tvb);
}
static void
dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
const isis_clv_handle_t *opts, int header_length, int id_length)
{
proto_item *ti;
proto_tree *psnp_tree = NULL;
proto_tree *psnp_tree;
guint16 pdu_length;
int len;
const guint8 *source_id;
gchar* system_id;
if (tree) {
ti = proto_tree_add_text(tree, tvb, offset, -1,
PROTO_STRING_PSNP);
psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
}
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS PSNP");
ti = proto_tree_add_item(tree, proto_isis_psnp, tvb, offset, -1, ENC_NA);
psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
pdu_length = tvb_get_ntohs(tvb, offset);
if (tree) {
proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
offset, 2, pdu_length);
}
offset += 2;
proto_tree_add_text(psnp_tree, tvb, offset, id_length + 1, "Source-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length + 1 ) );
col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s",
print_system_id( tvb_get_ptr(tvb, offset, id_length+1), id_length+1 ) );
source_id = tvb_get_ptr(tvb, offset, id_length);
system_id = print_system_id( source_id, id_length );
proto_tree_add_bytes_format_value(psnp_tree, hf_isis_psnp_source_id, tvb,
offset, id_length, source_id,
"%s", system_id);
col_append_fstr(pinfo->cinfo, COL_INFO, ", Source-ID: %s", system_id);
offset += id_length + 1;
len = pdu_length - header_length;
if (len < 0) {
isis_dissect_unknown(tvb, tree, offset,
"packet header length %d went beyond packet",
header_length );
proto_tree_add_expert_format(tree, pinfo, &ei_isis_psnp_long_packet, tvb, offset, -1,
"packet header length %d went beyond packet", header_length );
return;
}
/* Call into payload dissector */
if (type == ISIS_TYPE_L1_PSNP ) {
isis_dissect_clvs(tvb, psnp_tree, offset,
clv_l1_psnp_opts, len, id_length,
ett_isis_psnp_clv_unknown );
} else {
isis_dissect_clvs(tvb, psnp_tree, offset,
clv_l2_psnp_opts, len, id_length,
ett_isis_psnp_clv_unknown );
}
isis_dissect_clvs(tvb, pinfo, psnp_tree, offset,
opts, &ei_isis_psnp_short_packet, len, id_length, ett_isis_psnp_clv_unknown );
}
/*
* Name: dissect_snp_authentication_clv()
*
* Description:
* Decode for a snp packets authenticaion clv.
* Calls into the CLV common one.
*
* Input:
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : proto tree to build on (may be null)
* int : current offset into packet data
* int : length of IDs in packet.
* int : length of this clv
*
* Output:
* void, will modify proto_tree if not null.
*/
static void
dissect_snp_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int id_length _U_, int length)
static int
dissect_isis_l1_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
isis_dissect_authentication_clv(tvb, tree, offset, length);
isis_data_t* isis = (isis_data_t*)data;
dissect_isis_psnp(tvb, pinfo, tree, 0,
clv_l1_psnp_opts, isis->header_length, isis->system_id_len);
return tvb_length(tvb);
}
/*
* Name: dissect_snp_ip_authentication_clv()
*
* Description:
* Decode for a snp packets authenticaion clv.
* Calls into the CLV common one.
*
* Input:
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : proto tree to build on (may be null)
* int : current offset into packet data
* int : length of IDs in packet.
* int : length of this clv
*
* Output:
* void, will modify proto_tree if not null.
*/
static void
dissect_snp_ip_authentication_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
int id_length _U_, int length)
static int
dissect_isis_l2_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
isis_dissect_ip_authentication_clv(tvb, tree, offset, length);
isis_data_t* isis = (isis_data_t*)data;
dissect_isis_psnp(tvb, pinfo, tree, 0,
clv_l2_psnp_opts, isis->header_length, isis->system_id_len);
return tvb_length(tvb);
}
/*
* Name: dissect_snp_checksum_clv()
*
* Description:
* dump and verify the optional checksum in TLV 12
*
* Input:
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : protocol display tree to fill out. May be NULL
* int : offset into packet data where we are.
* int : length of clv we are decoding
*
* Output:
* void, but we will add to proto tree if !NULL.
*/
static void
dissect_snp_checksum_clv(tvbuff_t *tvb,
proto_tree *tree, int offset, int id_length _U_, int length) {
guint16 pdu_length,checksum, cacl_checksum=0;
if (tree) {
if ( length != 2 ) {
proto_tree_add_text ( tree, tvb, offset, length,
"incorrect checksum length (%u), should be (2)", length );
return;
}
checksum = tvb_get_ntohs(tvb, offset);
/* the check_and_get_checksum() function needs to know how big
* the packet is. we can either pass through the pdu-len through several layers
* of dissectors and wrappers or extract the PDU length field from the PDU specific header
* which is offseted 8 bytes (relative to the beginning of the IS-IS packet) in SNPs */
pdu_length = tvb_get_ntohs(tvb, 8);
/* unlike the LSP checksum verification which starts at an offset of 12 we start at offset 0*/
switch (check_and_get_checksum(tvb, 0, pdu_length, checksum, offset, &cacl_checksum))
{
case NO_CKSUM :
proto_tree_add_text ( tree, tvb, offset, length,
"Checksum: 0x%04x [unused]", checksum);
break;
case DATA_MISSING :
isis_dissect_unknown(tvb, tree, offset,
"[packet length %d went beyond packet]",
tvb_length(tvb));
break;
case CKSUM_NOT_OK :
proto_tree_add_text ( tree, tvb, offset, length,
"Checksum: 0x%04x [incorrect, should be 0x%04x]",
checksum,
cacl_checksum);
break;
case CKSUM_OK :
proto_tree_add_text ( tree, tvb, offset, length,
"Checksum: 0x%04x [correct]", checksum);
break;
default :
g_message("'check_and_get_checksum' returned an invalid value");
}
}
}
/*
* Name: isis_register_csnp()
*
* Description:
* Register our protocol sub-sets with protocol manager.
*
* Input:
* int : protocol index for the ISIS protocol
*
* Output:
* void
*/
void
isis_register_csnp(int proto_isis) {
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, NULL, HFILL }},
{ &hf_isis_csnp_source_id,
{ "Source-ID", "isis.csnp.source_id",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_start_lsp_id,
{ "Start LSP-ID", "isis.csnp.start_lsp_id",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_end_lsp_id,
{ "End LSP-ID", "isis.csnp.end_lsp_id",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_lsp_id,
{ "LSP-ID", "isis.csnp.lsp_id",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_lsp_seq_num,
{ "LSP Sequence Number", "isis.csnp.lsp_seq_num", FT_UINT32,
BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_lsp_remain_life,
{ "Remaining Lifetime", "isis.csnp.lsp_remain_life", FT_UINT16,
BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_lsp_checksum,
{ "LSP checksum", "isis.csnp.lsp_checksum", FT_UINT16,
BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_csnp_checksum,
{ "Checksum", "isis.csnp.checksum", FT_UINT16,
BASE_HEX, NULL, 0x0, NULL, HFILL }},
};
static gint *ett[] = {
&ett_isis_csnp,
&ett_isis_csnp_clv_lsp_entries,
@ -542,30 +474,41 @@ isis_register_csnp(int proto_isis) {
&ett_isis_csnp_clv_unknown,
};
proto_register_field_array(proto_isis, hf, array_length(hf));
static ei_register_info ei[] = {
{ &ei_isis_csnp_short_packet, { "isis.csnp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
{ &ei_isis_csnp_long_packet, { "isis.csnp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
{ &ei_isis_csnp_authentication, { "isis.csnp.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
};
expert_module_t* expert_isis_csnp;
/* Register the protocol name and description */
proto_isis_csnp = proto_register_protocol(PROTO_STRING_CSNP, "ISIS CSNP", "isis.csnp");
proto_register_field_array(proto_isis_csnp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_isis_csnp = expert_register_protocol(proto_isis_csnp);
expert_register_field_array(expert_isis_csnp, ei, array_length(ei));
}
/*
* Name: isis_register_psnp()
*
* Description:
* Register our protocol sub-sets with protocol manager.
*
* Input:
* int : protocol index for the ISIS protocol
*
* Output:
* void
*/
void
isis_register_psnp(int proto_isis) {
proto_reg_handoff_isis_csnp(void)
{
dissector_add_uint("isis.type", ISIS_TYPE_L1_CSNP, new_create_dissector_handle(dissect_isis_l1_csnp, proto_isis_csnp));
dissector_add_uint("isis.type", ISIS_TYPE_L2_CSNP, new_create_dissector_handle(dissect_isis_l2_csnp, proto_isis_csnp));
}
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, NULL, HFILL }},
{ &hf_isis_psnp_source_id,
{ "Source-ID", "isis.psnp.source_id",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
};
static gint *ett[] = {
&ett_isis_psnp,
&ett_isis_psnp_clv_lsp_entries,
@ -575,7 +518,24 @@ isis_register_psnp(int proto_isis) {
&ett_isis_psnp_clv_checksum,
&ett_isis_psnp_clv_unknown,
};
static ei_register_info ei[] = {
{ &ei_isis_psnp_long_packet, { "isis.psnp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
{ &ei_isis_psnp_short_packet, { "isis.psnp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
};
expert_module_t* expert_isis_psnp;
proto_register_field_array(proto_isis, hf, array_length(hf));
/* Register the protocol name and description */
proto_isis_psnp = proto_register_protocol(PROTO_STRING_PSNP, "ISIS PSNP", "isis.psnp");
proto_register_field_array(proto_isis_psnp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_isis_psnp = expert_register_protocol(proto_isis_psnp);
expert_register_field_array(expert_isis_psnp, ei, array_length(ei));
}
void
proto_reg_handoff_isis_psnp(void)
{
dissector_add_uint("isis.type", ISIS_TYPE_L1_PSNP, new_create_dissector_handle(dissect_isis_l1_psnp, proto_isis_psnp));
dissector_add_uint("isis.type", ISIS_TYPE_L2_PSNP, new_create_dissector_handle(dissect_isis_l2_psnp, proto_isis_psnp));
}

View File

@ -1,40 +0,0 @@
/* packet-isis-snp.h
* Defines and such for CSNP, PSNP, and their payloads
*
* $Id$
* Stuart Stanley <stuarts@mxmail.net>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _PACKET_ISIS_SNP_H
#define _PACKET_ISIS_SNP_H
/*
* Published API functions. NOTE, this are "local" API functions and
* are only valid from with isis decodes.
*/
extern void isis_dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, int type, int header_length, int id_length);
extern void isis_register_csnp(int proto_isis);
extern void isis_dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
int offset, int type, int header_length, int id_length);
extern void isis_register_psnp(int proto_isis);
#endif /* _PACKET_ISIS_CSNP_H */

View File

@ -28,17 +28,17 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/nlpid.h>
#include <epan/etypes.h>
#include "packet-osi.h"
#include "packet-isis.h"
#include "packet-isis-lsp.h"
#include "packet-isis-hello.h"
#include "packet-isis-snp.h"
void proto_register_isis(void);
void proto_reg_handoff_isis(void);
static dissector_table_t isis_dissector_table;
/* isis base header */
static int proto_isis = -1;
@ -47,12 +47,16 @@ static int hf_isis_header_length = -1;
static int hf_isis_version = -1;
static int hf_isis_system_id_length = -1;
static int hf_isis_type = -1;
static int hf_isis_type_reserved = -1;
static int hf_isis_version2 = -1;
static int hf_isis_reserved = -1;
static int hf_isis_max_area_adr = -1;
static gint ett_isis = -1;
static expert_field ei_isis_version = EI_INIT;
static expert_field ei_isis_type = EI_INIT;
static dissector_handle_t isis_handle;
static const value_string isis_vals[] = {
@ -67,194 +71,84 @@ static const value_string isis_vals[] = {
{ ISIS_TYPE_L2_PSNP, "L2 PSNP"},
{ 0, NULL} };
/*
* Name: isis_dissect_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
* tvbuff_t * : tvbuffer for packet data
* proto_tree * : tree of display data. May be NULL.
* int : current offset into packet data
* char * : format text
* subsequent args : arguments to format
*
* Output:
* void (may modify proto tree)
*/
void
isis_dissect_unknown(tvbuff_t *tvb, proto_tree *tree, int offset,
const char *fmat, ...)
{
va_list ap;
va_start(ap, fmat);
proto_tree_add_text_valist(tree, tvb, offset, -1, fmat, ap);
va_end(ap);
}
/*
* Name: dissect_isis()
*
* Description:
* Main entry area for isis de-mangling. This will build the
* main isis tree data and call the sub-protocols as needed.
*
* Input:
* tvbuff_t * : tvbuffer for packet data
* packet_info * : info for current packet
* proto_tree * : tree of display data. May be NULL.
*
* Output:
* void, but we will add to the proto_tree if it is not NULL.
*/
static void
dissect_isis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_item *ti, *version_item;
proto_tree *isis_tree = NULL;
int offset = 0;
guint8 isis_version;
guint8 isis_header_length;
guint8 isis_type_reserved;
guint8 isis_type;
guint8 isis_system_id_len;
tvbuff_t *next_tvb;
isis_data_t subdissector_data;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS");
col_clear(pinfo->cinfo, COL_INFO);
isis_version = tvb_get_guint8(tvb, 2);
ti = proto_tree_add_item(tree, proto_isis, tvb, 0, -1, ENC_NA);
isis_tree = proto_item_add_subtree(ti, ett_isis);
proto_tree_add_item(isis_tree, hf_isis_irpd, tvb, offset, 1, ENC_BIG_ENDIAN );
offset += 1;
subdissector_data.header_length = tvb_get_guint8(tvb, offset);
proto_tree_add_uint(isis_tree, hf_isis_header_length, tvb,
offset, 1, subdissector_data.header_length );
offset += 1;
isis_version = tvb_get_guint8(tvb, offset);
version_item = proto_tree_add_uint(isis_tree, hf_isis_version, tvb,
offset, 1, isis_version );
if (isis_version != ISIS_REQUIRED_VERSION){
col_add_fstr(pinfo->cinfo, COL_INFO,
"Unknown ISIS version (%u vs %u)",
isis_version, ISIS_REQUIRED_VERSION );
isis_dissect_unknown(tvb, tree, 0,
"Unknown ISIS version (%d vs %d)",
isis_version, ISIS_REQUIRED_VERSION);
expert_add_info(pinfo, version_item, &ei_isis_version);
return;
}
ti = proto_tree_add_item(tree, proto_isis, tvb, 0, -1, ENC_NA);
isis_tree = proto_item_add_subtree(ti, ett_isis);
if (tree) {
proto_tree_add_item(isis_tree, hf_isis_irpd, tvb, offset, 1,
ENC_BIG_ENDIAN );
}
offset += 1;
isis_header_length = tvb_get_guint8(tvb, offset);
if (tree) {
proto_tree_add_uint(isis_tree, hf_isis_header_length, tvb,
offset, 1, isis_header_length );
}
subdissector_data.system_id_len = tvb_get_guint8(tvb, offset);
proto_tree_add_uint(isis_tree, hf_isis_system_id_length, tvb,
offset, 1, subdissector_data.system_id_len );
offset += 1;
if (tree) {
proto_tree_add_uint(isis_tree, hf_isis_version, tvb,
offset, 1, isis_version );
}
offset += 1;
isis_system_id_len = tvb_get_guint8(tvb, offset);
if (tree) {
proto_tree_add_uint(isis_tree, hf_isis_system_id_length, tvb,
offset, 1, isis_system_id_len );
}
offset += 1;
isis_type_reserved = tvb_get_guint8(tvb, offset);
isis_type = isis_type_reserved & ISIS_TYPE_MASK;
isis_type = tvb_get_guint8(tvb, offset) & ISIS_TYPE_MASK;
col_add_str(pinfo->cinfo, COL_INFO,
val_to_str ( isis_type, isis_vals, "Unknown (0x%x)" ) );
proto_tree_add_uint_format(isis_tree, hf_isis_type, tvb,
offset, 1, isis_type,
"PDU Type : %s (R:%s%s%s)",
val_to_str(isis_type, isis_vals, "Unknown (0x%x)"),
(isis_type_reserved & ISIS_R8_MASK) ? "1" : "0",
(isis_type_reserved & ISIS_R7_MASK) ? "1" : "0",
(isis_type_reserved & ISIS_R6_MASK) ? "1" : "0");
proto_tree_add_item(isis_tree, hf_isis_type, tvb, offset, 1, ENC_BIG_ENDIAN );
proto_tree_add_item(isis_tree, hf_isis_type_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
offset += 1;
if (tree) {
proto_tree_add_item(isis_tree, hf_isis_version2, tvb, offset, 1,
ENC_BIG_ENDIAN );
}
proto_tree_add_item(isis_tree, hf_isis_version2, tvb, offset, 1, ENC_BIG_ENDIAN );
offset += 1;
if (tree) {
proto_tree_add_item(isis_tree, hf_isis_reserved, tvb, offset, 1,
ENC_BIG_ENDIAN );
}
proto_tree_add_item(isis_tree, hf_isis_reserved, tvb, offset, 1, ENC_BIG_ENDIAN );
offset += 1;
if (tree) {
proto_tree_add_item(isis_tree, hf_isis_max_area_adr, tvb, offset, 1,
ENC_BIG_ENDIAN );
}
proto_tree_add_item(isis_tree, hf_isis_max_area_adr, tvb, offset, 1, ENC_BIG_ENDIAN );
offset += 1;
/*
* Interpret the system ID length.
*/
if (isis_system_id_len == 0)
isis_system_id_len = 6; /* zero means 6-octet ID field length */
else if (isis_system_id_len == 255) {
isis_system_id_len = 0; /* 255 means null ID field */
if (subdissector_data.system_id_len == 0)
subdissector_data.system_id_len = 6; /* zero means 6-octet ID field length */
else if (subdissector_data.system_id_len == 255) {
subdissector_data.system_id_len = 0; /* 255 means null ID field */
/* XXX - what about the LAN ID? */
}
/* XXX - otherwise, must be in the range 1 through 8 */
switch (isis_type) {
case ISIS_TYPE_L1_HELLO:
case ISIS_TYPE_L2_HELLO:
case ISIS_TYPE_PTP_HELLO:
isis_dissect_isis_hello(tvb, pinfo, isis_tree, offset,
isis_type, isis_header_length, isis_system_id_len);
break;
case ISIS_TYPE_L1_LSP:
case ISIS_TYPE_L2_LSP:
isis_dissect_isis_lsp(tvb, pinfo, isis_tree, offset,
isis_type, isis_header_length, isis_system_id_len);
break;
case ISIS_TYPE_L1_CSNP:
case ISIS_TYPE_L2_CSNP:
isis_dissect_isis_csnp(tvb, pinfo, isis_tree, offset,
isis_type, isis_header_length, isis_system_id_len);
break;
case ISIS_TYPE_L1_PSNP:
case ISIS_TYPE_L2_PSNP:
isis_dissect_isis_psnp(tvb, pinfo, isis_tree, offset,
isis_type, isis_header_length, isis_system_id_len);
break;
default:
isis_dissect_unknown(tvb, tree, offset,
"Unknown ISIS packet type");
next_tvb = tvb_new_subset_remaining(tvb, offset);
if (!dissector_try_uint_new(isis_dissector_table, isis_type, next_tvb,
pinfo, tree, TRUE, &subdissector_data))
{
proto_tree_add_expert(tree, pinfo, &ei_isis_type, tvb, offset, -1);
}
} /* 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)
{
@ -267,7 +161,7 @@ proto_register_isis(void)
{ "PDU Header Length", "isis.len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_version,
{ "Version (==1)", "isis.version", FT_UINT8,
{ "Version", "isis.version", FT_UINT8,
BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_isis_system_id_length,
@ -276,7 +170,11 @@ proto_register_isis(void)
{ &hf_isis_type,
{ "PDU Type", "isis.type", FT_UINT8, BASE_DEC,
VALS(isis_vals), 0xff, NULL, HFILL }},
VALS(isis_vals), ISIS_TYPE_MASK, NULL, HFILL }},
{ &hf_isis_type_reserved,
{ "Reserved", "isis.reserved", FT_UINT8, BASE_HEX,
NULL, ISIS_TYPE_RESERVED_MASK, NULL, HFILL }},
{ &hf_isis_version2,
{ "Version2 (==1)", "isis.version2", FT_UINT8, BASE_DEC, NULL,
@ -299,20 +197,23 @@ proto_register_isis(void)
&ett_isis,
};
proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis");
proto_register_field_array(proto_isis, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
static ei_register_info ei[] = {
{ &ei_isis_version, { "isis.version.unknown", PI_PROTOCOL, PI_WARN, "Unknown ISIS version", EXPFILL }},
{ &ei_isis_type, { "isis.type.unknown", PI_PROTOCOL, PI_WARN, "Unknown ISIS packet type", EXPFILL }},
};
isis_handle = register_dissector("isis", dissect_isis, proto_isis);
expert_module_t* expert_isis;
/*
* Call registration routines for other source files in the ISIS
* dissector.
*/
isis_register_hello(proto_isis);
isis_register_lsp(proto_isis);
isis_register_csnp(proto_isis);
isis_register_psnp(proto_isis);
proto_isis = proto_register_protocol(PROTO_STRING_ISIS, "ISIS", "isis");
proto_register_field_array(proto_isis, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_isis = expert_register_protocol(proto_isis);
expert_register_field_array(expert_isis, ei, array_length(ei));
isis_handle = register_dissector("isis", dissect_isis, proto_isis);
isis_dissector_table = register_dissector_table("isis.type",
"ISIS Type", FT_UINT8, BASE_DEC);
}
void

View File

@ -44,17 +44,15 @@
#define ISIS_TYPE_L1_PSNP 26
#define ISIS_TYPE_L2_PSNP 27
#define ISIS_TYPE_MASK 0x1f
#define ISIS_R8_MASK 0x80
#define ISIS_R7_MASK 0x40
#define ISIS_R6_MASK 0x20
#define ISIS_TYPE_MASK 0x1f
#define ISIS_TYPE_RESERVED_MASK 0xe0
/*
* published API functions
* Data given to subdissectors
*/
extern char *isis_address_to_string(tvbuff_t *tvb, int offset, int len);
extern void isis_dissect_unknown(tvbuff_t *tvb, proto_tree *tree, int offset,
const char *fmat, ...);
typedef struct isis_data {
guint8 header_length;
guint8 system_id_len;
} isis_data_t;
#endif /* _PACKET_ISIS_H */

View File

@ -31,13 +31,11 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/nlpid.h>
#include "packet-osi.h"
#include "packet-isis.h"
#include "packet-isis-clv.h"
#include "packet-isis-hello.h"
#include "packet-isis-lsp.h"
#include "packet-isis-snp.h"
#include "packet-esis.h"
#include "packet-osi-options.h"