aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-05-12 13:45:14 -0700
committerGuy Harris <guy@alum.mit.edu>2019-05-12 21:50:11 +0000
commit87deef63c6a7471258b33573717bba885b24527a (patch)
tree0f4a9716f7bf175a0e8a791922dc5b6eed79faa8
parentbeed21b038683377efb7b5c13b36a3a35fa720a2 (diff)
Clean up some things.
Have separate expert info items for the PDU length field being too short, the PDU length field being too long, a CLV being too short, and a CLV being too long. Do the PDU length checks when we add the PDU length field, and add the expert infos to the length item; remember the results of the checks for future use. Use DISSECTOR_ASSERT for the tests in osi_check_and_get_checksum() that make sure the checksum field is contained within the data to be checksummed, so that's reported as a dissector bug to the user. That means that osi_check_and_get_checksum() only returns FALSE if we don't have all the data available to checksum; that already gets reported as an indication that the checksum is unverified, so we don't need to put confusing and misleading expert infos about the PDU length - whatever PDU length errors need to be reported have already been reported, as per the above. Make expert info names more consistent, and fix one expert info variable name. Make the length argument to isis_dissect_clvs() unsigned. Clean up white space. Change-Id: I0ce799c766dc427602d155c5b48099df8bf51c67 Reviewed-on: https://code.wireshark.org/review/33179 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--epan/dissectors/packet-isis-clv.c4
-rw-r--r--epan/dissectors/packet-isis-clv.h2
-rw-r--r--epan/dissectors/packet-isis-hello.c74
-rw-r--r--epan/dissectors/packet-isis-lsp.c120
-rw-r--r--epan/dissectors/packet-isis-snp.c87
-rw-r--r--epan/dissectors/packet-osi.c14
6 files changed, 166 insertions, 135 deletions
diff --git a/epan/dissectors/packet-isis-clv.c b/epan/dissectors/packet-isis-clv.c
index 77b9402d24..20f957d8a1 100644
--- a/epan/dissectors/packet-isis-clv.c
+++ b/epan/dissectors/packet-isis-clv.c
@@ -481,7 +481,7 @@ isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree, int hf_nlpid, int offset
*/
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,
+ const isis_clv_handle_t *opts, expert_field* expert_short_len, guint len, int id_length,
int unknown_tree_id _U_, int tree_type, int tree_length, expert_field ei_unknown)
{
guint8 code;
@@ -489,7 +489,7 @@ isis_dissect_clvs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offse
int q;
proto_tree *clv_tree;
- while ( len > 0 ) {
+ while ( len != 0 ) {
code = tvb_get_guint8(tvb, offset);
offset += 1;
len -= 1;
diff --git a/epan/dissectors/packet-isis-clv.h b/epan/dissectors/packet-isis-clv.h
index e55229e363..10eb90fb7c 100644
--- a/epan/dissectors/packet-isis-clv.h
+++ b/epan/dissectors/packet-isis-clv.h
@@ -87,7 +87,7 @@ typedef struct {
* are only valid from with isis decodes.
*/
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,
+ const isis_clv_handle_t *opts, expert_field* expert_short_len, guint len, int id_length,
int unknown_tree_id, int tree_type, int tree_length, expert_field ei_unknown);
extern void isis_dissect_nlpid_clv(tvbuff_t *tvb, proto_tree *tree,
diff --git a/epan/dissectors/packet-isis-hello.c b/epan/dissectors/packet-isis-hello.c
index c1703f8d42..b347dbde76 100644
--- a/epan/dissectors/packet-isis-hello.c
+++ b/epan/dissectors/packet-isis-hello.c
@@ -165,13 +165,14 @@ static gint ett_isis_hello_clv_reverse_metric = -1;
static gint ett_isis_hello_clv_bfd_enabled = -1;
static gint ett_isis_hello_clv_ipv6_glb_int_addr = -1;
-static expert_field ei_isis_hello_short_packet = EI_INIT;
-static expert_field ei_isis_hello_long_packet = EI_INIT;
+static expert_field ei_isis_hello_short_pdu = EI_INIT;
+static expert_field ei_isis_hello_long_pdu = EI_INIT;
+static expert_field ei_isis_hello_bad_checksum = EI_INIT;
static expert_field ei_isis_hello_authentication = EI_INIT;
static expert_field ei_isis_hello_subtlv = EI_INIT;
+static expert_field ei_isis_hello_short_clv = EI_INIT;
static expert_field ei_isis_hello_clv_mt = EI_INIT;
static expert_field ei_isis_hello_clv_unknown = EI_INIT;
-static expert_field ei_isis_hello_checksum = EI_INIT;
static const value_string isis_hello_circuit_type_vals[] = {
{ ISIS_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"},
@@ -191,7 +192,7 @@ dissect_hello_mt_port_cap_spb_mcid_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *subtree;
if (sublen != SUBLEN) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, -1,
"Short SPB MCID TLV (%d vs %d)", sublen, SUBLEN);
return;
}
@@ -216,7 +217,7 @@ dissect_hello_mt_port_cap_spb_digest_clv(tvbuff_t *tvb, packet_info* pinfo,
const int DIGEST_LEN = 32;
const int SUBLEN = 1 + DIGEST_LEN;
if (sublen != SUBLEN) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, -1,
"Short SPB Digest TLV (%d vs %d)", sublen, SUBLEN);
return;
}
@@ -249,7 +250,7 @@ dissect_hello_mt_port_cap_spb_bvid_tuples_clv(tvbuff_t *tvb, packet_info* pinfo,
while (sublen > 0) {
if (sublen < 6) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, -1,
"Short SPB BVID header entry (%d vs %d)", sublen, 6);
return;
}
@@ -426,7 +427,7 @@ dissect_hello_mt_port_cap_clv(tvbuff_t *tvb, packet_info* pinfo,
length -= 2;
offset += 2;
if (subtlvlen > length) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, -1,
"Short type %d TLV (%d vs %d)", subtype, subtlvlen, length);
return;
}
@@ -614,7 +615,7 @@ static void
dissect_hello_ip_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_ip_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet,
+ isis_dissect_ip_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_clv,
offset, length, hf_isis_hello_clv_ipv4_int_addr );
}
@@ -639,7 +640,7 @@ static void
dissect_hello_ipv6_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet,
+ isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_clv,
offset, length, hf_isis_hello_clv_ipv6_int_addr );
}
@@ -815,7 +816,7 @@ dissect_hello_checksum_clv(tvbuff_t *tvb, packet_info* pinfo,
guint16 pdu_length,checksum, cacl_checksum=0;
if ( length != 2 ) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, length,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, length,
"incorrect checksum length (%u), should be (2)", length );
return;
}
@@ -823,22 +824,21 @@ dissect_hello_checksum_clv(tvbuff_t *tvb, packet_info* pinfo,
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 17 bytes in IIHs (relative to the beginning of the IS-IS packet) */
+ * 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 17 bytes in IIHs (relative to the beginning of the IS-IS packet) */
pdu_length = tvb_get_ntohs(tvb, 17);
if (checksum == 0) {
/* No checksum present */
- proto_tree_add_checksum(tree, tvb, offset, hf_isis_hello_checksum, hf_isis_hello_checksum_status, &ei_isis_hello_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NOT_PRESENT);
+ proto_tree_add_checksum(tree, tvb, offset, hf_isis_hello_checksum, hf_isis_hello_checksum_status, &ei_isis_hello_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NOT_PRESENT);
} else {
if (osi_check_and_get_checksum(tvb, 0, pdu_length, offset, &cacl_checksum)) {
/* Successfully processed checksum, verify it */
- proto_tree_add_checksum(tree, tvb, offset, hf_isis_hello_checksum, hf_isis_hello_checksum_status, &ei_isis_hello_checksum, pinfo, cacl_checksum, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
+ proto_tree_add_checksum(tree, tvb, offset, hf_isis_hello_checksum, hf_isis_hello_checksum_status, &ei_isis_hello_bad_checksum, pinfo, cacl_checksum, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
} else {
- proto_tree_add_checksum(tree, tvb, offset, hf_isis_hello_checksum, hf_isis_hello_checksum_status, &ei_isis_hello_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_long_packet, tvb, offset, -1,
- "Packet length %d went beyond packet", tvb_captured_length(tvb) );
+ /* We didn't capture the entire packet, so we can't verify it */
+ proto_tree_add_checksum(tree, tvb, offset, hf_isis_hello_checksum, hf_isis_hello_checksum_status, &ei_isis_hello_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
}
}
}
@@ -866,7 +866,7 @@ static void
dissect_hello_area_address_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_area_address_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet, hf_isis_hello_area_address, offset, length);
+ isis_dissect_area_address_clv(tree, pinfo, tvb, &ei_isis_hello_short_clv, hf_isis_hello_area_address, offset, length);
}
/*
@@ -890,7 +890,7 @@ static void
dissect_hello_instance_identifier_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_instance_identifier_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet, hf_isis_hello_instance_identifier, hf_isis_hello_supported_itid, offset, length);
+ isis_dissect_instance_identifier_clv(tree, pinfo, tvb, &ei_isis_hello_short_clv, hf_isis_hello_instance_identifier, hf_isis_hello_supported_itid, offset, length);
}
static const value_string adj_state_vals[] = {
@@ -925,7 +925,7 @@ dissect_hello_ptp_adj_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree_add_item(tree, hf_isis_hello_neighbor_extended_local_circuit_id, tvb, offset+5+id_length, 4, ENC_BIG_ENDIAN);
break;
default:
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, -1,
"malformed TLV (%d vs 1,5,11,15)", length );
}
}
@@ -953,7 +953,7 @@ dissect_hello_is_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tr
{
while ( length > 0 ) {
if (length<6) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_hello_short_clv, tvb, offset, -1,
"short is neighbor (%d vs 6)", length );
return;
}
@@ -1012,7 +1012,7 @@ static void
dissect_hello_ipv6_glb_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_packet,
+ isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_hello_short_clv,
offset, length, hf_isis_hello_clv_ipv6_glb_int_addr );
}
static const isis_clv_handle_t clv_l1_hello_opts[] = {
@@ -1332,7 +1332,8 @@ dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs
{
proto_item *ti;
proto_tree *hello_tree;
- int pdu_length;
+ guint16 pdu_length;
+ gboolean pdu_length_too_short = FALSE;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS HELLO");
@@ -1353,8 +1354,14 @@ dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs
offset += 2;
pdu_length = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
- offset, 2, pdu_length);
+ ti = proto_tree_add_uint(hello_tree, hf_isis_hello_pdu_length, tvb,
+ offset, 2, pdu_length);
+ if (pdu_length < header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_hello_short_pdu);
+ pdu_length_too_short = TRUE;
+ } else if (pdu_length > tvb_reported_length(tvb) + header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_hello_long_pdu);
+ }
offset += 2;
if (opts == clv_ptp_hello_opts) {
@@ -1370,10 +1377,7 @@ dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs
offset += id_length + 1;
}
- pdu_length -= header_length;
- if (pdu_length < 0) {
- expert_add_info_format(pinfo, ti, &ei_isis_hello_long_packet,
- "Packet header length %d went beyond packet", header_length );
+ if (pdu_length_too_short) {
return;
}
/*
@@ -1381,7 +1385,8 @@ dissect_isis_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs
* our list of valid ones!
*/
isis_dissect_clvs(tvb, pinfo, hello_tree, offset,
- opts, &ei_isis_hello_short_packet, pdu_length, id_length,
+ opts, &ei_isis_hello_short_clv, pdu_length - header_length,
+ id_length,
ett_isis_hello_clv_unknown, hf_isis_hello_clv_type, hf_isis_hello_clv_length, ei_isis_hello_clv_unknown);
}
@@ -1621,13 +1626,14 @@ proto_register_isis_hello(void)
};
static ei_register_info ei[] = {
- { &ei_isis_hello_short_packet, { "isis.hello.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
- { &ei_isis_hello_long_packet, { "isis.hello.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
+ { &ei_isis_hello_short_pdu, { "isis.lsp.hello_pdu", PI_MALFORMED, PI_ERROR, "PDU length less than header length", EXPFILL }},
+ { &ei_isis_hello_long_pdu, { "isis.lsp.hello_pdu", PI_MALFORMED, PI_ERROR, "PDU length greater than packet length", EXPFILL }},
+ { &ei_isis_hello_bad_checksum, { "isis.hello.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
{ &ei_isis_hello_subtlv, { "isis.hello.subtlv.unknown", PI_PROTOCOL, PI_WARN, "Unknown Sub-TLV", EXPFILL }},
{ &ei_isis_hello_authentication, { "isis.hello.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
+ { &ei_isis_hello_short_clv, { "isis.hello.short_clv", PI_MALFORMED, PI_ERROR, "Short CLV", EXPFILL }},
{ &ei_isis_hello_clv_mt, { "isis.hello.clv_mt.malformed", PI_MALFORMED, PI_ERROR, "malformed MT-ID", EXPFILL }},
{ &ei_isis_hello_clv_unknown, { "isis.hello.clv.unknown", PI_UNDECODED, PI_NOTE, "Unknown option", EXPFILL }},
- { &ei_isis_hello_checksum, { "isis.hello.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
};
expert_module_t* expert_isis_hello;
diff --git a/epan/dissectors/packet-isis-lsp.c b/epan/dissectors/packet-isis-lsp.c
index f42933bcff..51b3637c40 100644
--- a/epan/dissectors/packet-isis-lsp.c
+++ b/epan/dissectors/packet-isis-lsp.c
@@ -531,11 +531,13 @@ static gint ett_isis_lsp_clv_srv6_loc_flags = -1;
static gint ett_isis_lsp_clv_srv6_loc_sub_tlv = -1;
static gint ett_isis_lsp_clv_srv6_endx_sid_flags = -1;
-static expert_field ie_isis_lsp_checksum_bad = EI_INIT;
-static expert_field ei_isis_lsp_short_packet = EI_INIT;
-static expert_field ei_isis_lsp_long_packet = EI_INIT;
+static expert_field ei_isis_lsp_short_pdu = EI_INIT;
+static expert_field ei_isis_lsp_long_pdu = EI_INIT;
+static expert_field ei_isis_lsp_bad_checksum = EI_INIT;
static expert_field ei_isis_lsp_subtlv = EI_INIT;
static expert_field ei_isis_lsp_authentication = EI_INIT;
+static expert_field ei_isis_lsp_short_clv = EI_INIT;
+static expert_field ei_isis_lsp_long_clv = EI_INIT;
static expert_field ei_isis_lsp_clv_mt = EI_INIT;
static expert_field ei_isis_lsp_clv_unknown = EI_INIT;
static expert_field ei_isis_lsp_malformed_subtlv = EI_INIT;
@@ -835,7 +837,7 @@ dissect_lsp_ip_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *t
while ( length > 0 ) {
if (length<12) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short IP reachability (%d vs 12)", length );
return;
}
@@ -1123,7 +1125,7 @@ dissect_lsp_ext_ip_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tre
bit_length = ctrl_info & 0x3f;
byte_length = tvb_get_ipv4_addr_with_prefix_len(tvb, offset+5, prefix.addr_bytes, bit_length);
if (byte_length == -1) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"IPv4 prefix has an invalid length: %d bits", bit_length );
return;
}
@@ -1760,7 +1762,7 @@ dissect_isis_rt_capable_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
offset += 2;
if (subtlvlen > length) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset-2, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset-2, -1,
"Short type %d TLV (%d vs %d)", subtype, subtlvlen, length);
return;
}
@@ -1818,7 +1820,7 @@ dissect_lsp_ipv6_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree
bit_length = tvb_get_guint8(tvb, offset+5);
byte_length = tvb_get_ipv6_addr_with_prefix_len(tvb, offset+6, &prefix, bit_length);
if (byte_length == -1) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"IPv6 prefix has an invalid length: %d bits", bit_length );
return;
}
@@ -2017,7 +2019,7 @@ static void
dissect_lsp_te_router_id_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length _U_, int length)
{
- isis_dissect_te_router_id_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
+ isis_dissect_te_router_id_clv(tree, pinfo, tvb, &ei_isis_lsp_short_clv, offset, length,
hf_isis_lsp_clv_te_router_id );
}
@@ -2043,7 +2045,7 @@ static void
dissect_lsp_ip_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length _U_, int length)
{
- isis_dissect_ip_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
+ isis_dissect_ip_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_clv, offset, length,
hf_isis_lsp_clv_ipv4_int_addr );
}
@@ -2068,7 +2070,7 @@ static void
dissect_lsp_ipv6_int_addr_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length _U_, int length)
{
- isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
+ isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_clv, offset, length,
hf_isis_lsp_clv_ipv6_int_addr );
}
@@ -2099,7 +2101,7 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t *tvb, packet_info *pinfo,
};
if (sublen < FIXED_LEN) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short SPB Digest subTLV (%d vs %d)", sublen, FIXED_LEN);
return;
}
@@ -2129,12 +2131,12 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t *tvb, packet_info *pinfo,
/*************************/
if (sublen != (num_trees * VLAN_ID_TUPLE_LEN)) {
- proto_tree_add_expert_format( subtree, pinfo, &ei_isis_lsp_short_packet, tvb, subofs, 0, "SubTLV length doesn't match number of trees");
+ proto_tree_add_expert_format( subtree, pinfo, &ei_isis_lsp_short_clv, tvb, subofs, 0, "SubTLV length doesn't match number of trees");
return;
}
while (sublen > 0 && num_trees > 0) {
if (sublen < VLAN_ID_TUPLE_LEN) {
- proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short VLAN_ID entry (%d vs %d)", sublen, VLAN_ID_TUPLE_LEN);
return;
}
@@ -2153,7 +2155,7 @@ dissect_isis_lsp_clv_mt_cap_spb_instance(tvbuff_t *tvb, packet_info *pinfo,
}
}
if (num_trees) {
- proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short subTLV (%d vs %d)", sublen, num_trees * VLAN_ID_TUPLE_LEN);
return;
}
@@ -2190,7 +2192,7 @@ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t *tvb, packet_info *
};
if (sublen < FIXED_LEN) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short SPBM Service Identifier and Unicast Address subTLV (%d vs %d)", sublen, FIXED_LEN);
return;
}
@@ -2212,7 +2214,7 @@ dissect_isis_lsp_clv_mt_cap_spbm_service_identifier(tvbuff_t *tvb, packet_info *
/*************************/
while (sublen > 0) {
if (sublen < ISID_LEN) {
- proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short ISID entry (%d vs %d)", sublen, 4);
return;
}
@@ -2242,7 +2244,7 @@ dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t *tvb, packet_info *pinfo,
if (sublen < 2) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short SPBV Mac Address subTLV (%d vs %d)", sublen, 2);
return;
}
@@ -2265,7 +2267,7 @@ dissect_isis_lsp_clv_mt_cap_spbv_mac_address(tvbuff_t *tvb, packet_info *pinfo,
/*************************/
while (sublen > 0) {
if (sublen < 7) {
- proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(subtree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short MAC Address entry (%d vs %d)", sublen, 7);
return;
}
@@ -2317,7 +2319,7 @@ dissect_isis_lsp_clv_mt_cap(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
length -= 2;
offset += 2;
if (subtlvlen > length) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset-2, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset-2, -1,
"Short type %d TLV (%d vs %d)", subtype, subtlvlen, length);
return;
}
@@ -2550,7 +2552,7 @@ static void
dissect_lsp_area_address_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length _U_, int length)
{
- isis_dissect_area_address_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, hf_isis_lsp_area_address, offset, length);
+ isis_dissect_area_address_clv(tree, pinfo, tvb, &ei_isis_lsp_short_clv, hf_isis_lsp_area_address, offset, length);
}
/*
@@ -2602,7 +2604,7 @@ dissect_lsp_eis_neighbors_clv_inner(tvbuff_t *tvb, packet_info *pinfo, proto_tre
while ( length > 0 ) {
if (length<tlen) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short E/IS reachability (%d vs %d)", length, tlen );
return;
}
@@ -2737,7 +2739,7 @@ static void
dissect_lsp_instance_identifier_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_instance_identifier_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, hf_isis_lsp_instance_identifier, hf_isis_lsp_supported_itid, offset, length);
+ isis_dissect_instance_identifier_clv(tree, pinfo, tvb, &ei_isis_lsp_short_clv, hf_isis_lsp_instance_identifier, hf_isis_lsp_supported_itid, offset, length);
}
/*
@@ -2976,7 +2978,7 @@ dissect_subclv_spb_link_metric(tvbuff_t *tvb, packet_info *pinfo,
const int SUBLEN = 6;
if (sublen != SUBLEN) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short SPB Link Metric sub-TLV (%d vs %d)", sublen, SUBLEN);
return;
}
@@ -3281,7 +3283,7 @@ dissect_lsp_mt_reachable_IPv4_prefx_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *tree, int offset, int id_length _U_, int length)
{
if (length < 2) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short lsp multi-topology reachable IPv4 prefixes(%d vs %d)", length, 2 );
return;
}
@@ -3310,7 +3312,7 @@ dissect_lsp_mt_reachable_IPv6_prefx_clv(tvbuff_t *tvb, packet_info* pinfo,
proto_tree *tree, int offset, int id_length _U_, int length)
{
if (length < 2) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short lsp multi-topology reachable IPv6 prefixes(%d vs %d)", length, 2 );
return;
}
@@ -3341,7 +3343,7 @@ dissect_lsp_mt_is_reachability_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree
int id_length _U_, int length)
{
if (length < 2) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short lsp reachability(%d vs %d)", length, 2 );
return;
}
@@ -3380,7 +3382,7 @@ dissect_lsp_ori_buffersize_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tr
int id_length, int length)
{
if ( length != 2 ) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short lsp partition DIS(%d vs %d)", length, id_length );
return;
}
@@ -3414,7 +3416,7 @@ dissect_lsp_partition_dis_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tre
int id_length, int length)
{
if ( length < id_length ) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"short lsp partition DIS(%d vs %d)", length, id_length );
return;
}
@@ -3426,7 +3428,7 @@ dissect_lsp_partition_dis_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tre
length -= id_length;
offset += id_length;
if ( length > 0 ) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_clv, tvb, offset, -1,
"Long lsp partition DIS, %d left over", length );
return;
}
@@ -3458,7 +3460,7 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *
int mylen;
if ( length < 4 ) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Short lsp prefix neighbors (%d vs 4)", length );
return;
}
@@ -3481,12 +3483,12 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *
mylen = tvb_get_guint8(tvb, offset);
length--;
if (length<=0) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, -1,
"Zero payload space after length in prefix neighbor" );
return;
}
if ( mylen > length*2) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_clv, tvb, offset, -1,
"Integral length of prefix neighbor too long (%d vs %d)", mylen, length*2 );
return;
}
@@ -3525,7 +3527,7 @@ static void
dissect_lsp_ipv6_te_router_id_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset,
int id_length _U_, int length)
{
- isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_packet, offset, length,
+ isis_dissect_ipv6_int_clv(tree, pinfo, tvb, &ei_isis_lsp_short_clv, offset, length,
hf_isis_lsp_clv_ipv6_te_router_id );
}
@@ -3602,7 +3604,7 @@ dissect_lsp_srv6_locator_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree
proto_tree *subtree = NULL;
if (length < min_tlv_len) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, length,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, length,
"Short LSP SRv6 locator (%d vs %d)",
length, min_tlv_len);
return;
@@ -3643,7 +3645,7 @@ dissect_lsp_srv6_locator_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree
return;
}
if (length < byte_length + 1) { /* including Sub-tlv-len */
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_packet, tvb, offset, length,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_short_clv, tvb, offset, length,
"Invalid locator length %u (%d bytes left)",
byte_length, length);
return;
@@ -4061,9 +4063,11 @@ dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset
proto_item *ti;
proto_tree *lsp_tree, *info_tree;
guint16 pdu_length, lifetime, checksum, cacl_checksum=0;
- guint8 lsp_info;
- int len, offset_checksum;
- char* system_id;
+ gboolean pdu_length_too_short = FALSE;
+ gboolean pdu_length_too_long = FALSE;
+ guint8 lsp_info;
+ int offset_checksum;
+ char *system_id;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS LSP");
@@ -4071,8 +4075,15 @@ dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset
lsp_tree = proto_item_add_subtree(ti, ett_isis_lsp);
pdu_length = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
+ ti = proto_tree_add_uint(lsp_tree, hf_isis_lsp_pdu_length, tvb,
offset, 2, pdu_length);
+ if (pdu_length < header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_lsp_short_pdu);
+ pdu_length_too_short = TRUE;
+ } else if (pdu_length > tvb_reported_length(tvb) + header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_lsp_long_pdu);
+ pdu_length_too_long = TRUE;
+ }
offset += 2;
proto_tree_add_item(lsp_tree, hf_isis_lsp_remaining_life,
@@ -4100,20 +4111,20 @@ dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset
checksum = lifetime ? tvb_get_ntohs(tvb, offset) : 0;
if (checksum == 0) {
/* No checksum present */
- proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ie_isis_lsp_checksum_bad, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NOT_PRESENT);
+ proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ei_isis_lsp_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NOT_PRESENT);
+ } else if (pdu_length_too_short || pdu_length_too_long) {
+ /* Length bogus, so we can't check the checksum */
+ proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ei_isis_lsp_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
} else {
if (osi_check_and_get_checksum(tvb, offset_checksum, pdu_length-12, offset, &cacl_checksum)) {
/* Successfully processed checksum, verify it */
- proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ie_isis_lsp_checksum_bad, pinfo, cacl_checksum, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
+ proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ei_isis_lsp_bad_checksum, pinfo, cacl_checksum, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
if (cacl_checksum != checksum) {
col_append_str(pinfo->cinfo, COL_INFO, " [ISIS CHECKSUM INCORRECT]");
}
-
} else {
- proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ie_isis_lsp_checksum_bad, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
- "Packet length %d went beyond packet",
- tvb_reported_length_remaining(tvb, offset_checksum));
+ /* We didn't capture the entire packet, so we can't verify it */
+ proto_tree_add_checksum(lsp_tree, tvb, offset, hf_isis_lsp_checksum, hf_isis_lsp_checksum_status, &ei_isis_lsp_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
}
}
offset += 2;
@@ -4148,11 +4159,7 @@ dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset
}
offset += 1;
- len = pdu_length - header_length;
- if (len < 0) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1,
- "packet header length %d went beyond packet",
- header_length );
+ if (pdu_length_too_short) {
return;
}
/*
@@ -4160,7 +4167,8 @@ dissect_isis_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset
* our list of valid ones!
*/
isis_dissect_clvs(tvb, pinfo, lsp_tree, offset,
- opts, &ei_isis_lsp_short_packet, len, id_length, ett_isis_lsp_clv_unknown, hf_isis_lsp_clv_type, hf_isis_lsp_clv_length, ei_isis_lsp_clv_unknown);
+ opts, &ei_isis_lsp_short_clv, pdu_length - header_length,
+ id_length, ett_isis_lsp_clv_unknown, hf_isis_lsp_clv_type, hf_isis_lsp_clv_length, ei_isis_lsp_clv_unknown);
}
static int
@@ -5824,11 +5832,13 @@ proto_register_isis_lsp(void)
};
static ei_register_info ei[] = {
- { &ie_isis_lsp_checksum_bad, { "isis.lsp.checksum_bad.expert", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
- { &ei_isis_lsp_short_packet, { "isis.lsp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
- { &ei_isis_lsp_long_packet, { "isis.lsp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }},
+ { &ei_isis_lsp_short_pdu, { "isis.lsp.short_pdu", PI_MALFORMED, PI_ERROR, "PDU length less than header length", EXPFILL }},
+ { &ei_isis_lsp_long_pdu, { "isis.lsp.long_pdu", PI_MALFORMED, PI_ERROR, "PDU length greater than packet length", EXPFILL }},
+ { &ei_isis_lsp_bad_checksum, { "isis.lsp.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
{ &ei_isis_lsp_subtlv, { "isis.lsp.subtlv.unknown", PI_PROTOCOL, PI_WARN, "Unknown SubTLV", EXPFILL }},
{ &ei_isis_lsp_authentication, { "isis.lsp.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
+ { &ei_isis_lsp_short_clv, { "isis.lsp.short_clv", PI_MALFORMED, PI_ERROR, "Short CLV", EXPFILL }},
+ { &ei_isis_lsp_long_clv, { "isis.lsp.long_clv", PI_MALFORMED, PI_ERROR, "Long CLV", EXPFILL }},
{ &ei_isis_lsp_clv_mt, { "isis.lsp.clv_mt.malformed", PI_MALFORMED, PI_ERROR, "malformed MT-ID", EXPFILL }},
{ &ei_isis_lsp_clv_unknown, { "isis.lsp.clv.unknown", PI_UNDECODED, PI_NOTE, "Unknown option", EXPFILL }},
{ &ei_isis_lsp_malformed_subtlv, { "isis.lsp.subtlv.malformed", PI_MALFORMED, PI_ERROR, "malformed SubTLV", EXPFILL }},
diff --git a/epan/dissectors/packet-isis-snp.c b/epan/dissectors/packet-isis-snp.c
index d287eb96f0..6842ac6810 100644
--- a/epan/dissectors/packet-isis-snp.c
+++ b/epan/dissectors/packet-isis-snp.c
@@ -56,11 +56,12 @@ static gint ett_isis_csnp_clv_instance_identifier = -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_short_pdu = EI_INIT;
+static expert_field ei_isis_csnp_long_pdu = EI_INIT;
+static expert_field ei_isis_csnp_bad_checksum = EI_INIT;
static expert_field ei_isis_csnp_authentication = EI_INIT;
+static expert_field ei_isis_csnp_short_clv = EI_INIT;
static expert_field ei_isis_csnp_clv_unknown = EI_INIT;
-static expert_field ei_isis_csnp_checksum = EI_INIT;
/* psnp packets */
static int hf_isis_psnp_pdu_length = -1;
@@ -76,8 +77,9 @@ 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 expert_field ei_isis_psnp_short_packet = EI_INIT;
-static expert_field ei_isis_psnp_long_packet = EI_INIT;
+static expert_field ei_isis_psnp_short_pdu = EI_INIT;
+static expert_field ei_isis_psnp_long_pdu = EI_INIT;
+static expert_field ei_isis_psnp_short_clv = EI_INIT;
static expert_field ei_isis_psnp_clv_unknown = EI_INIT;
static void
@@ -116,10 +118,9 @@ 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,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_clv, tvb, offset, -1,
"incorrect checksum length (%u), should be (2)", length );
return;
}
@@ -127,24 +128,23 @@ dissect_snp_checksum_clv(tvbuff_t *tvb, packet_info* pinfo,
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 */
+ /* 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);
if (checksum == 0) {
/* No checksum present */
- proto_tree_add_checksum(tree, tvb, offset, hf_isis_csnp_checksum, hf_isis_csnp_checksum_status, &ei_isis_csnp_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NOT_PRESENT);
+ proto_tree_add_checksum(tree, tvb, offset, hf_isis_csnp_checksum, hf_isis_csnp_checksum_status, &ei_isis_csnp_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NOT_PRESENT);
} else {
if (osi_check_and_get_checksum(tvb, 0, pdu_length, offset, &cacl_checksum)) {
/* Successfully processed checksum, verify it */
- proto_tree_add_checksum(tree, tvb, offset, hf_isis_csnp_checksum, hf_isis_csnp_checksum_status, &ei_isis_csnp_checksum, pinfo, cacl_checksum, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
+ proto_tree_add_checksum(tree, tvb, offset, hf_isis_csnp_checksum, hf_isis_csnp_checksum_status, &ei_isis_csnp_bad_checksum, pinfo, cacl_checksum, ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
} else {
- ti = proto_tree_add_checksum(tree, tvb, offset, hf_isis_csnp_checksum, hf_isis_csnp_checksum_status, &ei_isis_csnp_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
- expert_add_info_format(pinfo, ti, &ei_isis_csnp_long_packet,
- "Packet length %d went beyond packet", tvb_captured_length(tvb));
+ /* We didn't capture the entire packet, so we can't verify it */
+ proto_tree_add_checksum(tree, tvb, offset, hf_isis_csnp_checksum, hf_isis_csnp_checksum_status, &ei_isis_csnp_bad_checksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
}
}
}
@@ -168,7 +168,7 @@ dissect_snp_lsp_entries_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
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,
+ proto_tree_add_expert_format(tree, pinfo, &ei_isis_csnp_short_clv, tvb, offset, -1,
"Short SNP header entry (%d vs %d)", length, 2+id_length+2+4+2 );
return;
}
@@ -209,7 +209,7 @@ static void
dissect_snp_instance_identifier_clv(tvbuff_t *tvb, packet_info* pinfo _U_,
proto_tree *tree, int offset, int id_length _U_, int length)
{
- isis_dissect_instance_identifier_clv(tree, pinfo, tvb, &ei_isis_csnp_short_packet, hf_isis_csnp_instance_identifier, hf_isis_csnp_supported_itid, offset, length);
+ isis_dissect_instance_identifier_clv(tree, pinfo, tvb, &ei_isis_csnp_short_clv, hf_isis_csnp_instance_identifier, hf_isis_csnp_supported_itid, offset, length);
}
static const isis_clv_handle_t clv_l1_csnp_opts[] = {
@@ -363,7 +363,7 @@ dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
proto_item *ti;
proto_tree *csnp_tree = NULL;
guint16 pdu_length;
- int len;
+ gboolean pdu_length_too_short = FALSE;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS CSNP");
@@ -371,8 +371,14 @@ dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
csnp_tree = proto_item_add_subtree(ti, ett_isis_csnp);
pdu_length = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
+ ti = proto_tree_add_uint(csnp_tree, hf_isis_csnp_pdu_length, tvb,
offset, 2, pdu_length);
+ if (pdu_length < header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_csnp_short_pdu);
+ pdu_length_too_short = TRUE;
+ } else if (pdu_length > tvb_reported_length(tvb) + header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_csnp_long_pdu);
+ }
offset += 2;
proto_tree_add_item(csnp_tree, hf_isis_csnp_source_id, tvb, offset, id_length + 1, ENC_NA);
@@ -389,15 +395,12 @@ dissect_isis_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
tvb_print_system_id( tvb, offset, id_length+2 ));
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 );
+ if (pdu_length_too_short) {
return;
}
-
isis_dissect_clvs(tvb, pinfo, csnp_tree, offset,
- opts, &ei_isis_csnp_short_packet, len, id_length, ett_isis_csnp_clv_unknown, hf_isis_csnp_clv_type, hf_isis_csnp_clv_length, ei_isis_csnp_clv_unknown);
+ opts, &ei_isis_csnp_short_clv, pdu_length - header_length,
+ id_length, ett_isis_csnp_clv_unknown, hf_isis_csnp_clv_type, hf_isis_csnp_clv_length, ei_isis_csnp_clv_unknown);
}
@@ -426,7 +429,8 @@ dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
proto_item *ti;
proto_tree *psnp_tree;
guint16 pdu_length;
- int len;
+ gboolean pdu_length_too_short = FALSE;
+ int len;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISIS PSNP");
@@ -434,8 +438,14 @@ dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
psnp_tree = proto_item_add_subtree(ti, ett_isis_psnp);
pdu_length = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
+ ti = proto_tree_add_uint(psnp_tree, hf_isis_psnp_pdu_length, tvb,
offset, 2, pdu_length);
+ if (pdu_length < header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_psnp_short_pdu);
+ pdu_length_too_short = TRUE;
+ } else if (pdu_length > tvb_reported_length(tvb) + header_length) {
+ expert_add_info(pinfo, ti, &ei_isis_psnp_long_pdu);
+ }
offset += 2;
proto_tree_add_item(psnp_tree, hf_isis_psnp_source_id, tvb, offset, id_length, ENC_NA);
@@ -443,15 +453,12 @@ dissect_isis_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
offset += id_length + 1;
- len = pdu_length - header_length;
- if (len < 0) {
- proto_tree_add_expert_format(tree, pinfo, &ei_isis_psnp_long_packet, tvb, offset, -1,
- "packet header length %d went beyond packet", header_length );
+ if (pdu_length_too_short) {
return;
}
- /* Call into payload dissector */
+ len = pdu_length - header_length;
isis_dissect_clvs(tvb, pinfo, psnp_tree, offset,
- opts, &ei_isis_psnp_short_packet, len, id_length, ett_isis_psnp_clv_unknown, hf_isis_psnp_clv_type, hf_isis_psnp_clv_length, ei_isis_psnp_clv_unknown);
+ opts, &ei_isis_psnp_short_clv, len, id_length, ett_isis_psnp_clv_unknown, hf_isis_psnp_clv_type, hf_isis_psnp_clv_length, ei_isis_psnp_clv_unknown);
}
static int
@@ -538,11 +545,12 @@ proto_register_isis_csnp(void)
};
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_short_pdu, { "isis.csnp.short_pdu", PI_MALFORMED, PI_ERROR, "PDU length less than header length", EXPFILL }},
+ { &ei_isis_csnp_long_pdu, { "isis.csnp.long_pdu", PI_MALFORMED, PI_ERROR, "PDU length greater than packet length", EXPFILL }},
+ { &ei_isis_csnp_bad_checksum, { "isis.csnp.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
+ { &ei_isis_csnp_short_clv, { "isis.csnp.short_clv", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }},
{ &ei_isis_csnp_authentication, { "isis.csnp.authentication.unknown", PI_PROTOCOL, PI_WARN, "Unknown authentication type", EXPFILL }},
{ &ei_isis_csnp_clv_unknown, { "isis.csnp.clv.unknown", PI_UNDECODED, PI_NOTE, "Unknown option", EXPFILL }},
- { &ei_isis_csnp_checksum, { "isis.csnp.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
};
expert_module_t* expert_isis_csnp;
@@ -593,8 +601,9 @@ proto_register_isis_psnp(void)
&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 }},
+ { &ei_isis_psnp_short_pdu, { "isis.psnp.short_pdu", PI_MALFORMED, PI_ERROR, "PDU length less than header length", EXPFILL }},
+ { &ei_isis_psnp_long_pdu, { "isis.psnp.long_pdu", PI_MALFORMED, PI_ERROR, "PDU length greater than packet length", EXPFILL }},
+ { &ei_isis_psnp_short_clv, { "isis.psnp.short_clv", PI_MALFORMED, PI_ERROR, "Short CLV", EXPFILL }},
{ &ei_isis_psnp_clv_unknown, { "isis.psnp.clv.unknown", PI_UNDECODED, PI_NOTE, "Unknown option", EXPFILL }},
};
expert_module_t* expert_isis_psnp;
diff --git a/epan/dissectors/packet-osi.c b/epan/dissectors/packet-osi.c
index c58239941b..3240fb0b5d 100644
--- a/epan/dissectors/packet-osi.c
+++ b/epan/dissectors/packet-osi.c
@@ -86,7 +86,6 @@ osi_calc_checksum( tvbuff_t *tvb, int offset, guint len, guint32* c0, guint32* c
gboolean
osi_check_and_get_checksum( tvbuff_t *tvb, int offset, guint len, int offset_check, guint16* result) {
- guint available_len;
const guint8 *p;
guint8 discard = 0;
guint32 c0, c1, factor;
@@ -94,10 +93,17 @@ osi_check_and_get_checksum( tvbuff_t *tvb, int offset, guint len, int offset_che
guint i;
int block, x, y;
- available_len = tvb_captured_length_remaining( tvb, offset );
- offset_check -= offset;
- if ( ( available_len < len ) || ( offset_check < 0 ) || ( (guint)(offset_check+2) > len ) )
+ /* Make sure the checksum is part of the data being checksummed. */
+ DISSECTOR_ASSERT(offset_check >= offset);
+ DISSECTOR_ASSERT((guint)offset_check + 2 <= (guint)offset + len);
+
+ /*
+ * If we don't have all the data to be checksummed, report that and don't
+ * try checksumming.
+ */
+ if (!tvb_bytes_exist(tvb, offset, len))
return FALSE;
+ offset_check -= offset;
p = tvb_get_ptr( tvb, offset, len );
block = offset_check / 5803;