2 * Routines for LDP (RFC 3036) packet disassembly
4 * $Id: packet-ldp.c,v 1.33 2002/04/24 19:16:49 guy Exp $
6 * Copyright (c) November 2000 by Richard Sharpe <rsharpe@ns.aus.com>
8 * CRLDP (RFC3212) is now supported
9 * - (c) 2002 Michael Rozhavsky <mike[AT]tochna.technion.ac.il>
11 * Ethereal - Network traffic analyzer
12 * By Gerald Combs <gerald@ethereal.com>
13 * Copyright 1999 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
38 #ifdef HAVE_NETINET_IN_H
39 #include <netinet/in.h>
48 #include <epan/packet.h>
49 #include <epan/resolv.h>
53 #define TCP_PORT_LDP 646
54 #define UDP_PORT_LDP 646
56 void proto_reg_handoff_ldp(void);
58 static int proto_ldp = -1;
60 /* Delete the following if you do not use it, or add to it if you need */
61 static int hf_ldp_req = -1;
62 static int hf_ldp_rsp = -1;
63 static int hf_ldp_version = -1;
64 static int hf_ldp_pdu_len = -1;
65 static int hf_ldp_lsr = -1;
66 static int hf_ldp_ls_id = -1;
67 static int hf_ldp_msg_ubit = -1;
68 static int hf_ldp_msg_type = -1;
69 static int hf_ldp_msg_len = -1;
70 static int hf_ldp_msg_id = -1;
71 static int hf_ldp_msg_vendor_id = -1;
72 static int hf_ldp_msg_experiment_id = -1;
73 static int hf_ldp_tlv_value = -1;
74 static int hf_ldp_tlv_type = -1;
75 static int hf_ldp_tlv_unknown = -1;
76 static int hf_ldp_tlv_len = -1;
77 static int hf_ldp_tlv_val_hold = -1;
78 static int hf_ldp_tlv_val_target = -1;
79 static int hf_ldp_tlv_val_request = -1;
80 static int hf_ldp_tlv_val_res = -1;
81 static int hf_ldp_tlv_ipv4_taddr = -1;
82 static int hf_ldp_tlv_config_seqno = -1;
83 static int hf_ldp_tlv_ipv6_taddr = -1;
84 static int hf_ldp_tlv_fec_wc = -1;
85 static int hf_ldp_tlv_fec_af = -1;
86 static int hf_ldp_tlv_fec_len = -1;
87 static int hf_ldp_tlv_fec_pfval = -1;
88 static int hf_ldp_tlv_fec_hoval = -1;
89 static int hf_ldp_tlv_addrl_addr_family = -1;
90 static int hf_ldp_tlv_addrl_addr = -1;
91 static int hf_ldp_tlv_hc_value = -1;
92 static int hf_ldp_tlv_pv_lsrid = -1;
93 static int hf_ldp_tlv_generic_label = -1;
94 static int hf_ldp_tlv_atm_label_vbits = -1;
95 static int hf_ldp_tlv_atm_label_vpi = -1;
96 static int hf_ldp_tlv_atm_label_vci = -1;
97 static int hf_ldp_tlv_fr_label_len = -1;
98 static int hf_ldp_tlv_fr_label_dlci = -1;
99 static int hf_ldp_tlv_status_ebit = -1;
100 static int hf_ldp_tlv_status_fbit = -1;
101 static int hf_ldp_tlv_status_data = -1;
102 static int hf_ldp_tlv_status_msg_id = -1;
103 static int hf_ldp_tlv_status_msg_type = -1;
104 static int hf_ldp_tlv_extstatus_data = -1;
105 static int hf_ldp_tlv_returned_version = -1;
106 static int hf_ldp_tlv_returned_pdu_len = -1;
107 static int hf_ldp_tlv_returned_lsr = -1;
108 static int hf_ldp_tlv_returned_ls_id = -1;
109 static int hf_ldp_tlv_returned_msg_ubit = -1;
110 static int hf_ldp_tlv_returned_msg_type = -1;
111 static int hf_ldp_tlv_returned_msg_len = -1;
112 static int hf_ldp_tlv_returned_msg_id = -1;
113 static int hf_ldp_tlv_sess_ver = -1;
114 static int hf_ldp_tlv_sess_ka = -1;
115 static int hf_ldp_tlv_sess_advbit = -1;
116 static int hf_ldp_tlv_sess_ldetbit = -1;
117 static int hf_ldp_tlv_sess_pvlim = -1;
118 static int hf_ldp_tlv_sess_mxpdu = -1;
119 static int hf_ldp_tlv_sess_rxlsr = -1;
120 static int hf_ldp_tlv_sess_rxls = -1;
121 static int hf_ldp_tlv_sess_atm_merge = -1;
122 static int hf_ldp_tlv_sess_atm_lr = -1;
123 static int hf_ldp_tlv_sess_atm_dir = -1;
124 static int hf_ldp_tlv_sess_atm_minvpi = -1;
125 static int hf_ldp_tlv_sess_atm_maxvpi = -1;
126 static int hf_ldp_tlv_sess_atm_minvci = -1;
127 static int hf_ldp_tlv_sess_atm_maxvci = -1;
128 static int hf_ldp_tlv_sess_fr_merge = -1;
129 static int hf_ldp_tlv_sess_fr_lr = -1;
130 static int hf_ldp_tlv_sess_fr_dir = -1;
131 static int hf_ldp_tlv_sess_fr_len = -1;
132 static int hf_ldp_tlv_sess_fr_mindlci = -1;
133 static int hf_ldp_tlv_sess_fr_maxdlci = -1;
134 static int hf_ldp_tlv_lbl_req_msg_id = -1;
135 static int hf_ldp_tlv_vendor_id = -1;
136 static int hf_ldp_tlv_experiment_id = -1;
137 static int hf_ldp_tlv_fec_vc_controlword = -1;
138 static int hf_ldp_tlv_fec_vc_vctype = -1;
139 static int hf_ldp_tlv_fec_vc_infolength = -1;
140 static int hf_ldp_tlv_fec_vc_groupid = -1;
141 static int hf_ldp_tlv_fec_vc_vcid = -1;
142 static int hf_ldp_tlv_fec_vc_intparam_length = -1;
143 static int hf_ldp_tlv_fec_vc_intparam_mtu = -1;
144 static int hf_ldp_tlv_fec_vc_intparam_id = -1;
145 static int hf_ldp_tlv_fec_vc_intparam_maxcatmcells = -1;
146 static int hf_ldp_tlv_fec_vc_intparam_desc = -1;
147 static int hf_ldp_tlv_fec_vc_intparam_cembytes = -1;
148 static int hf_ldp_tlv_lspid_act_flg = -1;
149 static int hf_ldp_tlv_lspid_cr_lsp = -1;
150 static int hf_ldp_tlv_lspid_ldpid = -1;
151 static int hf_ldp_tlv_er_hop_loose = -1;
152 static int hf_ldp_tlv_er_hop_prelen = -1;
153 static int hf_ldp_tlv_er_hop_prefix4 = -1;
154 static int hf_ldp_tlv_er_hop_prefix6 = -1;
155 static int hf_ldp_tlv_er_hop_as = -1;
156 static int hf_ldp_tlv_er_hop_cr_lsp = -1;
157 static int hf_ldp_tlv_er_hop_ldpid = -1;
158 static int hf_ldp_tlv_flags_reserv = -1;
159 static int hf_ldp_tlv_flags_weight = -1;
160 static int hf_ldp_tlv_flags_ebs = -1;
161 static int hf_ldp_tlv_flags_cbs = -1;
162 static int hf_ldp_tlv_flags_cdr = -1;
163 static int hf_ldp_tlv_flags_pbs = -1;
164 static int hf_ldp_tlv_flags_pdr = -1;
165 static int hf_ldp_tlv_frequency = -1;
166 static int hf_ldp_tlv_pdr = -1;
167 static int hf_ldp_tlv_pbs = -1;
168 static int hf_ldp_tlv_cdr = -1;
169 static int hf_ldp_tlv_cbs = -1;
170 static int hf_ldp_tlv_ebs = -1;
171 static int hf_ldp_tlv_weight = -1;
172 static int hf_ldp_tlv_set_prio = -1;
173 static int hf_ldp_tlv_hold_prio = -1;
174 static int hf_ldp_tlv_route_pinning = -1;
175 static int hf_ldp_tlv_resource_class = -1;
176 static int ett_ldp = -1;
177 static int ett_ldp_header = -1;
178 static int ett_ldp_ldpid = -1;
179 static int ett_ldp_message = -1;
180 static int ett_ldp_tlv = -1;
181 static int ett_ldp_tlv_val = -1;
182 static int ett_ldp_fec = -1;
183 static int ett_ldp_fec_vc_interfaceparam = -1;
185 static int tcp_port = 0;
186 static int udp_port = 0;
188 /* desegmentation of LDP over TCP */
189 static gboolean ldp_desegment = FALSE;
191 /* Add your functions here */
193 static int global_ldp_tcp_port = TCP_PORT_LDP;
194 static int global_ldp_udp_port = UDP_PORT_LDP;
197 * The following define all the TLV types I know about
200 #define TLV_FEC 0x0100
201 #define TLV_ADDRESS_LIST 0x0101
202 #define TLV_HOP_COUNT 0x0103
203 #define TLV_PATH_VECTOR 0x0104
204 #define TLV_GENERIC_LABEL 0x0200
205 #define TLV_ATM_LABEL 0x0201
206 #define TLV_FRAME_LABEL 0x0202
207 #define TLV_STATUS 0x0300
208 #define TLV_EXTENDED_STATUS 0x0301
209 #define TLV_RETURNED_PDU 0x0302
210 #define TLV_RETURNED_MESSAGE 0x0303
211 #define TLV_COMMON_HELLO_PARMS 0x0400
212 #define TLV_IPV4_TRANSPORT_ADDRESS 0x0401
213 #define TLV_CONFIGURATION_SEQNO 0x0402
214 #define TLV_IPV6_TRANSPORT_ADDRESS 0x0403
215 #define TLV_COMMON_SESSION_PARMS 0x0500
216 #define TLV_ATM_SESSION_PARMS 0x0501
217 #define TLV_FRAME_RELAY_SESSION_PARMS 0x0502
218 #define TLV_LABEL_REQUEST_MESSAGE_ID 0x0600
219 #define TLV_ER 0x0800
220 #define TLV_ER_HOP_IPV4 0x0801
221 #define TLV_ER_HOP_IPV6 0x0802
222 #define TLV_ER_HOP_AS 0x0803
223 #define TLV_ER_HOP_LSPID 0x0804
224 #define TLV_TRAFFIC_PARAM 0x0810
225 #define TLV_PREEMPTION 0x0820
226 #define TLV_LSPID 0x0821
227 #define TLV_RESOURCE_CLASS 0x0822
228 #define TLV_ROUTE_PINNING 0x0823
230 #define TLV_VENDOR_PRIVATE_START 0x3E00
231 #define TLV_VENDOR_PRIVATE_END 0x3EFF
232 #define TLV_EXPERIMENTAL_START 0x3F00
233 #define TLV_EXPERIMENTAL_END 0x3FFF
235 static const value_string tlv_type_names[] = {
236 { TLV_FEC, "Forwarding Equivalence Classes TLV" },
237 { TLV_ADDRESS_LIST, "Address List TLV"},
238 { TLV_HOP_COUNT, "Hop Count TLV"},
239 { TLV_PATH_VECTOR, "Path Vector TLV"},
240 { TLV_GENERIC_LABEL, "Generic Label TLV"},
241 { TLV_ATM_LABEL, "ATM Label TLV"},
242 { TLV_FRAME_LABEL, "Frame Label TLV"},
243 { TLV_STATUS, "Status TLV"},
244 { TLV_EXTENDED_STATUS, "Extended Status TLV"},
245 { TLV_RETURNED_PDU, "Returned PDU TLV"},
246 { TLV_RETURNED_MESSAGE, "Returned Message TLV"},
247 { TLV_COMMON_HELLO_PARMS, "Common Hello Parameters TLV"},
248 { TLV_IPV4_TRANSPORT_ADDRESS, "IPv4 Transport Address TLV"},
249 { TLV_CONFIGURATION_SEQNO, "Configuration Sequence Number TLV"},
250 { TLV_IPV6_TRANSPORT_ADDRESS, "IPv6 Transport Address TLV"},
251 { TLV_COMMON_SESSION_PARMS, "Common Session Parameters TLV"},
252 { TLV_ATM_SESSION_PARMS, "ATM Session Parameters TLV"},
253 { TLV_FRAME_RELAY_SESSION_PARMS, "Frame Relay Session Parameters TLV"},
254 { TLV_LABEL_REQUEST_MESSAGE_ID, "Label Request Message ID TLV"},
255 { TLV_LSPID, "LSP ID TLV"},
256 { TLV_ER, "Explicit route TLV"},
257 { TLV_ER_HOP_IPV4, "ER hop IPv4 prefix TLV"},
258 { TLV_ER_HOP_IPV6, "ER hop IPv6 prefix TLV"},
259 { TLV_ER_HOP_AS, "ER hop Autonomous system number prefix TLV"},
260 { TLV_TRAFFIC_PARAM, "Traffic parameters TLV"},
261 { TLV_PREEMPTION, "Preemption TLV"},
262 { TLV_ER_HOP_LSPID, "ER hop LSPID prefix TLV"},
263 { TLV_RESOURCE_CLASS, "Resource Class (Color) TLV"},
264 { TLV_ROUTE_PINNING, "Route Pinning TLV"},
265 { TLV_VENDOR_PRIVATE_START, "Vendor Private TLV"},
266 { TLV_EXPERIMENTAL_START, "Experimental TLV"},
271 * The following define all the message types I know about
274 #define LDP_NOTIFICATION 0x0001
275 #define LDP_HELLO 0x0100
276 #define LDP_INITIALIZATION 0x0200
277 #define LDP_KEEPALIVE 0x0201
278 #define LDP_ADDRESS 0x0300
279 #define LDP_ADDRESS_WITHDRAWAL 0x0301
280 #define LDP_LABEL_MAPPING 0x0400
281 #define LDP_LABEL_REQUEST 0x0401
282 #define LDP_LABEL_WITHDRAWAL 0x0402
283 #define LDP_LABEL_RELEASE 0x0403
284 #define LDP_LABEL_ABORT_REQUEST 0x0404
285 #define LDP_VENDOR_PRIVATE_START 0x3E00
286 #define LDP_VENDOR_PRIVATE_END 0x3EFF
287 #define LDP_EXPERIMENTAL_MESSAGE_START 0x3F00
288 #define LDP_EXPERIMENTAL_MESSAGE_END 0x3FFF
290 static const value_string ldp_message_types[] = {
291 {LDP_NOTIFICATION, "Notification Message"},
292 {LDP_HELLO, "Hello Message"},
293 {LDP_INITIALIZATION, "Initialization Message"},
294 {LDP_KEEPALIVE, "Keep Alive Message"},
295 {LDP_ADDRESS, "Address Message"},
296 {LDP_ADDRESS_WITHDRAWAL, "Address Withdrawal Message"},
297 {LDP_LABEL_MAPPING, "Label Mapping Message"},
298 {LDP_LABEL_REQUEST, "Label Request Message"},
299 {LDP_LABEL_WITHDRAWAL, "Label Withdrawal Message"},
300 {LDP_LABEL_RELEASE, "Label Release Message"},
301 {LDP_LABEL_ABORT_REQUEST, "Label Abort Request Message"},
302 {LDP_VENDOR_PRIVATE_START, "Vendor-Private Message"},
303 {LDP_EXPERIMENTAL_MESSAGE_START, "Experimental Message"},
307 static const true_false_string ldp_message_ubit = {
309 "Unknown bit not set"
312 static const true_false_string hello_targeted_vals = {
317 static const value_string tlv_unknown_vals[] = {
318 {0, "Known TLV, do not Forward"},
319 {1, "Known TLV, do Forward"},
320 {2, "Unknown TLV, do not Forward"},
321 {3, "Unknown TLV, do Forward"},
325 #define WILDCARD_FEC 1
329 #define VC_FEC 0x80 /* draft-martini-l2circuit-trans-mpls */
331 static const value_string fec_types[] = {
332 {WILDCARD_FEC, "Wildcard FEC"},
333 {PREFIX_FEC, "Prefix FEC"},
334 {HOST_FEC, "Host Address FEC"},
335 {CRLSP_FEC, "CR LSP FEC"},
336 {VC_FEC, "Virtual Circuit FEC"},
341 static const value_string fec_vc_types_vals[] = {
342 {0x0001, "Frame Relay DLCI"},
343 {0x0002, "ATM VCC transport"},
344 {0x0003, "ATM VPC transport"},
345 {0x0004, "Ethernet VLAN"},
346 {0x0005, "Ethernet"},
349 {0x0009, "ATM VCC cell transport"},
351 {0x000A, "ATM VPC cell transport"},
356 #define FEC_VC_INTERFACEPARAM_MTU 0x01
357 #define FEC_VC_INTERFACEPARAM_MAXCATMCELLS 0x02
358 #define FEC_VC_INTERFACEPARAM_DESCRIPTION 0x03
359 #define FEC_VC_INTERFACEPARAM_CEMBYTES 0x04
360 #define FEC_VC_INTERFACEPARAM_CEMOPTIONS 0x05
363 static const value_string fec_vc_interfaceparm[] = {
364 {FEC_VC_INTERFACEPARAM_MTU, "MTU"},
365 {FEC_VC_INTERFACEPARAM_MAXCATMCELLS, "Max Concatenated ATM cells"},
366 {FEC_VC_INTERFACEPARAM_DESCRIPTION, "Interface Description"},
367 {FEC_VC_INTERFACEPARAM_CEMBYTES, "CEM Payload Bytes"},
368 {FEC_VC_INTERFACEPARAM_CEMOPTIONS, "CEM options"}
371 static const true_false_string fec_vc_cbit = {
372 "Contorl Word Present",
373 "Control Word NOT Present"
378 static const value_string tlv_atm_merge_vals[] = {
379 {0, "Merge not supported"},
380 {1, "VP merge supported"},
381 {2, "VC merge supported"},
382 {3, "VP & VC merge supported"},
386 static const value_string tlv_atm_vbits_vals[] = {
387 {0, "VPI & VCI Significant"},
388 {1, "Only VPI Significant"},
389 {2, "Only VCI Significant"},
390 {3, "VPI & VCI not Significant, nonsense"},
394 static const value_string tlv_fr_merge_vals[] = {
395 {0, "Merge not supported"},
396 {1, "Merge supported"},
402 static const value_string tlv_fr_len_vals[] = {
410 static const value_string ldp_act_flg_vals[] = {
411 {0, "indicates initial LSP setup"},
412 {1, "indicates modify LSP"},
416 static const value_string route_pinning_vals[] = {
417 {0, "route pinning is not requested"},
418 {1, "route pinning is requested"},
422 static const value_string ldp_loose_vals[] = {
428 static const value_string freq_values[] = {
435 static const true_false_string tlv_atm_dirbit = {
436 "Bidirectional capability",
437 "Unidirectional capability"
440 static const true_false_string hello_requested_vals = {
441 "Source requests periodic hellos",
442 "Source does not request periodic hellos"
445 static const true_false_string tlv_sess_advbit_vals = {
446 "Downstream On Demand proposed",
447 "Downstream Unsolicited proposed"
450 static const true_false_string tlv_sess_ldetbit_vals = {
451 "Loop Detection Enabled",
452 "Loop Detection Disabled"
455 static const true_false_string tlv_status_ebit = {
456 "Fatal Error Notification",
457 "Advisory Notification"
460 static const true_false_string tlv_status_fbit = {
461 "Notification should be Forwarded",
462 "Notification should NOT be Forwarded"
465 static const value_string tlv_status_data[] = {
467 {1, "Bad LDP Identifier"},
468 {2, "Bad Protocol Version"},
469 {3, "Bad PDU Length"},
470 {4, "Unknown Message Type"},
471 {5, "Bad Message Length"},
473 {7, "Bad TLV Length"},
474 {8, "Malformed TLV Value"},
475 {9, "Hold Timer Expired"},
477 {11, "Loop Detected"},
480 {14, "No Label Resources"},
481 {15, "Label Resources / Available"},
482 {16, "Session Rejected / No Hello"},
483 {17, "Session Rejected / Parameters Advertisement Mode"},
484 {18, "Session Rejected / Parameters Max PDU Length"},
485 {19, "Session Rejected / Parameters Label Range"},
486 {20, "KeepAlive Timer Expired"},
487 {21, "Label Request Aborted"},
488 {22, "Missing Message Parameters"},
489 {23, "Unsoported Address Family"},
490 {24, "Session Rejected / Bad KeepAlive Time"},
491 {25, "Internal Error"},
492 {0x01000001,"Unexpected Diff-Serv TLV"},
493 {0x01000002,"Unsupported PHB"},
494 {0x01000003,"Invalid EXP<->PHB Mapping"},
495 {0x01000004,"Unsupported PSC"},
496 {0x01000005,"Per-LSP context allocation failure"},
497 {0x04000001,"Bad Explicit Routing TLV Error"},
498 {0x04000002,"Bad Strict Node Error"},
499 {0x04000003,"Bad Strict Node Error"},
500 {0x04000004,"Bad Initial ER-Hop Error"},
501 {0x04000005,"Resource Unavailable"},
502 {0x04000006,"Traffic Parameters Unavailable"},
503 {0x04000007,"LSP Preempted"},
504 {0x04000008,"Modify Request Not Supported"},
505 {0x20000001,"Illegal C-Bit"},
506 {0x20000002,"Wrong C-Bit"},
510 /* Dissect FEC TLV */
513 dissect_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
515 proto_tree *ti=NULL, *val_tree=NULL, *fec_tree=NULL, *vcintparam_tree=NULL;
516 guint16 family, ix=1, ax;
517 guint8 addr_size=0, *addr, implemented, prefix_len_octets, prefix_len, host_len, vc_len;
519 void *str_handler=NULL;
523 ti=proto_tree_add_text(tree, tvb, offset, rem, "FEC Elements");
524 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
525 if(val_tree == NULL) return;
528 switch (tvb_get_guint8(tvb, offset)) {
531 ti = proto_tree_add_text(val_tree, tvb, offset, 1, "FEC Element %u", ix);
532 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
533 if(fec_tree == NULL) return;
534 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc,tvb, offset, 1, FALSE);
540 if( rem < 4 ){/*not enough*/
541 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
544 family=tvb_get_ntohs(tvb, offset+1);
545 prefix_len=tvb_get_guint8(tvb, offset+3);
546 prefix_len_octets=(prefix_len+7)/8;
550 case AFNUM_INET: /*IPv4*/
552 str_handler=ip_to_str;
554 case AFNUM_INET6: /*IPv6*/
556 str_handler=ip6_to_str;
566 noctets= rem>4+prefix_len_octets?4+prefix_len_octets:rem;
567 proto_tree_add_text(val_tree, tvb, offset, noctets,"Support for Address Family not implemented");
573 if( rem < 4+MIN(addr_size, prefix_len_octets) ){
574 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
578 /*Add a subtree for this*/
579 ti = proto_tree_add_text(val_tree, tvb, offset, 4+MIN(addr_size, prefix_len_octets), "FEC Element %u", ix);
580 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
581 if(fec_tree == NULL) return;
582 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
585 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
588 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
592 if( addr_size < prefix_len_octets) {
595 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"));
599 if( (addr=g_malloc0(addr_size)) == NULL ){
600 /*big big trouble, no mem or bad addr_size*/
601 fprintf(stderr, "packet-ldp: dissect_tlv_fec() malloc failed\n");
605 for(ax=0; ax+1 <= prefix_len_octets; ax++)
606 addr[ax]=tvb_get_guint8(tvb, offset+ax);
608 addr[ax-1] = addr[ax-1]&(0xFF<<(8-prefix_len%8));
610 str = (* (char* (*)(guint8 *))str_handler)(addr);
611 proto_tree_add_string_format(fec_tree, hf_ldp_tlv_fec_pfval, tvb, offset, prefix_len_octets, str, "Prefix: %s", str);
613 offset += prefix_len_octets;
614 rem -= 4+prefix_len_octets;
619 if( rem < 4 ){/*not enough*/
620 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
623 family=tvb_get_ntohs(tvb, offset+1);
624 host_len=tvb_get_guint8(tvb, offset+3);
628 case AFNUM_INET: /*IPv4*/
630 str_handler=ip_to_str;
632 case AFNUM_INET6: /*IPv6*/
634 str_handler=ip6_to_str;
644 noctets= rem>4+host_len?4+host_len:rem;
645 proto_tree_add_text(val_tree, tvb, offset, noctets,"Support for Address Family not implemented");
651 if( rem < 4+addr_size ){
652 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
656 /*Add a subtree for this*/
657 ti = proto_tree_add_text(val_tree, tvb, offset, 4+addr_size, "FEC Element %u", ix);
658 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
659 if(fec_tree == NULL) return;
660 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
663 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
666 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
670 if( addr_size != host_len) {
673 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"));
677 if( (addr=g_malloc0(addr_size)) == NULL ){
678 /*big big xtrouble, no mem or bad addr_size*/
679 fprintf(stderr, "packet-ldp: dissect_tlv_fec() malloc failed\n");
683 for(ax=0; ax+1 <= host_len; ax++)
684 addr[ax]=tvb_get_guint8(tvb, offset+ax);
686 str = (* (char* (*)(guint8 *))str_handler)(addr);
687 proto_tree_add_string_format(fec_tree, hf_ldp_tlv_fec_hoval, tvb, offset, host_len, str, "Address: %s", str);
695 if( rem < 8 ){/*not enough bytes for a minimal VC_FEC*/
696 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
699 vc_len = tvb_get_guint8 (tvb, offset+3);
702 ti = proto_tree_add_text(val_tree, tvb, offset, 8+vc_len, "FEC Element %u", ix);
703 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
704 if(fec_tree == NULL) return;
705 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
706 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_controlword, tvb, offset+1, 1, FALSE);
707 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_vctype, tvb, offset+1, 2, FALSE);
708 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_infolength, tvb, offset+3,1,FALSE);
709 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_groupid,tvb, offset +4, 4, FALSE);
713 if ( (vc_len > 3) && ( rem > 3 ) ) { /* there is enough room for vcid */
714 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_vcid,tvb, offset, 4, FALSE);
715 proto_item_append_text (ti," VCID: %u",tvb_get_ntohl(tvb,offset));
718 proto_tree_add_text(val_tree,tvb,offset +4, 8 +vc_len, "VC FEC size format error");
725 while ( (vc_len > 1) && (rem > 1) ) { /* enough to include id and length */
726 intparam_len = tvb_get_guint8(tvb, offset+1);
727 ti = proto_tree_add_text(fec_tree, tvb, offset, 4, "Interface Paramameter");
728 vcintparam_tree = proto_item_add_subtree(ti, ett_ldp_fec_vc_interfaceparam);
729 if(vcintparam_tree == NULL) return;
730 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_id,tvb,offset,1,FALSE);
731 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_length,tvb, offset+1, 1, FALSE);
732 if ( (vc_len -intparam_len) <0 && (rem -intparam_len) <0 ) { /* error condition */
733 proto_tree_add_text(vcintparam_tree, tvb, offset +2, MIN(vc_len,rem), "malformed data");
736 switch (tvb_get_guint8(tvb, offset)) {
737 case FEC_VC_INTERFACEPARAM_MTU:
738 proto_item_append_text(ti,": MTU %u", tvb_get_ntohs(tvb,offset+2));
739 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_mtu,tvb, offset+2, 2, FALSE);
741 case FEC_VC_INTERFACEPARAM_MAXCATMCELLS:
742 proto_item_append_text(ti,": Max ATM Concat Cells %u", tvb_get_ntohs(tvb,offset+2));
743 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_maxcatmcells,tvb, offset+2, 2, FALSE);
745 case FEC_VC_INTERFACEPARAM_DESCRIPTION:
746 proto_item_append_text(ti,": Description");
747 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_desc,tvb, offset+2, (intparam_len -2), FALSE);
749 case FEC_VC_INTERFACEPARAM_CEMBYTES:
750 proto_item_append_text(ti,": CEM Payload Bytes %u", tvb_get_ntohs(tvb,offset+2));
751 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_cembytes,tvb, offset+2, 2, FALSE);
753 case FEC_VC_INTERFACEPARAM_CEMOPTIONS:
754 /* draft-malis-sonet-ces-mpls CEM options still undefined */
755 default: /* unknown */
756 proto_item_append_text(ti," unknown");
757 proto_tree_add_text(vcintparam_tree,tvb, offset+2, (intparam_len -2), "Unknown data");
762 vc_len -= intparam_len;
763 offset += intparam_len;
767 default: /* Unknown */
768 /* XXX - do all FEC's have a length that's a multiple of 4? */
769 /* Hmmm, don't think so. Will check. RJS. */
770 /* If we don't know its structure, we have to exit */
771 ti = proto_tree_add_text(val_tree, tvb, offset, 4, "FEC Element %u", ix);
772 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
773 if(fec_tree == NULL) return;
774 proto_tree_add_text(fec_tree, tvb, offset, rem, "Unknown FEC TLV type");
782 /* Dissect Address List TLV */
785 dissect_tlv_address_list(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
787 proto_tree *ti = NULL, *val_tree = NULL;
789 guint8 addr_size, *addr;
795 proto_tree_add_text(tree, tvb, offset, rem,
796 "Error processing Address List TLV: length is %d, should be >= 2",
801 family=tvb_get_ntohs(tvb, offset);
802 proto_tree_add_item(tree, hf_ldp_tlv_addrl_addr_family, tvb,
805 case AFNUM_INET: /*IPv4*/
807 str_handler=ip_to_str;
809 case AFNUM_INET6: /*IPv6*/
811 str_handler=ip6_to_str;
814 proto_tree_add_text(tree, tvb, offset+2, rem-2,
815 "Support for Address Family not implemented");
820 ti=proto_tree_add_text(tree, tvb, offset, rem, "Addresses");
821 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
823 if(val_tree == NULL) return;
824 if( (addr=g_malloc(addr_size)) == NULL ){
826 fprintf(stderr, "packet-ldp: dissect_tlv_address_list() malloc failed\n");
830 for(ix=1; rem >= addr_size; ix++, offset += addr_size,
832 if( (tvb_memcpy(tvb, addr, offset, addr_size))
836 str = (* (char* (*)(guint8 *))str_handler)(addr);
837 proto_tree_add_string_format(val_tree,
838 hf_ldp_tlv_addrl_addr, tvb, offset, addr_size, str,
839 "Address %u: %s", ix, str);
842 proto_tree_add_text(val_tree, tvb, offset, rem,
843 "Error processing TLV: Extra data at end of address list");
848 /* Dissect Path Vector TLV */
851 dissect_tlv_path_vector(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
853 proto_tree *ti = NULL, *val_tree = NULL;
858 ti=proto_tree_add_text(tree, tvb, offset, rem, "LSR IDs");
859 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
861 if(val_tree == NULL) return;
863 for(ix=1; rem >= 4; ix++, offset += 4, rem -= 4) {
864 tvb_memcpy(tvb, (guint8 *)&addr, offset, 4);
865 proto_tree_add_ipv4_format(val_tree,
866 hf_ldp_tlv_pv_lsrid, tvb, offset, 4,
867 addr, "LSR Id %u: %s", ix,
868 ip_to_str((guint8 *)&addr));
871 proto_tree_add_text(val_tree, tvb, offset, rem,
872 "Error processing TLV: Extra data at end of path vector");
876 /* Dissect ATM Label TLV */
879 dissect_tlv_atm_label(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
881 proto_tree *ti = NULL, *val_tree = NULL;
886 proto_tree_add_text(tree, tvb, offset, rem,
887 "Error processing ATM Label TLV: length is %d, should be 4",
891 ti=proto_tree_add_text(tree, tvb, offset, rem, "ATM Label");
892 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
893 if(val_tree == NULL) return;
895 proto_tree_add_item(val_tree, hf_ldp_tlv_atm_label_vbits, tvb, offset, 1, FALSE);
897 id=tvb_get_ntohs(tvb, offset)&0x0FFF;
898 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_atm_label_vpi, tvb, offset, 2, id, "VPI: %u", id);
900 id=tvb_get_ntohs(tvb, offset+2);
901 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_atm_label_vci, tvb, offset+2, 2, id, "VCI: %u", id);
905 /* Dissect FRAME RELAY Label TLV */
908 dissect_tlv_frame_label(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
910 proto_tree *ti = NULL, *val_tree = NULL;
916 proto_tree_add_text(tree, tvb, offset, rem,
917 "Error processing Frame Relay Label TLV: length is %d, should be 4",
921 ti=proto_tree_add_text(tree, tvb, offset, rem, "Frame Relay Label");
922 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
923 if(val_tree == NULL) return;
925 len=(guint8)(tvb_get_ntohs(tvb, offset)>>7) & 0x03;
926 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);
928 id=tvb_get_ntoh24(tvb, offset+1)&0x7FFFFF;
929 proto_tree_add_uint_format(val_tree,
930 hf_ldp_tlv_fr_label_dlci, tvb, offset+1, 3, id, "DLCI: %u", id);
934 /* Dissect STATUS TLV */
937 dissect_tlv_status(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
939 proto_tree *ti = NULL, *val_tree = NULL;
944 proto_tree_add_text(tree, tvb, offset, rem,
945 "Error processing Status TLV: length is %d, should be 10",
950 ti=proto_tree_add_text(tree, tvb, offset, rem, "Status");
951 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
952 if(val_tree == NULL) return;
954 proto_tree_add_item(val_tree, hf_ldp_tlv_status_ebit, tvb, offset, 1, FALSE);
955 proto_tree_add_item(val_tree, hf_ldp_tlv_status_fbit, tvb, offset, 1, FALSE);
957 data=tvb_get_ntohl(tvb, offset)&0x3FFFFFFF;
958 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);
960 proto_tree_add_item(val_tree, hf_ldp_tlv_status_msg_id, tvb, offset+4, 4, FALSE);
961 proto_tree_add_item(val_tree, hf_ldp_tlv_status_msg_type, tvb, offset+8, 2, FALSE);
965 /* Dissect Returned PDU TLV */
968 dissect_tlv_returned_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
970 proto_tree *ti = NULL, *val_tree = NULL;
974 proto_tree_add_text(tree, tvb, offset, rem,
975 "Error processing Returned PDU TLV: length is %d, should be >= 10",
979 ti=proto_tree_add_text(tree, tvb, offset, rem, "Returned PDU");
980 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
981 if(val_tree == NULL) return;
983 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_version, tvb, offset, 2, FALSE);
984 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_pdu_len, tvb, offset+2, 2, FALSE);
985 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_lsr, tvb, offset+4, 4, FALSE);
986 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_ls_id, tvb, offset+8, 2, FALSE);
991 /*XXX - dissect returned pdu data*/
992 proto_tree_add_text(val_tree, tvb, offset, rem, "Returned PDU Data");
997 /* Dissect Returned MESSAGE TLV */
1000 dissect_tlv_returned_message(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1002 proto_tree *ti = NULL, *val_tree = NULL;
1007 proto_tree_add_text(tree, tvb, offset, rem,
1008 "Error processing Returned Message TLV: length is %d, should be >= 4",
1012 ti=proto_tree_add_text(tree, tvb, offset, rem, "Returned Message");
1013 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1014 if(val_tree == NULL) return;
1016 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_ubit, tvb, offset, 1, FALSE);
1018 type=tvb_get_ntohs(tvb, offset)&0x7FFF;
1019 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);
1021 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_len, tvb, offset+2, 2, FALSE);
1025 if( rem >= 4 ) { /*have msg_id*/
1026 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_id, tvb, offset, 4, FALSE);
1032 /*XXX - dissect returned msg parameters*/
1033 proto_tree_add_text(val_tree, tvb, offset, rem, "Returned Message Parameters");
1038 /* Dissect the common hello params */
1041 dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1043 proto_tree *ti = NULL, *val_tree = NULL;
1047 ti = proto_tree_add_item(tree, hf_ldp_tlv_value, tvb, offset, rem, FALSE);
1048 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1049 if(val_tree == NULL) return;
1053 proto_tree_add_item(val_tree, hf_ldp_tlv_val_hold, tvb, offset, 2, FALSE);
1054 proto_tree_add_item(val_tree, hf_ldp_tlv_val_target, tvb, offset + 2, 2, FALSE);
1055 proto_tree_add_item(val_tree, hf_ldp_tlv_val_request, tvb, offset + 2, 2, FALSE);
1056 proto_tree_add_item(val_tree, hf_ldp_tlv_val_res, tvb, offset + 2, 2, FALSE);
1060 /* Dissect the common session params */
1063 dissect_tlv_common_session_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1065 proto_tree *ti = NULL, *val_tree = NULL;
1068 if( rem != 14) { /*length of Comm Sess Parms tlv*/
1069 proto_tree_add_text(tree, tvb, offset, rem,
1070 "Error processing Common Session Parameters TLV: length is %d, should be 14",
1074 ti = proto_tree_add_text(tree, tvb, offset, rem, "Parameters");
1075 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1077 if(val_tree != NULL) {
1078 /*Protocol Version*/
1079 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ver, tvb,offset, 2, FALSE);
1082 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ka, tvb,offset + 2, 2, FALSE);
1085 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_advbit,tvb, offset + 4, 1, FALSE);
1088 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ldetbit,tvb, offset + 4, 1, FALSE);
1090 /*Path Vector Limit*/
1091 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_pvlim,tvb, offset + 5, 1, FALSE);
1094 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_mxpdu,tvb, offset + 6, 2, FALSE);
1097 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_rxlsr,tvb, offset + 8, 4, FALSE);
1100 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_rxls,tvb, offset + 12, 2, FALSE);
1105 /* Dissect the atm session params */
1108 dissect_tlv_atm_session_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1110 proto_tree *ti = NULL, *val_tree = NULL, *lbl_tree = NULL;
1116 proto_tree_add_text(tree, tvb, offset, rem,
1117 "Error processing ATM Parameters TLV: length is %d, should be >= 4",
1122 ti = proto_tree_add_text(tree, tvb, offset, rem,"ATM Parameters");
1123 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1125 if(val_tree != NULL) {
1126 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_atm_merge,tvb, offset, 1, FALSE);
1128 /*get the number of label ranges*/
1129 numlr=(tvb_get_guint8(tvb, offset)>>2) & 0x0F;
1130 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_sess_atm_lr,
1131 tvb, offset, 1, numlr, "Number of Label Range components: %u",
1134 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_atm_dir,tvb, offset, 1, FALSE);
1136 /*move into range components*/
1139 ti = proto_tree_add_text(val_tree, tvb, offset, rem,"ATM Label Range Components");
1142 val_tree=proto_item_add_subtree(ti,ett_ldp_tlv_val);
1143 if( ! val_tree ) return;
1145 /*now dissect ranges*/
1146 for(ix=1; numlr > 0 && rem >= 8; ix++, rem-=8, numlr--) {
1147 ti=proto_tree_add_text(val_tree, tvb, offset, 8,
1148 "ATM Label Range Component %u", ix);
1149 lbl_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1151 if( lbl_tree == NULL ) break;
1153 id=tvb_get_ntohs(tvb, offset)&0x0FFF;
1154 proto_tree_add_uint_format(lbl_tree,
1155 hf_ldp_tlv_sess_atm_minvpi,
1157 id, "Minimum VPI: %u", id);
1158 id=tvb_get_ntohs(tvb, offset+4)&0x0FFF;
1159 proto_tree_add_uint_format(lbl_tree,
1160 hf_ldp_tlv_sess_atm_maxvpi,
1161 tvb, (offset+4), 2, id,
1162 "Maximum VPI: %u", id);
1164 id=tvb_get_ntohs(tvb, offset+2);
1165 proto_tree_add_uint_format(lbl_tree,
1166 hf_ldp_tlv_sess_atm_minvci,
1168 id, "Minimum VCI: %u", id);
1169 id=tvb_get_ntohs(tvb, offset+6);
1170 proto_tree_add_uint_format(lbl_tree,
1171 hf_ldp_tlv_sess_atm_maxvci,
1173 id, "Maximum VCI: %u", id);
1178 proto_tree_add_text(val_tree, tvb, offset, rem,
1179 "Error processing TLV: Extra data at end of TLV");
1184 /* Dissect the frame relay session params */
1187 dissect_tlv_frame_relay_session_parms(tvbuff_t *tvb, guint offset,proto_tree *tree, int rem)
1189 proto_tree *ti = NULL, *val_tree = NULL, *lbl_tree = NULL;
1190 guint8 numlr, ix, len;
1195 proto_tree_add_text(tree, tvb, offset, rem,
1196 "Error processing Frame Relay Parameters TLV: length is %d, should be >= 4",
1201 ti = proto_tree_add_text(tree, tvb, offset, rem,
1202 "Frame Relay Parameters");
1203 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1205 if(val_tree != NULL) {
1206 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_fr_merge,
1207 tvb, offset, 1, FALSE);
1209 /*get the number of label ranges*/
1210 numlr=(tvb_get_guint8(tvb, offset)>>2) & 0x0F;
1211 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_sess_fr_lr,
1212 tvb, offset, 1, numlr, "Number of Label Range components: %u",
1215 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_fr_dir,
1216 tvb, offset, 1, FALSE);
1218 /*move into range components*/
1221 ti = proto_tree_add_text(val_tree, tvb, offset, rem,
1222 "Frame Relay Label Range Components");
1225 val_tree=proto_item_add_subtree(ti,
1227 if( ! val_tree ) return;
1230 /*now dissect ranges*/
1231 for(ix=1; numlr > 0 && rem >= 8; ix++, rem-=8, numlr--) {
1232 ti=proto_tree_add_text(val_tree, tvb, offset, 8,
1233 "Frame Relay Label Range Component %u", ix);
1234 lbl_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1236 if( lbl_tree == NULL ) break;
1238 len=(guint8)(tvb_get_ntohs(tvb, offset)>>7) & 0x03;
1239 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);
1241 id=tvb_get_ntoh24(tvb, offset+1)&0x7FFFFF;
1242 proto_tree_add_uint_format(lbl_tree,
1243 hf_ldp_tlv_sess_fr_mindlci, tvb, offset+1, 3, id, "Minimum DLCI %u", id);
1244 id=tvb_get_ntoh24(tvb, offset+5)&0x7FFFFF;
1245 proto_tree_add_uint_format(lbl_tree,
1246 hf_ldp_tlv_sess_fr_maxdlci, tvb, offset+5, 3, id, "Maximum DLCI %u", id);
1252 proto_tree_add_text(val_tree, tvb, offset, rem,
1253 "Error processing TLV: Extra data at end of TLV");
1260 dissect_tlv_lspid(tvbuff_t *tvb, guint offset,proto_tree *tree, int rem)
1262 proto_tree *ti = NULL, *val_tree = NULL;
1266 proto_tree_add_text(tree, tvb, offset, rem,
1267 "Error processing LSP ID TLV: length is %d, should be 8",
1272 ti = proto_tree_add_text(tree, tvb, offset, rem,
1274 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1276 if(val_tree != NULL) {
1277 proto_tree_add_item(val_tree, hf_ldp_tlv_lspid_act_flg,
1278 tvb, offset, 2, FALSE);
1280 proto_tree_add_item(val_tree, hf_ldp_tlv_lspid_cr_lsp,
1281 tvb, offset, 2, FALSE);
1283 proto_tree_add_item(val_tree, hf_ldp_tlv_lspid_ldpid,
1284 tvb, offset, 4, FALSE);
1290 dissect_tlv_er_hop_ipv4(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1292 proto_tree *ti = NULL, *val_tree = NULL;
1297 proto_tree_add_text(tree, tvb, offset, rem,
1298 "Error processing ER HOP IPv4 TLV: length is %d, should be 8",
1302 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP IPv4");
1303 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1305 if(val_tree != NULL) {
1306 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1307 tvb, offset, 3, FALSE);
1309 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prelen,
1310 tvb, offset, 1, FALSE);
1312 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prefix4,
1313 tvb, offset, 4, FALSE);
1319 dissect_tlv_er_hop_ipv6(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1321 proto_tree *ti = NULL, *val_tree = NULL;
1325 proto_tree_add_text(tree, tvb, offset, rem,
1326 "Error processing ER HOP IPv6 TLV: length is %d, should be 20",
1330 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP IPv6");
1331 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1333 if(val_tree != NULL) {
1334 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1335 tvb, offset, 3, FALSE);
1337 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prelen,
1338 tvb, offset, 1, FALSE);
1340 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prefix6,
1341 tvb, offset, 16, FALSE);
1347 dissect_tlv_er_hop_as(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1349 proto_tree *ti = NULL, *val_tree = NULL;
1353 proto_tree_add_text(tree, tvb, offset, rem,
1354 "Error processing ER HOP AS TLV: length is %d, should be 4",
1358 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP AS");
1359 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1361 if(val_tree != NULL) {
1362 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1363 tvb, offset, 2, FALSE);
1365 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_as,
1366 tvb, offset, 2, FALSE);
1372 dissect_tlv_er_hop_lspid(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1374 proto_tree *ti = NULL, *val_tree = NULL;
1378 proto_tree_add_text(tree, tvb, offset, rem,
1379 "Error processing ER HOP LSPID TLV: length is %d, should be 8",
1383 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP LSPID");
1384 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1386 if(val_tree != NULL) {
1387 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1388 tvb, offset, 2, FALSE);
1390 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_cr_lsp,
1391 tvb, offset, 2, FALSE);
1393 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_ldpid,
1394 tvb, offset, 4, FALSE);
1400 dissect_tlv_traffic(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1402 proto_tree *ti = NULL, *val_tree = NULL;
1412 proto_tree_add_text(tree, tvb, offset, rem,
1413 "Error processing Traffic Parameters TLV: length is %d, should be 24",
1417 ti = proto_tree_add_text(tree, tvb, offset, rem, "Traffic parameters");
1418 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1420 if(val_tree != NULL) {
1422 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_reserv, tvb, offset, 1, FALSE);
1423 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_weight, tvb, offset, 1, FALSE);
1424 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_ebs, tvb, offset, 1, FALSE);
1425 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_cbs, tvb, offset, 1, FALSE);
1426 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_cdr, tvb, offset, 1, FALSE);
1427 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_pbs, tvb, offset, 1, FALSE);
1428 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_pdr, tvb, offset, 1, FALSE);
1432 proto_tree_add_item(val_tree, hf_ldp_tlv_frequency, tvb, offset, 1, FALSE);
1439 pi = proto_tree_add_item(val_tree, hf_ldp_tlv_weight, tvb, offset, 1, FALSE);
1440 val_8 = tvb_get_guint8(tvb, offset);
1442 proto_item_set_text(pi, "Weight: Not applicable");
1446 conv.val_32 = tvb_get_ntohl (tvb, offset);
1447 proto_tree_add_double_format(val_tree, hf_ldp_tlv_pdr, tvb, offset,
1448 4, conv.val_f, "PDR: %f Bps", conv.val_f);
1451 conv.val_32 = (float)tvb_get_ntohl (tvb, offset);
1452 proto_tree_add_double_format(val_tree, hf_ldp_tlv_pbs, tvb, offset,
1453 4, conv.val_f, "PBS: %f Bytes", conv.val_f);
1457 conv.val_32 = (float)tvb_get_ntohl (tvb, offset);
1458 proto_tree_add_double_format(val_tree, hf_ldp_tlv_cdr, tvb, offset,
1459 4, conv.val_f, "CDR: %f Bps", conv.val_f);
1463 conv.val_32 = (float)tvb_get_ntohl (tvb, offset);
1464 proto_tree_add_double_format(val_tree, hf_ldp_tlv_cbs, tvb, offset,
1465 4, conv.val_f, "CBS: %f Bytes", conv.val_f);
1469 conv.val_32 = (float)tvb_get_ntohl (tvb, offset);
1470 proto_tree_add_double_format(val_tree, hf_ldp_tlv_ebs, tvb, offset,
1471 4, conv.val_f, "EBS: %f Bytes", conv.val_f);
1478 dissect_tlv_route_pinning(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1480 proto_tree *ti = NULL, *val_tree = NULL;
1484 proto_tree_add_text(tree, tvb, offset, rem,
1485 "Error processing Route Pinning TLV: length is %d, should be 4",
1489 ti = proto_tree_add_text(tree, tvb, offset, rem, "Route Pinning");
1490 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1492 if(val_tree != NULL) {
1493 proto_tree_add_item(val_tree, hf_ldp_tlv_route_pinning,
1494 tvb, offset, 4, FALSE);
1501 dissect_tlv_resource_class(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1503 proto_tree *ti = NULL, *val_tree = NULL;
1507 proto_tree_add_text(tree, tvb, offset, rem,
1508 "Error processing Resource Class TLV: length is %d, should be 4",
1512 ti = proto_tree_add_text(tree, tvb, offset, rem, "Resource Class");
1513 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1515 if(val_tree != NULL) {
1516 proto_tree_add_item(val_tree, hf_ldp_tlv_resource_class,
1517 tvb, offset, 4, FALSE);
1524 dissect_tlv_preemption(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1526 proto_tree *ti = NULL, *val_tree = NULL;
1530 proto_tree_add_text(tree, tvb, offset, rem,
1531 "Error processing Preemption TLV: length is %d, should be 4",
1535 ti = proto_tree_add_text(tree, tvb, offset, rem, "Preemption");
1536 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1538 if(val_tree != NULL) {
1539 proto_tree_add_item(val_tree, hf_ldp_tlv_set_prio,
1540 tvb, offset, 1, FALSE);
1542 proto_tree_add_item(val_tree, hf_ldp_tlv_hold_prio,
1543 tvb, offset, 1, FALSE);
1549 dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem);
1552 dissect_tlv_er(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1554 proto_tree *ti = NULL, *val_tree = NULL;
1558 ti = proto_tree_add_text(tree, tvb, offset, rem, "Explicit route");
1559 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1561 if(val_tree != NULL) {
1564 len = dissect_tlv (tvb, offset, val_tree, rem);
1573 /* Dissect a TLV and return the number of bytes consumed ... */
1576 dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1578 guint16 type, typebak;
1580 proto_tree *ti = NULL, *tlv_tree = NULL;
1582 length=tvb_reported_length_remaining(tvb, offset);
1583 rem=MIN(rem, length);
1585 if( rem < 4 ) {/*chk for minimum header*/
1587 proto_tree_add_text(tree, tvb, offset, rem,
1588 "Error processing TLV: length is %d, should be >= 4",
1592 type = tvb_get_ntohs(tvb, offset) & 0x3FFF;
1594 length = tvb_get_ntohs(tvb, offset + 2),
1595 rem -= 4; /*do not count header*/
1596 length = MIN(length, rem); /* Don't go haywire if a problem ... */
1599 /*chk for vendor-private*/
1600 if(type>=TLV_VENDOR_PRIVATE_START && type<=TLV_VENDOR_PRIVATE_END){
1601 typebak=type; /*keep type*/
1602 type=TLV_VENDOR_PRIVATE_START;
1604 /*chk for experimental*/
1605 } else if(type>=TLV_EXPERIMENTAL_START && type<=TLV_EXPERIMENTAL_END){
1606 typebak=type; /*keep type*/
1607 type=TLV_EXPERIMENTAL_START;
1610 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1611 val_to_str(type, tlv_type_names, "Unknown TLV type (0x%04X)"));
1612 tlv_tree = proto_item_add_subtree(ti, ett_ldp_tlv);
1613 if(tlv_tree == NULL) return length+4;
1615 proto_tree_add_item(tlv_tree, hf_ldp_tlv_unknown, tvb, offset, 1, FALSE);
1617 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 );
1619 proto_tree_add_item(tlv_tree, hf_ldp_tlv_len, tvb, offset + 2, 2, FALSE);
1624 dissect_tlv_fec(tvb, offset + 4, tlv_tree, length);
1627 case TLV_ADDRESS_LIST:
1628 dissect_tlv_address_list(tvb, offset + 4, tlv_tree, length);
1632 if( length != 1 ) /*error, only one byte*/
1633 proto_tree_add_text(tlv_tree, tvb, offset + 4,length,
1634 "Error processing Hop Count TLV: length is %d, should be 1",
1637 proto_tree_add_item(tlv_tree, hf_ldp_tlv_hc_value, tvb,offset + 4, length, FALSE);
1640 case TLV_PATH_VECTOR:
1641 dissect_tlv_path_vector(tvb, offset + 4, tlv_tree, length);
1644 case TLV_GENERIC_LABEL:
1645 if( length != 4 ) /*error, need only label*/
1646 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1647 "Error processing Generic Label TLV: length is %d, should be 4",
1650 guint32 label=tvb_get_ntohl(tvb, offset+4) & 0x000FFFFF;
1652 proto_tree_add_uint_format(tlv_tree, hf_ldp_tlv_generic_label,
1653 tvb, offset+4, length, label, "Generic Label: %u", label);
1658 dissect_tlv_atm_label(tvb, offset + 4, tlv_tree, length);
1661 case TLV_FRAME_LABEL:
1662 dissect_tlv_frame_label(tvb, offset + 4, tlv_tree, length);
1666 dissect_tlv_status(tvb, offset + 4, tlv_tree, length);
1669 case TLV_EXTENDED_STATUS:
1670 if( length != 4 ) /*error, need only status_code(guint32)*/
1671 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1672 "Error processing Extended Status TLV: length is %d, should be 4",
1675 proto_tree_add_item(tlv_tree, hf_ldp_tlv_extstatus_data, tvb, offset + 4, length, FALSE);
1679 case TLV_RETURNED_PDU:
1680 dissect_tlv_returned_pdu(tvb, offset + 4, tlv_tree, length);
1683 case TLV_RETURNED_MESSAGE:
1684 dissect_tlv_returned_message(tvb, offset + 4, tlv_tree, length);
1687 case TLV_COMMON_HELLO_PARMS:
1688 dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree, length);
1691 case TLV_IPV4_TRANSPORT_ADDRESS:
1692 if( length != 4 ) /*error, need only ipv4*/
1693 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1694 "Error processing IPv4 Transport Address TLV: length is %d, should be 4",
1697 proto_tree_add_item(tlv_tree, hf_ldp_tlv_ipv4_taddr, tvb, offset + 4, 4, FALSE);
1701 case TLV_CONFIGURATION_SEQNO:
1702 if( length != 4 ) /*error, need only seq_num(guint32)*/
1703 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1704 "Error processing Configuration Sequence Number TLV: length is %d, should be 4",
1707 proto_tree_add_item(tlv_tree, hf_ldp_tlv_config_seqno, tvb, offset + 4, 4, FALSE);
1711 case TLV_IPV6_TRANSPORT_ADDRESS:
1712 if( length != 16 ) /*error, need only ipv6*/
1713 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1714 "Error processing IPv6 Transport Address TLV: length is %d, should be 16",
1717 proto_tree_add_item(tlv_tree, hf_ldp_tlv_ipv6_taddr, tvb, offset + 4, 16, FALSE);
1721 case TLV_COMMON_SESSION_PARMS:
1722 dissect_tlv_common_session_parms(tvb, offset + 4, tlv_tree, length);
1725 case TLV_ATM_SESSION_PARMS:
1726 dissect_tlv_atm_session_parms(tvb, offset + 4, tlv_tree, length);
1729 case TLV_FRAME_RELAY_SESSION_PARMS:
1730 dissect_tlv_frame_relay_session_parms(tvb, offset + 4, tlv_tree, length);
1733 case TLV_LABEL_REQUEST_MESSAGE_ID:
1734 if( length != 4 ) /*error, need only one msgid*/
1735 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1736 "Error processing Label Request Message ID TLV: length is %d, should be 4",
1739 proto_tree_add_item(tlv_tree, hf_ldp_tlv_lbl_req_msg_id, tvb,offset + 4,length, FALSE);
1743 dissect_tlv_lspid(tvb, offset + 4, tlv_tree, length);
1747 dissect_tlv_er(tvb, offset + 4, tlv_tree, length);
1750 case TLV_ER_HOP_IPV4:
1751 dissect_tlv_er_hop_ipv4(tvb, offset + 4, tlv_tree, length);
1754 case TLV_ER_HOP_IPV6:
1755 dissect_tlv_er_hop_ipv6(tvb, offset +4, tlv_tree, length);
1759 dissect_tlv_er_hop_as(tvb, offset + 4, tlv_tree, length);
1762 case TLV_ER_HOP_LSPID:
1763 dissect_tlv_er_hop_lspid(tvb, offset +4, tlv_tree, length);
1766 case TLV_TRAFFIC_PARAM:
1767 dissect_tlv_traffic(tvb, offset +4, tlv_tree, length);
1770 case TLV_PREEMPTION:
1771 dissect_tlv_preemption(tvb, offset +4, tlv_tree, length);
1774 case TLV_RESOURCE_CLASS:
1775 dissect_tlv_resource_class(tvb, offset +4, tlv_tree, length);
1778 case TLV_ROUTE_PINNING:
1779 dissect_tlv_route_pinning(tvb, offset +4, tlv_tree, length);
1782 case TLV_VENDOR_PRIVATE_START:
1783 if( length < 4 ) /*error, at least Vendor ID*/
1784 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1785 "Error processing Vendor Private Start TLV: length is %d, should be >= 4",
1788 proto_tree_add_item(tlv_tree, hf_ldp_tlv_vendor_id, tvb,offset + 4, 4, FALSE);
1789 if( length > 4 ) /*have data*/
1790 proto_tree_add_text(tlv_tree, tvb, offset + 8, length-4,"Data");
1794 case TLV_EXPERIMENTAL_START:
1795 if( length < 4 ) /*error, at least Experiment ID*/
1796 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1797 "Error processing Experimental Start TLV: length is %d, should be >= 4",
1800 proto_tree_add_item(tlv_tree, hf_ldp_tlv_experiment_id, tvb,offset + 4, 4, FALSE);
1801 if( length > 4 ) /*have data*/
1802 proto_tree_add_text(tlv_tree, tvb, offset + 8, length-4,"Data");
1807 proto_tree_add_item(tlv_tree, hf_ldp_tlv_value, tvb, offset + 4, length, FALSE);
1812 return length + 4; /* Length of the value field + header */
1816 /* Dissect a Message and return the number of bytes consumed ... */
1819 dissect_msg(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, int rem)
1821 guint16 type, typebak;
1823 int length, ao=0, co;
1824 proto_tree *ti = NULL, *msg_tree = NULL;
1826 length=tvb_reported_length_remaining(tvb, offset);
1827 rem=MIN(rem, length);
1829 if( rem < 8 ) {/*chk for minimum header = type + length + msg_id*/
1830 if( check_col(pinfo->cinfo, COL_INFO) )
1831 col_append_fstr(pinfo->cinfo, COL_INFO, "Bad Message");
1833 proto_tree_add_text(tree, tvb, offset, rem,
1834 "Error processing Message: length is %d, should be >= 8",
1838 type = tvb_get_ntohs(tvb, offset) & 0x7FFF;
1840 /*chk for vendor-private*/
1841 if(type>=LDP_VENDOR_PRIVATE_START && type<=LDP_VENDOR_PRIVATE_END){
1842 typebak=type; /*keep type*/
1843 type=LDP_VENDOR_PRIVATE_START;
1845 /*chk for experimental*/
1846 } else if(type>=LDP_EXPERIMENTAL_MESSAGE_START && type<=LDP_EXPERIMENTAL_MESSAGE_END){
1847 typebak=type; /*keep type*/
1848 type=LDP_EXPERIMENTAL_MESSAGE_START;
1852 if( (length = tvb_get_ntohs(tvb, offset + 2)) < (4+extra) ) {/*not enough data for type*/
1853 if( check_col(pinfo->cinfo, COL_INFO) )
1854 col_append_fstr(pinfo->cinfo, COL_INFO, "Bad Message Length ");
1856 proto_tree_add_text(tree, tvb, offset, rem,
1857 "Error processing Message Length: length is %d, should be >= %u",
1862 length = MIN(length, rem); /* Don't go haywire if a problem ... */
1864 if( check_col(pinfo->cinfo, COL_INFO) ){
1865 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(type, ldp_message_types, "Unknown Message (0x%04X)"));
1869 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1870 val_to_str(type, ldp_message_types, "Unknown Message type (0x%04X)"));
1871 msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
1872 if(msg_tree == NULL) return length+4;
1874 proto_tree_add_item(msg_tree, hf_ldp_msg_ubit, tvb, offset, 1, FALSE);
1876 type=tvb_get_ntohs(tvb, offset)&0x7FFF;
1877 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);
1879 proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset+2, 2, FALSE);
1880 proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset+4, 4, FALSE);
1885 case LDP_VENDOR_PRIVATE_START:
1886 hf_tmp=hf_ldp_msg_vendor_id;
1888 case LDP_EXPERIMENTAL_MESSAGE_START:
1889 hf_tmp=hf_ldp_msg_experiment_id;
1892 proto_tree_add_item(msg_tree, hf_tmp, tvb, offset+8, extra, FALSE);
1896 offset += (8+extra);
1897 length -= (4+extra);
1900 while( (length-ao) > 0 ) {
1901 co=dissect_tlv(tvb, offset, msg_tree, length-ao);
1906 return length+8+extra;
1909 /* Dissect a PDU and return the number of bytes consumed ... */
1912 dissect_ldp_pdu(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, int rem, guint ix)
1914 int length, ao=0, co;
1915 proto_tree *ti=NULL, *pdu_tree = NULL;
1917 length=tvb_reported_length_remaining(tvb, offset);
1918 rem=MIN(rem, length);
1920 if( rem < 10 ){/*don't even have a PDU header*/
1921 /*XXX Need changes in desegment_tcp to handle multiple requests*/
1923 if( pinfo->can_desegment && (pinfo->ptype==PT_TCP) && ldp_desegment ){
1924 pinfo->desegment_offset=offset;
1925 pinfo->desegment_len=10-rem;
1929 proto_tree_add_text(tree, tvb, offset, rem,"Not enough bytes for PDU Hdr in TCP segment");
1934 if( (length = tvb_get_ntohs(tvb, offset + 2)) < 6 ) {/*not enough*/
1935 if( check_col(pinfo->cinfo, COL_INFO) && ix )
1936 col_append_fstr(pinfo->cinfo, COL_INFO, "PDU %u: ", ix);
1937 if( check_col(pinfo->cinfo, COL_INFO) ){
1938 col_append_fstr(pinfo->cinfo, COL_INFO, "Bad PDU Length ");
1941 proto_tree_add_text(tree, tvb, offset, rem,
1942 "Error processing PDU Length: length is %d, should be >= 6",
1949 if( pinfo->can_desegment && (pinfo->ptype==PT_TCP) && ldp_desegment ){/*ask for more*/
1950 pinfo->desegment_offset=offset;
1951 pinfo->desegment_len=length-rem;
1953 if( check_col(pinfo->cinfo, COL_INFO) && ix )
1954 col_append_fstr(pinfo->cinfo, COL_INFO, "PDU %u: ", ix);
1955 if( check_col(pinfo->cinfo, COL_INFO) )
1956 col_append_fstr(pinfo->cinfo, COL_INFO, "Bad PDU Length ");
1958 proto_tree_add_text(tree, tvb, offset, rem+4,
1959 "Error processing PDU Length: length is %d, should be <= %d",
1965 if( check_col(pinfo->cinfo, COL_INFO) && ix )
1966 col_append_fstr(pinfo->cinfo, COL_INFO, "PDU %u: ", ix);
1969 ti=proto_tree_add_protocol_format(tree, proto_ldp, tvb, offset,
1970 length+4, ix?"LDP PDU %u":"LDP PDU", ix);
1971 pdu_tree = proto_item_add_subtree(ti, ett_ldp);
1975 proto_tree_add_item(pdu_tree, hf_ldp_version, tvb, offset, 2, FALSE);
1976 proto_tree_add_item(pdu_tree, hf_ldp_pdu_len, tvb, offset+2, 2, FALSE);
1977 proto_tree_add_item(pdu_tree, hf_ldp_lsr, tvb, offset+4, 4, FALSE);
1978 proto_tree_add_item(pdu_tree, hf_ldp_ls_id, tvb, offset+8, 2, FALSE);
1983 while( (length-ao) > 0 ) {
1984 co=dissect_msg(tvb, offset, pinfo, pdu_tree, length-ao);
1993 dissect_ldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1995 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1996 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
1998 if (check_col(pinfo->cinfo, COL_INFO))
1999 col_clear(pinfo->cinfo, COL_INFO);
2001 dissect_ldp_pdu(tvb, 0, pinfo, tree, tvb_reported_length(tvb), 0);
2005 dissect_ldp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2007 int offset=0, length, rtn;
2011 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2012 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
2014 if (check_col(pinfo->cinfo, COL_INFO))
2015 col_clear(pinfo->cinfo, COL_INFO);
2017 length=tvb_reported_length(tvb);
2019 rtn = dissect_ldp_pdu(tvb, offset, pinfo, tree, length, ix++);
2025 /* Register all the bits needed with the filtering engine */
2028 proto_register_ldp(void)
2030 static hf_register_info hf[] = {
2032 /* Change the following to the type you need */
2033 { "Request", "ldp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
2036 { "Response", "ldp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
2039 { "Version", "ldp.hdr.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
2042 { "PDU Length", "ldp.hdr.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
2045 { "LSR ID", "ldp.hdr.ldpid.lsr", FT_IPv4, BASE_HEX, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
2048 { "Label Space ID", "ldp.hdr.ldpid.lsid", FT_UINT16, BASE_DEC, NULL, 0, "LDP Label Space ID", HFILL }},
2051 { "U bit", "ldp.msg.ubit", FT_BOOLEAN, 8, TFS(&ldp_message_ubit), 0x80, "Unknown Message Bit", HFILL }},
2054 { "Message Type", "ldp.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x7FFF, "LDP message type", HFILL }},
2057 { "Message Length", "ldp.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
2060 { "Message ID", "ldp.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
2062 { &hf_ldp_msg_vendor_id,
2063 { "Vendor ID", "ldp.msg.vendor.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Vendor-private Message ID", HFILL }},
2065 { &hf_ldp_msg_experiment_id,
2066 { "Experiment ID", "ldp.msg.experiment.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Experimental Message ID", HFILL }},
2068 { &hf_ldp_tlv_unknown,
2069 { "TLV Unknown bits", "ldp.msg.tlv.unknown", FT_UINT8, BASE_HEX, VALS(tlv_unknown_vals), 0xC0, "TLV Unknown bits Field", HFILL }},
2072 { "TLV Type", "ldp.msg.tlv.type", FT_UINT16, BASE_HEX, VALS(tlv_type_names), 0x3FFF, "TLV Type Field", HFILL }},
2075 {"TLV Length", "ldp.msg.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length Field", HFILL }},
2077 { &hf_ldp_tlv_value,
2078 { "TLV Value", "ldp.msg.tlv.value", FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value Bytes", HFILL }},
2080 { &hf_ldp_tlv_val_hold,
2081 { "Hold Time", "ldp.msg.tlv.hello.hold", FT_UINT16, BASE_DEC, NULL, 0x0, "Hello Common Parameters Hold Time", HFILL }},
2083 { &hf_ldp_tlv_val_target,
2084 { "Targeted Hello", "ldp.msg.tlv.hello.targeted", FT_BOOLEAN, 16, TFS(&hello_targeted_vals), 0x8000, "Hello Common Parameters Targeted Bit", HFILL }},
2086 { &hf_ldp_tlv_val_request,
2087 { "Hello Requested", "ldp,msg.tlv.hello.requested", FT_BOOLEAN, 16, TFS(&hello_requested_vals), 0x4000, "Hello Common Parameters Hello Requested Bit", HFILL }},
2089 { &hf_ldp_tlv_val_res,
2090 { "Reserved", "ldp.msg.tlv.hello.res", FT_UINT16, BASE_HEX, NULL, 0x3FFF, "Hello Common Parameters Reserved Field", HFILL }},
2092 { &hf_ldp_tlv_ipv4_taddr,
2093 { "IPv4 Transport Address", "ldp.msg.tlv.ipv4.taddr", FT_IPv4, BASE_DEC, NULL, 0x0, "IPv4 Transport Address", HFILL }},
2095 { &hf_ldp_tlv_config_seqno,
2096 { "Configuration Sequence Number", "ldp.msg.tlv.hello.cnf_seqno", FT_UINT32, BASE_DEC, NULL, 0x0, "Hello Configuration Sequence Number", HFILL }},
2098 { &hf_ldp_tlv_ipv6_taddr,
2099 { "IPv6 Transport Address", "ldp.msg.tlv.ipv6.taddr", FT_IPv6, BASE_DEC, NULL, 0x0, "IPv6 Transport Address", HFILL }},
2101 { &hf_ldp_tlv_fec_wc,
2102 { "FEC Element Type", "ldp.msg.tlv.fec.type", FT_UINT8, BASE_DEC, VALS(fec_types), 0x0, "Forwarding Equivalence Class Element Types", HFILL }},
2104 { &hf_ldp_tlv_fec_af,
2105 { "FEC Element Address Type", "ldp.msg.tlv.fec.af", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Forwarding Equivalence Class Element Address Family", HFILL }},
2107 { &hf_ldp_tlv_fec_len,
2108 { "FEC Element Length", "ldp.msg.tlv.fec.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Length", HFILL }},
2110 { &hf_ldp_tlv_fec_pfval,
2111 { "FEC Element Prefix Value", "ldp.msg.tlv.fec.pfval", FT_STRING, BASE_NONE, NULL, 0x0, "Forwarding Equivalence Class Element Prefix", HFILL }},
2113 { &hf_ldp_tlv_fec_hoval,
2114 { "FEC Element Host Address Value", "ldp.msg.tlv.fec.hoval", FT_STRING, BASE_NONE, NULL, 0x0, "Forwarding Equivalence Class Element Address", HFILL }},
2116 { &hf_ldp_tlv_addrl_addr_family,
2117 { "Address Family", "ldp.msg.tlv.addrl.addr_family", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Address Family List", HFILL }},
2119 { &hf_ldp_tlv_addrl_addr,
2120 { "Address", "ldp.msg.tlv.addrl.addr", FT_STRING, BASE_NONE, NULL, 0x0, "Address", HFILL }},
2122 { &hf_ldp_tlv_hc_value,
2123 { "Hop Count Value", "ldp.msg.tlv.hc.value", FT_UINT8, BASE_DEC, NULL, 0x0, "Hop Count", HFILL }},
2125 { &hf_ldp_tlv_pv_lsrid,
2126 { "LSR Id", "ldp.msg.tlv.pv.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Path Vector LSR Id", HFILL }},
2128 { &hf_ldp_tlv_sess_ver,
2129 { "Session Protocol Version", "ldp.msg.tlv.sess.ver", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Protocol Version", HFILL }},
2131 { &hf_ldp_tlv_sess_ka,
2132 { "Session KeepAlive Time", "ldp.msg.tlv.sess.ka", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters KeepAlive Time", HFILL }},
2134 { &hf_ldp_tlv_sess_advbit,
2135 { "Session Label Advertisement Discipline", "ldp.msg.tlv.sess.advbit",
2136 FT_BOOLEAN, 8, TFS(&tlv_sess_advbit_vals), 0x80,
2137 "Common Session Parameters Label Advertisement Discipline", HFILL }},
2139 { &hf_ldp_tlv_sess_ldetbit,
2140 { "Session Loop Detection", "ldp.msg.tlv.sess.ldetbit", FT_BOOLEAN, 8, TFS(&tlv_sess_ldetbit_vals), 0x40, "Common Session Parameters Loop Detection", HFILL }},
2142 { &hf_ldp_tlv_sess_pvlim,
2143 { "Session Path Vector Limit", "ldp.msg.tlv.sess.pvlim", FT_UINT8, BASE_DEC, NULL, 0x0, "Common Session Parameters Path Vector Limit", HFILL }},
2145 { &hf_ldp_tlv_sess_mxpdu,
2146 { "Session Max PDU Length", "ldp.msg.tlv.sess.mxpdu", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Max PDU Length", HFILL }},
2148 { &hf_ldp_tlv_sess_rxlsr,
2149 { "Session Receiver LSR Identifier", "ldp.msg.tlv.sess.rxlsr", FT_IPv4, BASE_DEC, NULL, 0x0, "Common Session Parameters LSR Identifier", HFILL }},
2151 { &hf_ldp_tlv_sess_rxls,
2152 { "Session Receiver Label Space Identifier", "ldp.msg.tlv.sess.rxlsr", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Receiver Label Space Identifier", HFILL }},
2154 { &hf_ldp_tlv_sess_atm_merge,
2155 { "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 }},
2157 { &hf_ldp_tlv_sess_atm_lr,
2158 { "Number of ATM Label Ranges", "ldp.msg.tlv.sess.atm.lr", FT_UINT8, BASE_DEC, NULL, 0x3C, "Number of Label Ranges", HFILL }},
2160 { &hf_ldp_tlv_sess_atm_dir,
2161 { "Directionality", "ldp.msg.tlv.sess.atm.dir", FT_BOOLEAN, 8, TFS(&tlv_atm_dirbit), 0x02, "Lablel Directionality", HFILL }},
2163 { &hf_ldp_tlv_sess_atm_minvpi,
2164 { "Minimum VPI", "ldp.msg.tlv.sess.atm.minvpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "Minimum VPI", HFILL }},
2166 { &hf_ldp_tlv_sess_atm_minvci,
2167 { "Minimum VCI", "ldp.msg.tlv.sess.atm.minvci", FT_UINT16, BASE_DEC, NULL, 0x0, "Minimum VCI", HFILL }},
2169 { &hf_ldp_tlv_sess_atm_maxvpi,
2170 { "Maximum VPI", "ldp.msg.tlv.sess.atm.maxvpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "Maximum VPI", HFILL }},
2172 { &hf_ldp_tlv_sess_atm_maxvci,
2173 { "Maximum VCI", "ldp.msg.tlv.sess.atm.maxvci", FT_UINT16, BASE_DEC, NULL, 0x0, "Maximum VCI", HFILL }},
2175 { &hf_ldp_tlv_sess_fr_merge,
2176 { "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 }},
2178 { &hf_ldp_tlv_sess_fr_lr,
2179 { "Number of Frame Relay Label Ranges", "ldp.msg.tlv.sess.fr.lr", FT_UINT8, BASE_DEC, NULL, 0x3C, "Number of Label Ranges", HFILL }},
2181 { &hf_ldp_tlv_sess_fr_dir,
2182 { "Directionality", "ldp.msg.tlv.sess.fr.dir", FT_BOOLEAN, 8, TFS(&tlv_atm_dirbit), 0x02, "Lablel Directionality", HFILL }},
2184 { &hf_ldp_tlv_sess_fr_len,
2185 { "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 }},
2187 { &hf_ldp_tlv_sess_fr_mindlci,
2188 { "Minimum DLCI", "ldp.msg.tlv.sess.fr.mindlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "Minimum DLCI", HFILL }},
2190 { &hf_ldp_tlv_sess_fr_maxdlci,
2191 { "Maximum DLCI", "ldp.msg.tlv.sess.fr.maxdlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "Maximum DLCI", HFILL }},
2193 { &hf_ldp_tlv_lbl_req_msg_id,
2194 { "Label Request Message ID", "ldp.tlv.lbl_req_msg_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Label Request Message to be aborted", HFILL }},
2196 { &hf_ldp_tlv_vendor_id,
2197 { "Vendor ID", "ldp.msg.tlv.vendor_id", FT_UINT32, BASE_HEX, NULL, 0, "IEEE 802 Assigned Vendor ID", HFILL }},
2199 { &hf_ldp_tlv_experiment_id,
2200 { "Experiment ID", "ldp.msg.tlv.experiment_id", FT_UINT32, BASE_HEX, NULL, 0, "Experiment ID", HFILL }},
2202 { &hf_ldp_tlv_generic_label,
2203 { "Generic Label", "ldp.msg.tlv.generic.label", FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, "Generic Label", HFILL }},
2205 { &hf_ldp_tlv_atm_label_vbits,
2206 { "V-bits", "ldp.msg.tlv.atm.label.vbits", FT_UINT8, BASE_HEX, VALS(tlv_atm_vbits_vals), 0x30, "ATM Label V Bits", HFILL }},
2208 { &hf_ldp_tlv_atm_label_vpi,
2209 { "VPI", "ldp.msg.tlv.atm.label.vpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "ATM Label VPI", HFILL }},
2211 { &hf_ldp_tlv_atm_label_vci,
2212 { "VCI", "ldp.msg.tlv.atm.label.vci", FT_UINT16, BASE_DEC, NULL, 0, "ATM Label VCI", HFILL }},
2214 { &hf_ldp_tlv_fr_label_len,
2215 { "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 }},
2217 { &hf_ldp_tlv_fr_label_dlci,
2218 { "DLCI", "ldp.msg.tlv.fr.label.dlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "FRAME RELAY Label DLCI", HFILL }},
2220 { &hf_ldp_tlv_status_ebit,
2221 { "E Bit", "ldp.msg.tlv.status.ebit", FT_BOOLEAN, 8, TFS(&tlv_status_ebit), 0x80, "Fatal Error Bit", HFILL }},
2223 { &hf_ldp_tlv_status_fbit,
2224 { "F Bit", "ldp.msg.tlv.status.fbit", FT_BOOLEAN, 8, TFS(&tlv_status_fbit), 0x40, "Forward Bit", HFILL }},
2226 { &hf_ldp_tlv_status_data,
2227 { "Status Data", "ldp.msg.tlv.status.data", FT_UINT32, BASE_HEX, VALS(tlv_status_data), 0x3FFFFFFF, "Status Data", HFILL }},
2229 { &hf_ldp_tlv_status_msg_id,
2230 { "Message ID", "ldp.msg.tlv.status.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "Identifies peer message to which Status TLV refers", HFILL }},
2232 { &hf_ldp_tlv_status_msg_type,
2233 { "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 }},
2235 { &hf_ldp_tlv_extstatus_data,
2236 { "Extended Status Data", "ldp.msg.tlv.extstatus.data", FT_UINT32, BASE_HEX, NULL, 0x0, "Extended Status Data", HFILL }},
2238 { &hf_ldp_tlv_returned_version,
2239 { "Returned PDU Version", "ldp.msg.tlv.returned.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
2241 { &hf_ldp_tlv_returned_pdu_len,
2242 { "Returned PDU Length", "ldp.msg.tlv.returned.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
2244 { &hf_ldp_tlv_returned_lsr,
2245 { "Returned PDU LSR ID", "ldp.msg.tlv.returned.ldpid.lsr", FT_IPv4, BASE_DEC, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
2247 { &hf_ldp_tlv_returned_ls_id,
2248 { "Returned PDU Label Space ID", "ldp.msg.tlv.returned.ldpid.lsid", FT_UINT16, BASE_HEX, NULL, 0x0, "LDP Label Space ID", HFILL }},
2250 { &hf_ldp_tlv_returned_msg_ubit,
2251 { "Returned Message Unknown bit", "ldp.msg.tlv.returned.msg.ubit", FT_UINT8, BASE_HEX, TFS(&ldp_message_ubit), 0x80, "Message Unknown bit", HFILL }},
2253 { &hf_ldp_tlv_returned_msg_type,
2254 { "Returned Message Type", "ldp.msg.tlv.returned.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x7FFF, "LDP message type", HFILL }},
2256 { &hf_ldp_tlv_returned_msg_len,
2257 { "Returned Message Length", "ldp.msg.tlv.returned.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
2259 { &hf_ldp_tlv_returned_msg_id,
2260 { "Returned Message ID", "ldp.msg.tlv.returned.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
2262 {&hf_ldp_tlv_fec_vc_controlword,
2263 {"C-bit", "ldp.msg.tlv.fec.vc.controlword", FT_BOOLEAN, 8, TFS(&fec_vc_cbit), 0x80, "Control Word Present", HFILL }},
2265 {&hf_ldp_tlv_fec_vc_vctype,
2266 {"VC Type", "ldp.msg.tlv.fec.vc.vctype", FT_UINT16, BASE_HEX, VALS(fec_vc_types_vals), 0x7FFF, "Virtual Circuit Type", HFILL }},
2268 {&hf_ldp_tlv_fec_vc_infolength,
2269 {"VC Info Length", "ldp.msg.tlv.fec.vc.infolength", FT_UINT8, BASE_DEC, NULL, 0x0, "VC FEC Info Length", HFILL }},
2271 {&hf_ldp_tlv_fec_vc_groupid,
2272 {"Group ID", "ldp.msg.tlv.fec.vc.groupid", FT_UINT32, BASE_DEC, NULL, 0x0, "VC FEC Group ID", HFILL }},
2274 {&hf_ldp_tlv_fec_vc_vcid,
2275 {"VC ID", "ldp.msg.tlv.fec.vc.vcid", FT_UINT32, BASE_DEC, NULL, 0x0, "VC FEC VCID", HFILL }},
2277 {&hf_ldp_tlv_fec_vc_intparam_length,
2278 {"Length", "ldp.msg.tlv.fec.vc.intparam.length", FT_UINT8, BASE_DEC, NULL, 0x0, "VC FEC Interface Paramater Length", HFILL }},
2280 {&hf_ldp_tlv_fec_vc_intparam_mtu,
2281 {"MTU", "ldp.msg.tlv.fec.vc.intparam.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, "VC FEC Interface Paramater MTU", HFILL }},
2283 {&hf_ldp_tlv_fec_vc_intparam_id,
2284 {"ID", "ldp.msg.tlv.fec.vc.intparam.id", FT_UINT8, BASE_HEX, VALS(fec_vc_interfaceparm), 0x0, "VC FEC Interface Paramater ID", HFILL }},
2286 {&hf_ldp_tlv_fec_vc_intparam_maxcatmcells,
2287 {"Number of Cells", "ldp.msg.tlv.fec.vc.intparam.maxatm", FT_UINT16, BASE_DEC, NULL, 0x0, "VC FEC Interface Param Max ATM Concat Cells", HFILL }},
2289 { &hf_ldp_tlv_fec_vc_intparam_desc,
2290 { "Description", "ldp.msg.tlv.fec.vc.intparam.desc", FT_STRING, BASE_DEC, NULL, 0, "VC FEC Interface Description", HFILL }},
2292 {&hf_ldp_tlv_fec_vc_intparam_cembytes,
2293 {"Payload Bytes", "ldp.msg.tlv.fec.vc.intparam.cembytes", FT_UINT16, BASE_DEC, NULL, 0x0, "VC FEC Interface Param CEM Payload Bytes", HFILL }},
2295 { &hf_ldp_tlv_lspid_act_flg,
2296 { "Action Indicator Flag", "ldp.msg.tlv.lspid.actflg", FT_UINT16, BASE_HEX, VALS(ldp_act_flg_vals), 0x000F, "Action Indicator Flag", HFILL}},
2298 { &hf_ldp_tlv_lspid_cr_lsp,
2299 { "Local CR-LSP ID", "ldp.msg.tlv.lspid.locallspid", FT_UINT16, BASE_HEX, NULL, 0x0, "Local CR-LSP ID", HFILL}},
2301 { &hf_ldp_tlv_lspid_ldpid,
2302 { "Ingress LSR Router ID", "ldp.msg.tlv.lspid.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Ingress LSR Router ID", HFILL}},
2304 { &hf_ldp_tlv_er_hop_loose,
2305 { "Loose route bit", "ldp.msg.tlv.er_hop.loose", FT_UINT24, BASE_HEX, VALS(ldp_loose_vals), 0x800000, "Loose route bit", HFILL}},
2307 { &hf_ldp_tlv_er_hop_prelen,
2308 { "Prefix length", "ldp.msg.tlv.er_hop.prefixlen", FT_UINT8, BASE_DEC, NULL, 0x0, "Prefix len", HFILL}},
2310 { &hf_ldp_tlv_er_hop_prefix4,
2311 { "IPv4 Address", "ldp.msg.tlv.er_hop.prefix4", FT_IPv4, BASE_DEC, NULL, 0x0, "IPv4 Address", HFILL}},
2312 { &hf_ldp_tlv_er_hop_prefix6,
2313 { "IPv6 Address", "ldp.msg.tlv.er_hop.prefix6", FT_IPv6, BASE_DEC, NULL, 0x0, "IPv6 Address", HFILL}},
2315 { &hf_ldp_tlv_er_hop_as,
2316 { "AS Number", "ldp.msg.tlv.er_hop.as", FT_UINT16, BASE_DEC, NULL, 0x0, "AS Number", HFILL}},
2318 { &hf_ldp_tlv_er_hop_cr_lsp,
2319 { "Local CR-LSP ID", "ldp.msg.tlv.er_hop.locallspid", FT_UINT16, BASE_DEC, NULL, 0x0, "Local CR-LSP ID", HFILL}},
2321 { &hf_ldp_tlv_er_hop_ldpid,
2322 { "Local CR-LSP ID", "ldp.msg.tlv.er_hop.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Local CR-LSP ID", HFILL}},
2324 { &hf_ldp_tlv_flags_reserv,
2325 { "Reserved", "ldp.msg.tlv.flags_reserv", FT_UINT8, BASE_HEX, NULL, 0xC0, "Reserved", HFILL}},
2327 { &hf_ldp_tlv_flags_pdr,
2328 { "PDR", "ldp.msg.tlv.flags_pdr", FT_BOOLEAN, 8, NULL, 0x1, "PDR", HFILL}},
2330 { &hf_ldp_tlv_flags_pbs,
2331 { "PBS", "ldp.msg.tlv.flags_pbs", FT_BOOLEAN, 8, NULL, 0x2, "PBS", HFILL}},
2333 { &hf_ldp_tlv_flags_cdr,
2334 { "CDR", "ldp.msg.tlv.flags_cdr", FT_BOOLEAN, 8, NULL, 0x4, "CDR", HFILL}},
2336 { &hf_ldp_tlv_flags_cbs,
2337 { "CBS", "ldp.msg.tlv.flags_cbs", FT_BOOLEAN, 8, NULL, 0x8, "CBS", HFILL}},
2339 { &hf_ldp_tlv_flags_ebs,
2340 { "EBS", "ldp.msg.tlv.flags_ebs", FT_BOOLEAN, 8, NULL, 0x10, "EBS", HFILL}},
2342 { &hf_ldp_tlv_flags_weight,
2343 { "Weight", "ldp.msg.tlv.flags_weight", FT_BOOLEAN, 8, NULL, 0x20, "Weight", HFILL}},
2345 { &hf_ldp_tlv_frequency,
2346 { "Frequency", "ldp.msg.tlv.frequency", FT_UINT8, BASE_DEC, VALS(freq_values), 0, "Frequency", HFILL}},
2348 { &hf_ldp_tlv_weight,
2349 { "Weight", "ldp.msg.tlv.weight", FT_UINT8, BASE_DEC, NULL, 0, "weight of the CR-LSP", HFILL}},
2352 { "PDR", "ldp.msg.tlv.pdr", FT_DOUBLE, BASE_NONE, NULL, 0, "Peak Data Rate", HFILL}},
2355 { "PBS", "ldp.msg.tlv.pbs", FT_DOUBLE, BASE_NONE, NULL, 0, "Peak Burst Size", HFILL}},
2358 { "CDR", "ldp.msg.tlv.cdr", FT_DOUBLE, BASE_NONE, NULL, 0, "Committed Data Rate", HFILL}},
2361 { "CBS", "ldp.msg.tlv.cbs", FT_DOUBLE, BASE_NONE, NULL, 0, "Committed Burst Size", HFILL}},
2364 { "EBS", "ldp.msg.tlv.ebs", FT_DOUBLE, BASE_NONE, NULL, 0, "Excess Burst Size", HFILL}},
2366 { &hf_ldp_tlv_set_prio,
2367 { "Set Prio", "ldp.msg.tlv.set_prio", FT_UINT8, BASE_DEC, NULL, 0, "LSP setup priority", HFILL}},
2369 { &hf_ldp_tlv_hold_prio,
2370 { "Hold Prio", "ldp.msg.tlv.hold_prio", FT_UINT8, BASE_DEC, NULL, 0, "LSP hold priority", HFILL}},
2372 { &hf_ldp_tlv_route_pinning,
2373 { "Route Pinning", "ldp.msg.tlv.route_pinning", FT_UINT32, BASE_DEC, VALS(route_pinning_vals), 0x80000000, "Route Pinning", HFILL}},
2375 { &hf_ldp_tlv_resource_class,
2376 { "Resource Class", "ldp.msg.tlv.resource_class", FT_UINT32, BASE_HEX, NULL, 0, "Resource Class (Color)", HFILL}},
2380 static gint *ett[] = {
2388 &ett_ldp_fec_vc_interfaceparam
2390 module_t *ldp_module;
2392 proto_ldp = proto_register_protocol("Label Distribution Protocol",
2395 proto_register_field_array(proto_ldp, hf, array_length(hf));
2396 proto_register_subtree_array(ett, array_length(ett));
2398 /* Register our configuration options for , particularly our port */
2400 ldp_module = prefs_register_protocol(proto_ldp, proto_reg_handoff_ldp);
2402 prefs_register_uint_preference(ldp_module, "tcp.port", "LDP TCP Port",
2403 "Set the TCP port for messages (if other"
2404 " than the default of 646)",
2405 10, &global_ldp_tcp_port);
2407 prefs_register_uint_preference(ldp_module, "udp.port", "LDP UDP Port",
2408 "Set the UDP port for messages (if other"
2409 " than the default of 646)",
2410 10, &global_ldp_udp_port);
2412 prefs_register_bool_preference(ldp_module, "desegment_ldp_messages",
2413 "Desegment all LDP messages spanning multiple TCP segments",
2414 "Whether the LDP dissector should desegment all messages spanning multiple TCP segments",
2418 /* The registration hand-off routine */
2420 proto_reg_handoff_ldp(void)
2422 static int ldp_prefs_initialized = FALSE;
2423 static dissector_handle_t ldp_tcp_handle, ldp_handle;
2425 if (!ldp_prefs_initialized) {
2427 ldp_tcp_handle = create_dissector_handle(dissect_ldp_tcp, proto_ldp);
2428 ldp_handle = create_dissector_handle(dissect_ldp, proto_ldp);
2430 ldp_prefs_initialized = TRUE;
2435 dissector_delete("tcp.port", tcp_port, ldp_tcp_handle);
2436 dissector_delete("udp.port", udp_port, ldp_handle);
2440 /* Set our port number for future use */
2442 tcp_port = global_ldp_tcp_port;
2443 udp_port = global_ldp_udp_port;
2445 dissector_add("tcp.port", global_ldp_tcp_port, ldp_tcp_handle);
2446 dissector_add("udp.port", global_ldp_udp_port, ldp_handle);