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@gredler.at) 14 * Support for LMP service discovery extensions (defined by OIF UNI 1.0) 15 * added by Manu Pathak (mapathak@cisco.com), May 2005 16 */ 17 18 /* \summary: Link Management Protocol (LMP) printer */ 19 20 /* specification: RFC 4204 */ 21 /* OIF UNI 1.0: http://www.oiforum.com/public/documents/OIF-UNI-01.0.pdf */ 22 23 #ifdef HAVE_CONFIG_H 24 #include "config.h" 25 #endif 26 27 #include <netdissect-stdinc.h> 28 29 #include "netdissect.h" 30 #include "extract.h" 31 #include "addrtoname.h" 32 #include "gmpls.h" 33 34 static const char tstr[] = " [|LMP]"; 35 36 /* 37 * LMP common header 38 * 39 * 0 1 2 3 40 * 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 41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 42 * | Vers | (Reserved) | Flags | Msg Type | 43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 44 * | LMP Length | (Reserved) | 45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 46 */ 47 48 struct lmp_common_header { 49 uint8_t version_res[2]; 50 uint8_t flags; 51 uint8_t msg_type; 52 uint8_t length[2]; 53 uint8_t reserved[2]; 54 }; 55 56 #define LMP_VERSION 1 57 #define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) 58 59 static const struct tok lmp_header_flag_values[] = { 60 { 0x01, "Control Channel Down"}, 61 { 0x02, "LMP restart"}, 62 { 0, NULL} 63 }; 64 65 static const struct tok lmp_obj_te_link_flag_values[] = { 66 { 0x01, "Fault Management Supported"}, 67 { 0x02, "Link Verification Supported"}, 68 { 0, NULL} 69 }; 70 71 static const struct tok lmp_obj_data_link_flag_values[] = { 72 { 0x01, "Data Link Port"}, 73 { 0x02, "Allocated for user traffic"}, 74 { 0x04, "Failed link"}, 75 { 0, NULL} 76 }; 77 78 static const struct tok lmp_obj_channel_status_values[] = { 79 { 1, "Signal Okay"}, 80 { 2, "Signal Degraded"}, 81 { 3, "Signal Fail"}, 82 { 0, NULL} 83 }; 84 85 static const struct tok lmp_obj_begin_verify_flag_values[] = { 86 { 0x0001, "Verify all links"}, 87 { 0x0002, "Data link type"}, 88 { 0, NULL} 89 }; 90 91 static const struct tok lmp_obj_begin_verify_error_values[] = { 92 { 0x01, "Link Verification Procedure Not supported"}, 93 { 0x02, "Unwilling to verify"}, 94 { 0x04, "Unsupported verification transport mechanism"}, 95 { 0x08, "Link-Id configuration error"}, 96 { 0x10, "Unknown object c-type"}, 97 { 0, NULL} 98 }; 99 100 static const struct tok lmp_obj_link_summary_error_values[] = { 101 { 0x01, "Unacceptable non-negotiable LINK-SUMMARY parameters"}, 102 { 0x02, "Renegotiate LINK-SUMMARY parameters"}, 103 { 0x04, "Invalid TE-LINK Object"}, 104 { 0x08, "Invalid DATA-LINK Object"}, 105 { 0x10, "Unknown TE-LINK Object c-type"}, 106 { 0x20, "Unknown DATA-LINK Object c-type"}, 107 { 0, NULL} 108 }; 109 110 /* Service Config Supported Protocols Flags */ 111 static const struct tok lmp_obj_service_config_sp_flag_values[] = { 112 { 0x01, "RSVP Supported"}, 113 { 0x02, "LDP Supported"}, 114 { 0, NULL} 115 }; 116 117 /* Service Config Client Port Service Attribute Transparency Flags */ 118 static const struct tok lmp_obj_service_config_cpsa_tp_flag_values[] = { 119 { 0x01, "Path/VC Overhead Transparency Supported"}, 120 { 0x02, "Line/MS Overhead Transparency Supported"}, 121 { 0x04, "Section/RS Overhead Transparency Supported"}, 122 { 0, NULL} 123 }; 124 125 /* Service Config Client Port Service Attribute Contiguous Concatenation Types Flags */ 126 static const struct tok lmp_obj_service_config_cpsa_cct_flag_values[] = { 127 { 0x01, "Contiguous Concatenation Types Supported"}, 128 { 0, NULL} 129 }; 130 131 /* Service Config Network Service Attributes Transparency Flags */ 132 static const struct tok lmp_obj_service_config_nsa_transparency_flag_values[] = { 133 { 0x01, "Standard SOH/RSOH Transparency Supported"}, 134 { 0x02, "Standard LOH/MSOH Transparency Supported"}, 135 { 0, NULL} 136 }; 137 138 /* Service Config Network Service Attributes TCM Monitoring Flags */ 139 static const struct tok lmp_obj_service_config_nsa_tcm_flag_values[] = { 140 { 0x01, "Transparent Tandem Connection Monitoring Supported"}, 141 { 0, NULL} 142 }; 143 144 /* Network Service Attributes Network Diversity Flags */ 145 static const struct tok lmp_obj_service_config_nsa_network_diversity_flag_values[] = { 146 { 0x01, "Node Diversity Supported"}, 147 { 0x02, "Link Diversity Supported"}, 148 { 0x04, "SRLG Diversity Supported"}, 149 { 0, NULL} 150 }; 151 152 #define LMP_MSGTYPE_CONFIG 1 153 #define LMP_MSGTYPE_CONFIG_ACK 2 154 #define LMP_MSGTYPE_CONFIG_NACK 3 155 #define LMP_MSGTYPE_HELLO 4 156 #define LMP_MSGTYPE_VERIFY_BEGIN 5 157 #define LMP_MSGTYPE_VERIFY_BEGIN_ACK 6 158 #define LMP_MSGTYPE_VERIFY_BEGIN_NACK 7 159 #define LMP_MSGTYPE_VERIFY_END 8 160 #define LMP_MSGTYPE_VERIFY_END_ACK 9 161 #define LMP_MSGTYPE_TEST 10 162 #define LMP_MSGTYPE_TEST_STATUS_SUCCESS 11 163 #define LMP_MSGTYPE_TEST_STATUS_FAILURE 12 164 #define LMP_MSGTYPE_TEST_STATUS_ACK 13 165 #define LMP_MSGTYPE_LINK_SUMMARY 14 166 #define LMP_MSGTYPE_LINK_SUMMARY_ACK 15 167 #define LMP_MSGTYPE_LINK_SUMMARY_NACK 16 168 #define LMP_MSGTYPE_CHANNEL_STATUS 17 169 #define LMP_MSGTYPE_CHANNEL_STATUS_ACK 18 170 #define LMP_MSGTYPE_CHANNEL_STATUS_REQ 19 171 #define LMP_MSGTYPE_CHANNEL_STATUS_RESP 20 172 /* LMP Service Discovery message types defined by UNI 1.0 */ 173 #define LMP_MSGTYPE_SERVICE_CONFIG 50 174 #define LMP_MSGTYPE_SERVICE_CONFIG_ACK 51 175 #define LMP_MSGTYPE_SERVICE_CONFIG_NACK 52 176 177 static const struct tok lmp_msg_type_values[] = { 178 { LMP_MSGTYPE_CONFIG, "Config"}, 179 { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"}, 180 { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"}, 181 { LMP_MSGTYPE_HELLO, "Hello"}, 182 { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"}, 183 { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"}, 184 { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"}, 185 { LMP_MSGTYPE_VERIFY_END, "End Verify"}, 186 { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"}, 187 { LMP_MSGTYPE_TEST, "Test"}, 188 { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"}, 189 { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"}, 190 { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"}, 191 { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"}, 192 { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"}, 193 { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"}, 194 { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"}, 195 { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"}, 196 { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"}, 197 { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"}, 198 { LMP_MSGTYPE_SERVICE_CONFIG, "Service Config"}, 199 { LMP_MSGTYPE_SERVICE_CONFIG_ACK, "Service Config ACK"}, 200 { LMP_MSGTYPE_SERVICE_CONFIG_NACK, "Service Config NACK"}, 201 { 0, NULL} 202 }; 203 204 /* 205 * LMP object header 206 * 207 * 0 1 2 3 208 * 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 209 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 210 * |N| C-Type | Class | Length | 211 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 212 * | | 213 * // (object contents) // 214 * | | 215 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 216 */ 217 218 struct lmp_object_header { 219 uint8_t ctype; 220 uint8_t class_num; 221 uint8_t length[2]; 222 }; 223 224 #define LMP_OBJ_CC_ID 1 225 #define LMP_OBJ_NODE_ID 2 226 #define LMP_OBJ_LINK_ID 3 227 #define LMP_OBJ_INTERFACE_ID 4 228 #define LMP_OBJ_MESSAGE_ID 5 229 #define LMP_OBJ_CONFIG 6 230 #define LMP_OBJ_HELLO 7 231 #define LMP_OBJ_VERIFY_BEGIN 8 232 #define LMP_OBJ_VERIFY_BEGIN_ACK 9 233 #define LMP_OBJ_VERIFY_ID 10 234 #define LMP_OBJ_TE_LINK 11 235 #define LMP_OBJ_DATA_LINK 12 236 #define LMP_OBJ_CHANNEL_STATUS 13 237 #define LMP_OBJ_CHANNEL_STATUS_REQ 14 238 #define LMP_OBJ_ERROR_CODE 20 239 240 #define LMP_OBJ_SERVICE_CONFIG 51 /* defined in UNI 1.0 */ 241 242 static const struct tok lmp_obj_values[] = { 243 { LMP_OBJ_CC_ID, "Control Channel ID" }, 244 { LMP_OBJ_NODE_ID, "Node ID" }, 245 { LMP_OBJ_LINK_ID, "Link ID" }, 246 { LMP_OBJ_INTERFACE_ID, "Interface ID" }, 247 { LMP_OBJ_MESSAGE_ID, "Message ID" }, 248 { LMP_OBJ_CONFIG, "Configuration" }, 249 { LMP_OBJ_HELLO, "Hello" }, 250 { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" }, 251 { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" }, 252 { LMP_OBJ_VERIFY_ID, "Verify ID" }, 253 { LMP_OBJ_TE_LINK, "TE Link" }, 254 { LMP_OBJ_DATA_LINK, "Data Link" }, 255 { LMP_OBJ_CHANNEL_STATUS, "Channel Status" }, 256 { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" }, 257 { LMP_OBJ_ERROR_CODE, "Error Code" }, 258 { LMP_OBJ_SERVICE_CONFIG, "Service Config" }, 259 260 { 0, NULL} 261 }; 262 263 #define INT_SWITCHING_TYPE_SUBOBJ 1 264 #define WAVELENGTH_SUBOBJ 2 265 266 static const struct tok lmp_data_link_subobj[] = { 267 { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" }, 268 { WAVELENGTH_SUBOBJ , "Wavelength" }, 269 { 0, NULL} 270 }; 271 272 #define LMP_CTYPE_IPV4 1 273 #define LMP_CTYPE_IPV6 2 274 275 #define LMP_CTYPE_LOC 1 276 #define LMP_CTYPE_RMT 2 277 #define LMP_CTYPE_UNMD 3 278 279 #define LMP_CTYPE_IPV4_LOC 1 280 #define LMP_CTYPE_IPV4_RMT 2 281 #define LMP_CTYPE_IPV6_LOC 3 282 #define LMP_CTYPE_IPV6_RMT 4 283 #define LMP_CTYPE_UNMD_LOC 5 284 #define LMP_CTYPE_UNMD_RMT 6 285 286 #define LMP_CTYPE_1 1 287 #define LMP_CTYPE_2 2 288 289 #define LMP_CTYPE_HELLO_CONFIG 1 290 #define LMP_CTYPE_HELLO 1 291 292 #define LMP_CTYPE_BEGIN_VERIFY_ERROR 1 293 #define LMP_CTYPE_LINK_SUMMARY_ERROR 2 294 295 /* C-Types for Service Config Object */ 296 #define LMP_CTYPE_SERVICE_CONFIG_SP 1 297 #define LMP_CTYPE_SERVICE_CONFIG_CPSA 2 298 #define LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM 3 299 #define LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY 4 300 301 /* 302 * Different link types allowed in the Client Port Service Attributes 303 * subobject defined for LMP Service Discovery in the UNI 1.0 spec 304 */ 305 #define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH 5 /* UNI 1.0 Sec 9.4.2 */ 306 #define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET 6 /* UNI 1.0 Sec 9.4.2 */ 307 308 /* 309 * the ctypes are not globally unique so for 310 * translating it to strings we build a table based 311 * on objects offsetted by the ctype 312 */ 313 314 static const struct tok lmp_ctype_values[] = { 315 { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" }, 316 { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" }, 317 { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" }, 318 { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" }, 319 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, 320 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, 321 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, 322 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, 323 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, 324 { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, 325 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, 326 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, 327 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, 328 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, 329 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, 330 { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, 331 { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" }, 332 { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" }, 333 { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" }, 334 { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" }, 335 { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" }, 336 { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" }, 337 { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" }, 338 { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" }, 339 { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" }, 340 { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, 341 { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" }, 342 { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" }, 343 { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, 344 { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" }, 345 { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" }, 346 { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" }, 347 { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" }, 348 { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" }, 349 { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" }, 350 { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" }, 351 { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" }, 352 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_SP, "1" }, 353 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_CPSA, "2" }, 354 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM, "3" }, 355 { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY, "4" }, 356 { 0, NULL} 357 }; 358 359 static int 360 lmp_print_data_link_subobjs(netdissect_options *ndo, const u_char *obj_tptr, 361 int total_subobj_len, int offset) 362 { 363 int hexdump = FALSE; 364 int subobj_type, subobj_len; 365 366 union { /* int to float conversion buffer */ 367 float f; 368 uint32_t i; 369 } bw; 370 371 while (total_subobj_len > 0 && hexdump == FALSE ) { 372 ND_TCHECK_16BITS(obj_tptr + offset); 373 subobj_type = EXTRACT_8BITS(obj_tptr + offset); 374 subobj_len = EXTRACT_8BITS(obj_tptr + offset + 1); 375 ND_PRINT((ndo, "\n\t Subobject, Type: %s (%u), Length: %u", 376 tok2str(lmp_data_link_subobj, 377 "Unknown", 378 subobj_type), 379 subobj_type, 380 subobj_len)); 381 if (subobj_len < 4) { 382 ND_PRINT((ndo, " (too short)")); 383 break; 384 } 385 if ((subobj_len % 4) != 0) { 386 ND_PRINT((ndo, " (not a multiple of 4)")); 387 break; 388 } 389 if (total_subobj_len < subobj_len) { 390 ND_PRINT((ndo, " (goes past the end of the object)")); 391 break; 392 } 393 switch(subobj_type) { 394 case INT_SWITCHING_TYPE_SUBOBJ: 395 ND_TCHECK_8BITS(obj_tptr + offset + 2); 396 ND_PRINT((ndo, "\n\t Switching Type: %s (%u)", 397 tok2str(gmpls_switch_cap_values, 398 "Unknown", 399 EXTRACT_8BITS(obj_tptr + offset + 2)), 400 EXTRACT_8BITS(obj_tptr + offset + 2))); 401 ND_TCHECK_8BITS(obj_tptr + offset + 3); 402 ND_PRINT((ndo, "\n\t Encoding Type: %s (%u)", 403 tok2str(gmpls_encoding_values, 404 "Unknown", 405 EXTRACT_8BITS(obj_tptr + offset + 3)), 406 EXTRACT_8BITS(obj_tptr + offset + 3))); 407 ND_TCHECK_32BITS(obj_tptr + offset + 4); 408 bw.i = EXTRACT_32BITS(obj_tptr+offset+4); 409 ND_PRINT((ndo, "\n\t Min Reservable Bandwidth: %.3f Mbps", 410 bw.f*8/1000000)); 411 ND_TCHECK_32BITS(obj_tptr + offset + 8); 412 bw.i = EXTRACT_32BITS(obj_tptr+offset+8); 413 ND_PRINT((ndo, "\n\t Max Reservable Bandwidth: %.3f Mbps", 414 bw.f*8/1000000)); 415 break; 416 case WAVELENGTH_SUBOBJ: 417 ND_TCHECK_32BITS(obj_tptr + offset + 4); 418 ND_PRINT((ndo, "\n\t Wavelength: %u", 419 EXTRACT_32BITS(obj_tptr+offset+4))); 420 break; 421 default: 422 /* Any Unknown Subobject ==> Exit loop */ 423 hexdump=TRUE; 424 break; 425 } 426 total_subobj_len-=subobj_len; 427 offset+=subobj_len; 428 } 429 return (hexdump); 430 trunc: 431 return -1; 432 } 433 434 void 435 lmp_print(netdissect_options *ndo, 436 register const u_char *pptr, register u_int len) 437 { 438 const struct lmp_common_header *lmp_com_header; 439 const struct lmp_object_header *lmp_obj_header; 440 const u_char *tptr,*obj_tptr; 441 u_int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; 442 int hexdump, ret; 443 u_int offset; 444 u_int link_type; 445 446 union { /* int to float conversion buffer */ 447 float f; 448 uint32_t i; 449 } bw; 450 451 tptr=pptr; 452 lmp_com_header = (const struct lmp_common_header *)pptr; 453 ND_TCHECK(*lmp_com_header); 454 455 /* 456 * Sanity checking of the header. 457 */ 458 if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) { 459 ND_PRINT((ndo, "LMP version %u packet not supported", 460 LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]))); 461 return; 462 } 463 464 /* in non-verbose mode just lets print the basic Message Type*/ 465 if (ndo->ndo_vflag < 1) { 466 ND_PRINT((ndo, "LMPv%u %s Message, length: %u", 467 LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), 468 tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type), 469 len)); 470 return; 471 } 472 473 /* ok they seem to want to know everything - lets fully decode it */ 474 475 tlen=EXTRACT_16BITS(lmp_com_header->length); 476 477 ND_PRINT((ndo, "\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u", 478 LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), 479 tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type), 480 bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags), 481 tlen)); 482 if (tlen < sizeof(const struct lmp_common_header)) { 483 ND_PRINT((ndo, " (too short)")); 484 return; 485 } 486 if (tlen > len) { 487 ND_PRINT((ndo, " (too long)")); 488 tlen = len; 489 } 490 491 tptr+=sizeof(const struct lmp_common_header); 492 tlen-=sizeof(const struct lmp_common_header); 493 494 while(tlen>0) { 495 /* did we capture enough for fully decoding the object header ? */ 496 ND_TCHECK2(*tptr, sizeof(struct lmp_object_header)); 497 498 lmp_obj_header = (const struct lmp_object_header *)tptr; 499 lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length); 500 lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f; 501 502 ND_PRINT((ndo, "\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", 503 tok2str(lmp_obj_values, 504 "Unknown", 505 lmp_obj_header->class_num), 506 lmp_obj_header->class_num, 507 tok2str(lmp_ctype_values, 508 "Unknown", 509 ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype), 510 lmp_obj_ctype, 511 (lmp_obj_header->ctype)&0x80 ? "" : "non-", 512 lmp_obj_len)); 513 514 if (lmp_obj_len < 4) { 515 ND_PRINT((ndo, " (too short)")); 516 return; 517 } 518 if ((lmp_obj_len % 4) != 0) { 519 ND_PRINT((ndo, " (not a multiple of 4)")); 520 return; 521 } 522 523 obj_tptr=tptr+sizeof(struct lmp_object_header); 524 obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header); 525 526 /* did we capture enough for fully decoding the object ? */ 527 ND_TCHECK2(*tptr, lmp_obj_len); 528 hexdump=FALSE; 529 530 switch(lmp_obj_header->class_num) { 531 532 case LMP_OBJ_CC_ID: 533 switch(lmp_obj_ctype) { 534 case LMP_CTYPE_LOC: 535 case LMP_CTYPE_RMT: 536 if (obj_tlen != 4) { 537 ND_PRINT((ndo, " (not correct for object)")); 538 break; 539 } 540 ND_PRINT((ndo, "\n\t Control Channel ID: %u (0x%08x)", 541 EXTRACT_32BITS(obj_tptr), 542 EXTRACT_32BITS(obj_tptr))); 543 break; 544 545 default: 546 hexdump=TRUE; 547 } 548 break; 549 550 case LMP_OBJ_LINK_ID: 551 case LMP_OBJ_INTERFACE_ID: 552 switch(lmp_obj_ctype) { 553 case LMP_CTYPE_IPV4_LOC: 554 case LMP_CTYPE_IPV4_RMT: 555 if (obj_tlen != 4) { 556 ND_PRINT((ndo, " (not correct for object)")); 557 break; 558 } 559 ND_PRINT((ndo, "\n\t IPv4 Link ID: %s (0x%08x)", 560 ipaddr_string(ndo, obj_tptr), 561 EXTRACT_32BITS(obj_tptr))); 562 break; 563 case LMP_CTYPE_IPV6_LOC: 564 case LMP_CTYPE_IPV6_RMT: 565 if (obj_tlen != 16) { 566 ND_PRINT((ndo, " (not correct for object)")); 567 break; 568 } 569 ND_PRINT((ndo, "\n\t IPv6 Link ID: %s (0x%08x)", 570 ip6addr_string(ndo, obj_tptr), 571 EXTRACT_32BITS(obj_tptr))); 572 break; 573 case LMP_CTYPE_UNMD_LOC: 574 case LMP_CTYPE_UNMD_RMT: 575 if (obj_tlen != 4) { 576 ND_PRINT((ndo, " (not correct for object)")); 577 break; 578 } 579 ND_PRINT((ndo, "\n\t Link ID: %u (0x%08x)", 580 EXTRACT_32BITS(obj_tptr), 581 EXTRACT_32BITS(obj_tptr))); 582 break; 583 default: 584 hexdump=TRUE; 585 } 586 break; 587 588 case LMP_OBJ_MESSAGE_ID: 589 switch(lmp_obj_ctype) { 590 case LMP_CTYPE_1: 591 if (obj_tlen != 4) { 592 ND_PRINT((ndo, " (not correct for object)")); 593 break; 594 } 595 ND_PRINT((ndo, "\n\t Message ID: %u (0x%08x)", 596 EXTRACT_32BITS(obj_tptr), 597 EXTRACT_32BITS(obj_tptr))); 598 break; 599 case LMP_CTYPE_2: 600 if (obj_tlen != 4) { 601 ND_PRINT((ndo, " (not correct for object)")); 602 break; 603 } 604 ND_PRINT((ndo, "\n\t Message ID Ack: %u (0x%08x)", 605 EXTRACT_32BITS(obj_tptr), 606 EXTRACT_32BITS(obj_tptr))); 607 break; 608 default: 609 hexdump=TRUE; 610 } 611 break; 612 613 case LMP_OBJ_NODE_ID: 614 switch(lmp_obj_ctype) { 615 case LMP_CTYPE_LOC: 616 case LMP_CTYPE_RMT: 617 if (obj_tlen != 4) { 618 ND_PRINT((ndo, " (not correct for object)")); 619 break; 620 } 621 ND_PRINT((ndo, "\n\t Node ID: %s (0x%08x)", 622 ipaddr_string(ndo, obj_tptr), 623 EXTRACT_32BITS(obj_tptr))); 624 break; 625 626 default: 627 hexdump=TRUE; 628 } 629 break; 630 631 case LMP_OBJ_CONFIG: 632 switch(lmp_obj_ctype) { 633 case LMP_CTYPE_HELLO_CONFIG: 634 if (obj_tlen != 4) { 635 ND_PRINT((ndo, " (not correct for object)")); 636 break; 637 } 638 ND_PRINT((ndo, "\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", 639 EXTRACT_16BITS(obj_tptr), 640 EXTRACT_16BITS(obj_tptr+2))); 641 break; 642 643 default: 644 hexdump=TRUE; 645 } 646 break; 647 648 case LMP_OBJ_HELLO: 649 switch(lmp_obj_ctype) { 650 case LMP_CTYPE_HELLO: 651 if (obj_tlen != 8) { 652 ND_PRINT((ndo, " (not correct for object)")); 653 break; 654 } 655 ND_PRINT((ndo, "\n\t Tx Seq: %u, Rx Seq: %u", 656 EXTRACT_32BITS(obj_tptr), 657 EXTRACT_32BITS(obj_tptr+4))); 658 break; 659 660 default: 661 hexdump=TRUE; 662 } 663 break; 664 665 case LMP_OBJ_TE_LINK: 666 switch(lmp_obj_ctype) { 667 case LMP_CTYPE_IPV4: 668 if (obj_tlen != 12) { 669 ND_PRINT((ndo, " (not correct for object)")); 670 break; 671 } 672 ND_PRINT((ndo, "\n\t Flags: [%s]", 673 bittok2str(lmp_obj_te_link_flag_values, 674 "none", 675 EXTRACT_8BITS(obj_tptr)))); 676 677 ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)" 678 "\n\t Remote Link-ID: %s (0x%08x)", 679 ipaddr_string(ndo, obj_tptr+4), 680 EXTRACT_32BITS(obj_tptr+4), 681 ipaddr_string(ndo, obj_tptr+8), 682 EXTRACT_32BITS(obj_tptr+8))); 683 break; 684 685 case LMP_CTYPE_IPV6: 686 if (obj_tlen != 36) { 687 ND_PRINT((ndo, " (not correct for object)")); 688 break; 689 } 690 ND_PRINT((ndo, "\n\t Flags: [%s]", 691 bittok2str(lmp_obj_te_link_flag_values, 692 "none", 693 EXTRACT_8BITS(obj_tptr)))); 694 695 ND_PRINT((ndo, "\n\t Local Link-ID: %s (0x%08x)" 696 "\n\t Remote Link-ID: %s (0x%08x)", 697 ip6addr_string(ndo, obj_tptr+4), 698 EXTRACT_32BITS(obj_tptr+4), 699 ip6addr_string(ndo, obj_tptr+20), 700 EXTRACT_32BITS(obj_tptr+20))); 701 break; 702 703 case LMP_CTYPE_UNMD: 704 if (obj_tlen != 12) { 705 ND_PRINT((ndo, " (not correct for object)")); 706 break; 707 } 708 ND_PRINT((ndo, "\n\t Flags: [%s]", 709 bittok2str(lmp_obj_te_link_flag_values, 710 "none", 711 EXTRACT_8BITS(obj_tptr)))); 712 713 ND_PRINT((ndo, "\n\t Local Link-ID: %u (0x%08x)" 714 "\n\t Remote Link-ID: %u (0x%08x)", 715 EXTRACT_32BITS(obj_tptr+4), 716 EXTRACT_32BITS(obj_tptr+4), 717 EXTRACT_32BITS(obj_tptr+8), 718 EXTRACT_32BITS(obj_tptr+8))); 719 break; 720 721 default: 722 hexdump=TRUE; 723 } 724 break; 725 726 case LMP_OBJ_DATA_LINK: 727 switch(lmp_obj_ctype) { 728 case LMP_CTYPE_IPV4: 729 if (obj_tlen < 12) { 730 ND_PRINT((ndo, " (not correct for object)")); 731 break; 732 } 733 ND_PRINT((ndo, "\n\t Flags: [%s]", 734 bittok2str(lmp_obj_data_link_flag_values, 735 "none", 736 EXTRACT_8BITS(obj_tptr)))); 737 ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)" 738 "\n\t Remote Interface ID: %s (0x%08x)", 739 ipaddr_string(ndo, obj_tptr+4), 740 EXTRACT_32BITS(obj_tptr+4), 741 ipaddr_string(ndo, obj_tptr+8), 742 EXTRACT_32BITS(obj_tptr+8))); 743 744 ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12); 745 if (ret == -1) 746 goto trunc; 747 if (ret == TRUE) 748 hexdump=TRUE; 749 break; 750 751 case LMP_CTYPE_IPV6: 752 if (obj_tlen < 36) { 753 ND_PRINT((ndo, " (not correct for object)")); 754 break; 755 } 756 ND_PRINT((ndo, "\n\t Flags: [%s]", 757 bittok2str(lmp_obj_data_link_flag_values, 758 "none", 759 EXTRACT_8BITS(obj_tptr)))); 760 ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)" 761 "\n\t Remote Interface ID: %s (0x%08x)", 762 ip6addr_string(ndo, obj_tptr+4), 763 EXTRACT_32BITS(obj_tptr+4), 764 ip6addr_string(ndo, obj_tptr+20), 765 EXTRACT_32BITS(obj_tptr+20))); 766 767 ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36); 768 if (ret == -1) 769 goto trunc; 770 if (ret == TRUE) 771 hexdump=TRUE; 772 break; 773 774 case LMP_CTYPE_UNMD: 775 if (obj_tlen < 12) { 776 ND_PRINT((ndo, " (not correct for object)")); 777 break; 778 } 779 ND_PRINT((ndo, "\n\t Flags: [%s]", 780 bittok2str(lmp_obj_data_link_flag_values, 781 "none", 782 EXTRACT_8BITS(obj_tptr)))); 783 ND_PRINT((ndo, "\n\t Local Interface ID: %u (0x%08x)" 784 "\n\t Remote Interface ID: %u (0x%08x)", 785 EXTRACT_32BITS(obj_tptr+4), 786 EXTRACT_32BITS(obj_tptr+4), 787 EXTRACT_32BITS(obj_tptr+8), 788 EXTRACT_32BITS(obj_tptr+8))); 789 790 ret = lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12); 791 if (ret == -1) 792 goto trunc; 793 if (ret == TRUE) 794 hexdump=TRUE; 795 break; 796 797 default: 798 hexdump=TRUE; 799 } 800 break; 801 802 case LMP_OBJ_VERIFY_BEGIN: 803 switch(lmp_obj_ctype) { 804 case LMP_CTYPE_1: 805 if (obj_tlen != 20) { 806 ND_PRINT((ndo, " (not correct for object)")); 807 break; 808 } 809 ND_PRINT((ndo, "\n\t Flags: %s", 810 bittok2str(lmp_obj_begin_verify_flag_values, 811 "none", 812 EXTRACT_16BITS(obj_tptr)))); 813 ND_PRINT((ndo, "\n\t Verify Interval: %u", 814 EXTRACT_16BITS(obj_tptr+2))); 815 ND_PRINT((ndo, "\n\t Data links: %u", 816 EXTRACT_32BITS(obj_tptr+4))); 817 ND_PRINT((ndo, "\n\t Encoding type: %s", 818 tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8)))); 819 ND_PRINT((ndo, "\n\t Verify Transport Mechanism: %u (0x%x)%s", 820 EXTRACT_16BITS(obj_tptr+10), 821 EXTRACT_16BITS(obj_tptr+10), 822 EXTRACT_16BITS(obj_tptr+10)&8000 ? " (Payload test messages capable)" : "")); 823 bw.i = EXTRACT_32BITS(obj_tptr+12); 824 ND_PRINT((ndo, "\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000)); 825 ND_PRINT((ndo, "\n\t Wavelength: %u", 826 EXTRACT_32BITS(obj_tptr+16))); 827 break; 828 829 default: 830 hexdump=TRUE; 831 } 832 break; 833 834 case LMP_OBJ_VERIFY_BEGIN_ACK: 835 switch(lmp_obj_ctype) { 836 case LMP_CTYPE_1: 837 if (obj_tlen != 4) { 838 ND_PRINT((ndo, " (not correct for object)")); 839 break; 840 } 841 ND_PRINT((ndo, "\n\t Verify Dead Interval: %u" 842 "\n\t Verify Transport Response: %u", 843 EXTRACT_16BITS(obj_tptr), 844 EXTRACT_16BITS(obj_tptr+2))); 845 break; 846 847 default: 848 hexdump=TRUE; 849 } 850 break; 851 852 case LMP_OBJ_VERIFY_ID: 853 switch(lmp_obj_ctype) { 854 case LMP_CTYPE_1: 855 if (obj_tlen != 4) { 856 ND_PRINT((ndo, " (not correct for object)")); 857 break; 858 } 859 ND_PRINT((ndo, "\n\t Verify ID: %u", 860 EXTRACT_32BITS(obj_tptr))); 861 break; 862 863 default: 864 hexdump=TRUE; 865 } 866 break; 867 868 case LMP_OBJ_CHANNEL_STATUS: 869 switch(lmp_obj_ctype) { 870 case LMP_CTYPE_IPV4: 871 offset = 0; 872 /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */ 873 while (offset+8 <= obj_tlen) { 874 ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", 875 ipaddr_string(ndo, obj_tptr+offset), 876 EXTRACT_32BITS(obj_tptr+offset))); 877 878 ND_PRINT((ndo, "\n\t\t Active: %s (%u)", 879 (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? 880 "Allocated" : "Non-allocated", 881 (EXTRACT_32BITS(obj_tptr+offset+4)>>31))); 882 883 ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", 884 (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? 885 "Transmit" : "Receive", 886 (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1)); 887 888 ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", 889 tok2str(lmp_obj_channel_status_values, 890 "Unknown", 891 EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), 892 EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF)); 893 offset+=8; 894 } 895 break; 896 897 case LMP_CTYPE_IPV6: 898 offset = 0; 899 /* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */ 900 while (offset+20 <= obj_tlen) { 901 ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", 902 ip6addr_string(ndo, obj_tptr+offset), 903 EXTRACT_32BITS(obj_tptr+offset))); 904 905 ND_PRINT((ndo, "\n\t\t Active: %s (%u)", 906 (EXTRACT_32BITS(obj_tptr+offset+16)>>31) ? 907 "Allocated" : "Non-allocated", 908 (EXTRACT_32BITS(obj_tptr+offset+16)>>31))); 909 910 ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", 911 (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1 ? 912 "Transmit" : "Receive", 913 (EXTRACT_32BITS(obj_tptr+offset+16)>>30)&0x1)); 914 915 ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", 916 tok2str(lmp_obj_channel_status_values, 917 "Unknown", 918 EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF), 919 EXTRACT_32BITS(obj_tptr+offset+16)&0x3FFFFFF)); 920 offset+=20; 921 } 922 break; 923 924 case LMP_CTYPE_UNMD: 925 offset = 0; 926 /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */ 927 while (offset+8 <= obj_tlen) { 928 ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)", 929 EXTRACT_32BITS(obj_tptr+offset), 930 EXTRACT_32BITS(obj_tptr+offset))); 931 932 ND_PRINT((ndo, "\n\t\t Active: %s (%u)", 933 (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? 934 "Allocated" : "Non-allocated", 935 (EXTRACT_32BITS(obj_tptr+offset+4)>>31))); 936 937 ND_PRINT((ndo, "\n\t\t Direction: %s (%u)", 938 (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? 939 "Transmit" : "Receive", 940 (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1)); 941 942 ND_PRINT((ndo, "\n\t\t Channel Status: %s (%u)", 943 tok2str(lmp_obj_channel_status_values, 944 "Unknown", 945 EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), 946 EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF)); 947 offset+=8; 948 } 949 break; 950 951 default: 952 hexdump=TRUE; 953 } 954 break; 955 956 case LMP_OBJ_CHANNEL_STATUS_REQ: 957 switch(lmp_obj_ctype) { 958 case LMP_CTYPE_IPV4: 959 offset = 0; 960 while (offset+4 <= obj_tlen) { 961 ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", 962 ipaddr_string(ndo, obj_tptr+offset), 963 EXTRACT_32BITS(obj_tptr+offset))); 964 offset+=4; 965 } 966 break; 967 968 case LMP_CTYPE_IPV6: 969 offset = 0; 970 while (offset+16 <= obj_tlen) { 971 ND_PRINT((ndo, "\n\t Interface ID: %s (0x%08x)", 972 ip6addr_string(ndo, obj_tptr+offset), 973 EXTRACT_32BITS(obj_tptr+offset))); 974 offset+=16; 975 } 976 break; 977 978 case LMP_CTYPE_UNMD: 979 offset = 0; 980 while (offset+4 <= obj_tlen) { 981 ND_PRINT((ndo, "\n\t Interface ID: %u (0x%08x)", 982 EXTRACT_32BITS(obj_tptr+offset), 983 EXTRACT_32BITS(obj_tptr+offset))); 984 offset+=4; 985 } 986 break; 987 988 default: 989 hexdump=TRUE; 990 } 991 break; 992 993 case LMP_OBJ_ERROR_CODE: 994 switch(lmp_obj_ctype) { 995 case LMP_CTYPE_BEGIN_VERIFY_ERROR: 996 if (obj_tlen != 4) { 997 ND_PRINT((ndo, " (not correct for object)")); 998 break; 999 } 1000 ND_PRINT((ndo, "\n\t Error Code: %s", 1001 bittok2str(lmp_obj_begin_verify_error_values, 1002 "none", 1003 EXTRACT_32BITS(obj_tptr)))); 1004 break; 1005 1006 case LMP_CTYPE_LINK_SUMMARY_ERROR: 1007 if (obj_tlen != 4) { 1008 ND_PRINT((ndo, " (not correct for object)")); 1009 break; 1010 } 1011 ND_PRINT((ndo, "\n\t Error Code: %s", 1012 bittok2str(lmp_obj_link_summary_error_values, 1013 "none", 1014 EXTRACT_32BITS(obj_tptr)))); 1015 break; 1016 default: 1017 hexdump=TRUE; 1018 } 1019 break; 1020 1021 case LMP_OBJ_SERVICE_CONFIG: 1022 switch (lmp_obj_ctype) { 1023 case LMP_CTYPE_SERVICE_CONFIG_SP: 1024 if (obj_tlen != 4) { 1025 ND_PRINT((ndo, " (not correct for object)")); 1026 break; 1027 } 1028 ND_PRINT((ndo, "\n\t Flags: %s", 1029 bittok2str(lmp_obj_service_config_sp_flag_values, 1030 "none", 1031 EXTRACT_8BITS(obj_tptr)))); 1032 1033 ND_PRINT((ndo, "\n\t UNI Version: %u", 1034 EXTRACT_8BITS(obj_tptr + 1))); 1035 1036 break; 1037 1038 case LMP_CTYPE_SERVICE_CONFIG_CPSA: 1039 if (obj_tlen != 16) { 1040 ND_PRINT((ndo, " (not correct for object)")); 1041 break; 1042 } 1043 1044 link_type = EXTRACT_8BITS(obj_tptr); 1045 1046 ND_PRINT((ndo, "\n\t Link Type: %s (%u)", 1047 tok2str(lmp_sd_service_config_cpsa_link_type_values, 1048 "Unknown", link_type), 1049 link_type)); 1050 1051 switch (link_type) { 1052 case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH: 1053 ND_PRINT((ndo, "\n\t Signal Type: %s (%u)", 1054 tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values, 1055 "Unknown", 1056 EXTRACT_8BITS(obj_tptr + 1)), 1057 EXTRACT_8BITS(obj_tptr + 1))); 1058 break; 1059 1060 case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET: 1061 ND_PRINT((ndo, "\n\t Signal Type: %s (%u)", 1062 tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values, 1063 "Unknown", 1064 EXTRACT_8BITS(obj_tptr + 1)), 1065 EXTRACT_8BITS(obj_tptr + 1))); 1066 break; 1067 } 1068 1069 ND_PRINT((ndo, "\n\t Transparency: %s", 1070 bittok2str(lmp_obj_service_config_cpsa_tp_flag_values, 1071 "none", 1072 EXTRACT_8BITS(obj_tptr + 2)))); 1073 1074 ND_PRINT((ndo, "\n\t Contiguous Concatenation Types: %s", 1075 bittok2str(lmp_obj_service_config_cpsa_cct_flag_values, 1076 "none", 1077 EXTRACT_8BITS(obj_tptr + 3)))); 1078 1079 ND_PRINT((ndo, "\n\t Minimum NCC: %u", 1080 EXTRACT_16BITS(obj_tptr+4))); 1081 1082 ND_PRINT((ndo, "\n\t Maximum NCC: %u", 1083 EXTRACT_16BITS(obj_tptr+6))); 1084 1085 ND_PRINT((ndo, "\n\t Minimum NVC:%u", 1086 EXTRACT_16BITS(obj_tptr+8))); 1087 1088 ND_PRINT((ndo, "\n\t Maximum NVC:%u", 1089 EXTRACT_16BITS(obj_tptr+10))); 1090 1091 ND_PRINT((ndo, "\n\t Local Interface ID: %s (0x%08x)", 1092 ipaddr_string(ndo, obj_tptr+12), 1093 EXTRACT_32BITS(obj_tptr+12))); 1094 1095 break; 1096 1097 case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM: 1098 if (obj_tlen != 8) { 1099 ND_PRINT((ndo, " (not correct for object)")); 1100 break; 1101 } 1102 1103 ND_PRINT((ndo, "\n\t Transparency Flags: %s", 1104 bittok2str( 1105 lmp_obj_service_config_nsa_transparency_flag_values, 1106 "none", 1107 EXTRACT_32BITS(obj_tptr)))); 1108 1109 ND_PRINT((ndo, "\n\t TCM Monitoring Flags: %s", 1110 bittok2str( 1111 lmp_obj_service_config_nsa_tcm_flag_values, 1112 "none", 1113 EXTRACT_8BITS(obj_tptr + 7)))); 1114 1115 break; 1116 1117 case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY: 1118 if (obj_tlen != 4) { 1119 ND_PRINT((ndo, " (not correct for object)")); 1120 break; 1121 } 1122 1123 ND_PRINT((ndo, "\n\t Diversity: Flags: %s", 1124 bittok2str( 1125 lmp_obj_service_config_nsa_network_diversity_flag_values, 1126 "none", 1127 EXTRACT_8BITS(obj_tptr + 3)))); 1128 break; 1129 1130 default: 1131 hexdump = TRUE; 1132 } 1133 1134 break; 1135 1136 default: 1137 if (ndo->ndo_vflag <= 1) 1138 print_unknown_data(ndo,obj_tptr,"\n\t ",obj_tlen); 1139 break; 1140 } 1141 /* do we want to see an additionally hexdump ? */ 1142 if (ndo->ndo_vflag > 1 || hexdump==TRUE) 1143 print_unknown_data(ndo,tptr+sizeof(struct lmp_object_header),"\n\t ", 1144 lmp_obj_len-sizeof(struct lmp_object_header)); 1145 1146 tptr+=lmp_obj_len; 1147 tlen-=lmp_obj_len; 1148 } 1149 return; 1150 trunc: 1151 ND_PRINT((ndo, "%s", tstr)); 1152 } 1153 /* 1154 * Local Variables: 1155 * c-style: whitesmith 1156 * c-basic-offset: 8 1157 * End: 1158 */ 1159