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 * Support for the Link Management Protocol as per rfc 4204. 14 * 15 * Original code by Hannes Gredler (hannes@juniper.net) 16 * Support for LMP service discovery extensions (defined by UNI 1.0) added 17 * by Manu Pathak (mapathak@cisco.com), May 2005 18 */ 19 20#include <sys/cdefs.h> 21#ifndef lint 22#if 0 23static const char rcsid[] _U_ = 24 "@(#) Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.11 2007-08-02 17:32:49 hannes Exp"; 25#else 26__RCSID("$NetBSD: print-lmp.c,v 1.3 2012/01/16 17:34:18 christos Exp $"); 27#endif 28#endif 29 30#ifdef HAVE_CONFIG_H 31#include "config.h" 32#endif 33 34#include <tcpdump-stdinc.h> 35 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39 40#include "interface.h" 41#include "extract.h" 42#include "addrtoname.h" 43#include "gmpls.h" 44 45/* 46 * LMP common header 47 * 48 * 0 1 2 3 49 * 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 50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 51 * | Vers | (Reserved) | Flags | Msg Type | 52 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 53 * | LMP Length | (Reserved) | 54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 55 */ 56 57struct lmp_common_header { 58 u_int8_t version_res[2]; 59 u_int8_t flags; 60 u_int8_t msg_type; 61 u_int8_t length[2]; 62 u_int8_t reserved[2]; 63}; 64 65#define LMP_VERSION 1 66#define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) 67 68static const struct tok lmp_header_flag_values[] = { 69 { 0x01, "Control Channel Down"}, 70 { 0x02, "LMP restart"}, 71 { 0, NULL} 72}; 73 74static const struct tok lmp_obj_te_link_flag_values[] = { 75 { 0x01, "Fault Management Supported"}, 76 { 0x02, "Link Verification Supported"}, 77 { 0, NULL} 78}; 79 80static const struct tok lmp_obj_data_link_flag_values[] = { 81 { 0x01, "Data Link Port"}, 82 { 0x02, "Allocated for user traffic"}, 83 { 0x04, "Failed link"}, 84 { 0, NULL} 85}; 86 87static const struct tok lmp_obj_channel_status_values[] = { 88 { 1, "Signal Okay"}, 89 { 2, "Signal Degraded"}, 90 { 3, "Signal Fail"}, 91 { 0, NULL} 92}; 93 94static const struct tok lmp_obj_begin_verify_flag_values[] = { 95 { 0x0001, "Verify all links"}, 96 { 0x0002, "Data link type"}, 97 { 0, NULL} 98}; 99 100static const struct tok lmp_obj_begin_verify_error_values[] = { 101 { 0x01, "Link Verification Procedure Not supported"}, 102 { 0x02, "Unwilling to verify"}, 103 { 0x04, "Unsupported verification transport mechanism"}, 104 { 0x08, "Link-Id configuration error"}, 105 { 0x10, "Unknown object c-type"}, 106 { 0, NULL} 107}; 108 109static const struct tok lmp_obj_link_summary_error_values[] = { 110 { 0x01, "Unacceptable non-negotiable LINK-SUMMARY parameters"}, 111 { 0x02, "Renegotiate LINK-SUMMARY parameters"}, 112 { 0x04, "Invalid TE-LINK Object"}, 113 { 0x08, "Invalid DATA-LINK Object"}, 114 { 0x10, "Unknown TE-LINK Object c-type"}, 115 { 0x20, "Unknown DATA-LINK Object c-type"}, 116 { 0, NULL} 117}; 118 119/* Service Config Supported Protocols Flags */ 120static const struct tok lmp_obj_service_config_sp_flag_values[] = { 121 { 0x01, "RSVP Supported"}, 122 { 0x02, "LDP Supported"}, 123 { 0, NULL} 124}; 125 126/* Service Config Client Port Service Attribute Transparency Flags */ 127static const struct tok lmp_obj_service_config_cpsa_tp_flag_values[] = { 128 { 0x01, "Path/VC Overhead Transparency Supported"}, 129 { 0x02, "Line/MS Overhead Transparency Supported"}, 130 { 0x04, "Section/RS Overhead Transparency Supported"}, 131 { 0, NULL} 132}; 133 134/* Service Config Client Port Service Attribute Contiguous Concatenation Types Flags */ 135static const struct tok lmp_obj_service_config_cpsa_cct_flag_values[] = { 136 { 0x01, "Contiguous Concatenation Types Supported"}, 137 { 0, NULL} 138}; 139 140/* Service Config Network Service Attributes Transparency Flags */ 141static const struct tok lmp_obj_service_config_nsa_transparency_flag_values[] = { 142 { 0x01, "Standard SOH/RSOH Transparency Supported"}, 143 { 0x02, "Standard LOH/MSOH Transparency Supported"}, 144 { 0, NULL} 145}; 146 147/* Service Config Network Service Attributes TCM Monitoring Flags */ 148static const struct tok lmp_obj_service_config_nsa_tcm_flag_values[] = { 149 { 0x01, "Transparent Tandem Connection Monitoring Supported"}, 150 { 0, NULL} 151}; 152 153/* Network Service Attributes Network Diversity Flags */ 154static const struct tok lmp_obj_service_config_nsa_network_diversity_flag_values[] = { 155 { 0x01, "Node Diversity Supported"}, 156 { 0x02, "Link Diversity Supported"}, 157 { 0x04, "SRLG Diversity Supported"}, 158 { 0, NULL} 159}; 160 161#define LMP_MSGTYPE_CONFIG 1 162#define LMP_MSGTYPE_CONFIG_ACK 2 163#define LMP_MSGTYPE_CONFIG_NACK 3 164#define LMP_MSGTYPE_HELLO 4 165#define LMP_MSGTYPE_VERIFY_BEGIN 5 166#define LMP_MSGTYPE_VERIFY_BEGIN_ACK 6 167#define LMP_MSGTYPE_VERIFY_BEGIN_NACK 7 168#define LMP_MSGTYPE_VERIFY_END 8 169#define LMP_MSGTYPE_VERIFY_END_ACK 9 170#define LMP_MSGTYPE_TEST 10 171#define LMP_MSGTYPE_TEST_STATUS_SUCCESS 11 172#define LMP_MSGTYPE_TEST_STATUS_FAILURE 12 173#define LMP_MSGTYPE_TEST_STATUS_ACK 13 174#define LMP_MSGTYPE_LINK_SUMMARY 14 175#define LMP_MSGTYPE_LINK_SUMMARY_ACK 15 176#define LMP_MSGTYPE_LINK_SUMMARY_NACK 16 177#define LMP_MSGTYPE_CHANNEL_STATUS 17 178#define LMP_MSGTYPE_CHANNEL_STATUS_ACK 18 179#define LMP_MSGTYPE_CHANNEL_STATUS_REQ 19 180#define LMP_MSGTYPE_CHANNEL_STATUS_RESP 20 181/* LMP Service Discovery message types defined by UNI 1.0 */ 182#define LMP_MSGTYPE_SERVICE_CONFIG 50 183#define LMP_MSGTYPE_SERVICE_CONFIG_ACK 51 184#define LMP_MSGTYPE_SERVICE_CONFIG_NACK 52 185 186static const struct tok lmp_msg_type_values[] = { 187 { LMP_MSGTYPE_CONFIG, "Config"}, 188 { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"}, 189 { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"}, 190 { LMP_MSGTYPE_HELLO, "Hello"}, 191 { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"}, 192 { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"}, 193 { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"}, 194 { LMP_MSGTYPE_VERIFY_END, "End Verify"}, 195 { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"}, 196 { LMP_MSGTYPE_TEST, "Test"}, 197 { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"}, 198 { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"}, 199 { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"}, 200 { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"}, 201 { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"}, 202 { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"}, 203 { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"}, 204 { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"}, 205 { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"}, 206 { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"}, 207 { LMP_MSGTYPE_SERVICE_CONFIG, "Service Config"}, 208 { LMP_MSGTYPE_SERVICE_CONFIG_ACK, "Service Config ACK"}, 209 { LMP_MSGTYPE_SERVICE_CONFIG_NACK, "Service Config NACK"}, 210 { 0, NULL} 211}; 212 213/* 214 * LMP object header 215 * 216 * 0 1 2 3 217 * 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 218 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 219 * |N| C-Type | Class | Length | 220 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 221 * | | 222 * // (object contents) // 223 * | | 224 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 225 */ 226 227struct lmp_object_header { 228 u_int8_t ctype; 229 u_int8_t class_num; 230 u_int8_t length[2]; 231}; 232 233#define LMP_OBJ_CC_ID 1 234#define LMP_OBJ_NODE_ID 2 235#define LMP_OBJ_LINK_ID 3 236#define LMP_OBJ_INTERFACE_ID 4 237#define LMP_OBJ_MESSAGE_ID 5 238#define LMP_OBJ_CONFIG 6 239#define LMP_OBJ_HELLO 7 240#define LMP_OBJ_VERIFY_BEGIN 8 241#define LMP_OBJ_VERIFY_BEGIN_ACK 9 242#define LMP_OBJ_VERIFY_ID 10 243#define LMP_OBJ_TE_LINK 11 244#define LMP_OBJ_DATA_LINK 12 245#define LMP_OBJ_CHANNEL_STATUS 13 246#define LMP_OBJ_CHANNEL_STATUS_REQ 14 247#define LMP_OBJ_ERROR_CODE 20 248 249#define LMP_OBJ_SERVICE_CONFIG 51 /* defined in UNI 1.0 */ 250 251static const struct tok lmp_obj_values[] = { 252 { LMP_OBJ_CC_ID, "Control Channel ID" }, 253 { LMP_OBJ_NODE_ID, "Node ID" }, 254 { LMP_OBJ_LINK_ID, "Link ID" }, 255 { LMP_OBJ_INTERFACE_ID, "Interface ID" }, 256 { LMP_OBJ_MESSAGE_ID, "Message ID" }, 257 { LMP_OBJ_CONFIG, "Configuration" }, 258 { LMP_OBJ_HELLO, "Hello" }, 259 { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" }, 260 { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" }, 261 { LMP_OBJ_VERIFY_ID, "Verify ID" }, 262 { LMP_OBJ_TE_LINK, "TE Link" }, 263 { LMP_OBJ_DATA_LINK, "Data Link" }, 264 { LMP_OBJ_CHANNEL_STATUS, "Channel Status" }, 265 { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" }, 266 { LMP_OBJ_ERROR_CODE, "Error Code" }, 267 { LMP_OBJ_SERVICE_CONFIG, "Service Config" }, 268 269 { 0, NULL} 270}; 271 272#define INT_SWITCHING_TYPE_SUBOBJ 1 273#define WAVELENGTH_SUBOBJ 2 274 275static const struct tok lmp_data_link_subobj[] = { 276 { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" }, 277 { WAVELENGTH_SUBOBJ , "Wavelength" }, 278 { 0, NULL} 279}; 280 281#define LMP_CTYPE_IPV4 1 282#define LMP_CTYPE_IPV6 2 283 284#define LMP_CTYPE_LOC 1 285#define LMP_CTYPE_RMT 2 286#define LMP_CTYPE_UNMD 3 287 288#define LMP_CTYPE_IPV4_LOC 1 289#define LMP_CTYPE_IPV4_RMT 2 290#define LMP_CTYPE_IPV6_LOC 3 291#define LMP_CTYPE_IPV6_RMT 4 292#define LMP_CTYPE_UNMD_LOC 5 293#define LMP_CTYPE_UNMD_RMT 6 294 295#define LMP_CTYPE_1 1 296#define LMP_CTYPE_2 2 297 298#define LMP_CTYPE_HELLO_CONFIG 1 299#define LMP_CTYPE_HELLO 1 300 301#define LMP_CTYPE_BEGIN_VERIFY_ERROR 1 302#define LMP_CTYPE_LINK_SUMMARY_ERROR 2 303 304/* C-Types for Service Config Object */ 305#define LMP_CTYPE_SERVICE_CONFIG_SP 1 306#define LMP_CTYPE_SERVICE_CONFIG_CPSA 2 307#define LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM 3 308#define LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY 4 309 310/* 311 * Different link types allowed in the Client Port Service Attributes 312 * subobject defined for LMP Service Discovery in the UNI 1.0 spec 313 */ 314#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH 5 /* UNI 1.0 Sec 9.4.2 */ 315#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET 6 /* UNI 1.0 Sec 9.4.2 */ 316 317/* 318 * the ctypes are not globally unique so for 319 * translating it to strings we build a table based 320 * on objects offsetted by the ctype 321 */ 322 323static const struct tok lmp_ctype_values[] = { 324 { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" }, 325 { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" }, 326 { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" }, 327 { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" }, 328 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, 329 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, 330 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, 331 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, 332 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, 333 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, 334 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, 335 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, 336 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, 337 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, 338 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, 339 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, 340 { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" }, 341 { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" }, 342 { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" }, 343 { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" }, 344 { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" }, 345 { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" }, 346 { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" }, 347 { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" }, 348 { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" }, 349 { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, 350 { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" }, 351 { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" }, 352 { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, 353 { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" }, 354 { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" }, 355 { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" }, 356 { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" }, 357 { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" }, 358 { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" }, 359 { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" }, 360 { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" }, 361 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_SP, "1" }, 362 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_CPSA, "2" }, 363 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM, "3" }, 364 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY, "4" }, 365 { 0, NULL} 366}; 367 368void 369lmp_print(register const u_char *pptr, register u_int len) { 370 371 const struct lmp_common_header *lmp_com_header; 372 const struct lmp_object_header *lmp_obj_header; 373 const u_char *tptr,*obj_tptr; 374 int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; 375 int hexdump; 376 int offset,subobj_type,subobj_len,total_subobj_len; 377 int link_type; 378 379 union { /* int to float conversion buffer */ 380 float f; 381 u_int32_t i; 382 } bw; 383 384 tptr=pptr; 385 lmp_com_header = (const struct lmp_common_header *)pptr; 386 TCHECK(*lmp_com_header); 387 388 /* 389 * Sanity checking of the header. 390 */ 391 if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) { 392 printf("LMP version %u packet not supported", 393 LMP_EXTRACT_VERSION(lmp_com_header->version_res[0])); 394 return; 395 } 396 397 /* in non-verbose mode just lets print the basic Message Type*/ 398 if (vflag < 1) { 399 printf("LMPv%u %s Message, length: %u", 400 LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), 401 tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type), 402 len); 403 return; 404 } 405 406 /* ok they seem to want to know everything - lets fully decode it */ 407 408 tlen=EXTRACT_16BITS(lmp_com_header->length); 409 410 printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u", 411 LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), 412 tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type), 413 bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags), 414 tlen); 415 416 tptr+=sizeof(const struct lmp_common_header); 417 tlen-=sizeof(const struct lmp_common_header); 418 419 while(tlen>0) { 420 /* did we capture enough for fully decoding the object header ? */ 421 if (!TTEST2(*tptr, sizeof(struct lmp_object_header))) 422 goto trunc; 423 424 lmp_obj_header = (const struct lmp_object_header *)tptr; 425 lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length); 426 lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f; 427 428 if(lmp_obj_len % 4 || lmp_obj_len < 4) 429 return; 430 431 printf("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", 432 tok2str(lmp_obj_values, 433 "Unknown", 434 lmp_obj_header->class_num), 435 lmp_obj_header->class_num, 436 tok2str(lmp_ctype_values, 437 "Unknown", 438 ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype), 439 lmp_obj_ctype, 440 (lmp_obj_header->ctype)&0x80 ? "" : "non-", 441 lmp_obj_len); 442 443 obj_tptr=tptr+sizeof(struct lmp_object_header); 444 obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header); 445 446 /* did we capture enough for fully decoding the object ? */ 447 if (!TTEST2(*tptr, lmp_obj_len)) 448 goto trunc; 449 hexdump=FALSE; 450 451 switch(lmp_obj_header->class_num) { 452 453 case LMP_OBJ_CC_ID: 454 switch(lmp_obj_ctype) { 455 case LMP_CTYPE_LOC: 456 case LMP_CTYPE_RMT: 457 printf("\n\t Control Channel ID: %u (0x%08x)", 458 EXTRACT_32BITS(obj_tptr), 459 EXTRACT_32BITS(obj_tptr)); 460 break; 461 462 default: 463 hexdump=TRUE; 464 } 465 break; 466 467 case LMP_OBJ_LINK_ID: 468 case LMP_OBJ_INTERFACE_ID: 469 switch(lmp_obj_ctype) { 470 case LMP_CTYPE_IPV4_LOC: 471 case LMP_CTYPE_IPV4_RMT: 472 printf("\n\t IPv4 Link ID: %s (0x%08x)", 473 ipaddr_string(obj_tptr), 474 EXTRACT_32BITS(obj_tptr)); 475 break; 476#ifdef INET6 477 case LMP_CTYPE_IPV6_LOC: 478 case LMP_CTYPE_IPV6_RMT: 479 printf("\n\t IPv6 Link ID: %s (0x%08x)", 480 ip6addr_string(obj_tptr), 481 EXTRACT_32BITS(obj_tptr)); 482 break; 483#endif 484 case LMP_CTYPE_UNMD_LOC: 485 case LMP_CTYPE_UNMD_RMT: 486 printf("\n\t Link ID: %u (0x%08x)", 487 EXTRACT_32BITS(obj_tptr), 488 EXTRACT_32BITS(obj_tptr)); 489 break; 490 default: 491 hexdump=TRUE; 492 } 493 break; 494 495 case LMP_OBJ_MESSAGE_ID: 496 switch(lmp_obj_ctype) { 497 case LMP_CTYPE_1: 498 printf("\n\t Message ID: %u (0x%08x)", 499 EXTRACT_32BITS(obj_tptr), 500 EXTRACT_32BITS(obj_tptr)); 501 break; 502 case LMP_CTYPE_2: 503 printf("\n\t Message ID Ack: %u (0x%08x)", 504 EXTRACT_32BITS(obj_tptr), 505 EXTRACT_32BITS(obj_tptr)); 506 break; 507 default: 508 hexdump=TRUE; 509 } 510 break; 511 512 case LMP_OBJ_NODE_ID: 513 switch(lmp_obj_ctype) { 514 case LMP_CTYPE_LOC: 515 case LMP_CTYPE_RMT: 516 printf("\n\t Node ID: %s (0x%08x)", 517 ipaddr_string(obj_tptr), 518 EXTRACT_32BITS(obj_tptr)); 519 break; 520 521 default: 522 hexdump=TRUE; 523 } 524 break; 525 526 case LMP_OBJ_CONFIG: 527 switch(lmp_obj_ctype) { 528 case LMP_CTYPE_HELLO_CONFIG: 529 printf("\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", 530 EXTRACT_16BITS(obj_tptr), 531 EXTRACT_16BITS(obj_tptr+2)); 532 break; 533 534 default: 535 hexdump=TRUE; 536 } 537 break; 538 539 case LMP_OBJ_HELLO: 540 switch(lmp_obj_ctype) { 541 case LMP_CTYPE_HELLO: 542 printf("\n\t Tx Seq: %u, Rx Seq: %u", 543 EXTRACT_32BITS(obj_tptr), 544 EXTRACT_32BITS(obj_tptr+4)); 545 break; 546 547 default: 548 hexdump=TRUE; 549 } 550 break; 551 552 case LMP_OBJ_TE_LINK: 553 printf("\n\t Flags: [%s]", 554 bittok2str(lmp_obj_te_link_flag_values, 555 "none", 556 EXTRACT_16BITS(obj_tptr)>>8)); 557 558 switch(lmp_obj_ctype) { 559 case LMP_CTYPE_IPV4: 560 printf("\n\t Local Link-ID: %s (0x%08x) \ 561 \n\t Remote Link-ID: %s (0x%08x)", 562 ipaddr_string(obj_tptr+4), 563 EXTRACT_32BITS(obj_tptr+4), 564 ipaddr_string(obj_tptr+8), 565 EXTRACT_32BITS(obj_tptr+8)); 566 break; 567 568#ifdef INET6 569 case LMP_CTYPE_IPV6: 570#endif 571 case LMP_CTYPE_UNMD: 572 default: 573 hexdump=TRUE; 574 } 575 break; 576 577 case LMP_OBJ_DATA_LINK: 578 printf("\n\t Flags: [%s]", 579 bittok2str(lmp_obj_data_link_flag_values, 580 "none", 581 EXTRACT_16BITS(obj_tptr)>>8)); 582 583 switch(lmp_obj_ctype) { 584 case LMP_CTYPE_IPV4: 585 case LMP_CTYPE_UNMD: 586 printf("\n\t Local Interface ID: %s (0x%08x) \ 587 \n\t Remote Interface ID: %s (0x%08x)", 588 ipaddr_string(obj_tptr+4), 589 EXTRACT_32BITS(obj_tptr+4), 590 ipaddr_string(obj_tptr+8), 591 EXTRACT_32BITS(obj_tptr+8)); 592 593 total_subobj_len = lmp_obj_len - 16; 594 offset = 12; 595 while (total_subobj_len > 0 && hexdump == FALSE ) { 596 subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8; 597 subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF; 598 printf("\n\t Subobject, Type: %s (%u), Length: %u", 599 tok2str(lmp_data_link_subobj, 600 "Unknown", 601 subobj_type), 602 subobj_type, 603 subobj_len); 604 switch(subobj_type) { 605 case INT_SWITCHING_TYPE_SUBOBJ: 606 printf("\n\t Switching Type: %s (%u)", 607 tok2str(gmpls_switch_cap_values, 608 "Unknown", 609 EXTRACT_16BITS(obj_tptr+offset+2)>>8), 610 EXTRACT_16BITS(obj_tptr+offset+2)>>8); 611 printf("\n\t Encoding Type: %s (%u)", 612 tok2str(gmpls_encoding_values, 613 "Unknown", 614 EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF), 615 EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF); 616 bw.i = EXTRACT_32BITS(obj_tptr+offset+4); 617 printf("\n\t Min Reservable Bandwidth: %.3f Mbps", 618 bw.f*8/1000000); 619 bw.i = EXTRACT_32BITS(obj_tptr+offset+8); 620 printf("\n\t Max Reservable Bandwidth: %.3f Mbps", 621 bw.f*8/1000000); 622 break; 623 case WAVELENGTH_SUBOBJ: 624 printf("\n\t Wavelength: %u", 625 EXTRACT_32BITS(obj_tptr+offset+4)); 626 break; 627 default: 628 /* Any Unknown Subobject ==> Exit loop */ 629 hexdump=TRUE; 630 break; 631 } 632 total_subobj_len-=subobj_len; 633 offset+=subobj_len; 634 } 635 636 break; 637#ifdef INET6 638 case LMP_CTYPE_IPV6: 639#endif 640 default: 641 hexdump=TRUE; 642 } 643 break; 644 645 case LMP_OBJ_VERIFY_BEGIN: 646 switch(lmp_obj_ctype) { 647 case LMP_CTYPE_1: 648 printf("\n\t Flags: %s", 649 bittok2str(lmp_obj_begin_verify_flag_values, 650 "none", 651 EXTRACT_16BITS(obj_tptr))); 652 printf("\n\t Verify Interval: %u", 653 EXTRACT_16BITS(obj_tptr+2)); 654 printf("\n\t Data links: %u", 655 EXTRACT_32BITS(obj_tptr+4)); 656 printf("\n\t Encoding type: %s", 657 tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8))); 658 printf("\n\t Verify Tranport Mechanism: %u (0x%x) %s", 659 EXTRACT_16BITS(obj_tptr+10), 660 EXTRACT_16BITS(obj_tptr+10), 661 EXTRACT_16BITS(obj_tptr+10)&8000 ? "(Payload test messages capable)" : ""); 662 bw.i = EXTRACT_32BITS(obj_tptr+12); 663 printf("\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000); 664 printf("\n\t Wavelength: %u", 665 EXTRACT_32BITS(obj_tptr+16)); 666 break; 667 668 default: 669 hexdump=TRUE; 670 } 671 break; 672 673 case LMP_OBJ_VERIFY_BEGIN_ACK: 674 switch(lmp_obj_ctype) { 675 case LMP_CTYPE_1: 676 printf("\n\t Verify Dead Interval: %u \ 677 \n\t Verify Transport Response: %u", 678 EXTRACT_16BITS(obj_tptr), 679 EXTRACT_16BITS(obj_tptr+2)); 680 break; 681 682 default: 683 hexdump=TRUE; 684 } 685 break; 686 687 case LMP_OBJ_VERIFY_ID: 688 switch(lmp_obj_ctype) { 689 case LMP_CTYPE_1: 690 printf("\n\t Verify ID: %u", 691 EXTRACT_32BITS(obj_tptr)); 692 break; 693 694 default: 695 hexdump=TRUE; 696 } 697 break; 698 699 case LMP_OBJ_CHANNEL_STATUS: 700 switch(lmp_obj_ctype) { 701 case LMP_CTYPE_IPV4: 702 case LMP_CTYPE_UNMD: 703 offset = 0; 704 /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */ 705 while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { 706 printf("\n\t Interface ID: %s (0x%08x)", 707 ipaddr_string(obj_tptr+offset), 708 EXTRACT_32BITS(obj_tptr+offset)); 709 710 printf("\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? 711 "Allocated" : "Non-allocated", 712 (EXTRACT_32BITS(obj_tptr+offset+4)>>31)); 713 714 printf("\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? 715 "Transmit" : "Receive", 716 (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1); 717 718 printf("\n\t\t Channel Status: %s (%u)", 719 tok2str(lmp_obj_channel_status_values, 720 "Unknown", 721 EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), 722 EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF); 723 offset+=8; 724 } 725 break; 726#ifdef INET6 727 case LMP_CTYPE_IPV6: 728#endif 729 default: 730 hexdump=TRUE; 731 } 732 break; 733 734 case LMP_OBJ_CHANNEL_STATUS_REQ: 735 switch(lmp_obj_ctype) { 736 case LMP_CTYPE_IPV4: 737 case LMP_CTYPE_UNMD: 738 offset = 0; 739 while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { 740 printf("\n\t Interface ID: %s (0x%08x)", 741 ipaddr_string(obj_tptr+offset), 742 EXTRACT_32BITS(obj_tptr+offset)); 743 offset+=4; 744 } 745 break; 746#ifdef INET6 747 case LMP_CTYPE_IPV6: 748#endif 749 default: 750 hexdump=TRUE; 751 } 752 break; 753 754 case LMP_OBJ_ERROR_CODE: 755 switch(lmp_obj_ctype) { 756 case LMP_CTYPE_BEGIN_VERIFY_ERROR: 757 printf("\n\t Error Code: %s", 758 bittok2str(lmp_obj_begin_verify_error_values, 759 "none", 760 EXTRACT_32BITS(obj_tptr))); 761 break; 762 763 case LMP_CTYPE_LINK_SUMMARY_ERROR: 764 printf("\n\t Error Code: %s", 765 bittok2str(lmp_obj_link_summary_error_values, 766 "none", 767 EXTRACT_32BITS(obj_tptr))); 768 break; 769 default: 770 hexdump=TRUE; 771 } 772 break; 773 774 case LMP_OBJ_SERVICE_CONFIG: 775 switch (lmp_obj_ctype) { 776 case LMP_CTYPE_SERVICE_CONFIG_SP: 777 778 printf("\n\t Flags: %s", 779 bittok2str(lmp_obj_service_config_sp_flag_values, 780 "none", 781 EXTRACT_16BITS(obj_tptr)>>8)); 782 783 printf("\n\t UNI Version: %u", 784 EXTRACT_16BITS(obj_tptr) & 0x00FF); 785 786 break; 787 788 case LMP_CTYPE_SERVICE_CONFIG_CPSA: 789 790 link_type = EXTRACT_16BITS(obj_tptr)>>8; 791 792 printf("\n\t Link Type: %s (%u)", 793 tok2str(lmp_sd_service_config_cpsa_link_type_values, 794 "Unknown", link_type), 795 link_type); 796 797 if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) { 798 printf("\n\t Signal Type: %s (%u)", 799 tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values, 800 "Unknown", 801 EXTRACT_16BITS(obj_tptr) & 0x00FF), 802 EXTRACT_16BITS(obj_tptr) & 0x00FF); 803 } 804 805 if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) { 806 printf("\n\t Signal Type: %s (%u)", 807 tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values, 808 "Unknown", 809 EXTRACT_16BITS(obj_tptr) & 0x00FF), 810 EXTRACT_16BITS(obj_tptr) & 0x00FF); 811 } 812 813 printf("\n\t Transparency: %s", 814 bittok2str(lmp_obj_service_config_cpsa_tp_flag_values, 815 "none", 816 EXTRACT_16BITS(obj_tptr+2)>>8)); 817 818 printf("\n\t Contiguous Concatenation Types: %s", 819 bittok2str(lmp_obj_service_config_cpsa_cct_flag_values, 820 "none", 821 EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)); 822 823 printf("\n\t Minimum NCC: %u", 824 EXTRACT_16BITS(obj_tptr+4)); 825 826 printf("\n\t Maximum NCC: %u", 827 EXTRACT_16BITS(obj_tptr+6)); 828 829 printf("\n\t Minimum NVC:%u", 830 EXTRACT_16BITS(obj_tptr+8)); 831 832 printf("\n\t Maximum NVC:%u", 833 EXTRACT_16BITS(obj_tptr+10)); 834 835 printf("\n\t Local Interface ID: %s (0x%08x)", 836 ipaddr_string(obj_tptr+12), 837 EXTRACT_32BITS(obj_tptr+12)); 838 839 break; 840 841 case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM: 842 843 printf("\n\t Transparency Flags: %s", 844 bittok2str( 845 lmp_obj_service_config_nsa_transparency_flag_values, 846 "none", 847 EXTRACT_32BITS(obj_tptr))); 848 849 printf("\n\t TCM Monitoring Flags: %s", 850 bittok2str( 851 lmp_obj_service_config_nsa_tcm_flag_values, 852 "none", 853 EXTRACT_16BITS(obj_tptr+6) & 0x00FF)); 854 855 break; 856 857 case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY: 858 859 printf("\n\t Diversity: Flags: %s", 860 bittok2str( 861 lmp_obj_service_config_nsa_network_diversity_flag_values, 862 "none", 863 EXTRACT_16BITS(obj_tptr+2) & 0x00FF)); 864 break; 865 866 default: 867 hexdump = TRUE; 868 }; 869 870 break; 871 872 default: 873 if (vflag <= 1) 874 print_unknown_data(obj_tptr,"\n\t ",obj_tlen); 875 break; 876 } 877 /* do we want to see an additionally hexdump ? */ 878 if (vflag > 1 || hexdump==TRUE) 879 print_unknown_data(tptr+sizeof(struct lmp_object_header),"\n\t ", 880 lmp_obj_len-sizeof(struct lmp_object_header)); 881 882 tptr+=lmp_obj_len; 883 tlen-=lmp_obj_len; 884 } 885 return; 886trunc: 887 printf("\n\t\t packet exceeded snapshot"); 888} 889