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