print-lmp.c revision 146773
1279377Simp/*
2279377Simp * Redistribution and use in source and binary forms, with or without
3279377Simp * modification, are permitted provided that: (1) source code
4279377Simp * distributions retain the above copyright notice and this paragraph
5279377Simp * in its entirety, and (2) distributions including binary code include
6279377Simp * the above copyright notice and this paragraph in its entirety in
7279377Simp * the documentation or other materials provided with the distribution.
8279377Simp * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9279377Simp * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10279377Simp * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11279377Simp * FOR A PARTICULAR PURPOSE.
12279377Simp *
13279377Simp * Original code by Hannes Gredler (hannes@juniper.net)
14279377Simp */
15279377Simp
16279377Simp#ifndef lint
17279377Simpstatic const char rcsid[] _U_ =
18279377Simp    "@(#) $Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.5 2004/04/27 14:03:44 hannes Exp $";
19279377Simp#endif
20279377Simp
21279377Simp#ifdef HAVE_CONFIG_H
22279377Simp#include "config.h"
23279377Simp#endif
24279377Simp
25279377Simp#include <tcpdump-stdinc.h>
26279377Simp
27279377Simp#include <stdio.h>
28279377Simp#include <stdlib.h>
29279377Simp#include <string.h>
30279377Simp
31279377Simp#include "interface.h"
32279377Simp#include "extract.h"
33279377Simp#include "addrtoname.h"
34279377Simp#include "gmpls.h"
35279377Simp
36279377Simp/*
37279377Simp * LMP common header
38279377Simp *
39279377Simp *  0                   1                   2                   3
40279377Simp *  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
41279377Simp * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42279377Simp * | Vers  |      (Reserved)       |    Flags      |    Msg Type   |
43279377Simp * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44279377Simp * |          LMP Length           |          (Reserved)           |
45279377Simp * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46279377Simp */
47279377Simp
48279377Simpstruct lmp_common_header {
49279377Simp    u_int8_t version_res[2];
50279377Simp    u_int8_t flags;
51279377Simp    u_int8_t msg_type;
52279377Simp    u_int8_t length[2];
53279377Simp    u_int8_t reserved[2];
54279377Simp};
55279377Simp
56279377Simp#define LMP_VERSION            1
57279377Simp#define	LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
58279377Simp
59279377Simpstatic const struct tok lmp_header_flag_values[] = {
60279377Simp    { 0x00, "Control Channel Down"},
61279377Simp    { 0x02, "LMP restart"},
62279377Simp    { 0, NULL}
63279377Simp};
64279377Simp
65279377Simpstatic const struct tok lmp_obj_te_link_flag_values[] = {
66279377Simp    { 0x01, "Fault Management Supported"},
67279377Simp    { 0x02, "Link Verification Supported"},
68279377Simp    { 0, NULL}
69279377Simp};
70279377Simp
71279377Simpstatic const struct tok lmp_obj_data_link_flag_values[] = {
72279377Simp    { 0x01, "Data Link Port"},
73279377Simp    { 0x02, "Allocated for user traffic"},
74279377Simp    { 0x04, "Failed link"},
75279377Simp    { 0, NULL}
76279377Simp};
77279377Simp
78279377Simpstatic const struct tok lmp_obj_channel_status_values[] = {
79279377Simp    { 1, "Signal Okay"},
80279377Simp    { 2, "Signal Degraded"},
81279377Simp    { 3, "Signal Fail"},
82279377Simp    { 0, NULL}
83279377Simp};
84279377Simp
85279377Simpstatic const struct tok lmp_obj_begin_verify_flag_values[] = {
86279377Simp    { 0x0001, "Verify all links"},
87279377Simp    { 0x0002, "Data link type"},
88279377Simp    { 0, NULL}
89279377Simp};
90279377Simp
91279377Simpstatic const struct tok lmp_obj_begin_verify_error_values[] = {
92279377Simp    { 0x01, "\n\t\tLink Verification Procedure Not supported"},
93    { 0x02, "\n\t\tUnwilling to verify"},
94    { 0x04, "\n\t\tUnsupported verification transport mechanism"},
95    { 0x08, "\n\t\tLink_Id configuration error"},
96    { 0x10, "\n\t\tUnknown object c-type"},
97    { 0, NULL}
98};
99
100static const struct tok lmp_obj_link_summary_error_values[] = {
101    { 0x01, "\n\t\tUnacceptable non-negotiable LINK_SUMMARY parameters"},
102    { 0x02, "\n\t\tRenegotiate LINK_SUMMARY parameters"},
103    { 0x04, "\n\t\tInvalid TE-LINK Object"},
104    { 0x08, "\n\t\tInvalid DATA-LINK Object"},
105    { 0x10, "\n\t\tUnknown TE-LINK Object c-type"},
106    { 0x20, "\n\t\tUnknown DATA-LINK Object c-type"},
107    { 0, NULL}
108};
109
110#define	LMP_MSGTYPE_CONFIG                 1
111#define	LMP_MSGTYPE_CONFIG_ACK             2
112#define	LMP_MSGTYPE_CONFIG_NACK            3
113#define	LMP_MSGTYPE_HELLO                  4
114#define	LMP_MSGTYPE_VERIFY_BEGIN           5
115#define	LMP_MSGTYPE_VERIFY_BEGIN_ACK       6
116#define	LMP_MSGTYPE_VERIFY_BEGIN_NACK      7
117#define LMP_MSGTYPE_VERIFY_END             8
118#define LMP_MSGTYPE_VERIFY_END_ACK         9
119#define LMP_MSGTYPE_TEST                  10
120#define LMP_MSGTYPE_TEST_STATUS_SUCCESS   11
121#define	LMP_MSGTYPE_TEST_STATUS_FAILURE   12
122#define	LMP_MSGTYPE_TEST_STATUS_ACK       13
123#define	LMP_MSGTYPE_LINK_SUMMARY          14
124#define	LMP_MSGTYPE_LINK_SUMMARY_ACK      15
125#define	LMP_MSGTYPE_LINK_SUMMARY_NACK     16
126#define	LMP_MSGTYPE_CHANNEL_STATUS        17
127#define	LMP_MSGTYPE_CHANNEL_STATUS_ACK    18
128#define	LMP_MSGTYPE_CHANNEL_STATUS_REQ    19
129#define	LMP_MSGTYPE_CHANNEL_STATUS_RESP   20
130
131static const struct tok lmp_msg_type_values[] = {
132    { LMP_MSGTYPE_CONFIG, "Config"},
133    { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"},
134    { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"},
135    { LMP_MSGTYPE_HELLO, "Hello"},
136    { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"},
137    { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"},
138    { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"},
139    { LMP_MSGTYPE_VERIFY_END, "End Verify"},
140    { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"},
141    { LMP_MSGTYPE_TEST, "Test"},
142    { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"},
143    { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"},
144    { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"},
145    { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"},
146    { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"},
147    { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"},
148    { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"},
149    { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"},
150    { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"},
151    { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"},
152    { 0, NULL}
153};
154
155/*
156 * LMP object header
157 *
158 *  0                   1                   2                   3
159 *  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
160 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 * |N|   C-Type    |     Class     |            Length             |
162 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 * |                                                               |
164 * //                       (object contents)                     //
165 * |                                                               |
166 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167 */
168
169struct lmp_object_header {
170    u_int8_t ctype;
171    u_int8_t class_num;
172    u_int8_t length[2];
173};
174
175#define	LMP_OBJ_CC_ID                 1
176#define	LMP_OBJ_NODE_ID               2
177#define	LMP_OBJ_LINK_ID               3
178#define	LMP_OBJ_INTERFACE_ID          4
179#define	LMP_OBJ_MESSAGE_ID            5
180#define	LMP_OBJ_CONFIG                6
181#define	LMP_OBJ_HELLO                 7
182#define	LMP_OBJ_VERIFY_BEGIN          8
183#define LMP_OBJ_VERIFY_BEGIN_ACK      9
184#define LMP_OBJ_VERIFY_ID            10
185#define LMP_OBJ_TE_LINK              11
186#define LMP_OBJ_DATA_LINK            12
187#define LMP_OBJ_CHANNEL_STATUS       13
188#define LMP_OBJ_CHANNEL_STATUS_REQ   14
189#define LMP_OBJ_ERROR_CODE           20
190
191static const struct tok lmp_obj_values[] = {
192    { LMP_OBJ_CC_ID, "Control Channel ID" },
193    { LMP_OBJ_NODE_ID, "Node ID" },
194    { LMP_OBJ_LINK_ID, "Link ID" },
195    { LMP_OBJ_INTERFACE_ID, "Interface ID" },
196    { LMP_OBJ_MESSAGE_ID, "Message ID" },
197    { LMP_OBJ_CONFIG, "Configuration" },
198    { LMP_OBJ_HELLO, "Hello" },
199    { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" },
200    { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" },
201    { LMP_OBJ_VERIFY_ID, "Verify ID" },
202    { LMP_OBJ_TE_LINK, "TE Link" },
203    { LMP_OBJ_DATA_LINK, "Data Link" },
204    { LMP_OBJ_CHANNEL_STATUS, "Channel Status" },
205    { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" },
206    { LMP_OBJ_ERROR_CODE, "Error Code" },
207    { 0, NULL}
208};
209
210#define INT_SWITCHING_TYPE_SUBOBJ 1
211#define WAVELENGTH_SUBOBJ         2
212
213static const struct tok lmp_data_link_subobj[] = {
214    { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" },
215    { WAVELENGTH_SUBOBJ        , "Wavelength" },
216    { 0, NULL}
217};
218
219#define	LMP_CTYPE_IPV4       1
220#define	LMP_CTYPE_IPV6       2
221
222#define	LMP_CTYPE_LOC        1
223#define	LMP_CTYPE_RMT        2
224#define	LMP_CTYPE_UNMD       3
225
226#define	LMP_CTYPE_IPV4_LOC   1
227#define	LMP_CTYPE_IPV4_RMT   2
228#define	LMP_CTYPE_IPV6_LOC   3
229#define	LMP_CTYPE_IPV6_RMT   4
230#define	LMP_CTYPE_UNMD_LOC   5
231#define	LMP_CTYPE_UNMD_RMT   6
232
233#define	LMP_CTYPE_1          1
234#define	LMP_CTYPE_2          2
235
236#define LMP_CTYPE_HELLO_CONFIG  1
237#define LMP_CTYPE_HELLO         1
238
239#define LMP_CTYPE_BEGIN_VERIFY_ERROR 1
240#define LMP_CTYPE_LINK_SUMMARY_ERROR 2
241
242#define FALSE 0
243#define TRUE  1
244
245/*
246 * the ctypes are not globally unique so for
247 * translating it to strings we build a table based
248 * on objects offsetted by the ctype
249 */
250
251static const struct tok lmp_ctype_values[] = {
252    { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" },
253    { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" },
254    { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" },
255    { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" },
256    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" },
257    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" },
258    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" },
259    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" },
260    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" },
261    { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" },
262    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" },
263    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" },
264    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" },
265    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" },
266    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" },
267    { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" },
268    { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" },
269    { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" },
270    { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" },
271    { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" },
272    { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" },
273    { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" },
274    { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" },
275    { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" },
276    { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" },
277    { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" },
278    { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" },
279    { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" },
280    { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" },
281    { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" },
282    { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" },
283    { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" },
284    { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" },
285    { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" },
286    { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" },
287    { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" },
288    { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" },
289    { 0, NULL}
290};
291
292void
293lmp_print(register const u_char *pptr, register u_int len) {
294
295    const struct lmp_common_header *lmp_com_header;
296    const struct lmp_object_header *lmp_obj_header;
297    const u_char *tptr,*obj_tptr;
298    int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
299    int hexdump;
300    int offset,subobj_type,subobj_len,total_subobj_len;
301
302    union { /* int to float conversion buffer */
303        float f;
304        u_int32_t i;
305    } bw;
306
307    tptr=pptr;
308    lmp_com_header = (const struct lmp_common_header *)pptr;
309    TCHECK(*lmp_com_header);
310
311    /*
312     * Sanity checking of the header.
313     */
314    if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) {
315	printf("LMP version %u packet not supported",
316               LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]));
317	return;
318    }
319
320    /* in non-verbose mode just lets print the basic Message Type*/
321    if (vflag < 1) {
322        printf("LMPv%u %s Message, length: %u",
323               LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]),
324               tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type),
325               len);
326        return;
327    }
328
329    /* ok they seem to want to know everything - lets fully decode it */
330
331    tlen=EXTRACT_16BITS(lmp_com_header->length);
332
333    printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u",
334           LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]),
335           tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
336           bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
337           tlen);
338
339    tptr+=sizeof(const struct lmp_common_header);
340    tlen-=sizeof(const struct lmp_common_header);
341
342    while(tlen>0) {
343        /* did we capture enough for fully decoding the object header ? */
344        if (!TTEST2(*tptr, sizeof(struct lmp_object_header)))
345            goto trunc;
346
347        lmp_obj_header = (const struct lmp_object_header *)tptr;
348        lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
349        lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
350
351        if(lmp_obj_len % 4 || lmp_obj_len < 4)
352            return;
353
354        printf("\n\t  %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
355               tok2str(lmp_obj_values,
356                       "Unknown",
357                       lmp_obj_header->class_num),
358               lmp_obj_header->class_num,
359               tok2str(lmp_ctype_values,
360                       "Unknown",
361                       ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype),
362               lmp_obj_ctype,
363               (lmp_obj_header->ctype)&0x80 ? "" : "non-",
364               lmp_obj_len);
365
366        obj_tptr=tptr+sizeof(struct lmp_object_header);
367        obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
368
369        /* did we capture enough for fully decoding the object ? */
370        if (!TTEST2(*tptr, lmp_obj_len))
371            goto trunc;
372        hexdump=FALSE;
373
374        switch(lmp_obj_header->class_num) {
375
376        case LMP_OBJ_CC_ID:
377            switch(lmp_obj_ctype) {
378            case LMP_CTYPE_LOC:
379            case LMP_CTYPE_RMT:
380                printf("\n\t    Control Channel ID: %u (0x%08x)",
381                       EXTRACT_32BITS(obj_tptr),
382                       EXTRACT_32BITS(obj_tptr));
383                break;
384
385            default:
386                hexdump=TRUE;
387            }
388            break;
389
390        case LMP_OBJ_LINK_ID:
391        case LMP_OBJ_INTERFACE_ID:
392            switch(lmp_obj_ctype) {
393            case LMP_CTYPE_IPV4_LOC:
394            case LMP_CTYPE_IPV4_RMT:
395                printf("\n\t    IPv4 Link ID: %s (0x%08x)",
396                       ipaddr_string(obj_tptr),
397                       EXTRACT_32BITS(obj_tptr));
398                break;
399#ifdef INET6
400            case LMP_CTYPE_IPV6_LOC:
401            case LMP_CTYPE_IPV6_RMT:
402                printf("\n\t    IPv6 Link ID: %s (0x%08x)",
403                       ip6addr_string(obj_tptr),
404                       EXTRACT_32BITS(obj_tptr));
405                break;
406#endif
407            case LMP_CTYPE_UNMD_LOC:
408            case LMP_CTYPE_UNMD_RMT:
409                printf("\n\t    Link ID: %u (0x%08x)",
410                       EXTRACT_32BITS(obj_tptr),
411                       EXTRACT_32BITS(obj_tptr));
412                break;
413            default:
414                hexdump=TRUE;
415            }
416            break;
417
418        case LMP_OBJ_MESSAGE_ID:
419            switch(lmp_obj_ctype) {
420            case LMP_CTYPE_1:
421                printf("\n\t    Message ID: %u (0x%08x)",
422                       EXTRACT_32BITS(obj_tptr),
423                       EXTRACT_32BITS(obj_tptr));
424                break;
425            case LMP_CTYPE_2:
426                printf("\n\t    Message ID Ack: %u (0x%08x)",
427                       EXTRACT_32BITS(obj_tptr),
428                       EXTRACT_32BITS(obj_tptr));
429                break;
430            default:
431                hexdump=TRUE;
432            }
433            break;
434
435        case LMP_OBJ_NODE_ID:
436            switch(lmp_obj_ctype) {
437            case LMP_CTYPE_LOC:
438            case LMP_CTYPE_RMT:
439                printf("\n\t    Node ID: %s (0x%08x)",
440                       ipaddr_string(obj_tptr),
441                       EXTRACT_32BITS(obj_tptr));
442                break;
443
444            default:
445                hexdump=TRUE;
446            }
447            break;
448
449        case LMP_OBJ_CONFIG:
450            switch(lmp_obj_ctype) {
451            case LMP_CTYPE_HELLO_CONFIG:
452                printf("\n\t    Hello Interval: %u\n\t    Hello Dead Interval: %u",
453                       EXTRACT_16BITS(obj_tptr),
454                       EXTRACT_16BITS(obj_tptr+2));
455                break;
456
457            default:
458                hexdump=TRUE;
459            }
460            break;
461
462        case LMP_OBJ_HELLO:
463            switch(lmp_obj_ctype) {
464	    case LMP_CTYPE_HELLO:
465                printf("\n\t    TxSeqNum: %u\n\t    RcvSeqNum: %u",
466                       EXTRACT_32BITS(obj_tptr),
467                       EXTRACT_32BITS(obj_tptr+4));
468                break;
469
470            default:
471                hexdump=TRUE;
472            }
473            break;
474
475        case LMP_OBJ_TE_LINK:
476		printf("\n\t    Flags: [%s]",
477		bittok2str(lmp_obj_te_link_flag_values,
478			"none",
479			EXTRACT_16BITS(obj_tptr)>>8));
480
481	    switch(lmp_obj_ctype) {
482	    case LMP_CTYPE_IPV4:
483		printf("\n\t    Local Link-ID: %s (0x%08x) \
484			\n\t    Remote Link-ID: %s (0x%08x)",
485                       ipaddr_string(obj_tptr+4),
486                       EXTRACT_32BITS(obj_tptr+4),
487                       ipaddr_string(obj_tptr+8),
488                       EXTRACT_32BITS(obj_tptr+8));
489		break;
490
491#ifdef INET6
492	    case LMP_CTYPE_IPV6:
493#endif
494	    case LMP_CTYPE_UNMD:
495            default:
496                hexdump=TRUE;
497            }
498            break;
499
500        case LMP_OBJ_DATA_LINK:
501		printf("\n\t    Flags: [%s]",
502		bittok2str(lmp_obj_data_link_flag_values,
503			"none",
504			EXTRACT_16BITS(obj_tptr)>>8));
505
506	    switch(lmp_obj_ctype) {
507	    case LMP_CTYPE_IPV4:
508	    case LMP_CTYPE_UNMD:
509                printf("\n\t    Local Interface ID: %s (0x%08x) \
510			\n\t    Remote Interface ID: %s (0x%08x)",
511                       ipaddr_string(obj_tptr+4),
512                       EXTRACT_32BITS(obj_tptr+4),
513                       ipaddr_string(obj_tptr+8),
514                       EXTRACT_32BITS(obj_tptr+8));
515
516		total_subobj_len = lmp_obj_len - 16;
517		offset = 12;
518		while (total_subobj_len > 0 && hexdump == FALSE ) {
519			subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
520			subobj_len  = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
521			printf("\n\t    Subobject, Type: %s (%u), Length: %u",
522				tok2str(lmp_data_link_subobj,
523					"Unknown",
524					subobj_type),
525					subobj_type,
526					subobj_len);
527			switch(subobj_type) {
528			case INT_SWITCHING_TYPE_SUBOBJ:
529				printf("\n\t\t    Switching Type: %s (%u)",
530					tok2str(gmpls_switch_cap_values,
531						"Unknown",
532						EXTRACT_16BITS(obj_tptr+offset+2)>>8),
533					EXTRACT_16BITS(obj_tptr+offset+2)>>8);
534				printf("\n\t\t    Encoding Type: %s (%u)",
535					tok2str(gmpls_encoding_values,
536						"Unknown",
537						EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
538					EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF);
539				bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
540				printf("\n\t\t    Min Reservable Bandwidth: %.3f Mbps",
541					bw.f);
542				bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
543				printf("\n\t\t    Max Reservable Bandwidth: %.3f Mbps",
544					bw.f);
545				break;
546			case WAVELENGTH_SUBOBJ:
547				printf("\n\t\t    Wavelength: %u",
548					EXTRACT_32BITS(obj_tptr+offset+4));
549				break;
550			default:
551				/* Any Unknown Subobject ==> Exit loop */
552				hexdump=TRUE;
553				break;
554			}
555			total_subobj_len-=subobj_len;
556			offset+=subobj_len;
557		}
558
559		break;
560#ifdef INET6
561	    case LMP_CTYPE_IPV6:
562#endif
563            default:
564                hexdump=TRUE;
565            }
566            break;
567
568        case LMP_OBJ_VERIFY_BEGIN:
569	    switch(lmp_obj_ctype) {
570            case LMP_CTYPE_1:
571		printf("\n\t    Flags: %s",
572		bittok2str(lmp_obj_begin_verify_flag_values,
573			"none",
574			EXTRACT_16BITS(obj_tptr)));
575		printf("\n\t    Verify Interval: %u",
576			EXTRACT_16BITS(obj_tptr+2));
577		printf("\n\t    Data links: %u",
578			EXTRACT_32BITS(obj_tptr+4));
579                printf("\n\t    Encoding type: %s",
580			tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8)));
581                printf("\n\t    Verify Tranport Mechanism: %u (0x%x) %s",
582			EXTRACT_16BITS(obj_tptr+10),
583			EXTRACT_16BITS(obj_tptr+10),
584			EXTRACT_16BITS(obj_tptr+10)&8000 ? "(Payload test messages capable)" : "");
585                bw.i = EXTRACT_32BITS(obj_tptr+12);
586		printf("\n\t    Transmission Rate: %.3f Mbps",bw.f);
587		printf("\n\t    Wavelength: %u",
588			EXTRACT_32BITS(obj_tptr+16));
589		break;
590
591            default:
592                hexdump=TRUE;
593            }
594            break;
595
596        case LMP_OBJ_VERIFY_BEGIN_ACK:
597	    switch(lmp_obj_ctype) {
598            case LMP_CTYPE_1:
599                printf("\n\t    Verify Dead Interval: %u 	\
600			\n\t    Verify Transport Response: %u",
601                       EXTRACT_16BITS(obj_tptr),
602                       EXTRACT_16BITS(obj_tptr+2));
603                break;
604
605            default:
606                hexdump=TRUE;
607            }
608            break;
609
610	case LMP_OBJ_VERIFY_ID:
611	    switch(lmp_obj_ctype) {
612            case LMP_CTYPE_1:
613                printf("\n\t    Verify ID: %u",
614                       EXTRACT_32BITS(obj_tptr));
615                break;
616
617            default:
618                hexdump=TRUE;
619            }
620            break;
621
622	case LMP_OBJ_CHANNEL_STATUS:
623            switch(lmp_obj_ctype) {
624	    case LMP_CTYPE_IPV4:
625	    case LMP_CTYPE_UNMD:
626		offset = 0;
627		/* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
628		while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
629			printf("\n\t    Interface ID: %s (0x%08x)",
630			ipaddr_string(obj_tptr+offset),
631			EXTRACT_32BITS(obj_tptr+offset));
632
633			printf("\n\t\t    Active: %s (%u)", 		(EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
634						"Allocated" : "Non-allocated",
635				(EXTRACT_32BITS(obj_tptr+offset+4)>>31));
636
637			printf("\n\t\t    Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
638						"Transmit" : "Receive",
639				(EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1);
640
641			printf("\n\t\t    Channel Status: %s (%u)",
642					tok2str(lmp_obj_channel_status_values,
643			 		"Unknown",
644					EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
645			EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF);
646			offset+=8;
647		}
648                break;
649#ifdef INET6
650	    case LMP_CTYPE_IPV6:
651#endif
652            default:
653                hexdump=TRUE;
654            }
655            break;
656
657	case LMP_OBJ_CHANNEL_STATUS_REQ:
658            switch(lmp_obj_ctype) {
659	    case LMP_CTYPE_IPV4:
660	    case LMP_CTYPE_UNMD:
661		offset = 0;
662		while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
663			printf("\n\t    Interface ID: %s (0x%08x)",
664			ipaddr_string(obj_tptr+offset),
665			EXTRACT_32BITS(obj_tptr+offset));
666			offset+=4;
667		}
668                break;
669#ifdef INET6
670	    case LMP_CTYPE_IPV6:
671#endif
672	    default:
673                hexdump=TRUE;
674            }
675            break;
676
677        case LMP_OBJ_ERROR_CODE:
678	    switch(lmp_obj_ctype) {
679            case LMP_CTYPE_BEGIN_VERIFY_ERROR:
680		printf("\n\t    Error Code: %s",
681		bittok2str(lmp_obj_begin_verify_error_values,
682			"none",
683			EXTRACT_32BITS(obj_tptr)));
684                break;
685
686            case LMP_CTYPE_LINK_SUMMARY_ERROR:
687		printf("\n\t    Error Code: %s",
688		bittok2str(lmp_obj_link_summary_error_values,
689			"none",
690			EXTRACT_32BITS(obj_tptr)));
691                break;
692            default:
693                hexdump=TRUE;
694            }
695            break;
696
697        default:
698            if (vflag <= 1)
699                print_unknown_data(obj_tptr,"\n\t    ",obj_tlen);
700            break;
701        }
702        /* do we want to see an additionally hexdump ? */
703        if (vflag > 1 || hexdump==TRUE)
704            print_unknown_data(tptr+sizeof(sizeof(struct lmp_object_header)),"\n\t    ",
705                               lmp_obj_len-sizeof(struct lmp_object_header));
706
707        tptr+=lmp_obj_len;
708        tlen-=lmp_obj_len;
709    }
710    return;
711trunc:
712    printf("\n\t\t packet exceeded snapshot");
713}
714