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