1/* 2 * Redistribution and use in source and binary forms, with or without 3 * modification, are permitted provided that: (1) source code 4 * distributions retain the above copyright notice and this paragraph 5 * in its entirety, and (2) distributions including binary code include 6 * the above copyright notice and this paragraph in its entirety in 7 * the documentation or other materials provided with the distribution. 8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 11 * FOR A PARTICULAR PURPOSE. 12 * 13 * Original code by Hannes Gredler (hannes@juniper.net) 14 * and Steinar Haug (sthaug@nethelp.no) 15 */ 16 17#ifndef lint 18static const char rcsid[] _U_ = 19 "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.8.2.9 2006/06/23 02:07:27 hannes Exp $"; 20#endif 21 22#ifdef HAVE_CONFIG_H 23#include "config.h" 24#endif 25 26#include <tcpdump-stdinc.h> 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31 32#include "interface.h" 33#include "decode_prefix.h" 34#include "extract.h" 35#include "addrtoname.h" 36 37#include "l2vpn.h" 38 39/* 40 * ldp common header 41 * 42 * 0 1 2 3 43 * 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 44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 45 * | Version | PDU Length | 46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 47 * | LDP Identifier | 48 * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 49 * | | 50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 51 * 52 */ 53 54struct ldp_common_header { 55 u_int8_t version[2]; 56 u_int8_t pdu_length[2]; 57 u_int8_t lsr_id[4]; 58 u_int8_t label_space[2]; 59}; 60 61#define LDP_VERSION 1 62 63/* 64 * ldp message header 65 * 66 * 0 1 2 3 67 * 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 68 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 69 * |U| Message Type | Message Length | 70 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 71 * | Message ID | 72 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 73 * | | 74 * + + 75 * | Mandatory Parameters | 76 * + + 77 * | | 78 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 79 * | | 80 * + + 81 * | Optional Parameters | 82 * + + 83 * | | 84 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 85 */ 86 87struct ldp_msg_header { 88 u_int8_t type[2]; 89 u_int8_t length[2]; 90 u_int8_t id[4]; 91}; 92 93#define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff) 94#define LDP_MASK_U_BIT(x) ((x)&0x8000) 95 96#define LDP_MSG_NOTIF 0x0001 97#define LDP_MSG_HELLO 0x0100 98#define LDP_MSG_INIT 0x0200 99#define LDP_MSG_KEEPALIVE 0x0201 100#define LDP_MSG_ADDRESS 0x0300 101#define LDP_MSG_ADDRESS_WITHDRAW 0x0301 102#define LDP_MSG_LABEL_MAPPING 0x0400 103#define LDP_MSG_LABEL_REQUEST 0x0401 104#define LDP_MSG_LABEL_WITHDRAW 0x0402 105#define LDP_MSG_LABEL_RELEASE 0x0403 106#define LDP_MSG_LABEL_ABORT_REQUEST 0x0404 107 108#define LDP_VENDOR_PRIVATE_MIN 0x3e00 109#define LDP_VENDOR_PRIVATE_MAX 0x3eff 110#define LDP_EXPERIMENTAL_MIN 0x3f00 111#define LDP_EXPERIMENTAL_MAX 0x3fff 112 113static const struct tok ldp_msg_values[] = { 114 { LDP_MSG_NOTIF, "Notification" }, 115 { LDP_MSG_HELLO, "Hello" }, 116 { LDP_MSG_INIT, "Initialization" }, 117 { LDP_MSG_KEEPALIVE, "Keepalive" }, 118 { LDP_MSG_ADDRESS, "Address" }, 119 { LDP_MSG_ADDRESS_WITHDRAW, "Address Withdraw" }, 120 { LDP_MSG_LABEL_MAPPING, "Label Mapping" }, 121 { LDP_MSG_LABEL_REQUEST, "Label Request" }, 122 { LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" }, 123 { LDP_MSG_LABEL_RELEASE, "Label Release" }, 124 { LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" }, 125 { 0, NULL} 126}; 127 128#define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff) 129#define LDP_MASK_F_BIT(x) ((x)&0x4000) 130 131#define LDP_TLV_FEC 0x0100 132#define LDP_TLV_ADDRESS_LIST 0x0101 133#define LDP_TLV_HOP_COUNT 0x0103 134#define LDP_TLV_PATH_VECTOR 0x0104 135#define LDP_TLV_GENERIC_LABEL 0x0200 136#define LDP_TLV_ATM_LABEL 0x0201 137#define LDP_TLV_FR_LABEL 0x0202 138#define LDP_TLV_STATUS 0x0300 139#define LDP_TLV_EXTD_STATUS 0x0301 140#define LDP_TLV_RETURNED_PDU 0x0302 141#define LDP_TLV_RETURNED_MSG 0x0303 142#define LDP_TLV_COMMON_HELLO 0x0400 143#define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401 144#define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402 145#define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403 146#define LDP_TLV_COMMON_SESSION 0x0500 147#define LDP_TLV_ATM_SESSION_PARM 0x0501 148#define LDP_TLV_FR_SESSION_PARM 0x0502 149#define LDP_TLV_FT_SESSION 0x0503 150#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600 151 152static const struct tok ldp_tlv_values[] = { 153 { LDP_TLV_FEC, "FEC" }, 154 { LDP_TLV_ADDRESS_LIST, "Address List" }, 155 { LDP_TLV_HOP_COUNT, "Hop Count" }, 156 { LDP_TLV_PATH_VECTOR, "Path Vector" }, 157 { LDP_TLV_GENERIC_LABEL, "Generic Label" }, 158 { LDP_TLV_ATM_LABEL, "ATM Label" }, 159 { LDP_TLV_FR_LABEL, "Frame-Relay Label" }, 160 { LDP_TLV_STATUS, "Status" }, 161 { LDP_TLV_EXTD_STATUS, "Extended Status" }, 162 { LDP_TLV_RETURNED_PDU, "Returned PDU" }, 163 { LDP_TLV_RETURNED_MSG, "Returned Message" }, 164 { LDP_TLV_COMMON_HELLO, "Common Hello Parameters" }, 165 { LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" }, 166 { LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" }, 167 { LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" }, 168 { LDP_TLV_COMMON_SESSION, "Common Session Parameters" }, 169 { LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" }, 170 { LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" }, 171 { LDP_TLV_FT_SESSION, "Fault-Tolerant Session Parameters" }, 172 { LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" }, 173 { 0, NULL} 174}; 175 176#define LDP_FEC_WILDCARD 0x01 177#define LDP_FEC_PREFIX 0x02 178#define LDP_FEC_HOSTADDRESS 0x03 179/* From draft-martini-l2circuit-trans-mpls-13.txt */ 180#define LDP_FEC_MARTINI_VC 0x80 181 182static const struct tok ldp_fec_values[] = { 183 { LDP_FEC_WILDCARD, "Wildcard" }, 184 { LDP_FEC_PREFIX, "Prefix" }, 185 { LDP_FEC_HOSTADDRESS, "Host address" }, 186 { LDP_FEC_MARTINI_VC, "Martini VC" }, 187 { 0, NULL} 188}; 189 190#define LDP_FEC_MARTINI_IFPARM_MTU 0x01 191#define LDP_FEC_MARTINI_IFPARM_DESC 0x03 192#define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c 193 194static const struct tok ldp_fec_martini_ifparm_values[] = { 195 { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" }, 196 { LDP_FEC_MARTINI_IFPARM_DESC, "Description" }, 197 { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" }, 198 { 0, NULL} 199}; 200 201/* draft-ietf-pwe3-vccv-04.txt */ 202static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = { 203 { 0x01, "PWE3 control word" }, 204 { 0x02, "MPLS Router Alert Label" }, 205 { 0x04, "MPLS inner label TTL = 1" }, 206 { 0, NULL} 207}; 208 209/* draft-ietf-pwe3-vccv-04.txt */ 210static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { 211 { 0x01, "ICMP Ping" }, 212 { 0x02, "LSP Ping" }, 213 { 0x04, "BFD" }, 214 { 0, NULL} 215}; 216 217/* RFC1700 address family numbers, same definition in print-bgp.c */ 218/* FIXME: move all AF stuff into dedicated files */ 219#define AFNUM_INET 1 220#define AFNUM_INET6 2 221#define AFNUM_LEN 2 222 223int ldp_msg_print(register const u_char *); 224int ldp_tlv_print(register const u_char *); 225 226/* 227 * ldp tlv header 228 * 229 * 0 1 2 3 230 * 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 231 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 232 * |U|F| Type | Length | 233 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 234 * | | 235 * | Value | 236 * ~ ~ 237 * | | 238 * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 239 * | | 240 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 241 */ 242 243int 244ldp_tlv_print(register const u_char *tptr) { 245 246 struct ldp_tlv_header { 247 u_int8_t type[2]; 248 u_int8_t length[2]; 249 }; 250 251 const struct ldp_tlv_header *ldp_tlv_header; 252 u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags; 253 u_char fec_type; 254 u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx; 255 char buf[100]; 256 int i; 257 258 ldp_tlv_header = (const struct ldp_tlv_header *)tptr; 259 tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); 260 tlv_tlen=tlv_len; 261 tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); 262 263 /* FIXME vendor private / experimental check */ 264 printf("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", 265 tok2str(ldp_tlv_values, 266 "Unknown", 267 tlv_type), 268 tlv_type, 269 tlv_len, 270 LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore", 271 LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't"); 272 273 tptr+=sizeof(struct ldp_tlv_header); 274 275 switch(tlv_type) { 276 277 case LDP_TLV_COMMON_HELLO: 278 printf("\n\t Hold Time: %us, Flags: [%s Hello%s]", 279 EXTRACT_16BITS(tptr), 280 (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link", 281 (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : ""); 282 break; 283 284 case LDP_TLV_IPV4_TRANSPORT_ADDR: 285 printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr)); 286 break; 287#ifdef INET6 288 case LDP_TLV_IPV6_TRANSPORT_ADDR: 289 printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr)); 290 break; 291#endif 292 case LDP_TLV_CONFIG_SEQ_NUMBER: 293 printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr)); 294 break; 295 296 case LDP_TLV_ADDRESS_LIST: 297 af = EXTRACT_16BITS(tptr); 298 tptr+=AFNUM_LEN; 299 tlv_tlen -= AFNUM_LEN; 300 printf("\n\t Address Family: "); 301 if (af == AFNUM_INET) { 302 printf("IPv4, addresses:"); 303 while(tlv_tlen >= sizeof(struct in_addr)) { 304 printf(" %s",ipaddr_string(tptr)); 305 tlv_tlen-=sizeof(struct in_addr); 306 tptr+=sizeof(struct in_addr); 307 } 308 } 309#ifdef INET6 310 else if (af == AFNUM_INET6) { 311 printf("IPv6, addresses:"); 312 while(tlv_tlen >= sizeof(struct in6_addr)) { 313 printf(" %s",ip6addr_string(tptr)); 314 tlv_tlen-=sizeof(struct in6_addr); 315 tptr+=sizeof(struct in6_addr); 316 } 317 } 318#endif 319 break; 320 321 case LDP_TLV_COMMON_SESSION: 322 printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", 323 EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2), 324 (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited", 325 (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled" 326 ); 327 break; 328 329 case LDP_TLV_FEC: 330 fec_type = *tptr; 331 printf("\n\t %s FEC (0x%02x)", 332 tok2str(ldp_fec_values, "Unknown", fec_type), 333 fec_type); 334 335 tptr+=1; 336 switch(fec_type) { 337 338 case LDP_FEC_WILDCARD: 339 break; 340 case LDP_FEC_PREFIX: 341 af = EXTRACT_16BITS(tptr); 342 tptr+=2; 343 if (af == AFNUM_INET) { 344 i=decode_prefix4(tptr,buf,sizeof(buf)); 345 printf(": IPv4 prefix %s",buf); 346 } 347#ifdef INET6 348 else if (af == AFNUM_INET6) { 349 i=decode_prefix6(tptr,buf,sizeof(buf)); 350 printf(": IPv6 prefix %s",buf); 351 } 352#endif 353 break; 354 case LDP_FEC_HOSTADDRESS: 355 break; 356 case LDP_FEC_MARTINI_VC: 357 if (!TTEST2(*tptr, 11)) 358 goto trunc; 359 vc_info_len = *(tptr+2); 360 361 printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", 362 tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), 363 EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", 364 EXTRACT_32BITS(tptr+3), 365 EXTRACT_32BITS(tptr+7), 366 vc_info_len); 367 368 if (vc_info_len == 0) /* infinite loop protection */ 369 break; 370 371 tptr+=11; 372 if (!TTEST2(*tptr, vc_info_len)) 373 goto trunc; 374 375 while (vc_info_len > 2) { 376 vc_info_tlv_type = *tptr; 377 vc_info_tlv_len = *(tptr+1); 378 if (vc_info_tlv_len < 2) 379 break; 380 if (vc_info_len < vc_info_tlv_len) 381 break; 382 383 printf("\n\t\tInterface Parameter: %s (0x%02x), len %u", 384 tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type), 385 vc_info_tlv_type, 386 vc_info_tlv_len); 387 388 switch(vc_info_tlv_type) { 389 case LDP_FEC_MARTINI_IFPARM_MTU: 390 printf(": %u",EXTRACT_16BITS(tptr+2)); 391 break; 392 393 case LDP_FEC_MARTINI_IFPARM_DESC: 394 printf(": "); 395 for (idx = 2; idx < vc_info_tlv_len; idx++) 396 safeputchar(*(tptr+idx)); 397 break; 398 399 case LDP_FEC_MARTINI_IFPARM_VCCV: 400 printf("\n\t\t Control Channels (0x%02x) = [%s]", 401 *(tptr+2), 402 bittok2str(ldp_fec_martini_ifparm_vccv_cc_values,"none",*(tptr+2))); 403 printf("\n\t\t CV Types (0x%02x) = [%s]", 404 *(tptr+3), 405 bittok2str(ldp_fec_martini_ifparm_vccv_cv_values,"none",*(tptr+3))); 406 break; 407 408 default: 409 print_unknown_data(tptr+2,"\n\t\t ",vc_info_tlv_len-2); 410 break; 411 } 412 413 vc_info_len -= vc_info_tlv_len; 414 tptr += vc_info_tlv_len; 415 } 416 break; 417 } 418 419 break; 420 421 case LDP_TLV_GENERIC_LABEL: 422 printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff); 423 break; 424 425 case LDP_TLV_STATUS: 426 ui = EXTRACT_32BITS(tptr); 427 tptr+=4; 428 printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]", 429 ui&0x3fffffff, 430 ui&0x80000000 ? "Fatal error" : "Advisory Notification", 431 ui&0x40000000 ? "do" : "don't"); 432 ui = EXTRACT_32BITS(tptr); 433 tptr+=4; 434 if (ui) 435 printf(", causing Message ID: 0x%08x", ui); 436 break; 437 438 case LDP_TLV_FT_SESSION: 439 ft_flags = EXTRACT_16BITS(tptr); 440 printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", 441 ft_flags&0x8000 ? "" : "No ", 442 ft_flags&0x8 ? "" : "Don't ", 443 ft_flags&0x4 ? "" : "No ", 444 ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels", 445 ft_flags&0x1 ? "" : "Don't "); 446 tptr+=4; 447 ui = EXTRACT_32BITS(tptr); 448 if (ui) 449 printf(", Reconnect Timeout: %ums", ui); 450 tptr+=4; 451 ui = EXTRACT_32BITS(tptr); 452 if (ui) 453 printf(", Recovery Time: %ums", ui); 454 break; 455 456 457 /* 458 * FIXME those are the defined TLVs that lack a decoder 459 * you are welcome to contribute code ;-) 460 */ 461 462 case LDP_TLV_HOP_COUNT: 463 case LDP_TLV_PATH_VECTOR: 464 case LDP_TLV_ATM_LABEL: 465 case LDP_TLV_FR_LABEL: 466 case LDP_TLV_EXTD_STATUS: 467 case LDP_TLV_RETURNED_PDU: 468 case LDP_TLV_RETURNED_MSG: 469 case LDP_TLV_ATM_SESSION_PARM: 470 case LDP_TLV_FR_SESSION_PARM: 471 case LDP_TLV_LABEL_REQUEST_MSG_ID: 472 473 default: 474 if (vflag <= 1) 475 print_unknown_data(tptr,"\n\t ",tlv_tlen); 476 break; 477 } 478 return(tlv_len+4); /* Type & Length fields not included */ 479 480trunc: 481 printf("\n\t\t packet exceeded snapshot"); 482 return 0; 483} 484 485void 486ldp_print(register const u_char *pptr, register u_int len) { 487 488 int processed; 489 while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { 490 processed = ldp_msg_print(pptr); 491 if (processed == 0) 492 return; 493 len -= processed; 494 pptr += processed; 495 } 496} 497 498 499int 500ldp_msg_print(register const u_char *pptr) { 501 502 const struct ldp_common_header *ldp_com_header; 503 const struct ldp_msg_header *ldp_msg_header; 504 const u_char *tptr,*msg_tptr; 505 u_short tlen; 506 u_short pdu_len,msg_len,msg_type,msg_tlen; 507 int hexdump,processed; 508 509 tptr=pptr; 510 ldp_com_header = (const struct ldp_common_header *)pptr; 511 TCHECK(*ldp_com_header); 512 513 /* 514 * Sanity checking of the header. 515 */ 516 if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { 517 printf("%sLDP version %u packet not supported", 518 (vflag < 1) ? "" : "\n\t", 519 EXTRACT_16BITS(&ldp_com_header->version)); 520 return 0; 521 } 522 523 /* print the LSR-ID, label-space & length */ 524 pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length); 525 printf("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", 526 (vflag < 1) ? "" : "\n\t", 527 ipaddr_string(&ldp_com_header->lsr_id), 528 EXTRACT_16BITS(&ldp_com_header->label_space), 529 pdu_len); 530 531 /* bail out if non-verbose */ 532 if (vflag < 1) 533 return 0; 534 535 /* ok they seem to want to know everything - lets fully decode it */ 536 tlen=pdu_len; 537 538 tptr += sizeof(const struct ldp_common_header); 539 tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */ 540 541 while(tlen>0) { 542 /* did we capture enough for fully decoding the msg header ? */ 543 if (!TTEST2(*tptr, sizeof(struct ldp_msg_header))) 544 goto trunc; 545 546 ldp_msg_header = (const struct ldp_msg_header *)tptr; 547 msg_len=EXTRACT_16BITS(ldp_msg_header->length); 548 msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); 549 550 /* FIXME vendor private / experimental check */ 551 printf("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", 552 tok2str(ldp_msg_values, 553 "Unknown", 554 msg_type), 555 msg_type, 556 msg_len, 557 EXTRACT_32BITS(&ldp_msg_header->id), 558 LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore"); 559 560 if (msg_len == 0) /* infinite loop protection */ 561 return 0; 562 563 msg_tptr=tptr+sizeof(struct ldp_msg_header); 564 msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */ 565 566 /* did we capture enough for fully decoding the message ? */ 567 if (!TTEST2(*tptr, msg_len)) 568 goto trunc; 569 hexdump=FALSE; 570 571 switch(msg_type) { 572 573 case LDP_MSG_NOTIF: 574 case LDP_MSG_HELLO: 575 case LDP_MSG_INIT: 576 case LDP_MSG_KEEPALIVE: 577 case LDP_MSG_ADDRESS: 578 case LDP_MSG_LABEL_MAPPING: 579 case LDP_MSG_ADDRESS_WITHDRAW: 580 case LDP_MSG_LABEL_WITHDRAW: 581 while(msg_tlen >= 4) { 582 processed = ldp_tlv_print(msg_tptr); 583 if (processed == 0) 584 break; 585 msg_tlen-=processed; 586 msg_tptr+=processed; 587 } 588 break; 589 590 /* 591 * FIXME those are the defined messages that lack a decoder 592 * you are welcome to contribute code ;-) 593 */ 594 595 case LDP_MSG_LABEL_REQUEST: 596 case LDP_MSG_LABEL_RELEASE: 597 case LDP_MSG_LABEL_ABORT_REQUEST: 598 599 default: 600 if (vflag <= 1) 601 print_unknown_data(msg_tptr,"\n\t ",msg_tlen); 602 break; 603 } 604 /* do we want to see an additionally hexdump ? */ 605 if (vflag > 1 || hexdump==TRUE) 606 print_unknown_data(tptr+sizeof(sizeof(struct ldp_msg_header)),"\n\t ", 607 msg_len); 608 609 tptr += msg_len+4; 610 tlen -= msg_len+4; 611 } 612 return pdu_len+4; 613trunc: 614 printf("\n\t\t packet exceeded snapshot"); 615 return 0; 616} 617 618