diff --git a/epan/dissectors/packet-isis-lsp.c b/epan/dissectors/packet-isis-lsp.c index 34feda0aa3..2ed6cd30ba 100644 --- a/epan/dissectors/packet-isis-lsp.c +++ b/epan/dissectors/packet-isis-lsp.c @@ -622,9 +622,9 @@ dissect_metric(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset, int s; proto_item *item, *support_item; - s = ISIS_LSP_CLV_METRIC_SUPPORTED(value); - item = proto_tree_add_uint(tree, hf, tvb, offset, 1, value); - support_item = proto_tree_add_uint(tree, hf_support, tvb, offset, 1, value); + s = ISIS_LSP_CLV_METRIC_SUPPORTED(value) ? TRUE : FALSE; + item = proto_tree_add_uint(tree, hf, tvb, offset, 1, ISIS_LSP_CLV_METRIC_VALUE(value)); + support_item = proto_tree_add_boolean(tree, hf_support, tvb, offset, 1, s); if (s && force_supported) proto_item_append_text(support_item, " (but is required to be)"); @@ -3078,6 +3078,9 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree * offset += 4; length -= 4; while ( length > 0 ) { + /* + * This is a length in "semi-octets", i.e., in nibbles. + */ mylen = tvb_get_guint8(tvb, offset); length--; if (length<=0) { @@ -3085,9 +3088,9 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree * "Zero payload space after length in prefix neighbor" ); return; } - if ( mylen > length) { + if ( mylen > length*2) { proto_tree_add_expert_format(tree, pinfo, &ei_isis_lsp_long_packet, tvb, offset, -1, - "Integral length of prefix neighbor too long (%d vs %d)", mylen, length ); + "Integral length of prefix neighbor too long (%d vs %d)", mylen, length*2 ); return; } @@ -3095,9 +3098,9 @@ dissect_lsp_prefix_neighbors_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree * * Lets turn the area address into "standard" 0000.0000.etc * format string. */ - sbuf = print_area( tvb, offset+1, mylen ); + sbuf = print_address_prefix( tvb, offset+1, mylen ); /* and spit it out */ - proto_tree_add_string( tree, hf_isis_lsp_area_address_str, tvb, offset, mylen + 1, sbuf); + proto_tree_add_string( tree, hf_isis_lsp_area_address_str, tvb, offset, (mylen+1)/2 + 1, sbuf); offset += mylen + 1; length -= mylen; /* length already adjusted for len fld*/ diff --git a/epan/osi-utils.c b/epan/osi-utils.c index 82a4216b86..46d20caf0e 100644 --- a/epan/osi-utils.c +++ b/epan/osi-utils.c @@ -37,6 +37,7 @@ static void print_nsap_net_buf( const guint8 *, int, gchar *, int); static void print_area_buf ( const guint8 *, int, gchar *, int); +static void print_address_prefix_buf ( const guint8 *, int, gchar *, int); /* * XXX - shouldn't there be a centralized routine for dissecting NSAPs? @@ -152,16 +153,40 @@ print_area(tvbuff_t *tvb, const gint offset, int length) return cur; } +/* + * Note: length is in units of half-octets. + */ +gchar * +print_address_prefix(tvbuff_t *tvb, const gint offset, int length) +{ + gchar *cur; + + cur = (gchar *)wmem_alloc(wmem_packet_scope(), MAX_AREA_LEN * 3 + 20); + print_address_prefix_buf(tvb_get_ptr(tvb, offset, (length+1)/2), length, cur, MAX_AREA_LEN * 3 + 20); + return cur; +} + +/* + * Note: length is in units of octets. + */ static void print_area_buf(const guint8 *ad, int length, gchar *buf, int buf_len) +{ + print_address_prefix_buf(ad, length*2, buf, buf_len); +} + +/* + * Note: length is in units of half-octets. + */ +static void +print_address_prefix_buf(const guint8 *ad, int length, gchar *buf, int buf_len) { gchar *cur; int tmp = 0; /* to do : all real area decoding now: NET is assumed if id len is 1 more byte - * and take away all these stupid resource consuming local statics */ - if (length <= 0 || length > MAX_AREA_LEN) { + if (length <= 0 || length > MAX_AREA_LEN*2) { g_strlcpy(buf, "", buf_len); return; } @@ -171,8 +196,8 @@ print_area_buf(const guint8 *ad, int length, gchar *buf, int buf_len) || ( NSAP_IDI_ISO_6523_ICD_BIN == *ad ) ) && - ( ( RFC1237_FULLAREA_LEN == length ) - || ( RFC1237_FULLAREA_LEN + 1 == length ) + ( ( RFC1237_FULLAREA_LEN*2 == length ) + || ( (RFC1237_FULLAREA_LEN + 1)*2 == length ) ) ) { /* AFI is good and length is long enough */ @@ -187,35 +212,40 @@ print_area_buf(const guint8 *ad, int length, gchar *buf, int buf_len) ad[5], ad[6], ad[7], ad[8] ); cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "[%02x:%02x|%02x:%02x]", ad[9], ad[10], ad[11], ad[12] ); - if ( RFC1237_FULLAREA_LEN + 1 == length ) + if ( (RFC1237_FULLAREA_LEN + 1)*2 == length ) g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "-[%02x]", ad[20] ); } else { /* print standard format */ - if ( length == RFC1237_AREA_LEN ) { + if ( length == RFC1237_AREA_LEN*2 ) { g_snprintf(buf, buf_len, "%02x.%02x%02x", ad[0], ad[1], ad[2] ); return; } - if ( length == 4 ) { + if ( length == 4*2 ) { g_snprintf(buf, buf_len, "%02x%02x%02x%02x", ad[0], ad[1], ad[2], ad[3] ); return; } - while ( tmp < length / 4 ) { /* 16/4==4 > four Octets left to print */ + while ( tmp < length / 8 ) { /* 32/8==4 > four Octets left to print */ cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "%02x", ad[tmp++] ); cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "%02x", ad[tmp++] ); cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "%02x", ad[tmp++] ); cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "%02x.", ad[tmp++] ); } - if ( 1 == tmp ) { /* Special case for Designated IS */ + if ( 2 == tmp ) { /* Special case for Designated IS */ cur--; g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "-%02x", ad[tmp] ); } else { - for ( ; tmp < length; ) { /* print the rest without dot or dash */ + for ( ; tmp < length / 2; ) { /* print the rest without dot or dash */ cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "%02x", ad[tmp++] ); } + /* Odd half-octet? */ + if (length & 1) { + /* Yes - print it (it's the upper half-octet) */ + cur += g_snprintf(cur, (gulong) (buf_len-(cur-buf)), "%x", (ad[tmp] & 0xF0)>>4 ); + } } } -} /* print_area_buf */ +} /* print_address_prefix_buf */ /****************************************************************************** * OSI Address Type diff --git a/epan/osi-utils.h b/epan/osi-utils.h index d3f172e3e5..40fd06db8c 100644 --- a/epan/osi-utils.h +++ b/epan/osi-utils.h @@ -115,6 +115,7 @@ gchar* print_area ( tvbuff_t *, const gint, int ); gchar* print_system_id(wmem_allocator_t *, const guint8 *, int ); gchar* tvb_print_system_id( tvbuff_t *, const gint, int ); void print_system_id_buf( const guint8 *, int, gchar *, int); +gchar* print_address_prefix( tvbuff_t *, const gint, int ); int get_osi_address_type(void); void register_osi_address_type(void);