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