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