|
version 1.1.1.1, 2012/02/21 17:26:11
|
version 1.1.1.4, 2016/11/02 10:09:10
|
|
Line 43
|
Line 43
|
| #include "isisd/isis_pdu.h" |
#include "isisd/isis_pdu.h" |
| #include "isisd/isis_lsp.h" |
#include "isisd/isis_lsp.h" |
| |
|
| extern struct isis *isis; |
|
| |
|
| /* |
|
| * Prototypes. |
|
| */ |
|
| int add_tlv (u_char, u_char, u_char *, struct stream *); |
|
| |
|
| void |
void |
| free_tlv (void *val) |
free_tlv (void *val) |
| { |
{ |
|
Line 75 free_tlvs (struct tlvs *tlvs)
|
Line 68 free_tlvs (struct tlvs *tlvs)
|
| list_delete (tlvs->es_neighs); |
list_delete (tlvs->es_neighs); |
| if (tlvs->lsp_entries) |
if (tlvs->lsp_entries) |
| list_delete (tlvs->lsp_entries); |
list_delete (tlvs->lsp_entries); |
| if (tlvs->lan_neighs) |
|
| list_delete (tlvs->lan_neighs); |
|
| if (tlvs->prefix_neighs) |
if (tlvs->prefix_neighs) |
| list_delete (tlvs->prefix_neighs); |
list_delete (tlvs->prefix_neighs); |
| |
if (tlvs->lan_neighs) |
| |
list_delete (tlvs->lan_neighs); |
| if (tlvs->ipv4_addrs) |
if (tlvs->ipv4_addrs) |
| list_delete (tlvs->ipv4_addrs); |
list_delete (tlvs->ipv4_addrs); |
| if (tlvs->ipv4_int_reachs) |
if (tlvs->ipv4_int_reachs) |
|
Line 93 free_tlvs (struct tlvs *tlvs)
|
Line 86 free_tlvs (struct tlvs *tlvs)
|
| if (tlvs->ipv6_reachs) |
if (tlvs->ipv6_reachs) |
| list_delete (tlvs->ipv6_reachs); |
list_delete (tlvs->ipv6_reachs); |
| #endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
| | |
| | memset (tlvs, 0, sizeof (struct tlvs)); |
| | |
| return; |
return; |
| } |
} |
| |
|
|
Line 103 free_tlvs (struct tlvs *tlvs)
|
Line 98 free_tlvs (struct tlvs *tlvs)
|
| */ |
*/ |
| int |
int |
| parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected, |
parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected, |
| u_int32_t * found, struct tlvs *tlvs) | u_int32_t * found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset) |
| { |
{ |
| u_char type, length; |
u_char type, length; |
| struct lan_neigh *lan_nei; |
struct lan_neigh *lan_nei; |
|
Line 120 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 115 parse_tlvs (char *areatag, u_char * stream, int size,
|
| struct ipv6_reachability *ipv6_reach; |
struct ipv6_reachability *ipv6_reach; |
| int prefix_octets; |
int prefix_octets; |
| #endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
| u_char virtual; |
|
| int value_len, retval = ISIS_OK; |
int value_len, retval = ISIS_OK; |
| u_char *pnt = stream; | u_char *start = stream, *pnt = stream, *endpnt; |
| |
|
| *found = 0; |
*found = 0; |
| memset (tlvs, 0, sizeof (struct tlvs)); |
memset (tlvs, 0, sizeof (struct tlvs)); |
|
Line 184 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 178 parse_tlvs (char *areatag, u_char * stream, int size,
|
| * | Virtual Flag | |
* | Virtual Flag | |
| * +-------+-------+-------+-------+-------+-------+-------+-------+ |
* +-------+-------+-------+-------+-------+-------+-------+-------+ |
| */ |
*/ |
| virtual = *pnt; /* FIXME: what is the use for this? */ | /* virtual = *pnt; FIXME: what is the use for this? */ |
| pnt++; |
pnt++; |
| value_len++; |
value_len++; |
| /* +-------+-------+-------+-------+-------+-------+-------+-------+ |
/* +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
Line 443 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 437 parse_tlvs (char *areatag, u_char * stream, int size,
|
| if (*expected & TLVFLAG_AUTH_INFO) |
if (*expected & TLVFLAG_AUTH_INFO) |
| { |
{ |
| tlvs->auth_info.type = *pnt; |
tlvs->auth_info.type = *pnt; |
| tlvs->auth_info.len = length-1; | if (length == 0) |
| | { |
| | zlog_warn ("ISIS-TLV (%s): TLV (type %d, length %d) " |
| | "incorrect.", areatag, type, length); |
| | return ISIS_WARNING; |
| | } |
| | --length; |
| | tlvs->auth_info.len = length; |
| pnt++; |
pnt++; |
| memcpy (tlvs->auth_info.passwd, pnt, length - 1); | memcpy (tlvs->auth_info.passwd, pnt, length); |
| pnt += length - 1; | /* Return the authentication tlv pos for later computation |
| | * of MD5 (RFC 5304, 2) |
| | */ |
| | if (auth_tlv_offset) |
| | *auth_tlv_offset += (pnt - start - 3); |
| | pnt += length; |
| } |
} |
| else |
else |
| { |
{ |
|
Line 577 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 583 parse_tlvs (char *areatag, u_char * stream, int size,
|
| zlog_debug ("ISIS-TLV (%s): IPv4 extended Reachability length %d", |
zlog_debug ("ISIS-TLV (%s): IPv4 extended Reachability length %d", |
| areatag, length); |
areatag, length); |
| #endif /* EXTREME_TLV_DEBUG */ |
#endif /* EXTREME_TLV_DEBUG */ |
| |
endpnt = pnt + length; |
| if (*expected & TLVFLAG_TE_IPV4_REACHABILITY) |
if (*expected & TLVFLAG_TE_IPV4_REACHABILITY) |
| { |
{ |
| while (length > value_len) |
while (length > value_len) |
| { |
{ |
| te_ipv4_reach = (struct te_ipv4_reachability *) pnt; |
te_ipv4_reach = (struct te_ipv4_reachability *) pnt; |
| |
if ((te_ipv4_reach->control & 0x3F) > IPV4_MAX_BITLEN) |
| |
{ |
| |
zlog_warn ("ISIS-TLV (%s): invalid IPv4 extended reach" |
| |
"ability prefix length %d", areatag, |
| |
te_ipv4_reach->control & 0x3F); |
| |
retval = ISIS_WARNING; |
| |
break; |
| |
} |
| if (!tlvs->te_ipv4_reachs) |
if (!tlvs->te_ipv4_reachs) |
| tlvs->te_ipv4_reachs = list_new (); |
tlvs->te_ipv4_reachs = list_new (); |
| listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach); |
listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach); |
|
Line 593 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 608 parse_tlvs (char *areatag, u_char * stream, int size,
|
| ((((te_ipv4_reach->control & 0x3F) - 1) >> 3) + 1) : 0); |
((((te_ipv4_reach->control & 0x3F) - 1) >> 3) + 1) : 0); |
| } |
} |
| } |
} |
| else | |
| { | pnt = endpnt; |
| pnt += length; | |
| } | |
| break; |
break; |
| |
|
| #ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
|
Line 641 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 654 parse_tlvs (char *areatag, u_char * stream, int size,
|
| * +---------------------------------------------------------------+ |
* +---------------------------------------------------------------+ |
| */ |
*/ |
| *found |= TLVFLAG_IPV6_REACHABILITY; |
*found |= TLVFLAG_IPV6_REACHABILITY; |
| |
endpnt = pnt + length; |
| |
|
| if (*expected & TLVFLAG_IPV6_REACHABILITY) |
if (*expected & TLVFLAG_IPV6_REACHABILITY) |
| { |
{ |
| while (length > value_len) |
while (length > value_len) |
| { |
{ |
| ipv6_reach = (struct ipv6_reachability *) pnt; |
ipv6_reach = (struct ipv6_reachability *) pnt; |
| |
if (ipv6_reach->prefix_len > IPV6_MAX_BITLEN) |
| |
{ |
| |
zlog_warn ("ISIS-TLV (%s): invalid IPv6 extended reach" |
| |
"ability prefix length %d", areatag, |
| |
ipv6_reach->prefix_len); |
| |
retval = ISIS_WARNING; |
| |
break; |
| |
} |
| |
|
| prefix_octets = ((ipv6_reach->prefix_len + 7) / 8); |
prefix_octets = ((ipv6_reach->prefix_len + 7) / 8); |
| value_len += prefix_octets + 6; |
value_len += prefix_octets + 6; |
| pnt += prefix_octets + 6; |
pnt += prefix_octets + 6; |
|
Line 655 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 679 parse_tlvs (char *areatag, u_char * stream, int size,
|
| listnode_add (tlvs->ipv6_reachs, ipv6_reach); |
listnode_add (tlvs->ipv6_reachs, ipv6_reach); |
| } |
} |
| } |
} |
| else | |
| { | pnt = endpnt; |
| pnt += length; | |
| } | |
| break; |
break; |
| #endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
| |
|
|
Line 689 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 711 parse_tlvs (char *areatag, u_char * stream, int size,
|
| Neighbor Extended Local Circuit ID (four octets, if Neighbor |
Neighbor Extended Local Circuit ID (four octets, if Neighbor |
| System ID is present) */ |
System ID is present) */ |
| pnt += length; |
pnt += length; |
| |
value_len += length; |
| } |
} |
| } |
} |
| else |
else |
|
Line 718 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 741 parse_tlvs (char *areatag, u_char * stream, int size,
|
| zlog_warn ("ISIS-TLV (%s): unsupported TLV type %d, length %d", |
zlog_warn ("ISIS-TLV (%s): unsupported TLV type %d, length %d", |
| areatag, type, length); |
areatag, type, length); |
| |
|
| retval = ISIS_WARNING; |
|
| pnt += length; |
pnt += length; |
| break; |
break; |
| } |
} |
|
Line 730 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 752 parse_tlvs (char *areatag, u_char * stream, int size,
|
| int |
int |
| add_tlv (u_char tag, u_char len, u_char * value, struct stream *stream) |
add_tlv (u_char tag, u_char len, u_char * value, struct stream *stream) |
| { |
{ |
| if ((stream_get_size (stream) - stream_get_endp (stream)) < |
| if (STREAM_SIZE (stream) - stream_get_endp (stream) < (unsigned) len + 2) | (((unsigned)len) + 2)) |
| { |
{ |
| zlog_warn ("No room for TLV of type %d", tag); | zlog_warn ("No room for TLV of type %d " |
| | "(total size %d available %d required %d)", |
| | tag, (int)stream_get_size (stream), |
| | (int)(stream_get_size (stream) - stream_get_endp (stream)), |
| | len+2); |
| return ISIS_WARNING; |
return ISIS_WARNING; |
| } |
} |
| |
|
|
Line 873 tlv_add_nlpid (struct nlpids *nlpids, struct stream *s
|
Line 899 tlv_add_nlpid (struct nlpids *nlpids, struct stream *s
|
| } |
} |
| |
|
| int |
int |
| tlv_add_authinfo (char auth_type, char auth_len, u_char *auth_value, | tlv_add_authinfo (u_char auth_type, u_char auth_len, u_char *auth_value, |
| struct stream *stream) |
struct stream *stream) |
| { |
{ |
| u_char value[255]; |
u_char value[255]; |
| u_char *pos = value; |
u_char *pos = value; |
| *pos++ = ISIS_PASSWD_TYPE_CLEARTXT; | *pos++ = auth_type; |
| memcpy (pos, auth_value, auth_len); |
memcpy (pos, auth_value, auth_len); |
| |
|
| return add_tlv (AUTH_INFO, auth_len + 1, value, stream); |
return add_tlv (AUTH_INFO, auth_len + 1, value, stream); |
|
Line 899 tlv_add_ip_addrs (struct list *ip_addrs, struct stream
|
Line 925 tlv_add_ip_addrs (struct list *ip_addrs, struct stream
|
| struct prefix_ipv4 *ipv4; |
struct prefix_ipv4 *ipv4; |
| u_char value[255]; |
u_char value[255]; |
| u_char *pos = value; |
u_char *pos = value; |
| int retval; |
|
| |
|
| for (ALL_LIST_ELEMENTS_RO (ip_addrs, node, ipv4)) |
for (ALL_LIST_ELEMENTS_RO (ip_addrs, node, ipv4)) |
| { |
{ |
| if (pos - value + IPV4_MAX_BYTELEN > 255) |
if (pos - value + IPV4_MAX_BYTELEN > 255) |
| { |
{ |
| retval = add_tlv (IPV4_ADDR, pos - value, value, stream); | /* RFC 1195 s4.2: only one tuple of 63 allowed. */ |
| if (retval != ISIS_OK) | zlog_warn ("tlv_add_ip_addrs(): cutting off at 63 IP addresses"); |
| return retval; | break; |
| pos = value; | |
| } |
} |
| *(u_int32_t *) pos = ipv4->prefix.s_addr; |
*(u_int32_t *) pos = ipv4->prefix.s_addr; |
| pos += IPV4_MAX_BYTELEN; |
pos += IPV4_MAX_BYTELEN; |
|
Line 969 tlv_add_lsp_entries (struct list *lsps, struct stream
|
Line 993 tlv_add_lsp_entries (struct list *lsps, struct stream
|
| return add_tlv (LSP_ENTRIES, pos - value, value, stream); |
return add_tlv (LSP_ENTRIES, pos - value, value, stream); |
| } |
} |
| |
|
| int | static int |
| tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct stream *stream) | tlv_add_ipv4_reachs (u_char tag, struct list *ipv4_reachs, struct stream *stream) |
| { |
{ |
| struct listnode *node; |
struct listnode *node; |
| struct ipv4_reachability *reach; |
struct ipv4_reachability *reach; |
|
Line 983 tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct
|
Line 1007 tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct
|
| if (pos - value + IPV4_REACH_LEN > 255) |
if (pos - value + IPV4_REACH_LEN > 255) |
| { |
{ |
| retval = |
retval = |
| add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream); | add_tlv (tag, pos - value, value, stream); |
| if (retval != ISIS_OK) |
if (retval != ISIS_OK) |
| return retval; |
return retval; |
| pos = value; |
pos = value; |
|
Line 1002 tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct
|
Line 1026 tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct
|
| pos += IPV4_MAX_BYTELEN; |
pos += IPV4_MAX_BYTELEN; |
| } |
} |
| |
|
| |
return add_tlv (tag, pos - value, value, stream); |
| |
} |
| |
|
| return add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream); | int |
| | tlv_add_ipv4_int_reachs (struct list *ipv4_reachs, struct stream *stream) |
| | { |
| | return tlv_add_ipv4_reachs(IPV4_INT_REACHABILITY, ipv4_reachs, stream); |
| } |
} |
| |
|
| int |
int |
| |
tlv_add_ipv4_ext_reachs (struct list *ipv4_reachs, struct stream *stream) |
| |
{ |
| |
return tlv_add_ipv4_reachs(IPV4_EXT_REACHABILITY, ipv4_reachs, stream); |
| |
} |
| |
|
| |
|
| |
int |
| tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream) |
tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, struct stream *stream) |
| { |
{ |
| struct listnode *node; |
struct listnode *node; |
|
Line 1023 tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, s
|
Line 1059 tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, s
|
| if (pos - value + (5 + prefix_size) > 255) |
if (pos - value + (5 + prefix_size) > 255) |
| { |
{ |
| retval = |
retval = |
| add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream); | add_tlv (TE_IPV4_REACHABILITY, pos - value, value, stream); |
| if (retval != ISIS_OK) |
if (retval != ISIS_OK) |
| return retval; |
return retval; |
| pos = value; |
pos = value; |
|
Line 1106 tlv_add_padding (struct stream *stream)
|
Line 1142 tlv_add_padding (struct stream *stream)
|
| /* |
/* |
| * How many times can we add full padding ? |
* How many times can we add full padding ? |
| */ |
*/ |
| fullpads = (STREAM_SIZE (stream) - stream_get_endp (stream)) / 257; | fullpads = (stream_get_size (stream) - stream_get_endp (stream)) / 257; |
| for (i = 0; i < fullpads; i++) |
for (i = 0; i < fullpads; i++) |
| { |
{ |
| if (!stream_putc (stream, (u_char) PADDING)) /* TAG */ |
if (!stream_putc (stream, (u_char) PADDING)) /* TAG */ |
|
Line 1116 tlv_add_padding (struct stream *stream)
|
Line 1152 tlv_add_padding (struct stream *stream)
|
| stream_put (stream, NULL, 255); /* zero padding */ |
stream_put (stream, NULL, 255); /* zero padding */ |
| } |
} |
| |
|
| left = STREAM_SIZE (stream) - stream_get_endp (stream); | left = stream_get_size (stream) - stream_get_endp (stream); |
| |
|
| if (left < 2) |
if (left < 2) |
| return ISIS_OK; |
return ISIS_OK; |