xref: /dflybsd-src/contrib/tcpdump/print-ldp.c (revision 59c07fbdf8168fa08c76c515186d561b5a92690c)
141c99275SPeter Avalos /*
241c99275SPeter Avalos  * Redistribution and use in source and binary forms, with or without
341c99275SPeter Avalos  * modification, are permitted provided that: (1) source code
441c99275SPeter Avalos  * distributions retain the above copyright notice and this paragraph
541c99275SPeter Avalos  * in its entirety, and (2) distributions including binary code include
641c99275SPeter Avalos  * the above copyright notice and this paragraph in its entirety in
741c99275SPeter Avalos  * the documentation or other materials provided with the distribution.
841c99275SPeter Avalos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
941c99275SPeter Avalos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
1041c99275SPeter Avalos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1141c99275SPeter Avalos  * FOR A PARTICULAR PURPOSE.
1241c99275SPeter Avalos  *
13411677aeSAaron LI  * Original code by Hannes Gredler (hannes@gredler.at)
1441c99275SPeter Avalos  *  and Steinar Haug (sthaug@nethelp.no)
1541c99275SPeter Avalos  */
1641c99275SPeter Avalos 
17411677aeSAaron LI /* \summary: Label Distribution Protocol (LDP) printer */
1841c99275SPeter Avalos 
1941c99275SPeter Avalos #ifdef HAVE_CONFIG_H
20*ed775ee7SAntonio Huete Jimenez #include <config.h>
2141c99275SPeter Avalos #endif
2241c99275SPeter Avalos 
23*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
2441c99275SPeter Avalos 
25411677aeSAaron LI #include "netdissect.h"
2641c99275SPeter Avalos #include "extract.h"
2741c99275SPeter Avalos #include "addrtoname.h"
2841c99275SPeter Avalos 
2941c99275SPeter Avalos #include "l2vpn.h"
30ea7b4bf5SPeter Avalos #include "af.h"
3141c99275SPeter Avalos 
32411677aeSAaron LI 
3341c99275SPeter Avalos /*
3441c99275SPeter Avalos  * ldp common header
3541c99275SPeter Avalos  *
3641c99275SPeter Avalos  *  0                   1                   2                   3
3741c99275SPeter Avalos  *  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
3841c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3941c99275SPeter Avalos  * |  Version                      |         PDU Length            |
4041c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4141c99275SPeter Avalos  * |                         LDP Identifier                        |
4241c99275SPeter Avalos  * +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4341c99275SPeter Avalos  * |                               |
4441c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4541c99275SPeter Avalos  *
4641c99275SPeter Avalos  */
4741c99275SPeter Avalos 
4841c99275SPeter Avalos struct ldp_common_header {
49*ed775ee7SAntonio Huete Jimenez     nd_uint16_t version;
50*ed775ee7SAntonio Huete Jimenez     nd_uint16_t pdu_length;
51*ed775ee7SAntonio Huete Jimenez     nd_ipv4     lsr_id;
52*ed775ee7SAntonio Huete Jimenez     nd_uint16_t label_space;
5341c99275SPeter Avalos };
5441c99275SPeter Avalos 
5541c99275SPeter Avalos #define LDP_VERSION 1
5641c99275SPeter Avalos 
5741c99275SPeter Avalos /*
5841c99275SPeter Avalos  * ldp message header
5941c99275SPeter Avalos  *
6041c99275SPeter Avalos  *  0                   1                   2                   3
6141c99275SPeter Avalos  *  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
6241c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6341c99275SPeter Avalos  * |U|   Message Type              |      Message Length           |
6441c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6541c99275SPeter Avalos  * |                     Message ID                                |
6641c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6741c99275SPeter Avalos  * |                                                               |
6841c99275SPeter Avalos  * +                                                               +
6941c99275SPeter Avalos  * |                     Mandatory Parameters                      |
7041c99275SPeter Avalos  * +                                                               +
7141c99275SPeter Avalos  * |                                                               |
7241c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
7341c99275SPeter Avalos  * |                                                               |
7441c99275SPeter Avalos  * +                                                               +
7541c99275SPeter Avalos  * |                     Optional Parameters                       |
7641c99275SPeter Avalos  * +                                                               +
7741c99275SPeter Avalos  * |                                                               |
7841c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
7941c99275SPeter Avalos  */
8041c99275SPeter Avalos 
8141c99275SPeter Avalos struct ldp_msg_header {
82*ed775ee7SAntonio Huete Jimenez     nd_uint16_t type;
83*ed775ee7SAntonio Huete Jimenez     nd_uint16_t length;
84*ed775ee7SAntonio Huete Jimenez     nd_uint32_t id;
8541c99275SPeter Avalos };
8641c99275SPeter Avalos 
8741c99275SPeter Avalos #define	LDP_MASK_MSG_TYPE(x)  ((x)&0x7fff)
8841c99275SPeter Avalos #define	LDP_MASK_U_BIT(x)     ((x)&0x8000)
8941c99275SPeter Avalos 
9041c99275SPeter Avalos #define	LDP_MSG_NOTIF                0x0001
9141c99275SPeter Avalos #define	LDP_MSG_HELLO                0x0100
9241c99275SPeter Avalos #define	LDP_MSG_INIT                 0x0200
9341c99275SPeter Avalos #define	LDP_MSG_KEEPALIVE            0x0201
9441c99275SPeter Avalos #define	LDP_MSG_ADDRESS              0x0300
9541c99275SPeter Avalos #define	LDP_MSG_ADDRESS_WITHDRAW     0x0301
9641c99275SPeter Avalos #define	LDP_MSG_LABEL_MAPPING        0x0400
9741c99275SPeter Avalos #define	LDP_MSG_LABEL_REQUEST        0x0401
9841c99275SPeter Avalos #define	LDP_MSG_LABEL_WITHDRAW       0x0402
9941c99275SPeter Avalos #define	LDP_MSG_LABEL_RELEASE        0x0403
10041c99275SPeter Avalos #define	LDP_MSG_LABEL_ABORT_REQUEST  0x0404
10141c99275SPeter Avalos 
10241c99275SPeter Avalos #define	LDP_VENDOR_PRIVATE_MIN       0x3e00
10341c99275SPeter Avalos #define	LDP_VENDOR_PRIVATE_MAX       0x3eff
10441c99275SPeter Avalos #define	LDP_EXPERIMENTAL_MIN         0x3f00
10541c99275SPeter Avalos #define	LDP_EXPERIMENTAL_MAX         0x3fff
10641c99275SPeter Avalos 
10741c99275SPeter Avalos static const struct tok ldp_msg_values[] = {
10841c99275SPeter Avalos     { LDP_MSG_NOTIF,	             "Notification" },
10941c99275SPeter Avalos     { LDP_MSG_HELLO,	             "Hello" },
11041c99275SPeter Avalos     { LDP_MSG_INIT,	             "Initialization" },
11141c99275SPeter Avalos     { LDP_MSG_KEEPALIVE,             "Keepalive" },
11241c99275SPeter Avalos     { LDP_MSG_ADDRESS,	             "Address" },
11341c99275SPeter Avalos     { LDP_MSG_ADDRESS_WITHDRAW,	     "Address Withdraw" },
11441c99275SPeter Avalos     { LDP_MSG_LABEL_MAPPING,	     "Label Mapping" },
11541c99275SPeter Avalos     { LDP_MSG_LABEL_REQUEST,	     "Label Request" },
11641c99275SPeter Avalos     { LDP_MSG_LABEL_WITHDRAW,	     "Label Withdraw" },
11741c99275SPeter Avalos     { LDP_MSG_LABEL_RELEASE,	     "Label Release" },
11841c99275SPeter Avalos     { LDP_MSG_LABEL_ABORT_REQUEST,   "Label Abort Request" },
11941c99275SPeter Avalos     { 0, NULL}
12041c99275SPeter Avalos };
12141c99275SPeter Avalos 
12241c99275SPeter Avalos #define	LDP_MASK_TLV_TYPE(x)  ((x)&0x3fff)
12341c99275SPeter Avalos #define	LDP_MASK_F_BIT(x) ((x)&0x4000)
12441c99275SPeter Avalos 
12541c99275SPeter Avalos #define	LDP_TLV_FEC                  0x0100
12641c99275SPeter Avalos #define	LDP_TLV_ADDRESS_LIST         0x0101
127ea7b4bf5SPeter Avalos #define LDP_TLV_ADDRESS_LIST_AFNUM_LEN 2
12841c99275SPeter Avalos #define	LDP_TLV_HOP_COUNT            0x0103
12941c99275SPeter Avalos #define	LDP_TLV_PATH_VECTOR          0x0104
13041c99275SPeter Avalos #define	LDP_TLV_GENERIC_LABEL        0x0200
13141c99275SPeter Avalos #define	LDP_TLV_ATM_LABEL            0x0201
13241c99275SPeter Avalos #define	LDP_TLV_FR_LABEL             0x0202
13341c99275SPeter Avalos #define	LDP_TLV_STATUS               0x0300
13441c99275SPeter Avalos #define	LDP_TLV_EXTD_STATUS          0x0301
13541c99275SPeter Avalos #define	LDP_TLV_RETURNED_PDU         0x0302
13641c99275SPeter Avalos #define	LDP_TLV_RETURNED_MSG         0x0303
13741c99275SPeter Avalos #define	LDP_TLV_COMMON_HELLO         0x0400
13841c99275SPeter Avalos #define	LDP_TLV_IPV4_TRANSPORT_ADDR  0x0401
13941c99275SPeter Avalos #define	LDP_TLV_CONFIG_SEQ_NUMBER    0x0402
14041c99275SPeter Avalos #define	LDP_TLV_IPV6_TRANSPORT_ADDR  0x0403
14141c99275SPeter Avalos #define	LDP_TLV_COMMON_SESSION       0x0500
14241c99275SPeter Avalos #define	LDP_TLV_ATM_SESSION_PARM     0x0501
14341c99275SPeter Avalos #define	LDP_TLV_FR_SESSION_PARM      0x0502
14441c99275SPeter Avalos #define LDP_TLV_FT_SESSION	     0x0503
14541c99275SPeter Avalos #define	LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600
146ea7b4bf5SPeter Avalos #define LDP_TLV_MTU                  0x0601 /* rfc 3988 */
14741c99275SPeter Avalos 
14841c99275SPeter Avalos static const struct tok ldp_tlv_values[] = {
14941c99275SPeter Avalos     { LDP_TLV_FEC,	             "FEC" },
15041c99275SPeter Avalos     { LDP_TLV_ADDRESS_LIST,          "Address List" },
15141c99275SPeter Avalos     { LDP_TLV_HOP_COUNT,             "Hop Count" },
15241c99275SPeter Avalos     { LDP_TLV_PATH_VECTOR,           "Path Vector" },
15341c99275SPeter Avalos     { LDP_TLV_GENERIC_LABEL,         "Generic Label" },
15441c99275SPeter Avalos     { LDP_TLV_ATM_LABEL,             "ATM Label" },
15541c99275SPeter Avalos     { LDP_TLV_FR_LABEL,              "Frame-Relay Label" },
15641c99275SPeter Avalos     { LDP_TLV_STATUS,                "Status" },
15741c99275SPeter Avalos     { LDP_TLV_EXTD_STATUS,           "Extended Status" },
15841c99275SPeter Avalos     { LDP_TLV_RETURNED_PDU,          "Returned PDU" },
15941c99275SPeter Avalos     { LDP_TLV_RETURNED_MSG,          "Returned Message" },
16041c99275SPeter Avalos     { LDP_TLV_COMMON_HELLO,          "Common Hello Parameters" },
16141c99275SPeter Avalos     { LDP_TLV_IPV4_TRANSPORT_ADDR,   "IPv4 Transport Address" },
16241c99275SPeter Avalos     { LDP_TLV_CONFIG_SEQ_NUMBER,     "Configuration Sequence Number" },
16341c99275SPeter Avalos     { LDP_TLV_IPV6_TRANSPORT_ADDR,   "IPv6 Transport Address" },
16441c99275SPeter Avalos     { LDP_TLV_COMMON_SESSION,        "Common Session Parameters" },
16541c99275SPeter Avalos     { LDP_TLV_ATM_SESSION_PARM,      "ATM Session Parameters" },
16641c99275SPeter Avalos     { LDP_TLV_FR_SESSION_PARM,       "Frame-Relay Session Parameters" },
16741c99275SPeter Avalos     { LDP_TLV_FT_SESSION,            "Fault-Tolerant Session Parameters" },
16841c99275SPeter Avalos     { LDP_TLV_LABEL_REQUEST_MSG_ID,  "Label Request Message ID" },
169ea7b4bf5SPeter Avalos     { LDP_TLV_MTU,                   "MTU" },
17041c99275SPeter Avalos     { 0, NULL}
17141c99275SPeter Avalos };
17241c99275SPeter Avalos 
17341c99275SPeter Avalos #define LDP_FEC_WILDCARD	0x01
17441c99275SPeter Avalos #define LDP_FEC_PREFIX		0x02
17541c99275SPeter Avalos #define LDP_FEC_HOSTADDRESS	0x03
1766263709fSPeter Avalos /* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */
17741c99275SPeter Avalos #define LDP_FEC_MARTINI_VC	0x80
17841c99275SPeter Avalos 
17941c99275SPeter Avalos static const struct tok ldp_fec_values[] = {
18041c99275SPeter Avalos     { LDP_FEC_WILDCARD,		"Wildcard" },
18141c99275SPeter Avalos     { LDP_FEC_PREFIX,		"Prefix" },
18241c99275SPeter Avalos     { LDP_FEC_HOSTADDRESS,	"Host address" },
18341c99275SPeter Avalos     { LDP_FEC_MARTINI_VC,	"Martini VC" },
18441c99275SPeter Avalos     { 0, NULL}
18541c99275SPeter Avalos };
18641c99275SPeter Avalos 
18741c99275SPeter Avalos #define LDP_FEC_MARTINI_IFPARM_MTU  0x01
18841c99275SPeter Avalos #define LDP_FEC_MARTINI_IFPARM_DESC 0x03
18941c99275SPeter Avalos #define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c
19041c99275SPeter Avalos 
19141c99275SPeter Avalos static const struct tok ldp_fec_martini_ifparm_values[] = {
19241c99275SPeter Avalos     { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" },
19341c99275SPeter Avalos     { LDP_FEC_MARTINI_IFPARM_DESC, "Description" },
19441c99275SPeter Avalos     { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" },
19541c99275SPeter Avalos     { 0, NULL}
19641c99275SPeter Avalos };
19741c99275SPeter Avalos 
19841c99275SPeter Avalos /* draft-ietf-pwe3-vccv-04.txt */
19941c99275SPeter Avalos static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = {
20041c99275SPeter Avalos     { 0x01, "PWE3 control word" },
20141c99275SPeter Avalos     { 0x02, "MPLS Router Alert Label" },
20241c99275SPeter Avalos     { 0x04, "MPLS inner label TTL = 1" },
20341c99275SPeter Avalos     { 0, NULL}
20441c99275SPeter Avalos };
20541c99275SPeter Avalos 
20641c99275SPeter Avalos /* draft-ietf-pwe3-vccv-04.txt */
20741c99275SPeter Avalos static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = {
20841c99275SPeter Avalos     { 0x01, "ICMP Ping" },
20941c99275SPeter Avalos     { 0x02, "LSP Ping" },
21041c99275SPeter Avalos     { 0x04, "BFD" },
21141c99275SPeter Avalos     { 0, NULL}
21241c99275SPeter Avalos };
21341c99275SPeter Avalos 
214*ed775ee7SAntonio Huete Jimenez static u_int ldp_pdu_print(netdissect_options *, const u_char *);
21541c99275SPeter Avalos 
21641c99275SPeter Avalos /*
21741c99275SPeter Avalos  * ldp tlv header
21841c99275SPeter Avalos  *
21941c99275SPeter Avalos  *  0                   1                   2                   3
22041c99275SPeter Avalos  *  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
22141c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22241c99275SPeter Avalos  * |U|F|        Type               |            Length             |
22341c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22441c99275SPeter Avalos  * |                                                               |
22541c99275SPeter Avalos  * |                             Value                             |
22641c99275SPeter Avalos  * ~                                                               ~
22741c99275SPeter Avalos  * |                                                               |
22841c99275SPeter Avalos  * |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22941c99275SPeter Avalos  * |                               |
23041c99275SPeter Avalos  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23141c99275SPeter Avalos  */
23241c99275SPeter Avalos 
2336263709fSPeter Avalos #define TLV_TCHECK(minlen) \
234*ed775ee7SAntonio Huete Jimenez     if (tlv_tlen < minlen) { \
235*ed775ee7SAntonio Huete Jimenez         ND_PRINT(" [tlv length %u < %u]", tlv_tlen, minlen); \
236*ed775ee7SAntonio Huete Jimenez         nd_print_invalid(ndo); \
237*ed775ee7SAntonio Huete Jimenez         goto invalid; \
238*ed775ee7SAntonio Huete Jimenez     }
2396263709fSPeter Avalos 
240*ed775ee7SAntonio Huete Jimenez static u_int
ldp_tlv_print(netdissect_options * ndo,const u_char * tptr,u_int msg_tlen)241411677aeSAaron LI ldp_tlv_print(netdissect_options *ndo,
242*ed775ee7SAntonio Huete Jimenez               const u_char *tptr,
243*ed775ee7SAntonio Huete Jimenez               u_int msg_tlen)
244411677aeSAaron LI {
24541c99275SPeter Avalos     struct ldp_tlv_header {
246*ed775ee7SAntonio Huete Jimenez         nd_uint16_t type;
247*ed775ee7SAntonio Huete Jimenez         nd_uint16_t length;
24841c99275SPeter Avalos     };
24941c99275SPeter Avalos 
25041c99275SPeter Avalos     const struct ldp_tlv_header *ldp_tlv_header;
25141c99275SPeter Avalos     u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
25241c99275SPeter Avalos     u_char fec_type;
25341c99275SPeter Avalos     u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
25441c99275SPeter Avalos     char buf[100];
25541c99275SPeter Avalos     int i;
25641c99275SPeter Avalos 
25741c99275SPeter Avalos     ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
258*ed775ee7SAntonio Huete Jimenez     ND_TCHECK_SIZE(ldp_tlv_header);
259*ed775ee7SAntonio Huete Jimenez     tlv_len=GET_BE_U_2(ldp_tlv_header->length);
260*ed775ee7SAntonio Huete Jimenez     if (tlv_len + 4U > msg_tlen) {
261*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t\t TLV contents go past end of message");
262411677aeSAaron LI         return 0;
263411677aeSAaron LI     }
26441c99275SPeter Avalos     tlv_tlen=tlv_len;
265*ed775ee7SAntonio Huete Jimenez     tlv_type=LDP_MASK_TLV_TYPE(GET_BE_U_2(ldp_tlv_header->type));
26641c99275SPeter Avalos 
26741c99275SPeter Avalos     /* FIXME vendor private / experimental check */
268*ed775ee7SAntonio Huete Jimenez     ND_PRINT("\n\t    %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
26941c99275SPeter Avalos            tok2str(ldp_tlv_values,
27041c99275SPeter Avalos                    "Unknown",
27141c99275SPeter Avalos                    tlv_type),
27241c99275SPeter Avalos            tlv_type,
27341c99275SPeter Avalos            tlv_len,
274*ed775ee7SAntonio Huete Jimenez            LDP_MASK_U_BIT(GET_BE_U_2(ldp_tlv_header->type)) ? "continue processing" : "ignore",
275*ed775ee7SAntonio Huete Jimenez            LDP_MASK_F_BIT(GET_BE_U_2(ldp_tlv_header->type)) ? "do" : "don't");
27641c99275SPeter Avalos 
27741c99275SPeter Avalos     tptr+=sizeof(struct ldp_tlv_header);
27841c99275SPeter Avalos 
27941c99275SPeter Avalos     switch(tlv_type) {
28041c99275SPeter Avalos 
28141c99275SPeter Avalos     case LDP_TLV_COMMON_HELLO:
2826263709fSPeter Avalos         TLV_TCHECK(4);
283*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t      Hold Time: %us, Flags: [%s Hello%s]",
284*ed775ee7SAntonio Huete Jimenez                GET_BE_U_2(tptr),
285*ed775ee7SAntonio Huete Jimenez                (GET_BE_U_2(tptr + 2)&0x8000) ? "Targeted" : "Link",
286*ed775ee7SAntonio Huete Jimenez                (GET_BE_U_2(tptr + 2)&0x4000) ? ", Request for targeted Hellos" : "");
28741c99275SPeter Avalos         break;
28841c99275SPeter Avalos 
28941c99275SPeter Avalos     case LDP_TLV_IPV4_TRANSPORT_ADDR:
2906263709fSPeter Avalos         TLV_TCHECK(4);
291*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t      IPv4 Transport Address: %s", GET_IPADDR_STRING(tptr));
29241c99275SPeter Avalos         break;
29341c99275SPeter Avalos     case LDP_TLV_IPV6_TRANSPORT_ADDR:
2946263709fSPeter Avalos         TLV_TCHECK(16);
295*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t      IPv6 Transport Address: %s", GET_IP6ADDR_STRING(tptr));
29641c99275SPeter Avalos         break;
29741c99275SPeter Avalos     case LDP_TLV_CONFIG_SEQ_NUMBER:
2986263709fSPeter Avalos         TLV_TCHECK(4);
299*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t      Sequence Number: %u", GET_BE_U_4(tptr));
30041c99275SPeter Avalos         break;
30141c99275SPeter Avalos 
30241c99275SPeter Avalos     case LDP_TLV_ADDRESS_LIST:
3036263709fSPeter Avalos         TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
304*ed775ee7SAntonio Huete Jimenez 	af = GET_BE_U_2(tptr);
305ea7b4bf5SPeter Avalos 	tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
306ea7b4bf5SPeter Avalos         tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
307*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      Address Family: %s, addresses",
308*ed775ee7SAntonio Huete Jimenez                tok2str(af_values, "Unknown (%u)", af));
309ea7b4bf5SPeter Avalos         switch (af) {
310ea7b4bf5SPeter Avalos         case AFNUM_INET:
311*ed775ee7SAntonio Huete Jimenez 	    while(tlv_tlen >= sizeof(nd_ipv4)) {
312*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" %s", GET_IPADDR_STRING(tptr));
313*ed775ee7SAntonio Huete Jimenez 		tlv_tlen-=sizeof(nd_ipv4);
314*ed775ee7SAntonio Huete Jimenez 		tptr+=sizeof(nd_ipv4);
31541c99275SPeter Avalos 	    }
316ea7b4bf5SPeter Avalos             break;
317ea7b4bf5SPeter Avalos         case AFNUM_INET6:
318*ed775ee7SAntonio Huete Jimenez 	    while(tlv_tlen >= sizeof(nd_ipv6)) {
319*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(" %s", GET_IP6ADDR_STRING(tptr));
320*ed775ee7SAntonio Huete Jimenez 		tlv_tlen-=sizeof(nd_ipv6);
321*ed775ee7SAntonio Huete Jimenez 		tptr+=sizeof(nd_ipv6);
32241c99275SPeter Avalos 	    }
323ea7b4bf5SPeter Avalos             break;
324ea7b4bf5SPeter Avalos         default:
325ea7b4bf5SPeter Avalos             /* unknown AF */
326ea7b4bf5SPeter Avalos             break;
327ea7b4bf5SPeter Avalos         }
32841c99275SPeter Avalos 	break;
32941c99275SPeter Avalos 
33041c99275SPeter Avalos     case LDP_TLV_COMMON_SESSION:
3316263709fSPeter Avalos 	TLV_TCHECK(8);
332*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
333*ed775ee7SAntonio Huete Jimenez 	       GET_BE_U_2(tptr), GET_BE_U_2(tptr + 2),
334*ed775ee7SAntonio Huete Jimenez 	       (GET_BE_U_2(tptr + 6)&0x8000) ? "On Demand" : "Unsolicited",
335*ed775ee7SAntonio Huete Jimenez 	       (GET_BE_U_2(tptr + 6)&0x4000) ? "Enabled" : "Disabled"
336*ed775ee7SAntonio Huete Jimenez 	       );
33741c99275SPeter Avalos 	break;
33841c99275SPeter Avalos 
33941c99275SPeter Avalos     case LDP_TLV_FEC:
3406263709fSPeter Avalos         TLV_TCHECK(1);
341*ed775ee7SAntonio Huete Jimenez         fec_type = GET_U_1(tptr);
342*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      %s FEC (0x%02x)",
34341c99275SPeter Avalos 	       tok2str(ldp_fec_values, "Unknown", fec_type),
344*ed775ee7SAntonio Huete Jimenez 	       fec_type);
34541c99275SPeter Avalos 
34641c99275SPeter Avalos 	tptr+=1;
3476263709fSPeter Avalos 	tlv_tlen-=1;
34841c99275SPeter Avalos 	switch(fec_type) {
34941c99275SPeter Avalos 
35041c99275SPeter Avalos 	case LDP_FEC_WILDCARD:
35141c99275SPeter Avalos 	    break;
35241c99275SPeter Avalos 	case LDP_FEC_PREFIX:
3536263709fSPeter Avalos 	    TLV_TCHECK(2);
354*ed775ee7SAntonio Huete Jimenez 	    af = GET_BE_U_2(tptr);
355*ed775ee7SAntonio Huete Jimenez 	    tptr+=2;
356*ed775ee7SAntonio Huete Jimenez 	    tlv_tlen-=2;
35741c99275SPeter Avalos 	    if (af == AFNUM_INET) {
358411677aeSAaron LI 		i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf));
3596263709fSPeter Avalos 		if (i == -2)
3606263709fSPeter Avalos 		    goto trunc;
3616263709fSPeter Avalos 		if (i == -3)
362*ed775ee7SAntonio Huete Jimenez 		    ND_PRINT(": IPv4 prefix (goes past end of TLV)");
3636263709fSPeter Avalos 		else if (i == -1)
364*ed775ee7SAntonio Huete Jimenez 		    ND_PRINT(": IPv4 prefix (invalid length)");
3656263709fSPeter Avalos 		else
366*ed775ee7SAntonio Huete Jimenez 		    ND_PRINT(": IPv4 prefix %s", buf);
36741c99275SPeter Avalos 	    }
36841c99275SPeter Avalos 	    else if (af == AFNUM_INET6) {
369411677aeSAaron LI 		i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf));
3706263709fSPeter Avalos 		if (i == -2)
3716263709fSPeter Avalos 		    goto trunc;
3726263709fSPeter Avalos 		if (i == -3)
373*ed775ee7SAntonio Huete Jimenez 		    ND_PRINT(": IPv4 prefix (goes past end of TLV)");
3746263709fSPeter Avalos 		else if (i == -1)
375*ed775ee7SAntonio Huete Jimenez 		    ND_PRINT(": IPv6 prefix (invalid length)");
3766263709fSPeter Avalos 		else
377*ed775ee7SAntonio Huete Jimenez 		    ND_PRINT(": IPv6 prefix %s", buf);
37841c99275SPeter Avalos 	    }
3796263709fSPeter Avalos 	    else
380*ed775ee7SAntonio Huete Jimenez 		ND_PRINT(": Address family %u prefix", af);
38141c99275SPeter Avalos 	    break;
38241c99275SPeter Avalos 	case LDP_FEC_HOSTADDRESS:
38341c99275SPeter Avalos 	    break;
38441c99275SPeter Avalos 	case LDP_FEC_MARTINI_VC:
3856263709fSPeter Avalos             /*
386411677aeSAaron LI              * We assume the type was supposed to be one of the MPLS
387411677aeSAaron LI              * Pseudowire Types.
3886263709fSPeter Avalos              */
3896263709fSPeter Avalos             TLV_TCHECK(7);
390*ed775ee7SAntonio Huete Jimenez             vc_info_len = GET_U_1(tptr + 2);
39141c99275SPeter Avalos 
392411677aeSAaron LI             /*
393411677aeSAaron LI 	     * According to RFC 4908, the VC info Length field can be zero,
394411677aeSAaron LI 	     * in which case not only are there no interface parameters,
395411677aeSAaron LI 	     * there's no VC ID.
396411677aeSAaron LI 	     */
3976263709fSPeter Avalos             if (vc_info_len == 0) {
398*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
399*ed775ee7SAntonio Huete Jimenez                        tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff),
400*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_2(tptr)&0x8000 ? "" : "no ",
401*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_4(tptr + 3),
402*ed775ee7SAntonio Huete Jimenez                        vc_info_len);
4036263709fSPeter Avalos                 break;
4046263709fSPeter Avalos             }
4056263709fSPeter Avalos 
4066263709fSPeter Avalos             /* Make sure we have the VC ID as well */
4076263709fSPeter Avalos             TLV_TCHECK(11);
408*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
409*ed775ee7SAntonio Huete Jimenez 		   tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff),
410*ed775ee7SAntonio Huete Jimenez 		   GET_BE_U_2(tptr)&0x8000 ? "" : "no ",
411*ed775ee7SAntonio Huete Jimenez 		   GET_BE_U_4(tptr + 3),
412*ed775ee7SAntonio Huete Jimenez 		   GET_BE_U_4(tptr + 7),
413*ed775ee7SAntonio Huete Jimenez 		   vc_info_len);
414411677aeSAaron LI             if (vc_info_len < 4) {
415411677aeSAaron LI                 /* minimum 4, for the VC ID */
416*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (invalid, < 4");
417411677aeSAaron LI                 return(tlv_len+4); /* Type & Length fields not included */
418411677aeSAaron LI 	    }
4196263709fSPeter Avalos             vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */
42041c99275SPeter Avalos 
4216263709fSPeter Avalos             /* Skip past the fixed information and the VC ID */
42241c99275SPeter Avalos             tptr+=11;
4236263709fSPeter Avalos             tlv_tlen-=11;
4246263709fSPeter Avalos             TLV_TCHECK(vc_info_len);
42541c99275SPeter Avalos 
42641c99275SPeter Avalos             while (vc_info_len > 2) {
427*ed775ee7SAntonio Huete Jimenez                 vc_info_tlv_type = GET_U_1(tptr);
428*ed775ee7SAntonio Huete Jimenez                 vc_info_tlv_len = GET_U_1(tptr + 1);
42941c99275SPeter Avalos                 if (vc_info_tlv_len < 2)
43041c99275SPeter Avalos                     break;
43141c99275SPeter Avalos                 if (vc_info_len < vc_info_tlv_len)
43241c99275SPeter Avalos                     break;
43341c99275SPeter Avalos 
434*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("\n\t\tInterface Parameter: %s (0x%02x), len %u",
43541c99275SPeter Avalos                        tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
43641c99275SPeter Avalos                        vc_info_tlv_type,
437*ed775ee7SAntonio Huete Jimenez                        vc_info_tlv_len);
43841c99275SPeter Avalos 
43941c99275SPeter Avalos                 switch(vc_info_tlv_type) {
44041c99275SPeter Avalos                 case LDP_FEC_MARTINI_IFPARM_MTU:
441*ed775ee7SAntonio Huete Jimenez                     ND_PRINT(": %u", GET_BE_U_2(tptr + 2));
44241c99275SPeter Avalos                     break;
44341c99275SPeter Avalos 
44441c99275SPeter Avalos                 case LDP_FEC_MARTINI_IFPARM_DESC:
445*ed775ee7SAntonio Huete Jimenez                     ND_PRINT(": ");
446*ed775ee7SAntonio Huete Jimenez                     for (idx = 2; idx < vc_info_tlv_len; idx++)
447*ed775ee7SAntonio Huete Jimenez                         fn_print_char(ndo, GET_U_1(tptr + idx));
44841c99275SPeter Avalos                     break;
44941c99275SPeter Avalos 
45041c99275SPeter Avalos                 case LDP_FEC_MARTINI_IFPARM_VCCV:
451*ed775ee7SAntonio Huete Jimenez                     ND_PRINT("\n\t\t  Control Channels (0x%02x) = [%s]",
452*ed775ee7SAntonio Huete Jimenez                            GET_U_1((tptr + 2)),
453*ed775ee7SAntonio Huete Jimenez                            bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", GET_U_1((tptr + 2))));
454*ed775ee7SAntonio Huete Jimenez                     ND_PRINT("\n\t\t  CV Types (0x%02x) = [%s]",
455*ed775ee7SAntonio Huete Jimenez                            GET_U_1((tptr + 3)),
456*ed775ee7SAntonio Huete Jimenez                            bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", GET_U_1((tptr + 3))));
45741c99275SPeter Avalos                     break;
45841c99275SPeter Avalos 
45941c99275SPeter Avalos                 default:
460411677aeSAaron LI                     print_unknown_data(ndo, tptr+2, "\n\t\t  ", vc_info_tlv_len-2);
46141c99275SPeter Avalos                     break;
46241c99275SPeter Avalos                 }
46341c99275SPeter Avalos 
46441c99275SPeter Avalos                 vc_info_len -= vc_info_tlv_len;
46541c99275SPeter Avalos                 tptr += vc_info_tlv_len;
46641c99275SPeter Avalos             }
46741c99275SPeter Avalos 	    break;
46841c99275SPeter Avalos 	}
46941c99275SPeter Avalos 
47041c99275SPeter Avalos 	break;
47141c99275SPeter Avalos 
47241c99275SPeter Avalos     case LDP_TLV_GENERIC_LABEL:
4736263709fSPeter Avalos 	TLV_TCHECK(4);
474*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      Label: %u", GET_BE_U_4(tptr) & 0xfffff);
47541c99275SPeter Avalos 	break;
47641c99275SPeter Avalos 
47741c99275SPeter Avalos     case LDP_TLV_STATUS:
4786263709fSPeter Avalos 	TLV_TCHECK(8);
479*ed775ee7SAntonio Huete Jimenez 	ui = GET_BE_U_4(tptr);
48041c99275SPeter Avalos 	tptr+=4;
481*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      Status: 0x%02x, Flags: [%s and %s forward]",
48241c99275SPeter Avalos 	       ui&0x3fffffff,
48341c99275SPeter Avalos 	       ui&0x80000000 ? "Fatal error" : "Advisory Notification",
484*ed775ee7SAntonio Huete Jimenez 	       ui&0x40000000 ? "do" : "don't");
485*ed775ee7SAntonio Huete Jimenez 	ui = GET_BE_U_4(tptr);
48641c99275SPeter Avalos 	tptr+=4;
48741c99275SPeter Avalos 	if (ui)
488*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(", causing Message ID: 0x%08x", ui);
48941c99275SPeter Avalos 	break;
49041c99275SPeter Avalos 
49141c99275SPeter Avalos     case LDP_TLV_FT_SESSION:
492411677aeSAaron LI 	TLV_TCHECK(12);
493*ed775ee7SAntonio Huete Jimenez 	ft_flags = GET_BE_U_2(tptr);
494*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
49541c99275SPeter Avalos 	       ft_flags&0x8000 ? "" : "No ",
49641c99275SPeter Avalos 	       ft_flags&0x8 ? "" : "Don't ",
49741c99275SPeter Avalos 	       ft_flags&0x4 ? "" : "No ",
49841c99275SPeter Avalos 	       ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
499*ed775ee7SAntonio Huete Jimenez 	       ft_flags&0x1 ? "" : "Don't ");
500411677aeSAaron LI 	/* 16 bits (FT Flags) + 16 bits (Reserved) */
50141c99275SPeter Avalos 	tptr+=4;
502*ed775ee7SAntonio Huete Jimenez 	ui = GET_BE_U_4(tptr);
50341c99275SPeter Avalos 	if (ui)
504*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(", Reconnect Timeout: %ums", ui);
50541c99275SPeter Avalos 	tptr+=4;
506*ed775ee7SAntonio Huete Jimenez 	ui = GET_BE_U_4(tptr);
50741c99275SPeter Avalos 	if (ui)
508*ed775ee7SAntonio Huete Jimenez 	    ND_PRINT(", Recovery Time: %ums", ui);
50941c99275SPeter Avalos 	break;
51041c99275SPeter Avalos 
511ea7b4bf5SPeter Avalos     case LDP_TLV_MTU:
5126263709fSPeter Avalos 	TLV_TCHECK(2);
513*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("\n\t      MTU: %u", GET_BE_U_2(tptr));
514ea7b4bf5SPeter Avalos 	break;
515ea7b4bf5SPeter Avalos 
51641c99275SPeter Avalos 
51741c99275SPeter Avalos     /*
51841c99275SPeter Avalos      *  FIXME those are the defined TLVs that lack a decoder
51941c99275SPeter Avalos      *  you are welcome to contribute code ;-)
52041c99275SPeter Avalos      */
52141c99275SPeter Avalos 
52241c99275SPeter Avalos     case LDP_TLV_HOP_COUNT:
52341c99275SPeter Avalos     case LDP_TLV_PATH_VECTOR:
52441c99275SPeter Avalos     case LDP_TLV_ATM_LABEL:
52541c99275SPeter Avalos     case LDP_TLV_FR_LABEL:
52641c99275SPeter Avalos     case LDP_TLV_EXTD_STATUS:
52741c99275SPeter Avalos     case LDP_TLV_RETURNED_PDU:
52841c99275SPeter Avalos     case LDP_TLV_RETURNED_MSG:
52941c99275SPeter Avalos     case LDP_TLV_ATM_SESSION_PARM:
53041c99275SPeter Avalos     case LDP_TLV_FR_SESSION_PARM:
53141c99275SPeter Avalos     case LDP_TLV_LABEL_REQUEST_MSG_ID:
53241c99275SPeter Avalos 
53341c99275SPeter Avalos     default:
534411677aeSAaron LI         if (ndo->ndo_vflag <= 1)
535411677aeSAaron LI             print_unknown_data(ndo, tptr, "\n\t      ", tlv_tlen);
53641c99275SPeter Avalos         break;
53741c99275SPeter Avalos     }
53841c99275SPeter Avalos     return(tlv_len+4); /* Type & Length fields not included */
53941c99275SPeter Avalos 
54041c99275SPeter Avalos trunc:
541*ed775ee7SAntonio Huete Jimenez     nd_trunc_longjmp(ndo);
5426263709fSPeter Avalos 
543*ed775ee7SAntonio Huete Jimenez invalid:
5446263709fSPeter Avalos     return(tlv_len+4); /* Type & Length fields not included */
54541c99275SPeter Avalos }
54641c99275SPeter Avalos 
54741c99275SPeter Avalos void
ldp_print(netdissect_options * ndo,const u_char * pptr,u_int len)548411677aeSAaron LI ldp_print(netdissect_options *ndo,
549*ed775ee7SAntonio Huete Jimenez           const u_char *pptr, u_int len)
550411677aeSAaron LI {
551411677aeSAaron LI     u_int processed;
552*ed775ee7SAntonio Huete Jimenez 
553*ed775ee7SAntonio Huete Jimenez     ndo->ndo_protocol = "ldp";
55441c99275SPeter Avalos     while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
555411677aeSAaron LI         processed = ldp_pdu_print(ndo, pptr);
55641c99275SPeter Avalos         if (processed == 0)
55741c99275SPeter Avalos             return;
558411677aeSAaron LI         if (len < processed) {
559*ed775ee7SAntonio Huete Jimenez             ND_PRINT(" [remaining length %u < %u]", len, processed);
560*ed775ee7SAntonio Huete Jimenez             nd_print_invalid(ndo);
561411677aeSAaron LI             break;
562411677aeSAaron LI         }
56341c99275SPeter Avalos         len -= processed;
56441c99275SPeter Avalos         pptr += processed;
56541c99275SPeter Avalos     }
56641c99275SPeter Avalos }
56741c99275SPeter Avalos 
568411677aeSAaron LI static u_int
ldp_pdu_print(netdissect_options * ndo,const u_char * pptr)569411677aeSAaron LI ldp_pdu_print(netdissect_options *ndo,
570*ed775ee7SAntonio Huete Jimenez               const u_char *pptr)
571411677aeSAaron LI {
57241c99275SPeter Avalos     const struct ldp_common_header *ldp_com_header;
57341c99275SPeter Avalos     const struct ldp_msg_header *ldp_msg_header;
57441c99275SPeter Avalos     const u_char *tptr,*msg_tptr;
57541c99275SPeter Avalos     u_short tlen;
576*ed775ee7SAntonio Huete Jimenez     u_short pdu_len,msg_len,msg_type;
577*ed775ee7SAntonio Huete Jimenez     u_int msg_tlen;
57841c99275SPeter Avalos     int hexdump,processed;
57941c99275SPeter Avalos 
58041c99275SPeter Avalos     ldp_com_header = (const struct ldp_common_header *)pptr;
581*ed775ee7SAntonio Huete Jimenez     ND_TCHECK_SIZE(ldp_com_header);
58241c99275SPeter Avalos 
58341c99275SPeter Avalos     /*
58441c99275SPeter Avalos      * Sanity checking of the header.
58541c99275SPeter Avalos      */
586*ed775ee7SAntonio Huete Jimenez     if (GET_BE_U_2(ldp_com_header->version) != LDP_VERSION) {
587*ed775ee7SAntonio Huete Jimenez 	ND_PRINT("%sLDP version %u packet not supported",
588411677aeSAaron LI                (ndo->ndo_vflag < 1) ? "" : "\n\t",
589*ed775ee7SAntonio Huete Jimenez                GET_BE_U_2(ldp_com_header->version));
590411677aeSAaron LI 	return 0;
591411677aeSAaron LI     }
592411677aeSAaron LI 
593*ed775ee7SAntonio Huete Jimenez     pdu_len = GET_BE_U_2(ldp_com_header->pdu_length);
594*ed775ee7SAntonio Huete Jimenez     if (pdu_len < sizeof(struct ldp_common_header)-4) {
595411677aeSAaron LI         /* length too short */
596*ed775ee7SAntonio Huete Jimenez         ND_PRINT("%sLDP, pdu-length: %u (too short, < %zu)",
597411677aeSAaron LI                  (ndo->ndo_vflag < 1) ? "" : "\n\t",
598411677aeSAaron LI                  pdu_len,
599*ed775ee7SAntonio Huete Jimenez                  sizeof(struct ldp_common_header)-4);
60041c99275SPeter Avalos         return 0;
60141c99275SPeter Avalos     }
60241c99275SPeter Avalos 
60341c99275SPeter Avalos     /* print the LSR-ID, label-space & length */
604*ed775ee7SAntonio Huete Jimenez     ND_PRINT("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
605411677aeSAaron LI            (ndo->ndo_vflag < 1) ? "" : "\n\t",
606*ed775ee7SAntonio Huete Jimenez            GET_IPADDR_STRING(ldp_com_header->lsr_id),
607*ed775ee7SAntonio Huete Jimenez            GET_BE_U_2(ldp_com_header->label_space),
608*ed775ee7SAntonio Huete Jimenez            pdu_len);
60941c99275SPeter Avalos 
61041c99275SPeter Avalos     /* bail out if non-verbose */
611411677aeSAaron LI     if (ndo->ndo_vflag < 1)
61241c99275SPeter Avalos         return 0;
61341c99275SPeter Avalos 
61441c99275SPeter Avalos     /* ok they seem to want to know everything - lets fully decode it */
615*ed775ee7SAntonio Huete Jimenez     tptr = pptr + sizeof(struct ldp_common_header);
616*ed775ee7SAntonio Huete Jimenez     tlen = pdu_len - (sizeof(struct ldp_common_header)-4);	/* Type & Length fields not included */
61741c99275SPeter Avalos 
61841c99275SPeter Avalos     while(tlen>0) {
61941c99275SPeter Avalos         /* did we capture enough for fully decoding the msg header ? */
620*ed775ee7SAntonio Huete Jimenez         ND_TCHECK_LEN(tptr, sizeof(struct ldp_msg_header));
62141c99275SPeter Avalos 
62241c99275SPeter Avalos         ldp_msg_header = (const struct ldp_msg_header *)tptr;
623*ed775ee7SAntonio Huete Jimenez         msg_len=GET_BE_U_2(ldp_msg_header->length);
624*ed775ee7SAntonio Huete Jimenez         msg_type=LDP_MASK_MSG_TYPE(GET_BE_U_2(ldp_msg_header->type));
62541c99275SPeter Avalos 
626411677aeSAaron LI         if (msg_len < sizeof(struct ldp_msg_header)-4) {
627411677aeSAaron LI             /* length too short */
62841c99275SPeter Avalos             /* FIXME vendor private / experimental check */
629*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t  %s Message (0x%04x), length: %u (too short, < %zu)",
630411677aeSAaron LI                      tok2str(ldp_msg_values,
631411677aeSAaron LI                              "Unknown",
632411677aeSAaron LI                              msg_type),
633411677aeSAaron LI                      msg_type,
634411677aeSAaron LI                      msg_len,
635*ed775ee7SAntonio Huete Jimenez                      sizeof(struct ldp_msg_header)-4);
636411677aeSAaron LI             return 0;
637411677aeSAaron LI         }
638411677aeSAaron LI 
639411677aeSAaron LI         /* FIXME vendor private / experimental check */
640*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t  %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
64141c99275SPeter Avalos                tok2str(ldp_msg_values,
64241c99275SPeter Avalos                        "Unknown",
64341c99275SPeter Avalos                        msg_type),
64441c99275SPeter Avalos                msg_type,
64541c99275SPeter Avalos                msg_len,
646*ed775ee7SAntonio Huete Jimenez                GET_BE_U_4(ldp_msg_header->id),
647*ed775ee7SAntonio Huete Jimenez                LDP_MASK_U_BIT(GET_BE_U_2(ldp_msg_header->type)) ? "continue processing" : "ignore");
64841c99275SPeter Avalos 
64941c99275SPeter Avalos         msg_tptr=tptr+sizeof(struct ldp_msg_header);
650411677aeSAaron LI         msg_tlen=msg_len-(sizeof(struct ldp_msg_header)-4); /* Type & Length fields not included */
65141c99275SPeter Avalos 
65241c99275SPeter Avalos         /* did we capture enough for fully decoding the message ? */
653*ed775ee7SAntonio Huete Jimenez         ND_TCHECK_LEN(tptr, msg_len);
65441c99275SPeter Avalos         hexdump=FALSE;
65541c99275SPeter Avalos 
65641c99275SPeter Avalos         switch(msg_type) {
65741c99275SPeter Avalos 
65841c99275SPeter Avalos         case LDP_MSG_NOTIF:
65941c99275SPeter Avalos         case LDP_MSG_HELLO:
66041c99275SPeter Avalos         case LDP_MSG_INIT:
66141c99275SPeter Avalos         case LDP_MSG_KEEPALIVE:
66241c99275SPeter Avalos         case LDP_MSG_ADDRESS:
66341c99275SPeter Avalos         case LDP_MSG_LABEL_MAPPING:
66441c99275SPeter Avalos         case LDP_MSG_ADDRESS_WITHDRAW:
66541c99275SPeter Avalos         case LDP_MSG_LABEL_WITHDRAW:
66641c99275SPeter Avalos             while(msg_tlen >= 4) {
667411677aeSAaron LI                 processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen);
66841c99275SPeter Avalos                 if (processed == 0)
66941c99275SPeter Avalos                     break;
67041c99275SPeter Avalos                 msg_tlen-=processed;
67141c99275SPeter Avalos                 msg_tptr+=processed;
67241c99275SPeter Avalos             }
67341c99275SPeter Avalos             break;
67441c99275SPeter Avalos 
67541c99275SPeter Avalos         /*
67641c99275SPeter Avalos          *  FIXME those are the defined messages that lack a decoder
67741c99275SPeter Avalos          *  you are welcome to contribute code ;-)
67841c99275SPeter Avalos          */
67941c99275SPeter Avalos 
68041c99275SPeter Avalos         case LDP_MSG_LABEL_REQUEST:
68141c99275SPeter Avalos         case LDP_MSG_LABEL_RELEASE:
68241c99275SPeter Avalos         case LDP_MSG_LABEL_ABORT_REQUEST:
68341c99275SPeter Avalos 
68441c99275SPeter Avalos         default:
685411677aeSAaron LI             if (ndo->ndo_vflag <= 1)
686411677aeSAaron LI                 print_unknown_data(ndo, msg_tptr, "\n\t  ", msg_tlen);
68741c99275SPeter Avalos             break;
68841c99275SPeter Avalos         }
68941c99275SPeter Avalos         /* do we want to see an additionally hexdump ? */
690411677aeSAaron LI         if (ndo->ndo_vflag > 1 || hexdump==TRUE)
691411677aeSAaron LI             print_unknown_data(ndo, tptr+sizeof(struct ldp_msg_header), "\n\t  ",
69241c99275SPeter Avalos                                msg_len);
69341c99275SPeter Avalos 
69441c99275SPeter Avalos         tptr += msg_len+4;
69541c99275SPeter Avalos         tlen -= msg_len+4;
69641c99275SPeter Avalos     }
69741c99275SPeter Avalos     return pdu_len+4;
69841c99275SPeter Avalos trunc:
699*ed775ee7SAntonio Huete Jimenez     nd_trunc_longjmp(ndo);
70041c99275SPeter Avalos }
701