X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/17934c433e64063bfb3e1a1b7ca8e5cff95f8710..refs/pull/482/head:/print-ldp.c diff --git a/print-ldp.c b/print-ldp.c index d31bfa89..45a23fe0 100644 --- a/print-ldp.c +++ b/print-ldp.c @@ -14,14 +14,13 @@ * and Steinar Haug (sthaug@nethelp.no) */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include -#include "interface.h" +#include "netdissect.h" #include "extract.h" #include "addrtoname.h" @@ -44,10 +43,10 @@ */ struct ldp_common_header { - u_int8_t version[2]; - u_int8_t pdu_length[2]; - u_int8_t lsr_id[4]; - u_int8_t label_space[2]; + uint8_t version[2]; + uint8_t pdu_length[2]; + uint8_t lsr_id[4]; + uint8_t label_space[2]; }; #define LDP_VERSION 1 @@ -77,9 +76,9 @@ struct ldp_common_header { */ struct ldp_msg_header { - u_int8_t type[2]; - u_int8_t length[2]; - u_int8_t id[4]; + uint8_t type[2]; + uint8_t length[2]; + uint8_t id[4]; }; #define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff) @@ -209,7 +208,7 @@ static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { { 0, NULL} }; -static int ldp_msg_print(netdissect_options *, register const u_char *); +static int ldp_pdu_print(netdissect_options *, register const u_char *); /* * ldp tlv header @@ -233,11 +232,12 @@ static int ldp_msg_print(netdissect_options *, register const u_char *); static int ldp_tlv_print(netdissect_options *ndo, - register const u_char *tptr) { - + register const u_char *tptr, + u_short msg_tlen) +{ struct ldp_tlv_header { - u_int8_t type[2]; - u_int8_t length[2]; + uint8_t type[2]; + uint8_t length[2]; }; const struct ldp_tlv_header *ldp_tlv_header; @@ -248,7 +248,12 @@ ldp_tlv_print(netdissect_options *ndo, int i; ldp_tlv_header = (const struct ldp_tlv_header *)tptr; + ND_TCHECK(*ldp_tlv_header); tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); + if (tlv_len + 4 > msg_tlen) { + ND_PRINT((ndo, "\n\t\t TLV contents go past end of message")); + return 0; + } tlv_tlen=tlv_len; tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); @@ -276,14 +281,12 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_TLV_IPV4_TRANSPORT_ADDR: TLV_TCHECK(4); - ND_PRINT((ndo, "\n\t IPv4 Transport Address: %s", ipaddr_string(tptr))); + ND_PRINT((ndo, "\n\t IPv4 Transport Address: %s", ipaddr_string(ndo, tptr))); break; -#ifdef INET6 case LDP_TLV_IPV6_TRANSPORT_ADDR: TLV_TCHECK(16); - ND_PRINT((ndo, "\n\t IPv6 Transport Address: %s", ip6addr_string(tptr))); + ND_PRINT((ndo, "\n\t IPv6 Transport Address: %s", ip6addr_string(ndo, tptr))); break; -#endif case LDP_TLV_CONFIG_SEQ_NUMBER: TLV_TCHECK(4); ND_PRINT((ndo, "\n\t Sequence Number: %u", EXTRACT_32BITS(tptr))); @@ -300,21 +303,19 @@ ldp_tlv_print(netdissect_options *ndo, case AFNUM_INET: while(tlv_tlen >= sizeof(struct in_addr)) { ND_TCHECK2(*tptr, sizeof(struct in_addr)); - ND_PRINT((ndo, " %s", ipaddr_string(tptr))); + ND_PRINT((ndo, " %s", ipaddr_string(ndo, tptr))); tlv_tlen-=sizeof(struct in_addr); tptr+=sizeof(struct in_addr); } break; -#ifdef INET6 case AFNUM_INET6: while(tlv_tlen >= sizeof(struct in6_addr)) { ND_TCHECK2(*tptr, sizeof(struct in6_addr)); - ND_PRINT((ndo, " %s", ip6addr_string(tptr))); + ND_PRINT((ndo, " %s", ip6addr_string(ndo, tptr))); tlv_tlen-=sizeof(struct in6_addr); tptr+=sizeof(struct in6_addr); } break; -#endif default: /* unknown AF */ break; @@ -349,7 +350,7 @@ ldp_tlv_print(netdissect_options *ndo, tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; if (af == AFNUM_INET) { - i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf)); + i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; if (i == -3) @@ -359,9 +360,8 @@ ldp_tlv_print(netdissect_options *ndo, else ND_PRINT((ndo, ": IPv4 prefix %s", buf)); } -#ifdef INET6 else if (af == AFNUM_INET6) { - i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf)); + i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf)); if (i == -2) goto trunc; if (i == -3) @@ -371,7 +371,6 @@ ldp_tlv_print(netdissect_options *ndo, else ND_PRINT((ndo, ": IPv6 prefix %s", buf)); } -#endif else ND_PRINT((ndo, ": Address family %u prefix", af)); break; @@ -403,8 +402,11 @@ ldp_tlv_print(netdissect_options *ndo, EXTRACT_32BITS(tptr+3), EXTRACT_32BITS(tptr+7), vc_info_len)); - if (vc_info_len < 4) - goto trunc; /* minimum 4, for the VC ID */ + if (vc_info_len < 4) { + /* minimum 4, for the VC ID */ + ND_PRINT((ndo, " (invalid, < 4")); + return(tlv_len+4); /* Type & Length fields not included */ + } vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */ /* Skip past the fixed information and the VC ID */ @@ -433,7 +435,7 @@ ldp_tlv_print(netdissect_options *ndo, case LDP_FEC_MARTINI_IFPARM_DESC: ND_PRINT((ndo, ": ")); for (idx = 2; idx < vc_info_tlv_len; idx++) - safeputchar(*(tptr+idx)); + safeputchar(ndo, *(tptr + idx)); break; case LDP_FEC_MARTINI_IFPARM_VCCV: @@ -536,11 +538,11 @@ badtlv: void ldp_print(netdissect_options *ndo, - register const u_char *pptr, register u_int len) { - + register const u_char *pptr, register u_int len) +{ int processed; while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { - processed = ldp_msg_print(ndo, pptr); + processed = ldp_pdu_print(ndo, pptr); if (processed == 0) return; len -= processed; @@ -549,9 +551,9 @@ ldp_print(netdissect_options *ndo, } static int -ldp_msg_print(netdissect_options *ndo, - register const u_char *pptr) { - +ldp_pdu_print(netdissect_options *ndo, + register const u_char *pptr) +{ const struct ldp_common_header *ldp_com_header; const struct ldp_msg_header *ldp_msg_header; const u_char *tptr,*msg_tptr; @@ -559,7 +561,6 @@ ldp_msg_print(netdissect_options *ndo, u_short pdu_len,msg_len,msg_type,msg_tlen; int hexdump,processed; - tptr=pptr; ldp_com_header = (const struct ldp_common_header *)pptr; ND_TCHECK(*ldp_com_header); @@ -573,11 +574,20 @@ ldp_msg_print(netdissect_options *ndo, return 0; } - /* print the LSR-ID, label-space & length */ pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length); + if (pdu_len < sizeof(const struct ldp_common_header)-4) { + /* length too short */ + ND_PRINT((ndo, "%sLDP, pdu-length: %u (too short, < %u)", + (ndo->ndo_vflag < 1) ? "" : "\n\t", + pdu_len, + (u_int)(sizeof(const struct ldp_common_header)-4))); + return 0; + } + + /* print the LSR-ID, label-space & length */ ND_PRINT((ndo, "%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", (ndo->ndo_vflag < 1) ? "" : "\n\t", - ipaddr_string(&ldp_com_header->lsr_id), + ipaddr_string(ndo, &ldp_com_header->lsr_id), EXTRACT_16BITS(&ldp_com_header->label_space), pdu_len)); @@ -586,10 +596,8 @@ ldp_msg_print(netdissect_options *ndo, return 0; /* ok they seem to want to know everything - lets fully decode it */ - tlen=pdu_len; - - tptr += sizeof(const struct ldp_common_header); - tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */ + tptr = pptr + sizeof(const struct ldp_common_header); + tlen = pdu_len - (sizeof(const struct ldp_common_header)-4); /* Type & Length fields not included */ while(tlen>0) { /* did we capture enough for fully decoding the msg header ? */ @@ -599,6 +607,19 @@ ldp_msg_print(netdissect_options *ndo, msg_len=EXTRACT_16BITS(ldp_msg_header->length); msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); + if (msg_len < sizeof(struct ldp_msg_header)-4) { + /* length too short */ + /* FIXME vendor private / experimental check */ + ND_PRINT((ndo, "\n\t %s Message (0x%04x), length: %u (too short, < %u)", + tok2str(ldp_msg_values, + "Unknown", + msg_type), + msg_type, + msg_len, + (u_int)(sizeof(struct ldp_msg_header)-4))); + return 0; + } + /* FIXME vendor private / experimental check */ ND_PRINT((ndo, "\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", tok2str(ldp_msg_values, @@ -609,11 +630,8 @@ ldp_msg_print(netdissect_options *ndo, EXTRACT_32BITS(&ldp_msg_header->id), LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore")); - if (msg_len == 0) /* infinite loop protection */ - return 0; - msg_tptr=tptr+sizeof(struct ldp_msg_header); - msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */ + msg_tlen=msg_len-(sizeof(struct ldp_msg_header)-4); /* Type & Length fields not included */ /* did we capture enough for fully decoding the message ? */ ND_TCHECK2(*tptr, msg_len); @@ -630,7 +648,7 @@ ldp_msg_print(netdissect_options *ndo, case LDP_MSG_ADDRESS_WITHDRAW: case LDP_MSG_LABEL_WITHDRAW: while(msg_tlen >= 4) { - processed = ldp_tlv_print(ndo, msg_tptr); + processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen); if (processed == 0) break; msg_tlen-=processed;