2 * Routines for LDP (RFC 3036) packet disassembly
4 * $Id: packet-ldp.c,v 1.22 2001/12/03 03:59:36 guy Exp $
6 * Copyright (c) November 2000 by Richard Sharpe <rsharpe@ns.aus.com>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1999 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
50 #define TCP_PORT_LDP 646
51 #define UDP_PORT_LDP 646
53 void proto_reg_handoff_ldp(void);
55 static int proto_ldp = -1;
57 /* Delete the following if you do not use it, or add to it if you need */
58 static int hf_ldp_req = -1;
59 static int hf_ldp_rsp = -1;
60 static int hf_ldp_version = -1;
61 static int hf_ldp_pdu_len = -1;
62 static int hf_ldp_lsr = -1;
63 static int hf_ldp_ls_id = -1;
64 static int hf_ldp_msg_type = -1;
65 static int hf_ldp_msg_len = -1;
66 static int hf_ldp_msg_id = -1;
67 static int hf_ldp_tlv_value = -1;
68 static int hf_ldp_tlv_type = -1;
69 static int hf_ldp_tlv_len = -1;
70 static int hf_ldp_tlv_val_hold = -1;
71 static int hf_ldp_tlv_val_target = -1;
72 static int hf_ldp_tlv_val_request = -1;
73 static int hf_ldp_tlv_val_res = -1;
74 static int hf_ldp_tlv_config_seqno = -1;
75 static int hf_ldp_tlv_fec_wc = -1;
76 static int hf_ldp_tlv_fec_af = -1;
77 static int hf_ldp_tlv_fec_len = -1;
78 static int hf_ldp_tlv_fec_pfval = -1;
79 static int hf_ldp_tlv_generic_label = -1;
81 static int ett_ldp = -1;
82 static int ett_ldp_header = -1;
83 static int ett_ldp_ldpid = -1;
84 static int ett_ldp_message = -1;
85 static int ett_ldp_tlv = -1;
86 static int ett_ldp_tlv_val = -1;
87 static int ett_ldp_fec = -1;
89 static int tcp_port = 0;
90 static int udp_port = 0;
92 /* Add your functions here */
94 static int global_ldp_tcp_port = TCP_PORT_LDP;
95 static int global_ldp_udp_port = UDP_PORT_LDP;
98 * The following define all the TLV types I know about
101 #define TLV_FEC 0x0100
102 #define TLV_ADDRESS_LIST 0x0101
103 #define TLV_HOP_COUNT 0x0103
104 #define TLV_PATH_VECTOR 0x0104
105 #define TLV_GENERIC_LABEL 0x0200
106 #define TLV_ATM_LABEL 0x0201
107 #define TLV_FRAME_LABEL 0x0202
108 #define TLV_STATUS 0x0300
109 #define TLV_EXTENDED_STATUS 0x0301
110 #define TLV_RETURNED_PDU 0x0302
111 #define TLV_RETURNED_MESSAGE 0x0303
112 #define TLV_COMMON_HELLO_PARMS 0x0400
113 #define TLV_IPV4_TRANSPORT_ADDRESS 0x0401
114 #define TLV_CONFIGURATION_SEQNO 0x0402
115 #define TLV_IPV6_TRANSPORT_ADDRESS 0x0403
116 #define TLV_COMMON_SESSION_PARMS 0x0500
117 #define TLV_ATM_SESSION_PARMS 0x0501
118 #define TLV_FRAME_RELAY_SESSION_PARMS 0x0502
119 #define TLV_LABEL_REQUEST_MESSAGE_ID 0x0600
121 #define TLV_VENDOR_PRIVATE_START 0x3E00
122 #define TLV_VENDOR_PROVATE_END 0x3EFF
123 #define TLV_EXPERIMENTAL_START 0x3F00
124 #define TLV_EXPERIMENTAL_END 0x3FFF
126 static const value_string tlv_type_names[] = {
127 { TLV_FEC, "Forwarding Equivalence Classes" },
128 { TLV_ADDRESS_LIST, "Address List"},
129 { TLV_HOP_COUNT, "Hop Count"},
130 { TLV_PATH_VECTOR, "Path Vector"},
131 { TLV_GENERIC_LABEL, "Generic Label"},
132 { TLV_ATM_LABEL, "Frame Label"},
133 { TLV_STATUS, "Status"},
134 { TLV_EXTENDED_STATUS, "Extended Status"},
135 { TLV_RETURNED_PDU, "Returned PDU"},
136 { TLV_RETURNED_MESSAGE, "Returned Message"},
137 { TLV_COMMON_HELLO_PARMS, "Common Hello Parameters"},
138 { TLV_IPV4_TRANSPORT_ADDRESS, "IPv4 Transport Address"},
139 { TLV_CONFIGURATION_SEQNO, "Configuration Sequence Number"},
140 { TLV_IPV6_TRANSPORT_ADDRESS, "IPv6 Transport Address"},
141 { TLV_COMMON_SESSION_PARMS, "Common Session Parameters"},
142 { TLV_ATM_SESSION_PARMS, "ATM Session Parameters"},
143 { TLV_FRAME_RELAY_SESSION_PARMS, "Frame Relay Session Parameters"},
144 { TLV_LABEL_REQUEST_MESSAGE_ID, "Label Request Message ID"},
149 * The following define all the message types I know about
152 #define LDP_NOTIFICATION 0x0001
153 #define LDP_HELLO 0x0100
154 #define LDP_INITIALIZATION 0x0200
155 #define LDP_KEEPALIVE 0x0201
156 #define LDP_ADDRESS 0x0300
157 #define LDP_ADDRESS_WITHDRAWAL 0x0301
158 #define LDP_LABEL_MAPPING 0x0400
159 #define LDP_LABEL_REQUEST 0x0401
160 #define LDP_LABEL_WITHDRAWAL 0x0402
161 #define LDP_LABEL_RELEASE 0x0403
162 #define LDP_LABEL_ABORT_REQUEST 0x0404
163 #define LDP_VENDOR_PRIVATE_START 0x3E00
164 #define LDP_VENDOR_PRIVATE_END 0x3EFF
165 #define LDP_EXPERIMENTAL_MESSAGE_START 0x3F00
166 #define LDP_EXPERIMENTAL_MESSAGE_END 0x3FFF
168 static const value_string ldp_message_types[] = {
169 {LDP_NOTIFICATION, "Notification"},
170 {LDP_HELLO, "Hello"},
171 {LDP_INITIALIZATION, "Initialization"},
172 {LDP_KEEPALIVE, "Keep Alive"},
173 {LDP_ADDRESS, "Address"},
174 {LDP_ADDRESS_WITHDRAWAL, "Address Withdrawal"},
175 {LDP_LABEL_MAPPING, "Label Mapping"},
176 {LDP_LABEL_REQUEST, "Label Request"},
177 {LDP_LABEL_WITHDRAWAL, "Label Withdrawal"},
178 {LDP_LABEL_RELEASE, "Label Release"},
179 {LDP_LABEL_ABORT_REQUEST, "Label Abort Request"},
183 static const true_false_string hello_targeted_vals = {
188 static const value_string fec_types[] = {
191 {3, "Host Address FEC"},
195 static const true_false_string hello_requested_vals = {
196 "Source requests periodic hellos",
197 "Source does not request periodic hellos"
200 /* Dissect the common hello params */
202 void dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
204 proto_tree *ti = NULL, *val_tree = NULL;
208 ti = proto_tree_add_item(tree, hf_ldp_tlv_value, tvb, offset, rem,
211 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
213 proto_tree_add_item(val_tree, hf_ldp_tlv_val_hold, tvb, offset, 2, FALSE);
215 proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_target, tvb, offset + 2, 2, FALSE);
216 proto_tree_add_boolean(val_tree, hf_ldp_tlv_val_request, tvb, offset + 2, 2, FALSE);
217 proto_tree_add_item(val_tree, hf_ldp_tlv_val_res, tvb, offset + 2, 2, FALSE);
222 /* Dissect a TLV and return the number of bytes consumed ... */
224 int dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
226 guint16 message = tvb_get_ntohs(tvb, offset),
227 length = tvb_get_ntohs(tvb, offset + 2),
228 pad = 0, fec_len = 0;
229 proto_tree *ti = NULL, *tlv_tree = NULL;
231 /* Hmmm, check for illegal alignment padding */
233 if (message == 0x00) {
235 proto_tree_add_text(tree, tvb, offset, 2, "Illegal Padding: %04X", message);
236 offset += 2; pad = 2;
237 message = tvb_get_ntohs(tvb, offset);
238 length = tvb_get_ntohs(tvb, offset + 2);
242 length = MIN(length, rem); /* Don't go haywire if a problem ... */
246 /* FIXME: Account for vendor and special messages */
248 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
249 val_to_str(message, tlv_type_names, "Unknown TLV type (0x%04X)"));
251 tlv_tree = proto_item_add_subtree(ti, ett_ldp_tlv);
253 proto_tree_add_item(tlv_tree, hf_ldp_tlv_type, tvb, offset, 2, FALSE);
255 proto_tree_add_item(tlv_tree, hf_ldp_tlv_len, tvb, offset + 2, 2, FALSE);
259 case TLV_FEC: /* Process an FEC */
261 offset += 4; /* Skip the TLV header */
265 while (fec_len > 0) {
266 proto_tree *fec_tree = NULL;
267 guint prefix_len_octets, prefix_len, prefix;
270 switch (tvb_get_guint8(tvb, offset)) {
271 case 1: /* Wild Card */
273 proto_tree_add_item(tlv_tree, hf_ldp_tlv_fec_wc, tvb, offset, 4, FALSE);
282 /* Add a subtree for this ... */
284 ti = proto_tree_add_text(tlv_tree, tvb, offset, 8, "Prefix FEC Element");
286 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
288 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
292 /* XXX - the address family length should be extracted and used to
293 dissect the prefix field. */
294 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
297 prefix_len = tvb_get_guint8(tvb, offset);
298 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
301 /* This is IPv4 specific. Should do IPv6 according to AF*/
302 prefix_len_octets = MIN( (prefix_len+7)/8 , 4 );
303 if (prefix_len > 32) {
304 proto_tree_add_text(fec_tree, tvb, offset, 0,
305 "Invalid prefix %u length, guessing 32", prefix_len);
306 prefix_len_octets = 4;
308 switch (prefix_len_octets){
309 case (0): /*prefix_length=0*/
312 case (1): /*1<=prefix_length<=8*/
313 prefix = tvb_get_guint8(tvb, offset);
315 case (2): /*9<=prefix_length<=16*/
316 prefix = tvb_get_letohs(tvb, offset);
318 case (3): /*17<=prefix_length<=24*/
319 prefix = tvb_get_letoh24(tvb, offset);
321 case (4): /*25<=prefix_length<=32*/
322 prefix = tvb_get_letohl(tvb, offset);
324 default: /*prefix_length>32*/
325 g_assert_not_reached();
329 proto_tree_add_ipv4(fec_tree, hf_ldp_tlv_fec_pfval, tvb,
330 offset, prefix_len_octets, prefix);
331 fec_len -= 4+prefix_len_octets;
334 case 3: /* Host address */
336 /* XXX - write me. */
344 default: /* Unknown */
346 /* XXX - do all FEC's have a length that's a multiple of 4? */
347 /* Hmmm, don't think so. Will check. RJS. */
361 case TLV_GENERIC_LABEL:
363 proto_tree_add_item(tlv_tree, hf_ldp_tlv_generic_label, tvb, offset + 4, 4, FALSE);
367 case TLV_COMMON_HELLO_PARMS:
369 dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree, length);
372 case TLV_CONFIGURATION_SEQNO:
374 proto_tree_add_item(tlv_tree, hf_ldp_tlv_config_seqno, tvb, offset + 4, 4, FALSE);
378 proto_tree_add_item(tlv_tree, hf_ldp_tlv_value, tvb, offset + 4,
386 return length + pad + 4; /* Length of the value field + header */
391 * Each of these routines dissect the relevant messages, but the msg header
392 * has already been dissected.
396 dissect_ldp_notification(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
398 guint rem = length, cc = 0;
402 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
409 /* Dissect a Hello Message ... */
411 dissect_ldp_hello(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
413 guint rem = length, cc = 0;
417 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
425 dissect_ldp_initialization(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
427 guint rem = length, cc = 0;
431 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
439 dissect_ldp_keepalive(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
441 guint rem = length, cc = 0;
445 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
453 dissect_ldp_address(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
455 guint rem = length, cc = 0;
459 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
467 dissect_ldp_address_withdrawal(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
469 guint rem = length, cc = 0;
473 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
481 dissect_ldp_label_mapping(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
483 guint rem = length, cc = 0;
487 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
495 dissect_ldp_label_request(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
497 guint rem = length, cc = 0;
501 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
509 dissect_ldp_label_withdrawal(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
511 guint rem = length, cc = 0;
515 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
523 dissect_ldp_label_release(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
525 guint rem = length, cc = 0;
529 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
537 dissect_ldp_label_abort_request(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, guint length)
539 guint rem = length, cc = 0;
543 rem -= (cc = dissect_tlv(tvb, offset, tree, rem));
551 dissect_ldp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
553 proto_tree *ldp_tree = NULL, *hdr_tree = NULL, *ldpid_tree = NULL;
554 proto_item *ldp_item = NULL, *hdr_item = NULL, *ldpid_item = NULL;
556 guint16 ldp_message = 0;
559 if (check_col(pinfo->fd, COL_INFO))
560 col_clear(pinfo->fd, COL_INFO);
562 if (tree) { /* Build the tree info ..., this is wrong! FIXME */
564 ldp_item = proto_tree_add_item(tree, proto_ldp, tvb, offset,
565 tvb_length_remaining(tvb, offset), FALSE);
566 ldp_tree = proto_item_add_subtree(ldp_item, ett_ldp);
570 /* Dissect LDP Header */
572 hdr_item = proto_tree_add_text(ldp_tree, tvb, offset, 10, "Header");
574 hdr_tree = proto_item_add_subtree(hdr_item, ett_ldp_header);
576 proto_tree_add_item(hdr_tree, hf_ldp_version, tvb, offset, 2, FALSE);
580 proto_tree_add_item(hdr_tree, hf_ldp_pdu_len, tvb, offset, 2, FALSE);
581 pdu_len = tvb_get_ntohs(tvb, offset);
582 proto_item_set_len(ldp_item, pdu_len + 2);
585 * XXX - do TCP reassembly, to handle LDP PDUs that cross TCP segment
593 * PDU is too short to hold the LDP identifier.
595 proto_tree_add_text(hdr_tree, tvb, offset, pdu_len,
596 "PDU too short (%u bytes, should be at least 6) for LDP Identifier",
602 ldpid_item = proto_tree_add_text(hdr_tree, tvb, offset, 6, "LDP Identifier");
604 ldpid_tree = proto_item_add_subtree(ldpid_item, ett_ldp_ldpid);
606 proto_tree_add_item(ldpid_tree, hf_ldp_lsr, tvb, offset, 4, FALSE);
611 proto_tree_add_item(ldpid_tree, hf_ldp_ls_id, tvb, offset, 2, FALSE);
616 while (pdu_len > 0) { /* Dissect LDP TLV */
620 ldp_message = tvb_get_ntohs(tvb, offset) & 0x7FFF; /* Get the message type */
622 msg_len = tvb_get_ntohs(tvb, offset + 2);
624 if (check_col(pinfo->fd, COL_INFO)) { /* Check the type ... */
627 col_append_fstr(pinfo->fd, COL_INFO, ", %s",
628 val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
630 col_add_fstr(pinfo->fd, COL_INFO, "%s",
631 val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
639 proto_tree *ti = NULL, *msg_tree = NULL;
641 /* FIXME: Account for vendor and experimental messages */
643 ti = proto_tree_add_text(ldp_tree, tvb, offset, msg_len + 4, "%s",
644 val_to_str(ldp_message, ldp_message_types, "Unknown Message (0x%04X)"));
646 msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
648 proto_tree_add_item(msg_tree, hf_ldp_msg_type, tvb, offset, 2, FALSE);
650 proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset + 2, 2, FALSE);
653 proto_tree_add_text(msg_tree, tvb, offset + 4, msg_len,
654 "Message too short (%u bytes, should be at least 4) for Message ID",
659 proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset + 4, 4, FALSE);
662 /* Nothing past the message ID */
666 switch (ldp_message) {
668 case LDP_NOTIFICATION:
670 dissect_ldp_notification(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
676 dissect_ldp_hello(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
680 case LDP_INITIALIZATION:
682 dissect_ldp_initialization(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
688 dissect_ldp_keepalive(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
694 dissect_ldp_address(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
698 case LDP_ADDRESS_WITHDRAWAL:
700 dissect_ldp_address_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
704 case LDP_LABEL_MAPPING:
706 dissect_ldp_label_mapping(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
710 case LDP_LABEL_REQUEST:
712 dissect_ldp_label_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
716 case LDP_LABEL_WITHDRAWAL:
718 dissect_ldp_label_withdrawal(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
722 case LDP_LABEL_RELEASE:
724 dissect_ldp_label_release(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
728 case LDP_LABEL_ABORT_REQUEST:
730 dissect_ldp_label_abort_request(tvb, offset + 8, pinfo, msg_tree, msg_len - 4);
736 /* Some sort of unknown message, treat as undissected data */
737 proto_tree_add_text(msg_tree, tvb, offset + 8, msg_len - 4,
747 offset += msg_len + 4;
748 pdu_len -= msg_len + 4;
755 dissect_ldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
757 if (check_col(pinfo->fd, COL_PROTOCOL))
758 col_add_str(pinfo->fd, COL_PROTOCOL, "LDP");
760 dissect_ldp_pdu(tvb, 0, pinfo, tree);
764 dissect_ldp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
768 if (check_col(pinfo->fd, COL_PROTOCOL))
769 col_add_str(pinfo->fd, COL_PROTOCOL, "LDP");
771 while (tvb_reported_length_remaining(tvb, offset) > 0) /* Dissect LDP PDUs */
772 offset = dissect_ldp_pdu(tvb, offset, pinfo, tree);
775 /* Register all the bits needed with the filtering engine */
778 proto_register_ldp(void)
780 static hf_register_info hf[] = {
782 /* Change the following to the type you need */
783 { "Request", "ldp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
786 { "Response", "ldp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
789 { "Version", "ldp.hdr.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
792 { "PDU Length", "ldp.hdr.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
795 { "LSR ID", "ldp.hdr.ldpid.lsr", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
798 { "Label Space ID", "ldp.hdr.ldpid.lsid", FT_UINT16, BASE_HEX, NULL, 0x0, "LDP Label Space ID", HFILL }},
801 { "Message Type", "ldp.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x0, "LDP message type", HFILL }},
804 { "Message Length", "ldp.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
807 { "Message ID", "ldp.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
810 { "TLV Type", "ldp.msg.tlv.type", FT_UINT16, BASE_HEX, VALS(tlv_type_names), 0x0, "TLV Type Field", HFILL }},
813 {"TLV Length", "ldp.msg.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length Field", HFILL }},
816 { "TLV Value", "ldp.msg.tlv.value", FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value Bytes", HFILL }},
818 { &hf_ldp_tlv_val_hold,
819 { "Hold Time", "ldp.msg.tlv.hello.hold", FT_UINT16, BASE_DEC, NULL, 0x0, "Hello Common Parameters Hold Time", HFILL }},
821 { &hf_ldp_tlv_val_target,
822 { "Targeted Hello", "ldp.msg.tlv.hello.targeted", FT_BOOLEAN, 8, TFS(&hello_targeted_vals), 0x80, "Hello Common Parameters Targeted Bit", HFILL }},
824 { &hf_ldp_tlv_val_request,
825 { "Hello Requested", "ldp,msg.tlv.hello.requested", FT_BOOLEAN, 8, TFS(&hello_requested_vals), 0x40, "Hello Common Parameters Hello Requested Bit", HFILL }},
827 { &hf_ldp_tlv_val_res,
828 { "Reserved", "ldp.msg.tlv.hello.res", FT_UINT16, BASE_HEX, NULL, 0x3FFF, "Hello Common Parameters Reserved Field", HFILL }},
830 { &hf_ldp_tlv_config_seqno,
831 { "Configuration Sequence Number", "ldp.msg.tlv.hello.cnf_seqno", FT_UINT32, BASE_HEX, NULL, 0x0, "Hello COnfiguration Sequence Number", HFILL }},
833 { &hf_ldp_tlv_fec_wc,
834 { "FEC Element Type", "ldp.msg.tlv.fec.type", FT_UINT8, BASE_DEC, VALS(fec_types), 0x0, "Forwarding Equivalence Class Element Types", HFILL }},
836 { &hf_ldp_tlv_fec_af,
837 { "FEC Element Address Type", "ldp.msg.tlv.fec.af", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Forwarding Equivalence Class Element Address Family", HFILL }},
839 { &hf_ldp_tlv_fec_len,
840 { "FEC Element Length", "ldp.msg.tlv.fec.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Length", HFILL }},
842 { &hf_ldp_tlv_fec_pfval,
843 { "FEC Element Prefix Value", "ldp.msg.tlv.fec.pfval", FT_IPv4, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Prefix", HFILL }},
845 { &hf_ldp_tlv_generic_label,
846 { "Generic Label", "ldp.msg.tlv.label", FT_UINT32, BASE_HEX, NULL, 0x0, "Label Mapping Generic Label", HFILL }},
849 static gint *ett[] = {
858 module_t *ldp_module;
860 proto_ldp = proto_register_protocol("Label Distribution Protocol",
863 proto_register_field_array(proto_ldp, hf, array_length(hf));
864 proto_register_subtree_array(ett, array_length(ett));
866 /* Register our configuration options for , particularly our port */
868 ldp_module = prefs_register_protocol(proto_ldp, proto_reg_handoff_ldp);
870 prefs_register_uint_preference(ldp_module, "tcp.port", "LDP TCP Port",
871 "Set the port for messages (if other"
872 " than the default of 646)",
873 10, &global_ldp_tcp_port);
875 prefs_register_uint_preference(ldp_module, "udp.port", "LDP UDP Port",
876 "Set the port for messages (if other"
877 " than the default of 646)",
878 10, &global_ldp_udp_port);
882 /* The registration hand-off routine */
884 proto_reg_handoff_ldp(void)
886 static int ldp_prefs_initialized = FALSE;
887 static dissector_handle_t ldp_tcp_handle, ldp_handle;
889 if (!ldp_prefs_initialized) {
891 ldp_tcp_handle = create_dissector_handle(dissect_ldp_tcp, proto_ldp);
892 ldp_handle = create_dissector_handle(dissect_ldp, proto_ldp);
894 ldp_prefs_initialized = TRUE;
899 dissector_delete("tcp.port", tcp_port, ldp_tcp_handle);
900 dissector_delete("udp.port", udp_port, ldp_handle);
904 /* Set our port number for future use */
906 tcp_port = global_ldp_tcp_port;
907 udp_port = global_ldp_udp_port;
909 dissector_add("tcp.port", global_ldp_tcp_port, ldp_tcp_handle);
910 dissector_add("udp.port", global_ldp_udp_port, ldp_handle);