From 0de64cbbd3413038818586af733b115cddca6b83 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Tue, 31 Jan 2017 16:10:25 +0100 Subject: [PATCH] isisd: parse TE-IP reachability and IPv6 reachability subtlvs Signed-off-by: Christian Franke --- isisd/isis_tlv.c | 56 ++++++++++++++++++++++++++++++++++++++++++------ isisd/isis_tlv.h | 2 +- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c index 1d29d78287..b19a181a3f 100644 --- a/isisd/isis_tlv.c +++ b/isisd/isis_tlv.c @@ -614,12 +614,32 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected, if (!tlvs->te_ipv4_reachs) tlvs->te_ipv4_reachs = list_new (); listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach); - /* this trickery is permitable since no subtlvs are defined */ - value_len += 5 + ((te_ipv4_reach->control & 0x3F) ? - ((((te_ipv4_reach->control & 0x3F) - - 1) >> 3) + 1) : 0); - pnt += 5 + ((te_ipv4_reach->control & 0x3F) ? - ((((te_ipv4_reach->control & 0x3F) - 1) >> 3) + 1) : 0); + + /* Metric + Control-Byte + Prefix */ + unsigned int entry_len = 5 + PSIZE(te_ipv4_reach->control & 0x3F); + value_len += entry_len; + pnt += entry_len; + + if (te_ipv4_reach->control & TE_IPV4_HAS_SUBTLV) + { + if (length <= value_len) + { + zlog_warn("ISIS-TLV (%s): invalid IPv4 extended reachability SubTLV missing", + areatag); + retval = ISIS_WARNING; + break; + } + u_char subtlv_len = *pnt; + value_len += subtlv_len + 1; + pnt += subtlv_len + 1; + if (length < value_len) + { + zlog_warn("ISIS-TLV (%s): invalid IPv4 extended reachability SubTLVs have oversize", + areatag); + retval = ISIS_WARNING; + break; + } + } } } @@ -687,6 +707,27 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected, prefix_octets = ((ipv6_reach->prefix_len + 7) / 8); value_len += prefix_octets + 6; pnt += prefix_octets + 6; + + if (ipv6_reach->control_info & CTRL_INFO_SUBTLVS) + { + if (length <= value_len) + { + zlog_warn("ISIS-TLV (%s): invalid IPv6 extended reachability SubTLV missing", + areatag); + retval = ISIS_WARNING; + break; + } + u_char subtlv_len = *pnt; + value_len += subtlv_len + 1; + pnt += subtlv_len + 1; + if (length < value_len) + { + zlog_warn("ISIS-TLV (%s): invalid IPv6 extended reachability SubTLVs have oversize", + areatag); + retval = ISIS_WARNING; + break; + } + } /* FIXME: sub-tlvs */ if (!tlvs->ipv6_reachs) tlvs->ipv6_reachs = list_new (); @@ -758,6 +799,9 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected, pnt += length; break; } + /* Abort Parsing if error occured */ + if (retval != ISIS_OK) + return retval; } return retval; diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h index 5a39d564dc..27ded7a0e8 100644 --- a/isisd/isis_tlv.h +++ b/isisd/isis_tlv.h @@ -223,7 +223,7 @@ struct te_ipv4_reachability u_char prefix_start; /* since this is variable length by nature it only */ }; /* points to an approximate location */ - +#define TE_IPV4_HAS_SUBTLV (0x40) struct idrp_info { -- 2.39.5