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