15b0fe478SBruce M Simpson /*
25b0fe478SBruce M Simpson * Redistribution and use in source and binary forms, with or without
35b0fe478SBruce M Simpson * modification, are permitted provided that: (1) source code
45b0fe478SBruce M Simpson * distributions retain the above copyright notice and this paragraph
55b0fe478SBruce M Simpson * in its entirety, and (2) distributions including binary code include
65b0fe478SBruce M Simpson * the above copyright notice and this paragraph in its entirety in
75b0fe478SBruce M Simpson * the documentation or other materials provided with the distribution.
85b0fe478SBruce M Simpson * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
95b0fe478SBruce M Simpson * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
105b0fe478SBruce M Simpson * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
115b0fe478SBruce M Simpson * FOR A PARTICULAR PURPOSE.
125b0fe478SBruce M Simpson *
130bff6a5aSEd Maste * Original code by Hannes Gredler (hannes@gredler.at)
141de50e9fSSam Leffler * and Steinar Haug (sthaug@nethelp.no)
155b0fe478SBruce M Simpson */
165b0fe478SBruce M Simpson
173340d773SGleb Smirnoff /* \summary: Label Distribution Protocol (LDP) printer */
183340d773SGleb Smirnoff
19ee67461eSJoseph Mingrone #include <config.h>
205b0fe478SBruce M Simpson
21ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
225b0fe478SBruce M Simpson
233340d773SGleb Smirnoff #include "netdissect.h"
245b0fe478SBruce M Simpson #include "extract.h"
255b0fe478SBruce M Simpson #include "addrtoname.h"
265b0fe478SBruce M Simpson
271de50e9fSSam Leffler #include "l2vpn.h"
28a5779b6eSRui Paulo #include "af.h"
291de50e9fSSam Leffler
3039e421e8SCy Schubert
315b0fe478SBruce M Simpson /*
325b0fe478SBruce M Simpson * ldp common header
335b0fe478SBruce M Simpson *
345b0fe478SBruce M Simpson * 0 1 2 3
355b0fe478SBruce M Simpson * 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
365b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
375b0fe478SBruce M Simpson * | Version | PDU Length |
385b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
395b0fe478SBruce M Simpson * | LDP Identifier |
405b0fe478SBruce M Simpson * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
415b0fe478SBruce M Simpson * | |
425b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
435b0fe478SBruce M Simpson *
445b0fe478SBruce M Simpson */
455b0fe478SBruce M Simpson
465b0fe478SBruce M Simpson struct ldp_common_header {
47ee67461eSJoseph Mingrone nd_uint16_t version;
48ee67461eSJoseph Mingrone nd_uint16_t pdu_length;
49ee67461eSJoseph Mingrone nd_ipv4 lsr_id;
50ee67461eSJoseph Mingrone nd_uint16_t label_space;
515b0fe478SBruce M Simpson };
525b0fe478SBruce M Simpson
535b0fe478SBruce M Simpson #define LDP_VERSION 1
545b0fe478SBruce M Simpson
555b0fe478SBruce M Simpson /*
565b0fe478SBruce M Simpson * ldp message header
575b0fe478SBruce M Simpson *
585b0fe478SBruce M Simpson * 0 1 2 3
595b0fe478SBruce M Simpson * 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
605b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
615b0fe478SBruce M Simpson * |U| Message Type | Message Length |
625b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
635b0fe478SBruce M Simpson * | Message ID |
645b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
655b0fe478SBruce M Simpson * | |
665b0fe478SBruce M Simpson * + +
675b0fe478SBruce M Simpson * | Mandatory Parameters |
685b0fe478SBruce M Simpson * + +
695b0fe478SBruce M Simpson * | |
705b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
715b0fe478SBruce M Simpson * | |
725b0fe478SBruce M Simpson * + +
735b0fe478SBruce M Simpson * | Optional Parameters |
745b0fe478SBruce M Simpson * + +
755b0fe478SBruce M Simpson * | |
765b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
775b0fe478SBruce M Simpson */
785b0fe478SBruce M Simpson
795b0fe478SBruce M Simpson struct ldp_msg_header {
80ee67461eSJoseph Mingrone nd_uint16_t type;
81ee67461eSJoseph Mingrone nd_uint16_t length;
82ee67461eSJoseph Mingrone nd_uint32_t id;
835b0fe478SBruce M Simpson };
845b0fe478SBruce M Simpson
855b0fe478SBruce M Simpson #define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff)
865b0fe478SBruce M Simpson #define LDP_MASK_U_BIT(x) ((x)&0x8000)
875b0fe478SBruce M Simpson
885b0fe478SBruce M Simpson #define LDP_MSG_NOTIF 0x0001
895b0fe478SBruce M Simpson #define LDP_MSG_HELLO 0x0100
905b0fe478SBruce M Simpson #define LDP_MSG_INIT 0x0200
915b0fe478SBruce M Simpson #define LDP_MSG_KEEPALIVE 0x0201
925b0fe478SBruce M Simpson #define LDP_MSG_ADDRESS 0x0300
935b0fe478SBruce M Simpson #define LDP_MSG_ADDRESS_WITHDRAW 0x0301
945b0fe478SBruce M Simpson #define LDP_MSG_LABEL_MAPPING 0x0400
955b0fe478SBruce M Simpson #define LDP_MSG_LABEL_REQUEST 0x0401
965b0fe478SBruce M Simpson #define LDP_MSG_LABEL_WITHDRAW 0x0402
975b0fe478SBruce M Simpson #define LDP_MSG_LABEL_RELEASE 0x0403
985b0fe478SBruce M Simpson #define LDP_MSG_LABEL_ABORT_REQUEST 0x0404
995b0fe478SBruce M Simpson
1005b0fe478SBruce M Simpson #define LDP_VENDOR_PRIVATE_MIN 0x3e00
1015b0fe478SBruce M Simpson #define LDP_VENDOR_PRIVATE_MAX 0x3eff
1025b0fe478SBruce M Simpson #define LDP_EXPERIMENTAL_MIN 0x3f00
1035b0fe478SBruce M Simpson #define LDP_EXPERIMENTAL_MAX 0x3fff
1045b0fe478SBruce M Simpson
1055b0fe478SBruce M Simpson static const struct tok ldp_msg_values[] = {
1065b0fe478SBruce M Simpson { LDP_MSG_NOTIF, "Notification" },
1075b0fe478SBruce M Simpson { LDP_MSG_HELLO, "Hello" },
1085b0fe478SBruce M Simpson { LDP_MSG_INIT, "Initialization" },
1095b0fe478SBruce M Simpson { LDP_MSG_KEEPALIVE, "Keepalive" },
1105b0fe478SBruce M Simpson { LDP_MSG_ADDRESS, "Address" },
111b5bfcb5dSMax Laier { LDP_MSG_ADDRESS_WITHDRAW, "Address Withdraw" },
1125b0fe478SBruce M Simpson { LDP_MSG_LABEL_MAPPING, "Label Mapping" },
1135b0fe478SBruce M Simpson { LDP_MSG_LABEL_REQUEST, "Label Request" },
1145b0fe478SBruce M Simpson { LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" },
1155b0fe478SBruce M Simpson { LDP_MSG_LABEL_RELEASE, "Label Release" },
1165b0fe478SBruce M Simpson { LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" },
1175b0fe478SBruce M Simpson { 0, NULL}
1185b0fe478SBruce M Simpson };
1195b0fe478SBruce M Simpson
1205b0fe478SBruce M Simpson #define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff)
1215b0fe478SBruce M Simpson #define LDP_MASK_F_BIT(x) ((x)&0x4000)
1225b0fe478SBruce M Simpson
1235b0fe478SBruce M Simpson #define LDP_TLV_FEC 0x0100
1245b0fe478SBruce M Simpson #define LDP_TLV_ADDRESS_LIST 0x0101
125a5779b6eSRui Paulo #define LDP_TLV_ADDRESS_LIST_AFNUM_LEN 2
1265b0fe478SBruce M Simpson #define LDP_TLV_HOP_COUNT 0x0103
1275b0fe478SBruce M Simpson #define LDP_TLV_PATH_VECTOR 0x0104
1285b0fe478SBruce M Simpson #define LDP_TLV_GENERIC_LABEL 0x0200
1295b0fe478SBruce M Simpson #define LDP_TLV_ATM_LABEL 0x0201
1305b0fe478SBruce M Simpson #define LDP_TLV_FR_LABEL 0x0202
1315b0fe478SBruce M Simpson #define LDP_TLV_STATUS 0x0300
1325b0fe478SBruce M Simpson #define LDP_TLV_EXTD_STATUS 0x0301
1335b0fe478SBruce M Simpson #define LDP_TLV_RETURNED_PDU 0x0302
1345b0fe478SBruce M Simpson #define LDP_TLV_RETURNED_MSG 0x0303
1355b0fe478SBruce M Simpson #define LDP_TLV_COMMON_HELLO 0x0400
1365b0fe478SBruce M Simpson #define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401
1375b0fe478SBruce M Simpson #define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402
1385b0fe478SBruce M Simpson #define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403
1395b0fe478SBruce M Simpson #define LDP_TLV_COMMON_SESSION 0x0500
1405b0fe478SBruce M Simpson #define LDP_TLV_ATM_SESSION_PARM 0x0501
1415b0fe478SBruce M Simpson #define LDP_TLV_FR_SESSION_PARM 0x0502
1421de50e9fSSam Leffler #define LDP_TLV_FT_SESSION 0x0503
1435b0fe478SBruce M Simpson #define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600
144a5779b6eSRui Paulo #define LDP_TLV_MTU 0x0601 /* rfc 3988 */
1455b0fe478SBruce M Simpson
1465b0fe478SBruce M Simpson static const struct tok ldp_tlv_values[] = {
1475b0fe478SBruce M Simpson { LDP_TLV_FEC, "FEC" },
1485b0fe478SBruce M Simpson { LDP_TLV_ADDRESS_LIST, "Address List" },
1495b0fe478SBruce M Simpson { LDP_TLV_HOP_COUNT, "Hop Count" },
1505b0fe478SBruce M Simpson { LDP_TLV_PATH_VECTOR, "Path Vector" },
1515b0fe478SBruce M Simpson { LDP_TLV_GENERIC_LABEL, "Generic Label" },
1525b0fe478SBruce M Simpson { LDP_TLV_ATM_LABEL, "ATM Label" },
1535b0fe478SBruce M Simpson { LDP_TLV_FR_LABEL, "Frame-Relay Label" },
1545b0fe478SBruce M Simpson { LDP_TLV_STATUS, "Status" },
1555b0fe478SBruce M Simpson { LDP_TLV_EXTD_STATUS, "Extended Status" },
1565b0fe478SBruce M Simpson { LDP_TLV_RETURNED_PDU, "Returned PDU" },
1575b0fe478SBruce M Simpson { LDP_TLV_RETURNED_MSG, "Returned Message" },
1585b0fe478SBruce M Simpson { LDP_TLV_COMMON_HELLO, "Common Hello Parameters" },
1595b0fe478SBruce M Simpson { LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" },
1605b0fe478SBruce M Simpson { LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" },
1615b0fe478SBruce M Simpson { LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" },
1625b0fe478SBruce M Simpson { LDP_TLV_COMMON_SESSION, "Common Session Parameters" },
1635b0fe478SBruce M Simpson { LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" },
1645b0fe478SBruce M Simpson { LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" },
1651de50e9fSSam Leffler { LDP_TLV_FT_SESSION, "Fault-Tolerant Session Parameters" },
1665b0fe478SBruce M Simpson { LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" },
167a5779b6eSRui Paulo { LDP_TLV_MTU, "MTU" },
1685b0fe478SBruce M Simpson { 0, NULL}
1695b0fe478SBruce M Simpson };
1705b0fe478SBruce M Simpson
1711de50e9fSSam Leffler #define LDP_FEC_WILDCARD 0x01
1721de50e9fSSam Leffler #define LDP_FEC_PREFIX 0x02
1731de50e9fSSam Leffler #define LDP_FEC_HOSTADDRESS 0x03
174d09a7e67SXin LI /* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */
1751de50e9fSSam Leffler #define LDP_FEC_MARTINI_VC 0x80
1761de50e9fSSam Leffler
1771de50e9fSSam Leffler static const struct tok ldp_fec_values[] = {
1781de50e9fSSam Leffler { LDP_FEC_WILDCARD, "Wildcard" },
1791de50e9fSSam Leffler { LDP_FEC_PREFIX, "Prefix" },
1801de50e9fSSam Leffler { LDP_FEC_HOSTADDRESS, "Host address" },
1811de50e9fSSam Leffler { LDP_FEC_MARTINI_VC, "Martini VC" },
1821de50e9fSSam Leffler { 0, NULL}
1831de50e9fSSam Leffler };
1841de50e9fSSam Leffler
185f4d0c64aSSam Leffler #define LDP_FEC_MARTINI_IFPARM_MTU 0x01
186f4d0c64aSSam Leffler #define LDP_FEC_MARTINI_IFPARM_DESC 0x03
187f4d0c64aSSam Leffler #define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c
188f4d0c64aSSam Leffler
189f4d0c64aSSam Leffler static const struct tok ldp_fec_martini_ifparm_values[] = {
190f4d0c64aSSam Leffler { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" },
191f4d0c64aSSam Leffler { LDP_FEC_MARTINI_IFPARM_DESC, "Description" },
192f4d0c64aSSam Leffler { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" },
193f4d0c64aSSam Leffler { 0, NULL}
194f4d0c64aSSam Leffler };
195f4d0c64aSSam Leffler
196f4d0c64aSSam Leffler /* draft-ietf-pwe3-vccv-04.txt */
197f4d0c64aSSam Leffler static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = {
198f4d0c64aSSam Leffler { 0x01, "PWE3 control word" },
199f4d0c64aSSam Leffler { 0x02, "MPLS Router Alert Label" },
200f4d0c64aSSam Leffler { 0x04, "MPLS inner label TTL = 1" },
201f4d0c64aSSam Leffler { 0, NULL}
202f4d0c64aSSam Leffler };
203f4d0c64aSSam Leffler
204f4d0c64aSSam Leffler /* draft-ietf-pwe3-vccv-04.txt */
205f4d0c64aSSam Leffler static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = {
206f4d0c64aSSam Leffler { 0x01, "ICMP Ping" },
207f4d0c64aSSam Leffler { 0x02, "LSP Ping" },
208f4d0c64aSSam Leffler { 0x04, "BFD" },
209f4d0c64aSSam Leffler { 0, NULL}
210f4d0c64aSSam Leffler };
211f4d0c64aSSam Leffler
212ee67461eSJoseph Mingrone static u_int ldp_pdu_print(netdissect_options *, const u_char *);
2135b0fe478SBruce M Simpson
2145b0fe478SBruce M Simpson /*
2155b0fe478SBruce M Simpson * ldp tlv header
2165b0fe478SBruce M Simpson *
2175b0fe478SBruce M Simpson * 0 1 2 3
2185b0fe478SBruce M Simpson * 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
2195b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2205b0fe478SBruce M Simpson * |U|F| Type | Length |
2215b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2225b0fe478SBruce M Simpson * | |
2235b0fe478SBruce M Simpson * | Value |
2245b0fe478SBruce M Simpson * ~ ~
2255b0fe478SBruce M Simpson * | |
2265b0fe478SBruce M Simpson * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2275b0fe478SBruce M Simpson * | |
2285b0fe478SBruce M Simpson * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2295b0fe478SBruce M Simpson */
2305b0fe478SBruce M Simpson
231d09a7e67SXin LI #define TLV_TCHECK(minlen) \
232ee67461eSJoseph Mingrone if (tlv_tlen < minlen) { \
233ee67461eSJoseph Mingrone ND_PRINT(" [tlv length %u < %u]", tlv_tlen, minlen); \
234ee67461eSJoseph Mingrone nd_print_invalid(ndo); \
235ee67461eSJoseph Mingrone goto invalid; \
236ee67461eSJoseph Mingrone }
237d09a7e67SXin LI
238ee67461eSJoseph Mingrone static u_int
ldp_tlv_print(netdissect_options * ndo,const u_char * tptr,u_int msg_tlen)2393c602fabSXin LI ldp_tlv_print(netdissect_options *ndo,
240ee67461eSJoseph Mingrone const u_char *tptr,
241ee67461eSJoseph Mingrone u_int msg_tlen)
2428bdc5a62SPatrick Kelsey {
2435b0fe478SBruce M Simpson struct ldp_tlv_header {
244ee67461eSJoseph Mingrone nd_uint16_t type;
245ee67461eSJoseph Mingrone nd_uint16_t length;
2465b0fe478SBruce M Simpson };
2475b0fe478SBruce M Simpson
2485b0fe478SBruce M Simpson const struct ldp_tlv_header *ldp_tlv_header;
2491de50e9fSSam Leffler u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
2501de50e9fSSam Leffler u_char fec_type;
251f4d0c64aSSam Leffler u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
2521de50e9fSSam Leffler char buf[100];
2531de50e9fSSam Leffler int i;
2545b0fe478SBruce M Simpson
2555b0fe478SBruce M Simpson ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
256ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ldp_tlv_header);
257ee67461eSJoseph Mingrone tlv_len=GET_BE_U_2(ldp_tlv_header->length);
258ee67461eSJoseph Mingrone if (tlv_len + 4U > msg_tlen) {
259ee67461eSJoseph Mingrone ND_PRINT("\n\t\t TLV contents go past end of message");
2608bdc5a62SPatrick Kelsey return 0;
2618bdc5a62SPatrick Kelsey }
2625b0fe478SBruce M Simpson tlv_tlen=tlv_len;
263ee67461eSJoseph Mingrone tlv_type=LDP_MASK_TLV_TYPE(GET_BE_U_2(ldp_tlv_header->type));
2645b0fe478SBruce M Simpson
2655b0fe478SBruce M Simpson /* FIXME vendor private / experimental check */
266ee67461eSJoseph Mingrone ND_PRINT("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
2675b0fe478SBruce M Simpson tok2str(ldp_tlv_values,
2685b0fe478SBruce M Simpson "Unknown",
2695b0fe478SBruce M Simpson tlv_type),
2705b0fe478SBruce M Simpson tlv_type,
2715b0fe478SBruce M Simpson tlv_len,
272ee67461eSJoseph Mingrone LDP_MASK_U_BIT(GET_BE_U_2(ldp_tlv_header->type)) ? "continue processing" : "ignore",
273ee67461eSJoseph Mingrone LDP_MASK_F_BIT(GET_BE_U_2(ldp_tlv_header->type)) ? "do" : "don't");
2745b0fe478SBruce M Simpson
2755b0fe478SBruce M Simpson tptr+=sizeof(struct ldp_tlv_header);
2765b0fe478SBruce M Simpson
2775b0fe478SBruce M Simpson switch(tlv_type) {
2785b0fe478SBruce M Simpson
2795b0fe478SBruce M Simpson case LDP_TLV_COMMON_HELLO:
280d09a7e67SXin LI TLV_TCHECK(4);
281ee67461eSJoseph Mingrone ND_PRINT("\n\t Hold Time: %us, Flags: [%s Hello%s]",
282ee67461eSJoseph Mingrone GET_BE_U_2(tptr),
283ee67461eSJoseph Mingrone (GET_BE_U_2(tptr + 2)&0x8000) ? "Targeted" : "Link",
284ee67461eSJoseph Mingrone (GET_BE_U_2(tptr + 2)&0x4000) ? ", Request for targeted Hellos" : "");
2855b0fe478SBruce M Simpson break;
2865b0fe478SBruce M Simpson
2875b0fe478SBruce M Simpson case LDP_TLV_IPV4_TRANSPORT_ADDR:
288d09a7e67SXin LI TLV_TCHECK(4);
289ee67461eSJoseph Mingrone ND_PRINT("\n\t IPv4 Transport Address: %s", GET_IPADDR_STRING(tptr));
2905b0fe478SBruce M Simpson break;
2915b0fe478SBruce M Simpson case LDP_TLV_IPV6_TRANSPORT_ADDR:
292d09a7e67SXin LI TLV_TCHECK(16);
293ee67461eSJoseph Mingrone ND_PRINT("\n\t IPv6 Transport Address: %s", GET_IP6ADDR_STRING(tptr));
2945b0fe478SBruce M Simpson break;
2955b0fe478SBruce M Simpson case LDP_TLV_CONFIG_SEQ_NUMBER:
296d09a7e67SXin LI TLV_TCHECK(4);
297ee67461eSJoseph Mingrone ND_PRINT("\n\t Sequence Number: %u", GET_BE_U_4(tptr));
2985b0fe478SBruce M Simpson break;
2995b0fe478SBruce M Simpson
3001de50e9fSSam Leffler case LDP_TLV_ADDRESS_LIST:
301d09a7e67SXin LI TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
302ee67461eSJoseph Mingrone af = GET_BE_U_2(tptr);
303a5779b6eSRui Paulo tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
304a5779b6eSRui Paulo tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
305ee67461eSJoseph Mingrone ND_PRINT("\n\t Address Family: %s, addresses",
306ee67461eSJoseph Mingrone tok2str(af_values, "Unknown (%u)", af));
307a5779b6eSRui Paulo switch (af) {
308a5779b6eSRui Paulo case AFNUM_INET:
309ee67461eSJoseph Mingrone while(tlv_tlen >= sizeof(nd_ipv4)) {
310ee67461eSJoseph Mingrone ND_PRINT(" %s", GET_IPADDR_STRING(tptr));
311ee67461eSJoseph Mingrone tlv_tlen-=sizeof(nd_ipv4);
312ee67461eSJoseph Mingrone tptr+=sizeof(nd_ipv4);
3131de50e9fSSam Leffler }
314a5779b6eSRui Paulo break;
315a5779b6eSRui Paulo case AFNUM_INET6:
316ee67461eSJoseph Mingrone while(tlv_tlen >= sizeof(nd_ipv6)) {
317ee67461eSJoseph Mingrone ND_PRINT(" %s", GET_IP6ADDR_STRING(tptr));
318ee67461eSJoseph Mingrone tlv_tlen-=sizeof(nd_ipv6);
319ee67461eSJoseph Mingrone tptr+=sizeof(nd_ipv6);
3201de50e9fSSam Leffler }
321a5779b6eSRui Paulo break;
322a5779b6eSRui Paulo default:
323a5779b6eSRui Paulo /* unknown AF */
324a5779b6eSRui Paulo break;
325a5779b6eSRui Paulo }
3261de50e9fSSam Leffler break;
3271de50e9fSSam Leffler
3281de50e9fSSam Leffler case LDP_TLV_COMMON_SESSION:
329*0a7e5f1fSJoseph Mingrone TLV_TCHECK(14);
330ee67461eSJoseph Mingrone ND_PRINT("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
331ee67461eSJoseph Mingrone GET_BE_U_2(tptr), GET_BE_U_2(tptr + 2),
332*0a7e5f1fSJoseph Mingrone (GET_BE_U_2(tptr + 4)&0x8000) ? "On Demand" : "Unsolicited",
333*0a7e5f1fSJoseph Mingrone (GET_BE_U_2(tptr + 4)&0x4000) ? "Enabled" : "Disabled"
334*0a7e5f1fSJoseph Mingrone );
335*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t Path Vector Limit %u, Max-PDU length: %u, Receiver Label-Space-ID %s:%u",
336*0a7e5f1fSJoseph Mingrone GET_U_1(tptr+5),
337*0a7e5f1fSJoseph Mingrone GET_BE_U_2(tptr+6),
338*0a7e5f1fSJoseph Mingrone GET_IPADDR_STRING(tptr+8),
339*0a7e5f1fSJoseph Mingrone GET_BE_U_2(tptr+12)
340ee67461eSJoseph Mingrone );
3411de50e9fSSam Leffler break;
3421de50e9fSSam Leffler
3431de50e9fSSam Leffler case LDP_TLV_FEC:
344d09a7e67SXin LI TLV_TCHECK(1);
345ee67461eSJoseph Mingrone fec_type = GET_U_1(tptr);
346ee67461eSJoseph Mingrone ND_PRINT("\n\t %s FEC (0x%02x)",
3471de50e9fSSam Leffler tok2str(ldp_fec_values, "Unknown", fec_type),
348ee67461eSJoseph Mingrone fec_type);
3491de50e9fSSam Leffler
3501de50e9fSSam Leffler tptr+=1;
351d09a7e67SXin LI tlv_tlen-=1;
3521de50e9fSSam Leffler switch(fec_type) {
3531de50e9fSSam Leffler
3541de50e9fSSam Leffler case LDP_FEC_WILDCARD:
3551de50e9fSSam Leffler break;
3561de50e9fSSam Leffler case LDP_FEC_PREFIX:
357d09a7e67SXin LI TLV_TCHECK(2);
358ee67461eSJoseph Mingrone af = GET_BE_U_2(tptr);
359ee67461eSJoseph Mingrone tptr+=2;
360ee67461eSJoseph Mingrone tlv_tlen-=2;
3611de50e9fSSam Leffler if (af == AFNUM_INET) {
3623c602fabSXin LI i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf));
363d09a7e67SXin LI if (i == -2)
364d09a7e67SXin LI goto trunc;
365d09a7e67SXin LI if (i == -3)
366ee67461eSJoseph Mingrone ND_PRINT(": IPv4 prefix (goes past end of TLV)");
367d09a7e67SXin LI else if (i == -1)
368ee67461eSJoseph Mingrone ND_PRINT(": IPv4 prefix (invalid length)");
369d09a7e67SXin LI else
370ee67461eSJoseph Mingrone ND_PRINT(": IPv4 prefix %s", buf);
371*0a7e5f1fSJoseph Mingrone } else if (af == AFNUM_INET6) {
3723c602fabSXin LI i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf));
373d09a7e67SXin LI if (i == -2)
374d09a7e67SXin LI goto trunc;
375d09a7e67SXin LI if (i == -3)
376ee67461eSJoseph Mingrone ND_PRINT(": IPv4 prefix (goes past end of TLV)");
377d09a7e67SXin LI else if (i == -1)
378ee67461eSJoseph Mingrone ND_PRINT(": IPv6 prefix (invalid length)");
379d09a7e67SXin LI else
380ee67461eSJoseph Mingrone ND_PRINT(": IPv6 prefix %s", buf);
381*0a7e5f1fSJoseph Mingrone } else
382ee67461eSJoseph Mingrone ND_PRINT(": Address family %u prefix", af);
3831de50e9fSSam Leffler break;
3841de50e9fSSam Leffler case LDP_FEC_HOSTADDRESS:
3851de50e9fSSam Leffler break;
3861de50e9fSSam Leffler case LDP_FEC_MARTINI_VC:
387d09a7e67SXin LI /*
3883340d773SGleb Smirnoff * We assume the type was supposed to be one of the MPLS
3893340d773SGleb Smirnoff * Pseudowire Types.
390d09a7e67SXin LI */
391d09a7e67SXin LI TLV_TCHECK(7);
392ee67461eSJoseph Mingrone vc_info_len = GET_U_1(tptr + 2);
393f4d0c64aSSam Leffler
3943340d773SGleb Smirnoff /*
3953340d773SGleb Smirnoff * According to RFC 4908, the VC info Length field can be zero,
3963340d773SGleb Smirnoff * in which case not only are there no interface parameters,
3973340d773SGleb Smirnoff * there's no VC ID.
3983340d773SGleb Smirnoff */
399d09a7e67SXin LI if (vc_info_len == 0) {
400ee67461eSJoseph Mingrone ND_PRINT(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
401ee67461eSJoseph Mingrone tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff),
402ee67461eSJoseph Mingrone GET_BE_U_2(tptr)&0x8000 ? "" : "no ",
403ee67461eSJoseph Mingrone GET_BE_U_4(tptr + 3),
404ee67461eSJoseph Mingrone vc_info_len);
405d09a7e67SXin LI break;
406d09a7e67SXin LI }
407d09a7e67SXin LI
408d09a7e67SXin LI /* Make sure we have the VC ID as well */
409d09a7e67SXin LI TLV_TCHECK(11);
410ee67461eSJoseph Mingrone ND_PRINT(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
411ee67461eSJoseph Mingrone tok2str(mpls_pw_types_values, "Unknown", GET_BE_U_2(tptr)&0x7fff),
412ee67461eSJoseph Mingrone GET_BE_U_2(tptr)&0x8000 ? "" : "no ",
413ee67461eSJoseph Mingrone GET_BE_U_4(tptr + 3),
414ee67461eSJoseph Mingrone GET_BE_U_4(tptr + 7),
415ee67461eSJoseph Mingrone vc_info_len);
4168bdc5a62SPatrick Kelsey if (vc_info_len < 4) {
4178bdc5a62SPatrick Kelsey /* minimum 4, for the VC ID */
418ee67461eSJoseph Mingrone ND_PRINT(" (invalid, < 4");
4198bdc5a62SPatrick Kelsey return(tlv_len+4); /* Type & Length fields not included */
4208bdc5a62SPatrick Kelsey }
421d09a7e67SXin LI vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */
422f4d0c64aSSam Leffler
423d09a7e67SXin LI /* Skip past the fixed information and the VC ID */
424f4d0c64aSSam Leffler tptr+=11;
425d09a7e67SXin LI tlv_tlen-=11;
426d09a7e67SXin LI TLV_TCHECK(vc_info_len);
427f4d0c64aSSam Leffler
428f4d0c64aSSam Leffler while (vc_info_len > 2) {
429ee67461eSJoseph Mingrone vc_info_tlv_type = GET_U_1(tptr);
430ee67461eSJoseph Mingrone vc_info_tlv_len = GET_U_1(tptr + 1);
431f4d0c64aSSam Leffler if (vc_info_tlv_len < 2)
432f4d0c64aSSam Leffler break;
433f4d0c64aSSam Leffler if (vc_info_len < vc_info_tlv_len)
434f4d0c64aSSam Leffler break;
435f4d0c64aSSam Leffler
436ee67461eSJoseph Mingrone ND_PRINT("\n\t\tInterface Parameter: %s (0x%02x), len %u",
437f4d0c64aSSam Leffler tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
438f4d0c64aSSam Leffler vc_info_tlv_type,
439ee67461eSJoseph Mingrone vc_info_tlv_len);
440f4d0c64aSSam Leffler
441f4d0c64aSSam Leffler switch(vc_info_tlv_type) {
442f4d0c64aSSam Leffler case LDP_FEC_MARTINI_IFPARM_MTU:
443ee67461eSJoseph Mingrone ND_PRINT(": %u", GET_BE_U_2(tptr + 2));
444f4d0c64aSSam Leffler break;
445f4d0c64aSSam Leffler
446f4d0c64aSSam Leffler case LDP_FEC_MARTINI_IFPARM_DESC:
447ee67461eSJoseph Mingrone ND_PRINT(": ");
448ee67461eSJoseph Mingrone for (idx = 2; idx < vc_info_tlv_len; idx++)
449ee67461eSJoseph Mingrone fn_print_char(ndo, GET_U_1(tptr + idx));
450f4d0c64aSSam Leffler break;
451f4d0c64aSSam Leffler
452f4d0c64aSSam Leffler case LDP_FEC_MARTINI_IFPARM_VCCV:
453ee67461eSJoseph Mingrone ND_PRINT("\n\t\t Control Channels (0x%02x) = [%s]",
454ee67461eSJoseph Mingrone GET_U_1((tptr + 2)),
455ee67461eSJoseph Mingrone bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", GET_U_1((tptr + 2))));
456ee67461eSJoseph Mingrone ND_PRINT("\n\t\t CV Types (0x%02x) = [%s]",
457ee67461eSJoseph Mingrone GET_U_1((tptr + 3)),
458ee67461eSJoseph Mingrone bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", GET_U_1((tptr + 3))));
459f4d0c64aSSam Leffler break;
460f4d0c64aSSam Leffler
461f4d0c64aSSam Leffler default:
4623c602fabSXin LI print_unknown_data(ndo, tptr+2, "\n\t\t ", vc_info_tlv_len-2);
463f4d0c64aSSam Leffler break;
464f4d0c64aSSam Leffler }
465f4d0c64aSSam Leffler
466f4d0c64aSSam Leffler vc_info_len -= vc_info_tlv_len;
467f4d0c64aSSam Leffler tptr += vc_info_tlv_len;
468f4d0c64aSSam Leffler }
4691de50e9fSSam Leffler break;
4701de50e9fSSam Leffler }
4711de50e9fSSam Leffler
4721de50e9fSSam Leffler break;
4731de50e9fSSam Leffler
4741de50e9fSSam Leffler case LDP_TLV_GENERIC_LABEL:
475d09a7e67SXin LI TLV_TCHECK(4);
476ee67461eSJoseph Mingrone ND_PRINT("\n\t Label: %u", GET_BE_U_4(tptr) & 0xfffff);
4771de50e9fSSam Leffler break;
4781de50e9fSSam Leffler
4791de50e9fSSam Leffler case LDP_TLV_STATUS:
480d09a7e67SXin LI TLV_TCHECK(8);
481ee67461eSJoseph Mingrone ui = GET_BE_U_4(tptr);
4821de50e9fSSam Leffler tptr+=4;
483ee67461eSJoseph Mingrone ND_PRINT("\n\t Status: 0x%02x, Flags: [%s and %s forward]",
4841de50e9fSSam Leffler ui&0x3fffffff,
4851de50e9fSSam Leffler ui&0x80000000 ? "Fatal error" : "Advisory Notification",
486ee67461eSJoseph Mingrone ui&0x40000000 ? "do" : "don't");
487ee67461eSJoseph Mingrone ui = GET_BE_U_4(tptr);
4881de50e9fSSam Leffler tptr+=4;
4891de50e9fSSam Leffler if (ui)
490ee67461eSJoseph Mingrone ND_PRINT(", causing Message ID: 0x%08x", ui);
4911de50e9fSSam Leffler break;
4921de50e9fSSam Leffler
4931de50e9fSSam Leffler case LDP_TLV_FT_SESSION:
49439e421e8SCy Schubert TLV_TCHECK(12);
495ee67461eSJoseph Mingrone ft_flags = GET_BE_U_2(tptr);
496ee67461eSJoseph Mingrone ND_PRINT("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
4971de50e9fSSam Leffler ft_flags&0x8000 ? "" : "No ",
4981de50e9fSSam Leffler ft_flags&0x8 ? "" : "Don't ",
4991de50e9fSSam Leffler ft_flags&0x4 ? "" : "No ",
5001de50e9fSSam Leffler ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
501ee67461eSJoseph Mingrone ft_flags&0x1 ? "" : "Don't ");
50239e421e8SCy Schubert /* 16 bits (FT Flags) + 16 bits (Reserved) */
5031de50e9fSSam Leffler tptr+=4;
504ee67461eSJoseph Mingrone ui = GET_BE_U_4(tptr);
5051de50e9fSSam Leffler if (ui)
506ee67461eSJoseph Mingrone ND_PRINT(", Reconnect Timeout: %ums", ui);
5071de50e9fSSam Leffler tptr+=4;
508ee67461eSJoseph Mingrone ui = GET_BE_U_4(tptr);
5091de50e9fSSam Leffler if (ui)
510ee67461eSJoseph Mingrone ND_PRINT(", Recovery Time: %ums", ui);
5111de50e9fSSam Leffler break;
5121de50e9fSSam Leffler
513a5779b6eSRui Paulo case LDP_TLV_MTU:
514d09a7e67SXin LI TLV_TCHECK(2);
515ee67461eSJoseph Mingrone ND_PRINT("\n\t MTU: %u", GET_BE_U_2(tptr));
516a5779b6eSRui Paulo break;
517a5779b6eSRui Paulo
5181de50e9fSSam Leffler
5195b0fe478SBruce M Simpson /*
5205b0fe478SBruce M Simpson * FIXME those are the defined TLVs that lack a decoder
5215b0fe478SBruce M Simpson * you are welcome to contribute code ;-)
5225b0fe478SBruce M Simpson */
5235b0fe478SBruce M Simpson
5245b0fe478SBruce M Simpson case LDP_TLV_HOP_COUNT:
5255b0fe478SBruce M Simpson case LDP_TLV_PATH_VECTOR:
5265b0fe478SBruce M Simpson case LDP_TLV_ATM_LABEL:
5275b0fe478SBruce M Simpson case LDP_TLV_FR_LABEL:
5285b0fe478SBruce M Simpson case LDP_TLV_EXTD_STATUS:
5295b0fe478SBruce M Simpson case LDP_TLV_RETURNED_PDU:
5305b0fe478SBruce M Simpson case LDP_TLV_RETURNED_MSG:
5315b0fe478SBruce M Simpson case LDP_TLV_ATM_SESSION_PARM:
5325b0fe478SBruce M Simpson case LDP_TLV_FR_SESSION_PARM:
5335b0fe478SBruce M Simpson case LDP_TLV_LABEL_REQUEST_MSG_ID:
5345b0fe478SBruce M Simpson
5355b0fe478SBruce M Simpson default:
5363c602fabSXin LI if (ndo->ndo_vflag <= 1)
5373c602fabSXin LI print_unknown_data(ndo, tptr, "\n\t ", tlv_tlen);
5385b0fe478SBruce M Simpson break;
5395b0fe478SBruce M Simpson }
5405b0fe478SBruce M Simpson return(tlv_len+4); /* Type & Length fields not included */
541f4d0c64aSSam Leffler
542f4d0c64aSSam Leffler trunc:
543ee67461eSJoseph Mingrone nd_trunc_longjmp(ndo);
544d09a7e67SXin LI
545ee67461eSJoseph Mingrone invalid:
546d09a7e67SXin LI return(tlv_len+4); /* Type & Length fields not included */
5475b0fe478SBruce M Simpson }
5485b0fe478SBruce M Simpson
5495b0fe478SBruce M Simpson void
ldp_print(netdissect_options * ndo,const u_char * pptr,u_int len)5503c602fabSXin LI ldp_print(netdissect_options *ndo,
551ee67461eSJoseph Mingrone const u_char *pptr, u_int len)
5528bdc5a62SPatrick Kelsey {
55339e421e8SCy Schubert u_int processed;
554ee67461eSJoseph Mingrone
555ee67461eSJoseph Mingrone ndo->ndo_protocol = "ldp";
556f4d0c64aSSam Leffler while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
5578bdc5a62SPatrick Kelsey processed = ldp_pdu_print(ndo, pptr);
558f4d0c64aSSam Leffler if (processed == 0)
559f4d0c64aSSam Leffler return;
56039e421e8SCy Schubert if (len < processed) {
561ee67461eSJoseph Mingrone ND_PRINT(" [remaining length %u < %u]", len, processed);
562ee67461eSJoseph Mingrone nd_print_invalid(ndo);
56339e421e8SCy Schubert break;
56439e421e8SCy Schubert }
565f4d0c64aSSam Leffler len -= processed;
566f4d0c64aSSam Leffler pptr += processed;
567f4d0c64aSSam Leffler }
568f4d0c64aSSam Leffler }
569f4d0c64aSSam Leffler
57039e421e8SCy Schubert static u_int
ldp_pdu_print(netdissect_options * ndo,const u_char * pptr)5718bdc5a62SPatrick Kelsey ldp_pdu_print(netdissect_options *ndo,
572ee67461eSJoseph Mingrone const u_char *pptr)
5738bdc5a62SPatrick Kelsey {
5745b0fe478SBruce M Simpson const struct ldp_common_header *ldp_com_header;
5755b0fe478SBruce M Simpson const struct ldp_msg_header *ldp_msg_header;
5765b0fe478SBruce M Simpson const u_char *tptr,*msg_tptr;
5775b0fe478SBruce M Simpson u_short tlen;
578ee67461eSJoseph Mingrone u_short pdu_len,msg_len,msg_type;
579ee67461eSJoseph Mingrone u_int msg_tlen;
5805b0fe478SBruce M Simpson int hexdump,processed;
5815b0fe478SBruce M Simpson
5825b0fe478SBruce M Simpson ldp_com_header = (const struct ldp_common_header *)pptr;
583ee67461eSJoseph Mingrone ND_TCHECK_SIZE(ldp_com_header);
5845b0fe478SBruce M Simpson
5855b0fe478SBruce M Simpson /*
5865b0fe478SBruce M Simpson * Sanity checking of the header.
5875b0fe478SBruce M Simpson */
588ee67461eSJoseph Mingrone if (GET_BE_U_2(ldp_com_header->version) != LDP_VERSION) {
589ee67461eSJoseph Mingrone ND_PRINT("%sLDP version %u packet not supported",
5903c602fabSXin LI (ndo->ndo_vflag < 1) ? "" : "\n\t",
591ee67461eSJoseph Mingrone GET_BE_U_2(ldp_com_header->version));
592f4d0c64aSSam Leffler return 0;
5935b0fe478SBruce M Simpson }
5945b0fe478SBruce M Simpson
595ee67461eSJoseph Mingrone pdu_len = GET_BE_U_2(ldp_com_header->pdu_length);
596ee67461eSJoseph Mingrone if (pdu_len < sizeof(struct ldp_common_header)-4) {
5978bdc5a62SPatrick Kelsey /* length too short */
598ee67461eSJoseph Mingrone ND_PRINT("%sLDP, pdu-length: %u (too short, < %zu)",
5998bdc5a62SPatrick Kelsey (ndo->ndo_vflag < 1) ? "" : "\n\t",
6008bdc5a62SPatrick Kelsey pdu_len,
601ee67461eSJoseph Mingrone sizeof(struct ldp_common_header)-4);
6028bdc5a62SPatrick Kelsey return 0;
6038bdc5a62SPatrick Kelsey }
6048bdc5a62SPatrick Kelsey
6058bdc5a62SPatrick Kelsey /* print the LSR-ID, label-space & length */
606ee67461eSJoseph Mingrone ND_PRINT("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
6073c602fabSXin LI (ndo->ndo_vflag < 1) ? "" : "\n\t",
608ee67461eSJoseph Mingrone GET_IPADDR_STRING(ldp_com_header->lsr_id),
609ee67461eSJoseph Mingrone GET_BE_U_2(ldp_com_header->label_space),
610ee67461eSJoseph Mingrone pdu_len);
6115b0fe478SBruce M Simpson
6125b0fe478SBruce M Simpson /* bail out if non-verbose */
6133c602fabSXin LI if (ndo->ndo_vflag < 1)
614f4d0c64aSSam Leffler return 0;
6155b0fe478SBruce M Simpson
6165b0fe478SBruce M Simpson /* ok they seem to want to know everything - lets fully decode it */
617ee67461eSJoseph Mingrone tptr = pptr + sizeof(struct ldp_common_header);
618ee67461eSJoseph Mingrone tlen = pdu_len - (sizeof(struct ldp_common_header)-4); /* Type & Length fields not included */
6195b0fe478SBruce M Simpson
6205b0fe478SBruce M Simpson while(tlen>0) {
6215b0fe478SBruce M Simpson /* did we capture enough for fully decoding the msg header ? */
622ee67461eSJoseph Mingrone ND_TCHECK_LEN(tptr, sizeof(struct ldp_msg_header));
6235b0fe478SBruce M Simpson
6245b0fe478SBruce M Simpson ldp_msg_header = (const struct ldp_msg_header *)tptr;
625ee67461eSJoseph Mingrone msg_len=GET_BE_U_2(ldp_msg_header->length);
626ee67461eSJoseph Mingrone msg_type=LDP_MASK_MSG_TYPE(GET_BE_U_2(ldp_msg_header->type));
6275b0fe478SBruce M Simpson
6288bdc5a62SPatrick Kelsey if (msg_len < sizeof(struct ldp_msg_header)-4) {
6298bdc5a62SPatrick Kelsey /* length too short */
6308bdc5a62SPatrick Kelsey /* FIXME vendor private / experimental check */
631ee67461eSJoseph Mingrone ND_PRINT("\n\t %s Message (0x%04x), length: %u (too short, < %zu)",
6328bdc5a62SPatrick Kelsey tok2str(ldp_msg_values,
6338bdc5a62SPatrick Kelsey "Unknown",
6348bdc5a62SPatrick Kelsey msg_type),
6358bdc5a62SPatrick Kelsey msg_type,
6368bdc5a62SPatrick Kelsey msg_len,
637ee67461eSJoseph Mingrone sizeof(struct ldp_msg_header)-4);
6388bdc5a62SPatrick Kelsey return 0;
6398bdc5a62SPatrick Kelsey }
6408bdc5a62SPatrick Kelsey
6415b0fe478SBruce M Simpson /* FIXME vendor private / experimental check */
642ee67461eSJoseph Mingrone ND_PRINT("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
6435b0fe478SBruce M Simpson tok2str(ldp_msg_values,
6445b0fe478SBruce M Simpson "Unknown",
6455b0fe478SBruce M Simpson msg_type),
6465b0fe478SBruce M Simpson msg_type,
6475b0fe478SBruce M Simpson msg_len,
648ee67461eSJoseph Mingrone GET_BE_U_4(ldp_msg_header->id),
649ee67461eSJoseph Mingrone LDP_MASK_U_BIT(GET_BE_U_2(ldp_msg_header->type)) ? "continue processing" : "ignore");
6505b0fe478SBruce M Simpson
6515b0fe478SBruce M Simpson msg_tptr=tptr+sizeof(struct ldp_msg_header);
6528bdc5a62SPatrick Kelsey msg_tlen=msg_len-(sizeof(struct ldp_msg_header)-4); /* Type & Length fields not included */
6535b0fe478SBruce M Simpson
6545b0fe478SBruce M Simpson /* did we capture enough for fully decoding the message ? */
655ee67461eSJoseph Mingrone ND_TCHECK_LEN(tptr, msg_len);
6565b0fe478SBruce M Simpson hexdump=FALSE;
6575b0fe478SBruce M Simpson
6585b0fe478SBruce M Simpson switch(msg_type) {
6595b0fe478SBruce M Simpson
6601de50e9fSSam Leffler case LDP_MSG_NOTIF:
6615b0fe478SBruce M Simpson case LDP_MSG_HELLO:
6621de50e9fSSam Leffler case LDP_MSG_INIT:
6631de50e9fSSam Leffler case LDP_MSG_KEEPALIVE:
6641de50e9fSSam Leffler case LDP_MSG_ADDRESS:
6651de50e9fSSam Leffler case LDP_MSG_LABEL_MAPPING:
666b5bfcb5dSMax Laier case LDP_MSG_ADDRESS_WITHDRAW:
667b5bfcb5dSMax Laier case LDP_MSG_LABEL_WITHDRAW:
6685b0fe478SBruce M Simpson while(msg_tlen >= 4) {
6698bdc5a62SPatrick Kelsey processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen);
6705b0fe478SBruce M Simpson if (processed == 0)
6715b0fe478SBruce M Simpson break;
6725b0fe478SBruce M Simpson msg_tlen-=processed;
6735b0fe478SBruce M Simpson msg_tptr+=processed;
6745b0fe478SBruce M Simpson }
6755b0fe478SBruce M Simpson break;
6765b0fe478SBruce M Simpson
6775b0fe478SBruce M Simpson /*
6785b0fe478SBruce M Simpson * FIXME those are the defined messages that lack a decoder
6795b0fe478SBruce M Simpson * you are welcome to contribute code ;-)
6805b0fe478SBruce M Simpson */
6815b0fe478SBruce M Simpson
6825b0fe478SBruce M Simpson case LDP_MSG_LABEL_REQUEST:
6835b0fe478SBruce M Simpson case LDP_MSG_LABEL_RELEASE:
6845b0fe478SBruce M Simpson case LDP_MSG_LABEL_ABORT_REQUEST:
6855b0fe478SBruce M Simpson
6865b0fe478SBruce M Simpson default:
6873c602fabSXin LI if (ndo->ndo_vflag <= 1)
6883c602fabSXin LI print_unknown_data(ndo, msg_tptr, "\n\t ", msg_tlen);
6895b0fe478SBruce M Simpson break;
6905b0fe478SBruce M Simpson }
6915b0fe478SBruce M Simpson /* do we want to see an additionally hexdump ? */
6923c602fabSXin LI if (ndo->ndo_vflag > 1 || hexdump==TRUE)
6933c602fabSXin LI print_unknown_data(ndo, tptr+sizeof(struct ldp_msg_header), "\n\t ",
6945b0fe478SBruce M Simpson msg_len);
6955b0fe478SBruce M Simpson
6961de50e9fSSam Leffler tptr += msg_len+4;
6971de50e9fSSam Leffler tlen -= msg_len+4;
6985b0fe478SBruce M Simpson }
699f4d0c64aSSam Leffler return pdu_len+4;
7005b0fe478SBruce M Simpson trunc:
701ee67461eSJoseph Mingrone nd_trunc_longjmp(ndo);
7025b0fe478SBruce M Simpson }
703