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