Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/tcpdump/print-ldp.c
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
/* draft-ietf-pwe3-vccv-04.txt */ | /* draft-ietf-pwe3-vccv-04.txt */ | ||||
static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { | static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { | ||||
{ 0x01, "ICMP Ping" }, | { 0x01, "ICMP Ping" }, | ||||
{ 0x02, "LSP Ping" }, | { 0x02, "LSP Ping" }, | ||||
{ 0x04, "BFD" }, | { 0x04, "BFD" }, | ||||
{ 0, NULL} | { 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 | * ldp tlv header | ||||
* | * | ||||
* 0 1 2 3 | * 0 1 2 3 | ||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
* |U|F| Type | Length | | * |U|F| Type | Length | | ||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
* | | | * | | | ||||
* | Value | | * | Value | | ||||
* ~ ~ | * ~ ~ | ||||
* | | | * | | | ||||
* | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
* | | | * | | | ||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
*/ | */ | ||||
#define TLV_TCHECK(minlen) \ | #define TLV_TCHECK(minlen) \ | ||||
ND_TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv; | ND_TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv; | ||||
static int | static int | ||||
ldp_tlv_print(netdissect_options *ndo, | ldp_tlv_print(netdissect_options *ndo, | ||||
register const u_char *tptr) { | register const u_char *tptr, | ||||
u_short msg_tlen) | |||||
{ | |||||
struct ldp_tlv_header { | struct ldp_tlv_header { | ||||
uint8_t type[2]; | uint8_t type[2]; | ||||
uint8_t length[2]; | uint8_t length[2]; | ||||
}; | }; | ||||
const struct ldp_tlv_header *ldp_tlv_header; | const struct ldp_tlv_header *ldp_tlv_header; | ||||
u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags; | u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags; | ||||
u_char fec_type; | u_char fec_type; | ||||
u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx; | u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx; | ||||
char buf[100]; | char buf[100]; | ||||
int i; | int i; | ||||
ldp_tlv_header = (const struct ldp_tlv_header *)tptr; | ldp_tlv_header = (const struct ldp_tlv_header *)tptr; | ||||
ND_TCHECK(*ldp_tlv_header); | |||||
tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); | 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_tlen=tlv_len; | ||||
tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); | tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); | ||||
/* FIXME vendor private / experimental check */ | /* FIXME vendor private / experimental check */ | ||||
ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", | ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", | ||||
tok2str(ldp_tlv_values, | tok2str(ldp_tlv_values, | ||||
"Unknown", | "Unknown", | ||||
tlv_type), | tlv_type), | ||||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | case LDP_FEC_MARTINI_VC: | ||||
/* Make sure we have the VC ID as well */ | /* Make sure we have the VC ID as well */ | ||||
TLV_TCHECK(11); | TLV_TCHECK(11); | ||||
ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", | ND_PRINT((ndo, ": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", | ||||
tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), | tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), | ||||
EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", | EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", | ||||
EXTRACT_32BITS(tptr+3), | EXTRACT_32BITS(tptr+3), | ||||
EXTRACT_32BITS(tptr+7), | EXTRACT_32BITS(tptr+7), | ||||
vc_info_len)); | vc_info_len)); | ||||
if (vc_info_len < 4) | if (vc_info_len < 4) { | ||||
goto trunc; /* minimum 4, for the VC ID */ | /* 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 */ | 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 */ | /* Skip past the fixed information and the VC ID */ | ||||
tptr+=11; | tptr+=11; | ||||
tlv_tlen-=11; | tlv_tlen-=11; | ||||
TLV_TCHECK(vc_info_len); | TLV_TCHECK(vc_info_len); | ||||
while (vc_info_len > 2) { | while (vc_info_len > 2) { | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | |||||
badtlv: | badtlv: | ||||
ND_PRINT((ndo, "\n\t\t TLV contents go past end of TLV")); | ND_PRINT((ndo, "\n\t\t TLV contents go past end of TLV")); | ||||
return(tlv_len+4); /* Type & Length fields not included */ | return(tlv_len+4); /* Type & Length fields not included */ | ||||
} | } | ||||
void | void | ||||
ldp_print(netdissect_options *ndo, | 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; | int processed; | ||||
while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { | 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) | if (processed == 0) | ||||
return; | return; | ||||
len -= processed; | len -= processed; | ||||
pptr += processed; | pptr += processed; | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
ldp_msg_print(netdissect_options *ndo, | ldp_pdu_print(netdissect_options *ndo, | ||||
register const u_char *pptr) { | register const u_char *pptr) | ||||
{ | |||||
const struct ldp_common_header *ldp_com_header; | const struct ldp_common_header *ldp_com_header; | ||||
const struct ldp_msg_header *ldp_msg_header; | const struct ldp_msg_header *ldp_msg_header; | ||||
const u_char *tptr,*msg_tptr; | const u_char *tptr,*msg_tptr; | ||||
u_short tlen; | u_short tlen; | ||||
u_short pdu_len,msg_len,msg_type,msg_tlen; | u_short pdu_len,msg_len,msg_type,msg_tlen; | ||||
int hexdump,processed; | int hexdump,processed; | ||||
tptr=pptr; | |||||
ldp_com_header = (const struct ldp_common_header *)pptr; | ldp_com_header = (const struct ldp_common_header *)pptr; | ||||
ND_TCHECK(*ldp_com_header); | ND_TCHECK(*ldp_com_header); | ||||
/* | /* | ||||
* Sanity checking of the header. | * Sanity checking of the header. | ||||
*/ | */ | ||||
if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { | if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { | ||||
ND_PRINT((ndo, "%sLDP version %u packet not supported", | ND_PRINT((ndo, "%sLDP version %u packet not supported", | ||||
(ndo->ndo_vflag < 1) ? "" : "\n\t", | (ndo->ndo_vflag < 1) ? "" : "\n\t", | ||||
EXTRACT_16BITS(&ldp_com_header->version))); | EXTRACT_16BITS(&ldp_com_header->version))); | ||||
return 0; | return 0; | ||||
} | } | ||||
/* print the LSR-ID, label-space & length */ | |||||
pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_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", | ND_PRINT((ndo, "%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", | ||||
(ndo->ndo_vflag < 1) ? "" : "\n\t", | (ndo->ndo_vflag < 1) ? "" : "\n\t", | ||||
ipaddr_string(ndo, &ldp_com_header->lsr_id), | ipaddr_string(ndo, &ldp_com_header->lsr_id), | ||||
EXTRACT_16BITS(&ldp_com_header->label_space), | EXTRACT_16BITS(&ldp_com_header->label_space), | ||||
pdu_len)); | pdu_len)); | ||||
/* bail out if non-verbose */ | /* bail out if non-verbose */ | ||||
if (ndo->ndo_vflag < 1) | if (ndo->ndo_vflag < 1) | ||||
return 0; | return 0; | ||||
/* ok they seem to want to know everything - lets fully decode it */ | /* ok they seem to want to know everything - lets fully decode it */ | ||||
tlen=pdu_len; | tptr = pptr + sizeof(const struct ldp_common_header); | ||||
tlen = pdu_len - (sizeof(const struct ldp_common_header)-4); /* Type & Length fields not included */ | |||||
tptr += sizeof(const struct ldp_common_header); | |||||
tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */ | |||||
while(tlen>0) { | while(tlen>0) { | ||||
/* did we capture enough for fully decoding the msg header ? */ | /* did we capture enough for fully decoding the msg header ? */ | ||||
ND_TCHECK2(*tptr, sizeof(struct ldp_msg_header)); | ND_TCHECK2(*tptr, sizeof(struct ldp_msg_header)); | ||||
ldp_msg_header = (const struct ldp_msg_header *)tptr; | ldp_msg_header = (const struct ldp_msg_header *)tptr; | ||||
msg_len=EXTRACT_16BITS(ldp_msg_header->length); | msg_len=EXTRACT_16BITS(ldp_msg_header->length); | ||||
msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); | 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 */ | /* 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]", | ND_PRINT((ndo, "\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", | ||||
tok2str(ldp_msg_values, | tok2str(ldp_msg_values, | ||||
"Unknown", | "Unknown", | ||||
msg_type), | msg_type), | ||||
msg_type, | msg_type, | ||||
msg_len, | msg_len, | ||||
EXTRACT_32BITS(&ldp_msg_header->id), | EXTRACT_32BITS(&ldp_msg_header->id), | ||||
LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore")); | 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_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 ? */ | /* did we capture enough for fully decoding the message ? */ | ||||
ND_TCHECK2(*tptr, msg_len); | ND_TCHECK2(*tptr, msg_len); | ||||
hexdump=FALSE; | hexdump=FALSE; | ||||
switch(msg_type) { | switch(msg_type) { | ||||
case LDP_MSG_NOTIF: | case LDP_MSG_NOTIF: | ||||
case LDP_MSG_HELLO: | case LDP_MSG_HELLO: | ||||
case LDP_MSG_INIT: | case LDP_MSG_INIT: | ||||
case LDP_MSG_KEEPALIVE: | case LDP_MSG_KEEPALIVE: | ||||
case LDP_MSG_ADDRESS: | case LDP_MSG_ADDRESS: | ||||
case LDP_MSG_LABEL_MAPPING: | case LDP_MSG_LABEL_MAPPING: | ||||
case LDP_MSG_ADDRESS_WITHDRAW: | case LDP_MSG_ADDRESS_WITHDRAW: | ||||
case LDP_MSG_LABEL_WITHDRAW: | case LDP_MSG_LABEL_WITHDRAW: | ||||
while(msg_tlen >= 4) { | while(msg_tlen >= 4) { | ||||
processed = ldp_tlv_print(ndo, msg_tptr); | processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen); | ||||
if (processed == 0) | if (processed == 0) | ||||
break; | break; | ||||
msg_tlen-=processed; | msg_tlen-=processed; | ||||
msg_tptr+=processed; | msg_tptr+=processed; | ||||
} | } | ||||
break; | break; | ||||
/* | /* | ||||
Show All 33 Lines |