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