diff options
| author | Christian Franke <chris@opensourcerouting.org> | 2017-01-31 16:10:25 +0100 | 
|---|---|---|
| committer | Christian Franke <chris@opensourcerouting.org> | 2017-01-31 16:13:23 +0100 | 
| commit | 0de64cbbd3413038818586af733b115cddca6b83 (patch) | |
| tree | 6b3e6d4f087113a4ae683caf662b1c168893aa6d /isisd | |
| parent | e08f1a05f248cf8cd25cde5f1af36bbdd6cbfb9b (diff) | |
isisd: parse TE-IP reachability and IPv6 reachability subtlvs
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Diffstat (limited to 'isisd')
| -rw-r--r-- | isisd/isis_tlv.c | 56 | ||||
| -rw-r--r-- | 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  {  | 
