version 1.1.1.1, 2012/02/21 17:26:11
|
version 1.1.1.3, 2013/07/21 23:54:39
|
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 122 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 117 parse_tlvs (char *areatag, u_char * stream, int size,
|
#endif /* HAVE_IPV6 */ |
#endif /* HAVE_IPV6 */ |
u_char virtual; |
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 443 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 438 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 584 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 609 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 655 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 680 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 712 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 730 parse_tlvs (char *areatag, u_char * stream, int size,
|
Line 754 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 901 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 905 tlv_add_ip_addrs (struct list *ip_addrs, struct stream
|
Line 933 tlv_add_ip_addrs (struct list *ip_addrs, struct stream
|
{ |
{ |
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 1002 tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct
|
Line 1029 tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct
|
pos += IPV4_MAX_BYTELEN; |
pos += IPV4_MAX_BYTELEN; |
} |
} |
|
|
|
|
return add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream); |
return add_tlv (IPV4_INT_REACHABILITY, pos - value, value, stream); |
} |
} |
|
|
Line 1023 tlv_add_te_ipv4_reachs (struct list *te_ipv4_reachs, s
|
Line 1049 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 1132 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 1142 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; |