/*
* 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
*/
#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 */
#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
{ 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"},
{ 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 }
};
{ 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 */
#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */
#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */
#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */
+#define ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID 32 /* rfc8667 */
#define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */
{ ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
{ ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" },
{ ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" },
+ { ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID, "LAN Adjacency Segment Identifier" },
{ ISIS_SUBTLV_SPB_METRIC, "SPB Metric" },
{ 250, "Reserved for cisco specific extensions" },
{ 251, "Reserved for cisco specific extensions" },
#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" },
{ 0, NULL }
};
+static const struct tok isis_lan_adj_sid_flag_values[] = {
+ { 0x80, "Address family IPv6" },
+ { 0x40, "Backup" },
+ { 0x20, "Value" },
+ { 0x10, "Local significance" },
+ { 0x08, "Set of adjacencies" },
+ { 0x04, "Persistent" },
+ { 0, NULL }
+};
+
#define ISIS_SUBTLV_AUTH_SIMPLE 1
#define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */
#define ISIS_SUBTLV_AUTH_MD5 54
isoclns_print(netdissect_options *ndo, const u_char *p, u_int length)
{
ndo->ndo_protocol = "isoclns";
- ND_TCHECK_1(p); /* enough bytes on the wire ? */
if (ndo->ndo_eflag)
ND_PRINT("OSI NLPID %s (0x%02x): ",
print_unknown_data(ndo, p, "\n\t", length);
break;
}
- return;
-trunc:
- nd_print_trunc(ndo);
}
#define CLNP_PDU_ER 1
ND_PRINT("li < size of fixed part of CLNP header and addresses");
return (0);
}
- ND_TCHECK_1(pptr);
dest_address_length = GET_U_1(pptr);
pptr += 1;
li_remaining -= 1;
ND_PRINT("li < size of fixed part of CLNP header and addresses");
return (0);
}
- ND_TCHECK_1(pptr);
source_address_length = GET_U_1(pptr);
pptr += 1;
li_remaining -= 1;
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);
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)) {
ND_PRINT(", bad opts/li");
return (0);
}
- ND_TCHECK_2(pptr);
op = GET_U_1(pptr);
opli = GET_U_1(pptr + 1);
pptr += 2;
}
if (source_address_length > 0) {
source_address=(tptr+1);
- ND_TCHECK_LEN(source_address,
- 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;
}
case CLNP_PDU_ER: /* fall through */
case CLNP_PDU_ERP:
- ND_TCHECK_1(pptr);
if (GET_U_1(pptr) == NLPID_CLNP) {
ND_PRINT("\n\t-----original packet-----\n\t");
/* FIXME recursion protection */
default:
/* dump the PDU specific data */
- if (length-(pptr-optr) > 0) {
+ if (length > ND_BYTES_BETWEEN(pptr, optr)) {
ND_PRINT("\n\t undecoded non-header data, length %u", length-li);
- print_unknown_data(ndo, pptr, "\n\t ", length - (int)(pptr - optr));
+ print_unknown_data(ndo, pptr, "\n\t ", length - ND_BYTES_BETWEEN(pptr, optr));
}
}
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) {
pptr += netal;
li -= netal;
- if (snpal == 6)
+ if (snpal == MAC_ADDR_LEN)
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;
}
}
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--;
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;
default:
if (ndo->ndo_vflag <= 1) {
- if (pptr < ndo->ndo_snapend)
- print_unknown_data(ndo, pptr, "\n\t ", (int)(ndo->ndo_snapend - pptr));
+ /*
+ * If there's at least one byte to print, print
+ * it/them.
+ */
+ if (ND_TTEST_LEN(pptr, 1))
+ print_unknown_data(ndo, pptr, "\n\t ", ND_BYTES_AVAILABLE_AFTER(pptr));
}
return;
}
ND_PRINT(", bad opts/li");
return;
}
- ND_TCHECK_2(pptr);
op = GET_U_1(pptr);
opli = GET_U_1(pptr + 1);
pptr += 2;
case ESIS_OPTION_PROTOCOLS:
while (opli>0) {
- ND_TCHECK_1(tptr);
ND_PRINT("%s (0x%02x)",
tok2str(nlpid_values,
"unknown",
while (len > 2)
{
- ND_TCHECK_2(tptr);
stlv_type = GET_U_1(tptr);
stlv_len = GET_U_1(tptr + 1);
while (len > 2)
{
- ND_TCHECK_2(tptr);
stlv_type = GET_U_1(tptr);
stlv_len = GET_U_1(tptr + 1);
tptr += 2;
stlv_len -= 8;
while (stlv_len >= 4) {
- ND_TCHECK_4(tptr);
ND_PRINT("\n\t T: %u, R: %u, RES: %u, ISID: %u",
(GET_BE_U_4(tptr) >> 31),
(GET_BE_U_4(tptr) >> 30) & 0x01,
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",
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) {
+ if (subl < 5)
+ goto trunc;
+ sid = GET_BE_U_3(tptr+2);
+ tptr+=5;
+ subl-=5;
+ } else {
+ if (subl < 6)
+ goto trunc;
+ 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);
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:
}
}
break;
+ case ISIS_SUBTLV_EXT_IS_REACH_LAN_ADJ_SEGMENT_ID:
+ if (subtlv_len >= 8) {
+ ND_PRINT("%s Flags: [%s]", ident,
+ bittok2str(isis_lan_adj_sid_flag_values,
+ "none",
+ GET_U_1(tptr)));
+ int vflag = (GET_U_1(tptr) & 0x20) ? 1:0;
+ int lflag = (GET_U_1(tptr) & 0x10) ? 1:0;
+ tptr++;
+ subtlv_len--;
+ subtlv_sum_len--;
+ proc_bytes++;
+ ND_PRINT("%s Weight: %u", ident, GET_U_1(tptr));
+ tptr++;
+ subtlv_len--;
+ subtlv_sum_len--;
+ proc_bytes++;
+ if(subtlv_len>=SYSTEM_ID_LEN) {
+ ND_TCHECK_LEN(tptr, SYSTEM_ID_LEN);
+ ND_PRINT("%s Neighbor System-ID: %s", ident,
+ isis_print_id(ndo, tptr, SYSTEM_ID_LEN));
+ }
+ /* RFC 8667 section 2.2.2 */
+ /* if V-flag is set to 1 and L-flag is set to 1 ==> 3 octet label */
+ /* if V-flag is set to 0 and L-flag is set to 0 ==> 4 octet index */
+ if (vflag && lflag) {
+ ND_PRINT("%s Label: %u",
+ ident, GET_BE_U_3(tptr+SYSTEM_ID_LEN));
+ } else if ((!vflag) && (!lflag)) {
+ ND_PRINT("%s Index: %u",
+ ident, GET_BE_U_4(tptr+SYSTEM_ID_LEN));
+ } else
+ nd_print_invalid(ndo);
+ }
+ break;
default:
if (!print_unknown_data(ndo, tptr, "\n\t\t ", subtlv_len))
return(0);
{
if (tlv_remaining < 2)
goto trunc;
- ND_TCHECK_2(tptr);
ND_PRINT("%s%s",
ident,
uint8_t prefix[sizeof(nd_ipv6)]; /* shared copy buffer for IPv4 and IPv6 prefixes */
u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen;
- ND_TCHECK_4(tptr);
metric = GET_BE_U_4(tptr);
processed=4;
tptr+=4;
if (afi == AF_INET) {
- ND_TCHECK_1(tptr);
status_byte=GET_U_1(tptr);
tptr++;
bit_length = status_byte&0x3f;
}
processed++;
} else if (afi == AF_INET6) {
- ND_TCHECK_2(tptr);
status_byte=GET_U_1(tptr);
bit_length=GET_U_1(tptr + 1);
if (bit_length > 128) {
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",
than one subTLV - therefore the first byte must reflect
the aggregate bytecount of the subTLVs for this prefix
*/
- ND_TCHECK_1(tptr);
sublen=GET_U_1(tptr);
tptr++;
processed+=sublen+1;
ND_PRINT(" (%u)", sublen); /* print out subTLV length */
while (sublen>0) {
- ND_TCHECK_2(tptr);
subtlvtype=GET_U_1(tptr);
subtlvlen=GET_U_1(tptr + 1);
tptr+=2;
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) {
+ 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.
*/
* 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)
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;
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;
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;
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;
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;
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;
switch (tlv_type) {
case ISIS_TLV_AREA_ADDR:
while (tlen != 0) {
- ND_TCHECK_1(tptr);
alen = GET_U_1(tptr);
tptr++;
tlen--;
if (tlen < alen)
goto tlv_trunc;
- 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;
}
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;
case ISIS_TLV_IS_REACH:
if (tlen < 1)
goto tlv_trunc;
- ND_TCHECK_1(tptr); /* check if there is one byte left to read out the virtual flag */
ND_PRINT("\n\t %s",
tok2str(isis_is_reach_virtual_values,
"bogus virtual flag 0x%02x",
while (tlen != 0) {
if (tlen < sizeof(nd_ipv6))
goto tlv_trunc;
- 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);
case ISIS_TLV_AUTH:
if (tlen < 1)
goto tlv_trunc;
- ND_TCHECK_1(tptr);
auth_type = GET_U_1(tptr);
tptr++;
tlen--;
break;
case ISIS_SUBTLV_AUTH_MD5:
for(i=0;i<tlen;i++) {
- ND_TCHECK_1(tptr + i);
ND_PRINT("%02x", GET_U_1(tptr + i));
}
if (tlen != ISIS_SUBTLV_AUTH_MD5_LEN)
case ISIS_SUBTLV_AUTH_GENERIC:
if (tlen < 2)
goto tlv_trunc;
- ND_TCHECK_2(tptr);
key_id = GET_BE_U_2(tptr);
ND_PRINT("%u, password: ", key_id);
tptr += 2;
tlen -= 2;
for(i=0;i<tlen;i++) {
- ND_TCHECK_1(tptr + i);
ND_PRINT("%02x", GET_U_1(tptr + i));
}
break;
case ISIS_TLV_PTP_ADJ:
tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
if(tlen>=1) {
- ND_TCHECK_1(tptr);
ND_PRINT("\n\t Adjacency State: %s (%u)",
tok2str(isis_ptp_adjancey_values, "unknown", GET_U_1(tptr)),
GET_U_1(tptr));
tlen--;
}
if(tlen>sizeof(tlv_ptp_adj->extd_local_circuit_id)) {
- ND_TCHECK_4(tlv_ptp_adj->extd_local_circuit_id);
ND_PRINT("\n\t Extended Local circuit-ID: 0x%08x",
GET_BE_U_4(tlv_ptp_adj->extd_local_circuit_id));
tlen-=sizeof(tlv_ptp_adj->extd_local_circuit_id);
tlen-=SYSTEM_ID_LEN;
}
if(tlen>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) {
- ND_TCHECK_4(tlv_ptp_adj->neighbor_extd_local_circuit_id);
ND_PRINT("\n\t Neighbor Extended Local circuit-ID: 0x%08x",
GET_BE_U_4(tlv_ptp_adj->neighbor_extd_local_circuit_id));
}
case ISIS_TLV_PROTOCOLS:
ND_PRINT("\n\t NLPID(s): ");
while (tlen != 0) {
- ND_TCHECK_1(tptr);
ND_PRINT("%s (0x%02x)",
tok2str(nlpid_values,
"unknown",
{
if (tlen < 2)
goto tlv_trunc;
- ND_TCHECK_2(tptr);
ND_PRINT("\n\t RES: %u, MTID(s): %u",
(GET_BE_U_2(tptr) >> 12),
case ISIS_TLV_MT_CAPABILITY:
if (tlen < 2)
goto tlv_trunc;
- ND_TCHECK_2(tptr);
ND_PRINT("\n\t O: %u, RES: %u, MTID(s): %u",
(GET_BE_U_2(tptr) >> 15) & 0x01,
case ISIS_TLV_TE_ROUTER_ID:
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:
while (tlen != 0) {
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);
}
if (tlen < 1)
break;
- ND_TCHECK_1(tptr);
ND_PRINT(", Flags: [%s]",
ISIS_MASK_TLV_SHARED_RISK_GROUP(GET_U_1(tptr)) ? "numbered" : "unnumbered");
tptr++;
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;
- ND_TCHECK_4(tptr);
+ if (tlen < 4)
+ goto tlv_trunc;
ND_PRINT("\n\t Link-ID: 0x%08x", GET_BE_U_4(tptr));
tptr+=4;
tlen-=4;
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));
- ND_TCHECK_4(tlv_lsp->sequence_number);
ND_PRINT(", seq: 0x%08x",
GET_BE_U_4(tlv_lsp->sequence_number));
- ND_TCHECK_2(tlv_lsp->remaining_lifetime);
ND_PRINT(", lifetime: %5ds",
GET_BE_U_2(tlv_lsp->remaining_lifetime));
- ND_TCHECK_2(tlv_lsp->checksum);
ND_PRINT(", chksum: 0x%04x", GET_BE_U_2(tlv_lsp->checksum));
tlen-=sizeof(struct isis_tlv_lsp);
tlv_lsp++;
case ISIS_TLV_POI:
if (tlen < 1)
goto tlv_trunc;
- ND_TCHECK_1(tptr);
num_system_ids = GET_U_1(tptr);
tptr++;
tlen--;
case ISIS_TLV_IDRP_INFO:
if (tlen < 1)
break;
- ND_TCHECK_1(tptr);
isis_subtlv_idrp = GET_U_1(tptr);
ND_PRINT("\n\t Inter-Domain Information Type: %s",
tok2str(isis_subtlv_idrp_values,
case ISIS_SUBTLV_IDRP_ASN:
if (tlen < 2)
goto tlv_trunc;
- ND_TCHECK_2(tptr); /* fetch AS number */
ND_PRINT("AS Number: %u", GET_BE_U_2(tptr));
break;
case ISIS_SUBTLV_IDRP_LOCAL:
case ISIS_TLV_LSP_BUFFERSIZE:
if (tlen < 2)
break;
- ND_TCHECK_2(tptr);
ND_PRINT("\n\t LSP Buffersize: %u", GET_BE_U_2(tptr));
break;
tlen-=sizeof(struct isis_metric_block);
while (tlen != 0) {
- ND_TCHECK_1(tptr);
prefix_len=GET_U_1(tptr); /* read out prefix length in semioctets*/
tptr++;
tlen--;
}
if (tlen < prefix_len/2)
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;
}
case ISIS_TLV_IIH_SEQNR:
if (tlen < 4)
break;
- ND_TCHECK_4(tptr); /* check if four bytes are on the wire */
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_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;
- ND_TCHECK_3(tptr); /* check if enough byte for a full oui */
vendor_id = GET_BE_U_3(tptr);
ND_PRINT("\n\t Vendor: %s (%u)",
tok2str(oui_values, "Unknown", vendor_id),