aboutsummaryrefslogtreecommitdiffstats
path: root/packet-ldp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-01-21 22:15:18 +0000
committerGuy Harris <guy@alum.mit.edu>2002-01-21 22:15:18 +0000
commit6deb504cff5b169cbfcdc6e58e99481b59d5bf1f (patch)
tree4dcb310176b96f64d83ba42e9f062f6b14691fd8 /packet-ldp.c
parentc2945fe39f2afc671ac54291c87fb3ee2f3155b6 (diff)
From Ricardo Barroetave�a: support for all TLVs and messages in RFC
3036. svn path=/trunk/; revision=4590
Diffstat (limited to 'packet-ldp.c')
-rw-r--r--packet-ldp.c1853
1 files changed, 1327 insertions, 526 deletions
diff --git a/packet-ldp.c b/packet-ldp.c
index ac5ed43d8c..bda07e5c04 100644
--- a/packet-ldp.c
+++ b/packet-ldp.c
@@ -1,7 +1,7 @@
/* packet-ldp.c
* Routines for LDP (RFC 3036) packet disassembly
*
- * $Id: packet-ldp.c,v 1.26 2002/01/21 07:36:36 guy Exp $
+ * $Id: packet-ldp.c,v 1.27 2002/01/21 22:15:17 guy Exp $
*
* Copyright (c) November 2000 by Richard Sharpe <rsharpe@ns.aus.com>
*
@@ -61,22 +61,76 @@ static int hf_ldp_version = -1;
static int hf_ldp_pdu_len = -1;
static int hf_ldp_lsr = -1;
static int hf_ldp_ls_id = -1;
+static int hf_ldp_msg_ubit = -1;
static int hf_ldp_msg_type = -1;
static int hf_ldp_msg_len = -1;
static int hf_ldp_msg_id = -1;
+static int hf_ldp_msg_vendor_id = -1;
+static int hf_ldp_msg_experiment_id = -1;
static int hf_ldp_tlv_value = -1;
static int hf_ldp_tlv_type = -1;
+static int hf_ldp_tlv_unknown = -1;
static int hf_ldp_tlv_len = -1;
static int hf_ldp_tlv_val_hold = -1;
static int hf_ldp_tlv_val_target = -1;
static int hf_ldp_tlv_val_request = -1;
static int hf_ldp_tlv_val_res = -1;
+static int hf_ldp_tlv_ipv4_taddr = -1;
static int hf_ldp_tlv_config_seqno = -1;
+static int hf_ldp_tlv_ipv6_taddr = -1;
static int hf_ldp_tlv_fec_wc = -1;
static int hf_ldp_tlv_fec_af = -1;
static int hf_ldp_tlv_fec_len = -1;
static int hf_ldp_tlv_fec_pfval = -1;
+static int hf_ldp_tlv_fec_hoval = -1;
+static int hf_ldp_tlv_addrl_addr_family = -1;
+static int hf_ldp_tlv_addrl_addr = -1;
+static int hf_ldp_tlv_hc_value = -1;
+static int hf_ldp_tlv_pv_lsrid = -1;
static int hf_ldp_tlv_generic_label = -1;
+static int hf_ldp_tlv_atm_label_vbits = -1;
+static int hf_ldp_tlv_atm_label_vpi = -1;
+static int hf_ldp_tlv_atm_label_vci = -1;
+static int hf_ldp_tlv_fr_label_len = -1;
+static int hf_ldp_tlv_fr_label_dlci = -1;
+static int hf_ldp_tlv_status_ebit = -1;
+static int hf_ldp_tlv_status_fbit = -1;
+static int hf_ldp_tlv_status_data = -1;
+static int hf_ldp_tlv_status_msg_id = -1;
+static int hf_ldp_tlv_status_msg_type = -1;
+static int hf_ldp_tlv_extstatus_data = -1;
+static int hf_ldp_tlv_returned_version = -1;
+static int hf_ldp_tlv_returned_pdu_len = -1;
+static int hf_ldp_tlv_returned_lsr = -1;
+static int hf_ldp_tlv_returned_ls_id = -1;
+static int hf_ldp_tlv_returned_msg_ubit = -1;
+static int hf_ldp_tlv_returned_msg_type = -1;
+static int hf_ldp_tlv_returned_msg_len = -1;
+static int hf_ldp_tlv_returned_msg_id = -1;
+static int hf_ldp_tlv_sess_ver = -1;
+static int hf_ldp_tlv_sess_ka = -1;
+static int hf_ldp_tlv_sess_advbit = -1;
+static int hf_ldp_tlv_sess_ldetbit = -1;
+static int hf_ldp_tlv_sess_pvlim = -1;
+static int hf_ldp_tlv_sess_mxpdu = -1;
+static int hf_ldp_tlv_sess_rxlsr = -1;
+static int hf_ldp_tlv_sess_rxls = -1;
+static int hf_ldp_tlv_sess_atm_merge = -1;
+static int hf_ldp_tlv_sess_atm_lr = -1;
+static int hf_ldp_tlv_sess_atm_dir = -1;
+static int hf_ldp_tlv_sess_atm_minvpi = -1;
+static int hf_ldp_tlv_sess_atm_maxvpi = -1;
+static int hf_ldp_tlv_sess_atm_minvci = -1;
+static int hf_ldp_tlv_sess_atm_maxvci = -1;
+static int hf_ldp_tlv_sess_fr_merge = -1;
+static int hf_ldp_tlv_sess_fr_lr = -1;
+static int hf_ldp_tlv_sess_fr_dir = -1;
+static int hf_ldp_tlv_sess_fr_len = -1;
+static int hf_ldp_tlv_sess_fr_mindlci = -1;
+static int hf_ldp_tlv_sess_fr_maxdlci = -1;
+static int hf_ldp_tlv_lbl_req_msg_id = -1;
+static int hf_ldp_tlv_vendor_id = -1;
+static int hf_ldp_tlv_experiment_id = -1;
static int ett_ldp = -1;
static int ett_ldp_header = -1;
@@ -89,6 +143,9 @@ static int ett_ldp_fec = -1;
static int tcp_port = 0;
static int udp_port = 0;
+/* desegmentation of LDP over TCP */
+static gboolean ldp_desegment = FALSE;
+
/* Add your functions here */
static int global_ldp_tcp_port = TCP_PORT_LDP;
@@ -119,29 +176,32 @@ static int global_ldp_udp_port = UDP_PORT_LDP;
#define TLV_LABEL_REQUEST_MESSAGE_ID 0x0600
#define TLV_VENDOR_PRIVATE_START 0x3E00
-#define TLV_VENDOR_PROVATE_END 0x3EFF
+#define TLV_VENDOR_PRIVATE_END 0x3EFF
#define TLV_EXPERIMENTAL_START 0x3F00
#define TLV_EXPERIMENTAL_END 0x3FFF
static const value_string tlv_type_names[] = {
- { TLV_FEC, "Forwarding Equivalence Classes" },
- { TLV_ADDRESS_LIST, "Address List"},
- { TLV_HOP_COUNT, "Hop Count"},
- { TLV_PATH_VECTOR, "Path Vector"},
- { TLV_GENERIC_LABEL, "Generic Label"},
- { TLV_ATM_LABEL, "Frame Label"},
- { TLV_STATUS, "Status"},
- { TLV_EXTENDED_STATUS, "Extended Status"},
- { TLV_RETURNED_PDU, "Returned PDU"},
- { TLV_RETURNED_MESSAGE, "Returned Message"},
- { TLV_COMMON_HELLO_PARMS, "Common Hello Parameters"},
- { TLV_IPV4_TRANSPORT_ADDRESS, "IPv4 Transport Address"},
- { TLV_CONFIGURATION_SEQNO, "Configuration Sequence Number"},
- { TLV_IPV6_TRANSPORT_ADDRESS, "IPv6 Transport Address"},
- { TLV_COMMON_SESSION_PARMS, "Common Session Parameters"},
- { TLV_ATM_SESSION_PARMS, "ATM Session Parameters"},
- { TLV_FRAME_RELAY_SESSION_PARMS, "Frame Relay Session Parameters"},
- { TLV_LABEL_REQUEST_MESSAGE_ID, "Label Request Message ID"},
+ { TLV_FEC, "Forwarding Equivalence Classes TLV" },
+ { TLV_ADDRESS_LIST, "Address List TLV"},
+ { TLV_HOP_COUNT, "Hop Count TLV"},
+ { TLV_PATH_VECTOR, "Path Vector TLV"},
+ { TLV_GENERIC_LABEL, "Generic Label TLV"},
+ { TLV_ATM_LABEL, "ATM Label TLV"},
+ { TLV_FRAME_LABEL, "Frame Label TLV"},
+ { TLV_STATUS, "Status TLV"},
+ { TLV_EXTENDED_STATUS, "Extended Status TLV"},
+ { TLV_RETURNED_PDU, "Returned PDU TLV"},
+ { TLV_RETURNED_MESSAGE, "Returned Message TLV"},
+ { TLV_COMMON_HELLO_PARMS, "Common Hello Parameters TLV"},
+ { TLV_IPV4_TRANSPORT_ADDRESS, "IPv4 Transport Address TLV"},
+ { TLV_CONFIGURATION_SEQNO, "Configuration Sequence Number TLV"},
+ { TLV_IPV6_TRANSPORT_ADDRESS, "IPv6 Transport Address TLV"},
+ { TLV_COMMON_SESSION_PARMS, "Common Session Parameters TLV"},
+ { TLV_ATM_SESSION_PARMS, "ATM Session Parameters TLV"},
+ { TLV_FRAME_RELAY_SESSION_PARMS, "Frame Relay Session Parameters TLV"},
+ { TLV_LABEL_REQUEST_MESSAGE_ID, "Label Request Message ID TLV"},
+ { TLV_VENDOR_PRIVATE_START, "Vendor Private TLV"},
+ { TLV_EXPERIMENTAL_START, "Experimental TLV"},
{ 0, NULL}
};
@@ -166,685 +226,1422 @@ static const value_string tlv_type_names[] = {
#define LDP_EXPERIMENTAL_MESSAGE_END 0x3FFF
static const value_string ldp_message_types[] = {
- {LDP_NOTIFICATION, "Notification"},
- {LDP_HELLO, "Hello"},
- {LDP_INITIALIZATION, "Initialization"},
- {LDP_KEEPALIVE, "Keep Alive"},
- {LDP_ADDRESS, "Address"},
- {LDP_ADDRESS_WITHDRAWAL, "Address Withdrawal"},
- {LDP_LABEL_MAPPING, "Label Mapping"},
- {LDP_LABEL_REQUEST, "Label Request"},
- {LDP_LABEL_WITHDRAWAL, "Label Withdrawal"},
- {LDP_LABEL_RELEASE, "Label Release"},
- {LDP_LABEL_ABORT_REQUEST, "Label Abort Request"},
+ {LDP_NOTIFICATION, "Notification Message"},
+ {LDP_HELLO, "Hello Message"},
+ {LDP_INITIALIZATION, "Initialization Message"},
+ {LDP_KEEPALIVE, "Keep Alive Message"},
+ {LDP_ADDRESS, "Address Message"},
+ {LDP_ADDRESS_WITHDRAWAL, "Address Withdrawal Message"},
+ {LDP_LABEL_MAPPING, "Label Mapping Message"},
+ {LDP_LABEL_REQUEST, "Label Request Message"},
+ {LDP_LABEL_WITHDRAWAL, "Label Withdrawal Message"},
+ {LDP_LABEL_RELEASE, "Label Release Message"},
+ {LDP_LABEL_ABORT_REQUEST, "Label Abort Request Message"},
+ {LDP_VENDOR_PRIVATE_START, "Vendor-Private Message"},
+ {LDP_EXPERIMENTAL_MESSAGE_START, "Experimental Message"},
{0, NULL}
};
+static const true_false_string ldp_message_ubit = {
+ "Unknown bit set",
+ "Unknown bit not set"
+};
+
static const true_false_string hello_targeted_vals = {
"Targeted Hello",
"Link Hello"
};
-static const value_string fec_types[] = {
- {1, "Wildcard FEC"},
- {2, "Prefix FEC"},
- {3, "Host Address FEC"},
+static const value_string tlv_unknown_vals[] = {
+ {0, "Known TLV"},
+ {1, "Known TLV"},
+ {2, "Unknown TLV, do not Forward"},
+ {3, "Unknown TLV, do Forward"},
{0, NULL}
};
-static const true_false_string hello_requested_vals = {
- "Source requests periodic hellos",
- "Source does not request periodic hellos"
-};
-
-/* Dissect the common hello params */
-
-void dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
-{
- proto_tree *ti = NULL, *val_tree = NULL;
-
- if (tree) {
-
- ti = proto_tree_add_item(tree, hf_ldp_tlv_value, tvb, offset, rem,
- FALSE);
-
- val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
-
- proto_tree_add_item(val_tree, hf_ldp_tlv_val_hold, tvb, offset, 2, FALSE);
-
- proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_target, tvb, offset + 2, 2, FALSE);
- proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_request, tvb, offset + 2, 2, FALSE);
- proto_tree_add_item(val_tree, hf_ldp_tlv_val_res, tvb, offset + 2, 2, FALSE);
- }
-
-}
-
-/* Dissect a TLV and return the number of bytes consumed ... */
-
-int dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
-{
- guint16 message = tvb_get_ntohs(tvb, offset),
- length = tvb_get_ntohs(tvb, offset + 2),
- pad = 0, fec_len = 0;
- proto_tree *ti = NULL, *tlv_tree = NULL;
-
- /* Hmmm, check for illegal alignment padding */
-
- if (message == 0x00) {
-
- proto_tree_add_text(tree, tvb, offset, 2, "Illegal Padding: %04X", message);
- offset += 2; pad = 2;
- message = tvb_get_ntohs(tvb, offset);
- length = tvb_get_ntohs(tvb, offset + 2);
-
- }
-
- length = MIN(length, rem); /* Don't go haywire if a problem ... */
-
- if (tree) {
-
- /* FIXME: Account for vendor and special messages */
-
- ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
- val_to_str(message, tlv_type_names, "Unknown TLV type (0x%04X)"));
-
- tlv_tree = proto_item_add_subtree(ti, ett_ldp_tlv);
-
- proto_tree_add_item(tlv_tree, hf_ldp_tlv_type, tvb, offset, 2, FALSE);
-
- proto_tree_add_item(tlv_tree, hf_ldp_tlv_len, tvb, offset + 2, 2, FALSE);
-
- switch (message) {
-
- case TLV_FEC: /* Process an FEC */
-
- offset += 4; /* Skip the TLV header */
-
- fec_len = length;
+#define WILDCARD_FEC 1
+#define PREFIX_FEC 2
+#define HOST_FEC 3
- while (fec_len > 0) {
- proto_tree *fec_tree = NULL;
- guint prefix_len_octets, prefix_len, prefix;
-
-
- switch (tvb_get_guint8(tvb, offset)) {
- case 1: /* Wild Card */
-
- proto_tree_add_item(tlv_tree, hf_ldp_tlv_fec_wc, tvb, offset, 4, FALSE);
- fec_len -= 4;
-
- offset += 4;
-
- break;
-
- case 2: /* Prefix */
-
- /* Add a subtree for this ... */
-
- ti = proto_tree_add_text(tlv_tree, tvb, offset, 8, "Prefix FEC Element");
-
- fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
-
- proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
-
- offset += 1;
-
- /* XXX - the address family length should be extracted and used to
- dissect the prefix field. */
- proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
- offset += 2;
+static const value_string fec_types[] = {
+ {WILDCARD_FEC, "Wildcard FEC"},
+ {PREFIX_FEC, "Prefix FEC"},
+ {HOST_FEC, "Host Address FEC"},
+ {0, NULL}
+};
- prefix_len = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
+static const value_string tlv_atm_merge_vals[] = {
+ {0, "Merge not supported"},
+ {1, "VP merge supported"},
+ {2, "VC merge supported"},
+ {3, "VP & VC merge supported"},
+ {0, NULL}
+};
- offset += 1;
- /* This is IPv4 specific. Should do IPv6 according to AF*/
- prefix_len_octets = MIN( (prefix_len+7)/8 , 4 );
- if (prefix_len > 32) {
- proto_tree_add_text(fec_tree, tvb, offset, 0,
- "Invalid prefix %u length, guessing 32", prefix_len);
- prefix_len_octets = 4;
- }
- switch (prefix_len_octets){
- case (0): /*prefix_length=0*/
- prefix = 0;
- break;
- case (1): /*1<=prefix_length<=8*/
- prefix = tvb_get_guint8(tvb, offset);
- break;
- case (2): /*9<=prefix_length<=16*/
- prefix = tvb_get_letohs(tvb, offset);
- break;
- case (3): /*17<=prefix_length<=24*/
- prefix = tvb_get_letoh24(tvb, offset);
- break;
- case (4): /*25<=prefix_length<=32*/
- prefix = tvb_get_letohl(tvb, offset);
- break;
- default: /*prefix_length>32*/
- g_assert_not_reached();
- prefix = 0;
- break;
- }
- proto_tree_add_ipv4(fec_tree, hf_ldp_tlv_fec_pfval, tvb,
- offset, prefix_len_octets, prefix);
- fec_len -= 4+prefix_len_octets;
- break;
+static const value_string tlv_atm_vbits_vals[] = {
+ {0, "VPI & VCI Significant"},
+ {1, "Only VPI Significant"},
+ {2, "Only VCI Significant"},
+ {3, "VPI & VCI not Significant, nonsense"},
+ {0, NULL}
+};
- case 3: /* Host address */
+static const value_string tlv_fr_merge_vals[] = {
+ {0, "Merge not supported"},
+ {1, "Merge supported"},
+ {2, "Unspecified"},
+ {3, "Unspecified"},
+ {0, NULL}
+};
- /* XXX - write me. */
+static const value_string tlv_fr_len_vals[] = {
+ {0, "10 bits"},
+ {1, "Reserved"},
+ {2, "23 bits"},
+ {3, "Reserved"},
+ {0, NULL}
+};
- fec_len -= 8;
+static const true_false_string tlv_atm_dirbit = {
+ "Bidirectional capability",
+ "Unidirectional capability"
+};
- offset += 8;
+static const true_false_string hello_requested_vals = {
+ "Source requests periodic hellos",
+ "Source does not request periodic hellos"
+};
- break;
+static const true_false_string tlv_sess_advbit_vals = {
+ "Downstream On Demand proposed",
+ "Downstream Unsolicited proposed"
+};
- default: /* Unknown */
+static const true_false_string tlv_sess_ldetbit_vals = {
+ "Loop Detection Enabled",
+ "Loop Detection Disabled"
+};
- /* XXX - do all FEC's have a length that's a multiple of 4? */
- /* Hmmm, don't think so. Will check. RJS. */
+static const true_false_string tlv_status_ebit = {
+ "Fatal Error Notification",
+ "Advisory Notification"
+};
- fec_len -= 4;
+static const true_false_string tlv_status_fbit = {
+ "Notification should be Forwarded",
+ "Notification should NOT be Forwarded"
+};
- offset += 4;
+static const value_string tlv_status_data[] = {
+ {0, "Success"},
+ {1, "Bad LDP Identifier"},
+ {2, "Bad Protocol Version"},
+ {3, "Bad PDU Length"},
+ {4, "Unknown Message Type"},
+ {5, "Bad Message Length"},
+ {6, "Unknown TLV"},
+ {7, "Bad TLV Length"},
+ {8, "Malformed TLV Value"},
+ {9, "Hold Timer Expired"},
+ {10, "Shutdown"},
+ {11, "Loop Detected"},
+ {12, "Unknown FEC"},
+ {13, "No Route"},
+ {14, "No Label Resources"},
+ {15, "Label Resources / Available"},
+ {16, "Session Rejected / No Hello"},
+ {17, "Session Rejected / Parameters Advertisement Mode"},
+ {18, "Session Rejected / Parameters Max PDU Length"},
+ {19, "Session Rejected / Parameters Label Range"},
+ {20, "KeepAlive Timer Expired"},
+ {21, "Label Request Aborted"},
+ {22, "Missing Message Parameters"},
+ {23, "Unsoported Address Family"},
+ {24, "Session Rejected / Bad KeepAlive Time"},
+ {25, "Internal Error"},
+ {0, NULL}
+};
- break;
+/* Dissect FEC TLV */
+void
+dissect_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+{
+ proto_tree *ti=NULL, *val_tree=NULL, *fec_tree=NULL;
+ guint16 family, ix=1, ax;
+ guint8 addr_size=0, *addr, implemented, prefix_len_octets, prefix_len, host_len;
+ void *str_handler=NULL;
+ char *str;
+
+ if (tree) {
+
+ if( rem < 4 ) {
+ proto_tree_add_text(tree, tvb, offset, rem, "Error processing TLV");
+ return;
+ }
+
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "FEC Elements");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
+
+ while (rem > 0){
+ switch (tvb_get_guint8(tvb, offset)) {
+ case WILDCARD_FEC:
+ ti = proto_tree_add_text(val_tree, tvb, offset, 4, "FEC Element %u", ix);
+ fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
+ if(fec_tree == NULL) return;
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc,tvb, offset, 4, FALSE);
+ rem -= 1;
+ offset += 1;
+ break;
+
+ case PREFIX_FEC:
+ if( rem < 4 ){/*not enough*/
+ proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
+ return;
+ }
+ family=tvb_get_ntohs(tvb, offset+1);
+ prefix_len=tvb_get_guint8(tvb, offset+3);
+ prefix_len_octets=(prefix_len+7)/8;
+
+ implemented=1;
+ switch(family) {
+ case AFNUM_INET: /*IPv4*/
+ addr_size=4;
+ str_handler=ip_to_str;
+ break;
+ case AFNUM_INET6: /*IPv6*/
+ addr_size=16;
+ str_handler=ip6_to_str;
+ break;
+ default:
+ implemented=0;
+ break;
+ }
+
+ if( !implemented ) {
+ guint16 noctets;
+
+ noctets= rem>4+prefix_len_octets?4+prefix_len_octets:rem;
+ proto_tree_add_text(val_tree, tvb, offset, noctets,"Support for Address Family not implemented");
+ offset+=noctets;
+ rem-=noctets;
+ break;
+ }
+
+ if( rem < 4+MIN(addr_size, prefix_len_octets) ){
+ proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
+ return;
+ }
+
+ /*Add a subtree for this*/
+ ti = proto_tree_add_text(val_tree, tvb, offset, 4+MIN(addr_size, prefix_len_octets), "FEC Element %u", ix);
+ fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
+ if(fec_tree == NULL) return;
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
+ offset += 1;
+
+
+ if( addr_size < prefix_len_octets) {
+ offset+=addr_size;
+ rem-=addr_size;
+ proto_tree_add_text(fec_tree, tvb, offset-1, 1, "Invalid prefix %u length for family %s", prefix_len, val_to_str(family, afn_vals, "Unknown Family"));
+ break;
+ }
+
+ if( (addr=g_malloc0(addr_size)) == NULL ){
+ /*big big trouble, no mem or bad addr_size*/
+ fprintf(stderr, "packet-ldp: dissect_tlv_fec() malloc failed\n");
+ return;
+ }
+
+ for(ax=0; ax+1 <= prefix_len_octets; ax++)
+ addr[ax]=tvb_get_guint8(tvb, offset+ax);
+ if( prefix_len % 8 )
+ addr[ax-1] = addr[ax-1]&(0xFF<<(8-prefix_len%8));
+
+ str = (* (char* (*)(guint8 *))str_handler)(addr);
+ proto_tree_add_string_format(fec_tree, hf_ldp_tlv_fec_pfval, tvb, offset, prefix_len_octets, str, "Prefix: %s", str);
+
+ offset += prefix_len_octets;
+ rem -= 4+prefix_len_octets;
+ g_free(addr);
+ break;
+
+ case HOST_FEC:
+ if( rem < 4 ){/*not enough*/
+ proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
+ return;
+ }
+ family=tvb_get_ntohs(tvb, offset+1);
+ host_len=tvb_get_guint8(tvb, offset+3);
+
+ implemented=1;
+ switch(family) {
+ case AFNUM_INET: /*IPv4*/
+ addr_size=4;
+ str_handler=ip_to_str;
+ break;
+ case AFNUM_INET6: /*IPv6*/
+ addr_size=16;
+ str_handler=ip6_to_str;
+ break;
+ default:
+ implemented=0;
+ break;
+ }
+
+ if( !implemented ) {
+ guint16 noctets;
+
+ noctets= rem>4+host_len?4+host_len:rem;
+ proto_tree_add_text(val_tree, tvb, offset, noctets,"Support for Address Family not implemented");
+ offset+=noctets;
+ rem-=noctets;
+ break;
+ }
+
+ if( rem < 4+addr_size ){
+ proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
+ return;
+ }
+
+ /*Add a subtree for this*/
+ ti = proto_tree_add_text(val_tree, tvb, offset, 4+addr_size, "FEC Element %u", ix);
+ fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
+ if(fec_tree == NULL) return;
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
+ offset += 1;
+
+
+ if( addr_size != host_len) {
+ offset+=addr_size;
+ rem-=addr_size;
+ proto_tree_add_text(fec_tree, tvb, offset-1, 1, "Invalid address length %u length for family %s", host_len, val_to_str(family, afn_vals, "Unknown Family"));
+ break;
+ }
+
+ if( (addr=g_malloc0(addr_size)) == NULL ){
+ /*big big xtrouble, no mem or bad addr_size*/
+ fprintf(stderr, "packet-ldp: dissect_tlv_fec() malloc failed\n");
+ return;
+ }
+
+ for(ax=0; ax+1 <= host_len; ax++)
+ addr[ax]=tvb_get_guint8(tvb, offset+ax);
+
+ str = (* (char* (*)(guint8 *))str_handler)(addr);
+ proto_tree_add_string_format(fec_tree, hf_ldp_tlv_fec_hoval, tvb, offset, host_len, str, "Address: %s", str);
+
+ offset += host_len;
+ rem -= 4+host_len;
+ g_free(addr);
+ break;
+
+ default: /* Unknown */
+ /* XXX - do all FEC's have a length that's a multiple of 4? */
+ /* Hmmm, don't think so. Will check. RJS. */
+ /* If we don't know its structure, we have to exit */
+ ti = proto_tree_add_text(val_tree, tvb, offset, 4, "FEC Element %u", ix);
+ fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
+ if(fec_tree == NULL) return;
+ proto_tree_add_text(fec_tree, tvb, offset, rem, "Unknown FEC TLV type");
+ return;
+ }
+ ix++;
+ }
}
-
- }
-
- break;;
-
- case TLV_GENERIC_LABEL:
-
- proto_tree_add_item(tlv_tree, hf_ldp_tlv_generic_label, tvb, offset + 4, 4, FALSE);
-
- break;
-
- case TLV_COMMON_HELLO_PARMS:
-
- dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree, length);
- break;
-
- case TLV_CONFIGURATION_SEQNO:
-
- proto_tree_add_item(tlv_tree, hf_ldp_tlv_config_seqno, tvb, offset + 4, 4, FALSE);
- break;
-
- default:
- proto_tree_add_item(tlv_tree, hf_ldp_tlv_value, tvb, offset + 4,
- length, FALSE);
-
- break;
- }
-
- }
-
- return length + pad + 4; /* Length of the value field + header */
-
}
-/*
- * Each of these routines dissect the relevant messages, but the msg header
- * has already been dissected.
- */
+/* Dissect Address List TLV */
void
-dissect_ldp_notification(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_address_list(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
+ proto_tree *ti = NULL, *val_tree = NULL;
+ guint16 family, ix;
+ guint8 addr_size, *addr;
+ void *str_handler;
+ char *str;
+
+ if (tree) {
+ if( rem < 2 ) {
+ proto_tree_add_text(tree, tvb, offset, rem,
+ "Error processing TLV");
+ return;
+ }
+
+ family=tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(tree, hf_ldp_tlv_addrl_addr_family, tvb,
+ offset, 2, FALSE);
+ switch(family) {
+ case AFNUM_INET: /*IPv4*/
+ addr_size=4;
+ str_handler=ip_to_str;
+ break;
+ case AFNUM_INET6: /*IPv6*/
+ addr_size=16;
+ str_handler=ip6_to_str;
+ break;
+ default:
+ proto_tree_add_text(tree, tvb, offset+2, rem-2,
+ "Support for Address Family not implemented");
+ return;
+ }
+
+ offset+=2; rem-=2;
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "Addresses");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if(val_tree == NULL) return;
+ if( (addr=g_malloc(addr_size)) == NULL ){
+ /*big big trouble*/
+ fprintf(stderr, "packet-ldp: dissect_tlv_address_list() malloc failed\n");
+ return;
+ }
+
+ for(ix=1; rem >= addr_size; ix++, offset += addr_size,
+ rem -= addr_size) {
+ if( (tvb_memcpy(tvb, addr, offset, addr_size))
+ == NULL)
+ break;
+
+ str = (* (char* (*)(guint8 *))str_handler)(addr);
+ proto_tree_add_string_format(val_tree,
+ hf_ldp_tlv_addrl_addr, tvb, offset, addr_size, str,
+ "Address %u : %s", ix, str);
+ }
+ if(rem)
+ proto_tree_add_text(val_tree, tvb, offset, rem,
+ "Error processing TLV");
+ g_free(addr);
+ }
}
-/* Dissect a Hello Message ... */
-void
-dissect_ldp_hello(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
-{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
-}
+/* Dissect Path Vector TLV */
void
-dissect_ldp_initialization(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_path_vector(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
+ proto_tree *ti = NULL, *val_tree = NULL;
+ guint8 ix, *addr;
+
+ if (tree) {
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "LSR IDs");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if(val_tree == NULL) return;
+
+ for(ix=1; rem >= 4; ix++, offset += 4, rem -= 4) {
+ if( (addr=(guint8 *)tvb_get_ptr(tvb, offset, 4))
+ == NULL)
+ break;
+ proto_tree_add_ipv4_format(val_tree, hf_ldp_tlv_pv_lsrid, tvb,
+ offset, 4, tvb_get_ntohl(tvb, offset), "LSR Id %u : %s", ix,
+ ip_to_str(addr));
+ }
+ if(rem)
+ proto_tree_add_text(val_tree, tvb, offset, rem,
+ "Error processing TLV");
+ }
}
-void
-dissect_ldp_keepalive(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
-{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
-}
+/* Dissect ATM Label TLV */
void
-dissect_ldp_address(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_atm_label(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
+ proto_tree *ti = NULL, *val_tree = NULL;
+ guint16 id;
+
+ if(tree) {
+ if(rem != 4){
+ proto_tree_add_text(tree, tvb, offset, rem, "Error processing TLV");
+ return;
+ }
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "ATM Label");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
+
+ proto_tree_add_item(val_tree, hf_ldp_tlv_atm_label_vbits, tvb, offset, 1, FALSE);
+
+ id=tvb_get_ntohs(tvb, offset)&0x0FFF;
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_atm_label_vpi, tvb, offset, 2, id, "VPI: %u", id);
+
+ id=tvb_get_ntohs(tvb, offset+2);
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_atm_label_vci, tvb, offset+2, 2, id, "VCI: %u", id);
+ }
}
-void
-dissect_ldp_address_withdrawal(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
-{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
-}
+/* Dissect FRAME RELAY Label TLV */
void
-dissect_ldp_label_mapping(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_frame_label(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
+ proto_tree *ti = NULL, *val_tree = NULL;
+ guint8 len;
+ guint32 id;
+
+ if(tree) {
+ if(rem != 4){
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing TLV");
+ return;
+ }
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "Frame Relay Label");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
+
+ len=(guint8)(tvb_get_ntohs(tvb, offset)>>7) & 0x03;
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_fr_label_len, tvb, offset, 2, len, "Number of DLCI bits: %s (%u)", val_to_str(len, tlv_fr_len_vals, "Unknown Length"), len);
+
+ id=tvb_get_ntoh24(tvb, offset+1)&0x7FFFFF;
+ proto_tree_add_uint_format(val_tree,
+ hf_ldp_tlv_fr_label_dlci, tvb, offset+1, 3, id, "DLCI: %u", id);
+ }
}
-void
-dissect_ldp_label_request(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
-{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
-}
+/* Dissect STATUS TLV */
void
-dissect_ldp_label_withdrawal(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_status(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
+ proto_tree *ti = NULL, *val_tree = NULL;
+ guint32 data;
- while (rem > 0) {
+ if(tree) {
+ if(rem != 10){
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing TLV");
+ return;
+ }
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "Status");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
- }
+ proto_tree_add_item(val_tree, hf_ldp_tlv_status_ebit, tvb, offset, 1, FALSE);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_status_fbit, tvb, offset, 1, FALSE);
+
+ data=tvb_get_ntohl(tvb, offset)&0x3FFFFFFF;
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_status_data, tvb, offset, 4, data, "Status Data: %s (0x%X)", val_to_str(data, tlv_status_data, "Unknown Status Data"), data);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_status_msg_id, tvb, offset+4, 4, FALSE);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_status_msg_type, tvb, offset+8, 2, FALSE);
+ }
}
+/* Dissect Returned PDU TLV */
+
void
-dissect_ldp_label_release(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_returned_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
-
- while (rem > 0) {
-
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
-
- }
-
+ proto_tree *ti = NULL, *val_tree = NULL;
+
+ if(tree) {
+ if(rem < 10){
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing TLV");
+ return;
+ }
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "Returned PDU");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
+
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_version, tvb, offset, 2, FALSE);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_pdu_len, tvb, offset+2, 2, FALSE);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_lsr, tvb, offset+4, 4, FALSE);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_ls_id, tvb, offset+8, 2, FALSE);
+ offset += 10;
+ rem -= 10;
+
+ if( rem > 0 ) {
+ /*XXX - dissect returned pdu data*/
+ proto_tree_add_text(val_tree, tvb, offset, rem, "Returned PDU Data");
+ }
+ }
}
+/* Dissect Returned MESSAGE TLV */
+
void
-dissect_ldp_label_abort_request(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
+dissect_tlv_returned_message(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- guint rem = length, cc = 0;
+ proto_tree *ti = NULL, *val_tree = NULL;
+ guint16 type;
+
+ if(tree) {
+ if(rem < 4){
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing TLV");
+ return;
+ }
+ ti=proto_tree_add_text(tree, tvb, offset, rem, "Returned Message");
+ val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
+
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_ubit, tvb, offset, 1, FALSE);
+
+ type=tvb_get_ntohs(tvb, offset)&0x7FFF;
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_returned_msg_type, tvb, offset, 2, type, "Message Type: %s (0x%X)", val_to_str(type, ldp_message_types,"Unknown Message Type"), type);
+
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_len, tvb, offset+2, 2, FALSE);
+ offset += 4;
+ rem -= 4;
+
+ if( rem >= 4 ) { /*have msg_id*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_id, tvb, offset, 4, FALSE);
+ offset += 4;
+ rem -= 4;
+ }
+
+ if( rem > 0 ) {
+ /*XXX - dissect returned msg parameters*/
+ proto_tree_add_text(val_tree, tvb, offset, rem, "Returned Message Parameters");
+ }
+ }
+}
- while (rem > 0) {
+/* Dissect the common hello params */
- rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
- offset += cc;
+void
+dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+{
+ proto_tree *ti = NULL, *val_tree = NULL;
+
+ if (tree) {
+#if 0
+ ti = proto_tree_add_item(tree, hf_ldp_tlv_value, tvb, offset, rem, FALSE);
+ val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
+ if(val_tree == NULL) return;
+#else
+ val_tree=tree;
+#endif
+ proto_tree_add_item(val_tree, hf_ldp_tlv_val_hold, tvb, offset, 2, FALSE);
+ proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_target, tvb, offset + 2, 2, FALSE);
+ proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_request, tvb, offset + 2, 2, FALSE);
+ proto_tree_add_item(val_tree, hf_ldp_tlv_val_res, tvb, offset + 2, 2, FALSE);
+ }
+}
- }
+/* Dissect the common session params */
+void
+dissect_tlv_common_session_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+{
+ proto_tree *ti = NULL, *val_tree = NULL;
+
+ if (tree != NULL) {
+ ti = proto_tree_add_text(tree, tvb, offset, rem, "Parameters");
+ if( rem != 14) { /*length of Comm Sess Parms tlv*/
+ proto_tree_add_text(tree, tvb, offset, rem, "Error processing TLV");
+ return ;
+ }
+ val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if(val_tree != NULL) {
+ /*Protocol Version*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ver, tvb,offset, 2, FALSE);
+
+ /*KeepAlive Time*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ka, tvb,offset + 2, 2, FALSE);
+
+ /*A bit*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_advbit,tvb, offset + 4, 1, FALSE);
+
+ /*D bit*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ldetbit,tvb, offset + 4, 1, FALSE);
+
+ /*Path Vector Limit*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_pvlim,tvb, offset + 5, 1, FALSE);
+
+ /*Max PDU Length*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_mxpdu,tvb, offset + 6, 2, FALSE);
+
+ /*Rx LSR*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_rxlsr,tvb, offset + 8, 4, FALSE);
+
+ /*Rx LS*/
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_rxls,tvb, offset + 12, 2, FALSE);
+ }
+ }
}
-static int
-dissect_ldp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+/* Dissect the atm session params */
+
+void
+dissect_tlv_atm_session_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
{
- proto_tree *ldp_tree = NULL, *hdr_tree = NULL, *ldpid_tree = NULL;
- proto_item *ldp_item = NULL, *hdr_item = NULL, *ldpid_item = NULL;
- int msg_cnt = 0;
- guint16 ldp_message = 0;
- guint pdu_len;
+ proto_tree *ti = NULL, *val_tree = NULL, *lbl_tree = NULL;
+ guint8 numlr, ix;
+ guint16 id;
+
+ if (tree != NULL) {
+ if(rem < 4) {
+ proto_tree_add_text(tree, tvb, offset, rem,
+ "Error processing TLV");
+ return;
+ }
+
+ ti = proto_tree_add_text(tree, tvb, offset, rem,"ATM Parameters");
+ val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if(val_tree != NULL) {
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_atm_merge,tvb, offset, 1, FALSE);
+
+ /*get the number of label ranges*/
+ numlr=(tvb_get_guint8(tvb, offset)>>2) & 0x0F;
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_sess_atm_lr,
+ tvb, offset, 1, numlr, "Number of Label Range components: %u",
+ numlr);
+
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_atm_dir,tvb, offset, 1, FALSE);
+
+ /*move into range components*/
+ offset += 4;
+ rem -= 4;
+ ti = proto_tree_add_text(val_tree, tvb, offset, rem,"ATM Label Range Components");
+
+ if(numlr) {
+ val_tree=proto_item_add_subtree(ti,ett_ldp_tlv_val);
+ if( ! val_tree ) return;
+ }
+ /*now dissect ranges*/
+ for(ix=1; numlr > 0 && rem >= 8; ix++, rem-=8, numlr--) {
+ ti=proto_tree_add_text(val_tree, tvb, offset, 8,
+ "ATM Label Range Component %u", ix);
+ lbl_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if( lbl_tree == NULL ) break;
+
+ id=tvb_get_ntohs(tvb, offset)&0x0FFF;
+ proto_tree_add_uint_format(lbl_tree,
+ hf_ldp_tlv_sess_atm_minvpi,tvb, offset, 2, id, "Minimum VPI: %u", id);
+ id=tvb_get_ntohs(tvb, offset+4)&0x0FFF;
+ proto_tree_add_uint_format(lbl_tree,
+ hf_ldp_tlv_sess_atm_maxvpi,tvb, (offset+4), 2, id, "Maximum VPI: %u", id);
+
+ id=tvb_get_ntohs(tvb, offset+2);
+ proto_tree_add_uint_format(lbl_tree,
+ hf_ldp_tlv_sess_atm_minvci,tvb, offset+2, 2, id, "Minimum VCI: %u", id);
+ id=tvb_get_ntohs(tvb, offset+6);
+ proto_tree_add_uint_format(lbl_tree,
+ hf_ldp_tlv_sess_atm_maxvci,tvb, offset+6, 2, id, "Maximum VCI: %u", id);
+
+ offset += 8;
+ }
+ if( rem || numlr)
+ proto_tree_add_text(val_tree, tvb, offset, rem,"Error processing TLV");
+ }
+ }
+}
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
+/* Dissect the frame relay session params */
- if (tree) { /* Build the tree info ..., this is wrong! FIXME */
+void
+dissect_tlv_frame_relay_session_parms(tvbuff_t *tvb, guint offset,proto_tree *tree, int rem)
+{
+ proto_tree *ti = NULL, *val_tree = NULL, *lbl_tree = NULL;
+ guint8 numlr, ix, len;
+ guint32 id;
+
+ if (tree != NULL) {
+ if(rem < 4) {
+ proto_tree_add_text(tree, tvb, offset, rem,
+ "Error processing TLV");
+ return;
+ }
+
+ ti = proto_tree_add_text(tree, tvb, offset, rem,
+ "Frame Relay Parameters");
+ val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if(val_tree != NULL) {
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_fr_merge,
+ tvb, offset, 1, FALSE);
+
+ /*get the number of label ranges*/
+ numlr=(tvb_get_guint8(tvb, offset)>>2) & 0x0F;
+ proto_tree_add_uint_format(val_tree, hf_ldp_tlv_sess_fr_lr,
+ tvb, offset, 1, numlr, "Number of Label Range components: %u",
+ numlr);
+
+ proto_tree_add_item(val_tree, hf_ldp_tlv_sess_fr_dir,
+ tvb, offset, 1, FALSE);
+
+ /*move into range components*/
+ offset += 4;
+ rem -= 4;
+ ti = proto_tree_add_text(val_tree, tvb, offset, rem,
+ "Frame Relay Label Range Components");
+
+ if(numlr) {
+ val_tree=proto_item_add_subtree(ti,
+ ett_ldp_tlv_val);
+ if( ! val_tree ) return;
+ }
+
+ /*now dissect ranges*/
+ for(ix=1; numlr > 0 && rem >= 8; ix++, rem-=8, numlr--) {
+ ti=proto_tree_add_text(val_tree, tvb, offset, 8,
+ "Frame Relay Label Range Component %u", ix);
+ lbl_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
+
+ if( lbl_tree == NULL ) break;
+
+ len=(guint8)(tvb_get_ntohs(tvb, offset)>>7) & 0x03;
+ proto_tree_add_uint_format(lbl_tree, hf_ldp_tlv_sess_fr_len, tvb, offset, 2, len, "Number of DLCI bits: %s (%u)", val_to_str(len, tlv_fr_len_vals, "Unknown Length"), len);
+
+ id=tvb_get_ntoh24(tvb, offset+1)&0x7FFFFF;
+ proto_tree_add_uint_format(lbl_tree,
+ hf_ldp_tlv_sess_fr_mindlci, tvb, offset+1, 3, id, "Minimum DLCI %u", id);
+ id=tvb_get_ntoh24(tvb, offset+5)&0x7FFFFF;
+ proto_tree_add_uint_format(lbl_tree,
+ hf_ldp_tlv_sess_fr_maxdlci, tvb, offset+5, 3, id, "Maximum DLCI %u", id);
+
+ offset += 8;
+ }
+
+ if( rem || numlr)
+ proto_tree_add_text(val_tree, tvb, offset, rem,
+ "Error processing TLV");
+ }
+ }
+}
- ldp_item = proto_tree_add_item(tree, proto_ldp, tvb, offset, -1, FALSE);
- ldp_tree = proto_item_add_subtree(ldp_item, ett_ldp);
- }
+/* Dissect a TLV and return the number of bytes consumed ... */
- /* Dissect LDP Header */
+int
+dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
+{
+ guint16 type, typebak;
+ int length;
+ proto_tree *ti = NULL, *tlv_tree = NULL;
- hdr_item = proto_tree_add_text(ldp_tree, tvb, offset, 10, "Header");
+ length=tvb_reported_length_remaining(tvb, offset);
+ rem=MIN(rem, length);
- hdr_tree = proto_item_add_subtree(hdr_item, ett_ldp_header);
+ if( rem < 4 ) {/*chk for minimum header*/
+ if(tree)
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing TLV");
+ return rem;
+ }
+ type = tvb_get_ntohs(tvb, offset) & 0x3FFF;
+
+ length = tvb_get_ntohs(tvb, offset + 2),
+ rem -= 4; /*do not count header*/
+ length = MIN(length, rem); /* Don't go haywire if a problem ... */
+
+ if (tree != NULL) {
+ /*chk for vendor-private*/
+ if(type>=TLV_VENDOR_PRIVATE_START && type<=TLV_VENDOR_PRIVATE_END){
+ typebak=type; /*keep type*/
+ type=TLV_VENDOR_PRIVATE_START;
+
+ /*chk for experimental*/
+ } else if(type>=TLV_EXPERIMENTAL_START && type<=TLV_EXPERIMENTAL_END){
+ typebak=type; /*keep type*/
+ type=TLV_EXPERIMENTAL_START;
+ }
+
+ ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
+ val_to_str(type, tlv_type_names, "Unknown TLV type (0x%04X)"));
+ tlv_tree = proto_item_add_subtree(ti, ett_ldp_tlv);
+ if(tlv_tree == NULL) return length+4;
+
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_unknown, tvb, offset, 1, FALSE);
+
+ proto_tree_add_uint_format(tlv_tree, hf_ldp_tlv_type, tvb, offset, 2, type, "TLV Type: %s (0x%X)", val_to_str(type, tlv_type_names, "Unknown TLV type"), type );
+
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_len, tvb, offset + 2, 2, FALSE);
+
+ switch (type) {
+
+ case TLV_FEC:
+ dissect_tlv_fec(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_ADDRESS_LIST:
+ dissect_tlv_address_list(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_HOP_COUNT:
+ if( length != 1 ) /*error, only one byte*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4,length,"Error processing TLV");
+ else
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_hc_value, tvb,offset + 4, length, FALSE);
+ break;
+
+ case TLV_PATH_VECTOR:
+ dissect_tlv_path_vector(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_GENERIC_LABEL:
+ if( length != 4 ) /*error, need only label*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ guint32 label=tvb_get_ntohl(tvb, offset+4) & 0x000FFFFF;
+
+ proto_tree_add_uint_format(tlv_tree, hf_ldp_tlv_generic_label,
+ tvb, offset+4, length, label, "Generic Label: %u", label);
+ }
+ break;
+
+ case TLV_ATM_LABEL:
+ dissect_tlv_atm_label(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_FRAME_LABEL:
+ dissect_tlv_frame_label(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_STATUS:
+ dissect_tlv_status(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_EXTENDED_STATUS:
+ if( length != 4 ) /*error, need only status_code(guint32)*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_extstatus_data, tvb, offset + 4, length, FALSE);
+ }
+ break;
+
+ case TLV_RETURNED_PDU:
+ dissect_tlv_returned_pdu(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_RETURNED_MESSAGE:
+ dissect_tlv_returned_message(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_COMMON_HELLO_PARMS:
+ dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_IPV4_TRANSPORT_ADDRESS:
+ if( length != 4 ) /*error, need only ipv4*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_ipv4_taddr, tvb, offset + 4, 4, FALSE);
+ }
+ break;
+
+ case TLV_CONFIGURATION_SEQNO:
+ if( length != 4 ) /*error, need only seq_num(guint32)*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_config_seqno, tvb, offset + 4, 4, FALSE);
+ }
+ break;
+
+ case TLV_IPV6_TRANSPORT_ADDRESS:
+ if( length != 16 ) /*error, need only ipv6*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_ipv6_taddr, tvb, offset + 4, 16, FALSE);
+ }
+ break;
+
+ case TLV_COMMON_SESSION_PARMS:
+ dissect_tlv_common_session_parms(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_ATM_SESSION_PARMS:
+ dissect_tlv_atm_session_parms(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_FRAME_RELAY_SESSION_PARMS:
+ dissect_tlv_frame_relay_session_parms(tvb, offset + 4, tlv_tree, length);
+ break;
+
+ case TLV_LABEL_REQUEST_MESSAGE_ID:
+ if( length != 4 ) /*error, need only one msgid*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_lbl_req_msg_id, tvb,offset + 4,length, FALSE);
+ break;
+
+ case TLV_VENDOR_PRIVATE_START:
+ if( length < 4 ) /*error, at least Vendor ID*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_vendor_id, tvb,offset + 4, 4, FALSE);
+ if( length > 4 ) /*have data*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 8, length-4,"Data");
+ }
+ break;
+
+ case TLV_EXPERIMENTAL_START:
+ if( length < 4 ) /*error, at least Experiment ID*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 4, length,"Error processing TLV");
+ else {
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_experiment_id, tvb,offset + 4, 4, FALSE);
+ if( length > 4 ) /*have data*/
+ proto_tree_add_text(tlv_tree, tvb, offset + 8, length-4,"Data");
+ }
+ break;
+
+ default:
+ proto_tree_add_item(tlv_tree, hf_ldp_tlv_value, tvb, offset + 4, length, FALSE);
+ break;
+ }
+ }
- proto_tree_add_item(hdr_tree, hf_ldp_version, tvb, offset, 2, FALSE);
+ return length + 4; /* Length of the value field + header */
+}
- offset += 2;
- proto_tree_add_item(hdr_tree, hf_ldp_pdu_len, tvb, offset, 2, FALSE);
- pdu_len = tvb_get_ntohs(tvb, offset);
- proto_item_set_len(ldp_item, pdu_len + 2);
+/* Dissect a Message and return the number of bytes consumed ... */
- /*
- * XXX - do TCP reassembly, to handle LDP PDUs that cross TCP segment
- * boundaries.
- */
+int
+dissect_msg(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, int rem)
+{
+ guint16 type, typebak;
+ guint8 extra=0;
+ int length, ao=0, co;
+ proto_tree *ti = NULL, *msg_tree = NULL;
+
+ length=tvb_reported_length_remaining(tvb, offset);
+ rem=MIN(rem, length);
+
+ if( rem < 8 ) {/*chk for minimum header = type + length + msg_id*/
+ if( check_col(pinfo->cinfo, COL_INFO) )
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Bad Message");
+ if(tree)
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing Message");
+ return rem;
+ }
+ type = tvb_get_ntohs(tvb, offset) & 0x7FFF;
+
+ /*chk for vendor-private*/
+ if(type>=LDP_VENDOR_PRIVATE_START && type<=LDP_VENDOR_PRIVATE_END){
+ typebak=type; /*keep type*/
+ type=LDP_VENDOR_PRIVATE_START;
+ extra=4;
+ /*chk for experimental*/
+ } else if(type>=LDP_EXPERIMENTAL_MESSAGE_START && type<=LDP_EXPERIMENTAL_MESSAGE_END){
+ typebak=type; /*keep type*/
+ type=LDP_EXPERIMENTAL_MESSAGE_START;
+ extra=4;
+ }
- offset += 2;
+ if( (length = tvb_get_ntohs(tvb, offset + 2)) < (4+extra) ) {/*not enough data for type*/
+ if( check_col(pinfo->cinfo, COL_INFO) )
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Bad Message Length ");
+ if(tree)
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing Message Length");
+ return rem;
+ }
+ rem -= 4;
+ length = MIN(length, rem); /* Don't go haywire if a problem ... */
- if (pdu_len < 6) {
- /*
- * PDU is too short to hold the LDP identifier.
- */
- proto_tree_add_text(hdr_tree, tvb, offset, pdu_len,
- "PDU too short (%u bytes, should be at least 6) for LDP Identifier",
- pdu_len);
- offset += pdu_len;
- return offset;
- }
+ if( check_col(pinfo->cinfo, COL_INFO) ){
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(type, ldp_message_types, "Unknown Message (0x%04X)"));
+ }
- ldpid_item = proto_tree_add_text(hdr_tree, tvb, offset, 6, "LDP Identifier");
+ if( tree ){
+ ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
+ val_to_str(type, ldp_message_types, "Unknown Message type (0x%04X)"));
+ msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
+ if(msg_tree == NULL) return length+4;
+
+ proto_tree_add_item(msg_tree, hf_ldp_msg_ubit, tvb, offset, 1, FALSE);
+
+ type=tvb_get_ntohs(tvb, offset)&0x7FFF;
+ proto_tree_add_uint_format(msg_tree, hf_ldp_msg_type, tvb, offset, 2, type, "Message Type: %s (0x%X)", val_to_str(type, ldp_message_types,"Unknown Message Type"), type);
+
+ proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset+2, 2, FALSE);
+ proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset+4, 4, FALSE);
+ if(extra){
+ int hf_tmp=0;
+
+ switch(type){
+ case LDP_VENDOR_PRIVATE_START:
+ hf_tmp=hf_ldp_msg_vendor_id;
+ break;
+ case LDP_EXPERIMENTAL_MESSAGE_START:
+ hf_tmp=hf_ldp_msg_experiment_id;
+ break;
+ }
+ proto_tree_add_item(msg_tree, hf_tmp, tvb, offset+8, extra, FALSE);
+ }
+ }
+
+ offset += (8+extra);
+ length -= (4+extra);
+
+ if( tree )
+ while( (length-ao) > 0 ) {
+ co=dissect_tlv(tvb, offset, msg_tree, length-ao);
+ offset += co;
+ ao += co;
+ }
+
+ return length+8+extra;
+}
- ldpid_tree = proto_item_add_subtree(ldpid_item, ett_ldp_ldpid);
+/* Dissect a PDU and return the number of bytes consumed ... */
- proto_tree_add_item(ldpid_tree, hf_ldp_lsr, tvb, offset, 4, FALSE);
+int
+dissect_ldp_pdu(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, int rem, guint ix)
+{
+ int length, ao=0, co;
+ proto_tree *ti=NULL, *pdu_tree = NULL;
+
+ length=tvb_reported_length_remaining(tvb, offset);
+ rem=MIN(rem, length);
+
+ if( rem < 10 ){/*don't even have a PDU header*/
+/*XXX Need changes in desegment_tcp to handle multiple requests*/
+#if 0
+ if( pinfo->can_desegment && (pinfo->ptype==PT_TCP) && ldp_desegment ){
+ pinfo->desegment_offset=offset;
+ pinfo->desegment_len=10-rem;
+ }
+#else
+ if(tree)
+ proto_tree_add_text(tree, tvb, offset, rem,"Not enough bytes for PDU Hdr in TCP segment");
+#endif
+ return rem;
+ }
- offset += 4;
- pdu_len -= 4;
+ if( (length = tvb_get_ntohs(tvb, offset + 2)) < 6 ) {/*not enough*/
+ if( check_col(pinfo->cinfo, COL_INFO) && ix )
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PDU %u: ", ix);
+ if( check_col(pinfo->cinfo, COL_INFO) ){
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Bad PDU Length ");
+ }
+ if(tree)
+ proto_tree_add_text(tree, tvb, offset, rem,"Error processing PDU Length");
+ return rem;
+ }
- proto_tree_add_item(ldpid_tree, hf_ldp_ls_id, tvb, offset, 2, FALSE);
+ rem -=4;
+ if( length>rem ){
+ if( pinfo->can_desegment && (pinfo->ptype==PT_TCP) && ldp_desegment ){/*ask for more*/
+ pinfo->desegment_offset=offset;
+ pinfo->desegment_len=length-rem;
+ }else {
+ if( check_col(pinfo->cinfo, COL_INFO) && ix )
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PDU %u: ", ix);
+ if( check_col(pinfo->cinfo, COL_INFO) )
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Bad PDU Length ");
+ if(tree)
+ proto_tree_add_text(tree, tvb, offset, rem+4,"Error processing PDU Length");
+ }
+ return rem+4;
+ }
+
+ if( check_col(pinfo->cinfo, COL_INFO) && ix )
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PDU %u: ", ix);
- offset += 2;
- pdu_len -= 2;
+ if( tree ){
+ ti=proto_tree_add_protocol_format(tree, proto_ldp, tvb, offset,
+ length+4, "LDP PDU %u", ix);
+ pdu_tree = proto_item_add_subtree(ti, ett_ldp);
+ }
- while (pdu_len > 0) { /* Dissect LDP TLV */
+ if(pdu_tree){
+ proto_tree_add_item(pdu_tree, hf_ldp_version, tvb, offset, 2, FALSE);
+ proto_tree_add_item(pdu_tree, hf_ldp_pdu_len, tvb, offset+2, 2, FALSE);
+ proto_tree_add_item(pdu_tree, hf_ldp_lsr, tvb, offset+4, 4, FALSE);
+ proto_tree_add_item(pdu_tree, hf_ldp_ls_id, tvb, offset+8, 2, FALSE);
+ }
+ offset += 10;
+ length -= 6;
- guint msg_len;
+ while( (length-ao) > 0 ) {
+ co=dissect_msg(tvb, offset, pinfo, pdu_tree, length-ao);
+ offset += co;
+ ao += co;
+ }
+
+ return length+10;
+}
- ldp_message = tvb_get_ntohs(tvb, offset) & 0x7FFF; /* Get the message type */
+static void
+dissect_ldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
- msg_len = tvb_get_ntohs(tvb, offset + 2);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
- if (check_col(pinfo->cinfo, COL_INFO)) { /* Check the type ... */
+ dissect_ldp_pdu(tvb, 0, pinfo, tree, tvb_reported_length(tvb), 0);
+}
- if (msg_cnt > 0)
- col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
- val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
- else
- col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
- val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
-
- }
+static void
+dissect_ldp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ int offset=0, length, rtn;
+ guint ix=1;
+
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ length=tvb_reported_length(tvb);
+ while (length > 0){
+ rtn = dissect_ldp_pdu(tvb, offset, pinfo, tree, length, ix++);
+ offset += rtn;
+ length -= rtn;
+ }
+}
- msg_cnt++;
+/* Register all the bits needed with the filtering engine */
- if (tree) {
+void
+proto_register_ldp(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_ldp_req,
+ /* Change the following to the type you need */
+ { "Request", "ldp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
- proto_tree *ti = NULL, *msg_tree = NULL;
+ { &hf_ldp_rsp,
+ { "Response", "ldp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
- /* FIXME: Account for vendor and experimental messages */
+ { &hf_ldp_version,
+ { "Version", "ldp.hdr.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
- ti = proto_tree_add_text(ldp_tree, tvb, offset, msg_len + 4, "%s",
- val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
+ { &hf_ldp_pdu_len,
+ { "PDU Length", "ldp.hdr.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
- msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
-
- proto_tree_add_item(msg_tree, hf_ldp_msg_type, tvb, offset, 2, FALSE);
+ { &hf_ldp_lsr,
+ { "LSR ID", "ldp.hdr.ldpid.lsr", FT_IPv4, BASE_HEX, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
- proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset + 2, 2, FALSE);
+ { &hf_ldp_ls_id,
+ { "Label Space ID", "ldp.hdr.ldpid.lsid", FT_UINT16, BASE_DEC, NULL, 0, "LDP Label Space ID", HFILL }},
- if (msg_len < 4) {
- proto_tree_add_text(msg_tree, tvb, offset + 4, msg_len,
- "Message too short (%u bytes, should be at least 4) for Message ID",
- msg_len);
- goto next;
- }
+ { &hf_ldp_msg_ubit,
+ { "U bit", "ldp.msg.ubit", FT_BOOLEAN, 8, TFS(&ldp_message_ubit), 0x80, "Unknown Message Bit", HFILL }},
- proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset + 4, 4, FALSE);
+ { &hf_ldp_msg_type,
+ { "Message Type", "ldp.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x7FFF, "LDP message type", HFILL }},
- if (msg_len == 4) {
- /* Nothing past the message ID */
- goto next;
- }
+ { &hf_ldp_msg_len,
+ { "Message Length", "ldp.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
- switch (ldp_message) {
+ { &hf_ldp_msg_id,
+ { "Message ID", "ldp.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
- case LDP_NOTIFICATION:
+ { &hf_ldp_msg_vendor_id,
+ { "Vendor ID", "ldp.msg.vendor.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Vendor-private Message ID", HFILL }},
- dissect_ldp_notification(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_msg_experiment_id,
+ { "Experiment ID", "ldp.msg.experiment.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Experimental Message ID", HFILL }},
- break;
+ { &hf_ldp_tlv_unknown,
+ { "TLV Unknown bits", "ldp.msg.tlv.unknown", FT_UINT8, BASE_HEX, VALS(tlv_unknown_vals), 0xC0, "TLV Unknown bits Field", HFILL }},
- case LDP_HELLO:
+ { &hf_ldp_tlv_type,
+ { "TLV Type", "ldp.msg.tlv.type", FT_UINT16, BASE_HEX, VALS(tlv_type_names), 0x3FFF, "TLV Type Field", HFILL }},
- dissect_ldp_hello(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_len,
+ {"TLV Length", "ldp.msg.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length Field", HFILL }},
- break;
+ { &hf_ldp_tlv_value,
+ { "TLV Value", "ldp.msg.tlv.value", FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value Bytes", HFILL }},
- case LDP_INITIALIZATION:
+ { &hf_ldp_tlv_val_hold,
+ { "Hold Time", "ldp.msg.tlv.hello.hold", FT_UINT16, BASE_DEC, NULL, 0x0, "Hello Common Parameters Hold Time", HFILL }},
- dissect_ldp_initialization(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_val_target,
+ { "Targeted Hello", "ldp.msg.tlv.hello.targeted", FT_BOOLEAN, 8, TFS(&hello_targeted_vals), 0x80, "Hello Common Parameters Targeted Bit", HFILL }},
- break;
+ { &hf_ldp_tlv_val_request,
+ { "Hello Requested", "ldp,msg.tlv.hello.requested", FT_BOOLEAN, 8, TFS(&hello_requested_vals), 0x40, "Hello Common Parameters Hello Requested Bit", HFILL }},
+
+ { &hf_ldp_tlv_val_res,
+ { "Reserved", "ldp.msg.tlv.hello.res", FT_UINT16, BASE_HEX, NULL, 0x3FFF, "Hello Common Parameters Reserved Field", HFILL }},
- case LDP_KEEPALIVE:
+ { &hf_ldp_tlv_ipv4_taddr,
+ { "IPv4 Transport Address", "ldp.msg.tlv.ipv4.taddr", FT_IPv4, BASE_DEC, NULL, 0x0, "IPv4 Transport Address", HFILL }},
- dissect_ldp_keepalive(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
-
- break;
+ { &hf_ldp_tlv_config_seqno,
+ { "Configuration Sequence Number", "ldp.msg.tlv.hello.cnf_seqno", FT_UINT32, BASE_DEC, NULL, 0x0, "Hello Configuration Sequence Number", HFILL }},
- case LDP_ADDRESS:
+ { &hf_ldp_tlv_ipv6_taddr,
+ { "IPv6 Transport Address", "ldp.msg.tlv.ipv6.taddr", FT_IPv6, BASE_DEC, NULL, 0x0, "IPv6 Transport Address", HFILL }},
- dissect_ldp_address(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_fec_wc,
+ { "FEC Element Type", "ldp.msg.tlv.fec.type", FT_UINT8, BASE_DEC, VALS(fec_types), 0x0, "Forwarding Equivalence Class Element Types", HFILL }},
- break;
+ { &hf_ldp_tlv_fec_af,
+ { "FEC Element Address Type", "ldp.msg.tlv.fec.af", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Forwarding Equivalence Class Element Address Family", HFILL }},
- case LDP_ADDRESS_WITHDRAWAL:
+ { &hf_ldp_tlv_fec_len,
+ { "FEC Element Length", "ldp.msg.tlv.fec.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Length", HFILL }},
- dissect_ldp_address_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_fec_pfval,
+ { "FEC Element Prefix Value", "ldp.msg.tlv.fec.pfval", FT_STRING, BASE_NONE, NULL, 0x0, "Forwarding Equivalence Class Element Prefix", HFILL }},
- break;
+ { &hf_ldp_tlv_fec_hoval,
+ { "FEC Element Host Address Value", "ldp.msg.tlv.fec.hoval", FT_STRING, BASE_NONE, NULL, 0x0, "Forwarding Equivalence Class Element Address", HFILL }},
- case LDP_LABEL_MAPPING:
+ { &hf_ldp_tlv_addrl_addr_family,
+ { "Address Family", "ldp.msg.tlv.addrl.addr_family", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Address Family List", HFILL }},
- dissect_ldp_label_mapping(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_addrl_addr,
+ { "Address", "ldp.msg.tlv.addrl.addr", FT_STRING, BASE_NONE, NULL, 0x0, "Address", HFILL }},
- break;
+ { &hf_ldp_tlv_hc_value,
+ { "Hop Count Value", "ldp.msg.tlv.hc.value", FT_UINT8, BASE_DEC, NULL, 0x0, "Hop Count", HFILL }},
- case LDP_LABEL_REQUEST:
+ { &hf_ldp_tlv_pv_lsrid,
+ { "LSR Id", "ldp.msg.tlv.pv.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Path Vector LSR Id", HFILL }},
- dissect_ldp_label_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_sess_ver,
+ { "Session Protocol Version", "ldp.msg.tlv.sess.ver", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Protocol Version", HFILL }},
- break;
+ { &hf_ldp_tlv_sess_ka,
+ { "Session KeepAlive Time", "ldp.msg.tlv.sess.ka", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters KeepAlive Time", HFILL }},
- case LDP_LABEL_WITHDRAWAL:
+ { &hf_ldp_tlv_sess_advbit,
+ { "Session Label Advertisement Discipline", "ldp.msg.tlv.sess.advbit",
+ FT_BOOLEAN, 8, TFS(&tlv_sess_advbit_vals), 0x80,
+ "Common Session Parameters Label Advertisement Discipline", HFILL }},
- dissect_ldp_label_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_sess_ldetbit,
+ { "Session Loop Detection", "ldp.msg.tlv.sess.ldetbit", FT_BOOLEAN, 8, TFS(&tlv_sess_ldetbit_vals), 0x40, "Common Session Parameters Loop Detection", HFILL }},
- break;
+ { &hf_ldp_tlv_sess_pvlim,
+ { "Session Path Vector Limit", "ldp.msg.tlv.sess.pvlim", FT_UINT8, BASE_DEC, NULL, 0x0, "Common Session Parameters Path Vector Limit", HFILL }},
- case LDP_LABEL_RELEASE:
+ { &hf_ldp_tlv_sess_mxpdu,
+ { "Session Max PDU Length", "ldp.msg.tlv.sess.mxpdu", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Max PDU Length", HFILL }},
- dissect_ldp_label_release(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_sess_rxlsr,
+ { "Session Receiver LSR Identifier", "ldp.msg.tlv.sess.rxlsr", FT_IPv4, BASE_DEC, NULL, 0x0, "Common Session Parameters LSR Identifier", HFILL }},
- break;
+ { &hf_ldp_tlv_sess_rxls,
+ { "Session Receiver Label Space Identifier", "ldp.msg.tlv.sess.rxlsr", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Receiver Label Space Identifier", HFILL }},
- case LDP_LABEL_ABORT_REQUEST:
+ { &hf_ldp_tlv_sess_atm_merge,
+ { "Session ATM Merge Parameter", "ldp.msg.tlv.sess.atm.merge", FT_UINT8, BASE_DEC, VALS(tlv_atm_merge_vals), 0xC0, "Merge ATM Session Parameters", HFILL }},
- dissect_ldp_label_abort_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
+ { &hf_ldp_tlv_sess_atm_lr,
+ { "Number of ATM Label Ranges", "ldp.msg.tlv.sess.atm.lr", FT_UINT8, BASE_DEC, NULL, 0x3C, "Number of Label Ranges", HFILL }},
- break;
+ { &hf_ldp_tlv_sess_atm_dir,
+ { "Directionality", "ldp.msg.tlv.sess.atm.dir", FT_BOOLEAN, 8, TFS(&tlv_atm_dirbit), 0x02, "Lablel Directionality", HFILL }},
- default:
+ { &hf_ldp_tlv_sess_atm_minvpi,
+ { "Minimum VPI", "ldp.msg.tlv.sess.atm.minvpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "Minimum VPI", HFILL }},
- /* Some sort of unknown message, treat as undissected data */
- proto_tree_add_text(msg_tree, tvb, offset + 8, msg_len - 4,
- "Message data");
+ { &hf_ldp_tlv_sess_atm_minvci,
+ { "Minimum VCI", "ldp.msg.tlv.sess.atm.minvci", FT_UINT16, BASE_DEC, NULL, 0x0, "Minimum VCI", HFILL }},
- break;
+ { &hf_ldp_tlv_sess_atm_maxvpi,
+ { "Maximum VPI", "ldp.msg.tlv.sess.atm.maxvpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "Maximum VPI", HFILL }},
- }
-
- }
+ { &hf_ldp_tlv_sess_atm_maxvci,
+ { "Maximum VCI", "ldp.msg.tlv.sess.atm.maxvci", FT_UINT16, BASE_DEC, NULL, 0x0, "Maximum VCI", HFILL }},
-next:
- offset += msg_len + 4;
- pdu_len -= msg_len + 4;
+ { &hf_ldp_tlv_sess_fr_merge,
+ { "Session Frame Relay Merge Parameter", "ldp.msg.tlv.sess.fr.merge", FT_UINT8, BASE_DEC, VALS(tlv_fr_merge_vals), 0xC0, "Merge Frame Relay Session Parameters", HFILL }},
- }
- return offset;
-}
+ { &hf_ldp_tlv_sess_fr_lr,
+ { "Number of Frame Relay Label Ranges", "ldp.msg.tlv.sess.fr.lr", FT_UINT8, BASE_DEC, NULL, 0x3C, "Number of Label Ranges", HFILL }},
-static void
-dissect_ldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_add_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
+ { &hf_ldp_tlv_sess_fr_dir,
+ { "Directionality", "ldp.msg.tlv.sess.fr.dir", FT_BOOLEAN, 8, TFS(&tlv_atm_dirbit), 0x02, "Lablel Directionality", HFILL }},
- dissect_ldp_pdu(tvb, 0, pinfo, tree);
-}
+ { &hf_ldp_tlv_sess_fr_len,
+ { "Number of DLCI bits", "ldp.msg.tlv.sess.fr.len", FT_UINT16, BASE_DEC, VALS(tlv_fr_len_vals), 0x0180, "DLCI Number of bits", HFILL }},
-static void
-dissect_ldp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- int offset = 0;
+ { &hf_ldp_tlv_sess_fr_mindlci,
+ { "Minimum DLCI", "ldp.msg.tlv.sess.fr.mindlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "Minimum DLCI", HFILL }},
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_add_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
+ { &hf_ldp_tlv_sess_fr_maxdlci,
+ { "Maximum DLCI", "ldp.msg.tlv.sess.fr.maxdlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "Maximum DLCI", HFILL }},
- while (tvb_reported_length_remaining(tvb, offset) > 0) /* Dissect LDP PDUs */
- offset = dissect_ldp_pdu(tvb, offset, pinfo, tree);
-}
+ { &hf_ldp_tlv_lbl_req_msg_id,
+ { "Label Request Message ID", "ldp.tlv.lbl_req_msg_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Label Request Message to be aborted", HFILL }},
-/* Register all the bits needed with the filtering engine */
+ { &hf_ldp_tlv_vendor_id,
+ { "Vendor ID", "ldp.msg.tlv.vendor_id", FT_UINT32, BASE_HEX, NULL, 0, "IEEE 802 Assigned Vendor ID", HFILL }},
-void
-proto_register_ldp(void)
-{
- static hf_register_info hf[] = {
- { &hf_ldp_req,
- /* Change the following to the type you need */
- { "Request", "ldp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_ldp_tlv_experiment_id,
+ { "Experiment ID", "ldp.msg.tlv.experiment_id", FT_UINT32, BASE_HEX, NULL, 0, "Experiment ID", HFILL }},
- { &hf_ldp_rsp,
- { "Response", "ldp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_ldp_tlv_generic_label,
+ { "Generic Label", "ldp.msg.tlv.generic.label", FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, "Generic Label", HFILL }},
- { &hf_ldp_version,
- { "Version", "ldp.hdr.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
+ { &hf_ldp_tlv_atm_label_vbits,
+ { "V-bits", "ldp.msg.tlv.atm.label.vbits", FT_UINT8, BASE_HEX, VALS(tlv_atm_vbits_vals), 0x30, "ATM Label V Bits", HFILL }},
- { &hf_ldp_pdu_len,
- { "PDU Length", "ldp.hdr.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
+ { &hf_ldp_tlv_atm_label_vpi,
+ { "VPI", "ldp.msg.tlv.atm.label.vpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "ATM Label VPI", HFILL }},
- { &hf_ldp_lsr,
- { "LSR ID", "ldp.hdr.ldpid.lsr", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
+ { &hf_ldp_tlv_atm_label_vci,
+ { "VCI", "ldp.msg.tlv.atm.label.vci", FT_UINT16, BASE_DEC, NULL, 0, "ATM Label VCI", HFILL }},
- { &hf_ldp_ls_id,
- { "Label Space ID", "ldp.hdr.ldpid.lsid", FT_UINT16, BASE_HEX, NULL, 0x0, "LDP Label Space ID", HFILL }},
+ { &hf_ldp_tlv_fr_label_len,
+ { "Number of DLCI bits", "ldp.msg.tlv.fr.label.len", FT_UINT16, BASE_DEC, VALS(tlv_fr_len_vals), 0x0180, "DLCI Number of bits", HFILL }},
- { &hf_ldp_msg_type,
- { "Message Type", "ldp.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x0, "LDP message type", HFILL }},
+ { &hf_ldp_tlv_fr_label_dlci,
+ { "DLCI", "ldp.msg.tlv.fr.label.dlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "FRAME RELAY Label DLCI", HFILL }},
- { &hf_ldp_msg_len,
- { "Message Length", "ldp.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
+ { &hf_ldp_tlv_status_ebit,
+ { "E Bit", "ldp.msg.tlv.status.ebit", FT_BOOLEAN, 8, TFS(&tlv_status_ebit), 0x80, "Fatal Error Bit", HFILL }},
- { &hf_ldp_msg_id,
- { "Message ID", "ldp.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
+ { &hf_ldp_tlv_status_fbit,
+ { "F Bit", "ldp.msg.tlv.status.fbit", FT_BOOLEAN, 8, TFS(&tlv_status_fbit), 0x40, "Forward Bit", HFILL }},
- { &hf_ldp_tlv_type,
- { "TLV Type", "ldp.msg.tlv.type", FT_UINT16, BASE_HEX, VALS(tlv_type_names), 0x0, "TLV Type Field", HFILL }},
+ { &hf_ldp_tlv_status_data,
+ { "Status Data", "ldp.msg.tlv.status.data", FT_UINT32, BASE_HEX, VALS(tlv_status_data), 0x3FFFFFFF, "Status Data", HFILL }},
- { &hf_ldp_tlv_len,
- {"TLV Length", "ldp.msg.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length Field", HFILL }},
+ { &hf_ldp_tlv_status_msg_id,
+ { "Message ID", "ldp.msg.tlv.status.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "Identifies peer message to which Status TLV refers", HFILL }},
- { &hf_ldp_tlv_value,
- { "TLV Value", "ldp.msg.tlv.value", FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value Bytes", HFILL }},
+ { &hf_ldp_tlv_status_msg_type,
+ { "Message Type", "ldp.msg.tlv.status.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x0, "Type of peer message to which Status TLV refers", HFILL }},
- { &hf_ldp_tlv_val_hold,
- { "Hold Time", "ldp.msg.tlv.hello.hold", FT_UINT16, BASE_DEC, NULL, 0x0, "Hello Common Parameters Hold Time", HFILL }},
+ { &hf_ldp_tlv_extstatus_data,
+ { "Extended Status Data", "ldp.msg.tlv.extstatus.data", FT_UINT32, BASE_HEX, NULL, 0x0, "Extended Status Data", HFILL }},
- { &hf_ldp_tlv_val_target,
- { "Targeted Hello", "ldp.msg.tlv.hello.targeted", FT_BOOLEAN, 8, TFS(&hello_targeted_vals), 0x80, "Hello Common Parameters Targeted Bit", HFILL }},
+ { &hf_ldp_tlv_returned_version,
+ { "Returned PDU Version", "ldp.msg.tlv.returned.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
- { &hf_ldp_tlv_val_request,
- { "Hello Requested", "ldp,msg.tlv.hello.requested", FT_BOOLEAN, 8, TFS(&hello_requested_vals), 0x40, "Hello Common Parameters Hello Requested Bit", HFILL }},
-
- { &hf_ldp_tlv_val_res,
- { "Reserved", "ldp.msg.tlv.hello.res", FT_UINT16, BASE_HEX, NULL, 0x3FFF, "Hello Common Parameters Reserved Field", HFILL }},
+ { &hf_ldp_tlv_returned_pdu_len,
+ { "Returned PDU Length", "ldp.msg.tlv.returned.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
- { &hf_ldp_tlv_config_seqno,
- { "Configuration Sequence Number", "ldp.msg.tlv.hello.cnf_seqno", FT_UINT32, BASE_HEX, NULL, 0x0, "Hello COnfiguration Sequence Number", HFILL }},
+ { &hf_ldp_tlv_returned_lsr,
+ { "Returned PDU LSR ID", "ldp.msg.tlv.returned.ldpid.lsr", FT_IPv4, BASE_DEC, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
- { &hf_ldp_tlv_fec_wc,
- { "FEC Element Type", "ldp.msg.tlv.fec.type", FT_UINT8, BASE_DEC, VALS(fec_types), 0x0, "Forwarding Equivalence Class Element Types", HFILL }},
+ { &hf_ldp_tlv_returned_ls_id,
+ { "Returned PDU Label Space ID", "ldp.msg.tlv.returned.ldpid.lsid", FT_UINT16, BASE_HEX, NULL, 0x0, "LDP Label Space ID", HFILL }},
- { &hf_ldp_tlv_fec_af,
- { "FEC Element Address Type", "ldp.msg.tlv.fec.af", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Forwarding Equivalence Class Element Address Family", HFILL }},
+ { &hf_ldp_tlv_returned_msg_ubit,
+ { "Returned Message Unknown bit", "ldp.msg.tlv.returned.msg.ubit", FT_UINT8, BASE_HEX, TFS(&ldp_message_ubit), 0x80, "Message Unknown bit", HFILL }},
- { &hf_ldp_tlv_fec_len,
- { "FEC Element Length", "ldp.msg.tlv.fec.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Length", HFILL }},
+ { &hf_ldp_tlv_returned_msg_type,
+ { "Returned Message Type", "ldp.msg.tlv.returned.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x7FFF, "LDP message type", HFILL }},
- { &hf_ldp_tlv_fec_pfval,
- { "FEC Element Prefix Value", "ldp.msg.tlv.fec.pfval", FT_IPv4, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Prefix", HFILL }},
+ { &hf_ldp_tlv_returned_msg_len,
+ { "Returned Message Length", "ldp.msg.tlv.returned.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
- { &hf_ldp_tlv_generic_label,
- { "Generic Label", "ldp.msg.tlv.label", FT_UINT32, BASE_HEX, NULL, 0x0, "Label Mapping Generic Label", HFILL }},
+ { &hf_ldp_tlv_returned_msg_id,
+ { "Returned Message ID", "ldp.msg.tlv.returned.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }}
};
+
static gint *ett[] = {
&ett_ldp,
&ett_ldp_header,
@@ -876,6 +1673,10 @@ proto_register_ldp(void)
" than the default of 646)",
10, &global_ldp_udp_port);
+ prefs_register_bool_preference(ldp_module, "desegment_ldp_messages",
+ "Desegment all LDP messages spanning multiple TCP segments",
+ "Whether the LDP dissector should desegment all messages spanning multiple TCP segments",
+ &ldp_desegment);
}
/* The registration hand-off routine */