X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/7217abf41a060c9e9b5cdde30a759e79329a1b00..a37ced67021c5f4afb14cfc26dd5fee115c78d33:/print-isoclns.c diff --git a/print-isoclns.c b/print-isoclns.c index 96a16bc3..f2235d28 100644 --- a/print-isoclns.c +++ b/print-isoclns.c @@ -29,7 +29,7 @@ /* * specification: * - * CLNP: ISO 8473 (respective ITU version is at http://www.itu.int/rec/T-REC-X.233/en/) + * CLNP: ISO 8473 (respective ITU version is at https://www.itu.int/rec/T-REC-X.233/en/) * ES-IS: ISO 9542 * IS-IS: ISO 10589 */ @@ -106,7 +106,7 @@ static const struct tok isis_pdu_values[] = { #define ISIS_TLV_PART_DIS 4 /* iso10589 */ #define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */ #define ISIS_TLV_ISNEIGH 6 /* iso10589 */ -#define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */ +#define ISIS_TLV_INSTANCE_ID 7 /* rfc8202 */ #define ISIS_TLV_PADDING 8 /* iso10589 */ #define ISIS_TLV_LSP 9 /* iso10589 */ #define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ @@ -143,6 +143,7 @@ static const struct tok isis_pdu_values[] = { #define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ #define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */ #define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ +#define ISIS_TLV_ROUTER_CAPABILITY 242 /* rfc7981 */ #define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */ #define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3 @@ -153,7 +154,7 @@ static const struct tok isis_tlv_values[] = { { ISIS_TLV_PART_DIS, "Partition DIS"}, { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"}, { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"}, - { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, + { ISIS_TLV_INSTANCE_ID, "Instance Identifier"}, { ISIS_TLV_PADDING, "Padding"}, { ISIS_TLV_LSP, "LSP entries"}, { ISIS_TLV_AUTH, "Authentication"}, @@ -187,6 +188,7 @@ static const struct tok isis_tlv_values[] = { { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"}, { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, + { ISIS_TLV_ROUTER_CAPABILITY, "IS-IS Router Capability"}, { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"}, { 0, NULL } }; @@ -340,6 +342,25 @@ static const struct tok clnp_option_qos_global_values[] = { { 0, NULL } }; +static const struct tok isis_tlv_router_capability_flags[] = { + { 0x01, "S bit"}, + { 0x02, "D bit"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_ROUTER_CAP_SR 2 /* rfc 8667 */ + +static const struct tok isis_router_capability_subtlv_values[] = { + { ISIS_SUBTLV_ROUTER_CAP_SR, "SR-Capabilities"}, + { 0, NULL } +}; + +static const struct tok isis_router_capability_sr_flags[] = { + { 0x80, "ipv4"}, + { 0x40, "ipv6"}, + { 0, NULL } +}; + #define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* rfc5305 */ #define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */ #define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* rfc5305 */ @@ -384,15 +405,42 @@ static const struct tok isis_ext_is_reach_subtlv_values[] = { #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */ #define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */ +#define ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID 3 /* rfc8667 */ #define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */ static const struct tok isis_ext_ip_reach_subtlv_values[] = { { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, + { ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID, "Prefix SID" }, { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" }, { 0, NULL } }; +#define ISIS_PREFIX_SID_FLAG_R 0x80 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_N 0x40 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_P 0x20 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_E 0x10 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_V 0x08 /* rfc 8667 */ +#define ISIS_PREFIX_SID_FLAG_L 0x04 /* rfc 8667 */ + +static const struct tok prefix_sid_flag_values[] = { + { ISIS_PREFIX_SID_FLAG_R, "Readvertisement"}, + { ISIS_PREFIX_SID_FLAG_N, "Node"}, + { ISIS_PREFIX_SID_FLAG_P, "No-PHP"}, + { ISIS_PREFIX_SID_FLAG_E, "Explicit NULL"}, + { ISIS_PREFIX_SID_FLAG_V, "Value"}, + { ISIS_PREFIX_SID_FLAG_L, "Local"}, + { 0, NULL} +}; + + +/* rfc 8667 */ +static const struct tok prefix_sid_algo_values[] = { + { 0, "SPF"}, + { 1, "strict-SPF"}, + { 0, NULL} +}; + static const struct tok isis_subtlv_link_attribute_values[] = { { 0x01, "Local Protection Available" }, { 0x02, "Link excluded from local protection path" }, @@ -857,8 +905,8 @@ clnp_print(netdissect_options *ndo, if (ndo->ndo_vflag < 1) { ND_PRINT("%s%s > %s, %s, length %u", ndo->ndo_eflag ? "" : ", ", - isonsap_string(ndo, source_address, source_address_length), - isonsap_string(ndo, dest_address, dest_address_length), + GET_ISONSAP_STRING(source_address, source_address_length), + GET_ISONSAP_STRING(dest_address, dest_address_length), tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), length); return (1); @@ -882,9 +930,9 @@ clnp_print(netdissect_options *ndo, ND_PRINT("\n\tsource address (length %u): %s\n\tdest address (length %u): %s", source_address_length, - isonsap_string(ndo, source_address, source_address_length), + GET_ISONSAP_STRING(source_address, source_address_length), dest_address_length, - isonsap_string(ndo, dest_address, dest_address_length)); + GET_ISONSAP_STRING(dest_address, dest_address_length)); if (clnp_flags & CLNP_SEGMENT_PART) { if (li_remaining < sizeof(struct clnp_segment_header_t)) { @@ -973,7 +1021,7 @@ clnp_print(netdissect_options *ndo, source_address_length); ND_PRINT("\n\t NSAP address (length %u): %s", source_address_length, - isonsap_string(ndo, source_address, source_address_length)); + GET_ISONSAP_STRING(source_address, source_address_length)); } tlen-=source_address_length+1; } @@ -1214,7 +1262,7 @@ esis_print(netdissect_options *ndo, dst = pptr; pptr += dstl; li -= dstl; - ND_PRINT("\n\t %s", isonsap_string(ndo, dst, dstl)); + ND_PRINT("\n\t %s", GET_ISONSAP_STRING(dst, dstl)); ND_TCHECK_1(pptr); if (li < 1) { @@ -1251,15 +1299,15 @@ esis_print(netdissect_options *ndo, if (snpal == 6) ND_PRINT("\n\t SNPA (length: %u): %s", snpal, - etheraddr_string(ndo, snpa)); + GET_ETHERADDR_STRING(snpa)); else ND_PRINT("\n\t SNPA (length: %u): %s", snpal, - linkaddr_string(ndo, snpa, LINKADDR_OTHER, snpal)); + GET_LINKADDR_STRING(snpa, LINKADDR_OTHER, snpal)); if (netal != 0) ND_PRINT("\n\t NET (length: %u) %s", netal, - isonsap_string(ndo, neta, netal)); + GET_ISONSAP_STRING(neta, netal)); break; } @@ -1292,7 +1340,7 @@ esis_print(netdissect_options *ndo, } ND_PRINT("\n\t NET (length: %u): %s", source_address_length, - isonsap_string(ndo, pptr, source_address_length)); + GET_ISONSAP_STRING(pptr, source_address_length)); pptr += source_address_length; li -= source_address_length; source_address_number--; @@ -1314,7 +1362,7 @@ esis_print(netdissect_options *ndo, ND_PRINT(", bad ish/li"); return; } - ND_PRINT("\n\t NET (length: %u): %s", source_address_length, isonsap_string(ndo, pptr, source_address_length)); + ND_PRINT("\n\t NET (length: %u): %s", source_address_length, GET_ISONSAP_STRING(pptr, source_address_length)); pptr += source_address_length; li -= source_address_length; break; @@ -1712,19 +1760,19 @@ isis_print_id(netdissect_options *ndo, const uint8_t *cp, u_int id_len) if (sysid_len > id_len) sysid_len = id_len; for (i = 1; i <= sysid_len; i++) { - nd_snprintf(pos, sizeof(id) - (pos - id), "%02x", GET_U_1(cp)); + snprintf(pos, sizeof(id) - (pos - id), "%02x", GET_U_1(cp)); cp++; pos += strlen(pos); if (i == 2 || i == 4) *pos++ = '.'; } if (id_len >= NODE_ID_LEN) { - nd_snprintf(pos, sizeof(id) - (pos - id), ".%02x", GET_U_1(cp)); + snprintf(pos, sizeof(id) - (pos - id), ".%02x", GET_U_1(cp)); cp++; pos += strlen(pos); } if (id_len == LSP_ID_LEN) - nd_snprintf(pos, sizeof(id) - (pos - id), "-%02x", GET_U_1(cp)); + snprintf(pos, sizeof(id) - (pos - id), "-%02x", GET_U_1(cp)); return (id); } @@ -1763,9 +1811,9 @@ isis_print_tlv_ip_reach(netdissect_options *ndo, while (length > 0) { if ((size_t)length < sizeof(*tlv_ip_reach)) { - ND_PRINT("short IPv4 Reachability (%u vs %lu)", + ND_PRINT("short IPv4 Reachability (%u vs %zu)", length, - (unsigned long)sizeof(*tlv_ip_reach)); + sizeof(*tlv_ip_reach)); return (0); } @@ -1776,12 +1824,12 @@ isis_print_tlv_ip_reach(netdissect_options *ndo, if (prefix_len == -1) ND_PRINT("%sIPv4 prefix: %s mask %s", ident, - ipaddr_string(ndo, (tlv_ip_reach->prefix)), - ipaddr_string(ndo, (tlv_ip_reach->mask))); + GET_IPADDR_STRING(tlv_ip_reach->prefix), + GET_IPADDR_STRING(tlv_ip_reach->mask)); else ND_PRINT("%sIPv4 prefix: %15s/%u", ident, - ipaddr_string(ndo, (tlv_ip_reach->prefix)), + GET_IPADDR_STRING(tlv_ip_reach->prefix), prefix_len); ND_PRINT(", Distribution: %s, Metric: %u, %s", @@ -1852,6 +1900,31 @@ isis_print_ip_reach_subtlv(netdissect_options *ndo, subl-=8; } break; + case ISIS_SUBTLV_EXTD_IP_REACH_PREFIX_SID: + { + uint8_t algo, flags; + uint32_t sid; + + flags = GET_U_1(tptr); + algo = GET_U_1(tptr+1); + + if (flags & ISIS_PREFIX_SID_FLAG_V) { + sid = GET_BE_U_3(tptr+2); + tptr+=5; + subl-=5; + } else { + sid = GET_BE_U_4(tptr+2); + tptr+=6; + subl-=6; + } + + ND_PRINT(", Flags [%s], Algo %s (%u), %s %u", + bittok2str(prefix_sid_flag_values, "None", flags), + tok2str(prefix_sid_algo_values, "Unknown", algo), algo, + flags & ISIS_PREFIX_SID_FLAG_V ? "label" : "index", + sid); + } + break; default: if (!print_unknown_data(ndo, tptr, "\n\t\t ", subl)) return(0); @@ -1913,7 +1986,7 @@ isis_print_ext_is_reach(netdissect_options *ndo, if (subtlv_sum_len) { ND_PRINT(" (%u)", subtlv_sum_len); /* prepend the indent string */ - nd_snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); ident = ident_buffer; while (subtlv_sum_len != 0) { ND_TCHECK_2(tptr); @@ -1964,7 +2037,7 @@ isis_print_ext_is_reach(netdissect_options *ndo, case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: if (subtlv_len >= sizeof(nd_ipv4)) - ND_PRINT(", %s", ipaddr_string(ndo, tptr)); + ND_PRINT(", %s", GET_IPADDR_STRING(tptr)); break; case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: @@ -2208,12 +2281,12 @@ isis_print_extd_ip_reach(netdissect_options *ndo, if (afi == AF_INET) ND_PRINT("%sIPv4 prefix: %15s/%u", ident, - ipaddr_string(ndo, prefix), + ipaddr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IPADDR_STRING() */ bit_length); else if (afi == AF_INET6) ND_PRINT("%sIPv6 prefix: %s/%u", ident, - ip6addr_string(ndo, prefix), + ip6addr_string(ndo, prefix), /* local buffer, not packet data; don't use GET_IP6ADDR_STRING() */ bit_length); ND_PRINT(", Distribution: %s, Metric: %u", @@ -2246,7 +2319,7 @@ isis_print_extd_ip_reach(netdissect_options *ndo, subtlvlen=GET_U_1(tptr + 1); tptr+=2; /* prepend the indent string */ - nd_snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); if (!isis_print_ip_reach_subtlv(ndo, tptr, subtlvtype, subtlvlen, ident_buffer)) return(0); tptr+=subtlvlen; @@ -2258,6 +2331,90 @@ trunc: return 0; } +static void +isis_print_router_cap_subtlv(netdissect_options *ndo, const uint8_t *tptr, uint8_t tlen) +{ + uint8_t subt, subl; + + while (tlen >= 2) { + ND_TCHECK_LEN(tptr, 2); + subt = GET_U_1(tptr); + subl = GET_U_1(tptr+1); + tlen -= 2; + tptr += 2; + + /* first lets see if we know the subTLVs name*/ + ND_PRINT("\n\t\t%s subTLV #%u, length: %u", + tok2str(isis_router_capability_subtlv_values, "unknown", subt), + subt, subl); + + /* + * Boundary check. + */ + if (subl > tlen) { + break; + } + ND_TCHECK_LEN(tptr, subl); + + switch (subt) { + case ISIS_SUBTLV_ROUTER_CAP_SR: + { + uint8_t flags, sid_tlen, sid_type, sid_len; + uint32_t range; + const uint8_t *sid_ptr; + + flags = GET_U_1(tptr); + range = GET_BE_U_3(tptr+1); + ND_PRINT(", Flags [%s], Range %u", + bittok2str(isis_router_capability_sr_flags, "None", flags), + range); + sid_ptr = tptr + 4; + sid_tlen = subl - 4; + + while (sid_tlen >= 5) { + sid_type = GET_U_1(sid_ptr); + sid_len = GET_U_1(sid_ptr+1); + sid_tlen -= 2; + sid_ptr += 2; + + /* + * Boundary check. + */ + if (sid_len > sid_tlen) { + break; + } + + switch (sid_type) { + case 1: + if (sid_len == 3) { + ND_PRINT(", SID value %u", GET_BE_U_3(sid_ptr)); + } else if (sid_len == 4) { + ND_PRINT(", SID value %u", GET_BE_U_4(sid_ptr)); + } else { + ND_PRINT(", Unknown SID length%u", sid_len); + } + break; + default: + print_unknown_data(ndo, sid_ptr, "\n\t\t ", sid_len); + } + + sid_ptr += sid_len; + sid_tlen -= sid_len; + } + } + break; + default: + print_unknown_data(ndo, tptr, "\n\t\t", subl); + break; + } + + tlen -= subl; + tptr += subl; + } + trunc: + return; +} + /* * Clear checksum and lifetime prior to signature verification. */ @@ -2277,6 +2434,14 @@ isis_clear_checksum_lifetime(void *header) * Decode IS-IS packets. Return 0 on error. */ +#define INVALID_OR_DECREMENT(length,decr) \ + if ((length) < (decr)) { \ + ND_PRINT(" [packet length %u < %zu]", (length), (decr)); \ + nd_print_invalid(ndo); \ + return 1; \ + } \ + length -= (decr); + static int isis_print(netdissect_options *ndo, const uint8_t *p, u_int length) @@ -2295,14 +2460,14 @@ isis_print(netdissect_options *ndo, const struct isis_tlv_es_reach *tlv_es_reach; uint8_t version, pdu_version, fixed_len; - uint8_t pdu_type, pdu_max_area, max_area, pdu_id_length, id_length, tlv_type, tlv_len, tlen, alen, lan_alen, prefix_len; + uint8_t pdu_type, pdu_max_area, max_area, pdu_id_length, id_length, tlv_type, tlv_len, tlen, alen, prefix_len; u_int ext_is_len, ext_ip_len; uint8_t mt_len; uint8_t isis_subtlv_idrp; const uint8_t *optr, *pptr, *tptr; u_int packet_len; u_short pdu_len, key_id; - u_int i,vendor_id; + u_int i,vendor_id, num_vals; uint8_t auth_type; uint8_t num_system_ids; int sigcheck; @@ -2435,8 +2600,8 @@ isis_print(netdissect_options *ndo, case ISIS_PDU_L1_LAN_IIH: case ISIS_PDU_L2_LAN_IIH: if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { - ND_PRINT(", bogus fixed header length %u should be %lu", - fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)); + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); return (0); } ND_TCHECK_SIZE(header_iih_lan); @@ -2474,14 +2639,14 @@ isis_print(netdissect_options *ndo, return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); break; case ISIS_PDU_PTP_IIH: if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { - ND_PRINT(", bogus fixed header length %u should be %lu", - fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)); + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); return (0); } ND_TCHECK_SIZE(header_iih_ptp); @@ -2513,16 +2678,15 @@ isis_print(netdissect_options *ndo, if (!print_unknown_data(ndo, pptr, "\n\t ", ISIS_IIH_PTP_HEADER_SIZE)) return (0); } - - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); break; case ISIS_PDU_L1_LSP: case ISIS_PDU_L2_LSP: if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { - ND_PRINT(", bogus fixed header length %u should be %lu", - fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_LSP_HEADER_SIZE); return (0); } ND_TCHECK_SIZE(header_lsp); @@ -2572,15 +2736,15 @@ isis_print(netdissect_options *ndo, return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); break; case ISIS_PDU_L1_CSNP: case ISIS_PDU_L2_CSNP: if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { - ND_PRINT(", bogus fixed header length %u should be %lu", - fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)); + ND_PRINT(", bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); return (0); } ND_TCHECK_SIZE(header_csnp); @@ -2610,15 +2774,15 @@ isis_print(netdissect_options *ndo, return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); break; case ISIS_PDU_L1_PSNP: case ISIS_PDU_L2_PSNP: if (fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { - ND_PRINT("- bogus fixed header length %u should be %lu", - fixed_len, (unsigned long)(ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)); + ND_PRINT("- bogus fixed header length %u should be %zu", + fixed_len, ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); return (0); } ND_TCHECK_SIZE(header_psnp); @@ -2644,7 +2808,7 @@ isis_print(netdissect_options *ndo, return (0); } - packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + INVALID_OR_DECREMENT(packet_len,ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); break; @@ -2696,15 +2860,15 @@ isis_print(netdissect_options *ndo, ND_TCHECK_LEN(tptr, alen); ND_PRINT("\n\t Area address (length: %u): %s", alen, - isonsap_string(ndo, tptr, alen)); + GET_ISONSAP_STRING(tptr, alen)); tptr += alen; tlen -= alen; } break; case ISIS_TLV_ISNEIGH: while (tlen != 0) { - if (tlen < MAC_ADDR_LEN) - goto tlv_trunc; + if (tlen < MAC_ADDR_LEN) + goto tlv_trunc; ND_TCHECK_LEN(tptr, MAC_ADDR_LEN); ND_PRINT("\n\t SNPA: %s", isis_print_id(ndo, tptr, MAC_ADDR_LEN)); tlen -= MAC_ADDR_LEN; @@ -2712,26 +2876,22 @@ isis_print(netdissect_options *ndo, } break; - case ISIS_TLV_ISNEIGH_VARLEN: - if (tlen < 1) - goto tlv_trunc; - ND_TCHECK_1(tptr); - lan_alen = GET_U_1(tptr); /* LAN address length */ - tptr++; - tlen--; - if (lan_alen == 0) { - ND_PRINT("\n\t LAN address length 0 bytes"); - nd_print_invalid(ndo); - break; - } - ND_PRINT("\n\t LAN address length %u bytes ", lan_alen); - while (tlen != 0) { - if (tlen < lan_alen) - goto tlv_trunc; - ND_TCHECK_LEN(tptr, lan_alen); - ND_PRINT("\n\t\tIS Neighbor: %s", isis_print_id(ndo, tptr, lan_alen)); - tlen -= lan_alen; - tptr +=lan_alen; + case ISIS_TLV_INSTANCE_ID: + if (tlen < 4) + goto tlv_trunc; + num_vals = (tlen-2)/2; + ND_PRINT("\n\t Instance ID: %u, ITIDs(%u)%s ", + GET_BE_U_2(tptr), num_vals, + num_vals ? ":" : ""); + tptr += 2; + tlen -= 2; + for (i=0; i < num_vals; i++) { + ND_PRINT("%u", GET_BE_U_2(tptr)); + if (i < (num_vals - 1)) { + ND_PRINT(", "); + } + tptr += 2; + tlen -= 2; } break; @@ -2912,7 +3072,7 @@ isis_print(netdissect_options *ndo, ND_TCHECK_LEN(tptr, sizeof(nd_ipv6)); ND_PRINT("\n\t IPv6 interface address: %s", - ip6addr_string(ndo, tptr)); + GET_IP6ADDR_STRING(tptr)); tptr += sizeof(nd_ipv6); tlen -= sizeof(nd_ipv6); @@ -3056,7 +3216,7 @@ isis_print(netdissect_options *ndo, if (tlen < sizeof(nd_ipv4)) goto tlv_trunc; ND_TCHECK_LEN(pptr, sizeof(nd_ipv4)); - ND_PRINT("\n\t Traffic Engineering Router ID: %s", ipaddr_string(ndo, pptr)); + ND_PRINT("\n\t Traffic Engineering Router ID: %s", GET_IPADDR_STRING(pptr)); break; case ISIS_TLV_IPADDR: @@ -3064,7 +3224,7 @@ isis_print(netdissect_options *ndo, if (tlen < sizeof(nd_ipv4)) goto tlv_trunc; ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); - ND_PRINT("\n\t IPv4 interface address: %s", ipaddr_string(ndo, tptr)); + ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr)); tptr += sizeof(nd_ipv4); tlen -= sizeof(nd_ipv4); } @@ -3095,20 +3255,20 @@ isis_print(netdissect_options *ndo, if (tlen < sizeof(nd_ipv4)) break; ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); - ND_PRINT("\n\t IPv4 interface address: %s", ipaddr_string(ndo, tptr)); + ND_PRINT("\n\t IPv4 interface address: %s", GET_IPADDR_STRING(tptr)); tptr+=sizeof(nd_ipv4); tlen-=sizeof(nd_ipv4); if (tlen < sizeof(nd_ipv4)) break; ND_TCHECK_LEN(tptr, sizeof(nd_ipv4)); - ND_PRINT("\n\t IPv4 neighbor address: %s", ipaddr_string(ndo, tptr)); + ND_PRINT("\n\t IPv4 neighbor address: %s", GET_IPADDR_STRING(tptr)); tptr+=sizeof(nd_ipv4); tlen-=sizeof(nd_ipv4); while (tlen != 0) { - if (tlen < 4) - goto tlv_trunc; + if (tlen < 4) + goto tlv_trunc; ND_TCHECK_4(tptr); ND_PRINT("\n\t Link-ID: 0x%08x", GET_BE_U_4(tptr)); tptr+=4; @@ -3119,8 +3279,8 @@ isis_print(netdissect_options *ndo, case ISIS_TLV_LSP: tlv_lsp = (const struct isis_tlv_lsp *)tptr; while (tlen != 0) { - if (tlen < sizeof(struct isis_tlv_lsp)) - goto tlv_trunc; + if (tlen < sizeof(struct isis_tlv_lsp)) + goto tlv_trunc; ND_TCHECK_1(tlv_lsp->lsp_id + LSP_ID_LEN - 1); ND_PRINT("\n\t lsp-id: %s", isis_print_id(ndo, tlv_lsp->lsp_id, LSP_ID_LEN)); @@ -3294,7 +3454,7 @@ isis_print(netdissect_options *ndo, break; ND_TCHECK_LEN(tptr, prefix_len / 2); ND_PRINT("\n\t\tAddress: %s/%u", - isonsap_string(ndo, tptr, prefix_len / 2), prefix_len * 4); + GET_ISONSAP_STRING(tptr, prefix_len / 2), prefix_len * 4); tptr+=prefix_len/2; tlen-=prefix_len/2; } @@ -3307,6 +3467,23 @@ isis_print(netdissect_options *ndo, ND_PRINT("\n\t Sequence number: %u", GET_BE_U_4(tptr)); break; + case ISIS_TLV_ROUTER_CAPABILITY: + if (tlen < 5) { + ND_PRINT(" [object length %u < 5]", tlen); + nd_print_invalid(ndo); + break; + } + ND_TCHECK_5(tptr); /* router-id + flags */ + ND_PRINT("\n\t Router-ID %s", GET_IPADDR_STRING(tptr)); + ND_PRINT(", Flags [%s]", + bittok2str(isis_tlv_router_capability_flags, "none", GET_U_1(tptr+4))); + + /* Optional set of sub-TLV */ + if (tlen > 5) { + isis_print_router_cap_subtlv(ndo, tptr+5, tlen-5); + } + break; + case ISIS_TLV_VENDOR_PRIVATE: if (tlen < 3) break;