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