Eliminate some unused variables.
[obnox/wireshark/wip.git] / packet-rsvp.c
1 /* packet-rsvp.c
2  * Routines for RSVP packet disassembly
3  *
4  * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
5  *
6  * $Id: packet-rsvp.c,v 1.60 2002/04/14 23:22:21 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*
28  * NOTES
29  *
30  * This module defines routines to disassemble RSVP packets, as defined in
31  * RFC 2205. All objects from RC2205 are supported, in IPv4 and IPv6 mode.
32  * In addition, the Integrated Services traffic specification objects
33  * defined in RFC2210 are also supported. 
34  *
35  * IPv6 support is not completely tested
36  *
37  * Mar 3, 2000: Added support for MPLS/TE objects, as defined in 
38  * <draft-ietf-mpls-rsvp-lsp-tunnel-04.txt>
39  */
40
41  
42 #ifdef HAVE_CONFIG_H
43 # include "config.h"
44 #endif
45
46 #include <stdio.h>
47
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51
52 #include <stdlib.h>
53 #include <string.h>
54
55 #ifdef HAVE_SYS_TYPES_H
56 # include <sys/types.h>
57 #endif
58
59 #ifdef HAVE_NETINET_IN_H
60 # include <netinet/in.h>
61 #endif
62
63 #include <glib.h>
64
65 #ifdef NEED_SNPRINTF_H
66 # include "snprintf.h"
67 #endif
68
69 #include <epan/tvbuff.h>
70 #include <epan/packet.h>
71 #include "in_cksum.h"
72 #include "ieee-float.h"
73 #include "etypes.h"
74 #include "ipproto.h"
75
76 #include "packet-rsvp.h"
77 #include "packet-ip.h"
78
79 static int proto_rsvp = -1;
80
81 static gint ett_rsvp = -1;
82 static gint ett_rsvp_hdr = -1;
83 static gint ett_rsvp_session = -1;
84 static gint ett_rsvp_hop = -1;
85 static gint ett_rsvp_time_values = -1;
86 static gint ett_rsvp_error = -1;
87 static gint ett_rsvp_scope = -1;
88 static gint ett_rsvp_style = -1;
89 static gint ett_rsvp_confirm = -1;
90 static gint ett_rsvp_sender_template = -1;
91 static gint ett_rsvp_filter_spec = -1;
92 static gint ett_rsvp_sender_tspec = -1;
93 static gint ett_rsvp_sender_tspec_subtree = -1;
94 static gint ett_rsvp_flowspec = -1;
95 static gint ett_rsvp_flowspec_subtree = -1;
96 static gint ett_rsvp_adspec = -1;
97 static gint ett_rsvp_adspec_subtree = -1;
98 static gint ett_rsvp_integrity = -1;
99 static gint ett_rsvp_dclass = -1;
100 static gint ett_rsvp_lsp_tunnel_if_id = -1;
101 static gint ett_rsvp_policy = -1;
102 static gint ett_rsvp_label = -1;
103 static gint ett_rsvp_label_request = -1;
104 static gint ett_rsvp_session_attribute = -1;
105 static gint ett_rsvp_session_attribute_flags = -1;
106 static gint ett_rsvp_hello_obj = -1;
107 static gint ett_rsvp_explicit_route = -1;
108 static gint ett_rsvp_explicit_route_subobj = -1;
109 static gint ett_rsvp_record_route = -1;
110 static gint ett_rsvp_record_route_subobj = -1;
111 static gint ett_rsvp_hop_subobj = -1;
112 static gint ett_rsvp_admin_status = -1;
113 static gint ett_rsvp_admin_status_flags = -1;
114 static gint ett_rsvp_unknown_class = -1;
115
116
117 /*
118  * RSVP message types
119  */
120 typedef enum {
121     RSVP_MSG_PATH=1, 
122     RSVP_MSG_RESV, 
123     RSVP_MSG_PERR, 
124     RSVP_MSG_RERR,
125     RSVP_MSG_PTEAR, 
126     RSVP_MSG_RTEAR, 
127     RSVP_MSG_CONFIRM, 
128     RSVP_MSG_RTEAR_CONFIRM=10,
129     RSVP_MSG_BUNDLE = 12,
130     RSVP_MSG_ACK,
131     RSVP_MSG_SREFRESH = 15,
132     RSVP_MSG_HELLO = 20
133 } rsvp_message_types;
134
135 static value_string message_type_vals[] = { 
136     {RSVP_MSG_PATH, "PATH Message. "},
137     {RSVP_MSG_RESV, "RESV Message. "},
138     {RSVP_MSG_PERR, "PATH ERROR Message. "},
139     {RSVP_MSG_RERR, "RESV ERROR Message. "},
140     {RSVP_MSG_PTEAR, "PATH TEAR Message. "},
141     {RSVP_MSG_RTEAR, "RESV TEAR Message. "},
142     {RSVP_MSG_CONFIRM, "CONFIRM Message. "},
143     {RSVP_MSG_RTEAR_CONFIRM, "RESV TEAR CONFIRM Message. "},
144     {RSVP_MSG_BUNDLE, "BUNDLE Message. "},
145     {RSVP_MSG_ACK, "ACK Message. "},
146     {RSVP_MSG_SREFRESH, "SREFRESH Message. "},
147     {RSVP_MSG_HELLO, "HELLO Message. "},
148     {0, NULL}
149 };
150
151 /* 
152  * RSVP classes
153  */
154 #define MAX_RSVP_CLASS 15
155
156 enum rsvp_classes {
157     RSVP_CLASS_NULL=0,
158     RSVP_CLASS_SESSION,
159
160     RSVP_CLASS_HOP=3,
161     RSVP_CLASS_INTEGRITY,
162     RSVP_CLASS_TIME_VALUES,
163     RSVP_CLASS_ERROR,
164     RSVP_CLASS_SCOPE,
165     RSVP_CLASS_STYLE,
166     RSVP_CLASS_FLOWSPEC,
167     RSVP_CLASS_FILTER_SPEC,
168     RSVP_CLASS_SENDER_TEMPLATE,
169     RSVP_CLASS_SENDER_TSPEC,
170     RSVP_CLASS_ADSPEC,
171     RSVP_CLASS_POLICY,
172     RSVP_CLASS_CONFIRM,
173     RSVP_CLASS_LABEL,
174
175     RSVP_CLASS_LABEL_REQUEST=19,
176     RSVP_CLASS_EXPLICIT_ROUTE,
177     RSVP_CLASS_RECORD_ROUTE,
178
179     RSVP_CLASS_HELLO,
180
181     RSVP_CLASS_MESSAGE_ID,
182     RSVP_CLASS_MESSAGE_ID_ACK,
183     RSVP_CLASS_MESSAGE_ID_LIST,
184
185     RSVP_CLASS_RECOVERY_LABEL = 34,
186     RSVP_CLASS_UPSTREAM_LABEL,
187     RSVP_CLASS_LABEL_SET,
188     RSVP_CLASS_PROTECTION,
189
190     RSVP_CLASS_SUGGESTED_LABEL = 129,
191     RSVP_CLASS_ACCEPTABLE_LABEL_SET,
192     RSVP_CLASS_RESTART_CAP,
193
194     RSVP_CLASS_NOTIFY_REQUEST = 195,
195     RSVP_CLASS_ADMIN_STATUS,
196
197     RSVP_CLASS_SESSION_ATTRIBUTE = 207,
198     RSVP_CLASS_DCLASS = 225,
199     RSVP_CLASS_LSP_TUNNEL_IF_ID = 227,
200 };
201
202 static value_string rsvp_class_vals[] = { 
203     {RSVP_CLASS_NULL, "NULL object"},
204     {RSVP_CLASS_SESSION, "SESSION object"},
205     {RSVP_CLASS_HOP, "HOP object"},
206     {RSVP_CLASS_INTEGRITY, "INTEGRITY object"},
207     {RSVP_CLASS_TIME_VALUES, "TIME VALUES object"},
208     {RSVP_CLASS_ERROR, "ERROR object"},
209     {RSVP_CLASS_SCOPE, "SCOPE object"},
210     {RSVP_CLASS_STYLE, "STYLE object"},
211     {RSVP_CLASS_FLOWSPEC, "FLOWSPEC object"},
212     {RSVP_CLASS_FILTER_SPEC, "FILTER SPEC object"},
213     {RSVP_CLASS_SENDER_TEMPLATE, "SENDER TEMPLATE object"},
214     {RSVP_CLASS_SENDER_TSPEC, "SENDER TSPEC object"},
215     {RSVP_CLASS_ADSPEC, "ADSPEC object"},
216     {RSVP_CLASS_POLICY, "POLICY object"},
217     {RSVP_CLASS_CONFIRM, "CONFIRM object"},
218     {RSVP_CLASS_LABEL, "LABEL object"},
219     {RSVP_CLASS_LABEL_REQUEST, "LABEL REQUEST object"},
220     {RSVP_CLASS_EXPLICIT_ROUTE, "EXPLICIT ROUTE object"},
221     {RSVP_CLASS_RECORD_ROUTE, "RECORD ROUTE object"},
222     {RSVP_CLASS_SESSION_ATTRIBUTE, "SESSION ATTRIBUTE object"},
223     {RSVP_CLASS_MESSAGE_ID, "MESSAGE-ID object"},
224     {RSVP_CLASS_MESSAGE_ID_ACK, "MESSAGE-ID ACK/NACK object"},
225     {RSVP_CLASS_MESSAGE_ID_LIST, "MESSAGE-ID LIST object"},
226     {RSVP_CLASS_HELLO, "HELLO object"},
227     {RSVP_CLASS_RECOVERY_LABEL, "RECOVERY-LABEL object"},
228     {RSVP_CLASS_UPSTREAM_LABEL, "UPSTREAM-LABEL object"},
229     {RSVP_CLASS_LABEL_SET, "LABEL-SET object"},
230     {RSVP_CLASS_PROTECTION, "PROTECTION object"},
231     {RSVP_CLASS_SUGGESTED_LABEL, "SUGGESTED-LABEL object"},
232     {RSVP_CLASS_ACCEPTABLE_LABEL_SET, "ACCEPTABLE-LABEL-SET object"},
233     {RSVP_CLASS_RESTART_CAP, "RESTART-CAPABILITY object"},
234     {RSVP_CLASS_DCLASS, "DCLASS object"},
235     {RSVP_CLASS_LSP_TUNNEL_IF_ID, "LSP-TUNNEL INTERFACE-ID object"},
236     {RSVP_CLASS_NOTIFY_REQUEST, "NOTIFY-REQUEST object"},
237     {RSVP_CLASS_ADMIN_STATUS, "ADMIN-STATUS object"},
238     {0, NULL}
239 };
240
241 /*
242  * RSVP error values
243  */
244 enum rsvp_error_types {
245     RSVP_ERROR_CONFIRM = 0,
246     RSVP_ERROR_ADMISSION,
247     RSVP_ERROR_POLICY,
248     RSVP_ERROR_NO_PATH,
249     RSVP_ERROR_NO_SENDER,
250     RSVP_ERROR_CONFLICT_RESV_STYLE,
251     RSVP_ERROR_UNKNOWN_RESV_STYLE,
252     RSVP_ERROR_CONFLICT_DEST_PORTS,
253     RSVP_ERROR_CONFLICT_SRC_PORTS,
254     RSVP_ERROR_PREEMPTED=12,
255     RSVP_ERROR_UNKNOWN_CLASS,
256     RSVP_ERROR_UNKNOWN_C_TYPE,
257     RSVP_ERROR_TRAFFIC = 21,
258     RSVP_ERROR_TRAFFIC_SYSTEM,
259     RSVP_ERROR_SYSTEM,
260     RSVP_ERROR_ROUTING,
261     RSVP_ERROR_NOTIFY
262 };
263
264 static value_string rsvp_error_vals[] = {
265     {RSVP_ERROR_CONFIRM, "Confirmation"},
266     {RSVP_ERROR_ADMISSION, "Admission Control Failure "},
267     {RSVP_ERROR_POLICY, "Policy Control Failure"},
268     {RSVP_ERROR_NO_PATH, "No PATH information for this RESV message"},
269     {RSVP_ERROR_NO_SENDER, "No sender information for this RESV message"},
270     {RSVP_ERROR_CONFLICT_RESV_STYLE, "Conflicting reservation styles"},
271     {RSVP_ERROR_UNKNOWN_RESV_STYLE, "Unknown reservation style"},
272     {RSVP_ERROR_CONFLICT_DEST_PORTS, "Conflicting destination ports"},
273     {RSVP_ERROR_CONFLICT_SRC_PORTS, "Conflicting source ports"},
274     {RSVP_ERROR_PREEMPTED, "Service preempted"},
275     {RSVP_ERROR_UNKNOWN_CLASS, "Unknown object class"},
276     {RSVP_ERROR_UNKNOWN_C_TYPE, "Unknown object C-type"},
277     {RSVP_ERROR_TRAFFIC, "Traffic Control Error"},
278     {RSVP_ERROR_TRAFFIC_SYSTEM, "Traffic Control System Error"},
279     {RSVP_ERROR_SYSTEM, "RSVP System Error"},
280     {RSVP_ERROR_ROUTING, "Routing Error"},
281     {RSVP_ERROR_NOTIFY, "RSVP Notify Error"},
282     {0, NULL}
283 };
284
285 /*
286  * Defines the reservation style plus style-specific information that
287  * is not a FLOWSPEC or FILTER_SPEC object, in a RESV message.
288  */
289 #define RSVP_DISTINCT (1 << 3)
290 #define RSVP_SHARED (2 << 3)
291 #define RSVP_SHARING_MASK (RSVP_DISTINCT | RSVP_SHARED)
292
293 #define RSVP_SCOPE_WILD 1
294 #define RSVP_SCOPE_EXPLICIT 2
295 #define RSVP_SCOPE_MASK 0x07
296
297 #define RSVP_WF (RSVP_SHARED | RSVP_SCOPE_WILD)
298 #define RSVP_FF (RSVP_DISTINCT | RSVP_SCOPE_EXPLICIT)
299 #define RSVP_SE (RSVP_SHARED | RSVP_SCOPE_EXPLICIT)
300
301 static value_string style_vals[] = {
302     { RSVP_WF, "Wildcard Filter" },
303     { RSVP_FF, "Fixed Filter" },
304     { RSVP_SE, "Shared-Explicit" },
305     { 0,       NULL }
306 };
307
308 /*
309  * Defines a desired QoS, in a RESV message.
310  */
311 enum    qos_service_type {
312     QOS_QUALITATIVE =     128,          /* Qualitative service */
313     QOS_NULL =              6,          /* Null service (RFC2997) */
314     QOS_CONTROLLED_LOAD=    5,          /* Controlled Load Service */
315     QOS_GUARANTEED =        2,          /* Guaranteed service */
316     QOS_TSPEC =             1           /* Traffic specification */
317     };
318
319 static value_string qos_vals[] = {
320     { QOS_QUALITATIVE, "Qualitative QoS" },
321     { QOS_NULL, "Null-Service QoS" },
322     { QOS_CONTROLLED_LOAD, "Controlled-load QoS" },
323     { QOS_GUARANTEED, "Guaranteed rate QoS" },
324     { QOS_TSPEC, "Traffic specification" },
325     { 0, NULL }
326 };
327
328 static value_string svc_vals[] = {
329     { 126, "Compression Hint" },
330     { 127, "Token bucket" },
331     { 128, "Null Service" },
332     { 130, "Guaranteed-rate RSpec" },
333     { 0, NULL }
334 };
335
336 enum rsvp_spec_types { INTSRV = 2 };
337
338 enum intsrv_services {
339         INTSRV_GENERAL = 1,
340         INTSRV_GTD = 2,
341         INTSRV_CLOAD = 5,
342         INTSRV_NULL = 6,
343         INTSRV_QUALITATIVE = 128
344 };
345
346 static value_string intsrv_services_str[] = { 
347     {INTSRV_GENERAL, "Default General Parameters"},
348     {INTSRV_GTD, "Guaranteed Rate"},
349     {INTSRV_CLOAD, "Controlled Load"},
350     {INTSRV_NULL, "Null Service"},
351     {INTSRV_QUALITATIVE, "Null Service"},
352     { 0, NULL }
353 };
354
355 #if 0
356 enum intsrv_field_name {
357         INTSRV_NON_IS_HOPS = 1, INTSRV_COMPOSED_NON_IS_HOPS,
358         INTSRV_IS_HOPS, INTSRV_COMPOSED_IS_HOPS,
359         INTSRV_PATH_BANDWIDTH, INTSRV_MIN_PATH_BANDWIDTH,
360         INTSRV_IF_LATENCY, INTSRV_PATH_LATENCY,
361         INTSRV_MTU, INTSRV_COMPOSED_MTU,
362
363         INTSRV_TOKEN_BUCKET_TSPEC = 127,
364         INTSRV_QUALITATIVE_TSPEC = 128,
365         INTSRV_GTD_RSPEC = 130,
366
367         INTSRV_DELAY = 131,     /* Gtd Parameter C - Max Delay Bound - bytes */
368         INTSRV_MAX_JITTER,      /* Gtd Parameter D - Max Jitter */
369         INTSRV_E2E_DELAY,       /* Gtd Parameter Ctot */
370         INTSRV_E2E_MAX_JITTER,  /* Gtd Parameter Dtot */
371         INTSRV_SHP_DELAY,       /* Gtd Parameter Csum */
372         INTSRV_SHP_MAX_JITTER   /* Gtd Parameter Dsum */
373 };
374 #endif
375
376 static value_string adspec_params[] = { 
377     {4, "IS Hop Count"},
378     {6, "Path b/w estimate"},
379     {8, "Minimum path latency"},
380     {10, "Composed MTU"},
381     {133, "End-to-end composed value for C"},
382     {134, "End-to-end composed value for D"},
383     {135, "Since-last-reshaping point composed C"},
384     {136, "Since-last-reshaping point composed D"},
385     { 0, NULL }
386 };
387
388 const value_string gmpls_lsp_enc_str[] = {
389     { 1, "Packet"},
390     { 2, "Ethernet v2/DIX"},
391     { 3, "ANSI PDH"},
392     { 4, "ETSI PDH"},
393     { 5, "SDH ITU-T G.707"},
394     { 6, "SONET ANSI T1.105"},
395     { 7, "Digital Wrapper"},
396     { 8, "Lambda (photonic)"},
397     { 9, "Fiber"},
398     {10, "Ethernet 802.3"},
399     {11, "FiberChannel"},
400     { 0, NULL }
401 };
402
403 const value_string gmpls_switching_type_str[] = {
404     {  1, "Packet-Switch Capable-1 (PSC-1)"},
405     {  2, "Packet-Switch Capable-2 (PSC-2)"},
406     {  3, "Packet-Switch Capable-3 (PSC-3)"},
407     {  4, "Packet-Switch Capable-4 (PSC-4)"},
408     { 51, "Layer-2 Switch Capable (L2SC)"},
409     {100, "Time-Division-Multiplex Capable (TDM)"},
410     {150, "Lambda-Switch Capable (LSC)"},
411     {200, "Fiber-Switch Capable (FSC)"},
412     { 0, NULL }
413 };
414
415 static const value_string gmpls_gpid_str[] = {
416     { 5, "Asynchronous mapping of E3 (SONET, SDH)"},
417     { 8, "Bit synchronous mapping of E3 (SDH)"},
418     { 9, "Byte synchronous mapping of E3 (SDH)"},
419     {10, "Asynchronous mapping of DS2/T2 (SONET, SDH)"},
420     {11, "Bit synchronous mapping of DS2/T2 (SONET, SDH)"},
421     {13, "Asynchronous mapping of E1 (SONET, SDH)"},
422     {14, "Byte synchronous mapping of E1 (SONET, SDH)"},
423     {15, "Byte synchronous mapping of 31 * DS0 (SONET, SDH)"},
424     {16, "Asynchronous mapping of DS1/T1 (SONET, SDH)"},
425     {17, "Bit synchronous mapping of DS1/T1 (SONET, SDH)"},
426     {18, "Byte synchronous mapping of DS1/T1 (SONET, SDH)"},
427     {19, "VC-11 in VC-12 (SDH)"},
428     {22, "DS1 SF Asynchronous (SONET)"},
429     {23, "DS1 ESF Asynchronous (SONET)"},
430     {24, "DS3 M23 Asynchronous (SONET)"},
431     {25, "DS3 C-Bit Parity Asynchronous (SONET)"},
432     {26, "VT/LOVC (SONET, SDH)"},
433     {27, "STS SPE/HOVC (SONET, SDH)"},
434     {28, "POS - No Scrambling, 16 bit CRC (SONET, SDH)"},
435     {29, "POS - No Scrambling, 32 bit CRC (SONET, SDH)"},
436     {30, "POS - Scrambling, 16 bit CRC (SONET, SDH)"},
437     {31, "POS - Scrambling, 32 bit CRC (SONET, SDH)"},
438     {32, "ATM Mapping (SONET, SDH)"},
439     {33, "Ethernet (SDH, Lambda, Fiber)"},
440     {34, "SDH (Lambda, Fiber)"},
441     {35, "SONET (Lambda, Fiber)"},
442     {36, "Digital Wrapper (Lambda, Fiber)"},
443     {37, "Lambda (Fiber)"},
444     {38, "ETSI PDH (SDH)"},
445     {39, "ANSI PDH (SONET, SDH)"},
446     {40, "Link Access Protocol SDH: LAPS - X.85 and X.86 (SONET, SDH)"},
447     {41, "FDDI (SONET, SDH, Lambda, Fiber)"},
448     {42, "DQDB: ETSI ETS 300 216 (SONET, SDH)"},
449     {43, "FiberChannel-3 Services (FiberChannel)"},
450     { 0, NULL },
451 };
452
453 /* -------------------- Stuff for MPLS/TE objects -------------------- */
454
455 static const value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"},
456                                            {IP_PROTO_IGMP, "IGMP"},
457                                            {IP_PROTO_TCP,  "TCP" },
458                                            {IP_PROTO_UDP,  "UDP" },
459                                            {IP_PROTO_OSPF, "OSPF"},
460                                            {0,             NULL  } };
461
462 /* Filter keys */
463 enum rsvp_filter_keys {
464
465     /* Message types */
466     RSVPF_MSG,          /* Message type */
467     /* Shorthand for message types */
468     RSVPF_PATH,
469     RSVPF_RESV,
470     RSVPF_PATHERR,
471     RSVPF_RESVERR,
472     RSVPF_PATHTEAR,
473     RSVPF_RESVTEAR,
474     RSVPF_RCONFIRM,
475     RSVPF_JUNK_MSG8,
476     RSVPF_JUNK_MSG9,
477     RSVPF_RTEARCONFIRM,
478     RSVPF_JUNK11,
479     RSVPF_BUNDLE,
480     RSVPF_ACK,
481     RSVPF_JUNK14,
482     RSVPF_SREFRESH,
483     RSVPF_HELLO,
484     /* Does the message contain an object of this type? */
485     RSVPF_OBJECT,
486     /* Object present shorthands */
487     RSVPF_SESSION,
488     RSVPF_DUMMY_1,
489     RSVPF_HOP,
490     RSVPF_INTEGRITY,
491     RSVPF_TIME_VALUES,
492     RSVPF_ERROR,
493     RSVPF_SCOPE,
494     RSVPF_STYLE,
495     RSVPF_FLOWSPEC,
496     RSVPF_FILTER_SPEC,
497     RSVPF_SENDER,
498     RSVPF_TSPEC,
499     RSVPF_ADSPEC,
500     RSVPF_POLICY,
501     RSVPF_CONFIRM,
502     RSVPF_LABEL,
503     RSVPF_DUMMY_2,
504     RSVPF_DUMMY_3,
505     RSVPF_LABEL_REQUEST,
506     RSVPF_EXPLICIT_ROUTE,
507     RSVPF_RECORD_ROUTE,
508     RSVPF_HELLO_OBJ,
509     RSVPF_MESSAGE_ID,
510     RSVPF_MESSAGE_ID_ACK,
511     RSVPF_MESSAGE_ID_LIST,
512     RSVPF_RECOVERY_LABEL,
513     RSVPF_UPSTREAM_LABEL,
514     RSVPF_LABEL_SET,
515     RSVPF_PROTECTION,
516
517     RSVPF_SUGGESTED_LABEL,
518     RSVPF_ACCEPTABLE_LABEL_SET,
519     RSVPF_RESTART_CAP,
520
521     RSVPF_SESSION_ATTRIBUTE,
522     RSVPF_DCLASS,
523     RSVPF_LSP_TUNNEL_IF_ID,
524     RSVPF_NOTIFY_REQUEST,
525     RSVPF_ADMIN_STATUS,
526     RSVPF_UNKNOWN_OBJ, 
527
528     /* Session object */
529     RSVPF_SESSION_IP,
530     RSVPF_SESSION_PROTO,
531     RSVPF_SESSION_PORT,
532     RSVPF_SESSION_TUNNEL_ID,
533     RSVPF_SESSION_EXT_TUNNEL_ID,
534
535     /* Sender template */
536     RSVPF_SENDER_IP,
537     RSVPF_SENDER_PORT,
538     RSVPF_SENDER_LSP_ID,
539
540     /* Sentinel */
541     RSVPF_MAX
542 };
543
544 static int rsvp_filter[RSVPF_MAX];
545
546 static hf_register_info rsvpf_info[] = {
547
548     /* Message type number */
549     {&rsvp_filter[RSVPF_MSG], 
550      { "Message Type", "rsvp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
551         "", HFILL }},
552
553     /* Message type shorthands */
554     {&rsvp_filter[RSVPF_PATH], 
555      { "Path Message", "rsvp.path", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
556         "", HFILL }},
557
558     {&rsvp_filter[RSVPF_HELLO], 
559      { "HELLO Message", "rsvp.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
560         "", HFILL }},
561
562     {&rsvp_filter[RSVPF_RESV], 
563      { "Resv Message", "rsvp.resv", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
564         "", HFILL }},
565
566     {&rsvp_filter[RSVPF_PATHERR], 
567      { "Path Error Message", "rsvp.perr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
568         "", HFILL }},
569
570     {&rsvp_filter[RSVPF_RESVERR], 
571      { "Resv Error Message", "rsvp.rerr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
572         "", HFILL }},
573
574     {&rsvp_filter[RSVPF_PATHTEAR], 
575      { "Path Tear Message", "rsvp.ptear", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
576         "", HFILL }},
577
578     {&rsvp_filter[RSVPF_RESVTEAR], 
579      { "Resv Tear Message", "rsvp.rtear", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
580         "", HFILL }},
581
582     {&rsvp_filter[RSVPF_RCONFIRM], 
583      { "Resv Confirm Message", "rsvp.resvconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
584         "", HFILL }},
585
586     {&rsvp_filter[RSVPF_RTEARCONFIRM], 
587      { "Resv Tear Confirm Message", "rsvp.rtearconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
588         "", HFILL }},
589
590     /* Object class */
591     {&rsvp_filter[RSVPF_OBJECT], 
592      { "Object class", "rsvp.object", FT_UINT8, BASE_DEC, VALS(rsvp_class_vals), 0x0,
593         "", HFILL }},
594
595     /* Object present shorthands */
596     {&rsvp_filter[RSVPF_SESSION], 
597      { "SESSION", "rsvp.session", FT_NONE, BASE_NONE, NULL, 0x0,
598         "", HFILL }},
599
600     {&rsvp_filter[RSVPF_HOP], 
601      { "HOP", "rsvp.hop", FT_NONE, BASE_NONE, NULL, 0x0,
602         "", HFILL }},
603
604     {&rsvp_filter[RSVPF_HELLO_OBJ], 
605      { "HELLO Request/Ack", "rsvp.hello_obj", FT_NONE, BASE_NONE, NULL, 0x0,
606         "", HFILL }},
607
608     {&rsvp_filter[RSVPF_INTEGRITY], 
609      { "INTEGRITY", "rsvp.integrity", FT_NONE, BASE_NONE, NULL, 0x0,
610         "", HFILL }},
611
612     {&rsvp_filter[RSVPF_TIME_VALUES], 
613      { "TIME VALUES", "rsvp.time", FT_NONE, BASE_NONE, NULL, 0x0,
614         "", HFILL }},
615
616     {&rsvp_filter[RSVPF_ERROR], 
617      { "ERROR", "rsvp.error", FT_NONE, BASE_NONE, NULL, 0x0,
618         "", HFILL }},
619
620     {&rsvp_filter[RSVPF_SCOPE], 
621      { "SCOPE", "rsvp.scope", FT_NONE, BASE_NONE, NULL, 0x0,
622         "", HFILL }},
623
624     {&rsvp_filter[RSVPF_STYLE], 
625      { "STYLE", "rsvp.style", FT_NONE, BASE_NONE, NULL, 0x0,
626         "", HFILL }},
627
628     {&rsvp_filter[RSVPF_FLOWSPEC], 
629      { "FLOWSPEC", "rsvp.flowspec", FT_NONE, BASE_NONE, NULL, 0x0,
630         "", HFILL }},
631
632     {&rsvp_filter[RSVPF_FILTER_SPEC], 
633      { "FILTERSPEC", "rsvp.filter", FT_NONE, BASE_NONE, NULL, 0x0,
634         "", HFILL }},
635
636     {&rsvp_filter[RSVPF_SENDER], 
637      { "SENDER TEMPLATE", "rsvp.sender", FT_NONE, BASE_NONE, NULL, 0x0,
638         "", HFILL }},
639
640     {&rsvp_filter[RSVPF_TSPEC], 
641      { "SENDER TSPEC", "rsvp.tspec", FT_NONE, BASE_NONE, NULL, 0x0,
642         "", HFILL }},
643
644     {&rsvp_filter[RSVPF_ADSPEC], 
645      { "ADSPEC", "rsvp.adspec", FT_NONE, BASE_NONE, NULL, 0x0,
646         "", HFILL }},
647
648     {&rsvp_filter[RSVPF_POLICY], 
649      { "POLICY", "rsvp.policy", FT_NONE, BASE_NONE, NULL, 0x0,
650         "", HFILL }},
651
652     {&rsvp_filter[RSVPF_CONFIRM], 
653      { "CONFIRM", "rsvp.confirm", FT_NONE, BASE_NONE, NULL, 0x0,
654         "", HFILL }},
655
656     {&rsvp_filter[RSVPF_LABEL], 
657      { "LABEL", "rsvp.label", FT_NONE, BASE_NONE, NULL, 0x0,
658         "", HFILL }},
659
660     {&rsvp_filter[RSVPF_RECOVERY_LABEL], 
661      { "RECOVERY LABEL", "rsvp.recovery_label", FT_NONE, BASE_NONE, NULL, 0x0,
662         "", HFILL }},
663
664     {&rsvp_filter[RSVPF_UPSTREAM_LABEL], 
665      { "UPSTREAM LABEL", "rsvp.upstream_label", FT_NONE, BASE_NONE, NULL, 0x0,
666         "", HFILL }},
667
668     {&rsvp_filter[RSVPF_SUGGESTED_LABEL], 
669      { "SUGGESTED LABEL", "rsvp.suggested_label", FT_NONE, BASE_NONE, NULL, 0x0,
670         "", HFILL }},
671
672     {&rsvp_filter[RSVPF_LABEL_SET], 
673      { "RESTRICTED LABEL SET", "rsvp.label_set", FT_NONE, BASE_NONE, NULL, 0x0,
674         "", HFILL }},
675
676     {&rsvp_filter[RSVPF_ACCEPTABLE_LABEL_SET], 
677      { "ACCEPTABLE LABEL SET", "rsvp.acceptable_label_set", FT_NONE, BASE_NONE, NULL, 0x0,
678         "", HFILL }},
679
680     {&rsvp_filter[RSVPF_PROTECTION], 
681      { "PROTECTION", "rsvp.protection", FT_NONE, BASE_NONE, NULL, 0x0,
682         "", HFILL }},
683
684     {&rsvp_filter[RSVPF_RESTART_CAP], 
685      { "RESTART CAPABILITY", "rsvp.restart", FT_NONE, BASE_NONE, NULL, 0x0,
686         "", HFILL }},
687
688     {&rsvp_filter[RSVPF_LABEL_REQUEST], 
689      { "LABEL REQUEST", "rsvp.label_request", FT_NONE, BASE_NONE, NULL, 0x0,
690         "", HFILL }},
691
692     {&rsvp_filter[RSVPF_SESSION_ATTRIBUTE], 
693      { "SESSION ATTRIBUTE", "rsvp.session_attribute", FT_NONE, BASE_NONE, NULL, 0x0,
694         "", HFILL }},
695
696     {&rsvp_filter[RSVPF_EXPLICIT_ROUTE], 
697      { "EXPLICIT ROUTE", "rsvp.explicit_route", FT_NONE, BASE_NONE, NULL, 0x0,
698         "", HFILL }},
699
700     {&rsvp_filter[RSVPF_RECORD_ROUTE], 
701      { "RECORD ROUTE", "rsvp.record_route", FT_NONE, BASE_NONE, NULL, 0x0,
702         "", HFILL }},
703
704     {&rsvp_filter[RSVPF_MESSAGE_ID], 
705      { "MESSAGE-ID", "rsvp.msgid", FT_NONE, BASE_NONE, NULL, 0x0,
706         "", HFILL }},
707
708     {&rsvp_filter[RSVPF_MESSAGE_ID_ACK], 
709      { "MESSAGE-ID ACK", "rsvp.ack", FT_NONE, BASE_NONE, NULL, 0x0,
710         "", HFILL }},
711
712     {&rsvp_filter[RSVPF_MESSAGE_ID_LIST], 
713      { "MESSAGE-ID LIST", "rsvp.msgid_list", FT_NONE, BASE_NONE, NULL, 0x0,
714         "", HFILL }},
715
716     {&rsvp_filter[RSVPF_HELLO_OBJ], 
717      { "HELLO", "rsvp.hello", FT_NONE, BASE_NONE, NULL, 0x0,
718         "", HFILL }},
719
720     {&rsvp_filter[RSVPF_DCLASS], 
721      { "DCLASS", "rsvp.dclass", FT_NONE, BASE_NONE, NULL, 0x0,
722         "", HFILL }},
723
724     {&rsvp_filter[RSVPF_LSP_TUNNEL_IF_ID], 
725      { "LSP INTERFACE-ID", "rsvp.lsp_tunnel_if_id", FT_NONE, BASE_NONE, NULL, 0x0,
726         "", HFILL }},
727
728     {&rsvp_filter[RSVPF_ADMIN_STATUS], 
729      { "ADMIN STATUS", "rsvp.admin_status", FT_NONE, BASE_NONE, NULL, 0x0,
730         "", HFILL }},
731
732     {&rsvp_filter[RSVPF_NOTIFY_REQUEST], 
733      { "NOTIFY REQUEST", "rsvp.notify_request", FT_NONE, BASE_NONE, NULL, 0x0,
734         "", HFILL }},
735
736     {&rsvp_filter[RSVPF_UNKNOWN_OBJ], 
737      { "Unknown object", "rsvp.obj_unknown", FT_NONE, BASE_NONE, NULL, 0x0,
738         "", HFILL }},
739
740     /* Session fields */
741     {&rsvp_filter[RSVPF_SESSION_IP], 
742      { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
743         "", HFILL }},
744
745     {&rsvp_filter[RSVPF_SESSION_PORT], 
746      { "Port number", "rsvp.session.port", FT_UINT16, BASE_DEC, NULL, 0x0,
747         "", HFILL }},
748
749     {&rsvp_filter[RSVPF_SESSION_PROTO], 
750      { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_DEC, VALS(proto_vals), 0x0,
751         "", HFILL }},
752
753     {&rsvp_filter[RSVPF_SESSION_TUNNEL_ID], 
754      { "Tunnel ID", "rsvp.session.tunnel_id", FT_UINT16, BASE_DEC, NULL, 0x0,
755         "", HFILL }},
756
757     {&rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID], 
758      { "Extended tunnel ID", "rsvp.session.ext_tunnel_id", FT_UINT32, BASE_DEC, NULL, 0x0,
759         "", HFILL }},
760
761     /* Sender template/Filterspec fields */
762     {&rsvp_filter[RSVPF_SENDER_IP], 
763      { "Sender IPv4 address", "rsvp.sender.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
764         "", HFILL }},
765
766     {&rsvp_filter[RSVPF_SENDER_PORT], 
767      { "Sender port number", "rsvp.sender.port", FT_UINT16, BASE_DEC, NULL, 0x0,
768        "", HFILL }},
769
770     {&rsvp_filter[RSVPF_SENDER_LSP_ID], 
771      { "Sender LSP ID", "rsvp.sender.lsp_id", FT_UINT16, BASE_DEC, NULL, 0x0,
772         "", HFILL }}
773 };
774
775 static inline int rsvp_class_to_filter_num(int classnum)
776 {
777     switch(classnum) {
778     case RSVP_CLASS_SESSION :
779     case RSVP_CLASS_HOP :
780     case RSVP_CLASS_INTEGRITY :
781     case RSVP_CLASS_TIME_VALUES :
782     case RSVP_CLASS_ERROR :
783     case RSVP_CLASS_SCOPE :
784     case RSVP_CLASS_STYLE :
785     case RSVP_CLASS_FLOWSPEC :
786     case RSVP_CLASS_FILTER_SPEC :
787     case RSVP_CLASS_SENDER_TEMPLATE :
788     case RSVP_CLASS_SENDER_TSPEC :
789     case RSVP_CLASS_ADSPEC :
790     case RSVP_CLASS_POLICY :
791     case RSVP_CLASS_CONFIRM :
792     case RSVP_CLASS_LABEL :
793     case RSVP_CLASS_LABEL_REQUEST :
794     case RSVP_CLASS_HELLO :
795     case RSVP_CLASS_EXPLICIT_ROUTE :
796     case RSVP_CLASS_RECORD_ROUTE :
797     case RSVP_CLASS_MESSAGE_ID :
798     case RSVP_CLASS_MESSAGE_ID_ACK :
799     case RSVP_CLASS_MESSAGE_ID_LIST :    
800         return classnum + RSVPF_OBJECT;
801         break;
802
803     case RSVP_CLASS_RECOVERY_LABEL :
804     case RSVP_CLASS_UPSTREAM_LABEL :
805     case RSVP_CLASS_LABEL_SET :
806     case RSVP_CLASS_PROTECTION :
807         return RSVPF_RECOVERY_LABEL + (classnum - RSVP_CLASS_RECOVERY_LABEL);
808
809     case RSVP_CLASS_SUGGESTED_LABEL :
810     case RSVP_CLASS_ACCEPTABLE_LABEL_SET :
811     case RSVP_CLASS_RESTART_CAP :
812         return RSVPF_SUGGESTED_LABEL + (classnum - RSVP_CLASS_SUGGESTED_LABEL);
813
814     case RSVP_CLASS_NOTIFY_REQUEST :
815     case RSVP_CLASS_ADMIN_STATUS :
816         return RSVPF_NOTIFY_REQUEST + (classnum - RSVP_CLASS_NOTIFY_REQUEST);
817
818     case RSVP_CLASS_SESSION_ATTRIBUTE :
819         return RSVPF_SESSION_ATTRIBUTE;
820     case RSVP_CLASS_DCLASS :
821         return RSVPF_DCLASS;
822     case RSVP_CLASS_LSP_TUNNEL_IF_ID :
823         return RSVPF_LSP_TUNNEL_IF_ID;
824         
825     default:
826         return RSVPF_UNKNOWN_OBJ;
827     }
828 }
829
830 static void
831 find_rsvp_session_tempfilt(tvbuff_t *tvb, int hdr_offset, int *session_offp, int *tempfilt_offp)
832 {
833     int s_off = 0, t_off = 0;
834     int len, off;
835
836     if (!tvb)
837         goto done;
838
839     len = tvb_get_ntohs(tvb, hdr_offset+6) + hdr_offset;
840     off = hdr_offset + 8;
841     for (off = hdr_offset + 8; off < len; off += tvb_get_ntohs(tvb, off)) {
842         switch(tvb_get_guint8(tvb, off+2)) {
843         case RSVP_CLASS_SESSION:
844             s_off = off;
845             break;
846         case RSVP_CLASS_SENDER_TEMPLATE:
847         case RSVP_CLASS_FILTER_SPEC:
848             t_off = off;
849             break;
850         default:
851             break;
852         }
853     }
854
855  done:
856     if (session_offp) *session_offp = s_off;
857     if (tempfilt_offp) *tempfilt_offp = t_off;
858 }
859
860 static char *summary_session (tvbuff_t *tvb, int offset)
861 {
862     static char buf[80];
863
864     switch(tvb_get_guint8(tvb, offset+3)) {
865     case 1:
866         snprintf(buf, 80, "SESSION: IPv4, Destination %s, Protocol %d, Port %d. ", 
867                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), 
868                  tvb_get_guint8(tvb, offset+8),
869                  tvb_get_ntohs(tvb, offset+10));
870         break;
871     case 7:
872         snprintf(buf, 80, "SESSION: IPv4-LSP, Destination %s, Tunnel ID %d, Ext ID %0x. ", 
873                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), 
874                  tvb_get_ntohs(tvb, offset+10),
875                  tvb_get_ntohl(tvb, offset+12));
876         break;
877     default:
878         snprintf(buf, 80, "SESSION: Type %d. ", tvb_get_guint8(tvb, offset+3));
879     }
880
881     return buf;
882 }
883
884 static char *summary_template (tvbuff_t *tvb, int offset)
885 {
886     static char buf[80];
887     char *objtype;
888
889     if (tvb_get_guint8(tvb, offset+2) == RSVP_CLASS_FILTER_SPEC)
890         objtype = "FILTERSPEC";
891     else
892         objtype = "SENDER TEMPLATE";
893
894     switch(tvb_get_guint8(tvb, offset+3)) {
895     case 1:
896         snprintf(buf, 80, "%s: IPv4, Sender %s, Port %d. ", objtype,
897                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), 
898                  tvb_get_ntohs(tvb, offset+10));
899         break;
900     case 7:
901         snprintf(buf, 80, "%s: IPv4-LSP, Tunnel Source: %s, LSP ID: %d. ", objtype,
902                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), 
903                  tvb_get_ntohs(tvb, offset+10));
904         break;
905     default:
906         snprintf(buf, 80, "%s: Type %d. ", objtype, tvb_get_guint8(tvb, offset+3));
907     }
908
909     return buf;
910 }
911
912 static void 
913 dissect_rsvp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
914 {
915     int offset = 0;
916     proto_tree *rsvp_tree = NULL, *ti, *ti2; 
917     proto_tree *rsvp_header_tree;
918     proto_tree *rsvp_object_tree;
919     proto_tree *rsvp_sa_flags_tree;
920     proto_tree *rsvp_ero_subtree;
921     proto_tree *rsvp_admin_subtree;
922     proto_tree *rsvp_hop_subtree;
923     guint8 ver_flags;
924     guint8 message_type;
925     guint16 cksum, computed_cksum;
926     vec_t cksum_vec[1];
927     int i, j, k, l, len;
928     int msg_length;
929     int obj_length;
930     int mylen;
931     int offset2;
932     int session_off, tempfilt_off;
933
934     if (check_col(pinfo->cinfo, COL_PROTOCOL))
935         col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSVP");
936     if (check_col(pinfo->cinfo, COL_INFO))
937         col_clear(pinfo->cinfo, COL_INFO);
938
939     ver_flags = tvb_get_guint8(tvb, offset+0);
940     message_type = tvb_get_guint8(tvb, offset+1);
941     if (check_col(pinfo->cinfo, COL_INFO)) {
942         col_add_str(pinfo->cinfo, COL_INFO,
943             val_to_str(message_type, message_type_vals, "Unknown (%u). ")); 
944         find_rsvp_session_tempfilt(tvb, offset, &session_off, &tempfilt_off);
945         if (session_off) 
946             col_append_str(pinfo->cinfo, COL_INFO, summary_session(tvb, session_off));
947         if (tempfilt_off) 
948             col_append_str(pinfo->cinfo, COL_INFO, summary_template(tvb, tempfilt_off));
949     }
950
951     if (tree) {
952         msg_length = tvb_get_ntohs(tvb, offset+6);
953         ti = proto_tree_add_item(tree, proto_rsvp, tvb, offset, msg_length,
954             FALSE);
955         rsvp_tree = proto_item_add_subtree(ti, ett_rsvp);
956
957         ti = proto_tree_add_text(rsvp_tree, tvb, offset, 8, "RSVP Header. %s", 
958                                  val_to_str(message_type, message_type_vals, 
959                                             "Unknown Message (%u). ")); 
960         rsvp_header_tree = proto_item_add_subtree(ti, ett_rsvp_hdr);
961
962         proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "RSVP Version: %u", 
963                             (ver_flags & 0xf0)>>4);  
964         proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "Flags: %02x",
965                             ver_flags & 0xf);
966         proto_tree_add_uint(rsvp_header_tree, rsvp_filter[RSVPF_MSG], tvb, 
967                             offset+1, 1, message_type);
968         if (message_type <= RSVPF_RTEARCONFIRM &&
969                         message_type != RSVPF_JUNK_MSG8 &&
970                         message_type != RSVPF_JUNK_MSG9 ) {
971                proto_tree_add_boolean_hidden(rsvp_header_tree, rsvp_filter[RSVPF_MSG + message_type], tvb, 
972                                    offset+1, 1, 1);
973         }
974         cksum = tvb_get_ntohs(tvb, offset+2);
975         if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) {
976             /* The packet isn't part of a fragmented datagram and isn't
977                truncated, so we can checksum it. */
978             cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length);
979             cksum_vec[0].len = msg_length;
980             computed_cksum = in_cksum(&cksum_vec[0], 1);
981             if (computed_cksum == 0) {
982                 proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
983                                     "Message Checksum: 0x%04x (correct)",
984                                     cksum);
985             } else {
986                 proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
987                                     "Message Checksum: 0x%04x (incorrect, should be 0x%04x)",
988                                     cksum,
989                                     in_cksum_shouldbe(cksum, computed_cksum));
990             }
991         } else {
992             proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
993                                 "Message Checksum: 0x%04x",
994                                 cksum);
995         }
996         proto_tree_add_text(rsvp_header_tree, tvb, offset+4, 1,
997                             "Sending TTL: %u",
998                             tvb_get_guint8(tvb, offset+4));
999         proto_tree_add_text(rsvp_header_tree, tvb, offset+6, 2,
1000                             "Message length: %u", msg_length);
1001
1002         offset += 8;
1003         len = 8;
1004         while (len < msg_length) {
1005             guint8 class;       
1006             guint8 type;
1007             char *object_type;
1008
1009             obj_length = tvb_get_ntohs(tvb, offset);
1010             class = tvb_get_guint8(tvb, offset+2);
1011             type = tvb_get_guint8(tvb, offset+3);
1012             object_type = val_to_str(class, rsvp_class_vals, "Unknown");
1013             proto_tree_add_uint_hidden(rsvp_tree, rsvp_filter[RSVPF_OBJECT], tvb, 
1014                                             offset, obj_length, class);
1015             ti = proto_tree_add_item(rsvp_tree, rsvp_filter[rsvp_class_to_filter_num(class)],
1016                                      tvb, offset, obj_length, FALSE);
1017
1018             offset2 = offset+4;
1019
1020             switch(class) {
1021
1022             case RSVP_CLASS_SESSION :           
1023                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_session);
1024                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1025                                     "Length: %u", obj_length);
1026                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1027                                     "Class number: %u - %s", 
1028                                     class, object_type);
1029                 mylen = obj_length - 4;
1030                 proto_item_set_text(ti, summary_session(tvb, offset));
1031
1032                 switch(type) {
1033                 case 1: {
1034                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1035                                         "C-type: 1 - IPv4");
1036                     proto_tree_add_item(rsvp_object_tree,
1037                                         rsvp_filter[RSVPF_SESSION_IP],
1038                                         tvb, offset2, 4, FALSE);
1039
1040                     proto_tree_add_item(rsvp_object_tree,
1041                                         rsvp_filter[RSVPF_SESSION_PROTO], tvb, 
1042                                         offset2+4, 1, FALSE);
1043                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1,
1044                                         "Flags: %x",
1045                                         tvb_get_guint8(tvb, offset2+5));
1046                     proto_tree_add_item(rsvp_object_tree,
1047                                         rsvp_filter[RSVPF_SESSION_PORT], tvb, 
1048                                         offset2+6, 2, FALSE);
1049                     break;
1050                 }
1051
1052                 case 2: {
1053                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1054                                         "C-type: 2 - IPv6");
1055                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
1056                                         "Destination address: %s", 
1057                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1058                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1,
1059                                         "Protocol: %u",
1060                                         tvb_get_guint8(tvb, offset2+16));
1061                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1,
1062                                         "Flags: %x",
1063                                         tvb_get_guint8(tvb, offset2+17));
1064                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
1065                                         "Destination port: %u", 
1066                                         tvb_get_ntohs(tvb, offset2+18));
1067                     break;
1068                 }
1069                 
1070                 case 7: {
1071                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1072                                         "C-type: 7 - IPv4 LSP");
1073                     proto_tree_add_item(rsvp_object_tree,
1074                                         rsvp_filter[RSVPF_SESSION_IP],
1075                                         tvb, offset2, 4, FALSE);
1076
1077                     proto_tree_add_item(rsvp_object_tree,
1078                                         rsvp_filter[RSVPF_SESSION_TUNNEL_ID],
1079                                         tvb, offset2+6, 2, FALSE);
1080
1081                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4, 
1082                                         "Extended Tunnel ID: %u (%s)",
1083                                         tvb_get_ntohl(tvb, offset2+8),
1084                                         ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1085                     proto_tree_add_item_hidden(rsvp_object_tree,
1086                                         rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID],
1087                                         tvb, offset2+8, 4, FALSE);
1088                     break;
1089                 }
1090
1091                 default: {
1092                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1093                                         "C-type: Unknown (%u)",
1094                                         type);
1095                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1096                                         "Data (%d bytes)", mylen);
1097                 }
1098                 }
1099                 break;
1100                 
1101             case RSVP_CLASS_HOP :               
1102                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_hop);
1103                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1104                                     "Length: %u", obj_length);
1105                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1106                                     "Class number: %u - %s", 
1107                                     class, object_type);
1108                 mylen = obj_length - 4;
1109                 switch(type) {
1110                 case 1: {
1111                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1112                                         "C-type: 1 - IPv4");
1113                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1114                                         "Neighbor address: %s", 
1115                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1116                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1117                                         "Logical interface: %u", 
1118                                         tvb_get_ntohl(tvb, offset2+4));
1119                     proto_item_set_text(ti, "HOP: IPv4, %s", 
1120                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1121                     break;
1122                 }
1123
1124                 case 2: {
1125                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1126                                         "C-type: 2 - IPv6");
1127                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
1128                                         "Neighbor address: %s", 
1129                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1130                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 4,
1131                                         "Logical interface: 0x%08x", 
1132                                         tvb_get_ntohl(tvb, offset2+16));
1133                     break;
1134                 }
1135                 
1136                 case 3: {
1137                     guint16   tlv_off;
1138                     guint16   tlv_type;
1139                     guint16   tlv_len;
1140                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1141                                         "C-type: 3 - IPv4 Out-Of-Band");
1142                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1143                                         "Neighbor address: %s", 
1144                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1145                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1146                                         "Logical interface: %u", 
1147                                         tvb_get_ntohl(tvb, offset2+4));
1148
1149                     for (tlv_off = 0; tlv_off < mylen - 8; ) {
1150                         tlv_type = tvb_get_ntohs(tvb, offset2+8+tlv_off);
1151                         tlv_len = tvb_get_ntohs(tvb, offset2+8+tlv_off+2);
1152                         switch(tlv_type) {
1153                         case 1: 
1154                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1155                                                       offset2+8+tlv_off, 8,
1156                                                       "IPv4 TLV - %s",
1157                                                       ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)));
1158                             rsvp_hop_subtree = 
1159                                 proto_item_add_subtree(ti2, ett_rsvp_hop_subobj); 
1160                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off, 2,
1161                                                 "Type: 1 (IPv4)");
1162                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+2, 2,
1163                                                 "Length: %u",
1164                                                 tvb_get_ntohs(tvb, offset2+8+tlv_off+2));
1165                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+4, 4, 
1166                                                 "IPv4 address: %s", 
1167                                                 ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)));
1168                             proto_item_set_text(ti, "HOP: Out-of-band. Control IPv4: %s. Data IPv4: %s", 
1169                                                 ip_to_str(tvb_get_ptr(tvb, offset2, 4)), 
1170                                                 ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)));
1171                             break;
1172
1173                         case 3: 
1174                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1175                                                       offset2+8+tlv_off, 12,
1176                                                       "Interface-Index TLV - %s, %d",
1177                                                       ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)),
1178                                                       tvb_get_ntohl(tvb, offset2+8+tlv_off+8));
1179                             rsvp_hop_subtree = 
1180                                 proto_item_add_subtree(ti2, ett_rsvp_hop_subobj); 
1181                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off, 2,
1182                                                 "Type: 3 (Interface Index)");
1183                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+2, 2,
1184                                                 "Length: %u",
1185                                                 tvb_get_ntohs(tvb, offset2+8+tlv_off+2));
1186                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+4, 4, 
1187                                                 "IPv4 address: %s", 
1188                                                 ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)));
1189                             proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+8, 4, 
1190                                                 "Interface-ID: %d", 
1191                                                 tvb_get_ntohl(tvb, offset2+8+tlv_off+8));
1192                             proto_item_set_text(ti, "HOP: Out-of-band. Control IPv4: %s. Data If-Index: %s, %d", 
1193                                                 ip_to_str(tvb_get_ptr(tvb, offset2, 4)), 
1194                                                 ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)), 
1195                                                 tvb_get_ntohl(tvb, offset2+8+tlv_off+8));
1196                             break;
1197
1198                         default:
1199                             proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1200                                                 "Logical interface: %u", 
1201                                                 tvb_get_ntohl(tvb, offset2+4));
1202                         }
1203                         tlv_off += tlv_len;
1204                     }
1205                     break;
1206                 }
1207
1208                 default: {
1209                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1210                                         "C-type: Unknown (%u)",
1211                                         type);
1212                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1213                                         "Data (%d bytes)", mylen);
1214                 }
1215                 }
1216                 break;
1217                 
1218             case RSVP_CLASS_TIME_VALUES : 
1219                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_time_values);
1220                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1221                                     "Length: %u", obj_length);
1222                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1223                                     "Class number: %u - %s", 
1224                                     class, object_type);
1225                 mylen = obj_length - 4;
1226                 switch(type) {
1227                 case 1: {
1228                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1229                                         "C-type: 1");
1230                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1231                                         "Refresh interval: %u ms (%u seconds)",
1232                                         tvb_get_ntohl(tvb, offset2),
1233                                         tvb_get_ntohl(tvb, offset2)/1000);
1234                     proto_item_set_text(ti, "TIME VALUES: %d ms", 
1235                                         tvb_get_ntohl(tvb, offset2));
1236                     break;
1237                 }
1238
1239                 default: {
1240                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1241                                         "C-type: Unknown (%u)",
1242                                         type);
1243                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1244                                         "Data (%d bytes)", mylen);
1245                     break;
1246                 }
1247                 }
1248                 break;
1249
1250             case RSVP_CLASS_ERROR :
1251                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_error);
1252                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1253                                     "Length: %u", obj_length);
1254                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1255                                     "Class number: %u - %s", 
1256                                     class, object_type);
1257                 mylen = obj_length - 4;
1258                 switch(type) {
1259                 case 1: {
1260                     guint8 error_code;
1261
1262                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1263                                         "C-type: 1 - IPv4");
1264                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1265                                         "Error node: %s",
1266                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1267                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 1,
1268                                         "Flags: 0x%02x",
1269                                         tvb_get_guint8(tvb, offset2+4));
1270                     error_code = tvb_get_guint8(tvb, offset2+5);
1271                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1,
1272                                         "Error code: %u - %s", error_code,
1273                                         val_to_str(error_code, rsvp_error_vals, "Unknown (%d)"));
1274                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+6, 2,
1275                                         "Error value: %u",
1276                                         tvb_get_ntohs(tvb, offset2+6));
1277                     proto_item_set_text(ti, "ERROR: IPv4, Error code: %s, Value: %d, Error Node: %s", 
1278                                         val_to_str(error_code, rsvp_error_vals, "Unknown (%d)"),
1279                                         tvb_get_ntohs(tvb, offset2+6),
1280                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1281                     break;
1282                 }
1283
1284                 case 2: {
1285                     guint8 error_code;
1286
1287                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1288                                         "C-type: 2 - IPv6");
1289                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
1290                                         "Error node: %s",
1291                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1292                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1,
1293                                         "Flags: 0x%02x",
1294                                         tvb_get_guint8(tvb, offset2+16));
1295                     error_code = tvb_get_guint8(tvb, offset2+17);
1296                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1,
1297                                         "Error code: %u - %s", error_code,
1298                                         val_to_str(error_code, rsvp_error_vals, "Unknown"));
1299                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
1300                                         "Error value: %u",
1301                                         tvb_get_ntohs(tvb, offset2+18));
1302                     break;
1303                 }
1304                 
1305                 default: {
1306                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1307                                         "C-type: Unknown (%u)",
1308                                         type);
1309                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1310                                         "Data (%d bytes)", mylen);
1311                 }
1312                 }
1313                 break;
1314                 
1315
1316             case RSVP_CLASS_SCOPE : 
1317                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_scope);
1318                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1319                                     "Length: %u", obj_length);
1320                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1321                                     "Class number: %u - %s", 
1322                                     class, object_type);
1323                 mylen = obj_length - 4;
1324                 switch(type) {
1325                 case 1: {
1326                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1327                                         "C-type: 1 - IPv4");
1328                     while (mylen > 0) {
1329                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1330                                             "IPv4 Address: %s",
1331                                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1332                         offset2 += 4;
1333                         mylen -= 4;
1334                     }
1335                     break;
1336                 }
1337
1338                 case 2: {
1339                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1340                                         "C-type: 2 - IPv6");
1341                     while (mylen > 0) {
1342                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, 
1343                                             "IPv6 Address: %s",
1344                                             ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1345                         offset2 += 16;
1346                         mylen -= 16;
1347                     }
1348                     break;
1349                 }
1350                 
1351                 default: {
1352                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1353                                         "C-type: Unknown (%u)",
1354                                         type);
1355                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1356                                         "Data (%d bytes)", mylen);
1357                 }
1358                 }
1359                 break;
1360                 
1361             case RSVP_CLASS_STYLE : 
1362                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_style);
1363                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1364                                     "Length: %u", obj_length);
1365                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1366                                     "Class number: %u - %s", 
1367                                     class, object_type);
1368                 mylen = obj_length - 4;
1369                 switch(type) {
1370                 case 1: {
1371                     guint32 style;
1372
1373                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1374                                         "C-type: 1");
1375                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
1376                                         "Flags: 0x%02x",
1377                                         tvb_get_guint8(tvb, offset2));
1378                     style = tvb_get_ntoh24(tvb, offset2+1);
1379                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+1,
1380                                         3, "Style: 0x%06X - %s", style,
1381                                         val_to_str(style, style_vals, "Unknown"));
1382                     proto_item_set_text(ti, "STYLE: %s (%d)", 
1383                                         val_to_str(style, style_vals, "Unknown"),
1384                                         style);
1385                     break;
1386                 }
1387
1388                 default: {
1389                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1390                                         "C-type: Unknown (%u)",
1391                                         type);
1392                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1393                                         "Data (%d bytes)", mylen);
1394                     break;
1395                 }
1396                 }
1397                 break;
1398             
1399             case RSVP_CLASS_CONFIRM :           
1400                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_confirm);
1401                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1402                                     "Length: %u", obj_length);
1403                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1404                                     "Class number: %u - %s", 
1405                                     class, object_type);
1406                 mylen = obj_length - 4;
1407                 switch(type) {
1408                 case 1: {
1409                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1410                                         "C-type: 1 - IPv4");
1411                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1412                                         "Receiver address: %s", 
1413                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1414                     proto_item_set_text(ti, "CONFIRM: Receiver %s", 
1415                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1416                     break;
1417                 }
1418
1419                 case 2: {
1420                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1421                                         "C-type: 2 - IPv6");
1422                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, 
1423                                         "Receiver address: %s", 
1424                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1425                     break;
1426                 }
1427
1428                 default: {
1429                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1430                                         "C-type: Unknown (%u)",
1431                                         type);
1432                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1433                                         "Data (%d bytes)", mylen);
1434                 }
1435                 }
1436                 break;
1437
1438             case RSVP_CLASS_SENDER_TEMPLATE :
1439                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_template);
1440                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1441                                     "Length: %u", obj_length);
1442                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1443                                     "Class number: %u - %s", 
1444                                     class, object_type);
1445                 goto common_template;
1446             case RSVP_CLASS_FILTER_SPEC :
1447                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_filter_spec);
1448                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1449                                     "Length: %u", obj_length);
1450                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1451                                     "Class number: %u - %s", 
1452                                     class, object_type);
1453             common_template:
1454                 mylen = obj_length - 4;
1455                 proto_item_set_text(ti, summary_template(tvb, offset));
1456                 switch(type) {
1457                 case 1: {
1458                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1459                                         "C-type: 1 - IPv4");
1460                     proto_tree_add_item(rsvp_object_tree,
1461                                         rsvp_filter[RSVPF_SENDER_IP],
1462                                         tvb, offset2, 4, FALSE);
1463                     proto_tree_add_item(rsvp_object_tree,
1464                                         rsvp_filter[RSVPF_SENDER_PORT],
1465                                         tvb, offset2+6, 2, FALSE);
1466                     break;
1467                 }
1468
1469                 case 2: {
1470                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1471                                         "C-type: 2 - IPv6");
1472                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, 
1473                                         "Source address: %s", 
1474                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1475                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
1476                                         "Source port: %u",
1477                                         tvb_get_ntohs(tvb, offset2+18));
1478                     break;
1479                 }
1480                 
1481                 case 7: {
1482                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1483                                         "C-type: 7 - IPv4 LSP");
1484                     proto_tree_add_item(rsvp_object_tree,
1485                                         rsvp_filter[RSVPF_SENDER_IP],
1486                                         tvb, offset2, 4, FALSE);
1487                     proto_tree_add_item(rsvp_object_tree,
1488                                         rsvp_filter[RSVPF_SENDER_LSP_ID],
1489                                         tvb, offset2+6, 2, FALSE);
1490                     break;
1491                 }
1492
1493                 default: {
1494                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1495                                         "C-type: Unknown (%u)",
1496                                         type);
1497                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1498                                         "Data (%d bytes)", mylen);
1499                 }
1500                 }
1501                 break;
1502
1503             case RSVP_CLASS_SENDER_TSPEC : {
1504                 proto_tree *tspec_tree;
1505
1506                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_tspec);
1507                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1508                                     "Length: %u", obj_length);
1509                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1510                                     "Class number: %u - %s", 
1511                                     class, object_type);
1512                 mylen = obj_length - 4;
1513
1514                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1515                                     "Message format version: %u", 
1516                                     tvb_get_guint8(tvb, offset2)>>4);
1517                 proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1518                                     "Data length: %u words, not including header", 
1519                                     tvb_get_ntohs(tvb, offset2+2));
1520
1521                 mylen -= 4;
1522                 offset2 += 4;
1523
1524                 proto_item_set_text(ti, "SENDER TSPEC: ");
1525
1526                 while (mylen > 0) {
1527                     guint8 service_num;
1528                     guint8 param_id;
1529                     guint16 param_len;
1530                     guint16 param_len_processed;
1531                     guint16 length;
1532
1533                     service_num = tvb_get_guint8(tvb, offset2);
1534                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1535                                         "Service header: %u - %s", 
1536                                         service_num,
1537                                         val_to_str(service_num, qos_vals, "Unknown"));
1538                     length = tvb_get_ntohs(tvb, offset2+2);
1539                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1540                                         "Length of service %u data: %u words, " 
1541                                         "not including header", 
1542                                         service_num, length);
1543
1544                     mylen -= 4;
1545                     offset2 += 4;
1546
1547                     /* Process all known service headers as a set of parameters */
1548                     param_len_processed = 0;
1549                     while (param_len_processed < length) {
1550                         param_id = tvb_get_guint8(tvb, offset2);
1551                         param_len = tvb_get_ntohs(tvb, offset2+2) + 1;
1552                         switch(param_id) {
1553                         case 127: 
1554                             /* Token Bucket */
1555                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1556                                                       offset2, param_len*4, 
1557                                                       "Token Bucket TSpec: ");
1558                             tspec_tree = proto_item_add_subtree(ti2, ett_rsvp_sender_tspec_subtree);
1559
1560                             proto_tree_add_text(tspec_tree, tvb, offset2, 1, 
1561                                                 "Parameter %u - %s", 
1562                                                 param_id,
1563                                                 val_to_str(param_id, svc_vals, "Unknown"));
1564                             proto_tree_add_text(tspec_tree, tvb, offset2+1, 1,
1565                                                 "Parameter %u flags: 0x%02x",
1566                                                 param_id,
1567                                                 tvb_get_guint8(tvb, offset2+1));
1568                             proto_tree_add_text(tspec_tree, tvb, offset2+2, 2,
1569                                                 "Parameter %u data length: %u words, " 
1570                                                 "not including header",
1571                                                 param_id,
1572                                                 tvb_get_ntohs(tvb, offset2+2));
1573                             proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
1574                                                 "Token bucket rate: %ld", 
1575                                                 tvb_ieee_to_long(tvb, offset2+4));
1576                             proto_tree_add_text(tspec_tree, tvb, offset2+8, 4,
1577                                                 "Token bucket size: %ld", 
1578                                                 tvb_ieee_to_long(tvb, offset2+8));
1579                             proto_tree_add_text(tspec_tree, tvb, offset2+12, 4,
1580                                                 "Peak data rate: %ld", 
1581                                                 tvb_ieee_to_long(tvb, offset2+12));
1582                             proto_tree_add_text(tspec_tree, tvb, offset2+16, 4,
1583                                                 "Minimum policed unit [m]: %u", 
1584                                                 tvb_get_ntohl(tvb, offset2+16));
1585                             proto_tree_add_text(tspec_tree, tvb, offset2+20, 4,
1586                                                 "Maximum packet size [M]: %u", 
1587                                                 tvb_get_ntohl(tvb, offset2+20));
1588                             proto_item_append_text(ti, "Token Bucket, %lu bytes/sec. ", 
1589                                                    tvb_ieee_to_long(tvb, offset2+4));
1590                             proto_item_append_text(ti2, "Rate=%lu Burst=%lu Peak=%lu m=%u M=%u", 
1591                                                    tvb_ieee_to_long(tvb, offset2+4),
1592                                                    tvb_ieee_to_long(tvb, offset2+8),
1593                                                    tvb_ieee_to_long(tvb, offset2+12),
1594                                                    tvb_get_ntohl(tvb, offset2+16),
1595                                                    tvb_get_ntohl(tvb, offset2+20));
1596                             break;
1597
1598                         case 128:
1599                             /* Null Service (RFC2997) */
1600                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1601                                                       offset2, param_len*4, 
1602                                                       "Null Service TSpec: ");
1603                             tspec_tree = proto_item_add_subtree(ti2, ett_rsvp_sender_tspec_subtree);
1604                                 
1605                             proto_tree_add_text(tspec_tree, tvb, offset2, 1, 
1606                                                 "Parameter %u - %s", 
1607                                                 param_id,
1608                                                 val_to_str(param_id, svc_vals, "Unknown"));
1609                             proto_tree_add_text(tspec_tree, tvb, offset2+1, 1,
1610                                                 "Parameter %u flags: %x", 
1611                                                 param_id,
1612                                                 tvb_get_guint8(tvb, offset2+1));
1613                             proto_tree_add_text(tspec_tree, tvb, offset2+2, 2,
1614                                                 "Parameter %u data length: %u words, " 
1615                                                 "not including header",
1616                                                 param_id,
1617                                                 tvb_get_ntohs(tvb, offset2+2));
1618                             proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
1619                                                 "Maximum packet size [M]: %u", 
1620                                                 tvb_get_ntohl(tvb, offset2+4));
1621                             proto_item_append_text(ti, "Null Service. M=%u", 
1622                                                    tvb_get_ntohl(tvb, offset2+4));
1623                             proto_item_append_text(ti2, "Max pkt size=%u", 
1624                                                    tvb_get_ntohl(tvb, offset2+4));
1625                             break;
1626
1627                         case 126:
1628                             /* Compression hint (RFC3006) */
1629                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1630                                                       offset2, param_len*4, 
1631                                                       "Compression Hint: ");
1632                             tspec_tree = proto_item_add_subtree(ti2, ett_rsvp_sender_tspec_subtree);
1633                                 
1634                             proto_tree_add_text(tspec_tree, tvb, offset2, 1, 
1635                                                 "Parameter %u - %s", 
1636                                                 param_id,
1637                                                 val_to_str(param_id, svc_vals, "Unknown"));
1638                             proto_tree_add_text(tspec_tree, tvb, offset2+1, 1,
1639                                                 "Parameter %u flags: %x", 
1640                                                 param_id,
1641                                                 tvb_get_guint8(tvb, offset2+1));
1642                             proto_tree_add_text(tspec_tree, tvb, offset2+2, 2,
1643                                                 "Parameter %u data length: %u words, " 
1644                                                 "not including header",
1645                                                 param_id,
1646                                                 tvb_get_ntohs(tvb, offset2+2));
1647                             proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
1648                                                 "Hint: %u", 
1649                                                 tvb_get_ntohl(tvb, offset2+4));
1650                             proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
1651                                                 "Compression Factor: %u", 
1652                                                 tvb_get_ntohl(tvb, offset2+8));
1653                             proto_item_append_text(ti, "Compression Hint. Hint=%u, Factor=%u", 
1654                                                    tvb_get_ntohl(tvb, offset2+4),
1655                                                    tvb_get_ntohl(tvb, offset2+8));
1656                             proto_item_append_text(ti2, "Hint=%u, Factor=%u", 
1657                                                    tvb_get_ntohl(tvb, offset2+4),
1658                                                    tvb_get_ntohl(tvb, offset2+8));
1659                             break;
1660
1661                         default: 
1662                             proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, 
1663                                                 "Unknown parameter %d, %d words", 
1664                                                 param_id, param_len);
1665                             break;
1666                         }
1667                         param_len_processed += param_len;
1668                         offset2 += param_len*4;
1669                     }
1670                     /* offset2 += length*4;  */
1671                     mylen -= length*4;
1672                 }
1673                 break;
1674             }
1675
1676             case RSVP_CLASS_FLOWSPEC : {
1677                 proto_tree *flowspec_tree;
1678
1679                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_flowspec);
1680                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1681                                     "Length: %u", obj_length);
1682                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1683                                     "Class number: %u - %s", 
1684                                     class, object_type);
1685                 mylen = obj_length - 4;
1686
1687                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1688                                     "Message format version: %u", 
1689                                     tvb_get_guint8(tvb, offset2)>>4);
1690                 proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1691                                     "Data length: %u words, not including header", 
1692                                     tvb_get_ntohs(tvb, offset2+2));
1693
1694                 proto_item_set_text(ti, "FLOWSPEC: ");
1695
1696                 mylen -= 4;
1697                 offset2+= 4;
1698                 while (mylen > 0) {
1699                     guint8 service_num;
1700                     guint16 length;
1701                     guint8 param_id;
1702                     guint16 param_len;
1703                     guint16 param_len_processed;
1704
1705                     service_num = tvb_get_guint8(tvb, offset2);
1706                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1707                                         "Service header: %u - %s", 
1708                                         service_num,
1709                                         val_to_str(service_num, intsrv_services_str, "Unknown"));
1710                     length = tvb_get_ntohs(tvb, offset2+2);
1711                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1712                                         "Length of service %u data: %u words, " 
1713                                         "not including header", 
1714                                         service_num,
1715                                         length);
1716
1717                     mylen -= 4;
1718                     offset2 += 4;
1719
1720                     proto_item_append_text(ti, "%s: ", 
1721                                            val_to_str(service_num, intsrv_services_str, 
1722                                                       "Unknown (%d)"));
1723
1724                     /* Process all known service headers as a set of parameters */
1725                     param_len_processed = 0;
1726                     while (param_len_processed < length) {
1727                         param_id = tvb_get_guint8(tvb, offset2);
1728                         param_len = tvb_get_ntohs(tvb, offset2+2) + 1;
1729                         switch(param_id) {
1730                         case 127: 
1731                             /* Token Bucket */
1732                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1733                                                       offset2, param_len*4, 
1734                                                       "Token Bucket: ");
1735                             flowspec_tree = proto_item_add_subtree(ti2, ett_rsvp_flowspec_subtree);
1736
1737                             proto_tree_add_text(flowspec_tree, tvb, offset2, 1, 
1738                                                 "Parameter %u - %s", 
1739                                                 param_id,
1740                                                 val_to_str(param_id, svc_vals, "Unknown"));
1741                             proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1,
1742                                                 "Parameter %u flags: 0x%02x",
1743                                                 param_id,
1744                                                 tvb_get_guint8(tvb, offset2+1));
1745                             proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2,
1746                                                 "Parameter %u data length: %u words, " 
1747                                                 "not including header",
1748                                                 param_id,
1749                                                 tvb_get_ntohs(tvb, offset2+2));
1750                             proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4,
1751                                                 "Token bucket rate: %ld", 
1752                                                 tvb_ieee_to_long(tvb, offset2+4));
1753                             proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4,
1754                                                 "Token bucket size: %ld", 
1755                                                 tvb_ieee_to_long(tvb, offset2+8));
1756                             proto_tree_add_text(flowspec_tree, tvb, offset2+12, 4,
1757                                                 "Peak data rate: %ld", 
1758                                                 tvb_ieee_to_long(tvb, offset2+12));
1759                             proto_tree_add_text(flowspec_tree, tvb, offset2+16, 4,
1760                                                 "Minimum policed unit [m]: %u", 
1761                                                 tvb_get_ntohl(tvb, offset2+16));
1762                             proto_tree_add_text(flowspec_tree, tvb, offset2+20, 4,
1763                                                 "Maximum packet size [M]: %u", 
1764                                                 tvb_get_ntohl(tvb, offset2+20));
1765                             proto_item_append_text(ti, "Token Bucket, %lu bytes/sec. ", 
1766                                                    tvb_ieee_to_long(tvb, offset2+4));
1767                             proto_item_append_text(ti2, "Rate=%lu Burst=%lu Peak=%lu m=%u M=%u", 
1768                                                    tvb_ieee_to_long(tvb, offset2+4),
1769                                                    tvb_ieee_to_long(tvb, offset2+8),
1770                                                    tvb_ieee_to_long(tvb, offset2+12),
1771                                                    tvb_get_ntohl(tvb, offset2+16),
1772                                                    tvb_get_ntohl(tvb, offset2+20));
1773                             break;
1774
1775                         case 130:
1776                             /* Guaranteed-rate RSpec */
1777                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1778                                                       offset2, param_len*4, 
1779                                                       "Guaranteed-Rate RSpec: ");
1780                             flowspec_tree = proto_item_add_subtree(ti2, ett_rsvp_flowspec_subtree);
1781                             proto_tree_add_text(flowspec_tree, tvb, offset2, 1,
1782                                                 "Parameter %u - %s", 
1783                                                 param_id,
1784                                                 val_to_str(param_id, svc_vals, "Unknown"));
1785                             proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1, 
1786                                                 "Parameter %u flags: %x", 
1787                                                 param_id,
1788                                                 tvb_get_guint8(tvb, offset2+1));
1789                             proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2,
1790                                                 "Parameter %u data length: %u words, " 
1791                                                 "not including header",
1792                                                 param_id,
1793                                                 tvb_get_ntohs(tvb, offset2+2));
1794                             
1795                             proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4,
1796                                                 "Rate: %ld", 
1797                                                 tvb_ieee_to_long(tvb, offset2+4));
1798                             proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4,
1799                                                 "Slack term: %u", 
1800                                                 tvb_get_ntohl(tvb, offset2+8));
1801                             proto_item_append_text(ti, "RSpec, %lu bytes/sec. ", 
1802                                                    tvb_ieee_to_long(tvb, offset2+4));
1803                             proto_item_append_text(ti2, "R=%lu, s=%u", 
1804                                                    tvb_ieee_to_long(tvb, offset2+4),
1805                                                    tvb_get_ntohl(tvb, offset2+8));
1806                             break;
1807
1808                         case 128:
1809                             /* Null Service (RFC2997) */
1810                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1811                                                       offset2, param_len*4, 
1812                                                       "Null Service Flowspec: ");
1813                             flowspec_tree = proto_item_add_subtree(ti2, ett_rsvp_flowspec_subtree);
1814                                 
1815                             proto_tree_add_text(flowspec_tree, tvb, offset2, 1, 
1816                                                 "Parameter %u - %s", 
1817                                                 param_id,
1818                                                 val_to_str(param_id, svc_vals, "Unknown"));
1819                             proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1,
1820                                                 "Parameter %u flags: %x", 
1821                                                 param_id,
1822                                                 tvb_get_guint8(tvb, offset2+1));
1823                             proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2,
1824                                                 "Parameter %u data length: %u words, " 
1825                                                 "not including header",
1826                                                 param_id,
1827                                                 tvb_get_ntohs(tvb, offset2+2));
1828                             proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4,
1829                                                 "Maximum packet size [M]: %u", 
1830                                                 tvb_get_ntohl(tvb, offset2+4));
1831                             proto_item_append_text(ti, "Null Service. M=%u", 
1832                                                    tvb_get_ntohl(tvb, offset2+4));
1833                             proto_item_append_text(ti2, "Max pkt size=%u", 
1834                                                    tvb_get_ntohl(tvb, offset2+4));
1835                             break;
1836
1837                         default: 
1838                             proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, 
1839                                                 "Unknown parameter %d, %d words", 
1840                                                 param_id, param_len);
1841                             break;
1842                         }
1843                         param_len_processed += param_len;
1844                         offset2 += param_len * 4;
1845                     }
1846
1847                     /* offset2 += length*4; */
1848                     mylen -= length*4;
1849                 }
1850                 break;
1851             }
1852
1853             case RSVP_CLASS_ADSPEC : {
1854                 proto_tree *adspec_tree;
1855
1856                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_adspec);
1857                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1858                                     "Length: %u", obj_length);
1859                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1860                                     "Class number: %u - %s", 
1861                                     class, object_type);
1862                 mylen = obj_length - 4;
1863
1864                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
1865                                     "Message format version: %u", 
1866                                     tvb_get_guint8(tvb, offset2)>>4);
1867                 proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1868                                     "Data length: %u words, not including header", 
1869                                     tvb_get_ntohs(tvb, offset2+2));
1870                 mylen -= 4;
1871                 offset2 += 4;
1872                 while (mylen > 0) {
1873                     guint8 service_num;
1874                     guint8 break_bit;
1875                     guint16 length;
1876                     char *str;
1877
1878                     service_num = tvb_get_guint8(tvb, offset2);
1879                     str = val_to_str(service_num, intsrv_services_str, "Unknown");
1880                     break_bit = tvb_get_guint8(tvb, offset2+1);
1881                     length = tvb_get_ntohs(tvb, offset2+2);
1882                     ti = proto_tree_add_text(rsvp_object_tree, tvb, offset2, 
1883                                              (length+1)*4,
1884                                              str);
1885                     adspec_tree = proto_item_add_subtree(ti,
1886                                                          ett_rsvp_adspec_subtree);
1887                     proto_tree_add_text(adspec_tree, tvb, offset2, 1,
1888                                         "Service header %u - %s",
1889                                         service_num, str);
1890                     proto_tree_add_text(adspec_tree, tvb, offset2+1, 1,
1891                                         (break_bit&0x80)?
1892                                         "Break bit set":"Break bit not set");
1893                     proto_tree_add_text(adspec_tree, tvb, offset2+2, 2, 
1894                                         "Data length: %u words, not including header", 
1895                                         length);
1896                     mylen -= 4;
1897                     offset2 += 4;
1898                     i = length*4;
1899                     while (i > 0) {
1900                         guint8 id;
1901                         guint16 phdr_length;
1902
1903                         id = tvb_get_guint8(tvb, offset2);
1904                         phdr_length = tvb_get_ntohs(tvb, offset2+2);
1905                         str = match_strval(id, adspec_params);
1906                         if (str) {
1907                             switch(id) {
1908                             case 4:
1909                             case 8:
1910                             case 10:
1911                             case 133:
1912                             case 134:
1913                             case 135:
1914                             case 136:
1915                                 /* 32-bit unsigned integer */
1916                                 proto_tree_add_text(adspec_tree, tvb, offset2,
1917                                                     (phdr_length+1)<<2,
1918                                                     "%s - %u (type %u, length %u)",
1919                                                     str,
1920                                                     tvb_get_ntohl(tvb, offset2+4),
1921                                                     id, phdr_length);
1922                                 break;
1923                                 
1924                             case 6:
1925                                 /* IEEE float */
1926                                 proto_tree_add_text(adspec_tree, tvb, offset2,
1927                                                     (phdr_length+1)<<2,
1928                                                     "%s - %lu (type %u, length %u)",
1929                                                     str,
1930                                                     tvb_ieee_to_long(tvb, offset2+4),
1931                                                     id, phdr_length);
1932                                 break;
1933                             default: 
1934                                 proto_tree_add_text(adspec_tree, tvb, offset2, 
1935                                                     (phdr_length+1)<<2,
1936                                                     "%s (type %u, length %u)",
1937                                                     str,
1938                                                     id, phdr_length);
1939                             }
1940                         } else {
1941                             proto_tree_add_text(adspec_tree, tvb, offset2, 
1942                                                 (phdr_length+1)<<2,
1943                                                 "Unknown (type %u, length %u)",
1944                                                 id, phdr_length);
1945                         }
1946                         offset2 += (phdr_length+1)<<2;
1947                         i -= (phdr_length+1)<<2;
1948                         mylen -= (phdr_length+1)<<2;
1949                     }
1950                 }
1951                 break;
1952             }
1953
1954             case RSVP_CLASS_INTEGRITY :
1955                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_integrity);
1956                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1957                                     "Length: %u", obj_length);
1958                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1959                                     "Class number: %u - %s", 
1960                                     class, object_type);
1961                 goto default_class;
1962
1963             case RSVP_CLASS_POLICY :
1964                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
1965                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1966                                     "Length: %u", obj_length);
1967                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1968                                     "Class number: %u - %s", 
1969                                     class, object_type);
1970                 goto default_class;
1971
1972             case RSVP_CLASS_LABEL_REQUEST : 
1973                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_label_request);
1974                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1975                                     "Length: %u", obj_length);
1976                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1977                                     "Class number: %u - %s", 
1978                                     class, object_type);
1979                 mylen = obj_length - 4;
1980                 switch(type) {
1981                 case 1: {
1982                     unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2);
1983                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1984                                         "C-type: 1");
1985                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1986                                         "L3PID: %s (0x%04x)",
1987                                         val_to_str(l3pid, etype_vals, "Unknown"),
1988                                         l3pid);
1989                     proto_item_set_text(ti, "LABEL REQUEST: %s (0x%04x)",
1990                                         val_to_str(l3pid, etype_vals, "Unknown"),
1991                                         l3pid);
1992                     break;
1993                 }
1994
1995                 case 4: {
1996                     unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2);
1997                     unsigned char  lsp_enc = tvb_get_guint8(tvb,offset2);
1998                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1999                                         "C-type: 4 (Generalized Label Request)");
2000                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2001                                         "LSP Encoding Type: %s",
2002                                         val_to_str(lsp_enc, gmpls_lsp_enc_str, "Unknown (%d)"));
2003                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
2004                                         "Switching Type: %s",
2005                                         val_to_str(tvb_get_guint8(tvb,offset2+1), 
2006                                                    gmpls_switching_type_str, "Unknown (%d)"));
2007                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2008                                         "G-PID: %s (0x%0x)",
2009                                         val_to_str(l3pid, gmpls_gpid_str, 
2010                                                    val_to_str(l3pid, etype_vals, 
2011                                                               "Unknown G-PID(0x%04x)")),
2012                                         l3pid);
2013                     proto_item_set_text(ti, "LABEL REQUEST: Generalized: LSP Encoding=%s, "
2014                                         "Switching Type=%s, G-PID=%s ",
2015                                         val_to_str(lsp_enc, gmpls_lsp_enc_str, "Unknown (%d)"),
2016                                         val_to_str(tvb_get_guint8(tvb,offset2+1), 
2017                                                    gmpls_switching_type_str, "Unknown (%d)"),
2018                                         val_to_str(l3pid, gmpls_gpid_str, 
2019                                                    val_to_str(l3pid, etype_vals, 
2020                                                               "Unknown (0x%04x)")));
2021                     break;
2022                 }
2023
2024                 default: {
2025                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2026                                         "C-type: Unknown (%u)",
2027                                         type);
2028                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2029                                         "Data (%d bytes)", mylen);
2030                     break;
2031                 }
2032                 }
2033                 break;
2034             
2035             case RSVP_CLASS_UPSTREAM_LABEL : 
2036             case RSVP_CLASS_SUGGESTED_LABEL : 
2037             case RSVP_CLASS_LABEL : {
2038                 char *name;
2039                 name = (class==RSVP_CLASS_SUGGESTED_LABEL ? "SUGGESTED LABEL" : 
2040                         (class==RSVP_CLASS_UPSTREAM_LABEL ? "UPSTREAM LABEL" :
2041                          "LABEL"));
2042                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_label);
2043                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2044                                     "Length: %u", obj_length);
2045                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2046                                     "Class number: %u - %s", 
2047                                     class, object_type);
2048                 mylen = obj_length - 4;
2049                 switch(type) {
2050                 case 1: {
2051                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2052                                         "C-type: 1 (Packet Label)");
2053                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
2054                                         "Label: %u", 
2055                                         tvb_get_ntohl(tvb, offset2));
2056                     proto_item_set_text(ti, "%s: %d", name,
2057                                         tvb_get_ntohl(tvb, offset2));
2058                     break;
2059                 }
2060
2061                 case 2: {
2062                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2063                                         "C-type: 2 (Generalized Label)");
2064                     proto_item_set_text(ti, "%s: Generalized: ", name);
2065                     for (i = 0; i < mylen; i += 4) {
2066                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+i, 4,
2067                                             "Generalized Label: %u", 
2068                                             tvb_get_ntohl(tvb, offset2+i));
2069                         if (i < 16) {
2070                             proto_item_append_text(ti, "%d%s", 
2071                                                    tvb_get_ntohl(tvb, offset2+i),
2072                                                    i+4<mylen?", ":"");
2073                         } else if (i == 16) {
2074                             proto_item_append_text(ti, "...");
2075                         }                           
2076                     }
2077                     break;
2078                 }
2079
2080                 default: {
2081                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2082                                         "C-type: Unknown (%u)",
2083                                         type);
2084                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2085                                         "Data (%d bytes)", mylen);
2086                     break;
2087                 }
2088                 }
2089                 break;
2090             }
2091             
2092             case RSVP_CLASS_SESSION_ATTRIBUTE : 
2093                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_session_attribute);
2094                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2095                                     "Length: %u", obj_length);
2096                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2097                                     "Class number: %u - %s", 
2098                                     class, object_type);
2099                 mylen = obj_length - 4;
2100                 switch(type) {
2101                 case 7: {
2102                     guint8 flags;
2103                     guint8 name_len;
2104
2105                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2106                                         "C-type: 7 - IPv4 LSP");
2107                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2108                                         "Setup priority: %u",
2109                                         tvb_get_guint8(tvb, offset2));
2110                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
2111                                         "Hold priority: %u",
2112                                         tvb_get_guint8(tvb, offset2+1));
2113                     flags = tvb_get_guint8(tvb, offset2+2);
2114                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 1,
2115                                               "Flags: 0x%02x", flags);
2116                     rsvp_sa_flags_tree = proto_item_add_subtree(ti2, 
2117                                                                 ett_rsvp_session_attribute_flags);
2118                     proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1,
2119                                         decode_boolean_bitfield(flags, 0x01, 8,
2120                                             "Local protection desired",
2121                                             "Local protection not desired"));
2122                     proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1,
2123                                         decode_boolean_bitfield(flags, 0x02, 8,
2124                                             "Merging permitted",
2125                                             "Merging not permitted"));
2126                     proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1,
2127                                         decode_boolean_bitfield(flags, 0x04, 8,
2128                                             "Ingress node may reroute",
2129                                             "Ingress node may not reroute"));
2130                     
2131                     name_len = tvb_get_guint8(tvb, offset2+3);
2132                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+3, 1,
2133                                         "Name length: %u", name_len);
2134                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, name_len,
2135                                         "Name: %.*s",
2136                                         name_len,
2137                                         tvb_get_ptr(tvb, offset2+4, name_len));
2138
2139                     proto_item_set_text(ti, "SESSION ATTRIBUTE: SetupPrio %d, HoldPrio %d, %s%s%s [%s]",
2140                                         tvb_get_guint8(tvb, offset2), 
2141                                         tvb_get_guint8(tvb, offset2+1),
2142                                         flags &0x01 ? "Local Protection, " : "",
2143                                         flags &0x02 ? "Merging, " : "",
2144                                         flags &0x04 ? "May Reroute, " : "",
2145                                         name_len ? (char*)tvb_format_text(tvb, offset2+4, name_len) : "");
2146                     break;
2147                 }
2148
2149                 default: {
2150                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2151                                         "C-type: Unknown (%u)",
2152                                         type);
2153                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2154                                         "Data (%d bytes)", mylen);
2155                     break;
2156                 }
2157                 }
2158                 break;
2159
2160             case RSVP_CLASS_EXPLICIT_ROUTE : 
2161                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_explicit_route);
2162                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2163                                     "Length: %u", obj_length);
2164                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2165                                     "Class number: %u - %s", 
2166                                     class, object_type);
2167                 mylen = obj_length - 4;
2168                 switch(type) {
2169                 case 1: {
2170                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2171                                         "C-type: 1");
2172                     proto_item_set_text(ti, "EXPLICIT ROUTE: ");
2173                     for (i=1, l = 0; l < mylen; i++) {
2174                         j = tvb_get_guint8(tvb, offset2+l) & 0x7f;
2175                         switch(j) {
2176                         case 1: /* IPv4 */
2177                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
2178                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2179                                                       offset2+l, 8,
2180                                                       "IPv4 Subobject - %s, %s",
2181                                                       ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)),
2182                                                       k ? "Loose" : "Strict");
2183                             rsvp_ero_subtree = 
2184                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
2185                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2186                                                 k ? "Loose Hop " : "Strict Hop");
2187                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2188                                                 "Type: 1 (IPv4)");
2189                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2190                                                 "Length: %u",
2191                                                 tvb_get_guint8(tvb, offset2+l+1));
2192                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 4,
2193                                                 "IPv4 hop: %s",
2194                                                 ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
2195                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+6, 1, 
2196                                                 "Prefix length: %u",
2197                                                 tvb_get_guint8(tvb, offset2+l+6));
2198                             if (i < 4) {
2199                                 proto_item_append_text(ti, "IPv4 %s%s", 
2200                                                        ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)),
2201                                                        k ? " [L]":"");
2202                             }
2203
2204                             break;
2205
2206                         case 2: /* IPv6 */
2207                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2208                                                       offset2+l, 20,
2209                                                       "IPv6 Subobject");
2210                             rsvp_ero_subtree = 
2211                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
2212                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
2213                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2214                                                 k ? "Loose Hop " : "Strict Hop");
2215                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2216                                                 "Type: 2 (IPv6)");
2217                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2218                                                 "Length: %u",
2219                                                 tvb_get_guint8(tvb, offset2+l+1));
2220                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 16,
2221                                                 "IPv6 hop: %s",
2222                                                 ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l+2, 16)));
2223                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+18, 1,
2224                                                 "Prefix length: %u",
2225                                                 tvb_get_guint8(tvb, offset2+l+6));
2226                             if (i < 4) {
2227                                 proto_item_append_text(ti, "IPv6 [...]%s", k ? " [L]":"");
2228                             }
2229
2230                             break;
2231
2232                         case 3: /* Label */
2233                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
2234                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2235                                                       offset2+l, 8,
2236                                                       "Label Subobject - %d, %s",
2237                                                       tvb_get_ntohl(tvb, offset2+l+4), 
2238                                                       k ? "Loose" : "Strict");
2239                             rsvp_ero_subtree = 
2240                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
2241                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2242                                                 k ? "Loose Hop " : "Strict Hop");
2243                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2244                                                 "Type: 3 (Label)");
2245                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2246                                                 "Length: %u",
2247                                                 tvb_get_guint8(tvb, offset2+l+1));
2248                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 1,
2249                                                 "Flags: %0x", 
2250                                                 tvb_get_guint8(tvb, offset2+l+2));
2251                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+3, 1,
2252                                                 "C-Type: %u",
2253                                                 tvb_get_guint8(tvb, offset2+l+3));
2254                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+4, 4,
2255                                                 "Label: %d",
2256                                                 tvb_get_ntohl(tvb, offset2+l+4));
2257                             if (i < 4) {
2258                                 proto_item_append_text(ti, "Label %d%s", 
2259                                                        tvb_get_ntohl(tvb, offset2+l+4), 
2260                                                        k ? " [L]":"");
2261                             }
2262                             break;
2263
2264                         case 4: /* Unnumbered Interface-ID */
2265                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
2266                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2267                                                       offset2+l, 8,
2268                                                       "Unnumbered Interface-ID - %s, %d, %s",
2269                                                       ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)),
2270                                                       tvb_get_ntohl(tvb, offset2+l+8), 
2271                                                       k ? "Loose" : "Strict");
2272                             rsvp_ero_subtree = 
2273                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
2274                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2275                                                 k ? "Loose Hop " : "Strict Hop");
2276                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2277                                                 "Type: 4 (Unnumbered Interface-ID)");
2278                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2279                                                 "Length: %u",
2280                                                 tvb_get_guint8(tvb, offset2+l+1));
2281                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+4, 4,
2282                                                 "Router-ID: %s",
2283                                                 ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)));
2284                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+8, 4,
2285                                                 "Interface-ID: %d",
2286                                                 tvb_get_ntohl(tvb, offset2+l+8));
2287                             if (i < 4) {
2288                                 proto_item_append_text(ti, "Unnum %s/%d%s", 
2289                                                        ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)),
2290                                                        tvb_get_ntohl(tvb, offset2+l+8),
2291                                                        k ? " [L]":"");
2292                             }
2293
2294                             break;
2295
2296                         case 32: /* AS */
2297                             k = tvb_get_ntohs(tvb, offset2+l+2);
2298                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2299                                                       offset2+l, 4,
2300                                                       "Autonomous System %u",
2301                                                       k);
2302                             rsvp_ero_subtree = 
2303                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
2304                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2305                                                 "Type: 32 (Autonomous System Number)");
2306                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2307                                                 "Length: %u",
2308                                                 tvb_get_guint8(tvb, offset2+l+1));
2309                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 2,
2310                                                 "Autonomous System %u", k);
2311                             if (i < 4) {
2312                                 proto_item_append_text(ti, "AS %d", 
2313                                                        tvb_get_ntohs(tvb, offset2+l+2));
2314                             }
2315
2316                             break;
2317
2318                         case 64: /* Path Term */
2319                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
2320                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2321                                                       offset2+l, 4,
2322                                                       "LSP Path Termination");
2323                             rsvp_ero_subtree = 
2324                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
2325                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2326                                                 k ? "Loose Hop " : "Strict Hop");
2327                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2328                                                 "Type: 64 (MPLS LSP Path Termination)");
2329                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2330                                                 "Length: %u",
2331                                                 tvb_get_guint8(tvb, offset2+l+1));
2332                             if (i < 4) {
2333                                 proto_item_append_text(ti, "Path Term");
2334                             }
2335                             break;
2336
2337                         default: /* Unknown subobject */
2338                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
2339                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2340                                                       offset2+l,
2341                                                       tvb_get_guint8(tvb, offset2+l+1),
2342                                                       "Unknown subobject: %d", j);
2343                             rsvp_ero_subtree = 
2344                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
2345                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2346                                                 k ? "Loose Hop " : "Strict Hop");
2347                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2348                                                 "Type: %u (Unknown)", j);
2349                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2350                                                 "Length: %u",
2351                                                 tvb_get_guint8(tvb, offset2+l+1));
2352
2353                         }
2354
2355                         l += tvb_get_guint8(tvb, offset2+l+1);
2356                         if (l < mylen) {
2357                             if (i < 4)
2358                                 proto_item_append_text(ti, ", ");
2359                             else if (i==4)
2360                                 proto_item_append_text(ti, "...");
2361                         }
2362                     }
2363                     break;
2364                 }
2365                 default: {
2366                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2367                                         "C-type: Unknown (%u)",
2368                                         type);
2369                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2370                                         "Data (%d bytes)", mylen);
2371                     break;
2372                 }
2373                 }
2374                 break;
2375             
2376
2377             case RSVP_CLASS_RECORD_ROUTE : 
2378                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_record_route);
2379                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2380                                     "Length: %u", obj_length);
2381                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2382                                     "Class number: %u - %s", 
2383                                     class, object_type);
2384                 proto_item_set_text(ti, "RECORD ROUTE: ");
2385                 mylen = obj_length - 4;
2386                 switch(type) {
2387                 case 1: {
2388                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2389                                         "C-type: 1");
2390                     for (i=1, l = 0; l < mylen; i++) {
2391                         j = tvb_get_guint8(tvb, offset2+l);
2392                         switch(j) {
2393                         case 1: /* IPv4 */
2394                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2395                                                       offset2+l, 8,
2396                                                       "IPv4 Subobject - %s",
2397                                                       ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
2398                             rsvp_ero_subtree = 
2399                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
2400                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2401                                                 "Type: 1 (IPv4)");
2402                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2403                                                 "Length: %u",
2404                                                 tvb_get_guint8(tvb, offset2+l+1));
2405                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 4,
2406                                                 "IPv4 hop: %s",
2407                                                 ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
2408                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+6, 1,
2409                                                 "Prefix length: %u",
2410                                                 tvb_get_guint8(tvb, offset2+l+6));
2411                             if (i < 4) {
2412                                 proto_item_append_text(ti, "IPv4 %s", 
2413                                                        ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
2414                             }
2415
2416                             break;
2417
2418                         case 2: /* IPv6 */
2419                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2420                                                       offset2+l, 20,
2421                                                       "IPv6 Subobject");
2422                             rsvp_ero_subtree = 
2423                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
2424                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2425                                                 "Type: 2 (IPv6)");
2426                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2427                                                 "Length: %u",
2428                                                 tvb_get_guint8(tvb, offset2+l+1));
2429                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 16,
2430                                                 "IPv6 hop: %s",
2431                                                 ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l+2, 16)));
2432                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+18, 1,
2433                                                 "Prefix length: %u",
2434                                                 tvb_get_guint8(tvb, offset2+l+6));
2435                             if (i < 4) {
2436                                 proto_item_append_text(ti, "IPv6 [...]");
2437                             }
2438                             break;
2439
2440                         case 3: /* Label */
2441                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2442                                                       offset2+l, 8,
2443                                                       "Label Subobject - %d",
2444                                                       tvb_get_ntohl(tvb, offset2+l+4));
2445                             rsvp_ero_subtree = 
2446                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
2447                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2448                                                 "Type: 3 (Label)");
2449                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2450                                                 "Length: %u",
2451                                                 tvb_get_guint8(tvb, offset2+l+1));
2452                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 1,
2453                                                 "Flags: %0x", 
2454                                                 tvb_get_guint8(tvb, offset2+l+2));
2455                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+3, 1,
2456                                                 "C-Type: %u",
2457                                                 tvb_get_guint8(tvb, offset2+l+3));
2458                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+4, 4,
2459                                                 "Label: %d",
2460                                                 tvb_get_ntohl(tvb, offset2+l+4));
2461                             if (i < 4) {
2462                                 proto_item_append_text(ti, "Label %d", 
2463                                                        tvb_get_ntohl(tvb, offset2+l+4));
2464                             }
2465                             break;
2466
2467                         case 4: /* Unnumbered Interface-ID */
2468                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2469                                                       offset2+l, 8,
2470                                                       "Unnumbered Interface-ID - %s, %d",
2471                                                       ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)),
2472                                                       tvb_get_ntohl(tvb, offset2+l+8));
2473                             rsvp_ero_subtree = 
2474                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
2475                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2476                                                 "Type: 4 (Unnumbered Interface-ID)");
2477                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2478                                                 "Length: %u",
2479                                                 tvb_get_guint8(tvb, offset2+l+1));
2480                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2481                                                 "Flags: %u",
2482                                                 tvb_get_guint8(tvb, offset2+l+2));
2483                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+4, 4,
2484                                                 "Router-ID: %s",
2485                                                 ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)));
2486                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+8, 4,
2487                                                 "Interface-ID: %d",
2488                                                 tvb_get_ntohl(tvb, offset2+l+8));
2489                             if (i < 4) {
2490                                 proto_item_append_text(ti, "Unnum %s/%d", 
2491                                                        ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)),
2492                                                        tvb_get_ntohl(tvb, offset2+l+8));
2493                             }
2494                             break;
2495
2496                         default: /* Unknown subobject */
2497                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
2498                                                       offset2+l,
2499                                                       tvb_get_guint8(tvb, offset2+l+1),
2500                                                       "Unknown subobject: %u",
2501                                                       j);
2502                             rsvp_ero_subtree = 
2503                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
2504                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
2505                                                 "Type: %u (Unknown)", j);
2506                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
2507                                                 "Length: %u",
2508                                                 tvb_get_guint8(tvb, offset2+l+1));
2509
2510                         }
2511
2512                         l += tvb_get_guint8(tvb, offset2+l+1);
2513                         if (l < mylen) {
2514                             if (i < 4)
2515                                 proto_item_append_text(ti, ", ");
2516                             else if (i==4)
2517                                 proto_item_append_text(ti, "...");
2518                         }
2519                     }
2520                     break;
2521                 }
2522                 
2523                 default: {
2524                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2525                                         "C-type: Unknown (%u)",
2526                                         type);
2527                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2528                                         "Data (%d bytes)", mylen);
2529                     break;
2530                 }
2531                 }
2532                 break;
2533             
2534             case RSVP_CLASS_MESSAGE_ID :
2535                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
2536                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2537                                     "Length: %u", obj_length);
2538                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2539                                     "Class number: %u - %s", 
2540                                     class, object_type);
2541                 switch(type) {
2542                 case 1: 
2543                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2544                                         "C-type: 1");
2545                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
2546                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
2547                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
2548                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
2549                     proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
2550                                         "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
2551                     proto_item_set_text(ti, "MESSAGE-ID: %d %s", 
2552                                         tvb_get_ntohl(tvb, offset+8), 
2553                                         tvb_get_guint8(tvb, offset+4) & 1 ? "(Ack Desired)" : "");
2554                     break;
2555
2556                 default:
2557                     mylen = obj_length - 4;
2558                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2559                                         "C-type: Unknown (%u)",
2560                                         type);
2561                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2562                                         "Data (%d bytes)", mylen);
2563                     break;
2564                 }
2565                 break;
2566
2567             case RSVP_CLASS_MESSAGE_ID_ACK :
2568                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
2569                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2570                                     "Length: %u", obj_length);
2571                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2572                                     "Class number: %u - %s", 
2573                                     class, object_type);
2574                 switch(type) {
2575                 case 1: 
2576                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2577                                         "C-type: 1");
2578                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
2579                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
2580                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
2581                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
2582                     proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
2583                                         "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
2584                     proto_item_set_text(ti, "MESSAGE-ID ACK: %d", tvb_get_ntohl(tvb, offset+8));
2585                     break;
2586
2587                 case 2: 
2588                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2589                                         "C-type: 2");
2590                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
2591                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
2592                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
2593                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
2594                     proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
2595                                         "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
2596                     proto_item_set_text(ti, "MESSAGE-ID NACK: %d", tvb_get_ntohl(tvb, offset+8));
2597                     break;
2598
2599                 default:
2600                     mylen = obj_length - 4;
2601                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2602                                         "C-type: Unknown (%u)",
2603                                         type);
2604                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2605                                         "Data (%d bytes)", mylen);
2606                     break;
2607                 }
2608                 break;
2609
2610             case RSVP_CLASS_MESSAGE_ID_LIST :
2611                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
2612                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2613                                     "Length: %u", obj_length);
2614                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2615                                     "Class number: %u - %s", 
2616                                     class, object_type);
2617                 switch(type) {
2618                 case 1: 
2619                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2620                                         "C-type: 1");
2621                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
2622                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
2623                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
2624                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
2625                     for (mylen = 8; mylen < obj_length; mylen += 4)
2626                         proto_tree_add_text(rsvp_object_tree, tvb, offset+mylen, 4,
2627                                             "Message-ID: %d", tvb_get_ntohl(tvb, offset+mylen));
2628                     proto_item_set_text(ti, "MESSAGE-ID LIST: %d IDs", 
2629                                         (obj_length - 8)/4);
2630                     break;
2631
2632                 default:
2633                     mylen = obj_length - 4;
2634                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2635                                         "C-type: Unknown (%u)",
2636                                         type);
2637                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2638                                         "Data (%d bytes)", mylen);
2639                     break;
2640                 }
2641                 break;
2642
2643             case RSVP_CLASS_HELLO:
2644                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_hello_obj);
2645                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2646                                     "Length: %u", obj_length);
2647                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2648                                     "Class number: %u - %s", 
2649                                     class, object_type);        
2650                 switch(type) {
2651                     case 1:
2652                       proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2653                                         "C-Type: 1 - HELLO REQUEST object");
2654                       break;
2655                     case 2:
2656                       proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2657                                         "C-Type: 2 - HELLO ACK object");
2658                       break;
2659                 };
2660
2661                 proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 4,
2662                                     "Source Instance: 0x%x",tvb_get_ntohl(tvb, offset+4));
2663    
2664                 proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
2665                                     "Destination Instance: 0x%x",tvb_get_ntohl(tvb, offset+8));
2666    
2667                 break;
2668
2669             case RSVP_CLASS_DCLASS:
2670                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_dclass);
2671                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2672                                     "Length: %u", obj_length);
2673                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2674                                     "Class number: %u - %s", 
2675                                     class, object_type);
2676                 proto_item_set_text(ti, "DCLASS: ");
2677                 switch(type) {
2678                 case 1: 
2679                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2680                                         "C-type: 1");
2681                     for (mylen = 4; mylen < obj_length; mylen += 4) {
2682                         proto_tree_add_text(rsvp_object_tree, tvb, offset+mylen+3, 1,
2683                                             "DSCP: %s", 
2684                                             val_to_str(tvb_get_guint8(tvb, offset+mylen+3),
2685                                                        dscp_vals, "Unknown (%d)"));
2686                         proto_item_append_text(ti, "%d%s", 
2687                                                tvb_get_guint8(tvb, offset+mylen+3)>>2,
2688                                                mylen==obj_length-4 ? "" : 
2689                                                mylen<16 ? ", " : 
2690                                                mylen==16 ? ", ..." : "");
2691                     }
2692                     break;
2693
2694                 default:
2695                     mylen = obj_length - 4;
2696                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2697                                         "C-type: Unknown (%u)",
2698                                         type);
2699                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2700                                         "Data (%d bytes)", mylen);
2701                     break;
2702                 }
2703                 break;
2704
2705             case RSVP_CLASS_ADMIN_STATUS: {
2706                 guint32 status;
2707                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_admin_status);
2708                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2709                                     "Length: %u", obj_length);
2710                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2711                                     "Class number: %u - %s", 
2712                                     class, object_type);
2713                 proto_item_set_text(ti, "ADMIN STATUS: ");
2714                 switch(type) {
2715                 case 1: 
2716                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2717                                         "C-type: 1");
2718                     status = tvb_get_ntohl(tvb, offset2);
2719                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
2720                                               "Admin Status: 0x%08x", status);
2721                     rsvp_admin_subtree = 
2722                         proto_item_add_subtree(ti2, ett_rsvp_admin_status_flags); 
2723                     proto_tree_add_text(rsvp_admin_subtree, tvb, offset2, 1,
2724                                         (status & (1<<31)) ? 
2725                                         "R: 1. Reflect" : 
2726                                         "R: 0. Do not reflect");
2727                     proto_tree_add_text(rsvp_admin_subtree, tvb, offset2+3, 1,
2728                                         (status & (1<<2)) ? 
2729                                         "T: 1. Testing" : 
2730                                         "T: 0. ");
2731                     proto_tree_add_text(rsvp_admin_subtree, tvb, offset2+3, 1,
2732                                         (status & (1<<1)) ? 
2733                                         "A: 1. Administratively down" : 
2734                                         "A: 0. ");
2735                     proto_tree_add_text(rsvp_admin_subtree, tvb, offset2+3, 1,
2736                                         (status & 1) ? 
2737                                         "D: 1. Deletion in progress" : 
2738                                         "D: 0. ");
2739                     proto_item_set_text(ti, "ADMIN-STATUS: %s %s %s %s", 
2740                                         (status & (1<<31)) ? "Reflect" : "",
2741                                         (status & (1<<2))  ? "Testing" : "",
2742                                         (status & (1<<1))  ? "Admin-Down" : "",
2743                                         (status & (1<<0))  ? "Deleting" : "");
2744                     break;
2745
2746                 default:
2747                     mylen = obj_length - 4;
2748                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2749                                         "C-type: Unknown (%u)",
2750                                         type);
2751                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2752                                         "Data (%d bytes)", mylen);
2753                     break;
2754                 }
2755             }
2756                 break;
2757
2758             case RSVP_CLASS_LSP_TUNNEL_IF_ID:
2759                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_lsp_tunnel_if_id);
2760                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2761                                     "Length: %u", obj_length);
2762                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2763                                     "Class number: %u - %s", 
2764                                     class, object_type);
2765                 proto_item_set_text(ti, "LSP INTERFACE-ID: ");
2766                 switch(type) {
2767                 case 1: 
2768                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2769                                         "C-type: 1 - IPv4");
2770                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
2771                                         "Router ID: %s",
2772                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
2773                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
2774                                         "Interface ID: %u", tvb_get_ntohl(tvb, offset2+4));
2775                     proto_item_set_text(ti, "LSP INTERFACE-ID: IPv4, Router-ID %s, Interface-ID %d", 
2776                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)),
2777                                         tvb_get_ntohl(tvb, offset2+4));
2778                     break;
2779
2780                 default:
2781                     mylen = obj_length - 4;
2782                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
2783                                         "C-type: Unknown (%u)",
2784                                         type);
2785                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2786                                         "Data (%d bytes)", mylen);
2787                     break;
2788                 }
2789                 break;
2790
2791             default :
2792                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_unknown_class);
2793                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2794                                     "Length: %u", obj_length);
2795                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2796                                     "Class number: %u - %s", 
2797                                     class, object_type);
2798             default_class:
2799                 mylen = obj_length - 4;
2800                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2801                                     "Data (%d bytes)", mylen);
2802                 break;
2803
2804             case RSVP_CLASS_NULL :
2805                 break;
2806
2807             }  
2808             
2809             offset += obj_length;
2810             len += obj_length;
2811         }
2812     }
2813 }
2814
2815 void
2816 proto_register_rsvp(void)
2817 {
2818         static gint *ett[] = {
2819                 &ett_rsvp,
2820                 &ett_rsvp_hdr,
2821                 &ett_rsvp_session,
2822                 &ett_rsvp_hop,
2823                 &ett_rsvp_hop_subobj,
2824                 &ett_rsvp_time_values,
2825                 &ett_rsvp_error,
2826                 &ett_rsvp_scope,
2827                 &ett_rsvp_style,
2828                 &ett_rsvp_confirm,
2829                 &ett_rsvp_sender_template,
2830                 &ett_rsvp_filter_spec,
2831                 &ett_rsvp_sender_tspec,
2832                 &ett_rsvp_sender_tspec_subtree,
2833                 &ett_rsvp_flowspec,
2834                 &ett_rsvp_flowspec_subtree,
2835                 &ett_rsvp_adspec,
2836                 &ett_rsvp_adspec_subtree,
2837                 &ett_rsvp_integrity,
2838                 &ett_rsvp_policy,
2839                 &ett_rsvp_label,
2840                 &ett_rsvp_label_request,
2841                 &ett_rsvp_session_attribute,
2842                 &ett_rsvp_session_attribute_flags,
2843                 &ett_rsvp_explicit_route,
2844                 &ett_rsvp_explicit_route_subobj,
2845                 &ett_rsvp_record_route,
2846                 &ett_rsvp_record_route_subobj,
2847                 &ett_rsvp_hello_obj,
2848                 &ett_rsvp_dclass,
2849                 &ett_rsvp_lsp_tunnel_if_id,
2850                 &ett_rsvp_admin_status,
2851                 &ett_rsvp_admin_status_flags,
2852                 &ett_rsvp_unknown_class,
2853         };
2854
2855         proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)",
2856             "RSVP", "rsvp");
2857         proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info));
2858         proto_register_subtree_array(ett, array_length(ett));
2859 }
2860
2861 void
2862 proto_reg_handoff_rsvp(void)
2863 {
2864         dissector_handle_t rsvp_handle;
2865
2866         rsvp_handle = create_dissector_handle(dissect_rsvp, proto_rsvp);
2867         dissector_add("ip.proto", IP_PROTO_RSVP, rsvp_handle);
2868 }