summaryrefslogtreecommitdiffstats
path: root/contrib/tcpdump/print-ldp.c
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2012-10-05 20:19:28 +0000
committerdelphij <delphij@FreeBSD.org>2012-10-05 20:19:28 +0000
commitdca5e2df844aab1432db6569445dc152e22cb279 (patch)
tree9869d83ad1eec4a1fa6e21d5865136e11aa5f9c0 /contrib/tcpdump/print-ldp.c
parenta130b811b9a9a99ca8b02c74857b7fa5be4a6e2a (diff)
parent69fe8a0033b22318969c85b57837b48863946665 (diff)
downloadFreeBSD-src-dca5e2df844aab1432db6569445dc152e22cb279.zip
FreeBSD-src-dca5e2df844aab1432db6569445dc152e22cb279.tar.gz
MFV: tcpdump 4.3.0.
MFC after: 4 weeks
Diffstat (limited to 'contrib/tcpdump/print-ldp.c')
-rw-r--r--contrib/tcpdump/print-ldp.c87
1 files changed, 70 insertions, 17 deletions
diff --git a/contrib/tcpdump/print-ldp.c b/contrib/tcpdump/print-ldp.c
index 1243104..262c9bd 100644
--- a/contrib/tcpdump/print-ldp.c
+++ b/contrib/tcpdump/print-ldp.c
@@ -180,7 +180,7 @@ static const struct tok ldp_tlv_values[] = {
#define LDP_FEC_WILDCARD 0x01
#define LDP_FEC_PREFIX 0x02
#define LDP_FEC_HOSTADDRESS 0x03
-/* From draft-martini-l2circuit-trans-mpls-13.txt */
+/* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */
#define LDP_FEC_MARTINI_VC 0x80
static const struct tok ldp_fec_values[] = {
@@ -238,6 +238,9 @@ int ldp_tlv_print(register const u_char *);
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
+#define TLV_TCHECK(minlen) \
+ TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv;
+
int
ldp_tlv_print(register const u_char *tptr) {
@@ -273,6 +276,7 @@ ldp_tlv_print(register const u_char *tptr) {
switch(tlv_type) {
case LDP_TLV_COMMON_HELLO:
+ TLV_TCHECK(4);
printf("\n\t Hold Time: %us, Flags: [%s Hello%s]",
EXTRACT_16BITS(tptr),
(EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
@@ -280,18 +284,22 @@ ldp_tlv_print(register const u_char *tptr) {
break;
case LDP_TLV_IPV4_TRANSPORT_ADDR:
+ TLV_TCHECK(4);
printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr));
break;
#ifdef INET6
case LDP_TLV_IPV6_TRANSPORT_ADDR:
+ TLV_TCHECK(16);
printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr));
break;
#endif
case LDP_TLV_CONFIG_SEQ_NUMBER:
+ TLV_TCHECK(4);
printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr));
break;
case LDP_TLV_ADDRESS_LIST:
+ TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
af = EXTRACT_16BITS(tptr);
tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
@@ -300,6 +308,7 @@ ldp_tlv_print(register const u_char *tptr) {
switch (af) {
case AFNUM_INET:
while(tlv_tlen >= sizeof(struct in_addr)) {
+ TCHECK2(*tptr, sizeof(struct in_addr));
printf(" %s",ipaddr_string(tptr));
tlv_tlen-=sizeof(struct in_addr);
tptr+=sizeof(struct in_addr);
@@ -308,6 +317,7 @@ ldp_tlv_print(register const u_char *tptr) {
#ifdef INET6
case AFNUM_INET6:
while(tlv_tlen >= sizeof(struct in6_addr)) {
+ TCHECK2(*tptr, sizeof(struct in6_addr));
printf(" %s",ip6addr_string(tptr));
tlv_tlen-=sizeof(struct in6_addr);
tptr+=sizeof(struct in6_addr);
@@ -321,6 +331,7 @@ ldp_tlv_print(register const u_char *tptr) {
break;
case LDP_TLV_COMMON_SESSION:
+ TLV_TCHECK(8);
printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
(EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
@@ -329,50 +340,86 @@ ldp_tlv_print(register const u_char *tptr) {
break;
case LDP_TLV_FEC:
+ TLV_TCHECK(1);
fec_type = *tptr;
printf("\n\t %s FEC (0x%02x)",
tok2str(ldp_fec_values, "Unknown", fec_type),
fec_type);
tptr+=1;
+ tlv_tlen-=1;
switch(fec_type) {
case LDP_FEC_WILDCARD:
break;
case LDP_FEC_PREFIX:
+ TLV_TCHECK(2);
af = EXTRACT_16BITS(tptr);
- tptr+=2;
+ tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
+ tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
if (af == AFNUM_INET) {
- i=decode_prefix4(tptr,buf,sizeof(buf));
- printf(": IPv4 prefix %s",buf);
+ i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf));
+ if (i == -2)
+ goto trunc;
+ if (i == -3)
+ printf(": IPv4 prefix (goes past end of TLV)");
+ else if (i == -1)
+ printf(": IPv4 prefix (invalid length)");
+ else
+ printf(": IPv4 prefix %s",buf);
}
#ifdef INET6
else if (af == AFNUM_INET6) {
- i=decode_prefix6(tptr,buf,sizeof(buf));
- printf(": IPv6 prefix %s",buf);
+ i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf));
+ if (i == -2)
+ goto trunc;
+ if (i == -3)
+ printf(": IPv4 prefix (goes past end of TLV)");
+ else if (i == -1)
+ printf(": IPv6 prefix (invalid length)");
+ else
+ printf(": IPv6 prefix %s",buf);
}
#endif
+ else
+ printf(": Address family %u prefix", af);
break;
case LDP_FEC_HOSTADDRESS:
break;
case LDP_FEC_MARTINI_VC:
- if (!TTEST2(*tptr, 11))
- goto trunc;
+ /*
+ * According to RFC 4908, the VC info Length field can be zero,
+ * in which case not only are there no interface parameters,
+ * there's no VC ID.
+ */
+ TLV_TCHECK(7);
vc_info_len = *(tptr+2);
+ if (vc_info_len == 0) {
+ printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
+ tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
+ EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
+ EXTRACT_32BITS(tptr+3),
+ vc_info_len);
+ break;
+ }
+
+ /* Make sure we have the VC ID as well */
+ TLV_TCHECK(11);
printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
EXTRACT_32BITS(tptr+3),
EXTRACT_32BITS(tptr+7),
vc_info_len);
+ if (vc_info_len < 4)
+ goto trunc; /* minimum 4, for the VC ID */
+ vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */
- if (vc_info_len == 0) /* infinite loop protection */
- break;
-
+ /* Skip past the fixed information and the VC ID */
tptr+=11;
- if (!TTEST2(*tptr, vc_info_len))
- goto trunc;
+ tlv_tlen-=11;
+ TLV_TCHECK(vc_info_len);
while (vc_info_len > 2) {
vc_info_tlv_type = *tptr;
@@ -421,10 +468,12 @@ ldp_tlv_print(register const u_char *tptr) {
break;
case LDP_TLV_GENERIC_LABEL:
+ TLV_TCHECK(4);
printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff);
break;
case LDP_TLV_STATUS:
+ TLV_TCHECK(8);
ui = EXTRACT_32BITS(tptr);
tptr+=4;
printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]",
@@ -438,6 +487,7 @@ ldp_tlv_print(register const u_char *tptr) {
break;
case LDP_TLV_FT_SESSION:
+ TLV_TCHECK(8);
ft_flags = EXTRACT_16BITS(tptr);
printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
ft_flags&0x8000 ? "" : "No ",
@@ -456,6 +506,7 @@ ldp_tlv_print(register const u_char *tptr) {
break;
case LDP_TLV_MTU:
+ TLV_TCHECK(2);
printf("\n\t MTU: %u", EXTRACT_16BITS(tptr));
break;
@@ -486,6 +537,10 @@ ldp_tlv_print(register const u_char *tptr) {
trunc:
printf("\n\t\t packet exceeded snapshot");
return 0;
+
+badtlv:
+ printf("\n\t\t TLV contents go past end of TLV");
+ return(tlv_len+4); /* Type & Length fields not included */
}
void
@@ -546,8 +601,7 @@ ldp_msg_print(register const u_char *pptr) {
while(tlen>0) {
/* did we capture enough for fully decoding the msg header ? */
- if (!TTEST2(*tptr, sizeof(struct ldp_msg_header)))
- goto trunc;
+ TCHECK2(*tptr, sizeof(struct ldp_msg_header));
ldp_msg_header = (const struct ldp_msg_header *)tptr;
msg_len=EXTRACT_16BITS(ldp_msg_header->length);
@@ -570,8 +624,7 @@ ldp_msg_print(register const u_char *pptr) {
msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */
/* did we capture enough for fully decoding the message ? */
- if (!TTEST2(*tptr, msg_len))
- goto trunc;
+ TCHECK2(*tptr, msg_len);
hexdump=FALSE;
switch(msg_type) {
OpenPOWER on IntegriCloud