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