print-lmp.c revision 147899
1146773Ssam/*
2146773Ssam * Redistribution and use in source and binary forms, with or without
3146773Ssam * modification, are permitted provided that: (1) source code
4146773Ssam * distributions retain the above copyright notice and this paragraph
5146773Ssam * in its entirety, and (2) distributions including binary code include
6146773Ssam * the above copyright notice and this paragraph in its entirety in
7146773Ssam * the documentation or other materials provided with the distribution.
8146773Ssam * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9146773Ssam * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10146773Ssam * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11146773Ssam * FOR A PARTICULAR PURPOSE.
12146773Ssam *
13146773Ssam * Original code by Hannes Gredler (hannes@juniper.net)
14147899Ssam * Support for LMP service discovery extensions (defined by UNI 1.0) added
15147899Ssam * by Manu Pathak (mapathak@cisco.com), May 2005
16146773Ssam */
17146773Ssam
18146773Ssam#ifndef lint
19146773Ssamstatic const char rcsid[] _U_ =
20147899Ssam    "@(#) $Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.5.2.1 2005/05/19 06:44:03 guy Exp $";
21146773Ssam#endif
22146773Ssam
23146773Ssam#ifdef HAVE_CONFIG_H
24146773Ssam#include "config.h"
25146773Ssam#endif
26146773Ssam
27146773Ssam#include <tcpdump-stdinc.h>
28146773Ssam
29146773Ssam#include <stdio.h>
30146773Ssam#include <stdlib.h>
31146773Ssam#include <string.h>
32146773Ssam
33146773Ssam#include "interface.h"
34146773Ssam#include "extract.h"
35146773Ssam#include "addrtoname.h"
36146773Ssam#include "gmpls.h"
37146773Ssam
38146773Ssam/*
39146773Ssam * LMP common header
40146773Ssam *
41146773Ssam *  0                   1                   2                   3
42146773Ssam *  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
43146773Ssam * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44146773Ssam * | Vers  |      (Reserved)       |    Flags      |    Msg Type   |
45146773Ssam * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46146773Ssam * |          LMP Length           |          (Reserved)           |
47146773Ssam * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48146773Ssam */
49146773Ssam
50146773Ssamstruct lmp_common_header {
51146773Ssam    u_int8_t version_res[2];
52146773Ssam    u_int8_t flags;
53146773Ssam    u_int8_t msg_type;
54146773Ssam    u_int8_t length[2];
55146773Ssam    u_int8_t reserved[2];
56146773Ssam};
57146773Ssam
58146773Ssam#define LMP_VERSION            1
59146773Ssam#define	LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
60146773Ssam
61146773Ssamstatic const struct tok lmp_header_flag_values[] = {
62146773Ssam    { 0x00, "Control Channel Down"},
63146773Ssam    { 0x02, "LMP restart"},
64146773Ssam    { 0, NULL}
65146773Ssam};
66146773Ssam
67146773Ssamstatic const struct tok lmp_obj_te_link_flag_values[] = {
68146773Ssam    { 0x01, "Fault Management Supported"},
69146773Ssam    { 0x02, "Link Verification Supported"},
70146773Ssam    { 0, NULL}
71146773Ssam};
72146773Ssam
73146773Ssamstatic const struct tok lmp_obj_data_link_flag_values[] = {
74146773Ssam    { 0x01, "Data Link Port"},
75146773Ssam    { 0x02, "Allocated for user traffic"},
76146773Ssam    { 0x04, "Failed link"},
77146773Ssam    { 0, NULL}
78146773Ssam};
79146773Ssam
80146773Ssamstatic const struct tok lmp_obj_channel_status_values[] = {
81146773Ssam    { 1, "Signal Okay"},
82146773Ssam    { 2, "Signal Degraded"},
83146773Ssam    { 3, "Signal Fail"},
84146773Ssam    { 0, NULL}
85146773Ssam};
86146773Ssam
87146773Ssamstatic const struct tok lmp_obj_begin_verify_flag_values[] = {
88146773Ssam    { 0x0001, "Verify all links"},
89146773Ssam    { 0x0002, "Data link type"},
90146773Ssam    { 0, NULL}
91146773Ssam};
92146773Ssam
93146773Ssamstatic const struct tok lmp_obj_begin_verify_error_values[] = {
94146773Ssam    { 0x01, "\n\t\tLink Verification Procedure Not supported"},
95146773Ssam    { 0x02, "\n\t\tUnwilling to verify"},
96146773Ssam    { 0x04, "\n\t\tUnsupported verification transport mechanism"},
97146773Ssam    { 0x08, "\n\t\tLink_Id configuration error"},
98146773Ssam    { 0x10, "\n\t\tUnknown object c-type"},
99146773Ssam    { 0, NULL}
100146773Ssam};
101146773Ssam
102146773Ssamstatic const struct tok lmp_obj_link_summary_error_values[] = {
103146773Ssam    { 0x01, "\n\t\tUnacceptable non-negotiable LINK_SUMMARY parameters"},
104146773Ssam    { 0x02, "\n\t\tRenegotiate LINK_SUMMARY parameters"},
105146773Ssam    { 0x04, "\n\t\tInvalid TE-LINK Object"},
106146773Ssam    { 0x08, "\n\t\tInvalid DATA-LINK Object"},
107146773Ssam    { 0x10, "\n\t\tUnknown TE-LINK Object c-type"},
108146773Ssam    { 0x20, "\n\t\tUnknown DATA-LINK Object c-type"},
109146773Ssam    { 0, NULL}
110146773Ssam};
111146773Ssam
112147899Ssam/* Service Config Supported Protocols Flags */
113147899Ssamstatic const struct tok lmp_obj_service_config_sp_flag_values[] = {
114147899Ssam    { 0x01, "RSVP Supported"},
115147899Ssam    { 0x02, "LDP Supported"},
116147899Ssam    { 0, NULL}
117147899Ssam};
118147899Ssam
119147899Ssam/* Service Config Client Port Service Attribute Transparency Flags */
120147899Ssamstatic const struct tok lmp_obj_service_config_cpsa_tp_flag_values[] = {
121147899Ssam    { 0x01, "Path/VC Overhead Transparency Supported"},
122147899Ssam    { 0x02, "Line/MS Overhead Transparency Supported"},
123147899Ssam    { 0x04, "Section/RS Overhead Transparency Supported"},
124147899Ssam    { 0, NULL}
125147899Ssam};
126147899Ssam
127147899Ssam/* Service Config Client Port Service Attribute Contiguous Concatenation Types Flags */
128147899Ssamstatic const struct tok lmp_obj_service_config_cpsa_cct_flag_values[] = {
129147899Ssam    { 0x01, "Contiguous Concatenation Types Supported"},
130147899Ssam    { 0, NULL}
131147899Ssam};
132147899Ssam
133147899Ssam/* Service Config Network Service Attributes Transparency Flags */
134147899Ssamstatic const struct tok lmp_obj_service_config_nsa_transparency_flag_values[] = {
135147899Ssam    { 0x01, "Standard SOH/RSOH Transparency Supported"},
136147899Ssam    { 0x02, "Standard LOH/MSOH Transparency Supported"},
137147899Ssam    { 0, NULL}
138147899Ssam};
139147899Ssam
140147899Ssam/* Service Config Network Service Attributes TCM Monitoring Flags */
141147899Ssamstatic const struct tok lmp_obj_service_config_nsa_tcm_flag_values[] = {
142147899Ssam    { 0x01, "Transparent Tandem Connection Monitoring Supported"},
143147899Ssam    { 0, NULL}
144147899Ssam};
145147899Ssam
146147899Ssam/* Network Service Attributes Network Diversity Flags */
147147899Ssamstatic const struct tok lmp_obj_service_config_nsa_network_diversity_flag_values[] = {
148147899Ssam    { 0x01, "Node Diversity Supported"},
149147899Ssam    { 0x02, "Link Diversity Supported"},
150147899Ssam    { 0x04, "SRLG Diversity Supported"},
151147899Ssam    { 0, NULL}
152147899Ssam};
153147899Ssam
154146773Ssam#define	LMP_MSGTYPE_CONFIG                 1
155146773Ssam#define	LMP_MSGTYPE_CONFIG_ACK             2
156146773Ssam#define	LMP_MSGTYPE_CONFIG_NACK            3
157146773Ssam#define	LMP_MSGTYPE_HELLO                  4
158146773Ssam#define	LMP_MSGTYPE_VERIFY_BEGIN           5
159146773Ssam#define	LMP_MSGTYPE_VERIFY_BEGIN_ACK       6
160146773Ssam#define	LMP_MSGTYPE_VERIFY_BEGIN_NACK      7
161146773Ssam#define LMP_MSGTYPE_VERIFY_END             8
162146773Ssam#define LMP_MSGTYPE_VERIFY_END_ACK         9
163146773Ssam#define LMP_MSGTYPE_TEST                  10
164146773Ssam#define LMP_MSGTYPE_TEST_STATUS_SUCCESS   11
165146773Ssam#define	LMP_MSGTYPE_TEST_STATUS_FAILURE   12
166146773Ssam#define	LMP_MSGTYPE_TEST_STATUS_ACK       13
167146773Ssam#define	LMP_MSGTYPE_LINK_SUMMARY          14
168146773Ssam#define	LMP_MSGTYPE_LINK_SUMMARY_ACK      15
169146773Ssam#define	LMP_MSGTYPE_LINK_SUMMARY_NACK     16
170146773Ssam#define	LMP_MSGTYPE_CHANNEL_STATUS        17
171146773Ssam#define	LMP_MSGTYPE_CHANNEL_STATUS_ACK    18
172146773Ssam#define	LMP_MSGTYPE_CHANNEL_STATUS_REQ    19
173146773Ssam#define	LMP_MSGTYPE_CHANNEL_STATUS_RESP   20
174147899Ssam/* LMP Service Discovery message types defined by UNI 1.0 */
175147899Ssam#define LMP_MSGTYPE_SERVICE_CONFIG        50
176147899Ssam#define LMP_MSGTYPE_SERVICE_CONFIG_ACK    51
177147899Ssam#define LMP_MSGTYPE_SERVICE_CONFIG_NACK   52
178146773Ssam
179146773Ssamstatic const struct tok lmp_msg_type_values[] = {
180146773Ssam    { LMP_MSGTYPE_CONFIG, "Config"},
181146773Ssam    { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"},
182146773Ssam    { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"},
183146773Ssam    { LMP_MSGTYPE_HELLO, "Hello"},
184146773Ssam    { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"},
185146773Ssam    { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"},
186146773Ssam    { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"},
187146773Ssam    { LMP_MSGTYPE_VERIFY_END, "End Verify"},
188146773Ssam    { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"},
189146773Ssam    { LMP_MSGTYPE_TEST, "Test"},
190146773Ssam    { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"},
191146773Ssam    { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"},
192146773Ssam    { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"},
193146773Ssam    { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"},
194146773Ssam    { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"},
195146773Ssam    { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"},
196146773Ssam    { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"},
197146773Ssam    { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"},
198146773Ssam    { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"},
199146773Ssam    { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"},
200147899Ssam    { LMP_MSGTYPE_SERVICE_CONFIG, "Service Config"},
201147899Ssam    { LMP_MSGTYPE_SERVICE_CONFIG_ACK, "Service Config ACK"},
202147899Ssam    { LMP_MSGTYPE_SERVICE_CONFIG_NACK, "Service Config NACK"},
203146773Ssam    { 0, NULL}
204146773Ssam};
205146773Ssam
206146773Ssam/*
207146773Ssam * LMP object header
208146773Ssam *
209146773Ssam *  0                   1                   2                   3
210146773Ssam *  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
211146773Ssam * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
212146773Ssam * |N|   C-Type    |     Class     |            Length             |
213146773Ssam * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
214146773Ssam * |                                                               |
215146773Ssam * //                       (object contents)                     //
216146773Ssam * |                                                               |
217146773Ssam * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218146773Ssam */
219146773Ssam
220146773Ssamstruct lmp_object_header {
221146773Ssam    u_int8_t ctype;
222146773Ssam    u_int8_t class_num;
223146773Ssam    u_int8_t length[2];
224146773Ssam};
225146773Ssam
226146773Ssam#define	LMP_OBJ_CC_ID                 1
227146773Ssam#define	LMP_OBJ_NODE_ID               2
228146773Ssam#define	LMP_OBJ_LINK_ID               3
229146773Ssam#define	LMP_OBJ_INTERFACE_ID          4
230146773Ssam#define	LMP_OBJ_MESSAGE_ID            5
231146773Ssam#define	LMP_OBJ_CONFIG                6
232146773Ssam#define	LMP_OBJ_HELLO                 7
233146773Ssam#define	LMP_OBJ_VERIFY_BEGIN          8
234146773Ssam#define LMP_OBJ_VERIFY_BEGIN_ACK      9
235146773Ssam#define LMP_OBJ_VERIFY_ID            10
236146773Ssam#define LMP_OBJ_TE_LINK              11
237146773Ssam#define LMP_OBJ_DATA_LINK            12
238146773Ssam#define LMP_OBJ_CHANNEL_STATUS       13
239146773Ssam#define LMP_OBJ_CHANNEL_STATUS_REQ   14
240146773Ssam#define LMP_OBJ_ERROR_CODE           20
241146773Ssam
242147899Ssam#define LMP_OBJ_SERVICE_CONFIG       51 /* defined in UNI 1.0 */
243147899Ssam
244146773Ssamstatic const struct tok lmp_obj_values[] = {
245146773Ssam    { LMP_OBJ_CC_ID, "Control Channel ID" },
246146773Ssam    { LMP_OBJ_NODE_ID, "Node ID" },
247146773Ssam    { LMP_OBJ_LINK_ID, "Link ID" },
248146773Ssam    { LMP_OBJ_INTERFACE_ID, "Interface ID" },
249146773Ssam    { LMP_OBJ_MESSAGE_ID, "Message ID" },
250146773Ssam    { LMP_OBJ_CONFIG, "Configuration" },
251146773Ssam    { LMP_OBJ_HELLO, "Hello" },
252146773Ssam    { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" },
253146773Ssam    { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" },
254146773Ssam    { LMP_OBJ_VERIFY_ID, "Verify ID" },
255146773Ssam    { LMP_OBJ_TE_LINK, "TE Link" },
256146773Ssam    { LMP_OBJ_DATA_LINK, "Data Link" },
257146773Ssam    { LMP_OBJ_CHANNEL_STATUS, "Channel Status" },
258146773Ssam    { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" },
259146773Ssam    { LMP_OBJ_ERROR_CODE, "Error Code" },
260147899Ssam    { LMP_OBJ_SERVICE_CONFIG, "Service Config" },
261147899Ssam
262146773Ssam    { 0, NULL}
263146773Ssam};
264146773Ssam
265146773Ssam#define INT_SWITCHING_TYPE_SUBOBJ 1
266146773Ssam#define WAVELENGTH_SUBOBJ         2
267146773Ssam
268146773Ssamstatic const struct tok lmp_data_link_subobj[] = {
269146773Ssam    { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" },
270146773Ssam    { WAVELENGTH_SUBOBJ        , "Wavelength" },
271146773Ssam    { 0, NULL}
272146773Ssam};
273146773Ssam
274146773Ssam#define	LMP_CTYPE_IPV4       1
275146773Ssam#define	LMP_CTYPE_IPV6       2
276146773Ssam
277146773Ssam#define	LMP_CTYPE_LOC        1
278146773Ssam#define	LMP_CTYPE_RMT        2
279146773Ssam#define	LMP_CTYPE_UNMD       3
280146773Ssam
281146773Ssam#define	LMP_CTYPE_IPV4_LOC   1
282146773Ssam#define	LMP_CTYPE_IPV4_RMT   2
283146773Ssam#define	LMP_CTYPE_IPV6_LOC   3
284146773Ssam#define	LMP_CTYPE_IPV6_RMT   4
285146773Ssam#define	LMP_CTYPE_UNMD_LOC   5
286146773Ssam#define	LMP_CTYPE_UNMD_RMT   6
287146773Ssam
288146773Ssam#define	LMP_CTYPE_1          1
289146773Ssam#define	LMP_CTYPE_2          2
290146773Ssam
291146773Ssam#define LMP_CTYPE_HELLO_CONFIG  1
292146773Ssam#define LMP_CTYPE_HELLO         1
293146773Ssam
294146773Ssam#define LMP_CTYPE_BEGIN_VERIFY_ERROR 1
295146773Ssam#define LMP_CTYPE_LINK_SUMMARY_ERROR 2
296146773Ssam
297147899Ssam/* C-Types for Service Config Object */
298147899Ssam#define LMP_CTYPE_SERVICE_CONFIG_SP                   1
299147899Ssam#define LMP_CTYPE_SERVICE_CONFIG_CPSA                 2
300147899Ssam#define LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM     3
301147899Ssam#define LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY    4
302147899Ssam
303147899Ssam/*
304147899Ssam * Different link types allowed in the Client Port Service Attributes
305147899Ssam * subobject defined for LMP Service Discovery in the UNI 1.0 spec
306147899Ssam */
307147899Ssam#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH     5 /* UNI 1.0 Sec 9.4.2 */
308147899Ssam#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET   6 /* UNI 1.0 Sec 9.4.2 */
309147899Ssam
310146773Ssam#define FALSE 0
311146773Ssam#define TRUE  1
312146773Ssam
313146773Ssam/*
314146773Ssam * the ctypes are not globally unique so for
315146773Ssam * translating it to strings we build a table based
316146773Ssam * on objects offsetted by the ctype
317146773Ssam */
318146773Ssam
319146773Ssamstatic const struct tok lmp_ctype_values[] = {
320146773Ssam    { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" },
321146773Ssam    { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" },
322146773Ssam    { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" },
323146773Ssam    { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" },
324146773Ssam    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" },
325146773Ssam    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" },
326146773Ssam    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" },
327146773Ssam    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" },
328146773Ssam    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" },
329146773Ssam    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" },
330146773Ssam    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" },
331146773Ssam    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" },
332146773Ssam    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" },
333146773Ssam    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" },
334146773Ssam    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" },
335146773Ssam    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" },
336146773Ssam    { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" },
337146773Ssam    { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" },
338146773Ssam    { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" },
339146773Ssam    { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" },
340146773Ssam    { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" },
341146773Ssam    { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" },
342146773Ssam    { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" },
343146773Ssam    { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" },
344146773Ssam    { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" },
345146773Ssam    { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" },
346146773Ssam    { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" },
347146773Ssam    { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" },
348146773Ssam    { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" },
349146773Ssam    { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" },
350146773Ssam    { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" },
351146773Ssam    { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" },
352146773Ssam    { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" },
353146773Ssam    { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" },
354146773Ssam    { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" },
355146773Ssam    { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" },
356146773Ssam    { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" },
357147899Ssam    { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_SP, "1" },
358147899Ssam    { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_CPSA, "2" },
359147899Ssam    { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM, "3" },
360147899Ssam    { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY, "4" },
361146773Ssam    { 0, NULL}
362146773Ssam};
363146773Ssam
364146773Ssamvoid
365146773Ssamlmp_print(register const u_char *pptr, register u_int len) {
366146773Ssam
367146773Ssam    const struct lmp_common_header *lmp_com_header;
368146773Ssam    const struct lmp_object_header *lmp_obj_header;
369146773Ssam    const u_char *tptr,*obj_tptr;
370146773Ssam    int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
371146773Ssam    int hexdump;
372146773Ssam    int offset,subobj_type,subobj_len,total_subobj_len;
373147899Ssam    int link_type;
374146773Ssam
375146773Ssam    union { /* int to float conversion buffer */
376146773Ssam        float f;
377146773Ssam        u_int32_t i;
378146773Ssam    } bw;
379146773Ssam
380146773Ssam    tptr=pptr;
381146773Ssam    lmp_com_header = (const struct lmp_common_header *)pptr;
382146773Ssam    TCHECK(*lmp_com_header);
383146773Ssam
384146773Ssam    /*
385146773Ssam     * Sanity checking of the header.
386146773Ssam     */
387146773Ssam    if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) {
388146773Ssam	printf("LMP version %u packet not supported",
389146773Ssam               LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]));
390146773Ssam	return;
391146773Ssam    }
392146773Ssam
393146773Ssam    /* in non-verbose mode just lets print the basic Message Type*/
394146773Ssam    if (vflag < 1) {
395146773Ssam        printf("LMPv%u %s Message, length: %u",
396146773Ssam               LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]),
397146773Ssam               tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type),
398146773Ssam               len);
399146773Ssam        return;
400146773Ssam    }
401146773Ssam
402146773Ssam    /* ok they seem to want to know everything - lets fully decode it */
403146773Ssam
404146773Ssam    tlen=EXTRACT_16BITS(lmp_com_header->length);
405146773Ssam
406146773Ssam    printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u",
407146773Ssam           LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]),
408146773Ssam           tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
409146773Ssam           bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
410146773Ssam           tlen);
411146773Ssam
412146773Ssam    tptr+=sizeof(const struct lmp_common_header);
413146773Ssam    tlen-=sizeof(const struct lmp_common_header);
414146773Ssam
415146773Ssam    while(tlen>0) {
416146773Ssam        /* did we capture enough for fully decoding the object header ? */
417146773Ssam        if (!TTEST2(*tptr, sizeof(struct lmp_object_header)))
418146773Ssam            goto trunc;
419146773Ssam
420146773Ssam        lmp_obj_header = (const struct lmp_object_header *)tptr;
421146773Ssam        lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
422146773Ssam        lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
423146773Ssam
424146773Ssam        if(lmp_obj_len % 4 || lmp_obj_len < 4)
425146773Ssam            return;
426146773Ssam
427146773Ssam        printf("\n\t  %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
428146773Ssam               tok2str(lmp_obj_values,
429146773Ssam                       "Unknown",
430146773Ssam                       lmp_obj_header->class_num),
431146773Ssam               lmp_obj_header->class_num,
432146773Ssam               tok2str(lmp_ctype_values,
433146773Ssam                       "Unknown",
434146773Ssam                       ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype),
435146773Ssam               lmp_obj_ctype,
436146773Ssam               (lmp_obj_header->ctype)&0x80 ? "" : "non-",
437146773Ssam               lmp_obj_len);
438146773Ssam
439146773Ssam        obj_tptr=tptr+sizeof(struct lmp_object_header);
440146773Ssam        obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
441146773Ssam
442146773Ssam        /* did we capture enough for fully decoding the object ? */
443146773Ssam        if (!TTEST2(*tptr, lmp_obj_len))
444146773Ssam            goto trunc;
445146773Ssam        hexdump=FALSE;
446146773Ssam
447146773Ssam        switch(lmp_obj_header->class_num) {
448146773Ssam
449146773Ssam        case LMP_OBJ_CC_ID:
450146773Ssam            switch(lmp_obj_ctype) {
451146773Ssam            case LMP_CTYPE_LOC:
452146773Ssam            case LMP_CTYPE_RMT:
453146773Ssam                printf("\n\t    Control Channel ID: %u (0x%08x)",
454146773Ssam                       EXTRACT_32BITS(obj_tptr),
455146773Ssam                       EXTRACT_32BITS(obj_tptr));
456146773Ssam                break;
457146773Ssam
458146773Ssam            default:
459146773Ssam                hexdump=TRUE;
460146773Ssam            }
461146773Ssam            break;
462146773Ssam
463146773Ssam        case LMP_OBJ_LINK_ID:
464146773Ssam        case LMP_OBJ_INTERFACE_ID:
465146773Ssam            switch(lmp_obj_ctype) {
466146773Ssam            case LMP_CTYPE_IPV4_LOC:
467146773Ssam            case LMP_CTYPE_IPV4_RMT:
468146773Ssam                printf("\n\t    IPv4 Link ID: %s (0x%08x)",
469146773Ssam                       ipaddr_string(obj_tptr),
470146773Ssam                       EXTRACT_32BITS(obj_tptr));
471146773Ssam                break;
472146773Ssam#ifdef INET6
473146773Ssam            case LMP_CTYPE_IPV6_LOC:
474146773Ssam            case LMP_CTYPE_IPV6_RMT:
475146773Ssam                printf("\n\t    IPv6 Link ID: %s (0x%08x)",
476146773Ssam                       ip6addr_string(obj_tptr),
477146773Ssam                       EXTRACT_32BITS(obj_tptr));
478146773Ssam                break;
479146773Ssam#endif
480146773Ssam            case LMP_CTYPE_UNMD_LOC:
481146773Ssam            case LMP_CTYPE_UNMD_RMT:
482146773Ssam                printf("\n\t    Link ID: %u (0x%08x)",
483146773Ssam                       EXTRACT_32BITS(obj_tptr),
484146773Ssam                       EXTRACT_32BITS(obj_tptr));
485146773Ssam                break;
486146773Ssam            default:
487146773Ssam                hexdump=TRUE;
488146773Ssam            }
489146773Ssam            break;
490146773Ssam
491146773Ssam        case LMP_OBJ_MESSAGE_ID:
492146773Ssam            switch(lmp_obj_ctype) {
493146773Ssam            case LMP_CTYPE_1:
494146773Ssam                printf("\n\t    Message ID: %u (0x%08x)",
495146773Ssam                       EXTRACT_32BITS(obj_tptr),
496146773Ssam                       EXTRACT_32BITS(obj_tptr));
497146773Ssam                break;
498146773Ssam            case LMP_CTYPE_2:
499146773Ssam                printf("\n\t    Message ID Ack: %u (0x%08x)",
500146773Ssam                       EXTRACT_32BITS(obj_tptr),
501146773Ssam                       EXTRACT_32BITS(obj_tptr));
502146773Ssam                break;
503146773Ssam            default:
504146773Ssam                hexdump=TRUE;
505146773Ssam            }
506146773Ssam            break;
507146773Ssam
508146773Ssam        case LMP_OBJ_NODE_ID:
509146773Ssam            switch(lmp_obj_ctype) {
510146773Ssam            case LMP_CTYPE_LOC:
511146773Ssam            case LMP_CTYPE_RMT:
512146773Ssam                printf("\n\t    Node ID: %s (0x%08x)",
513146773Ssam                       ipaddr_string(obj_tptr),
514146773Ssam                       EXTRACT_32BITS(obj_tptr));
515146773Ssam                break;
516146773Ssam
517146773Ssam            default:
518146773Ssam                hexdump=TRUE;
519146773Ssam            }
520146773Ssam            break;
521146773Ssam
522146773Ssam        case LMP_OBJ_CONFIG:
523146773Ssam            switch(lmp_obj_ctype) {
524146773Ssam            case LMP_CTYPE_HELLO_CONFIG:
525146773Ssam                printf("\n\t    Hello Interval: %u\n\t    Hello Dead Interval: %u",
526146773Ssam                       EXTRACT_16BITS(obj_tptr),
527146773Ssam                       EXTRACT_16BITS(obj_tptr+2));
528146773Ssam                break;
529146773Ssam
530146773Ssam            default:
531146773Ssam                hexdump=TRUE;
532146773Ssam            }
533146773Ssam            break;
534146773Ssam
535146773Ssam        case LMP_OBJ_HELLO:
536146773Ssam            switch(lmp_obj_ctype) {
537146773Ssam	    case LMP_CTYPE_HELLO:
538146773Ssam                printf("\n\t    TxSeqNum: %u\n\t    RcvSeqNum: %u",
539146773Ssam                       EXTRACT_32BITS(obj_tptr),
540146773Ssam                       EXTRACT_32BITS(obj_tptr+4));
541146773Ssam                break;
542146773Ssam
543146773Ssam            default:
544146773Ssam                hexdump=TRUE;
545146773Ssam            }
546146773Ssam            break;
547146773Ssam
548146773Ssam        case LMP_OBJ_TE_LINK:
549146773Ssam		printf("\n\t    Flags: [%s]",
550146773Ssam		bittok2str(lmp_obj_te_link_flag_values,
551146773Ssam			"none",
552146773Ssam			EXTRACT_16BITS(obj_tptr)>>8));
553146773Ssam
554146773Ssam	    switch(lmp_obj_ctype) {
555146773Ssam	    case LMP_CTYPE_IPV4:
556146773Ssam		printf("\n\t    Local Link-ID: %s (0x%08x) \
557146773Ssam			\n\t    Remote Link-ID: %s (0x%08x)",
558146773Ssam                       ipaddr_string(obj_tptr+4),
559146773Ssam                       EXTRACT_32BITS(obj_tptr+4),
560146773Ssam                       ipaddr_string(obj_tptr+8),
561146773Ssam                       EXTRACT_32BITS(obj_tptr+8));
562146773Ssam		break;
563146773Ssam
564146773Ssam#ifdef INET6
565146773Ssam	    case LMP_CTYPE_IPV6:
566146773Ssam#endif
567146773Ssam	    case LMP_CTYPE_UNMD:
568146773Ssam            default:
569146773Ssam                hexdump=TRUE;
570146773Ssam            }
571146773Ssam            break;
572146773Ssam
573146773Ssam        case LMP_OBJ_DATA_LINK:
574146773Ssam		printf("\n\t    Flags: [%s]",
575146773Ssam		bittok2str(lmp_obj_data_link_flag_values,
576146773Ssam			"none",
577146773Ssam			EXTRACT_16BITS(obj_tptr)>>8));
578146773Ssam
579146773Ssam	    switch(lmp_obj_ctype) {
580146773Ssam	    case LMP_CTYPE_IPV4:
581146773Ssam	    case LMP_CTYPE_UNMD:
582146773Ssam                printf("\n\t    Local Interface ID: %s (0x%08x) \
583146773Ssam			\n\t    Remote Interface ID: %s (0x%08x)",
584146773Ssam                       ipaddr_string(obj_tptr+4),
585146773Ssam                       EXTRACT_32BITS(obj_tptr+4),
586146773Ssam                       ipaddr_string(obj_tptr+8),
587146773Ssam                       EXTRACT_32BITS(obj_tptr+8));
588146773Ssam
589146773Ssam		total_subobj_len = lmp_obj_len - 16;
590146773Ssam		offset = 12;
591146773Ssam		while (total_subobj_len > 0 && hexdump == FALSE ) {
592146773Ssam			subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
593146773Ssam			subobj_len  = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
594146773Ssam			printf("\n\t    Subobject, Type: %s (%u), Length: %u",
595146773Ssam				tok2str(lmp_data_link_subobj,
596146773Ssam					"Unknown",
597146773Ssam					subobj_type),
598146773Ssam					subobj_type,
599146773Ssam					subobj_len);
600146773Ssam			switch(subobj_type) {
601146773Ssam			case INT_SWITCHING_TYPE_SUBOBJ:
602146773Ssam				printf("\n\t\t    Switching Type: %s (%u)",
603146773Ssam					tok2str(gmpls_switch_cap_values,
604146773Ssam						"Unknown",
605146773Ssam						EXTRACT_16BITS(obj_tptr+offset+2)>>8),
606146773Ssam					EXTRACT_16BITS(obj_tptr+offset+2)>>8);
607146773Ssam				printf("\n\t\t    Encoding Type: %s (%u)",
608146773Ssam					tok2str(gmpls_encoding_values,
609146773Ssam						"Unknown",
610146773Ssam						EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
611146773Ssam					EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF);
612146773Ssam				bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
613146773Ssam				printf("\n\t\t    Min Reservable Bandwidth: %.3f Mbps",
614146773Ssam					bw.f);
615146773Ssam				bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
616146773Ssam				printf("\n\t\t    Max Reservable Bandwidth: %.3f Mbps",
617146773Ssam					bw.f);
618146773Ssam				break;
619146773Ssam			case WAVELENGTH_SUBOBJ:
620146773Ssam				printf("\n\t\t    Wavelength: %u",
621146773Ssam					EXTRACT_32BITS(obj_tptr+offset+4));
622146773Ssam				break;
623146773Ssam			default:
624146773Ssam				/* Any Unknown Subobject ==> Exit loop */
625146773Ssam				hexdump=TRUE;
626146773Ssam				break;
627146773Ssam			}
628146773Ssam			total_subobj_len-=subobj_len;
629146773Ssam			offset+=subobj_len;
630146773Ssam		}
631146773Ssam
632146773Ssam		break;
633146773Ssam#ifdef INET6
634146773Ssam	    case LMP_CTYPE_IPV6:
635146773Ssam#endif
636146773Ssam            default:
637146773Ssam                hexdump=TRUE;
638146773Ssam            }
639146773Ssam            break;
640146773Ssam
641146773Ssam        case LMP_OBJ_VERIFY_BEGIN:
642146773Ssam	    switch(lmp_obj_ctype) {
643146773Ssam            case LMP_CTYPE_1:
644146773Ssam		printf("\n\t    Flags: %s",
645146773Ssam		bittok2str(lmp_obj_begin_verify_flag_values,
646146773Ssam			"none",
647146773Ssam			EXTRACT_16BITS(obj_tptr)));
648146773Ssam		printf("\n\t    Verify Interval: %u",
649146773Ssam			EXTRACT_16BITS(obj_tptr+2));
650146773Ssam		printf("\n\t    Data links: %u",
651146773Ssam			EXTRACT_32BITS(obj_tptr+4));
652146773Ssam                printf("\n\t    Encoding type: %s",
653146773Ssam			tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8)));
654146773Ssam                printf("\n\t    Verify Tranport Mechanism: %u (0x%x) %s",
655146773Ssam			EXTRACT_16BITS(obj_tptr+10),
656146773Ssam			EXTRACT_16BITS(obj_tptr+10),
657146773Ssam			EXTRACT_16BITS(obj_tptr+10)&8000 ? "(Payload test messages capable)" : "");
658146773Ssam                bw.i = EXTRACT_32BITS(obj_tptr+12);
659146773Ssam		printf("\n\t    Transmission Rate: %.3f Mbps",bw.f);
660146773Ssam		printf("\n\t    Wavelength: %u",
661146773Ssam			EXTRACT_32BITS(obj_tptr+16));
662146773Ssam		break;
663146773Ssam
664146773Ssam            default:
665146773Ssam                hexdump=TRUE;
666146773Ssam            }
667146773Ssam            break;
668146773Ssam
669146773Ssam        case LMP_OBJ_VERIFY_BEGIN_ACK:
670146773Ssam	    switch(lmp_obj_ctype) {
671146773Ssam            case LMP_CTYPE_1:
672146773Ssam                printf("\n\t    Verify Dead Interval: %u 	\
673146773Ssam			\n\t    Verify Transport Response: %u",
674146773Ssam                       EXTRACT_16BITS(obj_tptr),
675146773Ssam                       EXTRACT_16BITS(obj_tptr+2));
676146773Ssam                break;
677146773Ssam
678146773Ssam            default:
679146773Ssam                hexdump=TRUE;
680146773Ssam            }
681146773Ssam            break;
682146773Ssam
683146773Ssam	case LMP_OBJ_VERIFY_ID:
684146773Ssam	    switch(lmp_obj_ctype) {
685146773Ssam            case LMP_CTYPE_1:
686146773Ssam                printf("\n\t    Verify ID: %u",
687146773Ssam                       EXTRACT_32BITS(obj_tptr));
688146773Ssam                break;
689146773Ssam
690146773Ssam            default:
691146773Ssam                hexdump=TRUE;
692146773Ssam            }
693146773Ssam            break;
694146773Ssam
695146773Ssam	case LMP_OBJ_CHANNEL_STATUS:
696146773Ssam            switch(lmp_obj_ctype) {
697146773Ssam	    case LMP_CTYPE_IPV4:
698146773Ssam	    case LMP_CTYPE_UNMD:
699146773Ssam		offset = 0;
700146773Ssam		/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
701146773Ssam		while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
702146773Ssam			printf("\n\t    Interface ID: %s (0x%08x)",
703146773Ssam			ipaddr_string(obj_tptr+offset),
704146773Ssam			EXTRACT_32BITS(obj_tptr+offset));
705146773Ssam
706146773Ssam			printf("\n\t\t    Active: %s (%u)", 		(EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
707146773Ssam						"Allocated" : "Non-allocated",
708146773Ssam				(EXTRACT_32BITS(obj_tptr+offset+4)>>31));
709146773Ssam
710146773Ssam			printf("\n\t\t    Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
711146773Ssam						"Transmit" : "Receive",
712146773Ssam				(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1);
713146773Ssam
714146773Ssam			printf("\n\t\t    Channel Status: %s (%u)",
715146773Ssam					tok2str(lmp_obj_channel_status_values,
716146773Ssam			 		"Unknown",
717146773Ssam					EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
718146773Ssam			EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF);
719146773Ssam			offset+=8;
720146773Ssam		}
721146773Ssam                break;
722146773Ssam#ifdef INET6
723146773Ssam	    case LMP_CTYPE_IPV6:
724146773Ssam#endif
725146773Ssam            default:
726146773Ssam                hexdump=TRUE;
727146773Ssam            }
728146773Ssam            break;
729146773Ssam
730146773Ssam	case LMP_OBJ_CHANNEL_STATUS_REQ:
731146773Ssam            switch(lmp_obj_ctype) {
732146773Ssam	    case LMP_CTYPE_IPV4:
733146773Ssam	    case LMP_CTYPE_UNMD:
734146773Ssam		offset = 0;
735146773Ssam		while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
736146773Ssam			printf("\n\t    Interface ID: %s (0x%08x)",
737146773Ssam			ipaddr_string(obj_tptr+offset),
738146773Ssam			EXTRACT_32BITS(obj_tptr+offset));
739146773Ssam			offset+=4;
740146773Ssam		}
741146773Ssam                break;
742146773Ssam#ifdef INET6
743146773Ssam	    case LMP_CTYPE_IPV6:
744146773Ssam#endif
745146773Ssam	    default:
746146773Ssam                hexdump=TRUE;
747146773Ssam            }
748146773Ssam            break;
749146773Ssam
750146773Ssam        case LMP_OBJ_ERROR_CODE:
751146773Ssam	    switch(lmp_obj_ctype) {
752146773Ssam            case LMP_CTYPE_BEGIN_VERIFY_ERROR:
753146773Ssam		printf("\n\t    Error Code: %s",
754146773Ssam		bittok2str(lmp_obj_begin_verify_error_values,
755146773Ssam			"none",
756146773Ssam			EXTRACT_32BITS(obj_tptr)));
757146773Ssam                break;
758146773Ssam
759146773Ssam            case LMP_CTYPE_LINK_SUMMARY_ERROR:
760146773Ssam		printf("\n\t    Error Code: %s",
761146773Ssam		bittok2str(lmp_obj_link_summary_error_values,
762146773Ssam			"none",
763146773Ssam			EXTRACT_32BITS(obj_tptr)));
764146773Ssam                break;
765146773Ssam            default:
766146773Ssam                hexdump=TRUE;
767146773Ssam            }
768146773Ssam            break;
769147899Ssam
770147899Ssam	case LMP_OBJ_SERVICE_CONFIG:
771147899Ssam	    switch (lmp_obj_ctype) {
772147899Ssam	    case LMP_CTYPE_SERVICE_CONFIG_SP:
773147899Ssam
774147899Ssam		printf("\n\t Flags: %s",
775147899Ssam		       bittok2str(lmp_obj_service_config_sp_flag_values,
776147899Ssam				  "none",
777147899Ssam				  EXTRACT_16BITS(obj_tptr)>>8));
778147899Ssam
779147899Ssam		printf("\n\t  UNI Version: %u",
780147899Ssam		       EXTRACT_16BITS(obj_tptr) & 0x00FF);
781147899Ssam
782147899Ssam		break;
783147899Ssam
784147899Ssam            case LMP_CTYPE_SERVICE_CONFIG_CPSA:
785147899Ssam
786147899Ssam		link_type = EXTRACT_16BITS(obj_tptr)>>8;
787147899Ssam
788147899Ssam		printf("\n\t Link Type: %s (%u)",
789147899Ssam		       tok2str(lmp_sd_service_config_cpsa_link_type_values,
790147899Ssam			       "Unknown", link_type),
791147899Ssam		       link_type);
792147899Ssam
793147899Ssam		if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) {
794147899Ssam		    printf("\n\t Signal Type: %s (%u)",
795147899Ssam			   tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
796147899Ssam				   "Unknown",
797147899Ssam				   EXTRACT_16BITS(obj_tptr) & 0x00FF),
798147899Ssam			   EXTRACT_16BITS(obj_tptr) & 0x00FF);
799147899Ssam		}
800147899Ssam
801147899Ssam		if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) {
802147899Ssam		    printf("\n\t Signal Type: %s (%u)",
803147899Ssam			   tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
804147899Ssam				   "Unknown",
805147899Ssam				   EXTRACT_16BITS(obj_tptr) & 0x00FF),
806147899Ssam			   EXTRACT_16BITS(obj_tptr) & 0x00FF);
807147899Ssam		}
808147899Ssam
809147899Ssam		printf("\n\t Transparency: %s",
810147899Ssam		       bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
811147899Ssam				  "none",
812147899Ssam				  EXTRACT_16BITS(obj_tptr+2)>>8));
813147899Ssam
814147899Ssam		printf("\n\t Contiguous Concatenation Types: %s",
815147899Ssam		       bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
816147899Ssam				  "none",
817147899Ssam				  EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF));
818147899Ssam
819147899Ssam		printf("\n\t Minimum NCC: %u",
820147899Ssam		       EXTRACT_16BITS(obj_tptr+4));
821147899Ssam
822147899Ssam		printf("\n\t Maximum NCC: %u",
823147899Ssam		       EXTRACT_16BITS(obj_tptr+6));
824147899Ssam
825147899Ssam		printf("\n\t Minimum NVC:%u",
826147899Ssam		       EXTRACT_16BITS(obj_tptr+8));
827147899Ssam
828147899Ssam		printf("\n\t Maximum NVC:%u",
829147899Ssam		       EXTRACT_16BITS(obj_tptr+10));
830147899Ssam
831147899Ssam		printf("\n\t    Local Interface ID: %s (0x%08x)",
832147899Ssam		       ipaddr_string(obj_tptr+12),
833147899Ssam		       EXTRACT_32BITS(obj_tptr+12));
834147899Ssam
835147899Ssam		break;
836147899Ssam
837147899Ssam	    case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
838147899Ssam
839147899Ssam		printf("\n\t Transparency Flags: %s",
840147899Ssam		       bittok2str(
841147899Ssam			   lmp_obj_service_config_nsa_transparency_flag_values,
842147899Ssam			   "none",
843147899Ssam			   EXTRACT_32BITS(obj_tptr)));
844147899Ssam
845147899Ssam		printf("\n\t TCM Monitoring Flags: %s",
846147899Ssam		       bittok2str(
847147899Ssam			   lmp_obj_service_config_nsa_tcm_flag_values,
848147899Ssam			   "none",
849147899Ssam			   EXTRACT_16BITS(obj_tptr+6) & 0x00FF));
850147899Ssam
851147899Ssam		break;
852147899Ssam
853147899Ssam	    case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
854147899Ssam
855147899Ssam		printf("\n\t Diversity: Flags: %s",
856147899Ssam		       bittok2str(
857147899Ssam			   lmp_obj_service_config_nsa_network_diversity_flag_values,
858147899Ssam			   "none",
859147899Ssam			   EXTRACT_16BITS(obj_tptr+2) & 0x00FF));
860147899Ssam		break;
861147899Ssam
862147899Ssam	    default:
863147899Ssam		hexdump = TRUE;
864147899Ssam	    };
865147899Ssam
866147899Ssam	break;
867147899Ssam
868146773Ssam        default:
869146773Ssam            if (vflag <= 1)
870146773Ssam                print_unknown_data(obj_tptr,"\n\t    ",obj_tlen);
871146773Ssam            break;
872146773Ssam        }
873146773Ssam        /* do we want to see an additionally hexdump ? */
874146773Ssam        if (vflag > 1 || hexdump==TRUE)
875146773Ssam            print_unknown_data(tptr+sizeof(sizeof(struct lmp_object_header)),"\n\t    ",
876146773Ssam                               lmp_obj_len-sizeof(struct lmp_object_header));
877146773Ssam
878146773Ssam        tptr+=lmp_obj_len;
879146773Ssam        tlen-=lmp_obj_len;
880146773Ssam    }
881146773Ssam    return;
882146773Ssamtrunc:
883146773Ssam    printf("\n\t\t packet exceeded snapshot");
884146773Ssam}
885