2 * Routines for LDP (RFC 3036) packet disassembly
4 * $Id: packet-ldp.c,v 1.50 2004/01/17 12:51:00 ulfl 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.
40 #include <epan/packet.h>
41 #include <epan/resolv.h>
45 #include "packet-frame.h"
46 #include "packet-diffserv-mpls-common.h"
48 #define TCP_PORT_LDP 646
49 #define UDP_PORT_LDP 646
51 void proto_reg_handoff_ldp(void);
53 static int proto_ldp = -1;
55 /* Delete the following if you do not use it, or add to it if you need */
56 static int hf_ldp_req = -1;
57 static int hf_ldp_rsp = -1;
58 static int hf_ldp_version = -1;
59 static int hf_ldp_pdu_len = -1;
60 static int hf_ldp_lsr = -1;
61 static int hf_ldp_ls_id = -1;
62 static int hf_ldp_msg_ubit = -1;
63 static int hf_ldp_msg_type = -1;
64 static int hf_ldp_msg_len = -1;
65 static int hf_ldp_msg_id = -1;
66 static int hf_ldp_msg_vendor_id = -1;
67 static int hf_ldp_msg_experiment_id = -1;
68 static int hf_ldp_tlv_value = -1;
69 static int hf_ldp_tlv_type = -1;
70 static int hf_ldp_tlv_unknown = -1;
71 static int hf_ldp_tlv_len = -1;
72 static int hf_ldp_tlv_val_hold = -1;
73 static int hf_ldp_tlv_val_target = -1;
74 static int hf_ldp_tlv_val_request = -1;
75 static int hf_ldp_tlv_val_res = -1;
76 static int hf_ldp_tlv_ipv4_taddr = -1;
77 static int hf_ldp_tlv_config_seqno = -1;
78 static int hf_ldp_tlv_ipv6_taddr = -1;
79 static int hf_ldp_tlv_fec_wc = -1;
80 static int hf_ldp_tlv_fec_af = -1;
81 static int hf_ldp_tlv_fec_len = -1;
82 static int hf_ldp_tlv_fec_pfval = -1;
83 static int hf_ldp_tlv_fec_hoval = -1;
84 static int hf_ldp_tlv_addrl_addr_family = -1;
85 static int hf_ldp_tlv_addrl_addr = -1;
86 static int hf_ldp_tlv_hc_value = -1;
87 static int hf_ldp_tlv_pv_lsrid = -1;
88 static int hf_ldp_tlv_generic_label = -1;
89 static int hf_ldp_tlv_atm_label_vbits = -1;
90 static int hf_ldp_tlv_atm_label_vpi = -1;
91 static int hf_ldp_tlv_atm_label_vci = -1;
92 static int hf_ldp_tlv_fr_label_len = -1;
93 static int hf_ldp_tlv_fr_label_dlci = -1;
94 static int hf_ldp_tlv_status_ebit = -1;
95 static int hf_ldp_tlv_status_fbit = -1;
96 static int hf_ldp_tlv_status_data = -1;
97 static int hf_ldp_tlv_status_msg_id = -1;
98 static int hf_ldp_tlv_status_msg_type = -1;
99 static int hf_ldp_tlv_extstatus_data = -1;
100 static int hf_ldp_tlv_returned_version = -1;
101 static int hf_ldp_tlv_returned_pdu_len = -1;
102 static int hf_ldp_tlv_returned_lsr = -1;
103 static int hf_ldp_tlv_returned_ls_id = -1;
104 static int hf_ldp_tlv_returned_msg_ubit = -1;
105 static int hf_ldp_tlv_returned_msg_type = -1;
106 static int hf_ldp_tlv_returned_msg_len = -1;
107 static int hf_ldp_tlv_returned_msg_id = -1;
108 static int hf_ldp_tlv_mac = -1;
109 static int hf_ldp_tlv_sess_ver = -1;
110 static int hf_ldp_tlv_sess_ka = -1;
111 static int hf_ldp_tlv_sess_advbit = -1;
112 static int hf_ldp_tlv_sess_ldetbit = -1;
113 static int hf_ldp_tlv_sess_pvlim = -1;
114 static int hf_ldp_tlv_sess_mxpdu = -1;
115 static int hf_ldp_tlv_sess_rxlsr = -1;
116 static int hf_ldp_tlv_sess_rxls = -1;
117 static int hf_ldp_tlv_sess_atm_merge = -1;
118 static int hf_ldp_tlv_sess_atm_lr = -1;
119 static int hf_ldp_tlv_sess_atm_dir = -1;
120 static int hf_ldp_tlv_sess_atm_minvpi = -1;
121 static int hf_ldp_tlv_sess_atm_maxvpi = -1;
122 static int hf_ldp_tlv_sess_atm_minvci = -1;
123 static int hf_ldp_tlv_sess_atm_maxvci = -1;
124 static int hf_ldp_tlv_sess_fr_merge = -1;
125 static int hf_ldp_tlv_sess_fr_lr = -1;
126 static int hf_ldp_tlv_sess_fr_dir = -1;
127 static int hf_ldp_tlv_sess_fr_len = -1;
128 static int hf_ldp_tlv_sess_fr_mindlci = -1;
129 static int hf_ldp_tlv_sess_fr_maxdlci = -1;
130 static int hf_ldp_tlv_lbl_req_msg_id = -1;
131 static int hf_ldp_tlv_vendor_id = -1;
132 static int hf_ldp_tlv_experiment_id = -1;
133 static int hf_ldp_tlv_fec_vc_controlword = -1;
134 static int hf_ldp_tlv_fec_vc_vctype = -1;
135 static int hf_ldp_tlv_fec_vc_infolength = -1;
136 static int hf_ldp_tlv_fec_vc_groupid = -1;
137 static int hf_ldp_tlv_fec_vc_vcid = -1;
138 static int hf_ldp_tlv_fec_vc_intparam_length = -1;
139 static int hf_ldp_tlv_fec_vc_intparam_mtu = -1;
140 static int hf_ldp_tlv_fec_vc_intparam_tdmbps = -1;
141 static int hf_ldp_tlv_fec_vc_intparam_id = -1;
142 static int hf_ldp_tlv_fec_vc_intparam_maxcatmcells = -1;
143 static int hf_ldp_tlv_fec_vc_intparam_desc = -1;
144 static int hf_ldp_tlv_fec_vc_intparam_cembytes = -1;
145 static int hf_ldp_tlv_fec_vc_intparam_vpnid_oui = -1;
146 static int hf_ldp_tlv_fec_vc_intparam_vpnid_index = -1;
147 static int hf_ldp_tlv_lspid_act_flg = -1;
148 static int hf_ldp_tlv_lspid_cr_lsp = -1;
149 static int hf_ldp_tlv_lspid_ldpid = -1;
150 static int hf_ldp_tlv_er_hop_loose = -1;
151 static int hf_ldp_tlv_er_hop_prelen = -1;
152 static int hf_ldp_tlv_er_hop_prefix4 = -1;
153 static int hf_ldp_tlv_er_hop_prefix6 = -1;
154 static int hf_ldp_tlv_er_hop_as = -1;
155 static int hf_ldp_tlv_er_hop_cr_lsp = -1;
156 static int hf_ldp_tlv_er_hop_ldpid = -1;
157 static int hf_ldp_tlv_flags_reserv = -1;
158 static int hf_ldp_tlv_flags_weight = -1;
159 static int hf_ldp_tlv_flags_ebs = -1;
160 static int hf_ldp_tlv_flags_cbs = -1;
161 static int hf_ldp_tlv_flags_cdr = -1;
162 static int hf_ldp_tlv_flags_pbs = -1;
163 static int hf_ldp_tlv_flags_pdr = -1;
164 static int hf_ldp_tlv_frequency = -1;
165 static int hf_ldp_tlv_pdr = -1;
166 static int hf_ldp_tlv_pbs = -1;
167 static int hf_ldp_tlv_cdr = -1;
168 static int hf_ldp_tlv_cbs = -1;
169 static int hf_ldp_tlv_ebs = -1;
170 static int hf_ldp_tlv_weight = -1;
171 static int hf_ldp_tlv_set_prio = -1;
172 static int hf_ldp_tlv_hold_prio = -1;
173 static int hf_ldp_tlv_route_pinning = -1;
174 static int hf_ldp_tlv_resource_class = -1;
175 static int hf_ldp_tlv_diffserv = -1;
176 static int hf_ldp_tlv_diffserv_type = -1;
177 static int hf_ldp_tlv_diffserv_mapnb = -1;
178 static int hf_ldp_tlv_diffserv_map = -1;
179 static int hf_ldp_tlv_diffserv_map_exp = -1;
180 static int hf_ldp_tlv_diffserv_phbid = -1;
181 static int hf_ldp_tlv_diffserv_phbid_dscp = -1;
182 static int hf_ldp_tlv_diffserv_phbid_code = -1;
183 static int hf_ldp_tlv_diffserv_phbid_bit14 = -1;
184 static int hf_ldp_tlv_diffserv_phbid_bit15 = -1;
185 static int ett_ldp = -1;
186 static int ett_ldp_header = -1;
187 static int ett_ldp_ldpid = -1;
188 static int ett_ldp_message = -1;
189 static int ett_ldp_tlv = -1;
190 static int ett_ldp_tlv_val = -1;
191 static int ett_ldp_fec = -1;
192 static int ett_ldp_fec_vc_interfaceparam = -1;
193 static int ett_ldp_diffserv_map = -1;
194 static int ett_ldp_diffserv_map_phbid = -1;
196 static int tcp_port = 0;
197 static int udp_port = 0;
199 /* desegmentation of LDP over TCP */
200 static gboolean ldp_desegment = FALSE;
202 /* Add your functions here */
204 static guint32 global_ldp_tcp_port = TCP_PORT_LDP;
205 static guint32 global_ldp_udp_port = UDP_PORT_LDP;
208 * The following define all the TLV types I know about
211 #define TLV_FEC 0x0100
212 #define TLV_ADDRESS_LIST 0x0101
213 #define TLV_HOP_COUNT 0x0103
214 #define TLV_PATH_VECTOR 0x0104
215 #define TLV_GENERIC_LABEL 0x0200
216 #define TLV_ATM_LABEL 0x0201
217 #define TLV_FRAME_LABEL 0x0202
218 #define TLV_STATUS 0x0300
219 #define TLV_EXTENDED_STATUS 0x0301
220 #define TLV_RETURNED_PDU 0x0302
221 #define TLV_RETURNED_MESSAGE 0x0303
222 #define TLV_COMMON_HELLO_PARMS 0x0400
223 #define TLV_IPV4_TRANSPORT_ADDRESS 0x0401
224 #define TLV_CONFIGURATION_SEQNO 0x0402
225 #define TLV_IPV6_TRANSPORT_ADDRESS 0x0403
226 #define TLV_MAC 0x0404
227 #define TLV_COMMON_SESSION_PARMS 0x0500
228 #define TLV_ATM_SESSION_PARMS 0x0501
229 #define TLV_FRAME_RELAY_SESSION_PARMS 0x0502
230 #define TLV_LABEL_REQUEST_MESSAGE_ID 0x0600
231 #define TLV_ER 0x0800
232 #define TLV_ER_HOP_IPV4 0x0801
233 #define TLV_ER_HOP_IPV6 0x0802
234 #define TLV_ER_HOP_AS 0x0803
235 #define TLV_ER_HOP_LSPID 0x0804
236 #define TLV_TRAFFIC_PARAM 0x0810
237 #define TLV_PREEMPTION 0x0820
238 #define TLV_LSPID 0x0821
239 #define TLV_RESOURCE_CLASS 0x0822
240 #define TLV_ROUTE_PINNING 0x0823
241 #define TLV_DIFFSERV 0x0901
242 #define TLV_VENDOR_PRIVATE_START 0x3E00
243 #define TLV_VENDOR_PRIVATE_END 0x3EFF
244 #define TLV_EXPERIMENTAL_START 0x3F00
245 #define TLV_EXPERIMENTAL_END 0x3FFF
247 static const value_string tlv_type_names[] = {
248 { TLV_FEC, "Forwarding Equivalence Classes TLV" },
249 { TLV_ADDRESS_LIST, "Address List TLV"},
250 { TLV_HOP_COUNT, "Hop Count TLV"},
251 { TLV_PATH_VECTOR, "Path Vector TLV"},
252 { TLV_GENERIC_LABEL, "Generic Label TLV"},
253 { TLV_ATM_LABEL, "ATM Label TLV"},
254 { TLV_FRAME_LABEL, "Frame Label TLV"},
255 { TLV_STATUS, "Status TLV"},
256 { TLV_EXTENDED_STATUS, "Extended Status TLV"},
257 { TLV_RETURNED_PDU, "Returned PDU TLV"},
258 { TLV_RETURNED_MESSAGE, "Returned Message TLV"},
259 { TLV_COMMON_HELLO_PARMS, "Common Hello Parameters TLV"},
260 { TLV_IPV4_TRANSPORT_ADDRESS, "IPv4 Transport Address TLV"},
261 { TLV_CONFIGURATION_SEQNO, "Configuration Sequence Number TLV"},
262 { TLV_IPV6_TRANSPORT_ADDRESS, "IPv6 Transport Address TLV"},
263 { TLV_MAC, "MAC TLV"},
264 { TLV_COMMON_SESSION_PARMS, "Common Session Parameters TLV"},
265 { TLV_ATM_SESSION_PARMS, "ATM Session Parameters TLV"},
266 { TLV_FRAME_RELAY_SESSION_PARMS, "Frame Relay Session Parameters TLV"},
267 { TLV_LABEL_REQUEST_MESSAGE_ID, "Label Request Message ID TLV"},
268 { TLV_LSPID, "LSP ID TLV"},
269 { TLV_ER, "Explicit route TLV"},
270 { TLV_ER_HOP_IPV4, "ER hop IPv4 prefix TLV"},
271 { TLV_ER_HOP_IPV6, "ER hop IPv6 prefix TLV"},
272 { TLV_ER_HOP_AS, "ER hop Autonomous system number prefix TLV"},
273 { TLV_TRAFFIC_PARAM, "Traffic parameters TLV"},
274 { TLV_PREEMPTION, "Preemption TLV"},
275 { TLV_ER_HOP_LSPID, "ER hop LSPID prefix TLV"},
276 { TLV_RESOURCE_CLASS, "Resource Class (Color) TLV"},
277 { TLV_ROUTE_PINNING, "Route Pinning TLV"},
278 { TLV_DIFFSERV, "Diff-Serv TLV"},
279 { TLV_VENDOR_PRIVATE_START, "Vendor Private TLV"},
280 { TLV_EXPERIMENTAL_START, "Experimental TLV"},
285 * The following define all the message types I know about
288 #define LDP_NOTIFICATION 0x0001
289 #define LDP_HELLO 0x0100
290 #define LDP_INITIALIZATION 0x0200
291 #define LDP_KEEPALIVE 0x0201
292 #define LDP_ADDRESS 0x0300
293 #define LDP_ADDRESS_WITHDRAWAL 0x0301
294 #define LDP_LABEL_MAPPING 0x0400
295 #define LDP_LABEL_REQUEST 0x0401
296 #define LDP_LABEL_WITHDRAWAL 0x0402
297 #define LDP_LABEL_RELEASE 0x0403
298 #define LDP_LABEL_ABORT_REQUEST 0x0404
299 #define LDP_VENDOR_PRIVATE_START 0x3E00
300 #define LDP_VENDOR_PRIVATE_END 0x3EFF
301 #define LDP_EXPERIMENTAL_MESSAGE_START 0x3F00
302 #define LDP_EXPERIMENTAL_MESSAGE_END 0x3FFF
304 static const value_string ldp_message_types[] = {
305 {LDP_NOTIFICATION, "Notification Message"},
306 {LDP_HELLO, "Hello Message"},
307 {LDP_INITIALIZATION, "Initialization Message"},
308 {LDP_KEEPALIVE, "Keep Alive Message"},
309 {LDP_ADDRESS, "Address Message"},
310 {LDP_ADDRESS_WITHDRAWAL, "Address Withdrawal Message"},
311 {LDP_LABEL_MAPPING, "Label Mapping Message"},
312 {LDP_LABEL_REQUEST, "Label Request Message"},
313 {LDP_LABEL_WITHDRAWAL, "Label Withdrawal Message"},
314 {LDP_LABEL_RELEASE, "Label Release Message"},
315 {LDP_LABEL_ABORT_REQUEST, "Label Abort Request Message"},
316 {LDP_VENDOR_PRIVATE_START, "Vendor-Private Message"},
317 {LDP_EXPERIMENTAL_MESSAGE_START, "Experimental Message"},
321 static const true_false_string ldp_message_ubit = {
323 "Unknown bit not set"
326 static const true_false_string hello_targeted_vals = {
331 static const value_string tlv_unknown_vals[] = {
332 {0, "Known TLV, do not Forward"},
333 {1, "Known TLV, do Forward"},
334 {2, "Unknown TLV, do not Forward"},
335 {3, "Unknown TLV, do Forward"},
339 #define WILDCARD_FEC 1
343 #define VC_FEC 0x80 /* draft-martini-l2circuit-trans-mpls */
345 static const value_string fec_types[] = {
346 {WILDCARD_FEC, "Wildcard FEC"},
347 {PREFIX_FEC, "Prefix FEC"},
348 {HOST_FEC, "Host Address FEC"},
349 {CRLSP_FEC, "CR LSP FEC"},
350 {VC_FEC, "Virtual Circuit FEC"},
355 static const value_string fec_vc_types_vals[] = {
356 {0x0001, "Frame Relay DLCI"},
357 {0x0002, "ATM VCC transport"},
358 {0x0003, "ATM VPC transport"},
359 {0x0004, "Ethernet VLAN"},
360 {0x0005, "Ethernet"},
363 {0x0008, "SONET/SDH Circuit Emulation Service"},
364 {0x0009, "ATM n-to-one VCC cell transport"},
365 {0x000A, "ATM n-to one VPC cell transport"},
366 {0x000B, "IP layer2 transport"},
367 {0x000C, "ATM one-to-one VCC Cell Mode"},
368 {0x000D, "ATM one-to-one VPC Cell Mode"},
369 {0x000E, "ATM AAL5 PDU VCC transport"},
370 {0x000F, "Frame-Relay Port mode"},
371 {0x0010, "SONET/SDH Circuit Emulation over Packet"},
376 #define FEC_VC_INTERFACEPARAM_MTU 0x01
377 #define FEC_VC_INTERFACEPARAM_MAXCATMCELLS 0x02
378 #define FEC_VC_INTERFACEPARAM_DESCRIPTION 0x03
379 #define FEC_VC_INTERFACEPARAM_CEMBYTES 0x04
380 #define FEC_VC_INTERFACEPARAM_CEMOPTIONS 0x05
381 #define FEC_VC_INTERFACEPARAM_VPNID 0x06
382 #define FEC_VC_INTERFACEPARAM_TDMBPS 0x07
383 #define FEC_VC_INTERFACEPARAM_FRDLCILEN 0x08
387 static const value_string fec_vc_interfaceparm[] = {
388 {FEC_VC_INTERFACEPARAM_MTU, "MTU"},
389 {FEC_VC_INTERFACEPARAM_MAXCATMCELLS, "Max Concatenated ATM cells"},
390 {FEC_VC_INTERFACEPARAM_DESCRIPTION, "Interface Description"},
391 {FEC_VC_INTERFACEPARAM_CEMBYTES, "CEM Payload Bytes"},
392 {FEC_VC_INTERFACEPARAM_CEMOPTIONS, "CEM options"},
393 {FEC_VC_INTERFACEPARAM_VPNID, "VPN Id"},
394 {FEC_VC_INTERFACEPARAM_TDMBPS, "CEP/TDM bit-rate"},
395 {FEC_VC_INTERFACEPARAM_FRDLCILEN, "Frame-Relay DLCI Length"},
399 static const true_false_string fec_vc_cbit = {
400 "Contorl Word Present",
401 "Control Word NOT Present"
406 static const value_string tlv_atm_merge_vals[] = {
407 {0, "Merge not supported"},
408 {1, "VP merge supported"},
409 {2, "VC merge supported"},
410 {3, "VP & VC merge supported"},
414 static const value_string tlv_atm_vbits_vals[] = {
415 {0, "VPI & VCI Significant"},
416 {1, "Only VPI Significant"},
417 {2, "Only VCI Significant"},
418 {3, "VPI & VCI not Significant, nonsense"},
422 static const value_string tlv_fr_merge_vals[] = {
423 {0, "Merge not supported"},
424 {1, "Merge supported"},
430 static const value_string tlv_fr_len_vals[] = {
438 static const value_string ldp_act_flg_vals[] = {
439 {0, "indicates initial LSP setup"},
440 {1, "indicates modify LSP"},
444 static const value_string route_pinning_vals[] = {
445 {0, "route pinning is not requested"},
446 {1, "route pinning is requested"},
450 static const value_string diffserv_type_vals[] = {
456 static const value_string ldp_loose_vals[] = {
462 static const true_false_string tlv_negotiable = {
467 static const value_string freq_values[] = {
474 static const true_false_string tlv_atm_dirbit = {
475 "Bidirectional capability",
476 "Unidirectional capability"
479 static const true_false_string hello_requested_vals = {
480 "Source requests periodic hellos",
481 "Source does not request periodic hellos"
484 static const true_false_string tlv_sess_advbit_vals = {
485 "Downstream On Demand proposed",
486 "Downstream Unsolicited proposed"
489 static const true_false_string tlv_sess_ldetbit_vals = {
490 "Loop Detection Enabled",
491 "Loop Detection Disabled"
494 static const true_false_string tlv_status_ebit = {
495 "Fatal Error Notification",
496 "Advisory Notification"
499 static const true_false_string tlv_status_fbit = {
500 "Notification should be Forwarded",
501 "Notification should NOT be Forwarded"
504 static const value_string tlv_status_data[] = {
506 {1, "Bad LDP Identifier"},
507 {2, "Bad Protocol Version"},
508 {3, "Bad PDU Length"},
509 {4, "Unknown Message Type"},
510 {5, "Bad Message Length"},
512 {7, "Bad TLV Length"},
513 {8, "Malformed TLV Value"},
514 {9, "Hold Timer Expired"},
516 {11, "Loop Detected"},
519 {14, "No Label Resources"},
520 {15, "Label Resources / Available"},
521 {16, "Session Rejected / No Hello"},
522 {17, "Session Rejected / Parameters Advertisement Mode"},
523 {18, "Session Rejected / Parameters Max PDU Length"},
524 {19, "Session Rejected / Parameters Label Range"},
525 {20, "KeepAlive Timer Expired"},
526 {21, "Label Request Aborted"},
527 {22, "Missing Message Parameters"},
528 {23, "Unsoported Address Family"},
529 {24, "Session Rejected / Bad KeepAlive Time"},
530 {25, "Internal Error"},
531 {0x01000001,"Unexpected Diff-Serv TLV"},
532 {0x01000002,"Unsupported PHB"},
533 {0x01000003,"Invalid EXP<->PHB Mapping"},
534 {0x01000004,"Unsupported PSC"},
535 {0x01000005,"Per-LSP context allocation failure"},
536 {0x04000001,"Bad Explicit Routing TLV Error"},
537 {0x04000002,"Bad Strict Node Error"},
538 {0x04000003,"Bad Strict Node Error"},
539 {0x04000004,"Bad Initial ER-Hop Error"},
540 {0x04000005,"Resource Unavailable"},
541 {0x04000006,"Traffic Parameters Unavailable"},
542 {0x04000007,"LSP Preempted"},
543 {0x04000008,"Modify Request Not Supported"},
544 {0x20000001,"Illegal C-Bit"},
545 {0x20000002,"Wrong C-Bit"},
549 /* Define storage class for a string handler function
550 * with a const guint8 * argument, and returning a gchar *
552 typedef gchar *(string_handler_func)(const guint8 *);
554 /* Default handler for address to string conversion */
556 default_str_handler(const guint8 * bytes _U_)
558 return "<Support for this Address Family not implemented>";
561 /* Dissect FEC TLV */
564 dissect_tlv_fec(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
566 proto_tree *ti=NULL, *val_tree=NULL, *fec_tree=NULL, *vcintparam_tree=NULL;
567 guint16 family, ix=1, ax;
568 guint8 addr_size=0, *addr, implemented, prefix_len_octets, prefix_len, host_len, vc_len;
570 string_handler_func *str_handler = default_str_handler;
574 ti=proto_tree_add_text(tree, tvb, offset, rem, "FEC Elements");
575 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
576 if(val_tree == NULL) return;
579 switch (tvb_get_guint8(tvb, offset)) {
582 ti = proto_tree_add_text(val_tree, tvb, offset, 1, "FEC Element %u", ix);
583 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
584 if(fec_tree == NULL) return;
585 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc,tvb, offset, 1, FALSE);
591 if( rem < 4 ){/*not enough*/
592 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
595 family=tvb_get_ntohs(tvb, offset+1);
596 prefix_len=tvb_get_guint8(tvb, offset+3);
597 prefix_len_octets=(prefix_len+7)/8;
601 case AFNUM_INET: /*IPv4*/
603 str_handler=ip_to_str;
605 case AFNUM_INET6: /*IPv6*/
607 str_handler = (string_handler_func *) ip6_to_str;
617 noctets= rem>4+prefix_len_octets?4+prefix_len_octets:rem;
618 proto_tree_add_text(val_tree, tvb, offset, noctets,"Support for Address Family not implemented");
624 if( rem < 4+MIN(addr_size, prefix_len_octets) ){
625 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
629 /*Add a subtree for this*/
630 ti = proto_tree_add_text(val_tree, tvb, offset, 4+MIN(addr_size, prefix_len_octets), "FEC Element %u", ix);
631 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
632 if(fec_tree == NULL) return;
633 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
636 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
639 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
643 if( addr_size < prefix_len_octets) {
646 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"));
650 if( (addr=g_malloc0(addr_size)) == NULL ){
651 /*big big trouble, no mem or bad addr_size*/
652 fprintf(stderr, "packet-ldp: dissect_tlv_fec() malloc failed\n");
656 for(ax=0; ax+1 <= prefix_len_octets; ax++)
657 addr[ax]=tvb_get_guint8(tvb, offset+ax);
659 addr[ax-1] = addr[ax-1]&(0xFF<<(8-prefix_len%8));
661 str = str_handler((const guint8 *)addr);
662 proto_tree_add_string_format(fec_tree, hf_ldp_tlv_fec_pfval, tvb, offset, prefix_len_octets, str, "Prefix: %s", str);
664 offset += prefix_len_octets;
665 rem -= 4+prefix_len_octets;
670 if( rem < 4 ){/*not enough*/
671 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
674 family=tvb_get_ntohs(tvb, offset+1);
675 host_len=tvb_get_guint8(tvb, offset+3);
679 case AFNUM_INET: /*IPv4*/
681 str_handler=ip_to_str;
683 case AFNUM_INET6: /*IPv6*/
685 str_handler = (string_handler_func *) ip6_to_str;
695 noctets= rem>4+host_len?4+host_len:rem;
696 proto_tree_add_text(val_tree, tvb, offset, noctets,"Support for Address Family not implemented");
702 if( rem < 4+addr_size ){
703 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
707 /*Add a subtree for this*/
708 ti = proto_tree_add_text(val_tree, tvb, offset, 4+addr_size, "FEC Element %u", ix);
709 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
710 if(fec_tree == NULL) return;
711 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
714 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_af, tvb, offset, 2, FALSE);
717 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_len, tvb, offset, 1, FALSE);
721 if( addr_size != host_len) {
724 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"));
728 if( (addr=g_malloc0(addr_size)) == NULL ){
729 /*big big xtrouble, no mem or bad addr_size*/
730 fprintf(stderr, "packet-ldp: dissect_tlv_fec() malloc failed\n");
734 for(ax=0; ax+1 <= host_len; ax++)
735 addr[ax]=tvb_get_guint8(tvb, offset+ax);
737 str = str_handler((const guint8 *)addr);
738 proto_tree_add_string_format(fec_tree, hf_ldp_tlv_fec_hoval, tvb, offset, host_len, str, "Address: %s", str);
746 if( rem < 8 ){/*not enough bytes for a minimal VC_FEC*/
747 proto_tree_add_text(val_tree, tvb, offset, rem, "Error in FEC Element %u", ix);
750 vc_len = tvb_get_guint8 (tvb, offset+3);
753 ti = proto_tree_add_text(val_tree, tvb, offset, 8+vc_len, "FEC Element %u", ix);
754 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
755 if(fec_tree == NULL) return;
756 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_wc, tvb, offset, 1, FALSE);
757 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_controlword, tvb, offset+1, 1, FALSE);
758 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_vctype, tvb, offset+1, 2, FALSE);
759 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_infolength, tvb, offset+3,1,FALSE);
760 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_groupid,tvb, offset +4, 4, FALSE);
764 if ( (vc_len > 3) && ( rem > 3 ) ) { /* there is enough room for vcid */
765 proto_tree_add_item(fec_tree, hf_ldp_tlv_fec_vc_vcid,tvb, offset, 4, FALSE);
766 proto_item_append_text (ti," VCID: %u",tvb_get_ntohl(tvb,offset));
769 proto_tree_add_text(val_tree,tvb,offset +4, 8 +vc_len, "VC FEC size format error");
776 while ( (vc_len > 1) && (rem > 1) ) { /* enough to include id and length */
777 intparam_len = tvb_get_guint8(tvb, offset+1);
778 ti = proto_tree_add_text(fec_tree, tvb, offset, intparam_len, "Interface Paramameter");
779 vcintparam_tree = proto_item_add_subtree(ti, ett_ldp_fec_vc_interfaceparam);
780 if(vcintparam_tree == NULL) return;
781 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_id,tvb,offset,1,FALSE);
782 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_length,tvb, offset+1, 1, FALSE);
783 if ( (vc_len -intparam_len) <0 && (rem -intparam_len) <0 ) { /* error condition */
784 proto_tree_add_text(vcintparam_tree, tvb, offset +2, MIN(vc_len,rem), "malformed data");
787 switch (tvb_get_guint8(tvb, offset)) {
788 case FEC_VC_INTERFACEPARAM_MTU:
789 proto_item_append_text(ti,": MTU %u", tvb_get_ntohs(tvb,offset+2));
790 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_mtu,tvb, offset+2, 2, FALSE);
792 case FEC_VC_INTERFACEPARAM_TDMBPS:
793 proto_item_append_text(ti,": BPS %u", tvb_get_ntohs(tvb,offset+2));
794 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_tdmbps,tvb, offset+2, 2, FALSE);
796 case FEC_VC_INTERFACEPARAM_MAXCATMCELLS:
797 proto_item_append_text(ti,": Max ATM Concat Cells %u", tvb_get_ntohs(tvb,offset+2));
798 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_maxcatmcells,tvb, offset+2, 2, FALSE);
800 case FEC_VC_INTERFACEPARAM_DESCRIPTION:
801 proto_item_append_text(ti,": Description");
802 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_desc,tvb, offset+2, (intparam_len -2), FALSE);
804 case FEC_VC_INTERFACEPARAM_CEMBYTES:
805 proto_item_append_text(ti,": CEM Payload Bytes %u", tvb_get_ntohs(tvb,offset+2));
806 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_cembytes,tvb, offset+2, 2, FALSE);
808 case FEC_VC_INTERFACEPARAM_VPNID:
809 /* draft-lasserre-tls-mpls-00.txt */
810 proto_item_append_text(ti,": VPN Id");
811 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_vpnid_oui, tvb, offset+2, 3, FALSE);
812 proto_tree_add_item(vcintparam_tree,hf_ldp_tlv_fec_vc_intparam_vpnid_index, tvb, offset+5, 4, FALSE);
814 case FEC_VC_INTERFACEPARAM_CEMOPTIONS:
815 /* draft-malis-sonet-ces-mpls CEM options still undefined */
816 default: /* unknown */
817 proto_item_append_text(ti," unknown");
818 proto_tree_add_text(vcintparam_tree,tvb, offset+2, (intparam_len -2), "Unknown data");
823 vc_len -= intparam_len;
824 offset += intparam_len;
828 default: /* Unknown */
829 /* XXX - do all FEC's have a length that's a multiple of 4? */
830 /* Hmmm, don't think so. Will check. RJS. */
831 /* If we don't know its structure, we have to exit */
832 ti = proto_tree_add_text(val_tree, tvb, offset, 4, "FEC Element %u", ix);
833 fec_tree = proto_item_add_subtree(ti, ett_ldp_fec);
834 if(fec_tree == NULL) return;
835 proto_tree_add_text(fec_tree, tvb, offset, rem, "Unknown FEC TLV type");
843 /* Dissect Address List TLV */
846 dissect_tlv_address_list(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
848 proto_tree *ti = NULL, *val_tree = NULL;
850 guint8 addr_size, *addr;
851 string_handler_func *str_handler = default_str_handler;
856 proto_tree_add_text(tree, tvb, offset, rem,
857 "Error processing Address List TLV: length is %d, should be >= 2",
862 family=tvb_get_ntohs(tvb, offset);
863 proto_tree_add_item(tree, hf_ldp_tlv_addrl_addr_family, tvb,
866 case AFNUM_INET: /*IPv4*/
868 str_handler=ip_to_str;
870 case AFNUM_INET6: /*IPv6*/
872 str_handler = (string_handler_func *) ip6_to_str;
875 proto_tree_add_text(tree, tvb, offset+2, rem-2,
876 "Support for Address Family not implemented");
881 ti=proto_tree_add_text(tree, tvb, offset, rem, "Addresses");
882 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
884 if(val_tree == NULL) return;
885 if( (addr=g_malloc(addr_size)) == NULL ){
887 fprintf(stderr, "packet-ldp: dissect_tlv_address_list() malloc failed\n");
891 for(ix=1; rem >= addr_size; ix++, offset += addr_size,
893 if( (tvb_memcpy(tvb, addr, offset, addr_size))
897 str = str_handler((const guint8 *)addr);
898 proto_tree_add_string_format(val_tree,
899 hf_ldp_tlv_addrl_addr, tvb, offset, addr_size, str,
900 "Address %u: %s", ix, str);
903 proto_tree_add_text(val_tree, tvb, offset, rem,
904 "Error processing TLV: Extra data at end of address list");
909 /* Dissect Path Vector TLV */
912 dissect_tlv_path_vector(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
914 proto_tree *ti = NULL, *val_tree = NULL;
919 ti=proto_tree_add_text(tree, tvb, offset, rem, "LSR IDs");
920 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
922 if(val_tree == NULL) return;
924 for(ix=1; rem >= 4; ix++, offset += 4, rem -= 4) {
925 tvb_memcpy(tvb, (guint8 *)&addr, offset, 4);
926 proto_tree_add_ipv4_format(val_tree,
927 hf_ldp_tlv_pv_lsrid, tvb, offset, 4,
928 addr, "LSR Id %u: %s", ix,
929 ip_to_str((guint8 *)&addr));
932 proto_tree_add_text(val_tree, tvb, offset, rem,
933 "Error processing TLV: Extra data at end of path vector");
937 /* Dissect ATM Label TLV */
940 dissect_tlv_atm_label(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
942 proto_tree *ti = NULL, *val_tree = NULL;
947 proto_tree_add_text(tree, tvb, offset, rem,
948 "Error processing ATM Label TLV: length is %d, should be 4",
952 ti=proto_tree_add_text(tree, tvb, offset, rem, "ATM Label");
953 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
954 if(val_tree == NULL) return;
956 proto_tree_add_item(val_tree, hf_ldp_tlv_atm_label_vbits, tvb, offset, 1, FALSE);
958 id=tvb_get_ntohs(tvb, offset)&0x0FFF;
959 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_atm_label_vpi, tvb, offset, 2, id, "VPI: %u", id);
961 id=tvb_get_ntohs(tvb, offset+2);
962 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_atm_label_vci, tvb, offset+2, 2, id, "VCI: %u", id);
966 /* Dissect FRAME RELAY Label TLV */
969 dissect_tlv_frame_label(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
971 proto_tree *ti = NULL, *val_tree = NULL;
977 proto_tree_add_text(tree, tvb, offset, rem,
978 "Error processing Frame Relay Label TLV: length is %d, should be 4",
982 ti=proto_tree_add_text(tree, tvb, offset, rem, "Frame Relay Label");
983 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
984 if(val_tree == NULL) return;
986 len=(guint8)(tvb_get_ntohs(tvb, offset)>>7) & 0x03;
987 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);
989 id=tvb_get_ntoh24(tvb, offset+1)&0x7FFFFF;
990 proto_tree_add_uint_format(val_tree,
991 hf_ldp_tlv_fr_label_dlci, tvb, offset+1, 3, id, "DLCI: %u", id);
995 /* Dissect STATUS TLV */
998 dissect_tlv_status(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1000 proto_tree *ti = NULL, *val_tree = NULL;
1005 proto_tree_add_text(tree, tvb, offset, rem,
1006 "Error processing Status TLV: length is %d, should be 10",
1011 ti=proto_tree_add_text(tree, tvb, offset, rem, "Status");
1012 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1013 if(val_tree == NULL) return;
1015 proto_tree_add_item(val_tree, hf_ldp_tlv_status_ebit, tvb, offset, 1, FALSE);
1016 proto_tree_add_item(val_tree, hf_ldp_tlv_status_fbit, tvb, offset, 1, FALSE);
1018 data=tvb_get_ntohl(tvb, offset)&0x3FFFFFFF;
1019 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);
1021 proto_tree_add_item(val_tree, hf_ldp_tlv_status_msg_id, tvb, offset+4, 4, FALSE);
1022 proto_tree_add_item(val_tree, hf_ldp_tlv_status_msg_type, tvb, offset+8, 2, FALSE);
1026 /* Dissect Returned PDU TLV */
1029 dissect_tlv_returned_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1031 proto_tree *ti = NULL, *val_tree = NULL;
1035 proto_tree_add_text(tree, tvb, offset, rem,
1036 "Error processing Returned PDU TLV: length is %d, should be >= 10",
1040 ti=proto_tree_add_text(tree, tvb, offset, rem, "Returned PDU");
1041 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1042 if(val_tree == NULL) return;
1044 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_version, tvb, offset, 2, FALSE);
1045 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_pdu_len, tvb, offset+2, 2, FALSE);
1046 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_lsr, tvb, offset+4, 4, FALSE);
1047 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_ls_id, tvb, offset+8, 2, FALSE);
1052 /*XXX - dissect returned pdu data*/
1053 proto_tree_add_text(val_tree, tvb, offset, rem, "Returned PDU Data");
1058 /* Dissect Returned MESSAGE TLV */
1061 dissect_tlv_returned_message(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1063 proto_tree *ti = NULL, *val_tree = NULL;
1068 proto_tree_add_text(tree, tvb, offset, rem,
1069 "Error processing Returned Message TLV: length is %d, should be >= 4",
1073 ti=proto_tree_add_text(tree, tvb, offset, rem, "Returned Message");
1074 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1075 if(val_tree == NULL) return;
1077 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_ubit, tvb, offset, 1, FALSE);
1079 type=tvb_get_ntohs(tvb, offset)&0x7FFF;
1080 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);
1082 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_len, tvb, offset+2, 2, FALSE);
1086 if( rem >= 4 ) { /*have msg_id*/
1087 proto_tree_add_item(val_tree, hf_ldp_tlv_returned_msg_id, tvb, offset, 4, FALSE);
1093 /*XXX - dissect returned msg parameters*/
1094 proto_tree_add_text(val_tree, tvb, offset, rem, "Returned Message Parameters");
1099 /* Dissect the common hello params */
1103 dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1105 dissect_tlv_common_hello_parms(tvbuff_t *tvb, guint offset, proto_tree *tree)
1109 proto_tree *ti = NULL;
1111 proto_tree *val_tree = NULL;
1115 ti = proto_tree_add_item(tree, hf_ldp_tlv_value, tvb, offset, rem, FALSE);
1116 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1117 if(val_tree == NULL) return;
1121 proto_tree_add_item(val_tree, hf_ldp_tlv_val_hold, tvb, offset, 2, FALSE);
1122 proto_tree_add_item(val_tree, hf_ldp_tlv_val_target, tvb, offset + 2, 2, FALSE);
1123 proto_tree_add_item(val_tree, hf_ldp_tlv_val_request, tvb, offset + 2, 2, FALSE);
1124 proto_tree_add_item(val_tree, hf_ldp_tlv_val_res, tvb, offset + 2, 2, FALSE);
1128 /* Dissect MAC TLV */
1131 dissect_tlv_mac(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1133 proto_tree *ti = NULL, *val_tree = NULL;
1138 ti=proto_tree_add_text(tree, tvb, offset, rem, "MAC addresses");
1139 val_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1141 if(val_tree == NULL) return;
1143 for(ix=1; rem >= 6; ix++, offset += 6, rem -= 6) {
1144 mac = tvb_get_ptr(tvb, offset, 6);
1145 proto_tree_add_ether(val_tree,
1146 hf_ldp_tlv_mac, tvb, offset, 6, mac);
1149 proto_tree_add_text(val_tree, tvb, offset, rem,
1150 "Error processing TLV: Extra data at end of path vector");
1156 /* Dissect the common session params */
1159 dissect_tlv_common_session_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1161 proto_tree *ti = NULL, *val_tree = NULL;
1164 if( rem != 14) { /*length of Comm Sess Parms tlv*/
1165 proto_tree_add_text(tree, tvb, offset, rem,
1166 "Error processing Common Session Parameters TLV: length is %d, should be 14",
1170 ti = proto_tree_add_text(tree, tvb, offset, rem, "Parameters");
1171 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1173 if(val_tree != NULL) {
1174 /*Protocol Version*/
1175 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ver, tvb,offset, 2, FALSE);
1178 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ka, tvb,offset + 2, 2, FALSE);
1181 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_advbit,tvb, offset + 4, 1, FALSE);
1184 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_ldetbit,tvb, offset + 4, 1, FALSE);
1186 /*Path Vector Limit*/
1187 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_pvlim,tvb, offset + 5, 1, FALSE);
1190 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_mxpdu,tvb, offset + 6, 2, FALSE);
1193 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_rxlsr,tvb, offset + 8, 4, FALSE);
1196 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_rxls,tvb, offset + 12, 2, FALSE);
1201 /* Dissect the atm session params */
1204 dissect_tlv_atm_session_parms(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1206 proto_tree *ti = NULL, *val_tree = NULL, *lbl_tree = NULL;
1212 proto_tree_add_text(tree, tvb, offset, rem,
1213 "Error processing ATM Parameters TLV: length is %d, should be >= 4",
1218 ti = proto_tree_add_text(tree, tvb, offset, rem,"ATM Parameters");
1219 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1221 if(val_tree != NULL) {
1222 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_atm_merge,tvb, offset, 1, FALSE);
1224 /*get the number of label ranges*/
1225 numlr=(tvb_get_guint8(tvb, offset)>>2) & 0x0F;
1226 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_sess_atm_lr,
1227 tvb, offset, 1, numlr, "Number of Label Range components: %u",
1230 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_atm_dir,tvb, offset, 1, FALSE);
1232 /*move into range components*/
1235 ti = proto_tree_add_text(val_tree, tvb, offset, rem,"ATM Label Range Components");
1238 val_tree=proto_item_add_subtree(ti,ett_ldp_tlv_val);
1239 if( ! val_tree ) return;
1241 /*now dissect ranges*/
1242 for(ix=1; numlr > 0 && rem >= 8; ix++, rem-=8, numlr--) {
1243 ti=proto_tree_add_text(val_tree, tvb, offset, 8,
1244 "ATM Label Range Component %u", ix);
1245 lbl_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1247 if( lbl_tree == NULL ) break;
1249 id=tvb_get_ntohs(tvb, offset)&0x0FFF;
1250 proto_tree_add_uint_format(lbl_tree,
1251 hf_ldp_tlv_sess_atm_minvpi,
1253 id, "Minimum VPI: %u", id);
1254 id=tvb_get_ntohs(tvb, offset+4)&0x0FFF;
1255 proto_tree_add_uint_format(lbl_tree,
1256 hf_ldp_tlv_sess_atm_maxvpi,
1257 tvb, (offset+4), 2, id,
1258 "Maximum VPI: %u", id);
1260 id=tvb_get_ntohs(tvb, offset+2);
1261 proto_tree_add_uint_format(lbl_tree,
1262 hf_ldp_tlv_sess_atm_minvci,
1264 id, "Minimum VCI: %u", id);
1265 id=tvb_get_ntohs(tvb, offset+6);
1266 proto_tree_add_uint_format(lbl_tree,
1267 hf_ldp_tlv_sess_atm_maxvci,
1269 id, "Maximum VCI: %u", id);
1274 proto_tree_add_text(val_tree, tvb, offset, rem,
1275 "Error processing TLV: Extra data at end of TLV");
1280 /* Dissect the frame relay session params */
1283 dissect_tlv_frame_relay_session_parms(tvbuff_t *tvb, guint offset,proto_tree *tree, int rem)
1285 proto_tree *ti = NULL, *val_tree = NULL, *lbl_tree = NULL;
1286 guint8 numlr, ix, len;
1291 proto_tree_add_text(tree, tvb, offset, rem,
1292 "Error processing Frame Relay Parameters TLV: length is %d, should be >= 4",
1297 ti = proto_tree_add_text(tree, tvb, offset, rem,
1298 "Frame Relay Parameters");
1299 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1301 if(val_tree != NULL) {
1302 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_fr_merge,
1303 tvb, offset, 1, FALSE);
1305 /*get the number of label ranges*/
1306 numlr=(tvb_get_guint8(tvb, offset)>>2) & 0x0F;
1307 proto_tree_add_uint_format(val_tree, hf_ldp_tlv_sess_fr_lr,
1308 tvb, offset, 1, numlr, "Number of Label Range components: %u",
1311 proto_tree_add_item(val_tree, hf_ldp_tlv_sess_fr_dir,
1312 tvb, offset, 1, FALSE);
1314 /*move into range components*/
1317 ti = proto_tree_add_text(val_tree, tvb, offset, rem,
1318 "Frame Relay Label Range Components");
1321 val_tree=proto_item_add_subtree(ti,
1323 if( ! val_tree ) return;
1326 /*now dissect ranges*/
1327 for(ix=1; numlr > 0 && rem >= 8; ix++, rem-=8, numlr--) {
1328 ti=proto_tree_add_text(val_tree, tvb, offset, 8,
1329 "Frame Relay Label Range Component %u", ix);
1330 lbl_tree=proto_item_add_subtree(ti, ett_ldp_tlv_val);
1332 if( lbl_tree == NULL ) break;
1334 len=(guint8)(tvb_get_ntohs(tvb, offset)>>7) & 0x03;
1335 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);
1337 id=tvb_get_ntoh24(tvb, offset+1)&0x7FFFFF;
1338 proto_tree_add_uint_format(lbl_tree,
1339 hf_ldp_tlv_sess_fr_mindlci, tvb, offset+1, 3, id, "Minimum DLCI %u", id);
1340 id=tvb_get_ntoh24(tvb, offset+5)&0x7FFFFF;
1341 proto_tree_add_uint_format(lbl_tree,
1342 hf_ldp_tlv_sess_fr_maxdlci, tvb, offset+5, 3, id, "Maximum DLCI %u", id);
1348 proto_tree_add_text(val_tree, tvb, offset, rem,
1349 "Error processing TLV: Extra data at end of TLV");
1356 dissect_tlv_lspid(tvbuff_t *tvb, guint offset,proto_tree *tree, int rem)
1358 proto_tree *ti = NULL, *val_tree = NULL;
1362 proto_tree_add_text(tree, tvb, offset, rem,
1363 "Error processing LSP ID TLV: length is %d, should be 8",
1368 ti = proto_tree_add_text(tree, tvb, offset, rem,
1370 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1372 if(val_tree != NULL) {
1373 proto_tree_add_item(val_tree, hf_ldp_tlv_lspid_act_flg,
1374 tvb, offset, 2, FALSE);
1376 proto_tree_add_item(val_tree, hf_ldp_tlv_lspid_cr_lsp,
1377 tvb, offset, 2, FALSE);
1379 proto_tree_add_item(val_tree, hf_ldp_tlv_lspid_ldpid,
1380 tvb, offset, 4, FALSE);
1386 dissect_tlv_er_hop_ipv4(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1388 proto_tree *ti = NULL, *val_tree = NULL;
1393 proto_tree_add_text(tree, tvb, offset, rem,
1394 "Error processing ER HOP IPv4 TLV: length is %d, should be 8",
1398 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP IPv4");
1399 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1401 if(val_tree != NULL) {
1402 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1403 tvb, offset, 3, FALSE);
1405 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prelen,
1406 tvb, offset, 1, FALSE);
1408 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prefix4,
1409 tvb, offset, 4, FALSE);
1415 dissect_tlv_er_hop_ipv6(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1417 proto_tree *ti = NULL, *val_tree = NULL;
1421 proto_tree_add_text(tree, tvb, offset, rem,
1422 "Error processing ER HOP IPv6 TLV: length is %d, should be 20",
1426 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP IPv6");
1427 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1429 if(val_tree != NULL) {
1430 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1431 tvb, offset, 3, FALSE);
1433 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prelen,
1434 tvb, offset, 1, FALSE);
1436 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_prefix6,
1437 tvb, offset, 16, FALSE);
1443 dissect_tlv_er_hop_as(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1445 proto_tree *ti = NULL, *val_tree = NULL;
1449 proto_tree_add_text(tree, tvb, offset, rem,
1450 "Error processing ER HOP AS TLV: length is %d, should be 4",
1454 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP AS");
1455 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1457 if(val_tree != NULL) {
1458 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1459 tvb, offset, 2, FALSE);
1461 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_as,
1462 tvb, offset, 2, FALSE);
1468 dissect_tlv_er_hop_lspid(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1470 proto_tree *ti = NULL, *val_tree = NULL;
1474 proto_tree_add_text(tree, tvb, offset, rem,
1475 "Error processing ER HOP LSPID TLV: length is %d, should be 8",
1479 ti = proto_tree_add_text(tree, tvb, offset, rem, "ER HOP LSPID");
1480 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1482 if(val_tree != NULL) {
1483 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_loose,
1484 tvb, offset, 2, FALSE);
1486 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_cr_lsp,
1487 tvb, offset, 2, FALSE);
1489 proto_tree_add_item(val_tree, hf_ldp_tlv_er_hop_ldpid,
1490 tvb, offset, 4, FALSE);
1496 dissect_tlv_traffic(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1498 proto_tree *ti = NULL, *val_tree = NULL;
1505 proto_tree_add_text(tree, tvb, offset, rem,
1506 "Error processing Traffic Parameters TLV: length is %d, should be 24",
1510 ti = proto_tree_add_text(tree, tvb, offset, rem, "Traffic parameters");
1511 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1513 if(val_tree != NULL) {
1515 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_reserv, tvb, offset, 1, FALSE);
1516 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_weight, tvb, offset, 1, FALSE);
1517 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_ebs, tvb, offset, 1, FALSE);
1518 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_cbs, tvb, offset, 1, FALSE);
1519 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_cdr, tvb, offset, 1, FALSE);
1520 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_pbs, tvb, offset, 1, FALSE);
1521 proto_tree_add_item(val_tree, hf_ldp_tlv_flags_pdr, tvb, offset, 1, FALSE);
1525 proto_tree_add_item(val_tree, hf_ldp_tlv_frequency, tvb, offset, 1, FALSE);
1532 pi = proto_tree_add_item(val_tree, hf_ldp_tlv_weight, tvb, offset, 1, FALSE);
1533 val_8 = tvb_get_guint8(tvb, offset);
1535 proto_item_set_text(pi, "Weight: Not applicable");
1539 val_f = tvb_get_ntohieee_float (tvb, offset);
1540 proto_tree_add_double_format(val_tree, hf_ldp_tlv_pdr, tvb, offset,
1541 4, val_f, "PDR: %.10g Bps", val_f);
1544 val_f = tvb_get_ntohieee_float (tvb, offset);
1545 proto_tree_add_double_format(val_tree, hf_ldp_tlv_pbs, tvb, offset,
1546 4, val_f, "PBS: %.10g Bytes", val_f);
1550 val_f = tvb_get_ntohieee_float (tvb, offset);
1551 proto_tree_add_double_format(val_tree, hf_ldp_tlv_cdr, tvb, offset,
1552 4, val_f, "CDR: %.10g Bps", val_f);
1556 val_f = tvb_get_ntohieee_float (tvb, offset);
1557 proto_tree_add_double_format(val_tree, hf_ldp_tlv_cbs, tvb, offset,
1558 4, val_f, "CBS: %.10g Bytes", val_f);
1562 val_f = tvb_get_ntohieee_float (tvb, offset);
1563 proto_tree_add_double_format(val_tree, hf_ldp_tlv_ebs, tvb, offset,
1564 4, val_f, "EBS: %.10g Bytes", val_f);
1571 dissect_tlv_route_pinning(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1573 proto_tree *ti = NULL, *val_tree = NULL;
1577 proto_tree_add_text(tree, tvb, offset, rem,
1578 "Error processing Route Pinning TLV: length is %d, should be 4",
1582 ti = proto_tree_add_text(tree, tvb, offset, rem, "Route Pinning");
1583 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1585 if(val_tree != NULL) {
1586 proto_tree_add_item(val_tree, hf_ldp_tlv_route_pinning,
1587 tvb, offset, 4, FALSE);
1594 dissect_tlv_resource_class(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1596 proto_tree *ti = NULL, *val_tree = NULL;
1600 proto_tree_add_text(tree, tvb, offset, rem,
1601 "Error processing Resource Class TLV: length is %d, should be 4",
1605 ti = proto_tree_add_text(tree, tvb, offset, rem, "Resource Class");
1606 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1608 if(val_tree != NULL) {
1609 proto_tree_add_item(val_tree, hf_ldp_tlv_resource_class,
1610 tvb, offset, 4, FALSE);
1617 dissect_tlv_preemption(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1619 proto_tree *ti = NULL, *val_tree = NULL;
1623 proto_tree_add_text(tree, tvb, offset, rem,
1624 "Error processing Preemption TLV: length is %d, should be 4",
1628 ti = proto_tree_add_text(tree, tvb, offset, rem, "Preemption");
1629 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1631 if(val_tree != NULL) {
1632 proto_tree_add_item(val_tree, hf_ldp_tlv_set_prio,
1633 tvb, offset, 1, FALSE);
1635 proto_tree_add_item(val_tree, hf_ldp_tlv_hold_prio,
1636 tvb, offset, 1, FALSE);
1643 dissect_tlv_diffserv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1645 int type, mapnb, count;
1646 int *hfindexes[] = {
1647 &hf_ldp_tlv_diffserv_map,
1648 &hf_ldp_tlv_diffserv_map_exp,
1649 &hf_ldp_tlv_diffserv_phbid,
1650 &hf_ldp_tlv_diffserv_phbid_dscp,
1651 &hf_ldp_tlv_diffserv_phbid_code,
1652 &hf_ldp_tlv_diffserv_phbid_bit14,
1653 &hf_ldp_tlv_diffserv_phbid_bit15
1656 &ett_ldp_diffserv_map,
1657 &ett_ldp_diffserv_map_phbid
1661 proto_tree_add_text(tree, tvb, offset, rem,
1662 "Error processing Diff-Serv TLV: length is %d, should be >= 4", rem);
1665 proto_tree_add_uint(tree, hf_ldp_tlv_diffserv_type, tvb, offset, 1,
1666 type = tvb_get_guint8(tvb, offset));
1667 type = (type >> 7) + 1;
1671 proto_tree_add_uint(tree, hf_ldp_tlv_diffserv_mapnb, tvb, offset,
1672 1, mapnb = tvb_get_guint8(tvb, offset) & 15);
1674 for (count = 0; count < mapnb; count++) {
1675 dissect_diffserv_mpls_common(tvb, tree, type, offset, hfindexes, etts);
1679 else if (type == 2) {
1681 dissect_diffserv_mpls_common(tvb, tree, type, offset + 2, hfindexes, etts);
1687 dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem);
1690 dissect_tlv_er(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1692 proto_tree *ti = NULL, *val_tree = NULL;
1696 ti = proto_tree_add_text(tree, tvb, offset, rem, "Explicit route");
1697 val_tree = proto_item_add_subtree(ti, ett_ldp_tlv_val);
1699 if(val_tree != NULL) {
1702 len = dissect_tlv (tvb, offset, val_tree, rem);
1711 /* Dissect a TLV and return the number of bytes consumed ... */
1714 dissect_tlv(tvbuff_t *tvb, guint offset, proto_tree *tree, int rem)
1716 guint16 type, typebak;
1718 proto_tree *ti = NULL, *tlv_tree = NULL;
1720 length=tvb_reported_length_remaining(tvb, offset);
1721 rem=MIN(rem, length);
1723 if( rem < 4 ) {/*chk for minimum header*/
1725 proto_tree_add_text(tree, tvb, offset, rem,
1726 "Error processing TLV: length is %d, should be >= 4",
1730 type = tvb_get_ntohs(tvb, offset) & 0x3FFF;
1732 length = tvb_get_ntohs(tvb, offset + 2),
1733 rem -= 4; /*do not count header*/
1734 length = MIN(length, rem); /* Don't go haywire if a problem ... */
1737 /*chk for vendor-private*/
1738 if(type>=TLV_VENDOR_PRIVATE_START && type<=TLV_VENDOR_PRIVATE_END){
1739 typebak=type; /*keep type*/
1740 type=TLV_VENDOR_PRIVATE_START;
1742 /*chk for experimental*/
1743 } else if(type>=TLV_EXPERIMENTAL_START && type<=TLV_EXPERIMENTAL_END){
1744 typebak=type; /*keep type*/
1745 type=TLV_EXPERIMENTAL_START;
1748 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
1749 val_to_str(type, tlv_type_names, "Unknown TLV type (0x%04X)"));
1750 tlv_tree = proto_item_add_subtree(ti, ett_ldp_tlv);
1751 if(tlv_tree == NULL) return length+4;
1753 proto_tree_add_item(tlv_tree, hf_ldp_tlv_unknown, tvb, offset, 1, FALSE);
1755 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 );
1757 proto_tree_add_item(tlv_tree, hf_ldp_tlv_len, tvb, offset + 2, 2, FALSE);
1762 dissect_tlv_fec(tvb, offset + 4, tlv_tree, length);
1765 case TLV_ADDRESS_LIST:
1766 dissect_tlv_address_list(tvb, offset + 4, tlv_tree, length);
1770 if( length != 1 ) /*error, only one byte*/
1771 proto_tree_add_text(tlv_tree, tvb, offset + 4,length,
1772 "Error processing Hop Count TLV: length is %d, should be 1",
1775 proto_tree_add_item(tlv_tree, hf_ldp_tlv_hc_value, tvb,offset + 4, length, FALSE);
1778 case TLV_PATH_VECTOR:
1779 dissect_tlv_path_vector(tvb, offset + 4, tlv_tree, length);
1782 case TLV_GENERIC_LABEL:
1783 if( length != 4 ) /*error, need only label*/
1784 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1785 "Error processing Generic Label TLV: length is %d, should be 4",
1788 guint32 label=tvb_get_ntohl(tvb, offset+4) & 0x000FFFFF;
1790 proto_tree_add_uint_format(tlv_tree, hf_ldp_tlv_generic_label,
1791 tvb, offset+4, length, label, "Generic Label: %u", label);
1796 dissect_tlv_atm_label(tvb, offset + 4, tlv_tree, length);
1799 case TLV_FRAME_LABEL:
1800 dissect_tlv_frame_label(tvb, offset + 4, tlv_tree, length);
1804 dissect_tlv_status(tvb, offset + 4, tlv_tree, length);
1807 case TLV_EXTENDED_STATUS:
1808 if( length != 4 ) /*error, need only status_code(guint32)*/
1809 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1810 "Error processing Extended Status TLV: length is %d, should be 4",
1813 proto_tree_add_item(tlv_tree, hf_ldp_tlv_extstatus_data, tvb, offset + 4, length, FALSE);
1817 case TLV_RETURNED_PDU:
1818 dissect_tlv_returned_pdu(tvb, offset + 4, tlv_tree, length);
1821 case TLV_RETURNED_MESSAGE:
1822 dissect_tlv_returned_message(tvb, offset + 4, tlv_tree, length);
1825 case TLV_COMMON_HELLO_PARMS:
1827 dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree, length);
1829 dissect_tlv_common_hello_parms(tvb, offset + 4, tlv_tree);
1833 case TLV_IPV4_TRANSPORT_ADDRESS:
1834 if( length != 4 ) /*error, need only ipv4*/
1835 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1836 "Error processing IPv4 Transport Address TLV: length is %d, should be 4",
1839 proto_tree_add_item(tlv_tree, hf_ldp_tlv_ipv4_taddr, tvb, offset + 4, 4, FALSE);
1843 case TLV_CONFIGURATION_SEQNO:
1844 if( length != 4 ) /*error, need only seq_num(guint32)*/
1845 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1846 "Error processing Configuration Sequence Number TLV: length is %d, should be 4",
1849 proto_tree_add_item(tlv_tree, hf_ldp_tlv_config_seqno, tvb, offset + 4, 4, FALSE);
1853 case TLV_IPV6_TRANSPORT_ADDRESS:
1854 if( length != 16 ) /*error, need only ipv6*/
1855 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1856 "Error processing IPv6 Transport Address TLV: length is %d, should be 16",
1859 proto_tree_add_item(tlv_tree, hf_ldp_tlv_ipv6_taddr, tvb, offset + 4, 16, FALSE);
1863 case TLV_MAC: /* draft-lasserre-vkompella-ppvpn-vpls-02.txt */
1864 dissect_tlv_mac(tvb, offset + 4, tlv_tree, length);
1867 case TLV_COMMON_SESSION_PARMS:
1868 dissect_tlv_common_session_parms(tvb, offset + 4, tlv_tree, length);
1871 case TLV_ATM_SESSION_PARMS:
1872 dissect_tlv_atm_session_parms(tvb, offset + 4, tlv_tree, length);
1875 case TLV_FRAME_RELAY_SESSION_PARMS:
1876 dissect_tlv_frame_relay_session_parms(tvb, offset + 4, tlv_tree, length);
1879 case TLV_LABEL_REQUEST_MESSAGE_ID:
1880 if( length != 4 ) /*error, need only one msgid*/
1881 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1882 "Error processing Label Request Message ID TLV: length is %d, should be 4",
1885 proto_tree_add_item(tlv_tree, hf_ldp_tlv_lbl_req_msg_id, tvb,offset + 4,length, FALSE);
1889 dissect_tlv_lspid(tvb, offset + 4, tlv_tree, length);
1893 dissect_tlv_er(tvb, offset + 4, tlv_tree, length);
1896 case TLV_ER_HOP_IPV4:
1897 dissect_tlv_er_hop_ipv4(tvb, offset + 4, tlv_tree, length);
1900 case TLV_ER_HOP_IPV6:
1901 dissect_tlv_er_hop_ipv6(tvb, offset +4, tlv_tree, length);
1905 dissect_tlv_er_hop_as(tvb, offset + 4, tlv_tree, length);
1908 case TLV_ER_HOP_LSPID:
1909 dissect_tlv_er_hop_lspid(tvb, offset +4, tlv_tree, length);
1912 case TLV_TRAFFIC_PARAM:
1913 dissect_tlv_traffic(tvb, offset +4, tlv_tree, length);
1916 case TLV_PREEMPTION:
1917 dissect_tlv_preemption(tvb, offset +4, tlv_tree, length);
1920 case TLV_RESOURCE_CLASS:
1921 dissect_tlv_resource_class(tvb, offset +4, tlv_tree, length);
1924 case TLV_ROUTE_PINNING:
1925 dissect_tlv_route_pinning(tvb, offset +4, tlv_tree, length);
1929 dissect_tlv_diffserv(tvb, offset +4, tlv_tree, length);
1932 case TLV_VENDOR_PRIVATE_START:
1933 if( length < 4 ) /*error, at least Vendor ID*/
1934 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1935 "Error processing Vendor Private Start TLV: length is %d, should be >= 4",
1938 proto_tree_add_item(tlv_tree, hf_ldp_tlv_vendor_id, tvb,offset + 4, 4, FALSE);
1939 if( length > 4 ) /*have data*/
1940 proto_tree_add_text(tlv_tree, tvb, offset + 8, length-4,"Data");
1944 case TLV_EXPERIMENTAL_START:
1945 if( length < 4 ) /*error, at least Experiment ID*/
1946 proto_tree_add_text(tlv_tree, tvb, offset + 4, length,
1947 "Error processing Experimental Start TLV: length is %d, should be >= 4",
1950 proto_tree_add_item(tlv_tree, hf_ldp_tlv_experiment_id, tvb,offset + 4, 4, FALSE);
1951 if( length > 4 ) /*have data*/
1952 proto_tree_add_text(tlv_tree, tvb, offset + 8, length-4,"Data");
1957 proto_tree_add_item(tlv_tree, hf_ldp_tlv_value, tvb, offset + 4, length, FALSE);
1962 return length + 4; /* Length of the value field + header */
1966 /* Dissect a Message and return the number of bytes consumed ... */
1969 dissect_msg(tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree)
1971 guint16 type, typebak;
1973 int length, rem, ao=0, co;
1974 proto_tree *ti = NULL, *msg_tree = NULL;
1976 rem=tvb_reported_length_remaining(tvb, offset);
1978 if( rem < 8 ) {/*chk for minimum header = type + length + msg_id*/
1979 if( check_col(pinfo->cinfo, COL_INFO) )
1980 col_append_fstr(pinfo->cinfo, COL_INFO, "Bad Message");
1982 proto_tree_add_text(tree, tvb, offset, rem,
1983 "Error processing Message: length is %d, should be >= 8",
1987 type = tvb_get_ntohs(tvb, offset) & 0x7FFF;
1989 /*chk for vendor-private*/
1990 if(type>=LDP_VENDOR_PRIVATE_START && type<=LDP_VENDOR_PRIVATE_END){
1991 typebak=type; /*keep type*/
1992 type=LDP_VENDOR_PRIVATE_START;
1994 /*chk for experimental*/
1995 } else if(type>=LDP_EXPERIMENTAL_MESSAGE_START && type<=LDP_EXPERIMENTAL_MESSAGE_END){
1996 typebak=type; /*keep type*/
1997 type=LDP_EXPERIMENTAL_MESSAGE_START;
2001 if( (length = tvb_get_ntohs(tvb, offset + 2)) < (4+extra) ) {/*not enough data for type*/
2002 if( check_col(pinfo->cinfo, COL_INFO) )
2003 col_append_fstr(pinfo->cinfo, COL_INFO, "Bad Message Length ");
2005 proto_tree_add_text(tree, tvb, offset, rem,
2006 "Error processing Message Length: length is %d, should be >= %u",
2011 length = MIN(length, rem); /* Don't go haywire if a problem ... */
2013 if( check_col(pinfo->cinfo, COL_INFO) ){
2014 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(type, ldp_message_types, "Unknown Message (0x%04X)"));
2018 ti = proto_tree_add_text(tree, tvb, offset, length + 4, "%s",
2019 val_to_str(type, ldp_message_types, "Unknown Message type (0x%04X)"));
2020 msg_tree = proto_item_add_subtree(ti, ett_ldp_message);
2021 if(msg_tree == NULL) return length+4;
2023 proto_tree_add_item(msg_tree, hf_ldp_msg_ubit, tvb, offset, 1, FALSE);
2025 type=tvb_get_ntohs(tvb, offset)&0x7FFF;
2026 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);
2028 proto_tree_add_item(msg_tree, hf_ldp_msg_len, tvb, offset+2, 2, FALSE);
2029 proto_tree_add_item(msg_tree, hf_ldp_msg_id, tvb, offset+4, 4, FALSE);
2034 case LDP_VENDOR_PRIVATE_START:
2035 hf_tmp=hf_ldp_msg_vendor_id;
2037 case LDP_EXPERIMENTAL_MESSAGE_START:
2038 hf_tmp=hf_ldp_msg_experiment_id;
2041 proto_tree_add_item(msg_tree, hf_tmp, tvb, offset+8, extra, FALSE);
2045 offset += (8+extra);
2046 length -= (4+extra);
2049 while( (length-ao) > 0 ) {
2050 co=dissect_tlv(tvb, offset, msg_tree, length-ao);
2055 return length+8+extra;
2060 dissect_ldp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2064 proto_tree *ti=NULL, *pdu_tree = NULL;
2066 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2067 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LDP");
2069 if (check_col(pinfo->cinfo, COL_INFO))
2070 col_clear(pinfo->cinfo, COL_INFO);
2073 ti=proto_tree_add_item(tree, proto_ldp, tvb, 0, -1, FALSE);
2074 pdu_tree = proto_item_add_subtree(ti, ett_ldp);
2076 proto_tree_add_item(pdu_tree, hf_ldp_version, tvb, offset, 2, FALSE);
2079 length = tvb_get_ntohs(tvb, offset+2);
2081 proto_tree_add_uint(pdu_tree, hf_ldp_pdu_len, tvb, offset+2, 2, length);
2083 length += 4; /* add the version and type sizes */
2084 rem = tvb_reported_length_remaining(tvb, offset);
2086 tvb_set_reported_length(tvb, length);
2089 proto_tree_add_item(pdu_tree, hf_ldp_lsr, tvb, offset+4, 4, FALSE);
2090 proto_tree_add_item(pdu_tree, hf_ldp_ls_id, tvb, offset+8, 2, FALSE);
2094 while( tvb_reported_length_remaining(tvb, offset) > 0 ) {
2095 co=dissect_msg(tvb, offset, pinfo, pdu_tree);
2101 dissect_ldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2104 * Make sure the first PDU has a version number of 1;
2105 * if not, reject this, so we don't get confused by
2106 * packets that happen to be going to or from the
2107 * LDP port but that aren't LDP packets.
2109 if (!tvb_bytes_exist(tvb, 0, 2)) {
2111 * Not enough information to tell.
2115 if (tvb_get_ntohs(tvb, 0) != 1) {
2122 dissect_ldp_pdu(tvb, pinfo, tree);
2125 * XXX - return minimum of this and the length of the PDU?
2127 return tvb_length(tvb);
2131 dissect_ldp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2133 volatile gboolean first = TRUE;
2134 volatile int offset = 0;
2135 int length_remaining;
2140 while (tvb_reported_length_remaining(tvb, offset) != 0) {
2141 length_remaining = tvb_length_remaining(tvb, offset);
2144 * Make sure the first PDU has a version number of 1;
2145 * if not, reject this, so we don't get confused by
2146 * packets that happen to be going to or from the
2147 * LDP port but that aren't LDP packets.
2149 * XXX - this means we can't handle an LDP PDU of which
2150 * only one byte appears in a TCP segment. If that's
2151 * a problem, we'll either have to completely punt on
2152 * rejecting non-LDP packets, or will have to assume
2153 * that if we have only one byte, it's an LDP packet.
2156 if (length_remaining < 2) {
2158 * Not enough information to tell.
2162 if (tvb_get_ntohs(tvb, offset) != 1) {
2172 * Can we do reassembly?
2174 if (ldp_desegment && pinfo->can_desegment) {
2176 * Yes - is the LDP header split across segment
2179 if (length_remaining < 4) {
2181 * Yes. Tell the TCP dissector where
2182 * the data for this message starts in
2183 * the data it handed us, and how many
2184 * more bytes we need, and return.
2186 pinfo->desegment_offset = offset;
2187 pinfo->desegment_len = 4 - length_remaining;
2188 return -((gint32) pinfo->desegment_len);
2193 * Get the length of the rest of the LDP packet.
2194 * XXX - check for a version of 1 first?
2196 plen = tvb_get_ntohs(tvb, offset + 2);
2199 * Can we do reassembly?
2201 if (ldp_desegment && pinfo->can_desegment) {
2203 * Yes - is the LDP packet split across segment
2206 if (length_remaining < plen + 4) {
2208 * Yes. Tell the TCP dissector where the
2209 * data for this message starts in the data
2210 * it handed us, and how many more bytes we
2213 pinfo->desegment_offset = offset;
2214 pinfo->desegment_len =
2215 (plen + 4) - length_remaining;
2216 return -((gint32) pinfo->desegment_len);
2221 * Construct a tvbuff containing the amount of the payload
2222 * we have available. Make its reported length the
2223 * amount of data in the DNS-over-TCP packet.
2225 * XXX - if reassembly isn't enabled. the subdissector
2226 * will throw a BoundsError exception, rather than a
2227 * ReportedBoundsError exception. We really want
2228 * a tvbuff where the length is "length", the reported
2229 * length is "plen + 4", and the "if the snapshot length
2230 * were infinite" length is the minimum of the
2231 * reported length of the tvbuff handed to us and "plen+4",
2232 * with a new type of exception thrown if the offset is
2233 * within the reported length but beyond that third length,
2234 * with that exception getting the "Unreassembled Packet"
2237 length = length_remaining;
2238 if (length > plen + 4)
2240 next_tvb = tvb_new_subset(tvb, offset, length, plen + 4);
2243 * Dissect the LDP packet.
2245 * Catch the ReportedBoundsError exception; if this
2246 * particular message happens to get a ReportedBoundsError
2247 * exception, that doesn't mean that we should stop
2248 * dissecting LDP messages within this frame or chunk of
2251 * If it gets a BoundsError, we can stop, as there's nothing
2252 * more to see, so we just re-throw it.
2255 dissect_ldp_pdu(next_tvb, pinfo, tree);
2257 CATCH(BoundsError) {
2260 CATCH(ReportedBoundsError) {
2261 show_reported_bounds_error(tvb, pinfo, tree);
2266 * Skip the LDP header and the payload.
2270 return tvb_length(tvb);
2273 /* Register all the bits needed with the filtering engine */
2276 proto_register_ldp(void)
2278 static hf_register_info hf[] = {
2280 /* Change the following to the type you need */
2281 { "Request", "ldp.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
2284 { "Response", "ldp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }},
2287 { "Version", "ldp.hdr.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
2290 { "PDU Length", "ldp.hdr.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
2293 { "LSR ID", "ldp.hdr.ldpid.lsr", FT_IPv4, BASE_HEX, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
2296 { "Label Space ID", "ldp.hdr.ldpid.lsid", FT_UINT16, BASE_DEC, NULL, 0, "LDP Label Space ID", HFILL }},
2299 { "U bit", "ldp.msg.ubit", FT_BOOLEAN, 8, TFS(&ldp_message_ubit), 0x80, "Unknown Message Bit", HFILL }},
2302 { "Message Type", "ldp.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x7FFF, "LDP message type", HFILL }},
2305 { "Message Length", "ldp.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
2308 { "Message ID", "ldp.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
2310 { &hf_ldp_msg_vendor_id,
2311 { "Vendor ID", "ldp.msg.vendor.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Vendor-private Message ID", HFILL }},
2313 { &hf_ldp_msg_experiment_id,
2314 { "Experiment ID", "ldp.msg.experiment.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Experimental Message ID", HFILL }},
2316 { &hf_ldp_tlv_unknown,
2317 { "TLV Unknown bits", "ldp.msg.tlv.unknown", FT_UINT8, BASE_HEX, VALS(tlv_unknown_vals), 0xC0, "TLV Unknown bits Field", HFILL }},
2320 { "TLV Type", "ldp.msg.tlv.type", FT_UINT16, BASE_HEX, VALS(tlv_type_names), 0x3FFF, "TLV Type Field", HFILL }},
2323 {"TLV Length", "ldp.msg.tlv.len", FT_UINT16, BASE_DEC, NULL, 0x0, "TLV Length Field", HFILL }},
2325 { &hf_ldp_tlv_value,
2326 { "TLV Value", "ldp.msg.tlv.value", FT_BYTES, BASE_NONE, NULL, 0x0, "TLV Value Bytes", HFILL }},
2328 { &hf_ldp_tlv_val_hold,
2329 { "Hold Time", "ldp.msg.tlv.hello.hold", FT_UINT16, BASE_DEC, NULL, 0x0, "Hello Common Parameters Hold Time", HFILL }},
2331 { &hf_ldp_tlv_val_target,
2332 { "Targeted Hello", "ldp.msg.tlv.hello.targeted", FT_BOOLEAN, 16, TFS(&hello_targeted_vals), 0x8000, "Hello Common Parameters Targeted Bit", HFILL }},
2334 { &hf_ldp_tlv_val_request,
2335 { "Hello Requested", "ldp.msg.tlv.hello.requested", FT_BOOLEAN, 16, TFS(&hello_requested_vals), 0x4000, "Hello Common Parameters Hello Requested Bit", HFILL }},
2337 { &hf_ldp_tlv_val_res,
2338 { "Reserved", "ldp.msg.tlv.hello.res", FT_UINT16, BASE_HEX, NULL, 0x3FFF, "Hello Common Parameters Reserved Field", HFILL }},
2340 { &hf_ldp_tlv_ipv4_taddr,
2341 { "IPv4 Transport Address", "ldp.msg.tlv.ipv4.taddr", FT_IPv4, BASE_DEC, NULL, 0x0, "IPv4 Transport Address", HFILL }},
2343 { &hf_ldp_tlv_config_seqno,
2344 { "Configuration Sequence Number", "ldp.msg.tlv.hello.cnf_seqno", FT_UINT32, BASE_DEC, NULL, 0x0, "Hello Configuration Sequence Number", HFILL }},
2346 { &hf_ldp_tlv_ipv6_taddr,
2347 { "IPv6 Transport Address", "ldp.msg.tlv.ipv6.taddr", FT_IPv6, BASE_DEC, NULL, 0x0, "IPv6 Transport Address", HFILL }},
2349 { &hf_ldp_tlv_fec_wc,
2350 { "FEC Element Type", "ldp.msg.tlv.fec.type", FT_UINT8, BASE_DEC, VALS(fec_types), 0x0, "Forwarding Equivalence Class Element Types", HFILL }},
2352 { &hf_ldp_tlv_fec_af,
2353 { "FEC Element Address Type", "ldp.msg.tlv.fec.af", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Forwarding Equivalence Class Element Address Family", HFILL }},
2355 { &hf_ldp_tlv_fec_len,
2356 { "FEC Element Length", "ldp.msg.tlv.fec.len", FT_UINT8, BASE_DEC, NULL, 0x0, "Forwarding Equivalence Class Element Length", HFILL }},
2358 { &hf_ldp_tlv_fec_pfval,
2359 { "FEC Element Prefix Value", "ldp.msg.tlv.fec.pfval", FT_STRING, BASE_NONE, NULL, 0x0, "Forwarding Equivalence Class Element Prefix", HFILL }},
2361 { &hf_ldp_tlv_fec_hoval,
2362 { "FEC Element Host Address Value", "ldp.msg.tlv.fec.hoval", FT_STRING, BASE_NONE, NULL, 0x0, "Forwarding Equivalence Class Element Address", HFILL }},
2364 { &hf_ldp_tlv_addrl_addr_family,
2365 { "Address Family", "ldp.msg.tlv.addrl.addr_family", FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, "Address Family List", HFILL }},
2367 { &hf_ldp_tlv_addrl_addr,
2368 { "Address", "ldp.msg.tlv.addrl.addr", FT_STRING, BASE_NONE, NULL, 0x0, "Address", HFILL }},
2370 { &hf_ldp_tlv_hc_value,
2371 { "Hop Count Value", "ldp.msg.tlv.hc.value", FT_UINT8, BASE_DEC, NULL, 0x0, "Hop Count", HFILL }},
2373 { &hf_ldp_tlv_pv_lsrid,
2374 { "LSR Id", "ldp.msg.tlv.pv.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Path Vector LSR Id", HFILL }},
2376 { &hf_ldp_tlv_sess_ver,
2377 { "Session Protocol Version", "ldp.msg.tlv.sess.ver", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Protocol Version", HFILL }},
2379 { &hf_ldp_tlv_sess_ka,
2380 { "Session KeepAlive Time", "ldp.msg.tlv.sess.ka", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters KeepAlive Time", HFILL }},
2382 { &hf_ldp_tlv_sess_advbit,
2383 { "Session Label Advertisement Discipline", "ldp.msg.tlv.sess.advbit",
2384 FT_BOOLEAN, 8, TFS(&tlv_sess_advbit_vals), 0x80,
2385 "Common Session Parameters Label Advertisement Discipline", HFILL }},
2387 { &hf_ldp_tlv_sess_ldetbit,
2388 { "Session Loop Detection", "ldp.msg.tlv.sess.ldetbit", FT_BOOLEAN, 8, TFS(&tlv_sess_ldetbit_vals), 0x40, "Common Session Parameters Loop Detection", HFILL }},
2390 { &hf_ldp_tlv_sess_pvlim,
2391 { "Session Path Vector Limit", "ldp.msg.tlv.sess.pvlim", FT_UINT8, BASE_DEC, NULL, 0x0, "Common Session Parameters Path Vector Limit", HFILL }},
2393 { &hf_ldp_tlv_sess_mxpdu,
2394 { "Session Max PDU Length", "ldp.msg.tlv.sess.mxpdu", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Max PDU Length", HFILL }},
2396 { &hf_ldp_tlv_sess_rxlsr,
2397 { "Session Receiver LSR Identifier", "ldp.msg.tlv.sess.rxlsr", FT_IPv4, BASE_DEC, NULL, 0x0, "Common Session Parameters LSR Identifier", HFILL }},
2399 { &hf_ldp_tlv_sess_rxls,
2400 { "Session Receiver Label Space Identifier", "ldp.msg.tlv.sess.rxlsr", FT_UINT16, BASE_DEC, NULL, 0x0, "Common Session Parameters Receiver Label Space Identifier", HFILL }},
2402 { &hf_ldp_tlv_sess_atm_merge,
2403 { "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 }},
2405 { &hf_ldp_tlv_sess_atm_lr,
2406 { "Number of ATM Label Ranges", "ldp.msg.tlv.sess.atm.lr", FT_UINT8, BASE_DEC, NULL, 0x3C, "Number of Label Ranges", HFILL }},
2408 { &hf_ldp_tlv_sess_atm_dir,
2409 { "Directionality", "ldp.msg.tlv.sess.atm.dir", FT_BOOLEAN, 8, TFS(&tlv_atm_dirbit), 0x02, "Lablel Directionality", HFILL }},
2411 { &hf_ldp_tlv_sess_atm_minvpi,
2412 { "Minimum VPI", "ldp.msg.tlv.sess.atm.minvpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "Minimum VPI", HFILL }},
2414 { &hf_ldp_tlv_sess_atm_minvci,
2415 { "Minimum VCI", "ldp.msg.tlv.sess.atm.minvci", FT_UINT16, BASE_DEC, NULL, 0x0, "Minimum VCI", HFILL }},
2417 { &hf_ldp_tlv_sess_atm_maxvpi,
2418 { "Maximum VPI", "ldp.msg.tlv.sess.atm.maxvpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "Maximum VPI", HFILL }},
2420 { &hf_ldp_tlv_sess_atm_maxvci,
2421 { "Maximum VCI", "ldp.msg.tlv.sess.atm.maxvci", FT_UINT16, BASE_DEC, NULL, 0x0, "Maximum VCI", HFILL }},
2423 { &hf_ldp_tlv_sess_fr_merge,
2424 { "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 }},
2426 { &hf_ldp_tlv_sess_fr_lr,
2427 { "Number of Frame Relay Label Ranges", "ldp.msg.tlv.sess.fr.lr", FT_UINT8, BASE_DEC, NULL, 0x3C, "Number of Label Ranges", HFILL }},
2429 { &hf_ldp_tlv_sess_fr_dir,
2430 { "Directionality", "ldp.msg.tlv.sess.fr.dir", FT_BOOLEAN, 8, TFS(&tlv_atm_dirbit), 0x02, "Lablel Directionality", HFILL }},
2432 { &hf_ldp_tlv_sess_fr_len,
2433 { "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 }},
2435 { &hf_ldp_tlv_sess_fr_mindlci,
2436 { "Minimum DLCI", "ldp.msg.tlv.sess.fr.mindlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "Minimum DLCI", HFILL }},
2438 { &hf_ldp_tlv_sess_fr_maxdlci,
2439 { "Maximum DLCI", "ldp.msg.tlv.sess.fr.maxdlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "Maximum DLCI", HFILL }},
2441 { &hf_ldp_tlv_lbl_req_msg_id,
2442 { "Label Request Message ID", "ldp.tlv.lbl_req_msg_id", FT_UINT32, BASE_HEX, NULL, 0x0, "Label Request Message to be aborted", HFILL }},
2444 { &hf_ldp_tlv_vendor_id,
2445 { "Vendor ID", "ldp.msg.tlv.vendor_id", FT_UINT32, BASE_HEX, NULL, 0, "IEEE 802 Assigned Vendor ID", HFILL }},
2447 { &hf_ldp_tlv_experiment_id,
2448 { "Experiment ID", "ldp.msg.tlv.experiment_id", FT_UINT32, BASE_HEX, NULL, 0, "Experiment ID", HFILL }},
2450 { &hf_ldp_tlv_generic_label,
2451 { "Generic Label", "ldp.msg.tlv.generic.label", FT_UINT32, BASE_HEX, NULL, 0x000FFFFF, "Generic Label", HFILL }},
2453 { &hf_ldp_tlv_atm_label_vbits,
2454 { "V-bits", "ldp.msg.tlv.atm.label.vbits", FT_UINT8, BASE_HEX, VALS(tlv_atm_vbits_vals), 0x30, "ATM Label V Bits", HFILL }},
2456 { &hf_ldp_tlv_atm_label_vpi,
2457 { "VPI", "ldp.msg.tlv.atm.label.vpi", FT_UINT16, BASE_DEC, NULL, 0x0FFF, "ATM Label VPI", HFILL }},
2459 { &hf_ldp_tlv_atm_label_vci,
2460 { "VCI", "ldp.msg.tlv.atm.label.vci", FT_UINT16, BASE_DEC, NULL, 0, "ATM Label VCI", HFILL }},
2462 { &hf_ldp_tlv_fr_label_len,
2463 { "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 }},
2465 { &hf_ldp_tlv_fr_label_dlci,
2466 { "DLCI", "ldp.msg.tlv.fr.label.dlci", FT_UINT24, BASE_DEC, NULL, 0x7FFFFF, "FRAME RELAY Label DLCI", HFILL }},
2468 { &hf_ldp_tlv_status_ebit,
2469 { "E Bit", "ldp.msg.tlv.status.ebit", FT_BOOLEAN, 8, TFS(&tlv_status_ebit), 0x80, "Fatal Error Bit", HFILL }},
2471 { &hf_ldp_tlv_status_fbit,
2472 { "F Bit", "ldp.msg.tlv.status.fbit", FT_BOOLEAN, 8, TFS(&tlv_status_fbit), 0x40, "Forward Bit", HFILL }},
2474 { &hf_ldp_tlv_status_data,
2475 { "Status Data", "ldp.msg.tlv.status.data", FT_UINT32, BASE_HEX, VALS(tlv_status_data), 0x3FFFFFFF, "Status Data", HFILL }},
2477 { &hf_ldp_tlv_status_msg_id,
2478 { "Message ID", "ldp.msg.tlv.status.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "Identifies peer message to which Status TLV refers", HFILL }},
2480 { &hf_ldp_tlv_status_msg_type,
2481 { "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 }},
2483 { &hf_ldp_tlv_extstatus_data,
2484 { "Extended Status Data", "ldp.msg.tlv.extstatus.data", FT_UINT32, BASE_HEX, NULL, 0x0, "Extended Status Data", HFILL }},
2486 { &hf_ldp_tlv_returned_version,
2487 { "Returned PDU Version", "ldp.msg.tlv.returned.version", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Version Number", HFILL }},
2489 { &hf_ldp_tlv_returned_pdu_len,
2490 { "Returned PDU Length", "ldp.msg.tlv.returned.pdu_len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP PDU Length", HFILL }},
2492 { &hf_ldp_tlv_returned_lsr,
2493 { "Returned PDU LSR ID", "ldp.msg.tlv.returned.ldpid.lsr", FT_IPv4, BASE_DEC, NULL, 0x0, "LDP Label Space Router ID", HFILL }},
2495 { &hf_ldp_tlv_returned_ls_id,
2496 { "Returned PDU Label Space ID", "ldp.msg.tlv.returned.ldpid.lsid", FT_UINT16, BASE_HEX, NULL, 0x0, "LDP Label Space ID", HFILL }},
2498 { &hf_ldp_tlv_returned_msg_ubit,
2499 { "Returned Message Unknown bit", "ldp.msg.tlv.returned.msg.ubit", FT_BOOLEAN, BASE_HEX, TFS(&ldp_message_ubit), 0x80, "Message Unknown bit", HFILL }},
2501 { &hf_ldp_tlv_returned_msg_type,
2502 { "Returned Message Type", "ldp.msg.tlv.returned.msg.type", FT_UINT16, BASE_HEX, VALS(ldp_message_types), 0x7FFF, "LDP message type", HFILL }},
2504 { &hf_ldp_tlv_returned_msg_len,
2505 { "Returned Message Length", "ldp.msg.tlv.returned.msg.len", FT_UINT16, BASE_DEC, NULL, 0x0, "LDP Message Length (excluding message type and len)", HFILL }},
2507 { &hf_ldp_tlv_returned_msg_id,
2508 { "Returned Message ID", "ldp.msg.tlv.returned.msg.id", FT_UINT32, BASE_HEX, NULL, 0x0, "LDP Message ID", HFILL }},
2511 { "MAC address", "ldp.msg.tlv.mac", FT_ETHER, BASE_NONE, NULL, 0x0, "MAC address", HFILL}},
2513 {&hf_ldp_tlv_fec_vc_controlword,
2514 {"C-bit", "ldp.msg.tlv.fec.vc.controlword", FT_BOOLEAN, 8, TFS(&fec_vc_cbit), 0x80, "Control Word Present", HFILL }},
2516 {&hf_ldp_tlv_fec_vc_vctype,
2517 {"VC Type", "ldp.msg.tlv.fec.vc.vctype", FT_UINT16, BASE_HEX, VALS(fec_vc_types_vals), 0x7FFF, "Virtual Circuit Type", HFILL }},
2519 {&hf_ldp_tlv_fec_vc_infolength,
2520 {"VC Info Length", "ldp.msg.tlv.fec.vc.infolength", FT_UINT8, BASE_DEC, NULL, 0x0, "VC FEC Info Length", HFILL }},
2522 {&hf_ldp_tlv_fec_vc_groupid,
2523 {"Group ID", "ldp.msg.tlv.fec.vc.groupid", FT_UINT32, BASE_DEC, NULL, 0x0, "VC FEC Group ID", HFILL }},
2525 {&hf_ldp_tlv_fec_vc_vcid,
2526 {"VC ID", "ldp.msg.tlv.fec.vc.vcid", FT_UINT32, BASE_DEC, NULL, 0x0, "VC FEC VCID", HFILL }},
2528 {&hf_ldp_tlv_fec_vc_intparam_length,
2529 {"Length", "ldp.msg.tlv.fec.vc.intparam.length", FT_UINT8, BASE_DEC, NULL, 0x0, "VC FEC Interface Paramater Length", HFILL }},
2531 {&hf_ldp_tlv_fec_vc_intparam_mtu,
2532 {"MTU", "ldp.msg.tlv.fec.vc.intparam.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, "VC FEC Interface Paramater MTU", HFILL }},
2534 {&hf_ldp_tlv_fec_vc_intparam_tdmbps,
2535 {"BPS", "ldp.msg.tlv.fec.vc.intparam.tdmbps", FT_UINT16, BASE_DEC, NULL, 0x0, "VC FEC Interface Parameter CEP/TDM bit-rate", HFILL }},
2537 {&hf_ldp_tlv_fec_vc_intparam_id,
2538 {"ID", "ldp.msg.tlv.fec.vc.intparam.id", FT_UINT8, BASE_HEX, VALS(fec_vc_interfaceparm), 0x0, "VC FEC Interface Paramater ID", HFILL }},
2540 {&hf_ldp_tlv_fec_vc_intparam_maxcatmcells,
2541 {"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 }},
2543 { &hf_ldp_tlv_fec_vc_intparam_desc,
2544 { "Description", "ldp.msg.tlv.fec.vc.intparam.desc", FT_STRING, BASE_DEC, NULL, 0, "VC FEC Interface Description", HFILL }},
2546 { &hf_ldp_tlv_fec_vc_intparam_cembytes,
2547 {"Payload Bytes", "ldp.msg.tlv.fec.vc.intparam.cembytes", FT_UINT16, BASE_DEC, NULL, 0x0, "VC FEC Interface Param CEM Payload Bytes", HFILL }},
2549 { &hf_ldp_tlv_fec_vc_intparam_vpnid_oui,
2550 { "VPN OUI", "ldp.msg.tlv.fec.vc.intparam.vpnid.oui", FT_UINT24, BASE_HEX, NULL, 0x0, "VC FEC Interface Param VPN OUI", HFILL }},
2552 { &hf_ldp_tlv_fec_vc_intparam_vpnid_index,
2553 { "VPN Index", "ldp.msg.tlv.fec.vc.intparam.vpnid.index", FT_UINT32, BASE_HEX, NULL, 0x0, "VC FEC Interface Param VPN Index", HFILL }},
2555 { &hf_ldp_tlv_lspid_act_flg,
2556 { "Action Indicator Flag", "ldp.msg.tlv.lspid.actflg", FT_UINT16, BASE_HEX, VALS(ldp_act_flg_vals), 0x000F, "Action Indicator Flag", HFILL}},
2558 { &hf_ldp_tlv_lspid_cr_lsp,
2559 { "Local CR-LSP ID", "ldp.msg.tlv.lspid.locallspid", FT_UINT16, BASE_HEX, NULL, 0x0, "Local CR-LSP ID", HFILL}},
2561 { &hf_ldp_tlv_lspid_ldpid,
2562 { "Ingress LSR Router ID", "ldp.msg.tlv.lspid.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Ingress LSR Router ID", HFILL}},
2564 { &hf_ldp_tlv_er_hop_loose,
2565 { "Loose route bit", "ldp.msg.tlv.er_hop.loose", FT_UINT24, BASE_HEX, VALS(ldp_loose_vals), 0x800000, "Loose route bit", HFILL}},
2567 { &hf_ldp_tlv_er_hop_prelen,
2568 { "Prefix length", "ldp.msg.tlv.er_hop.prefixlen", FT_UINT8, BASE_DEC, NULL, 0x0, "Prefix len", HFILL}},
2570 { &hf_ldp_tlv_er_hop_prefix4,
2571 { "IPv4 Address", "ldp.msg.tlv.er_hop.prefix4", FT_IPv4, BASE_DEC, NULL, 0x0, "IPv4 Address", HFILL}},
2572 { &hf_ldp_tlv_er_hop_prefix6,
2573 { "IPv6 Address", "ldp.msg.tlv.er_hop.prefix6", FT_IPv6, BASE_DEC, NULL, 0x0, "IPv6 Address", HFILL}},
2575 { &hf_ldp_tlv_er_hop_as,
2576 { "AS Number", "ldp.msg.tlv.er_hop.as", FT_UINT16, BASE_DEC, NULL, 0x0, "AS Number", HFILL}},
2578 { &hf_ldp_tlv_er_hop_cr_lsp,
2579 { "Local CR-LSP ID", "ldp.msg.tlv.er_hop.locallspid", FT_UINT16, BASE_DEC, NULL, 0x0, "Local CR-LSP ID", HFILL}},
2581 { &hf_ldp_tlv_er_hop_ldpid,
2582 { "Local CR-LSP ID", "ldp.msg.tlv.er_hop.lsrid", FT_IPv4, BASE_DEC, NULL, 0x0, "Local CR-LSP ID", HFILL}},
2584 { &hf_ldp_tlv_flags_reserv,
2585 { "Reserved", "ldp.msg.tlv.flags_reserv", FT_UINT8, BASE_HEX, NULL, 0xC0, "Reserved", HFILL}},
2587 { &hf_ldp_tlv_flags_pdr,
2588 { "PDR", "ldp.msg.tlv.flags_pdr", FT_BOOLEAN, 8, TFS(&tlv_negotiable), 0x1, "PDR negotiability flag", HFILL}},
2590 { &hf_ldp_tlv_flags_pbs,
2591 { "PBS", "ldp.msg.tlv.flags_pbs", FT_BOOLEAN, 8, TFS(&tlv_negotiable), 0x2, "PBS negotiability flag", HFILL}},
2593 { &hf_ldp_tlv_flags_cdr,
2594 { "CDR", "ldp.msg.tlv.flags_cdr", FT_BOOLEAN, 8, TFS(&tlv_negotiable), 0x4, "CDR negotiability flag", HFILL}},
2596 { &hf_ldp_tlv_flags_cbs,
2597 { "CBS", "ldp.msg.tlv.flags_cbs", FT_BOOLEAN, 8, TFS(&tlv_negotiable), 0x8, "CBS negotiability flag", HFILL}},
2599 { &hf_ldp_tlv_flags_ebs,
2600 { "EBS", "ldp.msg.tlv.flags_ebs", FT_BOOLEAN, 8, TFS(&tlv_negotiable), 0x10, "EBS negotiability flag", HFILL}},
2602 { &hf_ldp_tlv_flags_weight,
2603 { "Weight", "ldp.msg.tlv.flags_weight", FT_BOOLEAN, 8, TFS(&tlv_negotiable), 0x20, "Weight negotiability flag", HFILL}},
2605 { &hf_ldp_tlv_frequency,
2606 { "Frequency", "ldp.msg.tlv.frequency", FT_UINT8, BASE_DEC, VALS(freq_values), 0, "Frequency", HFILL}},
2608 { &hf_ldp_tlv_weight,
2609 { "Weight", "ldp.msg.tlv.weight", FT_UINT8, BASE_DEC, NULL, 0, "Weight of the CR-LSP", HFILL}},
2612 { "PDR", "ldp.msg.tlv.pdr", FT_DOUBLE, BASE_NONE, NULL, 0, "Peak Data Rate", HFILL}},
2615 { "PBS", "ldp.msg.tlv.pbs", FT_DOUBLE, BASE_NONE, NULL, 0, "Peak Burst Size", HFILL}},
2618 { "CDR", "ldp.msg.tlv.cdr", FT_DOUBLE, BASE_NONE, NULL, 0, "Committed Data Rate", HFILL}},
2621 { "CBS", "ldp.msg.tlv.cbs", FT_DOUBLE, BASE_NONE, NULL, 0, "Committed Burst Size", HFILL}},
2624 { "EBS", "ldp.msg.tlv.ebs", FT_DOUBLE, BASE_NONE, NULL, 0, "Excess Burst Size", HFILL}},
2626 { &hf_ldp_tlv_set_prio,
2627 { "Set Prio", "ldp.msg.tlv.set_prio", FT_UINT8, BASE_DEC, NULL, 0, "LSP setup priority", HFILL}},
2629 { &hf_ldp_tlv_hold_prio,
2630 { "Hold Prio", "ldp.msg.tlv.hold_prio", FT_UINT8, BASE_DEC, NULL, 0, "LSP hold priority", HFILL}},
2632 { &hf_ldp_tlv_route_pinning,
2633 { "Route Pinning", "ldp.msg.tlv.route_pinning", FT_UINT32, BASE_DEC, VALS(route_pinning_vals), 0x80000000, "Route Pinning", HFILL}},
2635 { &hf_ldp_tlv_resource_class,
2636 { "Resource Class", "ldp.msg.tlv.resource_class", FT_UINT32, BASE_HEX, NULL, 0, "Resource Class (Color)", HFILL}},
2638 { &hf_ldp_tlv_diffserv,
2639 { "Diff-Serv TLV", "ldp.msg.tlv.diffserv", FT_NONE, BASE_NONE, NULL,
2640 0, "Diffserv TLV", HFILL}},
2642 { &hf_ldp_tlv_diffserv_type,
2643 { "LSP Type", "ldp.msg.tlv.diffserv.type", FT_UINT8, BASE_DEC,
2644 VALS(diffserv_type_vals), 0x80, "LSP Type", HFILL}},
2646 { &hf_ldp_tlv_diffserv_mapnb,
2647 { "MAPnb", "ldp.msg.tlv.diffserv.mapnb", FT_UINT8, BASE_DEC, NULL,
2648 0, MAPNB_DESCRIPTION, HFILL}},
2650 { &hf_ldp_tlv_diffserv_map,
2651 { "MAP", "ldp.msg.tlv.diffserv.map", FT_NONE, BASE_NONE, NULL,
2652 0, MAP_DESCRIPTION, HFILL}},
2654 { &hf_ldp_tlv_diffserv_map_exp,
2655 { "EXP", "ldp.msg.tlv.diffserv.map.exp", FT_UINT8, BASE_DEC, NULL,
2656 0, EXP_DESCRIPTION, HFILL}},
2658 { &hf_ldp_tlv_diffserv_phbid,
2659 { "PHBID", "ldp.msg.tlv.diffserv.phbid", FT_NONE, BASE_NONE, NULL,
2660 0, PHBID_DESCRIPTION, HFILL}},
2662 { &hf_ldp_tlv_diffserv_phbid_dscp,
2663 { "DSCP", "ldp.msg.tlv.diffserv.phbid.dscp", FT_UINT16, BASE_DEC,
2664 NULL, PHBID_DSCP_MASK, PHBID_DSCP_DESCRIPTION, HFILL}},
2666 { &hf_ldp_tlv_diffserv_phbid_code,
2667 { "PHB id code", "ldp.msg.tlv.diffserv.phbid.code", FT_UINT16, BASE_DEC,
2668 NULL, PHBID_CODE_MASK, PHBID_CODE_DESCRIPTION, HFILL}},
2670 { &hf_ldp_tlv_diffserv_phbid_bit14,
2671 { "Bit 14", "ldp.msg.tlv.diffserv.phbid.bit14", FT_UINT16, BASE_DEC,
2672 VALS(phbid_bit14_vals), PHBID_BIT14_MASK, PHBID_BIT14_DESCRIPTION, HFILL}},
2674 { &hf_ldp_tlv_diffserv_phbid_bit15,
2675 { "Bit 15", "ldp.msg.tlv.diffserv.phbid.bit15", FT_UINT16, BASE_DEC,
2676 VALS(phbid_bit15_vals), PHBID_BIT15_MASK, PHBID_BIT15_DESCRIPTION, HFILL}}
2680 static gint *ett[] = {
2688 &ett_ldp_fec_vc_interfaceparam,
2689 &ett_ldp_diffserv_map,
2690 &ett_ldp_diffserv_map_phbid
2692 module_t *ldp_module;
2694 proto_ldp = proto_register_protocol("Label Distribution Protocol",
2697 proto_register_field_array(proto_ldp, hf, array_length(hf));
2698 proto_register_subtree_array(ett, array_length(ett));
2700 /* Register our configuration options for , particularly our port */
2702 ldp_module = prefs_register_protocol(proto_ldp, proto_reg_handoff_ldp);
2704 prefs_register_uint_preference(ldp_module, "tcp.port", "LDP TCP Port",
2705 "Set the TCP port for messages (if other"
2706 " than the default of 646)",
2707 10, &global_ldp_tcp_port);
2709 prefs_register_uint_preference(ldp_module, "udp.port", "LDP UDP Port",
2710 "Set the UDP port for messages (if other"
2711 " than the default of 646)",
2712 10, &global_ldp_udp_port);
2714 prefs_register_bool_preference(ldp_module, "desegment_ldp_messages",
2715 "Desegment all LDP messages\nspanning multiple TCP segments",
2716 "Whether the LDP dissector should desegment all messages spanning multiple TCP segments",
2720 /* The registration hand-off routine */
2722 proto_reg_handoff_ldp(void)
2724 static gboolean ldp_prefs_initialized = FALSE;
2725 static dissector_handle_t ldp_tcp_handle, ldp_handle;
2727 if (!ldp_prefs_initialized) {
2729 ldp_tcp_handle = new_create_dissector_handle(dissect_ldp_tcp, proto_ldp);
2730 ldp_handle = new_create_dissector_handle(dissect_ldp, proto_ldp);
2732 ldp_prefs_initialized = TRUE;
2737 dissector_delete("tcp.port", tcp_port, ldp_tcp_handle);
2738 dissector_delete("udp.port", udp_port, ldp_handle);
2742 /* Set our port number for future use */
2744 tcp_port = global_ldp_tcp_port;
2745 udp_port = global_ldp_udp_port;
2747 dissector_add("tcp.port", global_ldp_tcp_port, ldp_tcp_handle);
2748 dissector_add("udp.port", global_ldp_udp_port, ldp_handle);