Squelch an MSVC++ complaint.
[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.47 2001/10/26 18:28:16 gram Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  * 
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 /*
29  * NOTES
30  *
31  * This module defines routines to disassemble RSVP packets, as defined in
32  * RFC 2205. All objects from RC2205 are supported, in IPv4 and IPv6 mode.
33  * In addition, the Integrated Services traffic specification objects
34  * defined in RFC2210 are also supported. 
35  *
36  * IPv6 support is not completely tested
37  *
38  * Mar 3, 2000: Added support for MPLS/TE objects, as defined in 
39  * <draft-ietf-mpls-rsvp-lsp-tunnel-04.txt>
40  */
41
42  
43 #ifdef HAVE_CONFIG_H
44 # include "config.h"
45 #endif
46
47 #include <stdio.h>
48
49 #ifdef HAVE_UNISTD_H
50 #include <unistd.h>
51 #endif
52
53 #include <stdlib.h>
54 #include <string.h>
55
56 #ifdef HAVE_SYS_TYPES_H
57 # include <sys/types.h>
58 #endif
59
60 #ifdef HAVE_NETINET_IN_H
61 # include <netinet/in.h>
62 #endif
63
64 #include <glib.h>
65
66 #ifdef NEED_SNPRINTF_H
67 # include "snprintf.h"
68 #endif
69
70 #include "packet.h"
71 #include "in_cksum.h"
72 #include "ieee-float.h"
73 #include "etypes.h"
74 #include "ipproto.h"
75
76 static int proto_rsvp = -1;
77
78 static gint ett_rsvp = -1;
79 static gint ett_rsvp_hdr = -1;
80 static gint ett_rsvp_session = -1;
81 static gint ett_rsvp_hop = -1;
82 static gint ett_rsvp_time_values = -1;
83 static gint ett_rsvp_error = -1;
84 static gint ett_rsvp_scope = -1;
85 static gint ett_rsvp_style = -1;
86 static gint ett_rsvp_confirm = -1;
87 static gint ett_rsvp_sender_template = -1;
88 static gint ett_rsvp_filter_spec = -1;
89 static gint ett_rsvp_sender_tspec = -1;
90 static gint ett_rsvp_flowspec = -1;
91 static gint ett_rsvp_adspec = -1;
92 static gint ett_rsvp_adspec_subtree = -1;
93 static gint ett_rsvp_integrity = -1;
94 static gint ett_rsvp_policy = -1;
95 static gint ett_rsvp_label = -1;
96 static gint ett_rsvp_label_request = -1;
97 static gint ett_rsvp_session_attribute = -1;
98 static gint ett_rsvp_session_attribute_flags = -1;
99 static gint ett_rsvp_hello_obj = -1;
100 static gint ett_rsvp_explicit_route = -1;
101 static gint ett_rsvp_explicit_route_subobj = -1;
102 static gint ett_rsvp_record_route = -1;
103 static gint ett_rsvp_record_route_subobj = -1;
104 static gint ett_rsvp_unknown_class = -1;
105
106
107 /*
108  * RSVP message types
109  */
110 typedef enum {
111     RSVP_MSG_PATH=1, 
112     RSVP_MSG_RESV, 
113     RSVP_MSG_PERR, 
114     RSVP_MSG_RERR,
115     RSVP_MSG_PTEAR, 
116     RSVP_MSG_RTEAR, 
117     RSVP_MSG_CONFIRM, 
118     RSVP_MSG_RTEAR_CONFIRM=10,
119     RSVP_MSG_BUNDLE = 12,
120     RSVP_MSG_ACK,
121     RSVP_MSG_SREFRESH = 15,
122     RSVP_MSG_HELLO = 20
123 } rsvp_message_types;
124
125 static value_string message_type_vals[] = { 
126     {RSVP_MSG_PATH, "PATH Message"},
127     {RSVP_MSG_RESV, "RESV Message"},
128     {RSVP_MSG_PERR, "PATH ERROR Message"},
129     {RSVP_MSG_RERR, "RESV ERROR Message"},
130     {RSVP_MSG_PTEAR, "PATH TEAR Message"},
131     {RSVP_MSG_RTEAR, "RESV TEAR Message"},
132     {RSVP_MSG_CONFIRM, "CONFIRM Message"},
133     {RSVP_MSG_RTEAR_CONFIRM, "RESV TEAR CONFIRM Message"},
134     {RSVP_MSG_BUNDLE, "BUNDLE Message"},
135     {RSVP_MSG_ACK, "ACK Message"},
136     {RSVP_MSG_SREFRESH, "SREFRESH Message"},
137     {RSVP_MSG_HELLO, "HELLO Message"},
138     {0, NULL}
139 };
140
141 /* 
142  * RSVP classes
143  */
144 #define MAX_RSVP_CLASS 15
145
146 enum rsvp_classes {
147     RSVP_CLASS_NULL=0,
148     RSVP_CLASS_SESSION,
149
150     RSVP_CLASS_HOP=3,
151     RSVP_CLASS_INTEGRITY,
152     RSVP_CLASS_TIME_VALUES,
153     RSVP_CLASS_ERROR,
154     RSVP_CLASS_SCOPE,
155     RSVP_CLASS_STYLE,
156     RSVP_CLASS_FLOWSPEC,
157     RSVP_CLASS_FILTER_SPEC,
158     RSVP_CLASS_SENDER_TEMPLATE,
159     RSVP_CLASS_SENDER_TSPEC,
160     RSVP_CLASS_ADSPEC,
161     RSVP_CLASS_POLICY,
162     RSVP_CLASS_CONFIRM,
163     RSVP_CLASS_LABEL,
164
165     RSVP_CLASS_LABEL_REQUEST=19,
166     RSVP_CLASS_EXPLICIT_ROUTE,
167     RSVP_CLASS_RECORD_ROUTE,
168
169     RSVP_CLASS_MESSAGE_ID = 23,
170     RSVP_CLASS_MESSAGE_ID_ACK,
171     RSVP_CLASS_MESSAGE_ID_LIST,
172
173     RSVP_CLASS_SESSION_ATTRIBUTE=207,
174     RSVP_CLASS_HELLO = 22
175 };
176
177 static value_string rsvp_class_vals[] = { 
178     {RSVP_CLASS_NULL, "NULL object"},
179     {RSVP_CLASS_SESSION, "SESSION object"},
180     {RSVP_CLASS_HOP, "HOP object"},
181     {RSVP_CLASS_INTEGRITY, "INTEGRITY object"},
182     {RSVP_CLASS_TIME_VALUES, "TIME VALUES object"},
183     {RSVP_CLASS_ERROR, "ERROR object"},
184     {RSVP_CLASS_SCOPE, "SCOPE object"},
185     {RSVP_CLASS_STYLE, "STYLE object"},
186     {RSVP_CLASS_FLOWSPEC, "FLOWSPEC object"},
187     {RSVP_CLASS_FILTER_SPEC, "FILTER SPEC object"},
188     {RSVP_CLASS_SENDER_TEMPLATE, "SENDER TEMPLATE object"},
189     {RSVP_CLASS_SENDER_TSPEC, "SENDER TSPEC object"},
190     {RSVP_CLASS_ADSPEC, "ADSPEC object"},
191     {RSVP_CLASS_POLICY, "POLICY object"},
192     {RSVP_CLASS_CONFIRM, "CONFIRM object"},
193     {RSVP_CLASS_LABEL, "LABEL object"},
194     {RSVP_CLASS_LABEL_REQUEST, "LABEL REQUEST object"},
195     {RSVP_CLASS_EXPLICIT_ROUTE, "EXPLICIT ROUTE object"},
196     {RSVP_CLASS_RECORD_ROUTE, "RECORD ROUTE object"},
197     {RSVP_CLASS_SESSION_ATTRIBUTE, "SESSION ATTRIBUTE object"},
198     {RSVP_CLASS_MESSAGE_ID, "MESSAGE-ID object"},
199     {RSVP_CLASS_MESSAGE_ID_ACK, "MESSAGE-ID ACK/NACK object"},
200     {RSVP_CLASS_MESSAGE_ID_LIST, "MESSAGE-ID LIST object"},
201     {RSVP_CLASS_HELLO, "HELLO object"},
202     {0, NULL}
203 };
204
205 /*
206  * RSVP error values
207  */
208 enum rsvp_error_types {
209     RSVP_ERROR_CONFIRM = 0,
210     RSVP_ERROR_ADMISSION,
211     RSVP_ERROR_POLICY,
212     RSVP_ERROR_NO_PATH,
213     RSVP_ERROR_NO_SENDER,
214     RSVP_ERROR_CONFLICT_RESV_STYLE,
215     RSVP_ERROR_UNKNOWN_RESV_STYLE,
216     RSVP_ERROR_CONFLICT_DEST_PORTS,
217     RSVP_ERROR_CONFLICT_SRC_PORTS,
218     RSVP_ERROR_PREEMPTED=12,
219     RSVP_ERROR_UNKNOWN_CLASS,
220     RSVP_ERROR_UNKNOWN_C_TYPE,
221     RSVP_ERROR_TRAFFIC = 21,
222     RSVP_ERROR_TRAFFIC_SYSTEM,
223     RSVP_ERROR_SYSTEM,
224     RSVP_ERROR_ROUTING,
225     RSVP_ERROR_NOTIFY
226 };
227
228 static value_string rsvp_error_vals[] = {
229     {RSVP_ERROR_CONFIRM, "Confirmation"},
230     {RSVP_ERROR_ADMISSION, "Admission Control Failure "},
231     {RSVP_ERROR_POLICY, "Policy Control Failure"},
232     {RSVP_ERROR_NO_PATH, "No PATH information for this RESV message"},
233     {RSVP_ERROR_NO_SENDER, "No sender information for this RESV message"},
234     {RSVP_ERROR_CONFLICT_RESV_STYLE, "Conflicting reservation styles"},
235     {RSVP_ERROR_UNKNOWN_RESV_STYLE, "Unknown reservation style"},
236     {RSVP_ERROR_CONFLICT_DEST_PORTS, "Conflicting destination ports"},
237     {RSVP_ERROR_CONFLICT_SRC_PORTS, "Conflicting source ports"},
238     {RSVP_ERROR_PREEMPTED, "Service preempted"},
239     {RSVP_ERROR_UNKNOWN_CLASS, "Unknown object class"},
240     {RSVP_ERROR_UNKNOWN_C_TYPE, "Unknown object C-type"},
241     {RSVP_ERROR_TRAFFIC, "Traffic Control Error"},
242     {RSVP_ERROR_TRAFFIC_SYSTEM, "Traffic Control System Error"},
243     {RSVP_ERROR_SYSTEM, "RSVP System Error"},
244     {RSVP_ERROR_ROUTING, "Routing Error"},
245     {RSVP_ERROR_NOTIFY, "RSVP Notify Error"},
246     {0, NULL}
247 };
248
249 /*
250  * Defines the reservation style plus style-specific information that
251  * is not a FLOWSPEC or FILTER_SPEC object, in a RESV message.
252  */
253 #define RSVP_DISTINCT (1 << 3)
254 #define RSVP_SHARED (2 << 3)
255 #define RSVP_SHARING_MASK (RSVP_DISTINCT | RSVP_SHARED)
256
257 #define RSVP_SCOPE_WILD 1
258 #define RSVP_SCOPE_EXPLICIT 2
259 #define RSVP_SCOPE_MASK 0x07
260
261 #define RSVP_WF (RSVP_SHARED | RSVP_SCOPE_WILD)
262 #define RSVP_FF (RSVP_DISTINCT | RSVP_SCOPE_EXPLICIT)
263 #define RSVP_SE (RSVP_SHARED | RSVP_SCOPE_EXPLICIT)
264
265 static value_string style_vals[] = {
266     { RSVP_WF, "Wildcard Filter" },
267     { RSVP_FF, "Fixed Filter" },
268     { RSVP_SE, "Shared-Explicit" },
269     { 0,       NULL }
270 };
271
272 /*
273  * Defines a desired QoS, in a RESV message.
274  */
275 enum    qos_service_type {
276     QOS_QUALITATIVE =     128,          /* Qualitative service */
277     QOS_CONTROLLED_LOAD=    5,          /* Controlled Load Service */
278     QOS_GUARANTEED =        2,          /* Guaranteed service */
279     QOS_TSPEC =             1           /* Traffic specification */
280     };
281
282 static value_string qos_vals[] = {
283     { QOS_QUALITATIVE, "Qualitative QoS" },
284     { QOS_CONTROLLED_LOAD, "Controlled-load QoS" },
285     { QOS_GUARANTEED, "Guaranteed rate QoS" },
286     { QOS_TSPEC, "Traffic specification" },
287     { 0, NULL }
288 };
289
290 static value_string svc_vals[] = {
291     { 127, "Token bucket TSpec" },
292     { 128, "Qualitative TSpec" },
293     { 130, "Guaranteed-rate RSpec" },
294     { 0, NULL }
295 };
296
297 enum rsvp_spec_types { INTSRV = 2 };
298
299 enum intsrv_services {
300         INTSRV_GENERAL = 1,
301         INTSRV_GTD = 2,
302         INTSRV_CLOAD = 5,
303         INTSRV_QUALITATIVE = 128
304 };
305
306 static value_string intsrv_services_str[] = { 
307     {INTSRV_GENERAL, "Default General Parameters"},
308     {INTSRV_GTD, "Guaranteed"},
309     {INTSRV_CLOAD, "Controlled Load"},
310     {INTSRV_QUALITATIVE, "Qualitative"},
311     { 0, NULL }
312 };
313
314 enum intsrv_field_name {
315         INTSRV_NON_IS_HOPS = 1, INTSRV_COMPOSED_NON_IS_HOPS,
316         INTSRV_IS_HOPS, INTSRV_COMPOSED_IS_HOPS,
317         INTSRV_PATH_BANDWIDTH, INTSRV_MIN_PATH_BANDWIDTH,
318         INTSRV_IF_LATENCY, INTSRV_PATH_LATENCY,
319         INTSRV_MTU, INTSRV_COMPOSED_MTU,
320
321         INTSRV_TOKEN_BUCKET_TSPEC = 127,
322         INTSRV_QUALITATIVE_TSPEC = 128,
323         INTSRV_GTD_RSPEC = 130,
324
325         INTSRV_DELAY = 131,     /* Gtd Parameter C - Max Delay Bound - bytes */
326         INTSRV_MAX_JITTER,      /* Gtd Parameter D - Max Jitter */
327         INTSRV_E2E_DELAY,       /* Gtd Parameter Ctot */
328         INTSRV_E2E_MAX_JITTER,  /* Gtd Parameter Dtot */
329         INTSRV_SHP_DELAY,       /* Gtd Parameter Csum */
330         INTSRV_SHP_MAX_JITTER   /* Gtd Parameter Dsum */
331 };
332
333 static value_string adspec_params[] = { 
334     {4, "IS Hop Count"},
335     {6, "Path b/w estimate"},
336     {8, "Minimum path latency"},
337     {10, "Composed MTU"},
338     {133, "End-to-end composed value for C"},
339     {134, "End-to-end composed value for D"},
340     {135, "Since-last-reshaping point composed C"},
341     {136, "Since-last-reshaping point composed D"},
342     { 0, NULL }
343 };
344
345 /* -------------------- Stuff for MPLS/TE objects -------------------- */
346
347 static const value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"},
348                                            {IP_PROTO_IGMP, "IGMP"},
349                                            {IP_PROTO_TCP,  "TCP" },
350                                            {IP_PROTO_UDP,  "UDP" },
351                                            {IP_PROTO_OSPF, "OSPF"},
352                                            {0,             NULL  } };
353
354 /* Filter keys */
355 enum rsvp_filter_keys {
356
357     /* Message types */
358     RSVPF_MSG,          /* Message type */
359     /* Shorthand for message types */
360     RSVPF_PATH,
361     RSVPF_RESV,
362     RSVPF_PATHERR,
363     RSVPF_RESVERR,
364     RSVPF_PATHTEAR,
365     RSVPF_RESVTEAR,
366     RSVPF_RCONFIRM,
367     RSVPF_JUNK_MSG8,
368     RSVPF_JUNK_MSG9,
369     RSVPF_RTEARCONFIRM,
370     RSVPF_JUNK11,
371     RSVPF_BUNDLE,
372     RSVPF_ACK,
373     RSVPF_JUNK14,
374     RSVPF_SREFRESH,
375     RSVPF_HELLO,
376     /* Does the message contain an object of this type? */
377     RSVPF_OBJECT,
378     /* Object present shorthands */
379     RSVPF_SESSION,
380     RSVPF_DUMMY_1,
381     RSVPF_HOP,
382     RSVPF_INTEGRITY,
383     RSVPF_TIME_VALUES,
384     RSVPF_ERROR,
385     RSVPF_SCOPE,
386     RSVPF_STYLE,
387     RSVPF_FLOWSPEC,
388     RSVPF_FILTER_SPEC,
389     RSVPF_SENDER,
390     RSVPF_TSPEC,
391     RSVPF_ADSPEC,
392     RSVPF_POLICY,
393     RSVPF_CONFIRM,
394     RSVPF_LABEL,
395     RSVPF_DUMMY_2,
396     RSVPF_DUMMY_3,
397     RSVPF_LABEL_REQUEST,
398     RSVPF_EXPLICIT_ROUTE,
399     RSVPF_RECORD_ROUTE,
400     RSVPF_DUMMY_4,
401     RSVPF_MESSAGE_ID,
402     RSVPF_MESSAGE_ID_ACK,
403     RSVPF_MESSAGE_ID_LIST,
404     RSVPF_HELLO_OBJ,
405     RSVPF_SESSION_ATTRIBUTE,
406     RSVPF_UNKNOWN_OBJ, 
407
408     /* Session object */
409     RSVPF_SESSION_IP,
410     RSVPF_SESSION_PROTO,
411     RSVPF_SESSION_PORT,
412     RSVPF_SESSION_TUNNEL_ID,
413     RSVPF_SESSION_EXT_TUNNEL_ID,
414
415     /* Sender template */
416     RSVPF_SENDER_IP,
417     RSVPF_SENDER_PORT,
418     RSVPF_SENDER_LSP_ID,
419
420     /* Sentinel */
421     RSVPF_MAX
422 };
423
424 static int rsvp_filter[RSVPF_MAX];
425
426 static hf_register_info rsvpf_info[] = {
427
428     /* Message type number */
429     {&rsvp_filter[RSVPF_MSG], 
430      { "Message Type", "rsvp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
431         "", HFILL }},
432
433     /* Message type shorthands */
434     {&rsvp_filter[RSVPF_PATH], 
435      { "Path Message", "rsvp.path", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
436         "", HFILL }},
437
438     {&rsvp_filter[RSVPF_HELLO], 
439      { "HELLO Message", "rsvp.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
440         "", HFILL }},
441
442     {&rsvp_filter[RSVPF_RESV], 
443      { "Resv Message", "rsvp.resv", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
444         "", HFILL }},
445
446     {&rsvp_filter[RSVPF_PATHERR], 
447      { "Path Error Message", "rsvp.perr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
448         "", HFILL }},
449
450     {&rsvp_filter[RSVPF_RESVERR], 
451      { "Resv Error Message", "rsvp.rerr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
452         "", HFILL }},
453
454     {&rsvp_filter[RSVPF_PATHTEAR], 
455      { "Path Tear Message", "rsvp.ptear", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
456         "", HFILL }},
457
458     {&rsvp_filter[RSVPF_RESVTEAR], 
459      { "Resv Tear Message", "rsvp.rtear", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
460         "", HFILL }},
461
462     {&rsvp_filter[RSVPF_RCONFIRM], 
463      { "Resv Confirm Message", "rsvp.resvconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
464         "", HFILL }},
465
466     {&rsvp_filter[RSVPF_RTEARCONFIRM], 
467      { "Resv Tear Confirm Message", "rsvp.rtearconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
468         "", HFILL }},
469
470     /* Object class */
471     {&rsvp_filter[RSVPF_OBJECT], 
472      { "Object class", "rsvp.object", FT_UINT8, BASE_DEC, VALS(rsvp_class_vals), 0x0,
473         "", HFILL }},
474
475     /* Object present shorthands */
476     {&rsvp_filter[RSVPF_SESSION], 
477      { "SESSION", "rsvp.session", FT_NONE, BASE_NONE, NULL, 0x0,
478         "", HFILL }},
479
480     {&rsvp_filter[RSVPF_HOP], 
481      { "HOP", "rsvp.hop", FT_NONE, BASE_NONE, NULL, 0x0,
482         "", HFILL }},
483
484     {&rsvp_filter[RSVPF_HELLO_OBJ], 
485      { "HELLO Request/Ack", "rsvp.hello_obj", FT_NONE, BASE_NONE, NULL, 0x0,
486         "", HFILL }},
487
488     {&rsvp_filter[RSVPF_INTEGRITY], 
489      { "INTEGRITY", "rsvp.integrity", FT_NONE, BASE_NONE, NULL, 0x0,
490         "", HFILL }},
491
492     {&rsvp_filter[RSVPF_TIME_VALUES], 
493      { "TIME VALUES", "rsvp.time", FT_NONE, BASE_NONE, NULL, 0x0,
494         "", HFILL }},
495
496     {&rsvp_filter[RSVPF_ERROR], 
497      { "ERROR", "rsvp.error", FT_NONE, BASE_NONE, NULL, 0x0,
498         "", HFILL }},
499
500     {&rsvp_filter[RSVPF_SCOPE], 
501      { "SCOPE", "rsvp.scope", FT_NONE, BASE_NONE, NULL, 0x0,
502         "", HFILL }},
503
504     {&rsvp_filter[RSVPF_STYLE], 
505      { "STYLE", "rsvp.style", FT_NONE, BASE_NONE, NULL, 0x0,
506         "", HFILL }},
507
508     {&rsvp_filter[RSVPF_FLOWSPEC], 
509      { "FLOWSPEC", "rsvp.flowspec", FT_NONE, BASE_NONE, NULL, 0x0,
510         "", HFILL }},
511
512     {&rsvp_filter[RSVPF_FILTER_SPEC], 
513      { "FILTERSPEC", "rsvp.filter", FT_NONE, BASE_NONE, NULL, 0x0,
514         "", HFILL }},
515
516     {&rsvp_filter[RSVPF_SENDER], 
517      { "SENDER TEMPLATE", "rsvp.sender", FT_NONE, BASE_NONE, NULL, 0x0,
518         "", HFILL }},
519
520     {&rsvp_filter[RSVPF_TSPEC], 
521      { "SENDER TSPEC", "rsvp.tspec", FT_NONE, BASE_NONE, NULL, 0x0,
522         "", HFILL }},
523
524     {&rsvp_filter[RSVPF_ADSPEC], 
525      { "ADSPEC", "rsvp.adspec", FT_NONE, BASE_NONE, NULL, 0x0,
526         "", HFILL }},
527
528     {&rsvp_filter[RSVPF_POLICY], 
529      { "POLICY", "rsvp.policy", FT_NONE, BASE_NONE, NULL, 0x0,
530         "", HFILL }},
531
532     {&rsvp_filter[RSVPF_CONFIRM], 
533      { "CONFIRM", "rsvp.confirm", FT_NONE, BASE_NONE, NULL, 0x0,
534         "", HFILL }},
535
536     {&rsvp_filter[RSVPF_LABEL], 
537      { "LABEL", "rsvp.label", FT_NONE, BASE_NONE, NULL, 0x0,
538         "", HFILL }},
539
540     {&rsvp_filter[RSVPF_LABEL_REQUEST], 
541      { "LABEL REQUEST", "rsvp.label_request", FT_NONE, BASE_NONE, NULL, 0x0,
542         "", HFILL }},
543
544     {&rsvp_filter[RSVPF_SESSION_ATTRIBUTE], 
545      { "SESSION ATTRIBUTE", "rsvp.session_attribute", FT_NONE, BASE_NONE, NULL, 0x0,
546         "", HFILL }},
547
548     {&rsvp_filter[RSVPF_EXPLICIT_ROUTE], 
549      { "EXPLICIT ROUTE", "rsvp.explicit_route", FT_NONE, BASE_NONE, NULL, 0x0,
550         "", HFILL }},
551
552     {&rsvp_filter[RSVPF_RECORD_ROUTE], 
553      { "RECORD ROUTE", "rsvp.record_route", FT_NONE, BASE_NONE, NULL, 0x0,
554         "", HFILL }},
555
556     {&rsvp_filter[RSVPF_MESSAGE_ID], 
557      { "MESSAGE-ID", "rsvp.msgid", FT_NONE, BASE_NONE, NULL, 0x0,
558         "", HFILL }},
559
560     {&rsvp_filter[RSVPF_MESSAGE_ID_ACK], 
561      { "MESSAGE-ID ACK", "rsvp.ack", FT_NONE, BASE_NONE, NULL, 0x0,
562         "", HFILL }},
563
564     {&rsvp_filter[RSVPF_MESSAGE_ID_LIST], 
565      { "MESSAGE-ID LIST", "rsvp.msgid_list", FT_NONE, BASE_NONE, NULL, 0x0,
566         "", HFILL }},
567
568     {&rsvp_filter[RSVPF_HELLO_OBJ], 
569      { "HELLO Message", "rsvp.hello", FT_NONE, BASE_NONE, NULL, 0x0,
570         "", HFILL }},
571
572     {&rsvp_filter[RSVPF_UNKNOWN_OBJ], 
573      { "Unknown object", "rsvp.obj_unknown", FT_NONE, BASE_NONE, NULL, 0x0,
574         "", HFILL }},
575
576     /* Session fields */
577     {&rsvp_filter[RSVPF_SESSION_IP], 
578      { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
579         "", HFILL }},
580
581     {&rsvp_filter[RSVPF_SESSION_PORT], 
582      { "Port number", "rsvp.session.port", FT_UINT16, BASE_DEC, NULL, 0x0,
583         "", HFILL }},
584
585     {&rsvp_filter[RSVPF_SESSION_PROTO], 
586      { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_DEC, VALS(proto_vals), 0x0,
587         "", HFILL }},
588
589     {&rsvp_filter[RSVPF_SESSION_TUNNEL_ID], 
590      { "Tunnel ID", "rsvp.session.tunnel_id", FT_UINT16, BASE_DEC, NULL, 0x0,
591         "", HFILL }},
592
593     {&rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID], 
594      { "Extended tunnel ID", "rsvp.session.ext_tunnel_id", FT_UINT32, BASE_DEC, NULL, 0x0,
595         "", HFILL }},
596
597     /* Sender template/Filterspec fields */
598     {&rsvp_filter[RSVPF_SENDER_IP], 
599      { "Sender IPv4 address", "rsvp.sender.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
600         "", HFILL }},
601
602     {&rsvp_filter[RSVPF_SENDER_PORT], 
603      { "Sender port number", "rsvp.sender.port", FT_UINT16, BASE_DEC, NULL, 0x0,
604        "", HFILL }},
605
606     {&rsvp_filter[RSVPF_SENDER_LSP_ID], 
607      { "Sender LSP ID", "rsvp.sender.lsp_id", FT_UINT16, BASE_DEC, NULL, 0x0,
608         "", HFILL }}
609 };
610
611 static inline int rsvp_class_to_filter_num(int classnum)
612 {
613     switch(classnum) {
614     case RSVP_CLASS_SESSION :
615     case RSVP_CLASS_HOP :
616     case RSVP_CLASS_INTEGRITY :
617     case RSVP_CLASS_TIME_VALUES :
618     case RSVP_CLASS_ERROR :
619     case RSVP_CLASS_SCOPE :
620     case RSVP_CLASS_STYLE :
621     case RSVP_CLASS_FLOWSPEC :
622     case RSVP_CLASS_FILTER_SPEC :
623     case RSVP_CLASS_SENDER_TEMPLATE :
624     case RSVP_CLASS_SENDER_TSPEC :
625     case RSVP_CLASS_ADSPEC :
626     case RSVP_CLASS_POLICY :
627     case RSVP_CLASS_CONFIRM :
628     case RSVP_CLASS_LABEL :
629     case RSVP_CLASS_LABEL_REQUEST :
630     case RSVP_CLASS_EXPLICIT_ROUTE :
631     case RSVP_CLASS_RECORD_ROUTE :
632     case RSVP_CLASS_MESSAGE_ID :
633     case RSVP_CLASS_MESSAGE_ID_ACK :
634     case RSVP_CLASS_MESSAGE_ID_LIST :    
635         return classnum + RSVPF_OBJECT;
636         break;
637     case RSVP_CLASS_HELLO :
638         return RSVPF_HELLO_OBJ;
639         break;
640
641     case RSVP_CLASS_SESSION_ATTRIBUTE :
642         return RSVPF_SESSION_ATTRIBUTE;
643         
644     default:
645         return RSVPF_UNKNOWN_OBJ;
646     }
647 }
648
649 static void 
650 dissect_rsvp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
651 {
652     int offset = 0;
653     proto_tree *rsvp_tree = NULL, *ti, *ti2; 
654     proto_tree *rsvp_header_tree;
655     proto_tree *rsvp_object_tree;
656     proto_tree *rsvp_sa_flags_tree;
657     proto_tree *rsvp_ero_subtree;
658     guint8 ver_flags;
659     guint8 message_type;
660     guint16 cksum, computed_cksum;
661     vec_t cksum_vec[1];
662     int i, j, k, l, len;
663     int msg_length;
664     int obj_length;
665     int mylen;
666     int offset2;
667     char *objtype;
668
669     if (check_col(pinfo->fd, COL_PROTOCOL))
670         col_set_str(pinfo->fd, COL_PROTOCOL, "RSVP");
671     if (check_col(pinfo->fd, COL_INFO))
672         col_clear(pinfo->fd, COL_INFO);
673
674     ver_flags = tvb_get_guint8(tvb, offset+0);
675     message_type = tvb_get_guint8(tvb, offset+1);
676     if (check_col(pinfo->fd, COL_INFO)) {
677         col_add_str(pinfo->fd, COL_INFO,
678             val_to_str(message_type, message_type_vals, "Unknown (%u)")); 
679     }
680
681     if (tree) {
682         msg_length = tvb_get_ntohs(tvb, offset+6);
683         ti = proto_tree_add_item(tree, proto_rsvp, tvb, offset, msg_length,
684             FALSE);
685         rsvp_tree = proto_item_add_subtree(ti, ett_rsvp);
686
687         ti = proto_tree_add_text(rsvp_tree, tvb, offset, 8, "RSVP Header"); 
688         rsvp_header_tree = proto_item_add_subtree(ti, ett_rsvp_hdr);
689
690         proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "RSVP Version: %u", 
691                             (ver_flags & 0xf0)>>4);  
692         proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "Flags: %02x",
693                             ver_flags & 0xf);
694         proto_tree_add_uint(rsvp_header_tree, rsvp_filter[RSVPF_MSG], tvb, 
695                             offset+1, 1, message_type);
696         if (message_type <= RSVPF_RTEARCONFIRM &&
697                         message_type != RSVPF_JUNK_MSG8 &&
698                         message_type != RSVPF_JUNK_MSG9 ) {
699                proto_tree_add_boolean_hidden(rsvp_header_tree, rsvp_filter[RSVPF_MSG + message_type], tvb, 
700                                    offset+1, 1, 1);
701         }
702         cksum = tvb_get_ntohs(tvb, offset+2);
703         if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) {
704             /* The packet isn't part of a fragmented datagram and isn't
705                truncated, so we can checksum it. */
706             cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length);
707             cksum_vec[0].len = msg_length;
708             computed_cksum = in_cksum(&cksum_vec[0], 1);
709             if (computed_cksum == 0) {
710                 proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
711                                     "Message Checksum: 0x%04x (correct)",
712                                     cksum);
713             } else {
714                 proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
715                                     "Message Checksum: 0x%04x (incorrect, should be 0x%04x)",
716                                     cksum,
717                                     in_cksum_shouldbe(cksum, computed_cksum));
718             }
719         } else {
720             proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
721                                 "Message Checksum: 0x%04x",
722                                 cksum);
723         }
724         proto_tree_add_text(rsvp_header_tree, tvb, offset+4, 1,
725                             "Sending TTL: %u",
726                             tvb_get_guint8(tvb, offset+4));
727         proto_tree_add_text(rsvp_header_tree, tvb, offset+6, 2,
728                             "Message length: %u", msg_length);
729
730         offset += 8;
731         len = 8;
732         while (len < msg_length) {
733             guint8 class;       
734             guint8 type;
735             char *object_type;
736
737             obj_length = tvb_get_ntohs(tvb, offset);
738             class = tvb_get_guint8(tvb, offset+2);
739             type = tvb_get_guint8(tvb, offset+3);
740             object_type = val_to_str(class, rsvp_class_vals, "Unknown");
741             proto_tree_add_uint_hidden(rsvp_tree, rsvp_filter[RSVPF_OBJECT], tvb, 
742                                             offset, obj_length, class);
743             ti = proto_tree_add_item(rsvp_tree, rsvp_filter[rsvp_class_to_filter_num(class)],
744                                      tvb, offset, obj_length, FALSE);
745
746             offset2 = offset+4;
747
748             switch(class) {
749
750             case RSVP_CLASS_SESSION :           
751                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_session);
752                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
753                                     "Length: %u", obj_length);
754                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
755                                     "Class number: %u - %s", 
756                                     class, object_type);
757                 mylen = obj_length - 4;
758                 switch(type) {
759                 case 1: {
760                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
761                                         "C-type: 1 - IPv4");
762                     proto_tree_add_item(rsvp_object_tree,
763                                         rsvp_filter[RSVPF_SESSION_IP],
764                                         tvb, offset2, 4, FALSE);
765
766                     proto_tree_add_item(rsvp_object_tree,
767                                         rsvp_filter[RSVPF_SESSION_PROTO], tvb, 
768                                         offset2+4, 1, FALSE);
769                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1,
770                                         "Flags: %x",
771                                         tvb_get_guint8(tvb, offset2+5));
772                     proto_tree_add_item(rsvp_object_tree,
773                                         rsvp_filter[RSVPF_SESSION_PORT], tvb, 
774                                         offset2+6, 2, FALSE);
775                     proto_item_set_text(ti, "SESSION: IPv4, %s, %d, %d", 
776                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)), 
777                                         tvb_get_guint8(tvb, offset2+4),
778                                         tvb_get_ntohs(tvb, offset2+6));
779                     break;
780                 }
781
782                 case 2: {
783                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
784                                         "C-type: 2 - IPv6");
785                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
786                                         "Destination address: %s", 
787                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
788                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1,
789                                         "Protocol: %u",
790                                         tvb_get_guint8(tvb, offset2+16));
791                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1,
792                                         "Flags: %x",
793                                         tvb_get_guint8(tvb, offset2+17));
794                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
795                                         "Destination port: %u", 
796                                         tvb_get_ntohs(tvb, offset2+18));
797                     break;
798                 }
799                 
800                 case 7: {
801                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
802                                         "C-type: 7 - IPv4 LSP");
803                     proto_tree_add_item(rsvp_object_tree,
804                                         rsvp_filter[RSVPF_SESSION_IP],
805                                         tvb, offset2, 4, FALSE);
806
807                     proto_tree_add_item(rsvp_object_tree,
808                                         rsvp_filter[RSVPF_SESSION_TUNNEL_ID],
809                                         tvb, offset2+6, 2, FALSE);
810
811                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4, 
812                                         "Extended Tunnel ID: %u (%s)",
813                                         tvb_get_ntohl(tvb, offset2+8),
814                                         ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
815                     proto_tree_add_item_hidden(rsvp_object_tree,
816                                         rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID],
817                                         tvb, offset2+8, 4, FALSE);
818                     proto_item_set_text(ti, "SESSION: IPv4-LSP, %s, %d, %0x", 
819                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)), 
820                                         tvb_get_ntohs(tvb, offset2+6),
821                                         tvb_get_ntohl(tvb, offset2+8));
822                     break;
823                 }
824
825                 default: {
826                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
827                                         "C-type: Unknown (%u)",
828                                         type);
829                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
830                                         "Data (%d bytes)", mylen);
831                 }
832                 }
833                 break;
834                 
835             case RSVP_CLASS_HOP :               
836                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_hop);
837                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
838                                     "Length: %u", obj_length);
839                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
840                                     "Class number: %u - %s", 
841                                     class, object_type);
842                 mylen = obj_length - 4;
843                 switch(type) {
844                 case 1: {
845                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
846                                         "C-type: 1 - IPv4");
847                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
848                                         "Neighbor address: %s", 
849                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
850                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
851                                         "Logical interface: %u", 
852                                         tvb_get_ntohl(tvb, offset2+4));
853                     proto_item_set_text(ti, "HOP: IPv4, %s", 
854                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
855                     break;
856                 }
857
858                 case 2: {
859                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
860                                         "C-type: 2 - IPv6");
861                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
862                                         "Neighbor address: %s", 
863                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
864                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 4,
865                                         "Logical interface: 0x%08x", 
866                                         tvb_get_ntohl(tvb, offset2+16));
867                     break;
868                 }
869                 
870                 default: {
871                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
872                                         "C-type: Unknown (%u)",
873                                         type);
874                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
875                                         "Data (%d bytes)", mylen);
876                 }
877                 }
878                 break;
879                 
880             case RSVP_CLASS_TIME_VALUES : 
881                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_time_values);
882                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
883                                     "Length: %u", obj_length);
884                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
885                                     "Class number: %u - %s", 
886                                     class, object_type);
887                 mylen = obj_length - 4;
888                 switch(type) {
889                 case 1: {
890                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
891                                         "C-type: 1");
892                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
893                                         "Refresh interval: %u ms (%u seconds)",
894                                         tvb_get_ntohl(tvb, offset2),
895                                         tvb_get_ntohl(tvb, offset2)/1000);
896                     proto_item_set_text(ti, "TIME VALUES: %d ms", 
897                                         tvb_get_ntohl(tvb, offset2));
898                     break;
899                 }
900
901                 default: {
902                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
903                                         "C-type: Unknown (%u)",
904                                         type);
905                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
906                                         "Data (%d bytes)", mylen);
907                     break;
908                 }
909                 }
910                 break;
911
912             case RSVP_CLASS_ERROR :
913                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_error);
914                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
915                                     "Length: %u", obj_length);
916                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
917                                     "Class number: %u - %s", 
918                                     class, object_type);
919                 mylen = obj_length - 4;
920                 switch(type) {
921                 case 1: {
922                     guint8 error_code;
923
924                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
925                                         "C-type: 1 - IPv4");
926                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
927                                         "Error node: %s",
928                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
929                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 1,
930                                         "Flags: 0x%02x",
931                                         tvb_get_guint8(tvb, offset2+4));
932                     error_code = tvb_get_guint8(tvb, offset2+5);
933                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1,
934                                         "Error code: %u - %s", error_code,
935                                         val_to_str(error_code, rsvp_error_vals, "Unknown"));
936                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+6, 2,
937                                         "Error value: %u",
938                                         tvb_get_ntohs(tvb, offset2+6));
939                     proto_item_set_text(ti, "ERROR: IPv4, %d, %d, %s", 
940                                         tvb_get_guint8(tvb, offset2+5),
941                                         tvb_get_ntohs(tvb, offset2+6),
942                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
943                     break;
944                 }
945
946                 case 2: {
947                     guint8 error_code;
948
949                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
950                                         "C-type: 2 - IPv6");
951                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
952                                         "Error node: %s",
953                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
954                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1,
955                                         "Flags: 0x%02x",
956                                         tvb_get_guint8(tvb, offset2+16));
957                     error_code = tvb_get_guint8(tvb, offset2+17);
958                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1,
959                                         "Error code: %u - %s", error_code,
960                                         val_to_str(error_code, rsvp_error_vals, "Unknown"));
961                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
962                                         "Error value: %u",
963                                         tvb_get_ntohs(tvb, offset2+18));
964                     break;
965                 }
966                 
967                 default: {
968                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
969                                         "C-type: Unknown (%u)",
970                                         type);
971                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
972                                         "Data (%d bytes)", mylen);
973                 }
974                 }
975                 break;
976                 
977
978             case RSVP_CLASS_SCOPE : 
979                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_scope);
980                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
981                                     "Length: %u", obj_length);
982                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
983                                     "Class number: %u - %s", 
984                                     class, object_type);
985                 mylen = obj_length - 4;
986                 switch(type) {
987                 case 1: {
988                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
989                                         "C-type: 1 - IPv4");
990                     while (mylen > 0) {
991                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
992                                             "IPv4 Address: %s",
993                                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
994                         offset2 += 4;
995                         mylen -= 4;
996                     }
997                     break;
998                 }
999
1000                 case 2: {
1001                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1002                                         "C-type: 2 - IPv6");
1003                     while (mylen > 0) {
1004                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, 
1005                                             "IPv6 Address: %s",
1006                                             ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1007                         offset2 += 16;
1008                         mylen -= 16;
1009                     }
1010                     break;
1011                 }
1012                 
1013                 default: {
1014                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1015                                         "C-type: Unknown (%u)",
1016                                         type);
1017                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1018                                         "Data (%d bytes)", mylen);
1019                 }
1020                 }
1021                 break;
1022                 
1023             case RSVP_CLASS_STYLE : 
1024                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_style);
1025                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1026                                     "Length: %u", obj_length);
1027                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1028                                     "Class number: %u - %s", 
1029                                     class, object_type);
1030                 mylen = obj_length - 4;
1031                 switch(type) {
1032                 case 1: {
1033                     guint32 style;
1034
1035                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1036                                         "C-type: 1");
1037                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
1038                                         "Flags: 0x%02x",
1039                                         tvb_get_guint8(tvb, offset2));
1040                     style = tvb_get_ntoh24(tvb, offset2+1);
1041                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+1,
1042                                         3, "Style: 0x%06X - %s", style,
1043                                         val_to_str(style, style_vals, "Unknown"));
1044                     proto_item_set_text(ti, "STYLE: %s (%d)", 
1045                                         val_to_str(style, style_vals, "Unknown"),
1046                                         style);
1047                     break;
1048                 }
1049
1050                 default: {
1051                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1052                                         "C-type: Unknown (%u)",
1053                                         type);
1054                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1055                                         "Data (%d bytes)", mylen);
1056                     break;
1057                 }
1058                 }
1059                 break;
1060             
1061             case RSVP_CLASS_CONFIRM :           
1062                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_confirm);
1063                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1064                                     "Length: %u", obj_length);
1065                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1066                                     "Class number: %u - %s", 
1067                                     class, object_type);
1068                 mylen = obj_length - 4;
1069                 switch(type) {
1070                 case 1: {
1071                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1072                                         "C-type: 1 - IPv4");
1073                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, 
1074                                         "Receiver address: %s", 
1075                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1076                     proto_item_set_text(ti, "CONFIRM: %s", 
1077                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1078                     break;
1079                 }
1080
1081                 case 2: {
1082                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1083                                         "C-type: 2 - IPv6");
1084                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, 
1085                                         "Receiver address: %s", 
1086                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1087                     break;
1088                 }
1089
1090                 default: {
1091                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1092                                         "C-type: Unknown (%u)",
1093                                         type);
1094                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1095                                         "Data (%d bytes)", mylen);
1096                 }
1097                 }
1098                 break;
1099
1100             case RSVP_CLASS_SENDER_TEMPLATE :
1101                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_template);
1102                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1103                                     "Length: %u", obj_length);
1104                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1105                                     "Class number: %u - %s", 
1106                                     class, object_type);
1107                 objtype = "SENDER TEMPLATE";
1108                 goto common_template;
1109             case RSVP_CLASS_FILTER_SPEC :
1110                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_filter_spec);
1111                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1112                                     "Length: %u", obj_length);
1113                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1114                                     "Class number: %u - %s", 
1115                                     class, object_type);
1116                 objtype = "FILTERSPEC";
1117             common_template:
1118                 mylen = obj_length - 4;
1119                 switch(type) {
1120                 case 1: {
1121                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1122                                         "C-type: 1 - IPv4");
1123                     proto_tree_add_item(rsvp_object_tree,
1124                                         rsvp_filter[RSVPF_SENDER_IP],
1125                                         tvb, offset2, 4, FALSE);
1126                     proto_tree_add_item(rsvp_object_tree,
1127                                         rsvp_filter[RSVPF_SENDER_PORT],
1128                                         tvb, offset2+6, 2, FALSE);
1129                     proto_item_set_text(ti, "%s: IPv4, %s, %d", objtype,
1130                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)), 
1131                                         tvb_get_ntohs(tvb, offset2+6));
1132                     break;
1133                 }
1134
1135                 case 2: {
1136                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1137                                         "C-type: 2 - IPv6");
1138                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, 
1139                                         "Source address: %s", 
1140                                         ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1141                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
1142                                         "Source port: %u",
1143                                         tvb_get_ntohs(tvb, offset2+18));
1144                     break;
1145                 }
1146                 
1147                 case 7: {
1148                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1149                                         "C-type: 7 - IPv4 LSP");
1150                     proto_tree_add_item(rsvp_object_tree,
1151                                         rsvp_filter[RSVPF_SENDER_IP],
1152                                         tvb, offset2, 4, FALSE);
1153                     proto_tree_add_item(rsvp_object_tree,
1154                                         rsvp_filter[RSVPF_SENDER_LSP_ID],
1155                                         tvb, offset2+6, 2, FALSE);
1156                     proto_item_set_text(ti, "%s: IPv4-LSP, %s, %d", objtype,
1157                                         ip_to_str(tvb_get_ptr(tvb, offset2, 4)), 
1158                                         tvb_get_ntohs(tvb, offset2+6));
1159                     break;
1160                 }
1161
1162                 default: {
1163                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1164                                         "C-type: Unknown (%u)",
1165                                         type);
1166                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1167                                         "Data (%d bytes)", mylen);
1168                 }
1169                 }
1170                 break;
1171
1172             case RSVP_CLASS_SENDER_TSPEC : {
1173                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_tspec);
1174                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1175                                     "Length: %u", obj_length);
1176                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1177                                     "Class number: %u - %s", 
1178                                     class, object_type);
1179                 mylen = obj_length - 4;
1180
1181                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1182                                     "Message format version: %u", 
1183                                     tvb_get_guint8(tvb, offset2)>>4);
1184                 proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1185                                     "Data length: %u words, not including header", 
1186                                     tvb_get_ntohs(tvb, offset2+2));
1187
1188                 mylen -= 4;
1189                 offset2 += 4;
1190                 while (mylen > 0) {
1191                     guint8 service_num;
1192                     guint8 param_id;
1193                     guint16 length;
1194
1195                     service_num = tvb_get_guint8(tvb, offset2);
1196                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1197                                         "Service header: %u - %s", 
1198                                         service_num,
1199                                         val_to_str(service_num, qos_vals, "Unknown"));
1200                     length = tvb_get_ntohs(tvb, offset2+2);
1201                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1202                                         "Length of service %u data: %u words, " 
1203                                         "not including header", 
1204                                         service_num, length);
1205
1206                     mylen -= 4;
1207                     offset2 += 4;
1208
1209                     switch(service_num) {
1210                         
1211                     case QOS_TSPEC :
1212                         /* Token bucket TSPEC */
1213                         param_id = tvb_get_guint8(tvb, offset2);
1214                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1215                                             "Parameter %u - %s", 
1216                                             param_id,
1217                                             val_to_str(param_id, svc_vals, "Unknown"));
1218                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
1219                                             "Parameter %u flags: 0x%02x",
1220                                             param_id,
1221                                             tvb_get_guint8(tvb, offset2+1));
1222                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1223                                             "Parameter %u data length: %u words, " 
1224                                             "not including header",
1225                                             param_id,
1226                                             tvb_get_ntohs(tvb, offset2+2));
1227                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1228                                             "Token bucket rate: %ld", 
1229                                             tvb_ieee_to_long(tvb, offset2+4));
1230                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
1231                                             "Token bucket size: %ld", 
1232                                             tvb_ieee_to_long(tvb, offset2+8));
1233                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+12, 4,
1234                                             "Peak data rate: %ld", 
1235                                             tvb_ieee_to_long(tvb, offset2+12));
1236                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 4,
1237                                             "Minimum policed unit [m]: %u", 
1238                                             tvb_get_ntohl(tvb, offset2+16));
1239                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+20, 4,
1240                                             "Maximum packet size [M]: %u", 
1241                                             tvb_get_ntohl(tvb, offset2+20));
1242                         proto_item_set_text(ti, "SENDER TSPEC: IntServ, %lu bytes/sec", 
1243                                             tvb_ieee_to_long(tvb, offset2+4));
1244                         break;
1245
1246                     case QOS_QUALITATIVE :
1247                         /* Token bucket TSPEC */
1248                         param_id = tvb_get_guint8(tvb, offset2);
1249                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1250                                             "Parameter %u - %s", 
1251                                             param_id,
1252                                             val_to_str(param_id, svc_vals, "Unknown"));
1253                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
1254                                             "Parameter %u flags: %x", 
1255                                             param_id,
1256                                             tvb_get_guint8(tvb, offset2+1));
1257                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1258                                             "Parameter %u data length: %u words, " 
1259                                             "not including header",
1260                                             param_id,
1261                                             tvb_get_ntohs(tvb, offset2+2));
1262                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1263                                             "Maximum packet size [M]: %u", 
1264                                             tvb_get_ntohl(tvb, offset2+4));
1265                         proto_item_set_text(ti, "SENDER TSPEC: Qualitative");
1266                         break;
1267
1268                     }
1269                     offset2 += length*4; 
1270                     mylen -= length*4;
1271                 }
1272                 break;
1273             }
1274
1275             case RSVP_CLASS_FLOWSPEC : {
1276                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_flowspec);
1277                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1278                                     "Length: %u", obj_length);
1279                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1280                                     "Class number: %u - %s", 
1281                                     class, object_type);
1282                 mylen = obj_length - 4;
1283
1284                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1285                                     "Message format version: %u", 
1286                                     tvb_get_guint8(tvb, offset2)>>4);
1287                 proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1288                                     "Data length: %u words, not including header", 
1289                                     tvb_get_ntohs(tvb, offset2+2));
1290
1291                 mylen -= 4;
1292                 offset2+= 4;
1293                 while (mylen > 0) {
1294                     guint8 service_num;
1295                     guint16 length;
1296                     guint8 param_id;
1297
1298                     service_num = tvb_get_guint8(tvb, offset2);
1299                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1300                                         "Service header: %u - %s", 
1301                                         service_num,
1302                                         val_to_str(service_num, intsrv_services_str, "Unknown"));
1303                     length = tvb_get_ntohs(tvb, offset2+2);
1304                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, 
1305                                         "Length of service %u data: %u words, " 
1306                                         "not including header", 
1307                                         service_num,
1308                                         length);
1309
1310                     mylen -= 4;
1311                     offset2 += 4;
1312
1313                     switch(service_num) {
1314
1315                     case QOS_CONTROLLED_LOAD :
1316                     case QOS_GUARANTEED :
1317                         /* Treat both these the same for now */
1318                         param_id = tvb_get_guint8(tvb, offset2);
1319                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1320                                             "Parameter %u - %s", 
1321                                             param_id,
1322                                             val_to_str(param_id, svc_vals, "Unknown"));
1323                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
1324                                             "Parameter %u flags: %x", 
1325                                             param_id,
1326                                             tvb_get_guint8(tvb, offset2+1));
1327                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1328                                             "Parameter %u data length: %u words, " 
1329                                             "not including header",
1330                                             param_id,
1331                                             tvb_get_ntohs(tvb, offset2+2));
1332                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1333                                             "Token bucket rate: %ld", 
1334                                             tvb_ieee_to_long(tvb, offset2+4));
1335                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
1336                                             "Token bucket size: %ld", 
1337                                             tvb_ieee_to_long(tvb, offset2+8));
1338                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+12, 4,
1339                                             "Peak data rate: %ld", 
1340                                             tvb_ieee_to_long(tvb, offset2+12));
1341                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 4,
1342                                             "Minimum policed unit [m]: %u", 
1343                                             tvb_get_ntohl(tvb, offset2+16));
1344                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+20, 4,
1345                                             "Maximum packet size [M]: %u", 
1346                                             tvb_get_ntohl(tvb, offset2+20));
1347
1348                         if (service_num != QOS_GUARANTEED) {
1349                             proto_item_set_text(ti, "FLOWSPEC: Controlled-Load, %lu bytes/sec", 
1350                                                 tvb_ieee_to_long(tvb, offset2+4));
1351                             break;
1352                         }
1353                         
1354                         /* Guaranteed-rate RSpec */
1355                         param_id = tvb_get_guint8(tvb, offset2+24);
1356                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+24, 1,
1357                                             "Parameter %u - %s", 
1358                                             param_id,
1359                                             val_to_str(param_id, svc_vals, "Unknown"));
1360                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+25, 1, 
1361                                             "Parameter %u flags: %x", 
1362                                             param_id,
1363                                             tvb_get_guint8(tvb, offset2+25));
1364                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+26, 2,
1365                                             "Parameter %u data length: %u words, " 
1366                                             "not including header",
1367                                             param_id,
1368                                             tvb_get_ntohs(tvb, offset2+26));
1369
1370                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+28, 4,
1371                                             "Rate: %ld", 
1372                                             tvb_ieee_to_long(tvb, offset2+28));
1373                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+32, 4,
1374                                             "Slack term: %u", 
1375                                             tvb_get_ntohl(tvb, offset2+32));
1376                         proto_item_set_text(ti, "FLOWSPEC: Guaranteed-Rate, %lu bytes/sec", 
1377                                             tvb_ieee_to_long(tvb, offset2+4));
1378                         break;
1379
1380                     case QOS_QUALITATIVE :
1381                         param_id = tvb_get_guint8(tvb, offset2);
1382                         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, 
1383                                             "Parameter %u - %s", 
1384                                             param_id,
1385                                             val_to_str(param_id, svc_vals, "Unknown"));
1386                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
1387                                             "Parameter %u flags: %x", 
1388                                             param_id,
1389                                             tvb_get_guint8(tvb, offset2+1));
1390                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1391                                             "Parameter %u data length: %u words, " 
1392                                             "not including header",
1393                                             param_id,
1394                                             tvb_get_ntohs(tvb, offset2+2));
1395                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1396                                             "Maximum packet size [M]: %u", 
1397                                             tvb_get_ntohl(tvb, offset2+4));
1398                         
1399                         proto_item_set_text(ti, "FLOWSPEC: Qualitative");
1400                         break;
1401                     }
1402                     offset2 += length*4;
1403                     mylen -= length*4;
1404                 }
1405                 break;
1406             }
1407
1408             case RSVP_CLASS_ADSPEC : {
1409                 proto_tree *adspec_tree;
1410
1411                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_adspec);
1412                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1413                                     "Length: %u", obj_length);
1414                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1415                                     "Class number: %u - %s", 
1416                                     class, object_type);
1417                 mylen = obj_length - 4;
1418
1419                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
1420                                     "Message format version: %u", 
1421                                     tvb_get_guint8(tvb, offset2)>>4);
1422                 proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1423                                     "Data length: %u words, not including header", 
1424                                     tvb_get_ntohs(tvb, offset2+2));
1425                 mylen -= 4;
1426                 offset2 += 4;
1427                 while (mylen > 0) {
1428                     guint8 service_num;
1429                     guint8 break_bit;
1430                     guint16 length;
1431                     char *str;
1432
1433                     service_num = tvb_get_guint8(tvb, offset2);
1434                     str = val_to_str(service_num, intsrv_services_str, "Unknown");
1435                     break_bit = tvb_get_guint8(tvb, offset2+1);
1436                     length = tvb_get_ntohs(tvb, offset2+2);
1437                     ti = proto_tree_add_text(rsvp_object_tree, tvb, offset2, 
1438                                              (length+1)*4,
1439                                              str);
1440                     adspec_tree = proto_item_add_subtree(ti,
1441                                                          ett_rsvp_adspec_subtree);
1442                     proto_tree_add_text(adspec_tree, tvb, offset2, 1,
1443                                         "Service header %u - %s",
1444                                         service_num, str);
1445                     proto_tree_add_text(adspec_tree, tvb, offset2+1, 1,
1446                                         (break_bit&0x80)?
1447                                         "Break bit set":"Break bit not set");
1448                     proto_tree_add_text(adspec_tree, tvb, offset2+2, 2, 
1449                                         "Data length: %u words, not including header", 
1450                                         length);
1451                     mylen -= 4;
1452                     offset2 += 4;
1453                     i = length*4;
1454                     while (i > 0) {
1455                         guint8 id;
1456                         guint16 phdr_length;
1457
1458                         id = tvb_get_guint8(tvb, offset2);
1459                         phdr_length = tvb_get_ntohs(tvb, offset2+2);
1460                         str = match_strval(id, adspec_params);
1461                         if (str) {
1462                             switch(id) {
1463                             case 4:
1464                             case 8:
1465                             case 10:
1466                             case 133:
1467                             case 134:
1468                             case 135:
1469                             case 136:
1470                                 /* 32-bit unsigned integer */
1471                                 proto_tree_add_text(adspec_tree, tvb, offset2,
1472                                                     (phdr_length+1)<<2,
1473                                                     "%s - %u (type %u, length %u)",
1474                                                     str,
1475                                                     tvb_get_ntohl(tvb, offset2+4),
1476                                                     id, phdr_length);
1477                                 break;
1478                                 
1479                             case 6:
1480                                 /* IEEE float */
1481                                 proto_tree_add_text(adspec_tree, tvb, offset2,
1482                                                     (phdr_length+1)<<2,
1483                                                     "%s - %lu (type %u, length %u)",
1484                                                     str,
1485                                                     tvb_ieee_to_long(tvb, offset2+4),
1486                                                     id, phdr_length);
1487                                 break;
1488                             default: 
1489                                 proto_tree_add_text(adspec_tree, tvb, offset2, 
1490                                                     (phdr_length+1)<<2,
1491                                                     "%s (type %u, length %u)",
1492                                                     str,
1493                                                     id, phdr_length);
1494                             }
1495                         } else {
1496                             proto_tree_add_text(adspec_tree, tvb, offset2, 
1497                                                 (phdr_length+1)<<2,
1498                                                 "Unknown (type %u, length %u)",
1499                                                 id, phdr_length);
1500                         }
1501                         offset2 += (phdr_length+1)<<2;
1502                         i -= (phdr_length+1)<<2;
1503                         mylen -= (phdr_length+1)<<2;
1504                     }
1505                 }
1506                 break;
1507             }
1508
1509             case RSVP_CLASS_INTEGRITY :
1510                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_integrity);
1511                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1512                                     "Length: %u", obj_length);
1513                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1514                                     "Class number: %u - %s", 
1515                                     class, object_type);
1516                 goto default_class;
1517
1518             case RSVP_CLASS_POLICY :
1519                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
1520                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1521                                     "Length: %u", obj_length);
1522                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1523                                     "Class number: %u - %s", 
1524                                     class, object_type);
1525                 goto default_class;
1526
1527             case RSVP_CLASS_LABEL_REQUEST : 
1528                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_label_request);
1529                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1530                                     "Length: %u", obj_length);
1531                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1532                                     "Class number: %u - %s", 
1533                                     class, object_type);
1534                 mylen = obj_length - 4;
1535                 switch(type) {
1536                 case 1: {
1537                     unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2);
1538                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1539                                         "C-type: 1");
1540                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
1541                                         "L3PID: %s (0x%04x)",
1542                                         val_to_str(l3pid, etype_vals, "Unknown"),
1543                                         l3pid);
1544                     proto_item_set_text(ti, "LABEL REQUEST: %s (0x%04x)",
1545                                         val_to_str(l3pid, etype_vals, "Unknown"),
1546                                         l3pid);
1547                     break;
1548                 }
1549
1550                 default: {
1551                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1552                                         "C-type: Unknown (%u)",
1553                                         type);
1554                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1555                                         "Data (%d bytes)", mylen);
1556                     break;
1557                 }
1558                 }
1559                 break;
1560             
1561             case RSVP_CLASS_LABEL : 
1562                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_label);
1563                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1564                                     "Length: %u", obj_length);
1565                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1566                                     "Class number: %u - %s", 
1567                                     class, object_type);
1568                 mylen = obj_length - 4;
1569                 switch(type) {
1570                 case 1: {
1571                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1572                                         "C-type: 1");
1573                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
1574                                         "Label: %u", 
1575                                         tvb_get_ntohl(tvb, offset2));
1576                     proto_item_set_text(ti, "LABEL: %d", 
1577                                         tvb_get_ntohl(tvb, offset2));
1578                     break;
1579                 }
1580
1581                 default: {
1582                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1583                                         "C-type: Unknown (%u)",
1584                                         type);
1585                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1586                                         "Data (%d bytes)", mylen);
1587                     break;
1588                 }
1589                 }
1590                 break;
1591             
1592             case RSVP_CLASS_SESSION_ATTRIBUTE : 
1593                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_session_attribute);
1594                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1595                                     "Length: %u", obj_length);
1596                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1597                                     "Class number: %u - %s", 
1598                                     class, object_type);
1599                 mylen = obj_length - 4;
1600                 switch(type) {
1601                 case 7: {
1602                     guint8 flags;
1603                     guint8 name_len;
1604
1605                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1606                                         "C-type: 7 - IPv4 LSP");
1607                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
1608                                         "Setup priority: %u",
1609                                         tvb_get_guint8(tvb, offset2));
1610                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
1611                                         "Hold priority: %u",
1612                                         tvb_get_guint8(tvb, offset2+1));
1613                     flags = tvb_get_guint8(tvb, offset2+2);
1614                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 1,
1615                                               "Flags: 0x%02x", flags);
1616                     rsvp_sa_flags_tree = proto_item_add_subtree(ti2, 
1617                                                                 ett_rsvp_session_attribute_flags);
1618                     proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1,
1619                                         decode_boolean_bitfield(flags, 0x01, 8,
1620                                             "Local protection desired",
1621                                             "Local protection not desired"));
1622                     proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1,
1623                                         decode_boolean_bitfield(flags, 0x02, 8,
1624                                             "Merging permitted",
1625                                             "Merging not permitted"));
1626                     proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1,
1627                                         decode_boolean_bitfield(flags, 0x04, 8,
1628                                             "Ingress node may reroute",
1629                                             "Ingress node may not reroute"));
1630                     
1631                     name_len = tvb_get_guint8(tvb, offset2+3);
1632                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+3, 1,
1633                                         "Name length: %u", name_len);
1634                     proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, name_len,
1635                                         "Name: %.*s",
1636                                         name_len,
1637                                         tvb_get_ptr(tvb, offset2+4, name_len));
1638                     break;
1639                 }
1640
1641                 default: {
1642                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1643                                         "C-type: Unknown (%u)",
1644                                         type);
1645                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1646                                         "Data (%d bytes)", mylen);
1647                     break;
1648                 }
1649                 }
1650                 break;
1651
1652             case RSVP_CLASS_EXPLICIT_ROUTE : 
1653                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_explicit_route);
1654                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1655                                     "Length: %u", obj_length);
1656                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1657                                     "Class number: %u - %s", 
1658                                     class, object_type);
1659                 mylen = obj_length - 4;
1660                 switch(type) {
1661                 case 1: {
1662                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1663                                         "C-type: 1");
1664                     for (i=1, l = 0; l < mylen; i++) {
1665                         j = tvb_get_guint8(tvb, offset2+l) & 0x7f;
1666                         switch(j) {
1667                         case 1: /* IPv4 */
1668                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
1669                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1670                                                       offset2+l, 8,
1671                                                       "IPv4 Subobject - %s, %s",
1672                                                       ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)),
1673                                                       k ? "Loose" : "Strict");
1674                             rsvp_ero_subtree = 
1675                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
1676                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1677                                                 k ? "Loose Hop " : "Strict Hop");
1678                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1679                                                 "Type: 1 (IPv4)");
1680                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1681                                                 "Length: %u",
1682                                                 tvb_get_guint8(tvb, offset2+l+1));
1683                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 4,
1684                                                 "IPv4 hop: %s",
1685                                                 ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
1686                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+6, 1, 
1687                                                 "Prefix length: %u",
1688                                                 tvb_get_guint8(tvb, offset2+l+6));
1689                             break;
1690
1691                         case 2: /* IPv6 */
1692                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1693                                                       offset2+l, 20,
1694                                                       "IPv6 Subobject");
1695                             rsvp_ero_subtree = 
1696                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
1697                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
1698                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1699                                                 k ? "Loose Hop " : "Strict Hop");
1700                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1701                                                 "Type: 2 (IPv6)");
1702                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1703                                                 "Length: %u",
1704                                                 tvb_get_guint8(tvb, offset2+l+1));
1705                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 16,
1706                                                 "IPv6 hop: %s",
1707                                                 ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l+2, 16)));
1708                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+18, 1,
1709                                                 "Prefix length: %u",
1710                                                 tvb_get_guint8(tvb, offset2+l+6));
1711                             break;
1712
1713                         case 32: /* AS */
1714                             k = tvb_get_ntohs(tvb, offset2+l+2);
1715                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1716                                                       offset2+l, 4,
1717                                                       "Autonomous System %u",
1718                                                       k);
1719                             rsvp_ero_subtree = 
1720                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
1721                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1722                                                 k ? "Loose Hop " : "Strict Hop");
1723                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1724                                                 "Type: 32 (Autonomous System Number)");
1725                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1726                                                 "Length: %u",
1727                                                 tvb_get_guint8(tvb, offset2+l+1));
1728                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 2,
1729                                                 "Autonomous System %u", k);
1730                             break;
1731
1732                         case 64: /* Path Term */
1733                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
1734                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1735                                                       offset2+l, 4,
1736                                                       "LSP Path Termination");
1737                             rsvp_ero_subtree = 
1738                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
1739                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1740                                                 k ? "Loose Hop " : "Strict Hop");
1741                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1742                                                 "Type: 64 (MPLS LSP Path Termination)");
1743                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1744                                                 "Length: %u",
1745                                                 tvb_get_guint8(tvb, offset2+l+1));
1746                             break;
1747
1748                         default: /* Unknown subobject */
1749                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
1750                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1751                                                       offset2+l,
1752                                                       tvb_get_guint8(tvb, offset2+l+1),
1753                                                       "Unknown subobject: %d", j);
1754                             rsvp_ero_subtree = 
1755                                 proto_item_add_subtree(ti2, ett_rsvp_explicit_route_subobj); 
1756                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1757                                                 k ? "Loose Hop " : "Strict Hop");
1758                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1759                                                 "Type: %u (Unknown)", j);
1760                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1761                                                 "Length: %u",
1762                                                 tvb_get_guint8(tvb, offset2+l+1));
1763
1764                         }
1765
1766                         l += tvb_get_guint8(tvb, offset2+l+1);
1767                     }
1768                     break;
1769                 }
1770                 default: {
1771                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1772                                         "C-type: Unknown (%u)",
1773                                         type);
1774                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1775                                         "Data (%d bytes)", mylen);
1776                     break;
1777                 }
1778                 }
1779                 break;
1780             
1781
1782             case RSVP_CLASS_RECORD_ROUTE : 
1783                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_record_route);
1784                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1785                                     "Length: %u", obj_length);
1786                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1787                                     "Class number: %u - %s", 
1788                                     class, object_type);
1789                 mylen = obj_length - 4;
1790                 switch(type) {
1791                 case 1: {
1792                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1793                                         "C-type: 1");
1794                     for (i=1, l = 0; l < mylen; i++) {
1795                         j = tvb_get_guint8(tvb, offset2+l);
1796                         switch(j) {
1797                         case 1: /* IPv4 */
1798                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1799                                                       offset2+l, 8,
1800                                                       "IPv4 Subobject - %s",
1801                                                       ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
1802                             rsvp_ero_subtree = 
1803                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
1804                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1805                                                 "Type: 1 (IPv4)");
1806                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1807                                                 "Length: %u",
1808                                                 tvb_get_guint8(tvb, offset2+l+1));
1809                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 4,
1810                                                 "IPv4 hop: %s",
1811                                                 ip_to_str(tvb_get_ptr(tvb, offset2+l+2, 4)));
1812                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+6, 1,
1813                                                 "Prefix length: %u",
1814                                                 tvb_get_guint8(tvb, offset2+l+6));
1815                             break;
1816
1817                         case 2: /* IPv6 */
1818                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1819                                                       offset2+l, 20,
1820                                                       "IPv6 Subobject");
1821                             rsvp_ero_subtree = 
1822                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
1823                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1824                                                 "Type: 2 (IPv6)");
1825                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1826                                                 "Length: %u",
1827                                                 tvb_get_guint8(tvb, offset2+l+1));
1828                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+2, 16,
1829                                                 "IPv6 hop: %s",
1830                                                 ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2+l+2, 16)));
1831                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+18, 1,
1832                                                 "Prefix length: %u",
1833                                                 tvb_get_guint8(tvb, offset2+l+6));
1834                             break;
1835
1836                         default: /* Unknown subobject */
1837                             k = tvb_get_guint8(tvb, offset2+l) & 0x80;
1838                             ti2 = proto_tree_add_text(rsvp_object_tree, tvb, 
1839                                                       offset2+l,
1840                                                       tvb_get_guint8(tvb, offset2+l+1),
1841                                                       "Unknown subobject: %u",
1842                                                       j);
1843                             rsvp_ero_subtree = 
1844                                 proto_item_add_subtree(ti2, ett_rsvp_record_route_subobj); 
1845                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1846                                                 k ? "Loose Hop " : "Strict Hop");
1847                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l, 1,
1848                                                 "Type: %u (Unknown)", j);
1849                             proto_tree_add_text(rsvp_ero_subtree, tvb, offset2+l+1, 1,
1850                                                 "Length: %u",
1851                                                 tvb_get_guint8(tvb, offset2+l+1));
1852
1853                         }
1854
1855                         l += tvb_get_guint8(tvb, offset2+l+1);
1856                     }
1857                     break;
1858                 }
1859                 
1860                 default: {
1861                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1862                                         "C-type: Unknown (%u)",
1863                                         type);
1864                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1865                                         "Data (%d bytes)", mylen);
1866                     break;
1867                 }
1868                 }
1869                 break;
1870             
1871             case RSVP_CLASS_MESSAGE_ID :
1872                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
1873                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1874                                     "Length: %u", obj_length);
1875                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1876                                     "Class number: %u - %s", 
1877                                     class, object_type);
1878                 switch(type) {
1879                 case 1: 
1880                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1881                                         "C-type: 1");
1882                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
1883                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
1884                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
1885                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
1886                     proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
1887                                         "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
1888                     proto_item_set_text(ti, "MESSAGE-ID: %d %s", 
1889                                         tvb_get_ntohl(tvb, offset+8), 
1890                                         tvb_get_guint8(tvb, offset+4) & 1 ? "(Ack Desired)" : "");
1891                     break;
1892
1893                 default:
1894                     mylen = obj_length - 4;
1895                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1896                                         "C-type: Unknown (%u)",
1897                                         type);
1898                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1899                                         "Data (%d bytes)", mylen);
1900                     break;
1901                 }
1902                 break;
1903
1904             case RSVP_CLASS_MESSAGE_ID_ACK :
1905                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
1906                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1907                                     "Length: %u", obj_length);
1908                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1909                                     "Class number: %u - %s", 
1910                                     class, object_type);
1911                 switch(type) {
1912                 case 1: 
1913                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1914                                         "C-type: 1");
1915                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
1916                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
1917                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
1918                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
1919                     proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
1920                                         "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
1921                     proto_item_set_text(ti, "MESSAGE-ID ACK: %d", tvb_get_ntohl(tvb, offset+8));
1922                     break;
1923
1924                 case 2: 
1925                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1926                                         "C-type: 2");
1927                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
1928                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
1929                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
1930                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
1931                     proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
1932                                         "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
1933                     proto_item_set_text(ti, "MESSAGE-ID NACK: %d", tvb_get_ntohl(tvb, offset+8));
1934                     break;
1935
1936                 default:
1937                     mylen = obj_length - 4;
1938                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1939                                         "C-type: Unknown (%u)",
1940                                         type);
1941                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1942                                         "Data (%d bytes)", mylen);
1943                     break;
1944                 }
1945                 break;
1946
1947             case RSVP_CLASS_MESSAGE_ID_LIST :
1948                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
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                 switch(type) {
1955                 case 1: 
1956                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1957                                         "C-type: 1");
1958                     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
1959                                         "Flags: %d", tvb_get_guint8(tvb, offset+4));
1960                     proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
1961                                         "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
1962                     for (mylen = 8; mylen < obj_length; mylen += 4)
1963                         proto_tree_add_text(rsvp_object_tree, tvb, offset+mylen, 4,
1964                                             "Message-ID: %d", tvb_get_ntohl(tvb, offset+mylen));
1965                     proto_item_set_text(ti, "MESSAGE-ID LIST: %d IDs", 
1966                                         (obj_length - 8)/4);
1967                     break;
1968
1969                 default:
1970                     mylen = obj_length - 4;
1971                     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1972                                         "C-type: Unknown (%u)",
1973                                         type);
1974                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
1975                                         "Data (%d bytes)", mylen);
1976                     break;
1977                 }
1978                 break;
1979
1980             case RSVP_CLASS_HELLO:
1981                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_hello_obj);
1982                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
1983                                     "Length: %u", obj_length);
1984                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
1985                                     "Class number: %u - %s", 
1986                                     class, object_type);        
1987                 switch(type) {
1988                     case 1:
1989                       proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1990                                         "C-Type: 1 - HELLO REQUEST object");
1991                       break;
1992                     case 2:
1993                       proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, 
1994                                         "C-Type: 2 - HELLO ACK object");
1995                       break;
1996                 };
1997
1998                 proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 4,
1999                                     "Source Instance: 0x%x",tvb_get_ntohl(tvb, offset+4));
2000    
2001                 proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
2002                                     "Destination Instance: 0x%x",tvb_get_ntohl(tvb, offset+8));
2003    
2004                 break;
2005
2006             default :
2007                 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_unknown_class);
2008                 proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
2009                                     "Length: %u", obj_length);
2010                 proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, 
2011                                     "Class number: %u - %s", 
2012                                     class, object_type);
2013             default_class:
2014                 mylen = obj_length - 4;
2015                 proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2016                                     "Data (%d bytes)", mylen);
2017                 break;
2018
2019             case RSVP_CLASS_NULL :
2020                 break;
2021
2022             }  
2023             
2024             offset += obj_length;
2025             len += obj_length;
2026         }
2027     }
2028 }
2029
2030 void
2031 proto_register_rsvp(void)
2032 {
2033         static gint *ett[] = {
2034                 &ett_rsvp,
2035                 &ett_rsvp_hdr,
2036                 &ett_rsvp_session,
2037                 &ett_rsvp_hop,
2038                 &ett_rsvp_time_values,
2039                 &ett_rsvp_error,
2040                 &ett_rsvp_scope,
2041                 &ett_rsvp_style,
2042                 &ett_rsvp_confirm,
2043                 &ett_rsvp_sender_template,
2044                 &ett_rsvp_filter_spec,
2045                 &ett_rsvp_sender_tspec,
2046                 &ett_rsvp_flowspec,
2047                 &ett_rsvp_adspec,
2048                 &ett_rsvp_adspec_subtree,
2049                 &ett_rsvp_integrity,
2050                 &ett_rsvp_policy,
2051                 &ett_rsvp_label,
2052                 &ett_rsvp_label_request,
2053                 &ett_rsvp_session_attribute,
2054                 &ett_rsvp_session_attribute_flags,
2055                 &ett_rsvp_explicit_route,
2056                 &ett_rsvp_explicit_route_subobj,
2057                 &ett_rsvp_record_route,
2058                 &ett_rsvp_record_route_subobj,
2059                 &ett_rsvp_hello_obj,
2060                 &ett_rsvp_unknown_class,
2061         };
2062
2063         proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)",
2064             "RSVP", "rsvp");
2065         proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info));
2066         proto_register_subtree_array(ett, array_length(ett));
2067 }
2068
2069 void
2070 proto_reg_handoff_rsvp(void)
2071 {
2072         dissector_add("ip.proto", IP_PROTO_RSVP, dissect_rsvp, proto_rsvp);
2073 }