]> The Tcpdump Group git mirrors - tcpdump/blob - print-lmp.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-lmp.c
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 while (total_subobj_len > 0 && hexdump == FALSE ) {
365 subobj_type = GET_U_1(obj_tptr + offset);
366 subobj_len = GET_U_1(obj_tptr + offset + 1);
367 ND_PRINT("\n\t Subobject, Type: %s (%u), Length: %u",
368 tok2str(lmp_data_link_subobj,
369 "Unknown",
370 subobj_type),
371 subobj_type,
372 subobj_len);
373 if (subobj_len < 4) {
374 ND_PRINT(" (too short)");
375 break;
376 }
377 if ((subobj_len % 4) != 0) {
378 ND_PRINT(" (not a multiple of 4)");
379 break;
380 }
381 if (total_subobj_len < subobj_len) {
382 ND_PRINT(" (goes past the end of the object)");
383 break;
384 }
385 switch(subobj_type) {
386 case INT_SWITCHING_TYPE_SUBOBJ:
387 ND_PRINT("\n\t Switching Type: %s (%u)",
388 tok2str(gmpls_switch_cap_values,
389 "Unknown",
390 GET_U_1(obj_tptr + offset + 2)),
391 GET_U_1(obj_tptr + offset + 2));
392 ND_PRINT("\n\t Encoding Type: %s (%u)",
393 tok2str(gmpls_encoding_values,
394 "Unknown",
395 GET_U_1(obj_tptr + offset + 3)),
396 GET_U_1(obj_tptr + offset + 3));
397 ND_PRINT("\n\t Min Reservable Bandwidth: %.3f Mbps",
398 GET_BE_F_4(obj_tptr + offset + 4)*8/1000000);
399 ND_PRINT("\n\t Max Reservable Bandwidth: %.3f Mbps",
400 GET_BE_F_4(obj_tptr + offset + 8)*8/1000000);
401 break;
402 case WAVELENGTH_SUBOBJ:
403 ND_PRINT("\n\t Wavelength: %u",
404 GET_BE_U_4(obj_tptr + offset + 4));
405 break;
406 default:
407 /* Any Unknown Subobject ==> Exit loop */
408 hexdump=TRUE;
409 break;
410 }
411 total_subobj_len-=subobj_len;
412 offset+=subobj_len;
413 }
414 return (hexdump);
415 }
416
417 void
418 lmp_print(netdissect_options *ndo,
419 const u_char *pptr, u_int length)
420 {
421 const struct lmp_common_header *lmp_com_header;
422 const u_char *tptr,*obj_tptr;
423 u_int version_res, tlen, lmp_obj_len, lmp_obj_ctype, obj_tlen;
424 int hexdump;
425 u_int offset;
426 u_int link_type;
427
428 ndo->ndo_protocol = "lmp";
429 tptr=pptr;
430 lmp_com_header = (const struct lmp_common_header *)pptr;
431 ND_TCHECK_SIZE(lmp_com_header);
432
433 version_res = GET_BE_U_2(lmp_com_header->version_res);
434
435 /*
436 * Sanity checking of the header.
437 */
438 if (LMP_EXTRACT_VERSION(version_res) != LMP_VERSION) {
439 ND_PRINT("LMP version %u packet not supported",
440 LMP_EXTRACT_VERSION(version_res));
441 return;
442 }
443
444 /* in non-verbose mode just lets print the basic Message Type*/
445 if (ndo->ndo_vflag < 1) {
446 ND_PRINT("LMPv%u %s Message, length: %u",
447 LMP_EXTRACT_VERSION(version_res),
448 tok2str(lmp_msg_type_values, "unknown (%u)",GET_U_1(lmp_com_header->msg_type)),
449 length);
450 return;
451 }
452
453 /* ok they seem to want to know everything - lets fully decode it */
454
455 tlen=GET_BE_U_2(lmp_com_header->length);
456
457 ND_PRINT("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u",
458 LMP_EXTRACT_VERSION(version_res),
459 tok2str(lmp_msg_type_values, "unknown, type: %u",GET_U_1(lmp_com_header->msg_type)),
460 bittok2str(lmp_header_flag_values,"none",GET_U_1(lmp_com_header->flags)),
461 tlen);
462 if (tlen < sizeof(struct lmp_common_header)) {
463 ND_PRINT(" (too short)");
464 return;
465 }
466 if (tlen > length) {
467 ND_PRINT(" (too long)");
468 tlen = length;
469 }
470
471 tptr+=sizeof(struct lmp_common_header);
472 tlen-=sizeof(struct lmp_common_header);
473
474 while(tlen != 0) {
475 const struct lmp_object_header *lmp_obj_header =
476 (const struct lmp_object_header *)tptr;
477 lmp_obj_len=GET_BE_U_2(lmp_obj_header->length);
478 lmp_obj_ctype=GET_U_1(lmp_obj_header->ctype)&0x7f;
479
480 ND_PRINT("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
481 tok2str(lmp_obj_values,
482 "Unknown",
483 GET_U_1(lmp_obj_header->class_num)),
484 GET_U_1(lmp_obj_header->class_num),
485 tok2str(lmp_ctype_values,
486 "Unknown",
487 (GET_U_1(lmp_obj_header->class_num)<<8)+lmp_obj_ctype),
488 lmp_obj_ctype,
489 GET_U_1(lmp_obj_header->ctype)&0x80 ? "" : "non-",
490 lmp_obj_len);
491
492 if (lmp_obj_len < 4) {
493 ND_PRINT(" (too short)");
494 return;
495 }
496 if ((lmp_obj_len % 4) != 0) {
497 ND_PRINT(" (not a multiple of 4)");
498 return;
499 }
500
501 obj_tptr=tptr+sizeof(struct lmp_object_header);
502 obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
503
504 /* did we capture enough for fully decoding the object ? */
505 ND_TCHECK_LEN(tptr, lmp_obj_len);
506 hexdump=FALSE;
507
508 switch(GET_U_1(lmp_obj_header->class_num)) {
509
510 case LMP_OBJ_CC_ID:
511 switch(lmp_obj_ctype) {
512 case LMP_CTYPE_LOC:
513 case LMP_CTYPE_RMT:
514 if (obj_tlen != 4) {
515 ND_PRINT(" (not correct for object)");
516 break;
517 }
518 ND_PRINT("\n\t Control Channel ID: %u (0x%08x)",
519 GET_BE_U_4(obj_tptr),
520 GET_BE_U_4(obj_tptr));
521 break;
522
523 default:
524 hexdump=TRUE;
525 }
526 break;
527
528 case LMP_OBJ_LINK_ID:
529 case LMP_OBJ_INTERFACE_ID:
530 switch(lmp_obj_ctype) {
531 case LMP_CTYPE_IPV4_LOC:
532 case LMP_CTYPE_IPV4_RMT:
533 if (obj_tlen != 4) {
534 ND_PRINT(" (not correct for object)");
535 break;
536 }
537 ND_PRINT("\n\t IPv4 Link ID: %s (0x%08x)",
538 GET_IPADDR_STRING(obj_tptr),
539 GET_BE_U_4(obj_tptr));
540 break;
541 case LMP_CTYPE_IPV6_LOC:
542 case LMP_CTYPE_IPV6_RMT:
543 if (obj_tlen != 16) {
544 ND_PRINT(" (not correct for object)");
545 break;
546 }
547 ND_PRINT("\n\t IPv6 Link ID: %s (0x%08x)",
548 GET_IP6ADDR_STRING(obj_tptr),
549 GET_BE_U_4(obj_tptr));
550 break;
551 case LMP_CTYPE_UNMD_LOC:
552 case LMP_CTYPE_UNMD_RMT:
553 if (obj_tlen != 4) {
554 ND_PRINT(" (not correct for object)");
555 break;
556 }
557 ND_PRINT("\n\t Link ID: %u (0x%08x)",
558 GET_BE_U_4(obj_tptr),
559 GET_BE_U_4(obj_tptr));
560 break;
561 default:
562 hexdump=TRUE;
563 }
564 break;
565
566 case LMP_OBJ_MESSAGE_ID:
567 switch(lmp_obj_ctype) {
568 case LMP_CTYPE_1:
569 if (obj_tlen != 4) {
570 ND_PRINT(" (not correct for object)");
571 break;
572 }
573 ND_PRINT("\n\t Message ID: %u (0x%08x)",
574 GET_BE_U_4(obj_tptr),
575 GET_BE_U_4(obj_tptr));
576 break;
577 case LMP_CTYPE_2:
578 if (obj_tlen != 4) {
579 ND_PRINT(" (not correct for object)");
580 break;
581 }
582 ND_PRINT("\n\t Message ID Ack: %u (0x%08x)",
583 GET_BE_U_4(obj_tptr),
584 GET_BE_U_4(obj_tptr));
585 break;
586 default:
587 hexdump=TRUE;
588 }
589 break;
590
591 case LMP_OBJ_NODE_ID:
592 switch(lmp_obj_ctype) {
593 case LMP_CTYPE_LOC:
594 case LMP_CTYPE_RMT:
595 if (obj_tlen != 4) {
596 ND_PRINT(" (not correct for object)");
597 break;
598 }
599 ND_PRINT("\n\t Node ID: %s (0x%08x)",
600 GET_IPADDR_STRING(obj_tptr),
601 GET_BE_U_4(obj_tptr));
602 break;
603
604 default:
605 hexdump=TRUE;
606 }
607 break;
608
609 case LMP_OBJ_CONFIG:
610 switch(lmp_obj_ctype) {
611 case LMP_CTYPE_HELLO_CONFIG:
612 if (obj_tlen != 4) {
613 ND_PRINT(" (not correct for object)");
614 break;
615 }
616 ND_PRINT("\n\t Hello Interval: %u\n\t Hello Dead Interval: %u",
617 GET_BE_U_2(obj_tptr),
618 GET_BE_U_2(obj_tptr + 2));
619 break;
620
621 default:
622 hexdump=TRUE;
623 }
624 break;
625
626 case LMP_OBJ_HELLO:
627 switch(lmp_obj_ctype) {
628 case LMP_CTYPE_HELLO:
629 if (obj_tlen != 8) {
630 ND_PRINT(" (not correct for object)");
631 break;
632 }
633 ND_PRINT("\n\t Tx Seq: %u, Rx Seq: %u",
634 GET_BE_U_4(obj_tptr),
635 GET_BE_U_4(obj_tptr + 4));
636 break;
637
638 default:
639 hexdump=TRUE;
640 }
641 break;
642
643 case LMP_OBJ_TE_LINK:
644 switch(lmp_obj_ctype) {
645 case LMP_CTYPE_IPV4:
646 if (obj_tlen != 12) {
647 ND_PRINT(" (not correct for object)");
648 break;
649 }
650 ND_PRINT("\n\t Flags: [%s]",
651 bittok2str(lmp_obj_te_link_flag_values,
652 "none",
653 GET_U_1(obj_tptr)));
654
655 ND_PRINT("\n\t Local Link-ID: %s (0x%08x)"
656 "\n\t Remote Link-ID: %s (0x%08x)",
657 GET_IPADDR_STRING(obj_tptr+4),
658 GET_BE_U_4(obj_tptr + 4),
659 GET_IPADDR_STRING(obj_tptr+8),
660 GET_BE_U_4(obj_tptr + 8));
661 break;
662
663 case LMP_CTYPE_IPV6:
664 if (obj_tlen != 36) {
665 ND_PRINT(" (not correct for object)");
666 break;
667 }
668 ND_PRINT("\n\t Flags: [%s]",
669 bittok2str(lmp_obj_te_link_flag_values,
670 "none",
671 GET_U_1(obj_tptr)));
672
673 ND_PRINT("\n\t Local Link-ID: %s (0x%08x)"
674 "\n\t Remote Link-ID: %s (0x%08x)",
675 GET_IP6ADDR_STRING(obj_tptr+4),
676 GET_BE_U_4(obj_tptr + 4),
677 GET_IP6ADDR_STRING(obj_tptr+20),
678 GET_BE_U_4(obj_tptr + 20));
679 break;
680
681 case LMP_CTYPE_UNMD:
682 if (obj_tlen != 12) {
683 ND_PRINT(" (not correct for object)");
684 break;
685 }
686 ND_PRINT("\n\t Flags: [%s]",
687 bittok2str(lmp_obj_te_link_flag_values,
688 "none",
689 GET_U_1(obj_tptr)));
690
691 ND_PRINT("\n\t Local Link-ID: %u (0x%08x)"
692 "\n\t Remote Link-ID: %u (0x%08x)",
693 GET_BE_U_4(obj_tptr + 4),
694 GET_BE_U_4(obj_tptr + 4),
695 GET_BE_U_4(obj_tptr + 8),
696 GET_BE_U_4(obj_tptr + 8));
697 break;
698
699 default:
700 hexdump=TRUE;
701 }
702 break;
703
704 case LMP_OBJ_DATA_LINK:
705 switch(lmp_obj_ctype) {
706 case LMP_CTYPE_IPV4:
707 if (obj_tlen < 12) {
708 ND_PRINT(" (not correct for object)");
709 break;
710 }
711 ND_PRINT("\n\t Flags: [%s]",
712 bittok2str(lmp_obj_data_link_flag_values,
713 "none",
714 GET_U_1(obj_tptr)));
715 ND_PRINT("\n\t Local Interface ID: %s (0x%08x)"
716 "\n\t Remote Interface ID: %s (0x%08x)",
717 GET_IPADDR_STRING(obj_tptr+4),
718 GET_BE_U_4(obj_tptr + 4),
719 GET_IPADDR_STRING(obj_tptr+8),
720 GET_BE_U_4(obj_tptr + 8));
721
722 if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
723 hexdump=TRUE;
724 break;
725
726 case LMP_CTYPE_IPV6:
727 if (obj_tlen < 36) {
728 ND_PRINT(" (not correct for object)");
729 break;
730 }
731 ND_PRINT("\n\t Flags: [%s]",
732 bittok2str(lmp_obj_data_link_flag_values,
733 "none",
734 GET_U_1(obj_tptr)));
735 ND_PRINT("\n\t Local Interface ID: %s (0x%08x)"
736 "\n\t Remote Interface ID: %s (0x%08x)",
737 GET_IP6ADDR_STRING(obj_tptr+4),
738 GET_BE_U_4(obj_tptr + 4),
739 GET_IP6ADDR_STRING(obj_tptr+20),
740 GET_BE_U_4(obj_tptr + 20));
741
742 if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 36, 36))
743 hexdump=TRUE;
744 break;
745
746 case LMP_CTYPE_UNMD:
747 if (obj_tlen < 12) {
748 ND_PRINT(" (not correct for object)");
749 break;
750 }
751 ND_PRINT("\n\t Flags: [%s]",
752 bittok2str(lmp_obj_data_link_flag_values,
753 "none",
754 GET_U_1(obj_tptr)));
755 ND_PRINT("\n\t Local Interface ID: %u (0x%08x)"
756 "\n\t Remote Interface ID: %u (0x%08x)",
757 GET_BE_U_4(obj_tptr + 4),
758 GET_BE_U_4(obj_tptr + 4),
759 GET_BE_U_4(obj_tptr + 8),
760 GET_BE_U_4(obj_tptr + 8));
761
762 if (lmp_print_data_link_subobjs(ndo, obj_tptr, obj_tlen - 12, 12))
763 hexdump=TRUE;
764 break;
765
766 default:
767 hexdump=TRUE;
768 }
769 break;
770
771 case LMP_OBJ_VERIFY_BEGIN:
772 switch(lmp_obj_ctype) {
773 case LMP_CTYPE_1:
774 if (obj_tlen != 20) {
775 ND_PRINT(" (not correct for object)");
776 break;
777 }
778 ND_PRINT("\n\t Flags: %s",
779 bittok2str(lmp_obj_begin_verify_flag_values,
780 "none",
781 GET_BE_U_2(obj_tptr)));
782 ND_PRINT("\n\t Verify Interval: %u",
783 GET_BE_U_2(obj_tptr + 2));
784 ND_PRINT("\n\t Data links: %u",
785 GET_BE_U_4(obj_tptr + 4));
786 ND_PRINT("\n\t Encoding type: %s",
787 tok2str(gmpls_encoding_values, "Unknown", GET_U_1((obj_tptr + 8))));
788 ND_PRINT("\n\t Verify Transport Mechanism: %u (0x%x)%s",
789 GET_BE_U_2(obj_tptr + 10),
790 GET_BE_U_2(obj_tptr + 10),
791 GET_BE_U_2(obj_tptr + 10)&8000 ? " (Payload test messages capable)" : "");
792 ND_PRINT("\n\t Transmission Rate: %.3f Mbps",
793 GET_BE_F_4(obj_tptr + 12)*8/1000000);
794 ND_PRINT("\n\t Wavelength: %u",
795 GET_BE_U_4(obj_tptr + 16));
796 break;
797
798 default:
799 hexdump=TRUE;
800 }
801 break;
802
803 case LMP_OBJ_VERIFY_BEGIN_ACK:
804 switch(lmp_obj_ctype) {
805 case LMP_CTYPE_1:
806 if (obj_tlen != 4) {
807 ND_PRINT(" (not correct for object)");
808 break;
809 }
810 ND_PRINT("\n\t Verify Dead Interval: %u"
811 "\n\t Verify Transport Response: %u",
812 GET_BE_U_2(obj_tptr),
813 GET_BE_U_2(obj_tptr + 2));
814 break;
815
816 default:
817 hexdump=TRUE;
818 }
819 break;
820
821 case LMP_OBJ_VERIFY_ID:
822 switch(lmp_obj_ctype) {
823 case LMP_CTYPE_1:
824 if (obj_tlen != 4) {
825 ND_PRINT(" (not correct for object)");
826 break;
827 }
828 ND_PRINT("\n\t Verify ID: %u",
829 GET_BE_U_4(obj_tptr));
830 break;
831
832 default:
833 hexdump=TRUE;
834 }
835 break;
836
837 case LMP_OBJ_CHANNEL_STATUS:
838 switch(lmp_obj_ctype) {
839 case LMP_CTYPE_IPV4:
840 offset = 0;
841 /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
842 while (offset+8 <= obj_tlen) {
843 ND_PRINT("\n\t Interface ID: %s (0x%08x)",
844 GET_IPADDR_STRING(obj_tptr+offset),
845 GET_BE_U_4(obj_tptr + offset));
846
847 ND_PRINT("\n\t\t Active: %s (%u)",
848 (GET_BE_U_4(obj_tptr + offset + 4)>>31) ?
849 "Allocated" : "Non-allocated",
850 (GET_BE_U_4(obj_tptr + offset + 4)>>31));
851
852 ND_PRINT("\n\t\t Direction: %s (%u)",
853 (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1 ?
854 "Transmit" : "Receive",
855 (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1);
856
857 ND_PRINT("\n\t\t Channel Status: %s (%u)",
858 tok2str(lmp_obj_channel_status_values,
859 "Unknown",
860 GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF),
861 GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF);
862 offset+=8;
863 }
864 break;
865
866 case LMP_CTYPE_IPV6:
867 offset = 0;
868 /* Decode pairs: <Interface_ID (16 bytes), Channel_status (4 bytes)> */
869 while (offset+20 <= obj_tlen) {
870 ND_PRINT("\n\t Interface ID: %s (0x%08x)",
871 GET_IP6ADDR_STRING(obj_tptr+offset),
872 GET_BE_U_4(obj_tptr + offset));
873
874 ND_PRINT("\n\t\t Active: %s (%u)",
875 (GET_BE_U_4(obj_tptr + offset + 16)>>31) ?
876 "Allocated" : "Non-allocated",
877 (GET_BE_U_4(obj_tptr + offset + 16)>>31));
878
879 ND_PRINT("\n\t\t Direction: %s (%u)",
880 (GET_BE_U_4(obj_tptr + offset + 16)>>30)&0x1 ?
881 "Transmit" : "Receive",
882 (GET_BE_U_4(obj_tptr + offset + 16)>>30)&0x1);
883
884 ND_PRINT("\n\t\t Channel Status: %s (%u)",
885 tok2str(lmp_obj_channel_status_values,
886 "Unknown",
887 GET_BE_U_4(obj_tptr + offset + 16)&0x3FFFFFF),
888 GET_BE_U_4(obj_tptr + offset + 16)&0x3FFFFFF);
889 offset+=20;
890 }
891 break;
892
893 case LMP_CTYPE_UNMD:
894 offset = 0;
895 /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
896 while (offset+8 <= obj_tlen) {
897 ND_PRINT("\n\t Interface ID: %u (0x%08x)",
898 GET_BE_U_4(obj_tptr + offset),
899 GET_BE_U_4(obj_tptr + offset));
900
901 ND_PRINT("\n\t\t Active: %s (%u)",
902 (GET_BE_U_4(obj_tptr + offset + 4)>>31) ?
903 "Allocated" : "Non-allocated",
904 (GET_BE_U_4(obj_tptr + offset + 4)>>31));
905
906 ND_PRINT("\n\t\t Direction: %s (%u)",
907 (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1 ?
908 "Transmit" : "Receive",
909 (GET_BE_U_4(obj_tptr + offset + 4)>>30)&0x1);
910
911 ND_PRINT("\n\t\t Channel Status: %s (%u)",
912 tok2str(lmp_obj_channel_status_values,
913 "Unknown",
914 GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF),
915 GET_BE_U_4(obj_tptr + offset + 4)&0x3FFFFFF);
916 offset+=8;
917 }
918 break;
919
920 default:
921 hexdump=TRUE;
922 }
923 break;
924
925 case LMP_OBJ_CHANNEL_STATUS_REQ:
926 switch(lmp_obj_ctype) {
927 case LMP_CTYPE_IPV4:
928 offset = 0;
929 while (offset+4 <= obj_tlen) {
930 ND_PRINT("\n\t Interface ID: %s (0x%08x)",
931 GET_IPADDR_STRING(obj_tptr+offset),
932 GET_BE_U_4(obj_tptr + offset));
933 offset+=4;
934 }
935 break;
936
937 case LMP_CTYPE_IPV6:
938 offset = 0;
939 while (offset+16 <= obj_tlen) {
940 ND_PRINT("\n\t Interface ID: %s (0x%08x)",
941 GET_IP6ADDR_STRING(obj_tptr+offset),
942 GET_BE_U_4(obj_tptr + offset));
943 offset+=16;
944 }
945 break;
946
947 case LMP_CTYPE_UNMD:
948 offset = 0;
949 while (offset+4 <= obj_tlen) {
950 ND_PRINT("\n\t Interface ID: %u (0x%08x)",
951 GET_BE_U_4(obj_tptr + offset),
952 GET_BE_U_4(obj_tptr + offset));
953 offset+=4;
954 }
955 break;
956
957 default:
958 hexdump=TRUE;
959 }
960 break;
961
962 case LMP_OBJ_ERROR_CODE:
963 switch(lmp_obj_ctype) {
964 case LMP_CTYPE_BEGIN_VERIFY_ERROR:
965 if (obj_tlen != 4) {
966 ND_PRINT(" (not correct for object)");
967 break;
968 }
969 ND_PRINT("\n\t Error Code: %s",
970 bittok2str(lmp_obj_begin_verify_error_values,
971 "none",
972 GET_BE_U_4(obj_tptr)));
973 break;
974
975 case LMP_CTYPE_LINK_SUMMARY_ERROR:
976 if (obj_tlen != 4) {
977 ND_PRINT(" (not correct for object)");
978 break;
979 }
980 ND_PRINT("\n\t Error Code: %s",
981 bittok2str(lmp_obj_link_summary_error_values,
982 "none",
983 GET_BE_U_4(obj_tptr)));
984 break;
985 default:
986 hexdump=TRUE;
987 }
988 break;
989
990 case LMP_OBJ_SERVICE_CONFIG:
991 switch (lmp_obj_ctype) {
992 case LMP_CTYPE_SERVICE_CONFIG_SP:
993 if (obj_tlen != 4) {
994 ND_PRINT(" (not correct for object)");
995 break;
996 }
997 ND_PRINT("\n\t Flags: %s",
998 bittok2str(lmp_obj_service_config_sp_flag_values,
999 "none",
1000 GET_U_1(obj_tptr)));
1001
1002 ND_PRINT("\n\t UNI Version: %u",
1003 GET_U_1(obj_tptr + 1));
1004
1005 break;
1006
1007 case LMP_CTYPE_SERVICE_CONFIG_CPSA:
1008 if (obj_tlen != 16) {
1009 ND_PRINT(" (not correct for object)");
1010 break;
1011 }
1012
1013 link_type = GET_U_1(obj_tptr);
1014
1015 ND_PRINT("\n\t Link Type: %s (%u)",
1016 tok2str(lmp_sd_service_config_cpsa_link_type_values,
1017 "Unknown", link_type),
1018 link_type);
1019
1020 switch (link_type) {
1021 case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH:
1022 ND_PRINT("\n\t Signal Type: %s (%u)",
1023 tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
1024 "Unknown",
1025 GET_U_1(obj_tptr + 1)),
1026 GET_U_1(obj_tptr + 1));
1027 break;
1028
1029 case LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET:
1030 ND_PRINT("\n\t Signal Type: %s (%u)",
1031 tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
1032 "Unknown",
1033 GET_U_1(obj_tptr + 1)),
1034 GET_U_1(obj_tptr + 1));
1035 break;
1036 }
1037
1038 ND_PRINT("\n\t Transparency: %s",
1039 bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
1040 "none",
1041 GET_U_1(obj_tptr + 2)));
1042
1043 ND_PRINT("\n\t Contiguous Concatenation Types: %s",
1044 bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
1045 "none",
1046 GET_U_1(obj_tptr + 3)));
1047
1048 ND_PRINT("\n\t Minimum NCC: %u",
1049 GET_BE_U_2(obj_tptr + 4));
1050
1051 ND_PRINT("\n\t Maximum NCC: %u",
1052 GET_BE_U_2(obj_tptr + 6));
1053
1054 ND_PRINT("\n\t Minimum NVC:%u",
1055 GET_BE_U_2(obj_tptr + 8));
1056
1057 ND_PRINT("\n\t Maximum NVC:%u",
1058 GET_BE_U_2(obj_tptr + 10));
1059
1060 ND_PRINT("\n\t Local Interface ID: %s (0x%08x)",
1061 GET_IPADDR_STRING(obj_tptr+12),
1062 GET_BE_U_4(obj_tptr + 12));
1063
1064 break;
1065
1066 case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
1067 if (obj_tlen != 8) {
1068 ND_PRINT(" (not correct for object)");
1069 break;
1070 }
1071
1072 ND_PRINT("\n\t Transparency Flags: %s",
1073 bittok2str(
1074 lmp_obj_service_config_nsa_transparency_flag_values,
1075 "none",
1076 GET_BE_U_4(obj_tptr)));
1077
1078 ND_PRINT("\n\t TCM Monitoring Flags: %s",
1079 bittok2str(
1080 lmp_obj_service_config_nsa_tcm_flag_values,
1081 "none",
1082 GET_U_1(obj_tptr + 7)));
1083
1084 break;
1085
1086 case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
1087 if (obj_tlen != 4) {
1088 ND_PRINT(" (not correct for object)");
1089 break;
1090 }
1091
1092 ND_PRINT("\n\t Diversity: Flags: %s",
1093 bittok2str(
1094 lmp_obj_service_config_nsa_network_diversity_flag_values,
1095 "none",
1096 GET_U_1(obj_tptr + 3)));
1097 break;
1098
1099 default:
1100 hexdump = TRUE;
1101 }
1102
1103 break;
1104
1105 default:
1106 if (ndo->ndo_vflag <= 1)
1107 print_unknown_data(ndo,obj_tptr,"\n\t ",obj_tlen);
1108 break;
1109 }
1110 /* do we want to see an additionally hexdump ? */
1111 if (ndo->ndo_vflag > 1 || hexdump==TRUE)
1112 print_unknown_data(ndo,tptr+sizeof(struct lmp_object_header),"\n\t ",
1113 lmp_obj_len-sizeof(struct lmp_object_header));
1114
1115 if (tlen < lmp_obj_len) {
1116 ND_PRINT(" [remaining objects length %u < %u]", tlen, lmp_obj_len);
1117 nd_print_invalid(ndo);
1118 break;
1119 }
1120 tptr+=lmp_obj_len;
1121 tlen-=lmp_obj_len;
1122 }
1123 }