Document the new Copy Profile button.
[obnox/wireshark/wip.git] / epan / dissectors / 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$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*
28  * NOTES
29  *
30  * This module defines routines to disassemble RSVP packets, as defined in
31  * RFC 2205. All objects from RFC2205 are supported, in IPv4 and IPv6 mode.
32  * In addition, the Integrated Services traffic specification objects
33  * defined in RFC2210 are also supported.
34  *
35  * IPv6 support is not completely tested
36  *
37  * Mar 3, 2000: Added support for MPLS/TE objects, as defined in
38  * <draft-ietf-mpls-rsvp-lsp-tunnel-04.txt>
39  *
40  * May 6, 2004: Added support for E-NNI objects, as defined in
41  * <OIF-E-NNI-01.0>   (Roberto Morro)
42  * <roberto.morro[AT]tilab.com>
43  *
44  * May 6, 2004: Modified some UNI objects, as defined in
45  * <OIF2003.249.09>   (Roberto Morro)
46  * <roberto.morro[AT]tilab.com>
47  *
48  * June 2, 2005: Modified more UNI objects to show correct TNA
49  * addresses; Fixed LSP interface ID subobject (Richard Rabbat)
50  * <richard[AT]us.fujitsu.com>
51  *
52  * July 25, 2005: improved ERROR and LABEL_SET objects dissector;
53  * new ASSOCIATION object dissector (Roberto Morro)
54  * <roberto.morro[AT]tilab.com>
55  *
56  * August 22, 2005: added support for tapping and conversations.
57  * (Manu Pathak) <mapathak[AT]cisco.com>
58  *
59  * July 4, 2006: added support for RFC4124; new CLASSTYPE object dissector
60  * (FF) <francesco.fondelli[AT]gmail.com>
61  *
62  * June 9, 2007: added support for draft-ietf-ccamp-ethernet-traffic-parameters-02
63  * and draft-ietf-ccamp-lsp-hierarchy-bis-02; added support for NOTIFY_REQUEST
64  * and RECOVERY_LABEL objects (Roberto Morro) * <roberto.morro[AT]tilab.com>
65  *
66  * Oct 21, 2009: add support for RFC4328, new G.709 traffic parameters,
67  * update gpid, switching and encoding type values to actual IANA numbers.
68  * (FF) <francesco.fondelli[AT]gmail.com>
69  */
70
71
72 #ifdef HAVE_CONFIG_H
73 # include "config.h"
74 #endif
75
76 #include <stdio.h>
77
78 #ifdef HAVE_UNISTD_H
79 #include <unistd.h>
80 #endif
81
82 #include <stdlib.h>
83 #include <string.h>
84
85 #include <glib.h>
86
87 #include <epan/tvbuff.h>
88 #include <epan/packet.h>
89 #include <prefs.h>
90 #include <epan/in_cksum.h>
91 #include <epan/etypes.h>
92 #include <epan/ipproto.h>
93 #include <epan/conversation.h>
94 #include <epan/tap.h>
95 #include <epan/emem.h>
96
97 #include "packet-rsvp.h"
98 #include "packet-ip.h"
99 #include "packet-frame.h"
100 #include "packet-diffserv-mpls-common.h"
101
102 /* RSVP over UDP encapsulation */
103 #define UDP_PORT_PRSVP 3455
104
105 static int proto_rsvp = -1;
106
107 static dissector_table_t rsvp_dissector_table;
108
109 static int rsvp_tap = -1;
110
111 /*
112  * All RSVP packets belonging to a particular flow  belong to the same
113  * conversation. The following structure definitions are for auxillary
114  * structures which have all the relevant flow information to make up the
115  * RSVP five-tuple. Note that the values of the five-tuple are determined
116  * from the session object and sender template/filter spec for PATH/RESV
117  * messages.
118  * Update rsvp_request_equal() when you add stuff here. You might also
119  * have to update rsvp_request_hash().
120  * TODO: Support for IPv6 conversations.
121  */
122
123 typedef struct rsvp_session_ipv4_info {
124     address destination;
125     guint8 protocol;
126     guint16 udp_dest_port;
127 } rsvp_session_ipv4_info;
128
129 typedef struct rsvp_session_ipv6_info {
130     /* not supported yet */
131
132     guint8 dummy;
133 } rsvp_session_ipv6_info;
134
135 typedef struct rsvp_session_ipv4_lsp_info {
136     address destination;
137     guint16 udp_dest_port;
138     guint32 ext_tunnel_id;
139 } rsvp_session_ipv4_lsp_info;
140
141 typedef struct rsvp_session_agg_ipv4_info {
142     address destination;
143     guint8 dscp;
144 } rsvp_session_agg_ipv4_info;
145
146 typedef struct rsvp_session_ipv4_uni_info {
147     address destination;
148     guint16 udp_dest_port;
149     guint32 ext_tunnel_id;
150 } rsvp_session_ipv4_uni_info;
151
152 typedef struct rsvp_session_ipv4_enni_info {
153     address destination;
154     guint16 udp_dest_port;
155     guint32 ext_tunnel_id;
156 } rsvp_session_ipv4_enni_info;
157
158 typedef struct rsvp_template_filter_info {
159     address source;
160     guint16 udp_source_port;
161 } rsvp_template_filter_info;
162
163 /*
164  * The actual request key consists of a union of the various session objects
165  * (which are uniquely identified based on the session type), and the
166  * source_info structure, which has the information derived from the sender
167  * template or the filter spec.
168  * The request key is populated by copying the information from the
169  * rsvp_conversation_info structure (rsvph), which in turn is populated when
170  * the session, filter and sender template objects are dissected.
171  */
172 struct rsvp_request_key {
173     guint32 session_type;
174
175     union { /* differentiated by session_type field */
176         rsvp_session_ipv4_info session_ipv4;
177         rsvp_session_ipv6_info session_ipv6;
178         rsvp_session_ipv4_lsp_info session_ipv4_lsp;
179         rsvp_session_agg_ipv4_info session_agg_ipv4;
180         rsvp_session_ipv4_uni_info session_ipv4_uni;
181         rsvp_session_ipv4_enni_info session_ipv4_enni;
182     } u;
183
184     rsvp_template_filter_info source_info;
185     guint32 conversation;
186 };
187
188 /*
189  * At present, there is nothing particularly important that we need to
190  * store for the request value for each rsvp_request_key, so we just
191  * store the unique 32-bit identifier internally allocated for the key
192  * (and stored in the conversation attribute of rsvp_request_key above.
193  * If this changes in the future, then other stuff can be added here.
194  */
195 struct rsvp_request_val {
196     guint32 value;
197 };
198
199 /*
200  * Initialize the conversation related data structures.
201  */
202 static GHashTable *rsvp_request_hash = NULL;
203
204 /*
205  * The list of tree types
206  */
207 enum {
208     TT_RSVP,
209     TT_HDR,
210     TT_SESSION,
211     TT_HOP,
212     TT_HOP_SUBOBJ,
213     TT_TIME_VALUES,
214     TT_ERROR,
215     TT_ERROR_SUBOBJ,
216     TT_ERROR_FLAGS,
217     TT_SCOPE,
218     TT_STYLE,
219     TT_CONFIRM,
220     TT_SENDER_TEMPLATE,
221     TT_FILTER_SPEC,
222     TT_TSPEC,
223     TT_TSPEC_SUBTREE,
224     TT_FLOWSPEC,
225     TT_FLOWSPEC_SUBTREE,
226     TT_ETHSPEC_SUBTREE,
227     TT_ADSPEC,
228     TT_ADSPEC_SUBTREE,
229     TT_INTEGRITY,
230     TT_INTEGRITY_FLAGS,
231     TT_DCLASS,
232     TT_LSP_TUNNEL_IF_ID,
233     TT_LSP_TUNNEL_IF_ID_SUBTREE,
234     TT_POLICY,
235     TT_MESSAGE_ID,
236     TT_MESSAGE_ID_ACK,
237     TT_MESSAGE_ID_LIST,
238     TT_LABEL,
239     TT_LABEL_SET,
240     TT_LABEL_REQUEST,
241     TT_SESSION_ATTRIBUTE,
242     TT_SESSION_ATTRIBUTE_FLAGS,
243     TT_HELLO_OBJ,
244     TT_EXPLICIT_ROUTE,
245     TT_EXPLICIT_ROUTE_SUBOBJ,
246     TT_RECORD_ROUTE,
247     TT_RECORD_ROUTE_SUBOBJ,
248     TT_RECORD_ROUTE_SUBOBJ_FLAGS,
249     TT_ADMIN_STATUS,
250     TT_ADMIN_STATUS_FLAGS,
251     TT_ASSOCIATION,
252     TT_GEN_UNI,
253     TT_GEN_UNI_SUBOBJ,
254     TT_CALL_ID,
255     TT_BUNDLE_COMPMSG,
256     TT_RESTART_CAP,
257     TT_PROTECTION_INFO,
258     TT_FAST_REROUTE,
259     TT_FAST_REROUTE_FLAGS,
260     TT_DETOUR,
261     TT_DIFFSERV,
262     TT_DIFFSERV_MAP,
263     TT_DIFFSERV_MAP_PHBID,
264     TT_CLASSTYPE,
265     TT_UNKNOWN_CLASS,
266
267     TT_MAX
268 };
269 static gint ett_treelist[TT_MAX];
270 #define TREE(X) ett_treelist[(X)]
271
272 /* Should we dissect bundle messages? */
273 static gboolean rsvp_bundle_dissect = TRUE;
274
275 /*
276  * RSVP message types.
277  * See
278  *
279  *      http://www.iana.org/assignments/rsvp-parameters
280  */
281 typedef enum {
282     RSVP_MSG_PATH=1,                    /* RFC 2205 */
283     RSVP_MSG_RESV,                      /* RFC 2205 */
284     RSVP_MSG_PERR,                      /* RFC 2205 */
285     RSVP_MSG_RERR,                      /* RFC 2205 */
286     RSVP_MSG_PTEAR,                     /* RFC 2205 */
287     RSVP_MSG_RTEAR,                     /* RFC 2205 */
288     RSVP_MSG_CONFIRM,                   /* XXX - DREQ, RFC 2745? */
289                                         /* 9 is DREP, RFC 2745 */
290     RSVP_MSG_RTEAR_CONFIRM=10,          /* from Fred Baker at Cisco */
291                                         /* 11 is unassigned */
292     RSVP_MSG_BUNDLE = 12,               /* RFC 2961 */
293     RSVP_MSG_ACK,                       /* RFC 2961 */
294                                         /* 14 is reserved */
295     RSVP_MSG_SREFRESH = 15,             /* RFC 2961 */
296                                         /* 16, 17, 18, 19 not listed */
297     RSVP_MSG_HELLO = 20,                /* RFC 3209 */
298     RSVP_MSG_NOTIFY                     /* [RFC3473] */
299                                         /* 25 is Integrity Challenge RFC 2747, RFC 3097 */
300                                         /* 26 is Integrity Response RFC 2747, RFC 3097 */
301                                         /* 66 is DSBM_willing [SBM] */
302                                         /* 67 is I_AM_DSBM [SBM] */
303                                         /* [SBM] is Subnet Bandwidth Manager ID from July 1997 */
304 } rsvp_message_types;
305
306 static const value_string message_type_vals[] = {
307     {RSVP_MSG_PATH,             "PATH Message. "},
308     {RSVP_MSG_RESV,             "RESV Message. "},
309     {RSVP_MSG_PERR,             "PATH ERROR Message. "},
310     {RSVP_MSG_RERR,             "RESV ERROR Message. "},
311     {RSVP_MSG_PTEAR,            "PATH TEAR Message. "},
312     {RSVP_MSG_RTEAR,            "RESV TEAR Message. "},
313     {RSVP_MSG_CONFIRM,          "CONFIRM Message. "},
314     {RSVP_MSG_RTEAR_CONFIRM,    "RESV TEAR CONFIRM Message. "},
315     {RSVP_MSG_BUNDLE,           "BUNDLE Message. "},
316     {RSVP_MSG_ACK,              "ACK Message. "},
317     {RSVP_MSG_SREFRESH,         "SREFRESH Message. "},
318     {RSVP_MSG_HELLO,            "HELLO Message. "},
319     {RSVP_MSG_NOTIFY,           "NOTIFY Message. "},
320     {0, NULL}
321 };
322
323 /*
324  * RSVP classes
325  */
326 #define MAX_RSVP_CLASS 15
327
328 enum rsvp_classes {
329     RSVP_CLASS_NULL=0,
330     RSVP_CLASS_SESSION,
331
332     RSVP_CLASS_HOP=3,
333     RSVP_CLASS_INTEGRITY,
334     RSVP_CLASS_TIME_VALUES,
335     RSVP_CLASS_ERROR,
336     RSVP_CLASS_SCOPE,
337     RSVP_CLASS_STYLE,
338     RSVP_CLASS_FLOWSPEC,
339     RSVP_CLASS_FILTER_SPEC,
340     RSVP_CLASS_SENDER_TEMPLATE,
341     RSVP_CLASS_SENDER_TSPEC,
342     RSVP_CLASS_ADSPEC,
343     RSVP_CLASS_POLICY,
344     RSVP_CLASS_CONFIRM,
345     RSVP_CLASS_LABEL,
346     RSVP_CLASS_HOP_COUNT,
347     RSVP_CLASS_STRICT_SOURCE_ROUTE,
348     RSVP_CLASS_LABEL_REQUEST=19,
349     RSVP_CLASS_EXPLICIT_ROUTE,
350     RSVP_CLASS_RECORD_ROUTE,
351
352     RSVP_CLASS_HELLO,
353
354     RSVP_CLASS_MESSAGE_ID,
355     RSVP_CLASS_MESSAGE_ID_ACK,
356     RSVP_CLASS_MESSAGE_ID_LIST,
357
358     /* 26-29  Unassigned */
359
360     RSVP_CLASS_DIAGNOSTIC = 30,
361     RSVP_CLASS_ROUTE,
362     RSVP_CLASS_DIAG_RESPONSE,
363     RSVP_CLASS_DIAG_SELECT,
364     RSVP_CLASS_RECOVERY_LABEL,
365     RSVP_CLASS_UPSTREAM_LABEL,
366     RSVP_CLASS_LABEL_SET,
367     RSVP_CLASS_PROTECTION,
368
369     /* 38-41  Unassigned */
370     RSVP_CLASS_DSBM_IP_ADDRESS = 42,
371     RSVP_CLASS_SBM_PRIORITY,
372     RSVP_CLASS_DSBM_TIMER_INTERVALS,
373     RSVP_CLASS_SBM_INFO,
374
375     /* 46-62  Unassigned */
376
377     RSVP_CLASS_DETOUR = 63,
378     RSVP_CLASS_CHALLENGE,
379     RSVP_CLASS_DIFFSERV,
380     RSVP_CLASS_CLASSTYPE, /* FF: RFC4124 */
381     RSVP_CLASS_LSP_REQUIRED_ATTRIBUTES,
382
383     /* 68-127  Unassigned */
384
385     RSVP_CLASS_NODE_CHAR = 128,
386     RSVP_CLASS_SUGGESTED_LABEL,
387     RSVP_CLASS_ACCEPTABLE_LABEL_SET,
388     RSVP_CLASS_RESTART_CAP,
389
390     /* 132-160 Unassigned */
391
392     /* 166-191 Unassigned */
393
394     RSVP_CLASS_SESSION_ASSOC = 192,
395     RSVP_CLASS_LSP_TUNNEL_IF_ID,
396     /* 194 Unassigned */
397     RSVP_CLASS_NOTIFY_REQUEST = 195,
398     RSVP_CLASS_ADMIN_STATUS,
399     RSVP_CLASS_LSP_ATTRIBUTES,
400     /* IANA has this as 198  ALARM_SPEC ??? */
401     RSVP_CLASS_ASSOCIATION = 198,
402
403     /* 199-204  Unassigned */
404     RSVP_CLASS_FAST_REROUTE = 205,
405     /* 206 Unassigned */
406     RSVP_CLASS_SESSION_ATTRIBUTE = 207,
407     /* 208-223 Unassigned */
408     /*
409       Class Numbers 224-255 are assigned by IANA using FCFS allocation.
410       RSVP will silently ignore, but FORWARD an object with a Class Number
411       in this range that it does not understand.
412     */
413     /* 224  Unassigned */
414     RSVP_CLASS_DCLASS = 225,
415     RSVP_CLASS_PACKETCABLE_EXTENSIONS,
416     RSVP_CLASS_ATM_SERVICECLASS,
417     RSVP_CLASS_CALL_OPS,
418     RSVP_CLASS_GENERALIZED_UNI,
419     RSVP_CLASS_CALL_ID,
420     RSVP_CLASS_3GPP2_OBJECT
421     /* 232-254 Unassigned */
422     /* 255  Reserved */
423
424 };
425
426 static const value_string rsvp_class_vals[] = {
427     {RSVP_CLASS_NULL, "NULL object"},
428     {RSVP_CLASS_SESSION, "SESSION object"},
429     {RSVP_CLASS_HOP, "HOP object"},
430     {RSVP_CLASS_INTEGRITY, "INTEGRITY object"},
431     {RSVP_CLASS_TIME_VALUES, "TIME VALUES object"},
432     {RSVP_CLASS_ERROR, "ERROR object"},
433     {RSVP_CLASS_SCOPE, "SCOPE object"},
434     {RSVP_CLASS_STYLE, "STYLE object"},
435     {RSVP_CLASS_FLOWSPEC, "FLOWSPEC object"},
436     {RSVP_CLASS_FILTER_SPEC, "FILTER SPEC object"},
437     {RSVP_CLASS_SENDER_TEMPLATE, "SENDER TEMPLATE object"},
438     {RSVP_CLASS_SENDER_TSPEC, "SENDER TSPEC object"},
439     {RSVP_CLASS_ADSPEC, "ADSPEC object"},
440     {RSVP_CLASS_POLICY, "POLICY object"},
441     {RSVP_CLASS_CONFIRM, "CONFIRM object"},
442     {RSVP_CLASS_LABEL, "LABEL object"},
443     {RSVP_CLASS_HOP_COUNT, "HOP_COUNT object"},
444     {RSVP_CLASS_STRICT_SOURCE_ROUTE, "STRICT_SOURCE_ROUTE object"},
445     {RSVP_CLASS_LABEL_REQUEST, "LABEL REQUEST object"},
446     {RSVP_CLASS_EXPLICIT_ROUTE, "EXPLICIT ROUTE object"},
447     {RSVP_CLASS_RECORD_ROUTE, "RECORD ROUTE object"},
448     {RSVP_CLASS_SESSION_ATTRIBUTE, "SESSION ATTRIBUTE object"},
449     {RSVP_CLASS_MESSAGE_ID, "MESSAGE-ID object"},
450     {RSVP_CLASS_MESSAGE_ID_ACK, "MESSAGE-ID ACK/NACK object"},
451     {RSVP_CLASS_MESSAGE_ID_LIST, "MESSAGE-ID LIST object"},
452     {RSVP_CLASS_HELLO, "HELLO object"},
453     {RSVP_CLASS_RECOVERY_LABEL, "RECOVERY-LABEL object"},
454     {RSVP_CLASS_UPSTREAM_LABEL, "UPSTREAM-LABEL object"},
455     {RSVP_CLASS_LABEL_SET, "LABEL-SET object"},
456     {RSVP_CLASS_PROTECTION, "PROTECTION object"},
457     {RSVP_CLASS_DIFFSERV, "DIFFSERV object"},
458     {RSVP_CLASS_CLASSTYPE, "CLASSTYPE object"},
459     {RSVP_CLASS_SUGGESTED_LABEL, "SUGGESTED-LABEL object"},
460     {RSVP_CLASS_ACCEPTABLE_LABEL_SET, "ACCEPTABLE-LABEL-SET object"},
461     {RSVP_CLASS_RESTART_CAP, "RESTART-CAPABILITY object"},
462     {RSVP_CLASS_DCLASS, "DCLASS object"},
463     {RSVP_CLASS_LSP_TUNNEL_IF_ID, "LSP-TUNNEL INTERFACE-ID object"},
464     {RSVP_CLASS_NOTIFY_REQUEST, "NOTIFY-REQUEST object"},
465     {RSVP_CLASS_ADMIN_STATUS, "ADMIN-STATUS object"},
466     {RSVP_CLASS_ASSOCIATION, "ASSOCIATION object"},
467     {RSVP_CLASS_GENERALIZED_UNI, "GENERALIZED-UNI object"},
468     {RSVP_CLASS_CALL_ID, "CALL-ID object"},
469     {RSVP_CLASS_DETOUR, "DETOUR object"},
470     {RSVP_CLASS_FAST_REROUTE, "FAST-REROUTE object"},
471     {0, NULL}
472 };
473
474 /*
475  * RSVP error values
476  */
477 enum rsvp_error_types {
478     RSVP_ERROR_CONFIRM = 0,
479     RSVP_ERROR_ADMISSION,
480     RSVP_ERROR_POLICY,
481     RSVP_ERROR_NO_PATH,
482     RSVP_ERROR_NO_SENDER,
483     RSVP_ERROR_CONFLICT_RESV_STYLE,
484     RSVP_ERROR_UNKNOWN_RESV_STYLE,
485     RSVP_ERROR_CONFLICT_DEST_PORTS,
486     RSVP_ERROR_CONFLICT_SRC_PORTS,
487     RSVP_ERROR_PREEMPTED=12,
488     RSVP_ERROR_UNKNOWN_CLASS,
489     RSVP_ERROR_UNKNOWN_C_TYPE,
490     RSVP_ERROR_TRAFFIC = 21,
491     RSVP_ERROR_TRAFFIC_SYSTEM, /* 22 */
492     RSVP_ERROR_SYSTEM,         /* 23 */
493     RSVP_ERROR_ROUTING,        /* 24 */
494     RSVP_ERROR_NOTIFY,         /* 25 */
495     RSVP_ERROR_DIFFSERV = 27,
496     RSVP_ERROR_DSTE = 28 /* FF: RFC4124 */
497     /*missing (11-2006) :
498       - 29 : Unknown Attributes TLV ,  RFC4420
499       - 30 : Unknown Attributes Bit RFC4420
500       - 31 : Alarms RFC-ietf-ccamp-gmpls-alarm-spec-06.txt
501     */
502 };
503
504 enum {
505     RSVP_AC_ERROR_DELAY_BOUND_ERROR = 1,
506     RSVP_AC_ERROR_BANDWITH_UNAVAILABLE,
507     RSVP_AC_ERROR_LARGE_MTU
508 };
509
510 enum {
511     RSVP_TRAFFIC_CONTROL_ERROR_SERVICE_CONFLICT = 1,
512     RSVP_TRAFFIC_CONTROL_ERROR_SERVIEC_UNSUPPORTED,
513     RSVP_TRAFFIC_CONTROL_ERROR_BAD_FLOWSPEC,
514     RSVP_TRAFFIC_CONTROL_ERROR_BAD_TSPEC,
515     RSVP_TRAFFIC_CONTROL_ERROR_BAD_ADSPEC
516 };
517
518 enum {
519     RSVP_ROUTING_ERROR_BAD_ERO = 1,
520     RSVP_ROUTING_ERROR_BAD_STRICT,
521     RSVP_ROUTING_ERROR_BAD_LOOSE,
522     RSVP_ROUTING_ERROR_BAD_INITIAL_SUBOBJ,
523     RSVP_ROUTING_ERROR_NO_ROUTE,
524     RSVP_ROUTING_ERROR_UNACCEPTABLE_LABEL,
525     RSVP_ROUTING_ERROR_RRO_LOOP,
526     RSVP_ROUTING_ERROR_NON_RSVP_CAPABLE_ROUTER,
527     RSVP_ROUTING_ERROR_LABEL_ALLOC_FAIL,
528     RSVP_ROUTING_ERROR_UNSUPPORTED_L3PID
529 };
530
531 enum {
532     RSVP_NOTIFY_ERROR_RRO_TOO_LARGE = 1,
533     RSVP_NOTIFY_ERROR_RRO_NOTIFICATION,
534     RSVP_NOTIFY_ERROR_RRO_TUNNEL_LOCAL_REPAIRED,
535     RSVP_NOTIFY_ERROR_RRO_CC_ACTIVE_STATE,       /* RFC3473*/
536     RSVP_NOTIFY_ERROR_RRO_CC_DEGRADED_STATE,     /* RFC3473*/
537     RSVP_NOTIFY_ERROR_LSP_FAILURE,               /* Private */
538     RSVP_NOTIFY_ERROR_LSP_RECOVERED,             /* Private */
539     RSVP_NOTIFY_ERROR_LSP_LOCAL_FAILURE          /* Private */
540
541 };
542
543 enum {
544     RSVP_DIFFSERV_ERROR_UNEXPECTED_DIFFSERVOBJ = 1,
545     RSVP_DIFFSERV_ERROR_UNSUPPORTED_PHB,
546     RSVP_DIFFSERV_ERROR_INVALID_EXP_PHB_MAPPING,
547     RSVP_DIFFSERV_ERROR_UNSUPPORTED_PSC,
548     RSVP_DIFFSERV_ERROR_PERLSP_CONTEXT_ALLOC_FAIL
549 };
550
551 /* FF: RFC4124 */
552 enum {
553     RSVP_DSTE_ERROR_UNEXPECTED_CLASSTYPEOBJ = 1,
554     RSVP_DSTE_ERROR_UNSUPPORTED_CLASSTYPE,
555     RSVP_DSTE_ERROR_INVALID_CLASSTYPE_VALUE,
556     RSVP_DSTE_ERROR_CT_SETUP_PRIO_NOT_CONFIGURED,
557     RSVP_DSTE_ERROR_CT_HOLDING_PRIO_NOT_CONFIGURED,
558     RSVP_DSTE_ERROR_CT_SETUP_PRIO_AND_CT_HOLDING_PRIO_NOT_CONFIGURED,
559     RSVP_DSTE_ERROR_INCONSISTENCY_PSC_CT,
560     RSVP_DSTE_ERROR_INCONSISTENCY_PHB_CT
561 };
562
563 static const value_string rsvp_error_codes[] = {
564     {RSVP_ERROR_CONFIRM, "Confirmation"},
565     {RSVP_ERROR_ADMISSION, "Admission Control Failure "},
566     {RSVP_ERROR_POLICY, "Policy Control Failure"},
567     {RSVP_ERROR_NO_PATH, "No PATH information for this RESV message"},
568     {RSVP_ERROR_NO_SENDER, "No sender information for this RESV message"},
569     {RSVP_ERROR_CONFLICT_RESV_STYLE, "Conflicting reservation styles"},
570     {RSVP_ERROR_UNKNOWN_RESV_STYLE, "Unknown reservation style"},
571     {RSVP_ERROR_CONFLICT_DEST_PORTS, "Conflicting destination ports"},
572     {RSVP_ERROR_CONFLICT_SRC_PORTS, "Conflicting source ports"},
573     {RSVP_ERROR_PREEMPTED, "Service preempted"},
574     {RSVP_ERROR_UNKNOWN_CLASS, "Unknown object class"},
575     {RSVP_ERROR_UNKNOWN_C_TYPE, "Unknown object C-type"},
576     {RSVP_ERROR_TRAFFIC, "Traffic Control Error"},
577     {RSVP_ERROR_TRAFFIC_SYSTEM, "Traffic Control System Error"},
578     {RSVP_ERROR_SYSTEM, "RSVP System Error"},
579     {RSVP_ERROR_ROUTING, "Routing Error"},
580     {RSVP_ERROR_NOTIFY, "RSVP Notify Error"},
581     {RSVP_ERROR_DIFFSERV, "RSVP Diff-Serv Error"},
582     {RSVP_ERROR_DSTE, "RSVP DiffServ-aware TE Error"},
583     {0, NULL}
584 };
585
586 static const value_string rsvp_admission_control_error_vals[] = {
587     {RSVP_AC_ERROR_DELAY_BOUND_ERROR, "Delay bound cannot be met"},
588     {RSVP_AC_ERROR_BANDWITH_UNAVAILABLE, "Requested bandwidth unavailable"},
589     {RSVP_AC_ERROR_LARGE_MTU, "MTU in flowspec larger than interface MTU"},
590     {0, NULL}
591 };
592
593 static const value_string rsvp_traffic_control_error_vals[] = {
594     {RSVP_TRAFFIC_CONTROL_ERROR_SERVICE_CONFLICT, "Service conflict"},
595     {RSVP_TRAFFIC_CONTROL_ERROR_SERVIEC_UNSUPPORTED, "Service unsupported"},
596     {RSVP_TRAFFIC_CONTROL_ERROR_BAD_FLOWSPEC, "Bad Flowspec value"},
597     {RSVP_TRAFFIC_CONTROL_ERROR_BAD_TSPEC, "Bad Tspec value"},
598     {RSVP_TRAFFIC_CONTROL_ERROR_BAD_ADSPEC, "Bad Adspec value"},
599     {0, NULL}
600 };
601
602 static const value_string rsvp_routing_error_vals[] = {
603     {RSVP_ROUTING_ERROR_BAD_ERO, "Bad EXPLICIT_ROUTE object"},
604     {RSVP_ROUTING_ERROR_BAD_STRICT, "Bad strict node"},
605     {RSVP_ROUTING_ERROR_BAD_LOOSE, "Bad loose node"},
606     {RSVP_ROUTING_ERROR_BAD_INITIAL_SUBOBJ, "Bad initial subobject"},
607     {RSVP_ROUTING_ERROR_NO_ROUTE, "No route available toward destination"},
608     {RSVP_ROUTING_ERROR_UNACCEPTABLE_LABEL, "Unacceptable label value"},
609     {RSVP_ROUTING_ERROR_RRO_LOOP, "RRO indicated routing loops"},
610     {RSVP_ROUTING_ERROR_NON_RSVP_CAPABLE_ROUTER, "non-RSVP-capable router stands in the path"},
611     {RSVP_ROUTING_ERROR_LABEL_ALLOC_FAIL, "MPLS label allocation failure"},
612     {RSVP_ROUTING_ERROR_UNSUPPORTED_L3PID, "Unsupported L3PID"},
613     {0, NULL}
614 };
615
616 static const value_string rsvp_notify_error_vals[] = {
617     {RSVP_NOTIFY_ERROR_RRO_TOO_LARGE, "RRO too large for MTU"},
618     {RSVP_NOTIFY_ERROR_RRO_NOTIFICATION, "RRO Notification"},
619     {RSVP_NOTIFY_ERROR_RRO_TUNNEL_LOCAL_REPAIRED, "Tunnel locally repaired"},
620     {RSVP_NOTIFY_ERROR_RRO_CC_ACTIVE_STATE, "Control Channel Active State"},/* RFC3473*/
621     {RSVP_NOTIFY_ERROR_RRO_CC_DEGRADED_STATE,"Control Channel Degraded State"}, /* RFC3473*/
622     {RSVP_NOTIFY_ERROR_LSP_FAILURE,  "Private : LSP Failure"},/* Private */
623     {RSVP_NOTIFY_ERROR_LSP_RECOVERED,"Private : LSP recovered"},/* Private */
624     {RSVP_NOTIFY_ERROR_LSP_LOCAL_FAILURE,"Private : LSP Local Failure"},/* Private */
625     {0, NULL}
626 };
627
628 static const value_string rsvp_diffserv_error_vals[] = {
629     {RSVP_DIFFSERV_ERROR_UNEXPECTED_DIFFSERVOBJ, "Unexpected DIFFSERV object"},
630     {RSVP_DIFFSERV_ERROR_UNSUPPORTED_PHB, "Unsupported PHB"},
631     {RSVP_DIFFSERV_ERROR_INVALID_EXP_PHB_MAPPING, "Invalid `EXP<->PHB mapping'"},
632     {RSVP_DIFFSERV_ERROR_UNSUPPORTED_PSC, "Unsupported PSC"},
633     {RSVP_DIFFSERV_ERROR_PERLSP_CONTEXT_ALLOC_FAIL, "Per-LSP context allocation failure"},
634     {0, NULL}
635 };
636
637 /* FF: RFC4124 */
638 static const value_string rsvp_diffserv_aware_te_error_vals[] = {
639     {RSVP_DSTE_ERROR_UNEXPECTED_CLASSTYPEOBJ, "Unexpected CLASSTYPE object"},
640     {RSVP_DSTE_ERROR_UNSUPPORTED_CLASSTYPE, "Unsupported Class-Type"},
641     {RSVP_DSTE_ERROR_INVALID_CLASSTYPE_VALUE, "Invalid Class-Type value"},
642     {RSVP_DSTE_ERROR_CT_SETUP_PRIO_NOT_CONFIGURED, "CT and setup priority do not form a configured TE-Class"},
643     {RSVP_DSTE_ERROR_CT_HOLDING_PRIO_NOT_CONFIGURED, "CT and holding priority do not form a configured TE-Class"},
644     {RSVP_DSTE_ERROR_CT_SETUP_PRIO_AND_CT_HOLDING_PRIO_NOT_CONFIGURED,
645      "CT and setup priority do not form a configured TE-Class AND CT and holding priority do not form a configured TE-Class"},
646     {RSVP_DSTE_ERROR_INCONSISTENCY_PSC_CT, "Inconsistency between signaled PSC and signaled CT"},
647     {RSVP_DSTE_ERROR_INCONSISTENCY_PHB_CT, "Inconsistency between signaled PHBs and signaled CT"},
648     {0, NULL}
649 };
650
651 /*
652  * Defines the reservation style plus style-specific information that
653  * is not a FLOWSPEC or FILTER_SPEC object, in a RESV message.
654  */
655 #define RSVP_DISTINCT (1 << 3)
656 #define RSVP_SHARED (2 << 3)
657 #define RSVP_SHARING_MASK (RSVP_DISTINCT | RSVP_SHARED)
658
659 #define RSVP_SCOPE_WILD 1
660 #define RSVP_SCOPE_EXPLICIT 2
661 #define RSVP_SCOPE_MASK 0x07
662
663 #define RSVP_WF (RSVP_SHARED | RSVP_SCOPE_WILD)
664 #define RSVP_FF (RSVP_DISTINCT | RSVP_SCOPE_EXPLICIT)
665 #define RSVP_SE (RSVP_SHARED | RSVP_SCOPE_EXPLICIT)
666
667 static const value_string style_vals[] = {
668     { RSVP_WF, "Wildcard Filter" },
669     { RSVP_FF, "Fixed Filter" },
670     { RSVP_SE, "Shared-Explicit" },
671     { 0,       NULL }
672 };
673
674 enum {
675     RSVP_SESSION_TYPE_IPV4 = 1,
676     RSVP_SESSION_TYPE_IPV6,
677
678     RSVP_SESSION_TYPE_IPV4_LSP = 7,
679     RSVP_SESSION_TYPE_IPV6_LSP,
680
681     RSVP_SESSION_TYPE_AGGREGATE_IPV4 = 9,
682     RSVP_SESSION_TYPE_AGGREGATE_IPV6,
683
684     RSVP_SESSION_TYPE_IPV4_UNI = 11,
685     RSVP_SESSION_TYPE_IPV4_E_NNI = 15
686 };
687
688 /*
689  * Defines a desired QoS, in a RESV message.
690  */
691 enum    qos_service_type {
692     QOS_QUALITATIVE =     128,          /* Qualitative service */
693     QOS_NULL =              6,          /* Null service (RFC2997) */
694     QOS_CONTROLLED_LOAD=    5,          /* Controlled Load Service */
695     QOS_GUARANTEED =        2,          /* Guaranteed service */
696     QOS_TSPEC =             1           /* Traffic specification */
697     };
698
699 static const value_string qos_vals[] = {
700     { QOS_QUALITATIVE, "Qualitative QoS" },
701     { QOS_NULL, "Null-Service QoS" },
702     { QOS_CONTROLLED_LOAD, "Controlled-load QoS" },
703     { QOS_GUARANTEED, "Guaranteed rate QoS" },
704     { QOS_TSPEC, "Traffic specification" },
705     { 0, NULL }
706 };
707
708 static const value_string svc_vals[] = {
709     { 126, "Compression Hint" },
710     { 127, "Token bucket" },
711     { 128, "Null Service" },
712     { 130, "Guaranteed-rate RSpec" },
713     { 0, NULL }
714 };
715
716 enum rsvp_spec_types { INTSRV = 2 };
717
718 enum intsrv_services {
719     INTSRV_GENERAL = 1,
720     INTSRV_GTD = 2,
721     INTSRV_CLOAD = 5,
722     INTSRV_NULL = 6,
723     INTSRV_QUALITATIVE = 128
724 };
725
726 static const value_string intsrv_services_str[] = {
727     {INTSRV_GENERAL, "Default General Parameters"},
728     {INTSRV_GTD, "Guaranteed Rate"},
729     {INTSRV_CLOAD, "Controlled Load"},
730     {INTSRV_NULL, "Null Service"},
731     {INTSRV_QUALITATIVE, "Null Service"},
732     { 0, NULL }
733 };
734
735 #if 0
736 enum intsrv_field_name {
737     INTSRV_NON_IS_HOPS = 1, INTSRV_COMPOSED_NON_IS_HOPS,
738     INTSRV_IS_HOPS, INTSRV_COMPOSED_IS_HOPS,
739     INTSRV_PATH_BANDWIDTH, INTSRV_MIN_PATH_BANDWIDTH,
740     INTSRV_IF_LATENCY, INTSRV_PATH_LATENCY,
741     INTSRV_MTU, INTSRV_COMPOSED_MTU,
742
743     INTSRV_TOKEN_BUCKET_TSPEC = 127,
744     INTSRV_QUALITATIVE_TSPEC = 128,
745     INTSRV_GTD_RSPEC = 130,
746
747     INTSRV_DELAY = 131,         /* Gtd Parameter C - Max Delay Bound - bytes */
748     INTSRV_MAX_JITTER,          /* Gtd Parameter D - Max Jitter */
749     INTSRV_E2E_DELAY,           /* Gtd Parameter Ctot */
750     INTSRV_E2E_MAX_JITTER,      /* Gtd Parameter Dtot */
751     INTSRV_SHP_DELAY,           /* Gtd Parameter Csum */
752     INTSRV_SHP_MAX_JITTER       /* Gtd Parameter Dsum */
753 };
754 #endif
755
756 static const value_string adspec_params[] = {
757     {4, "IS Hop Count"},
758     {6, "Path b/w estimate"},
759     {8, "Minimum path latency"},
760     {10, "Composed MTU"},
761     {133, "End-to-end composed value for C"},
762     {134, "End-to-end composed value for D"},
763     {135, "Since-last-reshaping point composed C"},
764     {136, "Since-last-reshaping point composed D"},
765     { 0, NULL }
766 };
767
768 /* 
769  * FF: please keep this list in sync with 
770  * http://www.iana.org/assignments/gmpls-sig-parameters
771  * Registry Name: 'LSP Encoding Types' 
772  */
773 const range_string gmpls_lsp_enc_rvals[] = {
774     {   1,   1, "Packet" },
775     {   2,   2, "Ethernet" },
776     {   3,   3, "ANSI/ETSI PDH" },
777     {   4,   4, "Reserved" },
778     {   5,   5, "SDH ITU-T G.707 / SONET ANSI T1.105" },
779     {   6,   6, "Reserved" },
780     {   7,   7, "Digital Wrapper" },
781     {   8,   8, "Lambda (photonic)" },
782     {   9,   9, "Fiber" },
783     {  10,  10, "Reserved" },
784     {  11,  11, "FiberChannel" },
785     {  12,  12, "G.709 ODUk (Digital Path)" },
786     {  13,  13, "G.709 Optical Channel" },
787     {  14, 239, "Unassigned" },
788     { 240, 255, "Experimental Usage/temporarily" },
789     {   0,   0, NULL }
790 };
791
792 /* 
793  * FF: please keep this list in sync with 
794  * http://www.iana.org/assignments/gmpls-sig-parameters
795  * Registry Name: 'Switching Types'
796  */
797 const range_string gmpls_switching_type_rvals[] = {
798     {   1,   1, "Packet-Switch Capable-1 (PSC-1)" },
799     {   2,   2, "Packet-Switch Capable-2 (PSC-2)" },
800     {   3,   3, "Packet-Switch Capable-3 (PSC-3)" },
801     {   4,   4, "Packet-Switch Capable-4 (PSC-4)" },
802     {   5,  50, "Unassigned" },
803     {  51,  51, "Layer-2 Switch Capable (L2SC)" },
804     {  52,  99, "Unassigned" },
805     { 100, 100, "Time-Division-Multiplex Capable (TDM)" },
806     { 101, 149, "Unassigned" },
807     { 150, 150, "Lambda-Switch Capable (LSC)" },
808     { 151, 169, "Unassigned" },
809     { 200, 200, "Fiber-Switch Capable (FSC)" },
810     { 201, 255, "Unassigned" },
811     {   0,   0, NULL }
812 };
813
814 /* 
815  * FF: please keep this list in sync with 
816  * http://www.iana.org/assignments/gmpls-sig-parameters
817  * Registry Name: 'Generalized PID (G-PID)'
818  */
819 static const range_string gmpls_gpid_rvals[] = {
820     {      0,     0, "Unknown" },
821     {      1,     4, "Reserved" },
822     {      5,     5, "Asynchronous mapping of E4" },
823     {      6,     6, "Asynchronous mapping of DS3/T3" },
824     {      7,     7, "Asynchronous mapping of E3" },
825     {      8,     8, "Bit synchronous mapping of E3" },
826     {      9,     9, "Byte synchronous mapping of E3" },
827     {     10,    10, "Asynchronous mapping of DS2/T2" },
828     {     11,    11, "Bit synchronous mapping of DS2/T2" },
829     {     12,    12, "Reserved" },
830     {     13,    13, "Asynchronous mapping of E1" },
831     {     14,    14, "Byte synchronous mapping of E1" },
832     {     15,    15, "Byte synchronous mapping of 31 * DS0" },
833     {     16,    16, "Asynchronous mapping of DS1/T1" },
834     {     17,    17, "Bit synchronous mapping of DS1/T1" },
835     {     18,    18, "Byte synchronous mapping of DS1/T1" },
836     {     19,    19, "VC-11 in VC-12" },
837     {     20,    21, "Reserved" },
838     {     22,    22, "DS1 SF Asynchronous" },
839     {     23,    23, "DS1 ESF Asynchronous" },
840     {     24,    24, "DS3 M23 Asynchronous" },
841     {     25,    25, "DS3 C-Bit Parity Asynchronous" },
842     {     26,    26, "VT/LOVC" },
843     {     27,    27, "STS SPE/HOVC" },
844     {     28,    28, "POS - No Scrambling, 16 bit CRC" },
845     {     29,    29, "POS - No Scrambling, 32 bit CRC" },
846     {     30,    30, "POS - Scrambling, 16 bit CRC" },
847     {     31,    31, "POS - Scrambling, 32 bit CRC" },
848     {     32,    32, "ATM mapping" },
849     {     33,    33, "Ethernet PHY" },
850     {     34,    34, "SONET/SDH" },
851     {     35,    35, "Reserved (SONET deprecated)" },
852     {     36,    36, "Digital Wrapper" },
853     {     37,    37, "Lambda" },
854     {     38,    38, "ANSI/ETSI PDH" },
855     {     39,    39, "Reserved" },
856     {     40,    40, "Link Access Protocol SDH (LAPS - X.85 and X.86)" },
857     {     41,    41, "FDDI" },
858     {     42,    42, "DQDB (ETSI ETS 300 216)" },
859     {     43,    43, "FiberChannel-3 (Services)" },
860     {     44,    44, "HDLC" },
861     {     45,    45, "Ethernet V2/DIX (only)" },
862     {     46,    46, "Ethernet 802.3 (only)" },
863     {     47,    47, "G.709 ODUj" },
864     {     48,    48, "G.709 OTUk(v)" },
865     {     49,    49, "CBR/CBRa" },
866     {     50,    50, "CBRb" },
867     {     51,    51, "BSOT" },
868     {     52,    52, "BSNT" },
869     {     53,    53, "IP/PPP (GFP)" },
870     {     54,    54, "Ethernet MAC (framed GFP)" },
871     {     55,    55, "Ethernet PHY (transparent GFP" },
872     {     56,    56, "ESCON" },
873     {     57,    57, "FICON" },
874     {     58,    58, "Fiber Channel" },
875     {     59, 31743, "Unassigned" },
876     {  31744, 32767, "Experimental Usage/temporarily" },
877     {  32768, 65535, "Reserved" },
878     {      0,     0, NULL },
879 };
880
881 const value_string gmpls_protection_cap_str[] = {
882     { 1, "Extra Traffic"},
883     { 2, "Unprotected"},
884     { 4, "Shared"},
885     { 8, "Dedicated 1:1"},
886     {16, "Dedicated 1+1"},
887     {32, "Enhanced"},
888     {64, "Reserved"},
889     {128,"Reserved"},
890     { 0, NULL }
891 };
892
893 const value_string gmpls_sonet_signal_type_str[] = {
894     { 1, "VT1.5 SPE / VC-11"},
895     { 2, "VT2 SPE / VC-12"},
896     { 3, "VT3 SPE"},
897     { 4, "VT6 SPE / VC-2"},
898     { 5, "STS-1 SPE / VC-3"},
899     { 6, "STS-3c SPE / VC-4"},
900     { 7, "STS-1 / STM-0 (transp)"},
901     { 8, "STS-3 / STM-1 (transp)"},
902     { 9, "STS-12 / STM-4 (transp)"},
903     {10, "STS-48 / STM-16 (transp)"},
904     {11, "STS-192 / STM-64 (transp)"},
905     {12, "STS-768 / STM-256 (transp)"},
906
907     /* Extended non-SONET signal types */
908     {13, "VTG / TUG-2"},
909     {14, "TUG-3"},
910     {15, "STSG-3 / AUG-1"},
911     {16, "STSG-12  / AUG-4"},
912     {17, "STSG-48  / AUG-16"},
913     {18, "STSG-192 / AUG-64"},
914     {19, "STSG-768 / AUG-256"},
915
916     /* Other SONEt signal types */
917     {21, "STS-12c SPE / VC-4-4c"},
918     {22, "STS-48c SPE / VC-4-16c"},
919     {23, "STS-192c SPE / VC-4-64c"},
920     {0, NULL}
921 };
922
923 static const value_string ouni_guni_diversity_str[] = {
924     {1, "Node Diverse"},
925     {2, "Link Diverse"},
926     {3, "Shared-Risk Link Group Diverse"},
927     {4, "Shared Path"},
928     {0, NULL}
929 };
930
931 /* FF: RFC 4328 G.709 signal type */
932 const range_string gmpls_g709_signal_type_rvals[] = {
933     { 0,   0, "Not significant"},
934     { 1,   1, "ODU1 (i.e., 2.5 Gbps)"},
935     { 2,   2, "ODU2 (i.e., 10  Gbps)"},
936     { 3,   3, "ODU3 (i.e., 40  Gbps)"},
937     { 4,   5, "Reserved (for future use)"},
938     { 6,   6, "OCh at 2.5 Gbps"},
939     { 7,   7, "OCh at 10  Gbps"},
940     { 8,   8, "OCh at 40  Gbps"},
941     { 9, 255, "Reserved (for future use)"},
942     { 0,   0, NULL}
943 };
944
945 /* -------------------- Stuff for MPLS/TE objects -------------------- */
946
947 static const value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"},
948                                            {IP_PROTO_IGMP, "IGMP"},
949                                            {IP_PROTO_TCP,  "TCP" },
950                                            {IP_PROTO_UDP,  "UDP" },
951                                            {IP_PROTO_OSPF, "OSPF"},
952                                            {0,             NULL  } };
953
954 /* Filter keys */
955 enum hf_rsvp_filter_keys {
956
957     /* Message types */
958     RSVPF_MSG,          /* Message type */
959     /* Shorthand for message types */
960     RSVPF_PATH,
961     RSVPF_RESV,
962     RSVPF_PATHERR,
963     RSVPF_RESVERR,
964     RSVPF_PATHTEAR,
965     RSVPF_RESVTEAR,
966     RSVPF_RCONFIRM,
967     RSVPF_JUNK_MSG8,
968     RSVPF_JUNK_MSG9,
969     RSVPF_RTEARCONFIRM,
970     RSVPF_JUNK11,
971     RSVPF_BUNDLE,
972     RSVPF_ACK,
973     RSVPF_JUNK14,
974     RSVPF_SREFRESH,
975     RSVPF_JUNK16,
976     RSVPF_JUNK17,
977     RSVPF_JUNK18,
978     RSVPF_JUNK19,
979     RSVPF_HELLO,
980     RSVPF_NOTIFY,
981     /* Does the message contain an object of this type? */
982     RSVPF_OBJECT,
983     /* Object present shorthands */
984     RSVPF_SESSION,
985     RSVPF_DUMMY_1,
986     RSVPF_HOP,
987     RSVPF_INTEGRITY,
988     RSVPF_TIME_VALUES,
989     RSVPF_ERROR,
990     RSVPF_SCOPE,
991     RSVPF_STYLE,
992     RSVPF_FLOWSPEC,
993     RSVPF_FILTER_SPEC,
994     RSVPF_SENDER,
995     RSVPF_TSPEC,
996     RSVPF_ADSPEC,
997     RSVPF_POLICY,
998     RSVPF_CONFIRM,
999     RSVPF_LABEL,
1000     RSVPF_DUMMY_2,
1001     RSVPF_DUMMY_3,
1002     RSVPF_LABEL_REQUEST,
1003     RSVPF_EXPLICIT_ROUTE,
1004     RSVPF_RECORD_ROUTE,
1005     RSVPF_HELLO_OBJ,
1006     RSVPF_MESSAGE_ID,
1007     RSVPF_MESSAGE_ID_ACK,
1008     RSVPF_MESSAGE_ID_LIST,
1009     RSVPF_RECOVERY_LABEL,
1010     RSVPF_UPSTREAM_LABEL,
1011     RSVPF_LABEL_SET,
1012     RSVPF_PROTECTION,
1013     RSVPF_DIFFSERV,
1014     RSVPF_DSTE,
1015
1016     RSVPF_SUGGESTED_LABEL,
1017     RSVPF_ACCEPTABLE_LABEL_SET,
1018     RSVPF_RESTART_CAP,
1019
1020     RSVPF_SESSION_ATTRIBUTE,
1021     RSVPF_DCLASS,
1022     RSVPF_LSP_TUNNEL_IF_ID,
1023     RSVPF_NOTIFY_REQUEST,
1024     RSVPF_ADMIN_STATUS,
1025     RSVPF_ASSOCIATION,
1026     RSVPF_GENERALIZED_UNI,
1027     RSVPF_CALL_ID,
1028     RSVPF_UNKNOWN_OBJ,
1029
1030     /* Session object */
1031     RSVPF_SESSION_IP,
1032     RSVPF_SESSION_PROTO,
1033     RSVPF_SESSION_PORT,
1034     RSVPF_SESSION_TUNNEL_ID,
1035     RSVPF_SESSION_EXT_TUNNEL_ID,
1036
1037     /* Sender template */
1038     RSVPF_SENDER_IP,
1039     RSVPF_SENDER_PORT,
1040     RSVPF_SENDER_LSP_ID,
1041
1042     /* Diffserv object */
1043     RSVPF_DIFFSERV_MAPNB,
1044     RSVPF_DIFFSERV_MAP,
1045     RSVPF_DIFFSERV_MAP_EXP,
1046     RSVPF_DIFFSERV_PHBID,
1047     RSVPF_DIFFSERV_PHBID_DSCP,
1048     RSVPF_DIFFSERV_PHBID_CODE,
1049     RSVPF_DIFFSERV_PHBID_BIT14,
1050     RSVPF_DIFFSERV_PHBID_BIT15,
1051
1052     /* Diffserv-aware TE object */
1053     RSVPF_DSTE_CLASSTYPE,
1054
1055     /* Generalized UNI object */
1056     RSVPF_GUNI_SRC_IPV4,
1057     RSVPF_GUNI_DST_IPV4,
1058     RSVPF_GUNI_SRC_IPV6,
1059     RSVPF_GUNI_DST_IPV6,
1060
1061     /* CALL ID object */
1062     RSVPF_CALL_ID_SRC_ADDR_IPV4,
1063     RSVPF_CALL_ID_SRC_ADDR_IPV6,
1064
1065     /* Sentinel */
1066     RSVPF_MAX
1067 };
1068
1069 static int hf_rsvp_filter[RSVPF_MAX];
1070
1071 /* RSVP Conversation related Hash functions */
1072
1073 /*
1074  * Compare two RSVP request keys to see if they are equal. Return 1 if they
1075  * are, 0 otherwise.
1076  * Two RSVP request keys are equal if and only if they have the exactly the
1077  * same internal conversation identifier, session type, and matching values in
1078  * the session info and source info structures.
1079  */
1080 static gint
1081 rsvp_equal (gconstpointer k1, gconstpointer k2)
1082 {
1083     const struct rsvp_request_key *key1 = (const struct rsvp_request_key*) k1;
1084     const struct rsvp_request_key *key2 = (const struct rsvp_request_key*) k2;
1085
1086     if (key1->conversation != key2->conversation) {
1087         return 0;
1088     }
1089
1090     if (key1->session_type != key2->session_type) {
1091         return 0;
1092     }
1093
1094     switch (key1->session_type) {
1095     case RSVP_SESSION_TYPE_IPV4:
1096         if (ADDRESSES_EQUAL(&key1->u.session_ipv4.destination,
1097                             &key2->u.session_ipv4.destination) == FALSE)
1098             return 0;
1099
1100         if (key1->u.session_ipv4.protocol != key2->u.session_ipv4.protocol)
1101             return 0;
1102
1103         if (key1->u.session_ipv4.udp_dest_port != key2->u.session_ipv4.udp_dest_port)
1104             return 0;
1105
1106         break;
1107
1108     case RSVP_SESSION_TYPE_IPV6:
1109         /* this is not supported yet for conversations */
1110         break;
1111
1112     case RSVP_SESSION_TYPE_IPV4_LSP:
1113         if (ADDRESSES_EQUAL(&key1->u.session_ipv4_lsp.destination,
1114                             &key2->u.session_ipv4_lsp.destination) == FALSE)
1115             return 0;
1116
1117         if (key1->u.session_ipv4_lsp.udp_dest_port !=
1118             key2->u.session_ipv4_lsp.udp_dest_port)
1119             return 0;
1120
1121
1122         if (key1->u.session_ipv4_lsp.ext_tunnel_id !=
1123             key2->u.session_ipv4_lsp.ext_tunnel_id)
1124             return 0;
1125
1126         break;
1127
1128     case RSVP_SESSION_TYPE_AGGREGATE_IPV4:
1129         if (ADDRESSES_EQUAL(&key1->u.session_agg_ipv4.destination,
1130                             &key2->u.session_agg_ipv4.destination) == FALSE)
1131             return 0;
1132
1133         if (key1->u.session_agg_ipv4.dscp != key2->u.session_agg_ipv4.dscp)
1134             return 0;
1135
1136         break;
1137
1138     case RSVP_SESSION_TYPE_AGGREGATE_IPV6:
1139         /* this is not supported yet for conversations */
1140         break;
1141
1142     case RSVP_SESSION_TYPE_IPV4_UNI:
1143         if (ADDRESSES_EQUAL(&key1->u.session_ipv4_uni.destination,
1144                             &key2->u.session_ipv4_uni.destination) == FALSE)
1145             return 0;
1146
1147         if (key1->u.session_ipv4_uni.udp_dest_port !=
1148             key2->u.session_ipv4_uni.udp_dest_port)
1149             return 0;
1150
1151
1152         if (key1->u.session_ipv4_uni.ext_tunnel_id !=
1153             key2->u.session_ipv4_uni.ext_tunnel_id)
1154             return 0;
1155
1156         break;
1157
1158     case RSVP_SESSION_TYPE_IPV4_E_NNI:
1159         if (ADDRESSES_EQUAL(&key1->u.session_ipv4_enni.destination,
1160                             &key2->u.session_ipv4_enni.destination) == FALSE)
1161             return 0;
1162
1163         if (key1->u.session_ipv4_enni.udp_dest_port !=
1164             key2->u.session_ipv4_enni.udp_dest_port)
1165             return 0;
1166
1167
1168         if (key1->u.session_ipv4_enni.ext_tunnel_id !=
1169             key2->u.session_ipv4_enni.ext_tunnel_id)
1170             return 0;
1171
1172         break;
1173
1174     default:
1175         /* This should never happen. */
1176         break;
1177     }
1178
1179     if (ADDRESSES_EQUAL(&key1->source_info.source,
1180                         &key2->source_info.source) == FALSE)
1181         return 0;
1182
1183     if (key1->source_info.udp_source_port != key2->source_info.udp_source_port)
1184         return 0;
1185
1186     /* If we get here, the two keys are equal. */
1187     return 1;
1188 }
1189
1190 /*
1191  * Calculate a hash key for the supplied RSVP request. The internally allocated
1192  * conversation-id is unique, so we just use that.
1193  */
1194 static guint
1195 rsvp_hash (gconstpointer k)
1196 {
1197     const struct rsvp_request_key *key = (const struct rsvp_request_key*) k;
1198     return key->conversation;
1199 }
1200
1201 /*
1202  * Conversation specific initialization code that deletes any unused memory that
1203  * might need to be freed, and allocates the memory for the various conversation
1204  * hash tables.
1205  */
1206 static void
1207 rsvp_init_protocol (void)
1208 {
1209     if (rsvp_request_hash)
1210         g_hash_table_destroy(rsvp_request_hash);
1211
1212     rsvp_request_hash = g_hash_table_new(rsvp_hash, rsvp_equal);
1213 }
1214
1215 static inline int rsvp_class_to_filter_num(int classnum)
1216 {
1217     switch(classnum) {
1218     case RSVP_CLASS_SESSION :
1219     case RSVP_CLASS_HOP :
1220     case RSVP_CLASS_INTEGRITY :
1221     case RSVP_CLASS_TIME_VALUES :
1222     case RSVP_CLASS_ERROR :
1223     case RSVP_CLASS_SCOPE :
1224     case RSVP_CLASS_STYLE :
1225     case RSVP_CLASS_FLOWSPEC :
1226     case RSVP_CLASS_FILTER_SPEC :
1227     case RSVP_CLASS_SENDER_TEMPLATE :
1228     case RSVP_CLASS_SENDER_TSPEC :
1229     case RSVP_CLASS_ADSPEC :
1230     case RSVP_CLASS_POLICY :
1231     case RSVP_CLASS_CONFIRM :
1232     case RSVP_CLASS_LABEL :
1233     case RSVP_CLASS_LABEL_REQUEST :
1234     case RSVP_CLASS_HELLO :
1235     case RSVP_CLASS_EXPLICIT_ROUTE :
1236     case RSVP_CLASS_RECORD_ROUTE :
1237     case RSVP_CLASS_MESSAGE_ID :
1238     case RSVP_CLASS_MESSAGE_ID_ACK :
1239     case RSVP_CLASS_MESSAGE_ID_LIST :
1240         return classnum + RSVPF_OBJECT;
1241         break;
1242
1243     case RSVP_CLASS_RECOVERY_LABEL :
1244     case RSVP_CLASS_UPSTREAM_LABEL :
1245     case RSVP_CLASS_LABEL_SET :
1246     case RSVP_CLASS_PROTECTION :
1247         return RSVPF_RECOVERY_LABEL + (classnum - RSVP_CLASS_RECOVERY_LABEL);
1248
1249     case RSVP_CLASS_SUGGESTED_LABEL :
1250     case RSVP_CLASS_ACCEPTABLE_LABEL_SET :
1251     case RSVP_CLASS_RESTART_CAP :
1252         return RSVPF_SUGGESTED_LABEL + (classnum - RSVP_CLASS_SUGGESTED_LABEL);
1253
1254     case RSVP_CLASS_DIFFSERV :
1255         return RSVPF_DIFFSERV;
1256
1257     case RSVP_CLASS_CLASSTYPE :
1258         return RSVPF_DSTE;
1259
1260     case RSVP_CLASS_NOTIFY_REQUEST :
1261         return RSVPF_NOTIFY_REQUEST;
1262     case RSVP_CLASS_ADMIN_STATUS :
1263         return RSVPF_ADMIN_STATUS;
1264     case RSVP_CLASS_ASSOCIATION :
1265         return RSVPF_ASSOCIATION;
1266
1267     case RSVP_CLASS_SESSION_ATTRIBUTE :
1268         return RSVPF_SESSION_ATTRIBUTE;
1269     case RSVP_CLASS_GENERALIZED_UNI :
1270         return RSVPF_GENERALIZED_UNI;
1271     case RSVP_CLASS_CALL_ID :
1272         return RSVPF_CALL_ID;
1273     case RSVP_CLASS_DCLASS :
1274         return RSVPF_DCLASS;
1275     case RSVP_CLASS_LSP_TUNNEL_IF_ID :
1276         return RSVPF_LSP_TUNNEL_IF_ID;
1277
1278     default:
1279         return RSVPF_UNKNOWN_OBJ;
1280     }
1281 }
1282
1283 static inline int rsvp_class_to_tree_type(int classnum)
1284 {
1285     switch(classnum) {
1286     case RSVP_CLASS_SESSION :
1287         return TT_SESSION;
1288     case RSVP_CLASS_HOP :
1289         return TT_HOP;
1290     case RSVP_CLASS_INTEGRITY :
1291         return TT_INTEGRITY;
1292     case RSVP_CLASS_TIME_VALUES :
1293         return TT_TIME_VALUES;
1294     case RSVP_CLASS_ERROR :
1295         return TT_ERROR;
1296     case RSVP_CLASS_SCOPE :
1297         return TT_SCOPE;
1298     case RSVP_CLASS_STYLE :
1299         return TT_STYLE;
1300     case RSVP_CLASS_FLOWSPEC :
1301         return TT_FLOWSPEC;
1302     case RSVP_CLASS_FILTER_SPEC :
1303         return TT_FILTER_SPEC;
1304     case RSVP_CLASS_SENDER_TEMPLATE :
1305         return TT_SENDER_TEMPLATE;
1306     case RSVP_CLASS_SENDER_TSPEC :
1307         return TT_TSPEC;
1308     case RSVP_CLASS_ADSPEC :
1309         return TT_ADSPEC;
1310     case RSVP_CLASS_POLICY :
1311         return TT_POLICY;
1312     case RSVP_CLASS_CONFIRM :
1313         return TT_CONFIRM;
1314     case RSVP_CLASS_RECOVERY_LABEL :
1315     case RSVP_CLASS_UPSTREAM_LABEL :
1316     case RSVP_CLASS_SUGGESTED_LABEL :
1317     case RSVP_CLASS_LABEL :
1318         return TT_LABEL;
1319     case RSVP_CLASS_LABEL_REQUEST :
1320         return TT_LABEL_REQUEST;
1321     case RSVP_CLASS_HELLO :
1322         return TT_HELLO_OBJ;
1323     case RSVP_CLASS_EXPLICIT_ROUTE :
1324         return TT_EXPLICIT_ROUTE;
1325     case RSVP_CLASS_RECORD_ROUTE :
1326         return TT_RECORD_ROUTE;
1327     case RSVP_CLASS_MESSAGE_ID :
1328         return TT_MESSAGE_ID;
1329     case RSVP_CLASS_MESSAGE_ID_ACK :
1330         return TT_MESSAGE_ID_ACK;
1331     case RSVP_CLASS_MESSAGE_ID_LIST :
1332         return TT_MESSAGE_ID_LIST;
1333     case RSVP_CLASS_LABEL_SET :
1334         return TT_LABEL_SET;
1335     case RSVP_CLASS_PROTECTION :
1336         return TT_PROTECTION_INFO;
1337     case RSVP_CLASS_ACCEPTABLE_LABEL_SET :
1338         return TT_UNKNOWN_CLASS;
1339     case RSVP_CLASS_RESTART_CAP :
1340         return TT_RESTART_CAP;
1341     case RSVP_CLASS_DIFFSERV :
1342         return TT_DIFFSERV;
1343     case RSVP_CLASS_CLASSTYPE:
1344         return TT_CLASSTYPE;
1345     case RSVP_CLASS_NOTIFY_REQUEST :
1346         return TT_UNKNOWN_CLASS;
1347     case RSVP_CLASS_ADMIN_STATUS :
1348         return TT_ADMIN_STATUS;
1349     case RSVP_CLASS_ASSOCIATION :
1350         return TT_ASSOCIATION;
1351     case RSVP_CLASS_SESSION_ATTRIBUTE :
1352         return TT_SESSION_ATTRIBUTE;
1353     case RSVP_CLASS_GENERALIZED_UNI :
1354         return TT_GEN_UNI;
1355     case RSVP_CLASS_CALL_ID :
1356         return TT_CALL_ID;
1357     case RSVP_CLASS_DCLASS :
1358         return TT_DCLASS;
1359     case RSVP_CLASS_LSP_TUNNEL_IF_ID :
1360         return TT_LSP_TUNNEL_IF_ID;
1361     default:
1362         return TT_UNKNOWN_CLASS;
1363     }
1364 }
1365
1366 static void
1367 find_rsvp_session_tempfilt(tvbuff_t *tvb, int hdr_offset, int *session_offp, int *tempfilt_offp)
1368 {
1369     int s_off = 0, t_off = 0;
1370     int len, off;
1371     guint obj_length;
1372
1373     if (!tvb_bytes_exist(tvb, hdr_offset+6, 2))
1374         goto done;
1375
1376     len = tvb_get_ntohs(tvb, hdr_offset+6) + hdr_offset;
1377     off = hdr_offset + 8;
1378     for (off = hdr_offset + 8; off < len && tvb_bytes_exist(tvb, off, 3);
1379          off += obj_length) {
1380         obj_length = tvb_get_ntohs(tvb, off);
1381         if (obj_length == 0)
1382             break;
1383         switch(tvb_get_guint8(tvb, off+2)) {
1384         case RSVP_CLASS_SESSION:
1385             s_off = off;
1386             break;
1387         case RSVP_CLASS_SENDER_TEMPLATE:
1388         case RSVP_CLASS_FILTER_SPEC:
1389             t_off = off;
1390             break;
1391         default:
1392             break;
1393         }
1394     }
1395
1396  done:
1397     if (session_offp) *session_offp = s_off;
1398     if (tempfilt_offp) *tempfilt_offp = t_off;
1399 }
1400
1401 static char *summary_session (tvbuff_t *tvb, int offset)
1402 {
1403     static char buf[100];
1404
1405     switch(tvb_get_guint8(tvb, offset+3)) {
1406     case RSVP_SESSION_TYPE_IPV4:
1407         g_snprintf(buf, 100, "SESSION: IPv4, Destination %s, Protocol %d, Port %d. ",
1408                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1409                  tvb_get_guint8(tvb, offset+8),
1410                  tvb_get_ntohs(tvb, offset+10));
1411         break;
1412     case RSVP_SESSION_TYPE_IPV4_LSP:
1413         g_snprintf(buf, 100, "SESSION: IPv4-LSP, Destination %s, Tunnel ID %d, Ext ID %0x. ",
1414                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1415                  tvb_get_ntohs(tvb, offset+10),
1416                  tvb_get_ntohl(tvb, offset+12));
1417         break;
1418     case RSVP_SESSION_TYPE_AGGREGATE_IPV4:
1419         g_snprintf(buf, 100, "SESSION: IPv4-Aggregate, Destination %s, DSCP %d. ",
1420                    ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1421                    tvb_get_guint8(tvb, offset+11));
1422         break;
1423     case RSVP_SESSION_TYPE_IPV4_UNI:
1424         g_snprintf(buf, 100, "SESSION: IPv4-UNI, Destination %s, Tunnel ID %d, Ext Address %s. ",
1425                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1426                  tvb_get_ntohs(tvb, offset+10),
1427                  ip_to_str(tvb_get_ptr(tvb, offset+12, 4)));
1428         break;
1429     case RSVP_SESSION_TYPE_IPV4_E_NNI:
1430         g_snprintf(buf, 100, "SESSION: IPv4-E-NNI, Destination %s, Tunnel ID %d, Ext Address %s. ",
1431                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1432                  tvb_get_ntohs(tvb, offset+10),
1433                  ip_to_str(tvb_get_ptr(tvb, offset+12, 4)));
1434         break;
1435     default:
1436         g_snprintf(buf, 100, "SESSION: Type %d. ", tvb_get_guint8(tvb, offset+3));
1437     }
1438
1439     return buf;
1440 }
1441
1442 static char *summary_template (tvbuff_t *tvb, int offset)
1443 {
1444     static char buf[80];
1445     const char *objtype;
1446
1447     if (tvb_get_guint8(tvb, offset+2) == RSVP_CLASS_FILTER_SPEC)
1448         objtype = "FILTERSPEC";
1449     else
1450         objtype = "SENDER TEMPLATE";
1451
1452     switch(tvb_get_guint8(tvb, offset+3)) {
1453     case 1:
1454         g_snprintf(buf, 80, "%s: IPv4, Sender %s, Port %d. ", objtype,
1455                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1456                  tvb_get_ntohs(tvb, offset+10));
1457         break;
1458     case 7:
1459         g_snprintf(buf, 80, "%s: IPv4-LSP, Tunnel Source: %s, LSP ID: %d. ", objtype,
1460                  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
1461                  tvb_get_ntohs(tvb, offset+10));
1462         break;
1463     case 9:
1464         g_snprintf(buf, 80, "%s: IPv4-Aggregate, Aggregator %s. ", objtype,
1465                    ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
1466         break;
1467     default:
1468         g_snprintf(buf, 80, "%s: Type %d. ", objtype, tvb_get_guint8(tvb, offset+3));
1469     }
1470
1471     return buf;
1472 }
1473
1474 /*------------------------------------------------------------------------------
1475  * SESSION
1476  *------------------------------------------------------------------------------*/
1477 static void
1478 dissect_rsvp_session (proto_item *ti, proto_tree *rsvp_object_tree,
1479                       tvbuff_t *tvb,
1480                       int offset, int obj_length,
1481                       int class _U_, int type,
1482                       rsvp_conversation_info *rsvph)
1483 {
1484     proto_item *hidden_item;
1485     int offset2 = offset + 4;
1486
1487     proto_item_set_text(ti, "%s", summary_session(tvb, offset));
1488
1489     switch(type) {
1490     case RSVP_SESSION_TYPE_IPV4:
1491         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1492                             "C-type: 1 - IPv4");
1493         proto_tree_add_item(rsvp_object_tree,
1494                             hf_rsvp_filter[RSVPF_SESSION_IP],
1495                             tvb, offset2, 4, FALSE);
1496
1497         proto_tree_add_item(rsvp_object_tree,
1498                             hf_rsvp_filter[RSVPF_SESSION_PROTO], tvb,
1499                             offset2+4, 1, FALSE);
1500         proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1,
1501                             "Flags: %x",
1502                             tvb_get_guint8(tvb, offset2+5));
1503         proto_tree_add_item(rsvp_object_tree,
1504                             hf_rsvp_filter[RSVPF_SESSION_PORT], tvb,
1505                             offset2+6, 2, FALSE);
1506
1507         /*
1508          * Save this information to build the conversation request key
1509          * later.
1510          */
1511         rsvph->session_type = RSVP_SESSION_TYPE_IPV4;
1512         SET_ADDRESS(&rsvph->destination, AT_IPv4, 4,
1513                     tvb_get_ptr(tvb, offset2, 4));
1514         rsvph->protocol = tvb_get_guint8(tvb, offset2+4);
1515         rsvph->udp_dest_port = tvb_get_ntohs(tvb, offset2+6);
1516
1517         break;
1518
1519     case RSVP_SESSION_TYPE_IPV6:
1520         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1521                             "C-type: 2 - IPv6");
1522         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
1523                             "Destination address: %s",
1524                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1525         proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1,
1526                             "Protocol: %u",
1527                             tvb_get_guint8(tvb, offset2+16));
1528         proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1,
1529                             "Flags: %x",
1530                             tvb_get_guint8(tvb, offset2+17));
1531         proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
1532                             "Destination port: %u",
1533                             tvb_get_ntohs(tvb, offset2+18));
1534         /*
1535          * Save this information to build the conversation request key
1536          * later. IPv6 conversatiuon support is not implemented yet, so only
1537          * the session type is stored.
1538          */
1539         rsvph->session_type = RSVP_SESSION_TYPE_IPV6;
1540
1541         break;
1542
1543     case RSVP_SESSION_TYPE_IPV4_LSP:
1544         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1545                             "C-type: 7 - IPv4 LSP");
1546         proto_tree_add_item(rsvp_object_tree,
1547                             hf_rsvp_filter[RSVPF_SESSION_IP],
1548                             tvb, offset2, 4, FALSE);
1549
1550         proto_tree_add_item(rsvp_object_tree,
1551                             hf_rsvp_filter[RSVPF_SESSION_TUNNEL_ID],
1552                             tvb, offset2+6, 2, FALSE);
1553
1554         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
1555                             "Extended Tunnel ID: %u (%s)",
1556                             tvb_get_ntohl(tvb, offset2+8),
1557                             ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1558         hidden_item = proto_tree_add_item(rsvp_object_tree,
1559                                    hf_rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID],
1560                                    tvb, offset2+8, 4, FALSE);
1561         PROTO_ITEM_SET_HIDDEN(hidden_item);
1562
1563         /*
1564          * Save this information to build the conversation request key
1565          * later.
1566          */
1567         rsvph->session_type = RSVP_SESSION_TYPE_IPV4_LSP;
1568         SET_ADDRESS(&rsvph->destination, AT_IPv4, 4,
1569                     tvb_get_ptr(tvb, offset2, 4));
1570         rsvph->udp_dest_port = tvb_get_ntohs(tvb, offset2+6);
1571         rsvph->ext_tunnel_id = tvb_get_ntohl(tvb, offset2 + 8);
1572         break;
1573
1574     case RSVP_SESSION_TYPE_AGGREGATE_IPV4:
1575         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1576                             "C-type: 9 - IPv4 Aggregate");
1577         proto_tree_add_item(rsvp_object_tree,
1578                             hf_rsvp_filter[RSVPF_SESSION_IP],
1579                             tvb, offset2, 4, FALSE);
1580
1581         proto_tree_add_text(rsvp_object_tree, tvb, offset2+7, 1,
1582                             "DSCP: %u (%s)",
1583                             tvb_get_guint8(tvb, offset2+7),
1584                             val_to_str(tvb_get_guint8(tvb, offset2+7),
1585                                        dscp_vals, "Unknown (%d)"));
1586         /*
1587          * Save this information to build the conversation request key
1588          * later.
1589          */
1590         rsvph->session_type = RSVP_SESSION_TYPE_AGGREGATE_IPV4;
1591         SET_ADDRESS(&rsvph->destination, AT_IPv4, 4,
1592                     tvb_get_ptr(tvb, offset2, 4));
1593         rsvph->dscp = tvb_get_guint8(tvb, offset2+7);
1594         rsvph->ext_tunnel_id = tvb_get_ntohl(tvb, offset2 + 8);
1595         break;
1596
1597     case RSVP_SESSION_TYPE_IPV4_UNI:
1598         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1599                             "C-type: 11 - IPv4 UNI");
1600         proto_tree_add_item(rsvp_object_tree,
1601                             hf_rsvp_filter[RSVPF_SESSION_IP],
1602                             tvb, offset2, 4, FALSE);
1603
1604         proto_tree_add_item(rsvp_object_tree,
1605                             hf_rsvp_filter[RSVPF_SESSION_TUNNEL_ID],
1606                             tvb, offset2+6, 2, FALSE);
1607
1608         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
1609                             "Extended IPv4 Address: %s",
1610                             ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1611         hidden_item = proto_tree_add_item(rsvp_object_tree,
1612                                    hf_rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID],
1613                                    tvb, offset2+8, 4, FALSE);
1614         PROTO_ITEM_SET_HIDDEN(hidden_item);
1615
1616         /*
1617          * Save this information to build the conversation request key
1618          * later.
1619          */
1620         rsvph->session_type = RSVP_SESSION_TYPE_IPV4_UNI;
1621         SET_ADDRESS(&rsvph->destination, AT_IPv4, 4,
1622                     tvb_get_ptr(tvb, offset2, 4));
1623         rsvph->udp_dest_port = tvb_get_ntohs(tvb, offset2+6);
1624         rsvph->ext_tunnel_id = tvb_get_ntohl(tvb, offset2 + 8);
1625
1626         break;
1627
1628     case RSVP_SESSION_TYPE_IPV4_E_NNI:
1629         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1630                             "C-type: 15 - IPv4 E-NNI");
1631         proto_tree_add_item(rsvp_object_tree,
1632                             hf_rsvp_filter[RSVPF_SESSION_IP],
1633                             tvb, offset2, 4, FALSE);
1634
1635         proto_tree_add_item(rsvp_object_tree,
1636                             hf_rsvp_filter[RSVPF_SESSION_TUNNEL_ID],
1637                             tvb, offset2+6, 2, FALSE);
1638
1639         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
1640                             "Extended IPv4 Address: %s",
1641                             ip_to_str(tvb_get_ptr(tvb, offset2+8, 4)));
1642         hidden_item = proto_tree_add_item(rsvp_object_tree,
1643                                    hf_rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID],
1644                                    tvb, offset2+8, 4, FALSE);
1645         PROTO_ITEM_SET_HIDDEN(hidden_item);
1646
1647         /*
1648          * Save this information to build the conversation request key
1649          * later.
1650          */
1651         rsvph->session_type = RSVP_SESSION_TYPE_IPV4_E_NNI;
1652         SET_ADDRESS(&rsvph->destination, AT_IPv4, 4,
1653                     tvb_get_ptr(tvb, offset2, 4));
1654         rsvph->udp_dest_port = tvb_get_ntohs(tvb, offset2+6);
1655         rsvph->ext_tunnel_id = tvb_get_ntohl(tvb, offset2 + 8);
1656
1657         break;
1658
1659     default:
1660         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1661                             "C-type: Unknown (%u)",
1662                             type);
1663         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length-4,
1664                             "Data (%d bytes)", obj_length-4);
1665     }
1666 }
1667
1668
1669 /*------------------------------------------------------------------------------
1670  * TLVs for HOP, ERROR and other IF_ID extended objects
1671  *------------------------------------------------------------------------------*/
1672 static void
1673 dissect_rsvp_ifid_tlv (proto_tree *ti, proto_tree *rsvp_object_tree,
1674                        tvbuff_t *tvb, int offset, int obj_length,
1675                        int subtree_type)
1676 {
1677     int     tlv_off;
1678     guint16   tlv_type;
1679     guint     tlv_len;
1680     const char *ifindex_name;
1681     proto_tree *rsvp_ifid_subtree, *ti2;
1682     int       offset2 = offset + 4;
1683
1684     for (tlv_off = 0; tlv_off < obj_length - 12; ) {
1685         tlv_type = tvb_get_ntohs(tvb, offset+tlv_off);
1686         tlv_len = tvb_get_ntohs(tvb, offset+tlv_off+2);
1687
1688         if (tlv_len == 0) {
1689             proto_tree_add_text(rsvp_object_tree, tvb, offset+tlv_off+2, 2,
1690                 "Invalid length (0)");
1691             return;
1692         }
1693         switch(tlv_type) {
1694         case 1:
1695             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1696                                       offset+tlv_off, 8,
1697                                       "IPv4 TLV - %s",
1698                                       ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)));
1699
1700             rsvp_ifid_subtree = proto_item_add_subtree(ti2, subtree_type);
1701             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off, 2,
1702                                 "Type: 1 (IPv4)");
1703             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off+2, 2,
1704                                 "Length: %u",
1705                                 tvb_get_ntohs(tvb, offset+tlv_off+2));
1706             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off+4, 4,
1707                                 "IPv4 address: %s",
1708                                 ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)));
1709             proto_item_append_text(ti, "Data IPv4: %s. ",
1710                                    ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)));
1711             break;
1712
1713         case 3:
1714             ifindex_name = "";
1715             goto ifid_ifindex;
1716         case 4:
1717             ifindex_name = " Forward";
1718             goto ifid_ifindex;
1719         case 5:
1720             ifindex_name = " Reverse";
1721         ifid_ifindex:
1722             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
1723                                       offset+tlv_off, 12,
1724                                       "Interface-Index%s TLV - %s, %d",
1725                                       ifindex_name,
1726                                       ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)),
1727                                       tvb_get_ntohl(tvb, offset+tlv_off+8));
1728             rsvp_ifid_subtree = proto_item_add_subtree(ti2, subtree_type);
1729             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off, 2,
1730                                 "Type: %d (Interface Index%s)", tlv_type, ifindex_name);
1731             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off+2, 2,
1732                                 "Length: %u",
1733                                 tvb_get_ntohs(tvb, offset+tlv_off+2));
1734             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off+4, 4,
1735                                 "IPv4 address: %s",
1736                                 ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)));
1737             proto_tree_add_text(rsvp_ifid_subtree, tvb, offset+tlv_off+8, 4,
1738                                 "Interface-ID: %d",
1739                                 tvb_get_ntohl(tvb, offset+tlv_off+8));
1740             proto_item_append_text(ti, "Data If-Index%s: %s, %d. ", ifindex_name,
1741                                    ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)),
1742                                    tvb_get_ntohl(tvb, offset+tlv_off+8));
1743             break;
1744
1745         default:
1746             proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1747                                 "Logical interface: %u",
1748                                 tvb_get_ntohl(tvb, offset2+4));
1749         }
1750         tlv_off += tlv_len;
1751     }
1752 }
1753
1754 /*------------------------------------------------------------------------------
1755  * HOP
1756  *------------------------------------------------------------------------------*/
1757 static void
1758 dissect_rsvp_hop (proto_item *ti, proto_tree *rsvp_object_tree,
1759                   tvbuff_t *tvb,
1760                   int offset, int obj_length,
1761                   int class _U_, int type)
1762 {
1763     int offset2 = offset + 4;
1764
1765     switch(type) {
1766     case 1:
1767         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1768                             "C-type: 1 - IPv4");
1769         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
1770                             "Neighbor address: %s",
1771                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1772         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1773                             "Logical interface: %u",
1774                             tvb_get_ntohl(tvb, offset2+4));
1775         proto_item_set_text(ti, "HOP: IPv4, %s",
1776                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1777         break;
1778
1779     case 2:
1780         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1781                             "C-type: 2 - IPv6");
1782         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
1783                             "Neighbor address: %s",
1784                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1785         proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 4,
1786                             "Logical interface: 0x%08x",
1787                             tvb_get_ntohl(tvb, offset2+16));
1788         break;
1789
1790     case 3:
1791         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1792                             "C-type: 3 - IPv4 IF-ID");
1793         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
1794                             "Neighbor address: %s",
1795                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1796         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
1797                             "Logical interface: %u",
1798                             tvb_get_ntohl(tvb, offset2+4));
1799
1800         proto_item_set_text(ti, "HOP: IPv4 IF-ID. Control IPv4: %s. ",
1801                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1802
1803         dissect_rsvp_ifid_tlv(ti, rsvp_object_tree, tvb, offset+12, obj_length,
1804                               TREE(TT_HOP_SUBOBJ));
1805
1806         break;
1807
1808     default:
1809         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1810                             "C-type: Unknown (%u)",
1811                             type);
1812         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
1813                             "Data (%d bytes)", obj_length - 4);
1814     }
1815 }
1816
1817 /*------------------------------------------------------------------------------
1818  * TIME VALUES
1819  *------------------------------------------------------------------------------*/
1820 static void
1821 dissect_rsvp_time_values (proto_item *ti, proto_tree *rsvp_object_tree,
1822                           tvbuff_t *tvb,
1823                           int offset, int obj_length,
1824                           int class _U_, int type)
1825 {
1826     int offset2 = offset + 4;
1827
1828     switch(type) {
1829     case 1:
1830         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1831                             "C-type: 1");
1832         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
1833                             "Refresh interval: %u ms (%u seconds)",
1834                             tvb_get_ntohl(tvb, offset2),
1835                             tvb_get_ntohl(tvb, offset2)/1000);
1836         proto_item_set_text(ti, "TIME VALUES: %d ms",
1837                             tvb_get_ntohl(tvb, offset2));
1838         break;
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, obj_length - 4,
1845                             "Data (%d bytes)", obj_length - 4);
1846         break;
1847     }
1848 }
1849
1850 /*------------------------------------------------------------------------------
1851  * Error value field in ERROR object
1852  *------------------------------------------------------------------------------*/
1853 static guint16
1854 dissect_rsvp_error_value (proto_tree *ti, tvbuff_t *tvb,
1855                           int offset, guint8 error_code)
1856 {
1857     guint16 error_val;
1858     const value_string *rsvp_error_vals = NULL;
1859
1860     error_val = tvb_get_ntohs(tvb, offset);
1861     switch (error_code) {
1862     case RSVP_ERROR_ADMISSION:
1863         rsvp_error_vals = rsvp_admission_control_error_vals;
1864         break;
1865     case RSVP_ERROR_TRAFFIC:
1866         rsvp_error_vals = rsvp_traffic_control_error_vals;
1867         break;
1868     case RSVP_ERROR_ROUTING:
1869         rsvp_error_vals = rsvp_routing_error_vals;
1870         break;
1871     case RSVP_ERROR_NOTIFY:
1872         rsvp_error_vals = rsvp_notify_error_vals;
1873         break;
1874     case RSVP_ERROR_DIFFSERV:
1875         rsvp_error_vals = rsvp_diffserv_error_vals;
1876         break;
1877     case RSVP_ERROR_DSTE:
1878         rsvp_error_vals = rsvp_diffserv_aware_te_error_vals;
1879         break;
1880     }
1881     switch (error_code) {
1882     case RSVP_ERROR_ADMISSION:
1883     case RSVP_ERROR_TRAFFIC:
1884     case RSVP_ERROR_NOTIFY:
1885     case RSVP_ERROR_ROUTING:
1886     case RSVP_ERROR_DIFFSERV:
1887     case RSVP_ERROR_DSTE:
1888         if ((error_val & 0xc0) == 0) {
1889             proto_tree_add_text(ti, tvb, offset, 2,
1890                 "Error value: %u - %s", error_val,
1891                 val_to_str(error_val, rsvp_error_vals, "Unknown (%d)"));
1892             break;
1893         }
1894     default:
1895         proto_tree_add_text(ti, tvb, offset, 2,
1896             "Error value: %u", error_val);
1897     }
1898     return error_val;
1899 }
1900
1901 /*------------------------------------------------------------------------------
1902  * ERROR
1903  *------------------------------------------------------------------------------*/
1904 static void
1905 dissect_rsvp_error (proto_item *ti, proto_tree *rsvp_object_tree,
1906                     tvbuff_t *tvb,
1907                     int offset, int obj_length,
1908                     int class _U_, int type)
1909 {
1910     int offset2 = offset + 4;
1911     int offset3;
1912     guint8 error_flags;
1913     guint8 error_code;
1914     guint16 error_val;
1915     proto_tree *ti2, *rsvp_error_subtree;
1916
1917     switch(type) {
1918     case 1: {
1919         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1920                             "C-type: 1 - IPv4");
1921         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
1922                             "Error node: %s",
1923                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1924         offset3 = offset2+4;
1925         break;
1926     }
1927
1928     case 2: {
1929         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1930                             "C-type: 2 - IPv6");
1931         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
1932                             "Error node: %s",
1933                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
1934         offset3 = offset2+16;
1935         break;
1936     }
1937
1938     case 3: {
1939         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1940                             "C-type: 3 - IPv4 IF-ID");
1941         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
1942                             "Error node: %s",
1943                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1944         offset3 = offset2+4;
1945         break;
1946     }
1947
1948     default:
1949         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
1950                             "C-type: Unknown (%u)",
1951                             type);
1952         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
1953                             "Data (%d bytes)", obj_length - 4);
1954         return;
1955     }
1956
1957     error_flags = tvb_get_guint8(tvb, offset3);
1958     ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset3, 1,
1959                               "Flags: 0x%02x", error_flags);
1960     rsvp_error_subtree = proto_item_add_subtree(ti2, TREE(TT_ERROR_FLAGS));
1961     proto_tree_add_text(rsvp_error_subtree, tvb, offset3, 1, "%s", 
1962                     decode_boolean_bitfield(error_flags, 0x04, 8,
1963                                             "Path State Removed",
1964                                             ""));
1965     proto_tree_add_text(rsvp_error_subtree, tvb, offset3, 1, "%s",
1966                     decode_boolean_bitfield(error_flags, 0x02, 8,
1967                                             "NotGuilty",
1968                                             ""));
1969     proto_tree_add_text(rsvp_error_subtree, tvb, offset3, 1, "%s",
1970                     decode_boolean_bitfield(error_flags, 0x01, 8,
1971                                             "InPlace",
1972                                             ""));
1973     proto_item_append_text(ti2, " %s %s %s",
1974                            (error_flags & (1<<2))  ? "Path-State-Removed" : "",
1975                            (error_flags & (1<<1))  ? "NotGuilty" : "",
1976                            (error_flags & (1<<0))  ? "InPlace" : "");
1977     error_code = tvb_get_guint8(tvb, offset3+1);
1978     proto_tree_add_text(rsvp_object_tree, tvb, offset3+1, 1,
1979                         "Error code: %u - %s", error_code,
1980                         val_to_str(error_code, rsvp_error_codes, "Unknown (%d)"));
1981     error_val = dissect_rsvp_error_value(rsvp_object_tree, tvb, offset3+2, error_code);
1982
1983     switch (type) {
1984     case 1:
1985         proto_item_set_text(ti, "ERROR: IPv4, Error code: %s, Value: %d, Error Node: %s",
1986                             val_to_str(error_code, rsvp_error_codes, "Unknown (%d)"),
1987                             error_val, ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1988         break;
1989     case 3:
1990         proto_item_set_text(ti, "ERROR: IPv4 IF-ID, Error code: %s, Value: %d, Control Node: %s. ",
1991                             val_to_str(error_code, rsvp_error_codes, "Unknown (%d)"),
1992                             error_val, ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
1993         dissect_rsvp_ifid_tlv(ti, rsvp_object_tree, tvb, offset+12, obj_length,
1994                               TREE(TT_ERROR_SUBOBJ));
1995         break;
1996     }
1997 }
1998
1999 /*------------------------------------------------------------------------------
2000  * SCOPE
2001  *------------------------------------------------------------------------------*/
2002 static void
2003 dissect_rsvp_scope (proto_item *ti _U_, proto_tree *rsvp_object_tree,
2004                     tvbuff_t *tvb,
2005                     int offset, int obj_length,
2006                     int class _U_, int type)
2007 {
2008     int offset2 = offset + 4;
2009     int mylen;
2010
2011     mylen = obj_length - 4;
2012     switch(type) {
2013     case 1: {
2014         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2015                             "C-type: 1 - IPv4");
2016         while (mylen > 0) {
2017             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
2018                                 "IPv4 Address: %s",
2019                                 ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
2020             offset2 += 4;
2021             mylen -= 4;
2022         }
2023         break;
2024     }
2025
2026     case 2: {
2027         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2028                             "C-type: 2 - IPv6");
2029         while (mylen > 0) {
2030             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
2031                                 "IPv6 Address: %s",
2032                                 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
2033             offset2 += 16;
2034             mylen -= 16;
2035         }
2036         break;
2037     }
2038
2039     default:
2040         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2041                             "C-type: Unknown (%u)",
2042                             type);
2043         proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
2044                             "Data (%d bytes)", mylen);
2045     }
2046 }
2047
2048 /*------------------------------------------------------------------------------
2049  * STYLE
2050  *------------------------------------------------------------------------------*/
2051 static void
2052 dissect_rsvp_style (proto_item *ti, proto_tree *rsvp_object_tree,
2053                     tvbuff_t *tvb,
2054                     int offset, int obj_length,
2055                     int class _U_, int type)
2056 {
2057     int offset2 = offset + 4;
2058
2059     switch(type) {
2060     case 1: {
2061         guint32 style;
2062
2063         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2064                             "C-type: 1");
2065         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2066                             "Flags: 0x%02x",
2067                             tvb_get_guint8(tvb, offset2));
2068         style = tvb_get_ntoh24(tvb, offset2+1);
2069         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1,
2070                             3, "Style: 0x%06X - %s", style,
2071                             val_to_str(style, style_vals, "Unknown"));
2072         proto_item_set_text(ti, "STYLE: %s (%d)",
2073                             val_to_str(style, style_vals, "Unknown"),
2074                             style);
2075         break;
2076     }
2077
2078     default:
2079         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2080                             "C-type: Unknown (%u)",
2081                             type);
2082         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
2083                             "Data (%d bytes)", obj_length - 4);
2084         break;
2085     }
2086 }
2087
2088 /*------------------------------------------------------------------------------
2089  * CONFIRM
2090  *------------------------------------------------------------------------------*/
2091 static void
2092 dissect_rsvp_confirm (proto_item *ti, proto_tree *rsvp_object_tree,
2093                       tvbuff_t *tvb,
2094                       int offset, int obj_length,
2095                       int class _U_, int type)
2096 {
2097     int offset2 = offset + 4;
2098
2099     switch(type) {
2100     case 1: {
2101         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2102                             "C-type: 1 - IPv4");
2103         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
2104                             "Receiver address: %s",
2105                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
2106         proto_item_set_text(ti, "CONFIRM: Receiver %s",
2107                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
2108         break;
2109     }
2110
2111     case 2: {
2112         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2113                             "C-type: 2 - IPv6");
2114         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
2115                             "Receiver address: %s",
2116                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
2117         break;
2118     }
2119
2120     default:
2121         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2122                             "C-type: Unknown (%u)",
2123                             type);
2124         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
2125                             "Data (%d bytes)", obj_length - 4);
2126     }
2127 }
2128
2129 /*------------------------------------------------------------------------------
2130  * SENDER TEMPLATE and FILTERSPEC
2131  *------------------------------------------------------------------------------*/
2132 static void
2133 dissect_rsvp_template_filter (proto_item *ti, proto_tree *rsvp_object_tree,
2134                               tvbuff_t *tvb,
2135                               int offset, int obj_length,
2136                               int class _U_, int type,
2137                               rsvp_conversation_info *rsvph)
2138 {
2139     int offset2 = offset + 4;
2140
2141     proto_item_set_text(ti, "%s", summary_template(tvb, offset));
2142     switch(type) {
2143     case 1:
2144          proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2145                              "C-type: 1 - IPv4");
2146          proto_tree_add_item(rsvp_object_tree,
2147                              hf_rsvp_filter[RSVPF_SENDER_IP],
2148                              tvb, offset2, 4, FALSE);
2149          proto_tree_add_item(rsvp_object_tree,
2150                              hf_rsvp_filter[RSVPF_SENDER_PORT],
2151                              tvb, offset2+6, 2, FALSE);
2152
2153          /*
2154           * Save this information to build the conversation request key later.
2155           */
2156          SET_ADDRESS(&rsvph->source, AT_IPv4, 4, tvb_get_ptr(tvb, offset2, 4));
2157          rsvph->udp_source_port = tvb_get_ntohs(tvb, offset2+6);
2158          break;
2159
2160      case 2:
2161          proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2162                              "C-type: 2 - IPv6");
2163          proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
2164                              "Source address: %s",
2165                              ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
2166          proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2,
2167                              "Source port: %u",
2168                              tvb_get_ntohs(tvb, offset2+18));
2169          break;
2170
2171      case 7:
2172          proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2173                              "C-type: 7 - IPv4 LSP");
2174          proto_tree_add_item(rsvp_object_tree,
2175                              hf_rsvp_filter[RSVPF_SENDER_IP],
2176                              tvb, offset2, 4, FALSE);
2177          proto_tree_add_item(rsvp_object_tree,
2178                              hf_rsvp_filter[RSVPF_SENDER_LSP_ID],
2179                              tvb, offset2+6, 2, FALSE);
2180
2181          /*
2182           * Save this information to build the conversation request key later.
2183           */
2184          SET_ADDRESS(&rsvph->source, AT_IPv4, 4, tvb_get_ptr(tvb, offset2, 4));
2185          rsvph->udp_source_port = tvb_get_ntohs(tvb, offset2+6);
2186          break;
2187
2188     case 9:
2189          proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2190                              "C-type: 9 - IPv4 Aggregate");
2191          proto_tree_add_item(rsvp_object_tree,
2192                              hf_rsvp_filter[RSVPF_SENDER_IP],
2193                              tvb, offset2, 4, FALSE);
2194
2195          /*
2196           * Save this information to build the conversation request key later.
2197           */
2198          SET_ADDRESS(&rsvph->source, AT_IPv4, 4, tvb_get_ptr(tvb, offset2, 4));
2199          break;
2200
2201      default:
2202          proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2203                              "C-type: Unknown (%u)",
2204                              type);
2205          proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
2206                              "Data (%d bytes)", obj_length - 4);
2207      }
2208 }
2209
2210 /*------------------------------------------------------------------------------
2211  * TLVs for Ethernet SENDER TSPEC and FLOWSPEC
2212  * draft-ietf-ccamp-ethernet-traffic-parameters-02
2213  *------------------------------------------------------------------------------*/
2214 static void
2215 dissect_rsvp_eth_tspec_tlv(proto_item *ti, proto_tree *rsvp_object_tree,
2216                            tvbuff_t *tvb, int offset, int tlv_length,
2217                            int subtree_type)
2218 {
2219     int       tlv_off;
2220     guint16   tlv_type;
2221     int       tlv_len;
2222     guint8    profile;
2223     proto_tree *rsvp_ethspec_subtree, *ethspec_profile_subtree, *ti2, *ti3;
2224
2225     for (tlv_off = 0; tlv_off < tlv_length; ) {
2226         tlv_type = tvb_get_ntohs(tvb, offset+tlv_off);
2227         tlv_len = tvb_get_ntohs(tvb, offset+tlv_off+2);
2228
2229         if (tlv_len == 0 || tlv_off+tlv_len > tlv_length) {
2230             proto_tree_add_text(rsvp_object_tree, tvb, offset+tlv_off+2, 2,
2231                                 "Invalid length");
2232             return;
2233         }
2234         switch(tlv_type) {
2235         case 128:
2236             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2237                                       offset+tlv_off, tlv_len,
2238                                       "RESERVED (TBD)");
2239             rsvp_ethspec_subtree = proto_item_add_subtree(ti2, subtree_type);
2240             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off, 2,
2241                                 "Type: 128 (RESERVED)");
2242             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+2, 2,
2243                                 "Length: %u", tlv_len);
2244             break;
2245             
2246         case 129:
2247             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2248                                       offset+tlv_off, tlv_len,
2249                                       "Ethernet Bandwidth Profile TLV: CIR=%.10g, CBS=%.10g, "
2250                                       "EIR=%.10g, EBS=%.10g",
2251                                       tvb_get_ntohieee_float(tvb, offset+tlv_off+8),
2252                                       tvb_get_ntohieee_float(tvb, offset+tlv_off+12),
2253                                       tvb_get_ntohieee_float(tvb, offset+tlv_off+16),
2254                                       tvb_get_ntohieee_float(tvb, offset+tlv_off+20));
2255             rsvp_ethspec_subtree = proto_item_add_subtree(ti2, subtree_type);
2256             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off, 2,
2257                                 "Type: %d - Ethernet Bandwidth Profile", tlv_type);
2258             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+2, 2,
2259                                 "Length: %u", tlv_len);
2260             profile = tvb_get_guint8(tvb, offset+tlv_off+4);
2261             ti3 = proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+4, 1,
2262                                       "Profile: 0x%02x", profile);
2263             ethspec_profile_subtree = proto_item_add_subtree(ti3, TREE(TT_ETHSPEC_SUBTREE));
2264             proto_tree_add_text(ethspec_profile_subtree, tvb, offset+tlv_off+4, 1, "%s",
2265                                 decode_boolean_bitfield(profile, 0x02, 8,
2266                                             "Color Mode (CM) set",
2267                                             "Color Mode (CM) NOT set"));
2268             proto_tree_add_text(ethspec_profile_subtree, tvb, offset+tlv_off+4, 1, "%s",
2269                                 decode_boolean_bitfield(profile, 0x01, 8,
2270                                             "Coupling Flag (CF) set",
2271                                             "Coupling Flag (CF) NOT set"));
2272             proto_item_append_text(ti3, " %s %s",
2273                                    (profile & (1<<1))  ? "CM" : "",
2274                                    (profile & (1<<0))  ? "CF" : "");
2275             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+5, 1,
2276                                 "Index: %x", tvb_get_guint8(tvb, offset+tlv_off+5));
2277             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+6, 2,
2278                                 "Reserved: %x", tvb_get_ntohs(tvb, offset+tlv_off+6));
2279             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+8, 4, "CIR: %.10g",
2280                                 tvb_get_ntohieee_float(tvb, offset+tlv_off+8));
2281             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+12, 4, "CBS: %.10g",
2282                                 tvb_get_ntohieee_float(tvb, offset+tlv_off+12));
2283             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+16, 4, "EIR: %.10g",
2284                                 tvb_get_ntohieee_float(tvb, offset+tlv_off+16));
2285             proto_tree_add_text(rsvp_ethspec_subtree, tvb, offset+tlv_off+20, 4, "EBS: %.10g",
2286                                 tvb_get_ntohieee_float(tvb, offset+tlv_off+20));
2287
2288             proto_item_append_text(ti, "ETH profile: CIR=%.10g, CBS=%.10g, EIR=%.10g, "
2289                                        "EBS=%.10g",
2290                                    tvb_get_ntohieee_float(tvb, offset+tlv_off+8),
2291                                    tvb_get_ntohieee_float(tvb, offset+tlv_off+12),
2292                                    tvb_get_ntohieee_float(tvb, offset+tlv_off+16),
2293                                    tvb_get_ntohieee_float(tvb, offset+tlv_off+20));
2294             break;
2295             
2296         default:
2297             proto_tree_add_text(rsvp_object_tree, tvb, offset+tlv_off, 2,
2298                                 "Unknown TLV: %u", tlv_type);
2299         }
2300         tlv_off += tlv_len;
2301     }
2302 }
2303
2304 /*------------------------------------------------------------------------------
2305  * SENDER TSPEC
2306  *------------------------------------------------------------------------------*/
2307 static void
2308 dissect_rsvp_tspec (proto_item *ti, proto_tree *rsvp_object_tree,
2309                     tvbuff_t *tvb,
2310                     int offset, int obj_length,
2311                     int class _U_, int type)
2312 {
2313     int offset2 = offset + 4;
2314     int mylen;
2315     proto_tree *tspec_tree, *ti2;
2316     guint8 signal_type;
2317     guint16 switch_gran;
2318
2319     mylen = obj_length - 4;
2320
2321     switch(type) {
2322     case 2:
2323         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2324                             "C-type: 2 - Integrated Services");
2325         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2326                             "Message format version: %u",
2327                             tvb_get_guint8(tvb, offset2)>>4);
2328         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2329                             "Data length: %u words, not including header",
2330                             tvb_get_ntohs(tvb, offset2+2));
2331
2332         mylen -= 4;
2333         offset2 += 4;
2334
2335         proto_item_set_text(ti, "SENDER TSPEC: IntServ, ");
2336
2337         while (mylen > 0) {
2338             guint8 service_num;
2339             guint8 param_id;
2340             guint param_len;
2341             guint param_len_processed;
2342             guint length;
2343
2344             service_num = tvb_get_guint8(tvb, offset2);
2345             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2346                                 "Service header: %u - %s",
2347                                 service_num,
2348                                 val_to_str(service_num, qos_vals, "Unknown"));
2349             length = tvb_get_ntohs(tvb, offset2+2);
2350             proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2351                                 "Length of service %u data: %u words, "
2352                                 "not including header",
2353                                 service_num, length);
2354
2355             mylen -= 4;
2356             offset2 += 4;
2357
2358             /* Process all known service headers as a set of parameters */
2359             param_len_processed = 0;
2360             while (param_len_processed < length) {
2361                 param_id = tvb_get_guint8(tvb, offset2);
2362                 param_len = tvb_get_ntohs(tvb, offset2+2) + 1;
2363                 if (param_len < 1)
2364                     THROW(ReportedBoundsError);
2365                 switch(param_id) {
2366                 case 127:
2367                     /* Token Bucket */
2368                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2369                                               offset2, param_len*4,
2370                                               "Token Bucket TSpec: ");
2371                     tspec_tree = proto_item_add_subtree(ti2, TREE(TT_TSPEC_SUBTREE));
2372
2373                     proto_tree_add_text(tspec_tree, tvb, offset2, 1,
2374                                         "Parameter %u - %s",
2375                                         param_id,
2376                                         val_to_str(param_id, svc_vals, "Unknown"));
2377                     proto_tree_add_text(tspec_tree, tvb, offset2+1, 1,
2378                                         "Parameter %u flags: 0x%02x",
2379                                         param_id,
2380                                         tvb_get_guint8(tvb, offset2+1));
2381                     proto_tree_add_text(tspec_tree, tvb, offset2+2, 2,
2382                                         "Parameter %u data length: %u words, "
2383                                         "not including header",
2384                                         param_id,
2385                                         tvb_get_ntohs(tvb, offset2+2));
2386                     proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
2387                                         "Token bucket rate: %.10g",
2388                                         tvb_get_ntohieee_float(tvb, offset2+4));
2389                     proto_tree_add_text(tspec_tree, tvb, offset2+8, 4,
2390                                         "Token bucket size: %.10g",
2391                                         tvb_get_ntohieee_float(tvb, offset2+8));
2392                     proto_tree_add_text(tspec_tree, tvb, offset2+12, 4,
2393                                         "Peak data rate: %.10g",
2394                                         tvb_get_ntohieee_float(tvb, offset2+12));
2395                     proto_tree_add_text(tspec_tree, tvb, offset2+16, 4,
2396                                         "Minimum policed unit [m]: %u",
2397                                         tvb_get_ntohl(tvb, offset2+16));
2398                     proto_tree_add_text(tspec_tree, tvb, offset2+20, 4,
2399                                         "Maximum packet size [M]: %u",
2400                                         tvb_get_ntohl(tvb, offset2+20));
2401                     proto_item_append_text(ti, "Token Bucket, %.10g bytes/sec. ",
2402                                            tvb_get_ntohieee_float(tvb, offset2+4));
2403                     proto_item_append_text(ti2, "Rate=%.10g Burst=%.10g Peak=%.10g m=%u M=%u",
2404                                            tvb_get_ntohieee_float(tvb, offset2+4),
2405                                            tvb_get_ntohieee_float(tvb, offset2+8),
2406                                            tvb_get_ntohieee_float(tvb, offset2+12),
2407                                            tvb_get_ntohl(tvb, offset2+16),
2408                                            tvb_get_ntohl(tvb, offset2+20));
2409                     break;
2410
2411                 case 128:
2412                     /* Null Service (RFC2997) */
2413                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2414                                               offset2, param_len*4,
2415                                               "Null Service TSpec: ");
2416                     tspec_tree = proto_item_add_subtree(ti2, TREE(TT_TSPEC_SUBTREE));
2417
2418                     proto_tree_add_text(tspec_tree, tvb, offset2, 1,
2419                                         "Parameter %u - %s",
2420                                         param_id,
2421                                         val_to_str(param_id, svc_vals, "Unknown"));
2422                     proto_tree_add_text(tspec_tree, tvb, offset2+1, 1,
2423                                         "Parameter %u flags: %x",
2424                                         param_id,
2425                                         tvb_get_guint8(tvb, offset2+1));
2426                     proto_tree_add_text(tspec_tree, tvb, offset2+2, 2,
2427                                         "Parameter %u data length: %u words, "
2428                                         "not including header",
2429                                         param_id,
2430                                         tvb_get_ntohs(tvb, offset2+2));
2431                     proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
2432                                         "Maximum packet size [M]: %u",
2433                                         tvb_get_ntohl(tvb, offset2+4));
2434                     proto_item_append_text(ti, "Null Service. M=%u",
2435                                            tvb_get_ntohl(tvb, offset2+4));
2436                     proto_item_append_text(ti2, "Max pkt size=%u",
2437                                            tvb_get_ntohl(tvb, offset2+4));
2438                     break;
2439
2440                 case 126:
2441                     /* Compression hint (RFC3006) */
2442                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2443                                               offset2, param_len*4,
2444                                               "Compression Hint: ");
2445                     tspec_tree = proto_item_add_subtree(ti2, TREE(TT_TSPEC_SUBTREE));
2446
2447                     proto_tree_add_text(tspec_tree, tvb, offset2, 1,
2448                                         "Parameter %u - %s",
2449                                         param_id,
2450                                         val_to_str(param_id, svc_vals, "Unknown"));
2451                     proto_tree_add_text(tspec_tree, tvb, offset2+1, 1,
2452                                         "Parameter %u flags: %x",
2453                                         param_id,
2454                                         tvb_get_guint8(tvb, offset2+1));
2455                     proto_tree_add_text(tspec_tree, tvb, offset2+2, 2,
2456                                         "Parameter %u data length: %u words, "
2457                                         "not including header",
2458                                         param_id,
2459                                         tvb_get_ntohs(tvb, offset2+2));
2460                     proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
2461                                         "Hint: %u",
2462                                         tvb_get_ntohl(tvb, offset2+4));
2463                     proto_tree_add_text(tspec_tree, tvb, offset2+4, 4,
2464                                         "Compression Factor: %u",
2465                                         tvb_get_ntohl(tvb, offset2+8));
2466                     proto_item_append_text(ti, "Compression Hint. Hint=%u, Factor=%u",
2467                                            tvb_get_ntohl(tvb, offset2+4),
2468                                            tvb_get_ntohl(tvb, offset2+8));
2469                     proto_item_append_text(ti2, "Hint=%u, Factor=%u",
2470                                            tvb_get_ntohl(tvb, offset2+4),
2471                                            tvb_get_ntohl(tvb, offset2+8));
2472                     break;
2473
2474                 default:
2475                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4,
2476                                         "Unknown parameter %d, %d words",
2477                                         param_id, param_len);
2478                     break;
2479                 }
2480                 param_len_processed += param_len;
2481                 offset2 += param_len*4;
2482             }
2483             mylen -= length*4;
2484         }
2485         break;
2486
2487     case 4: /* SONET/SDH Tspec */
2488         proto_item_set_text(ti, "SENDER TSPEC: SONET/SDH, ");
2489
2490         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2491                             "C-type: 4 - SONET/SDH");
2492         signal_type = tvb_get_guint8(tvb, offset2);
2493         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2494                             "Signal Type: %d - %s", signal_type,
2495                             val_to_str(signal_type,
2496                                        gmpls_sonet_signal_type_str, "Unknown"));
2497         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
2498                             "Requested Concatenation (RCC): %d", tvb_get_guint8(tvb, offset2+1));
2499         tspec_tree = proto_item_add_subtree(ti2, TREE(TT_TSPEC_SUBTREE));
2500         proto_tree_add_text(tspec_tree, tvb, offset2+1, 1, "%s",
2501                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+1), 0x01, 8,
2502                                                     "Standard contiguous concatenation",
2503                                                     "No standard contiguous concatenation"));
2504         proto_tree_add_text(tspec_tree, tvb, offset2+1, 1, "%s",
2505                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+1), 0x02, 8,
2506                                                     "Arbitrary contiguous concatenation",
2507                                                     "No arbitrary contiguous concatenation"));
2508         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2509                             "Number of Contiguous Components (NCC): %d", tvb_get_ntohs(tvb, offset2+2));
2510         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 2,
2511                             "Number of Virtual Components (NVC): %d", tvb_get_ntohs(tvb, offset2+4));
2512         proto_tree_add_text(rsvp_object_tree, tvb, offset2+6, 2,
2513                             "Multiplier (MT): %d", tvb_get_ntohs(tvb, offset2+6));
2514         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
2515                                   "Transparency (T): 0x%0x", tvb_get_ntohl(tvb, offset2+8));
2516         tspec_tree = proto_item_add_subtree(ti2, TREE(TT_TSPEC_SUBTREE));
2517         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2518                             decode_boolean_bitfield(tvb_get_ntohl(tvb, offset2+8), 0x0001, 32,
2519                                                     "Section/Regenerator Section layer transparency",
2520                                                     "No Section/Regenerator Section layer transparency"));
2521         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2522                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0002, 32,
2523                                                     "Line/Multiplex Section layer transparency",
2524                                                     "No Line/Multiplex Section layer transparency"));
2525         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2526                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0004, 32,
2527                                                     "J0 transparency",
2528                                                     "No J0 transparency"));
2529         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2530                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0008, 32,
2531                                                     "SOH/RSOH DCC transparency",
2532                                                     "No SOH/RSOH DCC transparency"));
2533         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2534                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0010, 32,
2535                                                     "LOH/MSOH DCC transparency",
2536                                                     "No LOH/MSOH DCC transparency"));
2537         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2538                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0020, 32,
2539                                                     "LOH/MSOH Extended DCC transparency",
2540                                                     "No LOH/MSOH Extended DCC transparency"));
2541         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2542                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0040, 32,
2543                                                     "K1/K2 transparency",
2544                                                     "No K1/K2 transparency"));
2545         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2546                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0080, 32,
2547                                                     "E1 transparency",
2548                                                     "No E1 transparency"));
2549         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2550                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0100, 32,
2551                                                     "F1 transparency",
2552                                                     "No F1 transparency"));
2553         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2554                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0200, 32,
2555                                                     "E2 transparency",
2556                                                     "No E2 transparency"));
2557         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2558                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0400, 32,
2559                                                     "B1 transparency",
2560                                                     "No B1 transparency"));
2561         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2562                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0800, 32,
2563                                                     "B2 transparency",
2564                                                     "No B2 transparency"));
2565         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2566                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x1000, 32,
2567                                                     "M0 transparency",
2568                                                     "No M0 transparency"));
2569         proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "%s",
2570                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x2000, 32,
2571                                                     "M1 transparency",
2572                                                     "No M1 transparency"));
2573         proto_tree_add_text(rsvp_object_tree, tvb, offset2+12, 4,
2574                             "Profile (P): %d", tvb_get_ntohl(tvb, offset2+12));
2575
2576         proto_item_append_text(ti, "Signal [%s], RCC %d, NCC %d, NVC %d, MT %d, Transparency %d, Profile %d",
2577                                val_to_str(signal_type, gmpls_sonet_signal_type_str, "Unknown"),
2578                                tvb_get_guint8(tvb, offset2+1), tvb_get_ntohs(tvb, offset2+2),
2579                                tvb_get_ntohs(tvb, offset2+4), tvb_get_ntohs(tvb, offset2+6),
2580                                tvb_get_ntohl(tvb, offset2+8), tvb_get_ntohl(tvb, offset2+12));
2581         break;
2582
2583     case 5: /* FF: G.709 TSPEC, RFC 4328 */
2584         proto_item_set_text(ti, "SENDER TSPEC: G.709, ");
2585
2586         proto_tree_add_text(rsvp_object_tree, tvb, offset + 3, 1,
2587                             "C-type: 5 - G.709");
2588         signal_type = tvb_get_guint8(tvb, offset2);
2589         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2590                             "Signal Type: %d - %s", signal_type,
2591                             rval_to_str(signal_type,
2592                                         gmpls_g709_signal_type_rvals, 
2593                                         "Unknown"));
2594         proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 2, 2,
2595                             "Number of Multiplexed Components (NMC): %d", 
2596                             tvb_get_ntohs(tvb, offset2 + 2));
2597         proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 4, 2,
2598                             "Number of Virtual Components (NVC): %d", 
2599                             tvb_get_ntohs(tvb, offset2 + 4));
2600
2601         proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 6, 2,
2602                             "Multiplier (MT): %d", 
2603                             tvb_get_ntohs(tvb, offset2 + 6));
2604         proto_item_append_text(ti, "Signal [%s], NMC %d, NVC %d, MT %d",
2605                                rval_to_str(signal_type, 
2606                                            gmpls_g709_signal_type_rvals, 
2607                                            "Unknown"),
2608                                tvb_get_ntohs(tvb, offset2 + 2),
2609                                tvb_get_ntohs(tvb, offset2 + 4), 
2610                                tvb_get_ntohs(tvb, offset2 + 6));
2611         break;
2612
2613     case 6:   /* Ethernet TSPEC  draft-ietf-ccamp-ethernet-traffic-parameters-02 */
2614         proto_item_set_text(ti, "SENDER TSPEC: Ethernet, ");
2615         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2616                             "C-type: 6 - Ethernet");
2617         switch_gran = tvb_get_ntohs(tvb, offset2);
2618         if (switch_gran == 1)
2619           proto_tree_add_text(rsvp_object_tree, tvb, offset2, 2,
2620                               "Switching granularity: 1 - Ethernet port");
2621         else if (switch_gran == 2)
2622           proto_tree_add_text(rsvp_object_tree, tvb, offset2, 2,
2623                               "Switching granularity: 2 - Ethernet frame");
2624         else
2625           proto_tree_add_text(rsvp_object_tree, tvb, offset2, 2,
2626                               "Switching granularity: %u - ???", switch_gran);
2627
2628         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2629                             "MTU: %u", tvb_get_ntohs(tvb, offset2+2));
2630
2631         dissect_rsvp_eth_tspec_tlv(ti, rsvp_object_tree, tvb, offset+8, obj_length-8,
2632                                    TREE(TT_TSPEC_SUBTREE));
2633         break;
2634
2635     default: /* Unknown TSpec */
2636         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2637                             "C-type: Unknown (%u)",
2638                             type);
2639         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
2640                             "Data (%d bytes)", obj_length - 4);
2641         break;
2642
2643     }
2644 }
2645
2646 /*------------------------------------------------------------------------------
2647  * FLOWSPEC
2648  *------------------------------------------------------------------------------*/
2649 static void
2650 dissect_rsvp_flowspec (proto_item *ti, proto_tree *rsvp_object_tree,
2651                        tvbuff_t *tvb,
2652                        int offset, int obj_length,
2653                        int class _U_, int type)
2654 {
2655     int offset2 = offset + 4;
2656     int mylen, signal_type;
2657     proto_tree *flowspec_tree, *ti2;
2658     proto_item *item;
2659     guint16 switch_gran;
2660
2661     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2662                         "C-type: %u", type);
2663     mylen = obj_length - 4;
2664
2665     switch(type) {
2666
2667     case 2:
2668         if (mylen < 4) {
2669             item = proto_tree_add_text(rsvp_object_tree, tvb, 0, 0,
2670                                        "Object length %u < 8", obj_length);
2671             PROTO_ITEM_SET_GENERATED(item);
2672             return;
2673         }
2674         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2675                             "Message format version: %u",
2676                             tvb_get_guint8(tvb, offset2)>>4);
2677         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2678                             "Data length: %u words, not including header",
2679                             tvb_get_ntohs(tvb, offset2+2));
2680
2681         proto_item_set_text(ti, "FLOWSPEC: ");
2682
2683         mylen -= 4;
2684         offset2+= 4;
2685         while (mylen > 0) {
2686             guint8 service_num;
2687             guint length;
2688             guint8 param_id;
2689             guint param_len;
2690             guint param_len_processed;
2691
2692             if (mylen < 4) {
2693                 item = proto_tree_add_text(rsvp_object_tree, tvb, 0, 0,
2694                                            "Object length %u not large enough",
2695                                            obj_length);
2696                 PROTO_ITEM_SET_GENERATED(item);
2697                 return;
2698             }
2699             service_num = tvb_get_guint8(tvb, offset2);
2700             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2701                                 "Service header: %u - %s",
2702                                 service_num,
2703                                 val_to_str(service_num, intsrv_services_str, "Unknown"));
2704             length = tvb_get_ntohs(tvb, offset2+2);
2705             proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2706                                 "Length of service %u data: %u words, "
2707                                 "not including header",
2708                                 service_num,
2709                                 length);
2710
2711             mylen -= 4;
2712             offset2 += 4;
2713
2714             proto_item_append_text(ti, "%s: ",
2715                                    val_to_str(service_num, intsrv_services_str,
2716                                               "Unknown (%d)"));
2717
2718             /* Process all known service headers as a set of parameters */
2719             param_len_processed = 0;
2720             while (param_len_processed < length) {
2721                 param_id = tvb_get_guint8(tvb, offset2);
2722                 param_len = tvb_get_ntohs(tvb, offset2+2) + 1;
2723                 if (param_len < 1)
2724                     THROW(ReportedBoundsError);
2725                 switch(param_id) {
2726                 case 127:
2727                     /* Token Bucket */
2728                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2729                                               offset2, param_len*4,
2730                                               "Token Bucket: ");
2731                     flowspec_tree = proto_item_add_subtree(ti2, TREE(TT_FLOWSPEC_SUBTREE));
2732
2733                     proto_tree_add_text(flowspec_tree, tvb, offset2, 1,
2734                                         "Parameter %u - %s",
2735                                         param_id,
2736                                         val_to_str(param_id, svc_vals, "Unknown"));
2737                     proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1,
2738                                         "Parameter %u flags: 0x%02x",
2739                                         param_id,
2740                                         tvb_get_guint8(tvb, offset2+1));
2741                     proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2,
2742                                         "Parameter %u data length: %u words, "
2743                                         "not including header",
2744                                         param_id,
2745                                         tvb_get_ntohs(tvb, offset2+2));
2746                     proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4,
2747                                         "Token bucket rate: %.10g",
2748                                         tvb_get_ntohieee_float(tvb, offset2+4));
2749                     proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4,
2750                                         "Token bucket size: %.10g",
2751                                         tvb_get_ntohieee_float(tvb, offset2+8));
2752                     proto_tree_add_text(flowspec_tree, tvb, offset2+12, 4,
2753                                         "Peak data rate: %.10g",
2754                                         tvb_get_ntohieee_float(tvb, offset2+12));
2755                     proto_tree_add_text(flowspec_tree, tvb, offset2+16, 4,
2756                                         "Minimum policed unit [m]: %u",
2757                                         tvb_get_ntohl(tvb, offset2+16));
2758                     proto_tree_add_text(flowspec_tree, tvb, offset2+20, 4,
2759                                         "Maximum packet size [M]: %u",
2760                                         tvb_get_ntohl(tvb, offset2+20));
2761                     proto_item_append_text(ti, "Token Bucket, %.10g bytes/sec. ",
2762                                            tvb_get_ntohieee_float(tvb, offset2+4));
2763                     proto_item_append_text(ti2, "Rate=%.10g Burst=%.10g Peak=%.10g m=%u M=%u",
2764                                            tvb_get_ntohieee_float(tvb, offset2+4),
2765                                            tvb_get_ntohieee_float(tvb, offset2+8),
2766                                            tvb_get_ntohieee_float(tvb, offset2+12),
2767                                            tvb_get_ntohl(tvb, offset2+16),
2768                                            tvb_get_ntohl(tvb, offset2+20));
2769                     break;
2770
2771                 case 130:
2772                     /* Guaranteed-rate RSpec */
2773                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2774                                               offset2, param_len*4,
2775                                               "Guaranteed-Rate RSpec: ");
2776                     flowspec_tree = proto_item_add_subtree(ti2, TREE(TT_FLOWSPEC_SUBTREE));
2777                     proto_tree_add_text(flowspec_tree, tvb, offset2, 1,
2778                                         "Parameter %u - %s",
2779                                         param_id,
2780                                         val_to_str(param_id, svc_vals, "Unknown"));
2781                     proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1,
2782                                         "Parameter %u flags: %x",
2783                                         param_id,
2784                                         tvb_get_guint8(tvb, offset2+1));
2785                     proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2,
2786                                         "Parameter %u data length: %u words, "
2787                                         "not including header",
2788                                         param_id,
2789                                         tvb_get_ntohs(tvb, offset2+2));
2790
2791                     proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4,
2792                                         "Rate: %.10g",
2793                                         tvb_get_ntohieee_float(tvb, offset2+4));
2794                     proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4,
2795                                         "Slack term: %u",
2796                                         tvb_get_ntohl(tvb, offset2+8));
2797                     proto_item_append_text(ti, "RSpec, %.10g bytes/sec. ",
2798                                            tvb_get_ntohieee_float(tvb, offset2+4));
2799                     proto_item_append_text(ti2, "R=%.10g, s=%u",
2800                                            tvb_get_ntohieee_float(tvb, offset2+4),
2801                                            tvb_get_ntohl(tvb, offset2+8));
2802                     break;
2803
2804                 case 128:
2805                     /* Null Service (RFC2997) */
2806                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
2807                                               offset2, param_len*4,
2808                                               "Null Service Flowspec: ");
2809                     flowspec_tree = proto_item_add_subtree(ti2, TREE(TT_FLOWSPEC_SUBTREE));
2810
2811                     proto_tree_add_text(flowspec_tree, tvb, offset2, 1,
2812                                         "Parameter %u - %s",
2813                                         param_id,
2814                                         val_to_str(param_id, svc_vals, "Unknown"));
2815                     proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1,
2816                                         "Parameter %u flags: %x",
2817                                         param_id,
2818                                         tvb_get_guint8(tvb, offset2+1));
2819                     proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2,
2820                                         "Parameter %u data length: %u words, "
2821                                         "not including header",
2822                                         param_id,
2823                                         tvb_get_ntohs(tvb, offset2+2));
2824                     proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4,
2825                                         "Maximum packet size [M]: %u",
2826                                         tvb_get_ntohl(tvb, offset2+4));
2827                     proto_item_append_text(ti, "Null Service. M=%u",
2828                                            tvb_get_ntohl(tvb, offset2+4));
2829                     proto_item_append_text(ti2, "Max pkt size=%u",
2830                                            tvb_get_ntohl(tvb, offset2+4));
2831                     break;
2832
2833                 default:
2834                     proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4,
2835                                         "Unknown parameter %d, %d words",
2836                                         param_id, param_len);
2837                     break;
2838                 }
2839                 param_len_processed += param_len;
2840                 offset2 += param_len * 4;
2841             }
2842
2843             /* offset2 += length*4; */
2844             mylen -= length*4;
2845         }
2846         break;
2847
2848     case 4:
2849         proto_item_set_text(ti, "FLOWSPEC: SONET/SDH, ");
2850
2851         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2852                             "C-type: 4 - SONET/SDH");
2853         signal_type = tvb_get_guint8(tvb, offset2);
2854         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2855                             "Signal Type: %d - %s", signal_type,
2856                             val_to_str(signal_type,
2857                                        gmpls_sonet_signal_type_str, "Unknown"));
2858         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
2859                                   "Requested Concatenation (RCC): %d", tvb_get_guint8(tvb, offset2+1));
2860         flowspec_tree = proto_item_add_subtree(ti2, TREE(TT_FLOWSPEC_SUBTREE));
2861         proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1, "%s",
2862                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+1), 0x01, 8,
2863                                                     "Standard contiguous concatenation",
2864                                                     "No standard contiguous concatenation"));
2865         proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1, "%s",
2866                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+1), 0x02, 8,
2867                                                     "Arbitrary contiguous concatenation",
2868                                                     "No arbitrary contiguous concatenation"));
2869         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2870                             "Number of Contiguous Components (NCC): %d", tvb_get_ntohs(tvb, offset2+2));
2871         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 2,
2872                             "Number of Virtual Components (NVC): %d", tvb_get_ntohs(tvb, offset2+4));
2873         proto_tree_add_text(rsvp_object_tree, tvb, offset2+6, 2,
2874                             "Multiplier (MT): %d", tvb_get_ntohs(tvb, offset2+6));
2875         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
2876                                   "Transparency (T): 0x%0x", tvb_get_ntohl(tvb, offset2+8));
2877         flowspec_tree = proto_item_add_subtree(ti2, TREE(TT_FLOWSPEC_SUBTREE));
2878         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2879                             decode_boolean_bitfield(tvb_get_ntohl(tvb, offset2+8), 0x0001, 32,
2880                                                     "Section/Regenerator Section layer transparency",
2881                                                     "No Section/Regenerator Section layer transparency"));
2882         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2883                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0002, 32,
2884                                                     "Line/Multiplex Section layer transparency",
2885                                                     "No Line/Multiplex Section layer transparency"));
2886         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2887                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0004, 32,
2888                                                     "J0 transparency",
2889                                                     "No J0 transparency"));
2890         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2891                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0008, 32,
2892                                                     "SOH/RSOH DCC transparency",
2893                                                     "No SOH/RSOH DCC transparency"));
2894         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2895                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0010, 32,
2896                                                     "LOH/MSOH DCC transparency",
2897                                                     "No LOH/MSOH DCC transparency"));
2898         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2899                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0020, 32,
2900                                                     "LOH/MSOH Extended DCC transparency",
2901                                                     "No LOH/MSOH Extended DCC transparency"));
2902         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2903                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0040, 32,
2904                                                     "K1/K2 transparency",
2905                                                     "No K1/K2 transparency"));
2906         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2907                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0080, 32,
2908                                                     "E1 transparency",
2909                                                     "No E1 transparency"));
2910         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2911                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0100, 32,
2912                                                     "F1 transparency",
2913                                                     "No F1 transparency"));
2914         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2915                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0200, 32,
2916                                                     "E2 transparency",
2917                                                     "No E2 transparency"));
2918         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2919                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0400, 32,
2920                                                     "B1 transparency",
2921                                                     "No B1 transparency"));
2922         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2923                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x0800, 32,
2924                                                     "B2 transparency",
2925                                                     "No B2 transparency"));
2926         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2927                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x1000, 32,
2928                                                     "M0 transparency",
2929                                                     "No M0 transparency"));
2930         proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "%s",
2931                             decode_boolean_bitfield(tvb_get_guint8(tvb, offset2+8), 0x2000, 32,
2932                                                     "M1 transparency",
2933                                                     "No M1 transparency"));
2934         proto_tree_add_text(rsvp_object_tree, tvb, offset2+12, 4,
2935                             "Profile (P): %d", tvb_get_ntohl(tvb, offset2+12));
2936
2937         proto_item_append_text(ti, "Signal [%s], RCC %d, NCC %d, NVC %d, MT %d, Transparency %d, Profile %d",
2938                                val_to_str(signal_type, gmpls_sonet_signal_type_str, "Unknown"),
2939                                tvb_get_guint8(tvb, offset2+1), tvb_get_ntohs(tvb, offset2+2),
2940                                tvb_get_ntohs(tvb, offset2+4), tvb_get_ntohs(tvb, offset2+6),
2941                                tvb_get_ntohl(tvb, offset2+8), tvb_get_ntohl(tvb, offset2+12));
2942         break;
2943
2944     case 5: /* FF: G.709 FLOWSPEC, RFC 4328 */
2945         proto_item_set_text(ti, "FLOWSPEC: G.709, ");
2946
2947         proto_tree_add_text(rsvp_object_tree, tvb, offset + 3, 1,
2948                             "C-type: 5 - G.709");
2949         signal_type = tvb_get_guint8(tvb, offset2);
2950         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
2951                             "Signal Type: %d - %s", signal_type,
2952                             rval_to_str(signal_type,
2953                                         gmpls_g709_signal_type_rvals, 
2954                                         "Unknown"));
2955         proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 2, 2,
2956                             "Number of Multiplexed Components (NMC): %d", 
2957                             tvb_get_ntohs(tvb, offset2 + 2));
2958         proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 4, 2,
2959                             "Number of Virtual Components (NVC): %d", 
2960                             tvb_get_ntohs(tvb, offset2 + 4));
2961
2962         proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 6, 2,
2963                             "Multiplier (MT): %d", 
2964                             tvb_get_ntohs(tvb, offset2 + 6));
2965         proto_item_append_text(ti, "Signal [%s], NMC %d, NVC %d, MT %d",
2966                                rval_to_str(signal_type, 
2967                                            gmpls_g709_signal_type_rvals, 
2968                                            "Unknown"),
2969                                tvb_get_ntohs(tvb, offset2 + 2),
2970                                tvb_get_ntohs(tvb, offset2 + 4), 
2971                                tvb_get_ntohs(tvb, offset2 + 6));
2972         break;
2973
2974     case 6:   /* Ethernet FLOWSPEC  draft-ietf-ccamp-ethernet-traffic-parameters-02 */
2975         proto_item_set_text(ti, "FLOWSPEC: Ethernet, ");
2976         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
2977                             "C-type: 6 - Ethernet");
2978         switch_gran = tvb_get_ntohs(tvb, offset2);
2979         if (switch_gran == 1)
2980           proto_tree_add_text(rsvp_object_tree, tvb, offset2, 2,
2981                               "Switching granularity: 1 - Ethernet port");
2982         else if (switch_gran == 2)
2983           proto_tree_add_text(rsvp_object_tree, tvb, offset2, 2,
2984                               "Switching granularity: 2 - Ethernet frame");
2985         else
2986           proto_tree_add_text(rsvp_object_tree, tvb, offset2, 2,
2987                               "Switching granularity: %u - ???", switch_gran);
2988
2989         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
2990                             "MTU: %u", tvb_get_ntohs(tvb, offset2+2));
2991
2992         dissect_rsvp_eth_tspec_tlv(ti, rsvp_object_tree, tvb, offset+8, obj_length-8,
2993                                    TREE(TT_FLOWSPEC_SUBTREE));
2994         break;
2995
2996     default:
2997         break;
2998     }
2999
3000
3001 }
3002
3003 /*------------------------------------------------------------------------------
3004  * ADSPEC
3005  *------------------------------------------------------------------------------*/
3006 static void
3007 dissect_rsvp_adspec (proto_item *ti, proto_tree *rsvp_object_tree,
3008                      tvbuff_t *tvb,
3009                      int offset, int obj_length,
3010                      int class _U_, int type)
3011 {
3012     int offset2 = offset + 4;
3013     int mylen, i;
3014     proto_tree *adspec_tree;
3015
3016     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3017                         "C-type: %u", type);
3018     mylen = obj_length - 4;
3019
3020     proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
3021                         "Message format version: %u",
3022                         tvb_get_guint8(tvb, offset2)>>4);
3023     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
3024                         "Data length: %u words, not including header",
3025                         tvb_get_ntohs(tvb, offset2+2));
3026     mylen -= 4;
3027     offset2 += 4;
3028     while (mylen > 0) {
3029         guint8 service_num;
3030         guint8 break_bit;
3031         guint length;
3032         const char *str;
3033
3034         service_num = tvb_get_guint8(tvb, offset2);
3035         str = val_to_str(service_num, intsrv_services_str, "Unknown");
3036         break_bit = tvb_get_guint8(tvb, offset2+1);
3037         length = tvb_get_ntohs(tvb, offset2+2);
3038         ti = proto_tree_add_text(rsvp_object_tree, tvb, offset2,
3039                                  (length+1)*4, "%s",
3040                                  str);
3041         adspec_tree = proto_item_add_subtree(ti,
3042                                              TREE(TT_ADSPEC_SUBTREE));
3043         proto_tree_add_text(adspec_tree, tvb, offset2, 1,
3044                             "Service header %u - %s",
3045                             service_num, str);
3046         proto_tree_add_text(adspec_tree, tvb, offset2+1, 1,
3047                             (break_bit&0x80)?
3048                             "Break bit set":"Break bit not set");
3049         proto_tree_add_text(adspec_tree, tvb, offset2+2, 2,
3050                             "Data length: %u words, not including header",
3051                             length);
3052         mylen -= 4;
3053         offset2 += 4;
3054         i = length*4;
3055         while (i > 0) {
3056             guint8 id;
3057             guint phdr_length;
3058
3059             id = tvb_get_guint8(tvb, offset2);
3060             phdr_length = tvb_get_ntohs(tvb, offset2+2);
3061             str = match_strval(id, adspec_params);
3062             if (str) {
3063                 switch(id) {
3064                 case 4:
3065                 case 8:
3066                 case 10:
3067                 case 133:
3068                 case 134:
3069                 case 135:
3070                 case 136:
3071                     /* 32-bit unsigned integer */
3072                     proto_tree_add_text(adspec_tree, tvb, offset2,
3073                                         (phdr_length+1)<<2,
3074                                         "%s - %u (type %u, length %u)",
3075                                         str,
3076                                         tvb_get_ntohl(tvb, offset2+4),
3077                                         id, phdr_length);
3078                     break;
3079
3080                 case 6:
3081                     /* IEEE float */
3082                     proto_tree_add_text(adspec_tree, tvb, offset2,
3083                                         (phdr_length+1)<<2,
3084                                         "%s - %.10g (type %u, length %u)",
3085                                         str,
3086                                         tvb_get_ntohieee_float(tvb, offset2+4),
3087                                         id, phdr_length);
3088                     break;
3089                 default:
3090                     proto_tree_add_text(adspec_tree, tvb, offset2,
3091                                         (phdr_length+1)<<2,
3092                                         "%s (type %u, length %u)",
3093                                         str,
3094                                         id, phdr_length);
3095                 }
3096             } else {
3097                 proto_tree_add_text(adspec_tree, tvb, offset2,
3098                                     (phdr_length+1)<<2,
3099                                     "Unknown (type %u, length %u)",
3100                                     id, phdr_length);
3101             }
3102             offset2 += (phdr_length+1)<<2;
3103             i -= (phdr_length+1)<<2;
3104             mylen -= (phdr_length+1)<<2;
3105         }
3106     }
3107 }
3108
3109 /*------------------------------------------------------------------------------
3110  * INTEGRITY
3111  *------------------------------------------------------------------------------*/
3112 static void
3113 dissect_rsvp_integrity (proto_item *ti _U_, proto_tree *rsvp_object_tree,
3114                         tvbuff_t *tvb,
3115                         int offset, int obj_length,
3116                         int class _U_, int type)
3117 {
3118     int offset2 = offset + 4;
3119     proto_tree *ti2, *rsvp_integ_flags_tree;
3120     int flags;
3121
3122     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3123                         "C-type: %u", type);
3124     flags = tvb_get_guint8(tvb, offset2);
3125     ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
3126                               "Flags: 0x%02x", flags);
3127     rsvp_integ_flags_tree = proto_item_add_subtree(ti2, TREE(TT_INTEGRITY_FLAGS));
3128     proto_tree_add_text(rsvp_integ_flags_tree, tvb, offset2, 1, "%s",
3129         decode_boolean_bitfield(flags, 0x01, 8, "Handshake capable", "Handshake not capable"));
3130     proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 6,
3131                         "Key Identifier: %s", tvb_bytes_to_str(tvb, offset2+2, 6));
3132     proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 8,
3133                         "Sequence Number: %" G_GINT64_MODIFIER "u", tvb_get_ntoh64(tvb, offset2+8));
3134     proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, obj_length - 20,
3135                         "Hash: %s", tvb_bytes_to_str(tvb, offset2+16, obj_length - 20));
3136 }
3137
3138 /*------------------------------------------------------------------------------
3139  * POLICY
3140  *------------------------------------------------------------------------------*/
3141 static void
3142 dissect_rsvp_policy (proto_item *ti _U_, proto_tree *rsvp_object_tree,
3143                      tvbuff_t *tvb,
3144                      int offset, int obj_length,
3145                      int class _U_, int type)
3146 {
3147     int offset2 = offset + 4;
3148
3149     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3150                         "C-type: %u", type);
3151     proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
3152                         "Data (%d bytes)", obj_length - 4);
3153 }
3154
3155 /*------------------------------------------------------------------------------
3156  * LABEL_REQUEST
3157  *------------------------------------------------------------------------------*/
3158 static void
3159 dissect_rsvp_label_request (proto_item *ti, proto_tree *rsvp_object_tree,
3160                             tvbuff_t *tvb,
3161                             int offset, int obj_length,
3162                             int class _U_, int type)
3163 {
3164     int offset2 = offset + 4;
3165
3166     switch(type) {
3167     case 1: {
3168         unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2);
3169         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3170                             "C-type: 1");
3171         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
3172                             "L3PID: %s (0x%04x)",
3173                             val_to_str(l3pid, etype_vals, "Unknown"),
3174                             l3pid);
3175         proto_item_set_text(ti, "LABEL REQUEST: Basic: L3PID: %s (0x%04x)",
3176                             val_to_str(l3pid, etype_vals, "Unknown"),
3177                             l3pid);
3178         break;
3179     }
3180
3181     case 2: {
3182         unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2);
3183         unsigned short min_vpi, min_vci, max_vpi, max_vci;
3184         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3185                             "C-type: 2 (Label Request with ATM label Range)");
3186         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
3187                             "L3PID: %s (0x%04x)",
3188                             val_to_str(l3pid, etype_vals, "Unknown"),
3189                             l3pid);
3190         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 1,
3191                             "M: %s Merge in Data Plane",
3192                             (tvb_get_guint8(tvb, offset2+4) & 0x80) ?
3193                             "1: Can" : "0: Cannot");
3194         min_vpi = tvb_get_ntohs(tvb, offset2+4) & 0x7f;
3195         min_vci = tvb_get_ntohs(tvb, offset2+6);
3196         max_vpi = tvb_get_ntohs(tvb, offset2+8) & 0x7f;
3197         max_vci = tvb_get_ntohs(tvb, offset2+10);
3198         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 2,
3199                             "Min VPI: %d", min_vpi);
3200         proto_tree_add_text(rsvp_object_tree, tvb, offset2+6, 2,
3201                             "Min VCI: %d", min_vci);
3202         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 2,
3203                             "Max VPI: %d", max_vpi);
3204         proto_tree_add_text(rsvp_object_tree, tvb, offset2+10, 2,
3205                             "Max VCI: %d", max_vci);
3206         proto_item_set_text(ti, "LABEL REQUEST: ATM: L3PID: %s (0x%04x). VPI/VCI: Min: %d/%d, Max: %d/%d. %s Merge. ",
3207                             val_to_str(l3pid, etype_vals, "Unknown"), l3pid,
3208                             min_vpi, min_vci, max_vpi, max_vci,
3209                             (tvb_get_guint8(tvb, offset2+4) & 0x80) ? "Can" : "Cannot");
3210         break;
3211     }
3212
3213     case 3: {
3214         guint16 l3pid = tvb_get_ntohs(tvb, offset2+2);
3215         guint32 min_dlci, max_dlci, dlci_len, dlci_len_code;
3216         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3217                             "C-type: 2 (Label Request with ATM label Range)");
3218         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
3219                             "L3PID: %s (0x%04x)",
3220                             val_to_str(l3pid, etype_vals, "Unknown"),
3221                             l3pid);
3222         dlci_len_code = (tvb_get_ntohs(tvb, offset2+4) & 0x0180) >> 7;
3223         min_dlci = tvb_get_ntohl(tvb, offset2+4) & 0x7fffff;
3224         max_dlci = tvb_get_ntohl(tvb, offset2+8) & 0x7fffff;
3225         switch(dlci_len_code) {
3226         case 0:
3227             /* 10-bit DLCIs */
3228             dlci_len = 10;
3229             min_dlci &= 0x3ff;
3230             max_dlci &= 0x3ff;
3231         case 2:
3232             dlci_len = 23;
3233         default:
3234             dlci_len = 0;
3235             min_dlci = 0;
3236             max_dlci = 0;
3237         }
3238         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 2,
3239                             "DLCI Length: %s (%d)",
3240                             dlci_len==10 ? "10 bits" :
3241                             dlci_len==23 ? "23 bits" :
3242                             "INVALID", dlci_len_code);
3243         proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 3,
3244                             "Min DLCI: %d", min_dlci);
3245         proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 2,
3246                             "Max DLCI: %d", max_dlci);
3247         proto_item_set_text(ti, "LABEL REQUEST: Frame: L3PID: %s (0x%04x). DLCI Len: %s. Min DLCI: %d. Max DLCI: %d",
3248                             val_to_str(l3pid, etype_vals, "Unknown"), l3pid,
3249                             dlci_len==10 ? "10 bits" :
3250                             dlci_len==23 ? "23 bits" :
3251                             "INVALID", min_dlci, max_dlci);
3252         break;
3253     }
3254     case 4: {
3255         unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2);
3256         unsigned char  lsp_enc = tvb_get_guint8(tvb,offset2);
3257         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3258                             "C-type: 4 (Generalized Label Request)");
3259         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
3260                             "LSP Encoding Type: %s",
3261                             rval_to_str(lsp_enc, gmpls_lsp_enc_rvals, "Unknown (%d)"));
3262         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
3263                             "Switching Type: %s",
3264                             rval_to_str(tvb_get_guint8(tvb,offset2+1),
3265                                        gmpls_switching_type_rvals, "Unknown (%d)"));
3266         proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2,
3267                             "G-PID: %s (0x%0x)",
3268                             rval_to_str(l3pid, gmpls_gpid_rvals,
3269                                        val_to_str(l3pid, etype_vals,
3270                                                   "Unknown G-PID(0x%04x)")),
3271                             l3pid);
3272         proto_item_set_text(ti, "LABEL REQUEST: Generalized: LSP Encoding=%s, "
3273                             "Switching Type=%s, G-PID=%s ",
3274                             rval_to_str(lsp_enc, gmpls_lsp_enc_rvals, "Unknown (%d)"),
3275                             rval_to_str(tvb_get_guint8(tvb,offset2+1),
3276                                        gmpls_switching_type_rvals, "Unknown (%d)"),
3277                             rval_to_str(l3pid, gmpls_gpid_rvals,
3278                                        val_to_str(l3pid, etype_vals,
3279                                                   "Unknown (0x%04x)")));
3280         break;
3281     }
3282
3283     default: {
3284         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3285                             "C-type: Unknown (%u)",
3286                             type);
3287         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
3288                             "Data (%d bytes)", obj_length - 4);
3289         break;
3290     }
3291     }
3292 }
3293
3294 /*------------------------------------------------------------------------------
3295  * LABEL
3296  *------------------------------------------------------------------------------*/
3297 static void
3298 dissect_rsvp_label (proto_tree *ti, proto_tree *rsvp_object_tree,
3299                     tvbuff_t *tvb,
3300                     int offset, int obj_length,
3301                     int class, int type)
3302 {
3303     int offset2 = offset + 4;
3304     int mylen, i;
3305     const char *name;
3306
3307     name = (class==RSVP_CLASS_SUGGESTED_LABEL ? "SUGGESTED LABEL":
3308             (class==RSVP_CLASS_UPSTREAM_LABEL ? "UPSTREAM LABEL":
3309              (class==RSVP_CLASS_RECOVERY_LABEL ? "RECOVERY LABEL":
3310              "LABEL")));
3311     mylen = obj_length - 4;
3312     switch(type) {
3313     case 1:
3314         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3315                             "C-type: 1 (Packet Label)");
3316         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
3317                             "Label: %u",
3318                             tvb_get_ntohl(tvb, offset2));
3319         proto_item_set_text(ti, "%s: %u", name,
3320                             tvb_get_ntohl(tvb, offset2));
3321         break;
3322
3323     case 2:
3324         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3325                             "C-type: 2 (Generalized Label)");
3326         proto_item_set_text(ti, "%s: Generalized: ", name);
3327         for (i = 0; i < mylen; i += 4) {
3328             proto_tree_add_text(rsvp_object_tree, tvb, offset2+i, 4,
3329                                 "Generalized Label: %u (0x%x)",
3330                                 tvb_get_ntohl(tvb, offset2+i),
3331                                 tvb_get_ntohl(tvb, offset2+i));
3332             if (i < 16) {
3333                 proto_item_append_text(ti, "0x%x%s",
3334                                        tvb_get_ntohl(tvb, offset2+i),
3335                                        i+4<mylen?", ":"");
3336             } else if (i == 16) {
3337                 proto_item_append_text(ti, "...");
3338             }
3339         }
3340         break;
3341
3342     default:
3343         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3344                             "C-type: Unknown (%u)",
3345                             type);
3346         proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
3347                             "Data (%d bytes)", mylen);
3348         break;
3349     }
3350 }
3351
3352 /*------------------------------------------------------------------------------
3353  * LABEL_SET
3354  *------------------------------------------------------------------------------*/
3355 static void
3356 dissect_rsvp_label_set (proto_item *ti, proto_tree *rsvp_object_tree,
3357                         tvbuff_t *tvb,
3358                         int offset, int obj_length,
3359                         int class _U_, int type)
3360 {
3361     int offset2 = offset + 8;
3362     guint8 label_type;
3363     int len, i;
3364
3365     static const value_string action_type_vals[] = {
3366         {0, "Inclusive list"},
3367         {1, "Exclusive list"},
3368         {2, "Inclusive range"},
3369         {3, "Exclusive range"},
3370         {0, NULL}
3371    };
3372
3373     len = obj_length - 8;
3374     proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: %u", type);
3375     proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1, "Action: %s",
3376                         val_to_str(tvb_get_guint8(tvb, offset+4),
3377                         action_type_vals, "Unknown (%u)"));
3378     proto_item_append_text(ti, ": %s",
3379                            val_to_str(tvb_get_guint8(tvb, offset+4),
3380                            action_type_vals, "Unknown (%u)"));
3381     label_type = tvb_get_guint8 (tvb, offset+7);
3382     proto_tree_add_text(rsvp_object_tree, tvb, offset+7, 1, "Label type: %s",
3383                         label_type==1 ? "Packet Label" : "Generalized Label");
3384     proto_item_append_text(ti, ", %s",
3385                         label_type==1 ? "Packet Label: " : "Generalized Label: ");
3386
3387     for (i = 0; i < len/4; i++) {
3388         proto_tree_add_text(rsvp_object_tree, tvb, offset2+i*4, 4,
3389                             "Subchannel %u: %u (0x%x)", i+1,
3390                             tvb_get_ntohl(tvb, offset2+i*4),
3391                             tvb_get_ntohl(tvb, offset2+i*4));
3392
3393         if (i<5) {
3394                 if (i!=0)
3395                   proto_item_append_text(ti, ", ");
3396
3397                 proto_item_append_text(ti, "%u",
3398                                         tvb_get_ntohl(tvb, offset2+i*4));
3399         }
3400     }
3401 }
3402
3403 /*------------------------------------------------------------------------------
3404  * SESSION ATTRIBUTE
3405  *------------------------------------------------------------------------------*/
3406 static void
3407 dissect_rsvp_session_attribute (proto_item *ti, proto_tree *rsvp_object_tree,
3408                                 tvbuff_t *tvb,
3409                                 int offset, int obj_length,
3410                                 int class _U_, int type)
3411 {
3412     int offset2 = offset + 4;
3413     guint8 flags;
3414     guint8 name_len;
3415     proto_tree *ti2, *rsvp_sa_flags_tree;
3416
3417     switch(type) {
3418     case 1:
3419     case 7:
3420
3421         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3422                             "C-type: %u - IPv4 LSP (%sResource Affinities)",
3423                             type, (type == 1) ? "" : "No ");
3424
3425         if (type == 1) {
3426             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
3427                             "Exclude-Any: 0x%0x", tvb_get_ntohl(tvb, offset2));
3428             proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
3429                             "Include-Any: 0x%0x", tvb_get_ntohl(tvb, offset2+4));
3430             proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4,
3431                             "Include-All: 0x%0x", tvb_get_ntohl(tvb, offset2+8));
3432             offset2 = offset2+12;
3433         }
3434
3435         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
3436                             "Setup priority: %u",
3437                             tvb_get_guint8(tvb, offset2));
3438         proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1,
3439                             "Hold priority: %u",
3440                             tvb_get_guint8(tvb, offset2+1));
3441         flags = tvb_get_guint8(tvb, offset2+2);
3442         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 1,
3443                                   "Flags: 0x%02x", flags);
3444         rsvp_sa_flags_tree = proto_item_add_subtree(ti2,
3445                                                     TREE(TT_SESSION_ATTRIBUTE_FLAGS));
3446         proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1, "%s",
3447                             decode_boolean_bitfield(flags, 0x01, 8,
3448                                                     "Local protection desired",
3449                                                     "Local protection not desired"));
3450         proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1, "%s",
3451                             decode_boolean_bitfield(flags, 0x02, 8,
3452                                                     "Label recording desired",
3453                                                     "Label recording not desired"));
3454         proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1, "%s",
3455                             decode_boolean_bitfield(flags, 0x04, 8,
3456                                                     "SE style desired",
3457                                                     "SE style not desired"));
3458         proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1, "%s",
3459                             decode_boolean_bitfield(flags, 0x08, 8,
3460                                                     "Bandwidth protection desired",
3461                                                     "Bandwidth protection not desired"));
3462         proto_tree_add_text(rsvp_sa_flags_tree, tvb, offset2+2, 1, "%s",
3463                             decode_boolean_bitfield(flags, 0x10, 8,
3464                                                     "Node protection desired",
3465                                                     "Node protection not desired"));
3466
3467         name_len = tvb_get_guint8(tvb, offset2+3);
3468         proto_tree_add_text(rsvp_object_tree, tvb, offset2+3, 1,
3469                             "Name length: %u", name_len);
3470         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, name_len,
3471                             "Name: %s",
3472                             tvb_format_text(tvb, offset2+4, name_len));
3473
3474         proto_item_set_text(ti, "SESSION ATTRIBUTE: SetupPrio %d, HoldPrio %d, %s%s%s%s%s [%s]",
3475                             tvb_get_guint8(tvb, offset2),
3476                             tvb_get_guint8(tvb, offset2+1),
3477                             flags &0x01 ? "Local Protection, " : "",
3478                             flags &0x02 ? "Label Recording, " : "",
3479                             flags &0x04 ? "SE Style, " : "",
3480                             flags &0x08 ? "Bandwidth Protection, " : "",
3481                             flags &0x10 ? "Node Protection, " : "",
3482                             name_len ? tvb_format_text(tvb, offset2+4, name_len) : "");
3483         break;
3484
3485     default:
3486         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3487                             "C-type: Unknown (%u)",
3488                             type);
3489         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
3490                             "Data (%d bytes)", obj_length - 4);
3491         break;
3492     }
3493 }
3494
3495 /*------------------------------------------------------------------------------
3496  * EXPLICIT ROUTE AND RECORD ROUTE SUBOBJECTS
3497  *------------------------------------------------------------------------------*/
3498 static void
3499 dissect_rsvp_ero_rro_subobjects (proto_tree *ti, proto_tree *rsvp_object_tree,
3500                                  tvbuff_t *tvb,
3501                                  int offset, int obj_length, int class)
3502 {
3503     int i, j, k, l, flags;
3504     proto_tree *ti2, *rsvp_ro_subtree, *rsvp_rro_flags_subtree;
3505     int tree_type;
3506
3507     switch(class) {
3508     case RSVP_CLASS_EXPLICIT_ROUTE:
3509         tree_type = TREE(TT_EXPLICIT_ROUTE_SUBOBJ);
3510         break;
3511     case RSVP_CLASS_RECORD_ROUTE:
3512         tree_type = TREE(TT_RECORD_ROUTE_SUBOBJ);
3513         break;
3514     default:
3515         /* Bail out */
3516         return;
3517     }
3518
3519     for (i=1, l = 0; l < obj_length - 4; i++) {
3520         j = tvb_get_guint8(tvb, offset+l) & 0x7f;
3521         switch(j) {
3522         case 1: /* IPv4 */
3523             k = tvb_get_guint8(tvb, offset+l) & 0x80;
3524             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
3525                                       offset+l, 8,
3526                                       "IPv4 Subobject - %s%s",
3527                                       ip_to_str(tvb_get_ptr(tvb, offset+l+2, 4)),
3528                                       class == RSVP_CLASS_EXPLICIT_ROUTE ?
3529                                       (k ? ", Loose" : ", Strict") : "");
3530             rsvp_ro_subtree =
3531                 proto_item_add_subtree(ti2, tree_type);
3532             if (class == RSVP_CLASS_EXPLICIT_ROUTE)
3533                 proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3534                                     k ? "Loose Hop " : "Strict Hop");
3535             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3536                                 "Type: 1 (IPv4)");
3537             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3538                                 "Length: %u",
3539                                 tvb_get_guint8(tvb, offset+l+1));
3540             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+2, 4,
3541                                 "IPv4 hop: %s",
3542                                 ip_to_str(tvb_get_ptr(tvb, offset+l+2, 4)));
3543             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+6, 1,
3544                                 "Prefix length: %u",
3545                                 tvb_get_guint8(tvb, offset+l+6));
3546             if (i < 4) {
3547                 proto_item_append_text(ti, "IPv4 %s%s",
3548                                        ip_to_str(tvb_get_ptr(tvb, offset+l+2, 4)),
3549                                        k ? " [L]" : "");
3550             }
3551             if (class == RSVP_CLASS_RECORD_ROUTE) {
3552                 flags = tvb_get_guint8(tvb, offset+l+7);
3553                 if (flags&0x10) {
3554                     proto_item_append_text(ti,  " (Node-id)");
3555                     proto_item_append_text(ti2, " (Node-id)");
3556                 }
3557                 if (flags&0x01) proto_item_append_text(ti2, ", Local Protection Available");
3558                 if (flags&0x02) proto_item_append_text(ti2, ", Local Protection In Use");
3559                 if (flags&0x04) proto_item_append_text(ti2, ", Backup BW Avail");
3560                 if (flags&0x08) proto_item_append_text(ti2, ", Backup is Next-Next-Hop");
3561                 ti2 = proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+7, 1,
3562                                           "Flags: 0x%02x", flags);
3563                 rsvp_rro_flags_subtree =
3564                     proto_item_add_subtree(ti2, TREE(TT_RECORD_ROUTE_SUBOBJ_FLAGS));
3565                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+7, 1, "%s",
3566                                     decode_boolean_bitfield(flags, 0x01, 8,
3567                                                             "Local Protection Available",
3568                                                             "Local Protection Not Available"));
3569                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+7, 1, "%s",
3570                                     decode_boolean_bitfield(flags, 0x02, 8,
3571                                                             "Local Protection In Use",
3572                                                             "Local Protection Not In Use"));
3573                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+7, 1, "%s",
3574                                     decode_boolean_bitfield(flags, 0x04, 8,
3575                                                             "Bandwidth Protection Available",
3576                                                             "Bandwidth Protection Not Available"));
3577                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+7, 1, "%s",
3578                                     decode_boolean_bitfield(flags, 0x08, 8,
3579                                                             "Node Protection Available",
3580                                                             "Node Protection Not Available"));
3581                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+7, 1, "%s",
3582                                     decode_boolean_bitfield(flags, 0x10, 8,
3583                                                             "Address Specifies a Node-id Address",
3584                                                             "Address Doesn't Specify a Node-id Address"));
3585             }
3586
3587             break;
3588
3589         case 2: /* IPv6 */
3590             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
3591                                       offset+l, 20,
3592                                       "IPv6 Subobject");
3593             rsvp_ro_subtree =
3594                 proto_item_add_subtree(ti2, tree_type);
3595             k = tvb_get_guint8(tvb, offset+l) & 0x80;
3596             if (class == RSVP_CLASS_EXPLICIT_ROUTE)
3597                 proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3598                                     k ? "Loose Hop " : "Strict Hop");
3599             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3600                                 "Type: 2 (IPv6)");
3601             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3602                                 "Length: %u",
3603                                 tvb_get_guint8(tvb, offset+l+1));
3604             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+2, 16,
3605                                 "IPv6 hop: %s",
3606                                 ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+l+2, 16)));
3607             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+18, 1,
3608                                 "Prefix length: %u",
3609                                 tvb_get_guint8(tvb, offset+l+18));
3610             if (i < 4) {
3611                 proto_item_append_text(ti, "IPv6 [...]%s", k ? " [L]":"");
3612             }
3613             if (class == RSVP_CLASS_RECORD_ROUTE) {
3614                 flags = tvb_get_guint8(tvb, offset+l+19);
3615                 if (flags&0x10) {
3616                     proto_item_append_text(ti,  " (Node-id)");
3617                     proto_item_append_text(ti2, " (Node-id)");
3618                 }
3619                 if (flags&0x01) proto_item_append_text(ti2, ", Local Protection Available");
3620                 if (flags&0x02) proto_item_append_text(ti2, ", Local Protection In Use");
3621                 if (flags&0x04) proto_item_append_text(ti2, ", Backup BW Avail");
3622                 if (flags&0x08) proto_item_append_text(ti2, ", Backup is Next-Next-Hop");
3623                 ti2 = proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+19, 1,
3624                                           "Flags: 0x%02x", flags);
3625                 rsvp_rro_flags_subtree =
3626                     proto_item_add_subtree(ti2, TREE(TT_RECORD_ROUTE_SUBOBJ_FLAGS));
3627                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+19, 1, "%s",
3628                                     decode_boolean_bitfield(flags, 0x01, 8,
3629                                                             "Local Protection Available",
3630                                                             "Local Protection Not Available"));
3631                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+19, 1, "%s",
3632                                     decode_boolean_bitfield(flags, 0x02, 8,
3633                                                             "Local Protection In Use",
3634                                                             "Local Protection Not In Use"));
3635                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+19, 1, "%s",
3636                                     decode_boolean_bitfield(flags, 0x04, 8,
3637                                                             "Backup Tunnel Has Bandwidth",
3638                                                             "Backup Tunnel Does Not Have Bandwidth"));
3639                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+19, 1, "%s",
3640                                     decode_boolean_bitfield(flags, 0x08, 8,
3641                                                             "Backup Tunnel Goes To Next-Next-Hop",
3642                                                             "Backup Tunnel Goes To Next-Hop"));
3643                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+19, 1, "%s",
3644                                     decode_boolean_bitfield(flags, 0x10, 8,
3645                                                             "Address Specifies a Node-id Address",
3646                                                             "Address Doesn't Specify a Node-id Address"));
3647             }
3648
3649             break;
3650
3651         case 3: /* Label */
3652             k = tvb_get_guint8(tvb, offset+l) & 0x80;
3653             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
3654                                       offset+l, 8,
3655                                       "Label Subobject - %d, %s",
3656                                       tvb_get_ntohl(tvb, offset+l+4),
3657                                       class == RSVP_CLASS_EXPLICIT_ROUTE ?
3658                                       (k ? "Loose" : "Strict") : "");
3659             rsvp_ro_subtree =
3660                 proto_item_add_subtree(ti2, tree_type);
3661             if (class == RSVP_CLASS_EXPLICIT_ROUTE)
3662                 proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3663                                     k ? "Loose Hop " : "Strict Hop");
3664             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3665                                 "Type: 3 (Label)");
3666             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3667                                 "Length: %u",
3668                                 tvb_get_guint8(tvb, offset+l+1));
3669             if (class == RSVP_CLASS_RECORD_ROUTE) {
3670                 flags = tvb_get_guint8(tvb, offset+l+2);
3671                 if (flags&0x01) proto_item_append_text(ti2, ", Local Protection Available");
3672                 if (flags&0x02) proto_item_append_text(ti2, ", Local Protection In Use");
3673                 if (flags&0x04) proto_item_append_text(ti2, ", Backup BW Avail");
3674                 if (flags&0x08) proto_item_append_text(ti2, ", Backup is Next-Next-Hop");
3675                 ti2 = proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+2, 1,
3676                                           "Flags: 0x%02x", flags);
3677                 rsvp_rro_flags_subtree =
3678                     proto_item_add_subtree(ti2, TREE(TT_RECORD_ROUTE_SUBOBJ_FLAGS));
3679                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3680                                     decode_boolean_bitfield(flags, 0x01, 8,
3681                                                             "Local Protection Available",
3682                                                             "Local Protection Not Available"));
3683                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3684                                     decode_boolean_bitfield(flags, 0x02, 8,
3685                                                             "Local Protection In Use",
3686                                                             "Local Protection Not In Use"));
3687                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3688                                     decode_boolean_bitfield(flags, 0x04, 8,
3689                                                             "Backup Tunnel Has Bandwidth",
3690                                                             "Backup Tunnel Does Not Have Bandwidth"));
3691                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3692                                     decode_boolean_bitfield(flags, 0x08, 8,
3693                                                             "Backup Tunnel Goes To Next-Next-Hop",
3694                                                             "Backup Tunnel Goes To Next-Hop"));
3695             }
3696             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+3, 1,
3697                                 "C-Type: %u",
3698                                 tvb_get_guint8(tvb, offset+l+3));
3699             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+4, 4,
3700                                 "Label: %d",
3701                                 tvb_get_ntohl(tvb, offset+l+4));
3702             if (i < 4) {
3703                 proto_item_append_text(ti, "Label %d%s",
3704                                        tvb_get_ntohl(tvb, offset+l+4),
3705                                        k ? " [L]":"");
3706             }
3707             break;
3708
3709         case 4: /* Unnumbered Interface-ID */
3710             k = tvb_get_guint8(tvb, offset+l) & 0x80;
3711             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
3712                                       offset+l, 8,
3713                                       "Unnumbered Interface-ID - %s, %d, %s",
3714                                       ip_to_str(tvb_get_ptr(tvb, offset+l+4, 4)),
3715                                       tvb_get_ntohl(tvb, offset+l+8),
3716                                       class == RSVP_CLASS_EXPLICIT_ROUTE ?
3717                                       (k ? "Loose" : "Strict") : "");
3718             rsvp_ro_subtree =
3719                 proto_item_add_subtree(ti2, tree_type);
3720             if (class == RSVP_CLASS_EXPLICIT_ROUTE)
3721                 proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3722                                     k ? "Loose Hop " : "Strict Hop");
3723             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3724                                 "Type: 4 (Unnumbered Interface-ID)");
3725             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3726                                 "Length: %u",
3727                                 tvb_get_guint8(tvb, offset+l+1));
3728             if (class == RSVP_CLASS_RECORD_ROUTE) {
3729                 flags = tvb_get_guint8(tvb, offset+l+2);
3730                 if (flags&0x01) proto_item_append_text(ti2, ", Local Protection Available");
3731                 if (flags&0x02) proto_item_append_text(ti2, ", Local Protection In Use");
3732                 if (flags&0x04) proto_item_append_text(ti2, ", Backup BW Avail");
3733                 if (flags&0x08) proto_item_append_text(ti2, ", Backup is Next-Next-Hop");
3734                 ti2 = proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+2, 1,
3735                                           "Flags: 0x%02x", flags);
3736                 rsvp_rro_flags_subtree =
3737                     proto_item_add_subtree(ti2, TREE(TT_RECORD_ROUTE_SUBOBJ_FLAGS));
3738                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3739                                     decode_boolean_bitfield(flags, 0x01, 8,
3740                                                             "Local Protection Available",
3741                                                             "Local Protection Not Available"));
3742                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3743                                     decode_boolean_bitfield(flags, 0x02, 8,
3744                                                             "Local Protection In Use",
3745                                                             "Local Protection Not In Use"));
3746                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3747                                     decode_boolean_bitfield(flags, 0x04, 8,
3748                                                             "Backup Tunnel Has Bandwidth",
3749                                                             "Backup Tunnel Does Not Have Bandwidth"));
3750                 proto_tree_add_text(rsvp_rro_flags_subtree, tvb, offset+l+2, 1, "%s",
3751                                     decode_boolean_bitfield(flags, 0x08, 8,
3752                                                             "Backup Tunnel Goes To Next-Next-Hop",
3753                                                             "Backup Tunnel Goes To Next-Hop"));
3754             }
3755             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+4, 4,
3756                                 "Router-ID: %s",
3757                                 ip_to_str(tvb_get_ptr(tvb, offset+l+4, 4)));
3758             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+8, 4,
3759                                 "Interface-ID: %d",
3760                                 tvb_get_ntohl(tvb, offset+l+8));
3761             if (i < 4) {
3762                 proto_item_append_text(ti, "Unnum %s/%d%s",
3763                                        ip_to_str(tvb_get_ptr(tvb, offset+l+4, 4)),
3764                                        tvb_get_ntohl(tvb, offset+l+8),
3765                                        k ? " [L]":"");
3766             }
3767
3768             break;
3769
3770         case 32: /* AS */
3771             if (class == RSVP_CLASS_RECORD_ROUTE) goto defaultsub;
3772             k = tvb_get_ntohs(tvb, offset+l+2);
3773             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
3774                                       offset+l, 4,
3775                                       "Autonomous System %u",
3776                                       k);
3777             rsvp_ro_subtree =
3778                 proto_item_add_subtree(ti2, tree_type);
3779             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3780                                 "Type: 32 (Autonomous System Number)");
3781             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3782                                 "Length: %u",
3783                                 tvb_get_guint8(tvb, offset+l+1));
3784             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+2, 2,
3785                                 "Autonomous System %u", k);
3786             if (i < 4) {
3787                 proto_item_append_text(ti, "AS %d",
3788                                        tvb_get_ntohs(tvb, offset+l+2));
3789             }
3790
3791             break;
3792
3793         default: /* Unknown subobject */
3794         defaultsub:
3795             k = tvb_get_guint8(tvb, offset+l) & 0x80;
3796             ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
3797                                       offset+l,
3798                                       tvb_get_guint8(tvb, offset+l+1),
3799                                       "Unknown subobject: %d", j);
3800             rsvp_ro_subtree =
3801                 proto_item_add_subtree(ti2, tree_type);
3802             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3803                                 k ? "Loose Hop " : "Strict Hop");
3804             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l, 1,
3805                                 "Type: %u (Unknown)", j);
3806             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3807                                 "Length: %u",
3808                                 tvb_get_guint8(tvb, offset+l+1));
3809
3810         }
3811
3812         if (tvb_get_guint8(tvb, offset+l+1) < 1) {
3813             proto_tree_add_text(rsvp_ro_subtree, tvb, offset+l+1, 1,
3814                 "Invalid length: %u", tvb_get_guint8(tvb, offset+l+1));
3815             return;
3816         }
3817         l += tvb_get_guint8(tvb, offset+l+1);
3818         if (l < obj_length - 4) {
3819             if (i < 4)
3820                 proto_item_append_text(ti, ", ");
3821             else if (i==4)
3822                 proto_item_append_text(ti, "...");
3823         }
3824     }
3825 }
3826
3827 /*------------------------------------------------------------------------------
3828  * EXPLICIT ROUTE OBJECT
3829  *------------------------------------------------------------------------------*/
3830 static void
3831 dissect_rsvp_explicit_route (proto_item *ti, proto_tree *rsvp_object_tree,
3832                              tvbuff_t *tvb,
3833                              int offset, int obj_length,
3834                              int class, int type)
3835 {
3836     /* int offset2 = offset + 4; */
3837     /* int mylen, i, j, k, l; */
3838     /* proto_tree *ti2, *rsvp_ero_subtree; */
3839
3840     /* mylen = obj_length - 4; */
3841     switch(type) {
3842     case 1:
3843         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3844                             "C-type: 1");
3845         proto_item_set_text(ti, "EXPLICIT ROUTE: ");
3846
3847         dissect_rsvp_ero_rro_subobjects(ti, rsvp_object_tree, tvb,
3848                                         offset + 4, obj_length, class);
3849         break;
3850
3851     default:
3852         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3853                             "C-type: Unknown (%u)",
3854                             type);
3855         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, obj_length - 4,
3856                             "Data (%d bytes)", obj_length - 4);
3857         break;
3858     }
3859 }
3860
3861 /*------------------------------------------------------------------------------
3862  * RECORD ROUTE OBJECT
3863  *------------------------------------------------------------------------------*/
3864 static void
3865 dissect_rsvp_record_route (proto_item *ti, proto_tree *rsvp_object_tree,
3866                            tvbuff_t *tvb,
3867                            int offset, int obj_length,
3868                            int class, int type)
3869 {
3870     /* int offset2 = offset + 4; */
3871     /* int mylen, i, j, l; */
3872     /* proto_tree *ti2, *rsvp_rro_subtree; */
3873
3874     proto_item_set_text(ti, "RECORD ROUTE: ");
3875     /* mylen = obj_length - 4; */
3876     switch(type) {
3877     case 1:
3878         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3879                             "C-type: 1");
3880
3881         dissect_rsvp_ero_rro_subobjects(ti, rsvp_object_tree, tvb,
3882                                         offset + 4, obj_length, class);
3883         break;
3884
3885     default:
3886         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3887                             "C-type: Unknown (%u)",
3888                             type);
3889         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, obj_length - 4,
3890                             "Data (%d bytes)", obj_length - 4);
3891         break;
3892     }
3893 }
3894
3895 /*------------------------------------------------------------------------------
3896  * MESSAGE ID
3897  *------------------------------------------------------------------------------*/
3898 static void
3899 dissect_rsvp_message_id (proto_tree *ti, proto_tree *rsvp_object_tree,
3900                          tvbuff_t *tvb,
3901                          int offset, int obj_length,
3902                          int class _U_, int type)
3903 {
3904     int offset2 = offset + 4;
3905
3906     switch(type) {
3907     case 1:
3908         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3909                             "C-type: 1");
3910         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
3911                             "Flags: %d", tvb_get_guint8(tvb, offset+4));
3912         proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
3913                             "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
3914         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
3915                             "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
3916         proto_item_set_text(ti, "MESSAGE-ID: %d %s",
3917                             tvb_get_ntohl(tvb, offset+8),
3918                             tvb_get_guint8(tvb, offset+4) & 1 ? "(Ack Desired)" : "");
3919         break;
3920
3921     default:
3922         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3923                             "C-type: Unknown (%u)",
3924                             type);
3925         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
3926                             "Data (%d bytes)", obj_length - 4);
3927         break;
3928     }
3929 }
3930
3931 /*------------------------------------------------------------------------------
3932  * MESSAGE ID ACK
3933  *------------------------------------------------------------------------------*/
3934 static void
3935 dissect_rsvp_message_id_ack (proto_tree *ti, proto_tree *rsvp_object_tree,
3936                              tvbuff_t *tvb,
3937                              int offset, int obj_length,
3938                              int class _U_, int type)
3939 {
3940     int offset2 = offset + 4;
3941
3942     switch(type) {
3943     case 1:
3944         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3945                             "C-type: 1");
3946         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
3947                             "Flags: %d", tvb_get_guint8(tvb, offset+4));
3948         proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
3949                             "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
3950         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
3951                             "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
3952         proto_item_set_text(ti, "MESSAGE-ID ACK: %d", tvb_get_ntohl(tvb, offset+8));
3953         break;
3954
3955     case 2:
3956         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3957                             "C-type: 2");
3958         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
3959                             "Flags: %d", tvb_get_guint8(tvb, offset+4));
3960         proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
3961                             "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
3962         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
3963                             "Message-ID: %d", tvb_get_ntohl(tvb, offset+8));
3964         proto_item_set_text(ti, "MESSAGE-ID NACK: %d", tvb_get_ntohl(tvb, offset+8));
3965         break;
3966
3967     default:
3968         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3969                             "C-type: Unknown (%u)",
3970                             type);
3971         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
3972                             "Data (%d bytes)", obj_length - 4);
3973         break;
3974     }
3975 }
3976
3977 /*------------------------------------------------------------------------------
3978  * MESSAGE ID LIST
3979  *------------------------------------------------------------------------------*/
3980 static void
3981 dissect_rsvp_message_id_list (proto_tree *ti, proto_tree *rsvp_object_tree,
3982                               tvbuff_t *tvb,
3983                               int offset, int obj_length,
3984                               int class _U_, int type)
3985 {
3986     int offset2 = offset + 4;
3987     int mylen;
3988
3989     switch(type) {
3990     case 1:
3991         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
3992                             "C-type: 1");
3993         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
3994                             "Flags: %d", tvb_get_guint8(tvb, offset+4));
3995         proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 3,
3996                             "Epoch: %d", tvb_get_ntoh24(tvb, offset+5));
3997         for (mylen = 8; mylen < obj_length; mylen += 4)
3998             proto_tree_add_text(rsvp_object_tree, tvb, offset+mylen, 4,
3999                                 "Message-ID: %d", tvb_get_ntohl(tvb, offset+mylen));
4000         proto_item_set_text(ti, "MESSAGE-ID LIST: %d IDs",
4001                             (obj_length - 8)/4);
4002         break;
4003
4004     default:
4005         mylen = obj_length - 4;
4006         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4007                             "C-type: Unknown (%u)",
4008                             type);
4009         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
4010                             "Data (%d bytes)", obj_length - 4);
4011         break;
4012     }
4013 }
4014
4015 /*------------------------------------------------------------------------------
4016  * HELLO
4017  *------------------------------------------------------------------------------*/
4018 static void
4019 dissect_rsvp_hello (proto_tree *ti, proto_tree *rsvp_object_tree,
4020                     tvbuff_t *tvb,
4021                     int offset, int obj_length _U_,
4022                     int class _U_, int type)
4023 {
4024     switch(type) {
4025     case 1:
4026     case 2:
4027         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4028                             "C-Type: %d - HELLO %s object",
4029                             tvb_get_guint8 (tvb, offset+3),
4030                             type==1 ? "REQUEST" : "ACK");
4031         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 4,
4032                             "Source Instance: 0x%x",tvb_get_ntohl(tvb, offset+4));
4033         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
4034                             "Destination Instance: 0x%x",tvb_get_ntohl(tvb, offset+8));
4035         proto_item_append_text(ti, ": %s. Src Instance: 0x%0x. Dest Instance: 0x%0x. ",
4036                                type==1 ? "REQUEST" : "ACK",
4037                                tvb_get_ntohl(tvb, offset+4),
4038                                tvb_get_ntohl(tvb, offset+8));
4039         break;
4040     default:
4041         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4042                             "C-Type: %d - UNKNOWN", type);
4043         break;
4044     };
4045 }
4046
4047 /*------------------------------------------------------------------------------
4048  * DCLASS
4049  *------------------------------------------------------------------------------*/
4050 static void
4051 dissect_rsvp_dclass (proto_tree *ti, proto_tree *rsvp_object_tree,
4052                      tvbuff_t *tvb,
4053                      int offset, int obj_length,
4054                      int class _U_, int type)
4055 {
4056     int offset2 = offset + 4;
4057     int mylen;
4058
4059     proto_item_set_text(ti, "DCLASS: ");
4060     switch(type) {
4061     case 1:
4062         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4063                             "C-type: 1");
4064         for (mylen = 4; mylen < obj_length; mylen += 4) {
4065             proto_tree_add_text(rsvp_object_tree, tvb, offset+mylen+3, 1,
4066                                 "DSCP: %s",
4067                                 val_to_str(tvb_get_guint8(tvb, offset+mylen+3),
4068                                            dscp_vals, "Unknown (%d)"));
4069             proto_item_append_text(ti, "%d%s",
4070                                    tvb_get_guint8(tvb, offset+mylen+3)>>2,
4071                                    mylen==obj_length-4 ? "":
4072                                    mylen<16 ? ", ":
4073                                    mylen==16 ? ", ..." : "");
4074         }
4075         break;
4076
4077     default:
4078         mylen = obj_length - 4;
4079         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4080                             "C-type: Unknown (%u)",
4081                             type);
4082         proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
4083                             "Data (%d bytes)", mylen);
4084         break;
4085     }
4086 }
4087
4088 /*------------------------------------------------------------------------------
4089  * ADMINISTRATIVE STATUS
4090  *------------------------------------------------------------------------------*/
4091 static void
4092 dissect_rsvp_admin_status (proto_tree *ti, proto_tree *rsvp_object_tree,
4093                            tvbuff_t *tvb,
4094                            int offset, int obj_length,
4095                            int class _U_, int type)
4096 {
4097     int offset2 = offset + 4;
4098     proto_tree *ti2, *rsvp_admin_subtree;
4099     int mylen;
4100     guint32 status;
4101
4102     proto_item_set_text(ti, "ADMIN STATUS: ");
4103     switch(type) {
4104     case 1:
4105         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4106                             "C-type: 1");
4107         status = tvb_get_ntohl(tvb, offset2);
4108         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
4109                                   "Admin Status: 0x%08x", status);
4110         rsvp_admin_subtree =
4111             proto_item_add_subtree(ti2, TREE(TT_ADMIN_STATUS_FLAGS));
4112         proto_tree_add_text(rsvp_admin_subtree, tvb, offset2, 4, "%s",
4113                             decode_boolean_bitfield(status, 0x80000000, 32,
4114                                                     "R: Reflect",
4115                                                     "R: Do not reflect"));
4116         proto_tree_add_text(rsvp_admin_subtree, tvb, offset2, 4, "%s",
4117                             decode_boolean_bitfield(status, 0x04, 32,
4118                                                     "T: Testing",
4119                                                     "T: "));
4120         proto_tree_add_text(rsvp_admin_subtree, tvb, offset2, 4, "%s",
4121                             decode_boolean_bitfield(status, 0x02, 32,
4122                                                     "A: Administratively Down",
4123                                                     "A: "));
4124         proto_tree_add_text(rsvp_admin_subtree, tvb, offset2, 4, "%s",
4125                             decode_boolean_bitfield(status, 0x01, 32,
4126                                                     "D: Delete In Progress",
4127                                                     "D: "));
4128         proto_item_set_text(ti, "ADMIN-STATUS: %s %s %s %s",
4129                             (status & (1<<31)) ? "Reflect" : "",
4130                             (status & (1<<2))  ? "Testing" : "",
4131                             (status & (1<<1))  ? "Admin-Down" : "",
4132                             (status & (1<<0))  ? "Deleting" : "");
4133         break;
4134
4135     default:
4136         mylen = obj_length - 4;
4137         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4138                             "C-type: Unknown (%u)",
4139                             type);
4140         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
4141                             "Data (%d bytes)", obj_length - 4);
4142         break;
4143     }
4144 }
4145
4146 /*------------------------------------------------------------------------------
4147  * ASSOCIATION
4148  *------------------------------------------------------------------------------*/
4149 static void
4150 dissect_rsvp_association (proto_tree *ti, proto_tree *rsvp_object_tree,
4151                           tvbuff_t *tvb,
4152                           int offset, int obj_length,
4153                           int class _U_, int type)
4154 {
4155     guint16 association_type;
4156     guint16 association_id;
4157     static const value_string association_type_vals[] = {
4158         {0, "Reserved"},
4159         {1, "Recovery"},
4160         { 0, NULL}
4161     };
4162
4163     proto_item_set_text(ti, "ASSOCIATION ");
4164     association_type = tvb_get_ntohs (tvb, offset + 4);
4165     association_id = tvb_get_ntohs (tvb, offset + 6);
4166     switch(type) {
4167     case 1:
4168         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4169                             "C-type: 1 (IPv4)");
4170         proto_item_append_text(ti, "(IPv4): ");
4171         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 2,
4172                             "Association type: %s",
4173                             val_to_str(association_type, association_type_vals, "Unknown (%u)"));
4174         proto_item_append_text(ti, "%s. ",
4175                                val_to_str(association_type, association_type_vals, "Unknown (%u)"));
4176         proto_tree_add_text(rsvp_object_tree, tvb, offset+6, 2,
4177                             "Association ID: %u", association_id);
4178         proto_item_append_text(ti, "ID: %u. ", association_id);
4179         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
4180                             "Association source: %s", ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
4181         proto_item_append_text(ti, "Src: %s", ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
4182         break;
4183
4184     case 2:
4185         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4186                             "C-type: 2 (IPv6)");
4187         proto_item_append_text(ti, "(IPv6): ");
4188         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 2,
4189                             "Association type: %s",
4190                             val_to_str(association_type, association_type_vals, "Unknown (%u)"));
4191         proto_item_append_text(ti, "%s. ",
4192                                val_to_str(association_type, association_type_vals, "Unknown (%u)"));
4193         proto_tree_add_text(rsvp_object_tree, tvb, offset+6, 2,
4194                             "Association ID: %u", association_id);
4195         proto_item_append_text(ti, "ID: %u. ", association_id);
4196         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 16,
4197                             "Association source: %s", ip6_to_str((const struct e_in6_addr *)
4198                                                                 tvb_get_ptr(tvb, offset+8, 16)));
4199         proto_item_append_text(ti, "Src: %s", ip6_to_str((const struct e_in6_addr *)
4200                                                         tvb_get_ptr(tvb, offset+8, 16)));
4201         break;
4202
4203     default:
4204         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4205                             "C-type: Unknown (%u)", type);
4206         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, obj_length - 4,
4207                             "Data (%d bytes)", obj_length - 4);
4208         break;
4209     }
4210 }
4211
4212 /*------------------------------------------------------------------------------
4213  * TLVs for LSP TUNNEL IF ID object
4214  * draft-ietf-ccamp-lsp-hierarchy-bis-02
4215  *------------------------------------------------------------------------------*/
4216 static void
4217 dissect_rsvp_lsp_tunnel_if_id_tlv(proto_tree *rsvp_object_tree,
4218                                   tvbuff_t *tvb, int offset, int tlv_length,
4219                                   int subtree_type)
4220 {
4221     int       tlv_off;
4222     guint16   tlv_type;
4223     int       tlv_len;
4224     proto_tree *ti, *rsvp_lsp_tunnel_if_id_subtree;
4225
4226     for (tlv_off = 0; tlv_off < tlv_length; ) {
4227         tlv_type = tvb_get_ntohs(tvb, offset+tlv_off);
4228         tlv_len = tvb_get_ntohs(tvb, offset+tlv_off+2);
4229
4230         if (tlv_len == 0 || tlv_off+tlv_len > tlv_length) {
4231             proto_tree_add_text(rsvp_object_tree, tvb, offset+tlv_off+2, 2,
4232                                 "Invalid length");
4233             return;
4234         }
4235         switch(tlv_type) {
4236         case 1:
4237             ti = proto_tree_add_text(rsvp_object_tree, tvb,
4238                                      offset+tlv_off, tlv_len,
4239                                      "Unnumbered component link identifier: %u",
4240                                      tvb_get_ntohl(tvb, offset+tlv_off+4));
4241             rsvp_lsp_tunnel_if_id_subtree = proto_item_add_subtree(ti, subtree_type);
4242             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off, 2,
4243                                 "Type: 1 (Unnumbered component link identifier)");
4244             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+2, 2,
4245                                 "Length: %u", tlv_len);
4246             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+4, 4,
4247                                 "Component link identifier: %u",
4248                                 tvb_get_ntohl(tvb, offset+tlv_off+4));
4249             break;
4250             
4251         case 2:
4252             ti = proto_tree_add_text(rsvp_object_tree, tvb,
4253                                      offset+tlv_off, tlv_len,
4254                                      "IPv4 component link identifier: %s",
4255                                      ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)));
4256             rsvp_lsp_tunnel_if_id_subtree = proto_item_add_subtree(ti, subtree_type);
4257             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off, 2,
4258                                 "Type: 2 (IPv4 component link identifier)");
4259             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+2, 2,
4260                                 "Length: %u", tlv_len);
4261             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+4, 4,
4262                                 "Component link identifier: %s",
4263                                 ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+4, 4)));
4264             break;
4265             
4266         case 32769:  /* oif-p0040.002.09 demo spec */
4267             ti = proto_tree_add_text(rsvp_object_tree, tvb,
4268                                      offset+tlv_off, tlv_len,
4269                                      "Targeted client layer: ");
4270             rsvp_lsp_tunnel_if_id_subtree = proto_item_add_subtree(ti, subtree_type);
4271             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off, 2,
4272                                 "Type: 32769 (Targeted client layer)");
4273             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+2, 2,
4274                                 "Length: %u", tlv_len);
4275             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+4, 1,
4276                                 "LSP Encoding Type: %s",
4277                                 rval_to_str(tvb_get_guint8(tvb,offset+tlv_off+4),
4278                                            gmpls_lsp_enc_rvals, "Unknown (%d)"));
4279             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+5, 1,
4280                                 "Switching Type: %s",
4281                                 rval_to_str(tvb_get_guint8(tvb,offset+tlv_off+5),
4282                                            gmpls_switching_type_rvals, "Unknown (%d)"));
4283             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+6, 1,
4284                                 "Signal Type: %s",
4285                                 val_to_str(tvb_get_guint8(tvb,offset+tlv_off+6),
4286                                            gmpls_sonet_signal_type_str, "Unknown (%d)"));
4287             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+8, 8,
4288                                 "Sub Interface/Connection ID: %" G_GINT64_MODIFIER "u (0x%s)",
4289                                 tvb_get_ntoh64(tvb, offset+tlv_off+8),
4290                                 tvb_bytes_to_str(tvb, offset+tlv_off+8, 8));
4291             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+16, 4,
4292                                 "SC PC ID: %s",
4293                                 ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+16, 4)));
4294             proto_tree_add_text(rsvp_lsp_tunnel_if_id_subtree, tvb, offset+tlv_off+20, 4,
4295                                 "SC PC SCN Address: %s",
4296                                 ip_to_str(tvb_get_ptr(tvb, offset+tlv_off+20, 4)));
4297             proto_item_append_text(ti, "LSP Encoding=%s, Switching Type=%s, Signal Type=%s",
4298                                    rval_to_str(tvb_get_guint8(tvb,offset+tlv_off+4),
4299                                               gmpls_lsp_enc_rvals, "Unknown (%d)"),
4300                                    rval_to_str(tvb_get_guint8(tvb,offset+tlv_off+5),
4301                                               gmpls_switching_type_rvals, "Unknown (%d)"),
4302                                    val_to_str(tvb_get_guint8(tvb,offset+tlv_off+6),
4303                                               gmpls_sonet_signal_type_str, "Unknown (%d)"));
4304             break;
4305
4306         default:
4307             proto_tree_add_text(rsvp_object_tree, tvb, offset+tlv_off, 2,
4308                                 "Unknown TLV: %u", tlv_type);
4309         }
4310         tlv_off += tlv_len;
4311     }
4312 }
4313
4314 /*------------------------------------------------------------------------------
4315  * LSP TUNNEL INTERFACE ID
4316  *------------------------------------------------------------------------------*/
4317 static void
4318 dissect_rsvp_lsp_tunnel_if_id (proto_tree *ti, proto_tree *rsvp_object_tree,
4319                                tvbuff_t *tvb,
4320                                int offset, int obj_length,
4321                                int class _U_, int type)
4322 {
4323     guint8  action;
4324
4325     static const value_string lsp_tunnel_if_id_action_str[] = {
4326         {0, "LSP is FA (MPLS-TE topology advertisement only)"},
4327         {1, "LSP is RA (IP network advertisement only)"},
4328         {2, "LSP is RA (both IP and MPLS-TE topology advertisement)"},
4329         {3, "LSP is to be used as a virtual local link"},
4330         {0, NULL}
4331     };
4332
4333     proto_item_set_text(ti, "LSP INTERFACE-ID: ");
4334     switch(type) {
4335     case 1:
4336         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4337                             "C-type: 1 - Unnumbered interface");
4338         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 4,
4339                             "Router ID: %s",
4340                             ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
4341         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
4342                             "Interface ID: %u", tvb_get_ntohl(tvb, offset+8));
4343         proto_item_set_text(ti, "LSP INTERFACE-ID: Unnumbered, Router-ID %s, Interface-ID %d",
4344                             ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
4345                             tvb_get_ntohl(tvb, offset+8));
4346         break;
4347
4348     case 2:
4349         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4350                             "C-type: 2 - IPv4");
4351         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 4,
4352                             "IPv4 interface address: %s",
4353                             ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
4354         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
4355                             "Target IGP instance: %s",
4356                             ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
4357         proto_item_set_text(ti, "LSP INTERFACE-ID: IPv4, interface address %s,"
4358                             "IGP instance %s",
4359                             ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
4360                             ip_to_str(tvb_get_ptr(tvb, offset+8, 4)));
4361         action = tvb_get_guint8(tvb, offset+12);
4362         action >>= 4;
4363         proto_tree_add_text(rsvp_object_tree, tvb, offset+12, 1, "Action: %d - %s",
4364                             action,
4365                             val_to_str(action, lsp_tunnel_if_id_action_str, "Unknown"));
4366         dissect_rsvp_lsp_tunnel_if_id_tlv(rsvp_object_tree, tvb, offset+16, obj_length-16,
4367                                           TREE(TT_LSP_TUNNEL_IF_ID_SUBTREE));
4368         break;
4369
4370     case 3:
4371         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4372                             "C-type: 3 - IPv6");
4373         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 16,
4374                             "IPv6 interface address: %s",
4375                             ip6_to_str((const struct e_in6_addr *)
4376                                         tvb_get_ptr(tvb, offset+4, 16)));
4377         proto_tree_add_text(rsvp_object_tree, tvb, offset+20, 4,
4378                             "Target IGP instance: %s",
4379                             ip_to_str(tvb_get_ptr(tvb, offset+20, 4)));
4380         proto_item_set_text(ti, "LSP INTERFACE-ID: IPv6, interface address %s,"
4381                             "IGP instance %s",
4382                             ip6_to_str((const struct e_in6_addr *)
4383                                         tvb_get_ptr(tvb, offset+4, 16)),
4384                             ip_to_str(tvb_get_ptr(tvb, offset+20, 4)));
4385         action = tvb_get_guint8(tvb, offset+24);
4386         action >>= 4;
4387         proto_tree_add_text(rsvp_object_tree, tvb, offset+24, 1, "Action: %d - %s",
4388                             action,
4389                             val_to_str(action, lsp_tunnel_if_id_action_str, "Unknown"));
4390         dissect_rsvp_lsp_tunnel_if_id_tlv(rsvp_object_tree, tvb, offset+28, obj_length-28,
4391                                           TREE(TT_LSP_TUNNEL_IF_ID_SUBTREE));
4392         break;
4393
4394     case 4:
4395         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4396                             "C-type: 4 - Unnumbered interface with target");
4397         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 4,
4398                             "Router ID: %s",
4399                             ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
4400         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
4401                             "Interface ID: %u", tvb_get_ntohl(tvb, offset+8));
4402         proto_tree_add_text(rsvp_object_tree, tvb, offset+12, 4,
4403                             "Target IGP instance: %s",
4404                             ip_to_str(tvb_get_ptr(tvb, offset+12, 4)));
4405         proto_item_set_text(ti, "LSP INTERFACE-ID: Unnumbered with target, Router-ID %s,"
4406                             " Interface-ID %d, IGP instance %s",
4407                             ip_to_str(tvb_get_ptr(tvb, offset+4, 4)),
4408                             tvb_get_ntohl(tvb, offset+8),
4409                             ip_to_str(tvb_get_ptr(tvb, offset+12, 4)));
4410         action = tvb_get_guint8(tvb, offset+16);
4411         action >>= 4;
4412         proto_tree_add_text(rsvp_object_tree, tvb, offset+16, 1, "Action: %d - %s",
4413                             action,
4414                             val_to_str(action, lsp_tunnel_if_id_action_str, "Unknown"));
4415         dissect_rsvp_lsp_tunnel_if_id_tlv(rsvp_object_tree, tvb, offset+20, obj_length-20,
4416                                           TREE(TT_LSP_TUNNEL_IF_ID_SUBTREE));
4417         break;
4418
4419     default:
4420         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4421                             "C-type: Unknown (%u)",
4422                             type);
4423         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, obj_length-4,
4424                             "Data (%d bytes)", obj_length-4);
4425         break;
4426     }
4427 }
4428
4429 /*------------------------------------------------------------------------------
4430  * NOTIFY REQUEST
4431  *------------------------------------------------------------------------------*/
4432 static void
4433 dissect_rsvp_notify_request (proto_item *ti, proto_tree *rsvp_object_tree,
4434                              tvbuff_t *tvb,
4435                              int offset, int obj_length,
4436                              int class _U_, int type)
4437 {
4438     int offset2 = offset + 4;
4439
4440     switch(type) {
4441     case 1: {
4442         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4443                             "C-type: 1 - IPv4");
4444         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
4445                             "Notify node address: %s",
4446                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
4447         proto_item_append_text(ti, ": Notify node: %s",
4448                             ip_to_str(tvb_get_ptr(tvb, offset2, 4)));
4449         break;
4450     }
4451
4452     case 2: {
4453         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4454                             "C-type: 2 - IPv6");
4455         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16,
4456                             "Notify node address: %s",
4457                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
4458         proto_item_append_text(ti, ": Notify node: %s",
4459                                ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16)));
4460         break;
4461     }
4462
4463     default:
4464         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4465                             "C-type: Unknown (%u)",
4466                             type);
4467         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
4468                             "Data (%d bytes)", obj_length - 4);
4469     }
4470 }
4471
4472 /*------------------------------------------------------------------------------
4473  * GENERALIZED UNI
4474  *------------------------------------------------------------------------------*/
4475 static void
4476 dissect_rsvp_gen_uni (proto_tree *ti, proto_tree *rsvp_object_tree,
4477                       tvbuff_t *tvb,
4478                       int offset, int obj_length,
4479                       int class _U_, int type,
4480                       rsvp_conversation_info *rsvph)
4481 {
4482     int offset2 = offset + 4;
4483     int mylen, i, j, k, l, m;
4484     proto_item *ti2;
4485     proto_tree *rsvp_gen_uni_subtree, *rsvp_session_subtree, *rsvp_template_subtree;
4486     int s_len, s_class, s_type;
4487     int offset3;
4488
4489     proto_item_set_text(ti, "GENERALIZED UNI: ");
4490
4491     mylen = obj_length - 4;
4492     switch(type) {
4493     case 1: {
4494         const char *c;
4495         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4496                             "C-type: 1");
4497         for (i=1, l = 0; l < mylen; i++) {
4498             j = tvb_get_guint8(tvb, offset2+l+2);
4499             switch(j) {
4500             case 1:
4501             case 2: /* We do source and destination TNA together */
4502                 c = (j==1) ? "Source" : "Destination";
4503                 k = tvb_get_guint8(tvb, offset2+l+3);
4504                 switch(k) {
4505                 case 1:
4506                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4507                                               offset2+l, 8,
4508                                               "%s IPv4 TNA: %s", c,
4509                                               ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)));
4510                     rsvp_gen_uni_subtree =
4511                         proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4512                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4513                                         "Class: %d (%s)", j, c);
4514                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4515                                         "Type: 1 (IPv4)");
4516                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4517                                         "Length: %u",
4518                                         tvb_get_ntohs(tvb, offset2+l));
4519                     if (j==1)
4520                       proto_tree_add_item(rsvp_gen_uni_subtree, hf_rsvp_filter[RSVPF_GUNI_SRC_IPV4],
4521                                           tvb, offset2+l+4, 4, FALSE);
4522                     else
4523                       proto_tree_add_item(rsvp_gen_uni_subtree, hf_rsvp_filter[RSVPF_GUNI_DST_IPV4],
4524                                           tvb, offset2+l+4, 4, FALSE);
4525                     if (i < 4) {
4526                         proto_item_append_text(ti, "%s IPv4 TNA: %s", c,
4527                                                ip_to_str(tvb_get_ptr(tvb, offset2+l+4, 4)));
4528                     }
4529                     break;
4530
4531                 case 2:
4532                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4533                                               offset2+l, 20,
4534                                               "%s IPv6 TNA", c);
4535                     rsvp_gen_uni_subtree =
4536                         proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4537                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4538                                         "Class: %d (%s)", j, c);
4539                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4540                                         "Type: 2 (IPv6)");
4541                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4542                                         "Length: %u",
4543                                         tvb_get_ntohs(tvb, offset2+l));
4544                     if (j==1)
4545                       proto_tree_add_item(rsvp_gen_uni_subtree, hf_rsvp_filter[RSVPF_GUNI_SRC_IPV6],
4546                                           tvb, offset2+l+4, 16, FALSE);
4547                     else
4548                       proto_tree_add_item(rsvp_gen_uni_subtree, hf_rsvp_filter[RSVPF_GUNI_DST_IPV6],
4549                                           tvb, offset2+l+4, 16, FALSE);
4550                     if (i < 4) {
4551                         proto_item_append_text(ti, "%s IPv6 %s", c,
4552                                                ip6_to_str((const struct e_in6_addr *)
4553                                                           tvb_get_ptr(tvb, offset2+l+4, 16)));
4554                     }
4555                     break;
4556
4557                 case 3:
4558                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4559                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4560                                               "%s NSAP TNA", c);
4561                     rsvp_gen_uni_subtree =
4562                         proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4563                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4564                                         "Class: %d (%s)", j, c);
4565                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4566                                         "Type: 3 (NSAP)");
4567                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4568                                         "Length: %u",
4569                                         tvb_get_ntohs(tvb, offset2+l));
4570                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+4,
4571                                         tvb_get_ntohs(tvb, offset2+l)-4,
4572                                         "Data");
4573                     if (i < 4) {
4574                         proto_item_append_text(ti, "%s NSAP", c);
4575                     }
4576                     break;
4577
4578                 default:
4579                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4580                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4581                                               "%s UNKNOWN TNA", c);
4582                     rsvp_gen_uni_subtree =
4583                         proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4584                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4585                                         "Class: %d (%s)", j, c);
4586                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4587                                         "Type: %d (UNKNOWN)", j);
4588                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4589                                         "Length: %u",
4590                                         tvb_get_ntohs(tvb, offset2+l));
4591                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+4,
4592                                         tvb_get_ntohs(tvb, offset2+l)-4,
4593                                         "Data");
4594                     if (i < 4) {
4595                         proto_item_append_text(ti, "%s UNKNOWN", c);
4596                     }
4597                     break;
4598                 }
4599                 break;
4600
4601             case 3: /* Diversity subobject */
4602                 k = tvb_get_guint8(tvb, offset2+l+3);
4603                 switch(k) {
4604                 default:
4605                 case 1:
4606                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4607                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4608                                               "Diversity Subobject");
4609                     rsvp_gen_uni_subtree =
4610                         proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4611                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4612                                         "Class: %d (Diversity)", j);
4613                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4614                                         "Type: %d", tvb_get_guint8(tvb, offset2+l+3));
4615                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4616                                         "Length: %u",
4617                                         tvb_get_ntohs(tvb, offset2+l));
4618                     m = tvb_get_guint8(tvb, offset2+l+4) >> 4;
4619                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+4, 1,
4620                                         "Diversity: %d - %s", m,
4621                                         val_to_str(m, ouni_guni_diversity_str, "Unknown"));
4622                     s_len = tvb_get_ntohs(tvb, offset2+l+8);
4623                     s_class = tvb_get_guint8(tvb, offset2+l+10);
4624                     s_type = tvb_get_guint8(tvb, offset2+l+11);
4625                     ti2 = proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+8,
4626                                               s_len, "Session");
4627                     rsvp_session_subtree =
4628                         proto_item_add_subtree(ti2, TREE(rsvp_class_to_tree_type(s_class)));
4629                     if (s_len < 4) {
4630                         proto_tree_add_text(rsvp_object_tree, tvb, offset2+l+8, 2,
4631                             "Length: %u (bogus, must be >= 4)", s_len);
4632                         break;
4633                     }
4634                     proto_tree_add_text(rsvp_session_subtree, tvb, offset2+l+8, 2,
4635                                 "Length: %u", s_len);
4636                     proto_tree_add_uint(rsvp_session_subtree, hf_rsvp_filter[RSVPF_OBJECT], tvb,
4637                                 offset2+8+l+10, 1, s_class);
4638                     dissect_rsvp_session(ti2, rsvp_session_subtree, tvb, offset2+l+8,
4639                                          s_len, s_class, s_type, rsvph);
4640                     offset3 = offset2 + s_len;
4641                     s_len = tvb_get_ntohs(tvb, offset3+l+8);
4642                     s_class = tvb_get_guint8(tvb, offset3+l+10);
4643                     s_type = tvb_get_guint8(tvb, offset3+l+11);
4644                     ti2 = proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset3+l+8,
4645                                               s_len, "Template");
4646                     rsvp_template_subtree =
4647                         proto_item_add_subtree(ti2, TREE(rsvp_class_to_tree_type(s_class)));
4648                     if (s_len < 4) {
4649                         proto_tree_add_text(rsvp_object_tree, tvb, offset3+l+8, 2,
4650                             "Length: %u (bogus, must be >= 4)", s_len);
4651                         break;
4652                     }
4653                     proto_tree_add_text(rsvp_template_subtree, tvb, offset3+l+8, 2,
4654                                 "Length: %u", s_len);
4655                     proto_tree_add_uint(rsvp_template_subtree, hf_rsvp_filter[RSVPF_OBJECT], tvb,
4656                                 offset3+8+l+10, 1, s_class);
4657                     dissect_rsvp_template_filter(ti2, rsvp_template_subtree, tvb, offset3+l+8,
4658                                                  s_len, s_class, s_type, rsvph);
4659
4660                     if (i < 4) {
4661                         proto_item_append_text(ti, "Diversity");
4662                     }
4663                     break;
4664
4665                 }
4666                 break;
4667
4668             case 4: /* Egress Label */
4669                 k = tvb_get_guint8(tvb, offset2+l+3);
4670                 if (k == 1)             /* Egress label sub-type */
4671                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4672                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4673                                               "Egress Label Subobject");
4674                 else if (k == 2)        /* SPC_label sub-type (see G.7713.2) */
4675                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4676                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4677                                               "SPC Label Subobject");
4678                 else
4679                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4680                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4681                                               "Unknown Label Subobject");
4682                 rsvp_gen_uni_subtree = proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4683                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4684                                     "Class: %d (Egress/SPC Label)", j);
4685                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4686                                     "Type: %d", k);
4687                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4688                                     "Length: %u",
4689                                     tvb_get_ntohs(tvb, offset2+l));
4690                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+4, 1,
4691                                     "Direction: %s",
4692                                     decode_boolean_bitfield(
4693                                         tvb_get_guint8(tvb, offset2+l+4), 0x80, 8,
4694                                         "U: 1 - Upstream label/port ID",
4695                                         "U: 0 - Downstream label/port ID"));
4696                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+7, 1,
4697                                     "Label type: %u", tvb_get_guint8(tvb, offset2+l+7));
4698                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+8, 4,
4699                                     "Logical Port ID: %u", tvb_get_ntohl(tvb, offset2+l+8));
4700                 proto_item_append_text(ti2, ": %s, Label type %d, Port ID %d, Label ",
4701                                        tvb_get_guint8(tvb, offset2+l+4) & 0x80 ?
4702                                        "Upstream" : "Downstream",
4703                                        tvb_get_guint8(tvb, offset2+l+7),
4704                                        tvb_get_ntohl(tvb, offset2+l+8));
4705                 for (j=12; j < tvb_get_ntohs(tvb, offset2+l); j+=4) {
4706                         proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+j, 4,
4707                                             "Label: %u", tvb_get_ntohl(tvb, offset2+l+j));
4708                         proto_item_append_text(ti2, "%u ", tvb_get_ntohl(tvb, offset2+l+j));
4709                 }
4710                 if (i < 4) {
4711                         if (k == 1)
4712                             proto_item_append_text(ti, "Egress Label");
4713                         else if (k == 2)
4714                             proto_item_append_text(ti, "SPC Label");
4715                 }
4716                 break;
4717
4718             case 5: /* Service Level */
4719                 k = tvb_get_guint8(tvb, offset2+l+3);
4720                 switch(k) {
4721                 default:
4722                 case 1:
4723                     ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4724                                               offset2+l, tvb_get_ntohs(tvb, offset2+l),
4725                                               "Service Level Subobject");
4726                     rsvp_gen_uni_subtree =
4727                         proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4728                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+2, 1,
4729                                         "Class: %d (Egress Label)", j);
4730                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+3, 1,
4731                                         "Type: %d", tvb_get_guint8(tvb, offset2+l+3));
4732                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 2,
4733                                         "Length: %u",
4734                                         tvb_get_ntohs(tvb, offset2+l));
4735                     proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+4, 1,
4736                                         "Service Level: %u", tvb_get_guint8(tvb, offset2+l+4));
4737                     proto_item_append_text(ti2, ": %u", tvb_get_guint8(tvb, offset2+l+4));
4738                     if (i < 4) {
4739                         proto_item_append_text(ti, "Service Level %d", tvb_get_guint8(tvb, offset2+l+4));
4740                     }
4741                     break;
4742                 }
4743                 break;
4744
4745             default: /* Unknown subobject */
4746                 ti2 = proto_tree_add_text(rsvp_object_tree, tvb,
4747                                           offset2+l,
4748                                           tvb_get_ntohs(tvb, offset2+l),
4749                                           "Unknown subobject: %u",
4750                                           j);
4751                 rsvp_gen_uni_subtree =
4752                     proto_item_add_subtree(ti2, TREE(TT_GEN_UNI_SUBOBJ));
4753                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l, 1,
4754                                     "Type: %u (Unknown)", j);
4755                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+1, 1,
4756                                     "Length: %u",
4757                                     tvb_get_guint8(tvb, offset2+l+1));
4758
4759             }
4760
4761             if (tvb_get_guint8(tvb, offset2+l+1) < 1) {
4762                 proto_tree_add_text(rsvp_gen_uni_subtree, tvb, offset2+l+1, 1,
4763                     "Invalid length: %u", tvb_get_guint8(tvb, offset2+l+1));
4764                 return;
4765             }
4766             l += tvb_get_guint8(tvb, offset2+l+1);
4767             if (l < mylen) {
4768                 if (i < 4)
4769                     proto_item_append_text(ti, ", ");
4770                 else if (i==4)
4771                     proto_item_append_text(ti, "...");
4772             }
4773         }
4774         break;
4775     }
4776
4777     default:
4778         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4779                             "C-type: Unknown (%u)",
4780                             type);
4781         proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen,
4782                             "Data (%d bytes)", mylen);
4783         break;
4784     }
4785 }
4786
4787 /*------------------------------------------------------------------------------
4788  * CALL_ID
4789  *------------------------------------------------------------------------------*/
4790 static void
4791 dissect_rsvp_call_id (proto_tree *ti, proto_tree *rsvp_object_tree,
4792                       tvbuff_t *tvb,
4793                       int offset, int obj_length,
4794                       int class _U_, int c_type)
4795 {
4796     int type;
4797     char *str;
4798     int offset2 = offset + 4;
4799     int offset3, offset4, len;
4800
4801     static const value_string address_type_vals[] = {
4802         {1, "1 (IPv4)"},
4803         {2, "2 (IPv6)"},
4804         {3, "3 (NSAP)"},
4805         {4, "4 (MAC)"},
4806         {0x7f, "0x7f (Vendor-defined)"},
4807         {0, NULL}
4808     };
4809
4810     proto_item_set_text(ti, "CALL-ID: ");
4811     type = tvb_get_guint8 (tvb, offset2);
4812     switch(c_type) {
4813     case 0:
4814         proto_item_append_text(ti,"Empty");
4815         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4816                             "C-type: Empty (%u)", type);
4817         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length-4,
4818                               "Data (%d bytes)", obj_length-4);
4819         break;
4820     case 1:
4821     case 2:
4822         if (c_type == 1) {
4823             offset3 = offset2 + 4;
4824             len = obj_length - 16;
4825             proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4826                                 "C-type: 1 (operator specific)");
4827             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Address type: %s",
4828                                 val_to_str(type, address_type_vals, "Unknown (%u)"));
4829             proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 3, "Reserved: %u",
4830                                 tvb_get_ntoh24(tvb, offset2+1));
4831             proto_item_append_text(ti, "Operator-Specific. Addr Type: %s. ",
4832                                    val_to_str(type, address_type_vals, "Unknown (%u)"));
4833         }
4834         else {
4835             offset3 = offset2 + 16;
4836             len = obj_length - 28;
4837             proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4838                                 "C-type: 2 (globally unique)");
4839             proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Address type: %s",
4840                                 val_to_str(type, address_type_vals, "Unknown (%u)"));
4841             str = tvb_get_ephemeral_string (tvb, offset2 + 1, 3);
4842             proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 1, 3,
4843                                 "International Segment: %s", str);
4844             proto_item_append_text(ti, "Globally-Unique. Addr Type: %s. Intl Segment: %s. ",
4845                                    val_to_str(type, address_type_vals, "Unknown (%u)"), str);
4846             str = tvb_get_ephemeral_string (tvb, offset2 + 4, 12);
4847             proto_tree_add_text(rsvp_object_tree, tvb, offset2 + 4, 12,
4848                               "National Segment: %s", str);
4849             proto_item_append_text(ti, "Natl Segment: %s. ", str);
4850         }
4851
4852         switch(type) {
4853         case 1:
4854             offset4 = offset3 + 4;
4855             proto_tree_add_item(rsvp_object_tree, hf_rsvp_filter[RSVPF_CALL_ID_SRC_ADDR_IPV4],
4856                                 tvb, offset3, 4, FALSE);
4857             proto_item_append_text(ti, "Src: %s. ", ip_to_str(tvb_get_ptr(tvb, offset3, 4)));
4858             break;
4859
4860         case 2:
4861             offset4 = offset3 + 16;
4862             proto_tree_add_item(rsvp_object_tree, hf_rsvp_filter[RSVPF_CALL_ID_SRC_ADDR_IPV6],
4863                                 tvb, offset3, 16, FALSE);
4864             proto_item_append_text(ti, "Src: %s. ",
4865                                    ip6_to_str((const struct e_in6_addr *) tvb_get_ptr(tvb, offset3, 16)));
4866             break;
4867
4868         case 3:
4869             offset4 = offset3 + 20;
4870             proto_tree_add_text(rsvp_object_tree, tvb, offset3, 20, "Source Transport Network addr: %s",
4871                                 tvb_bytes_to_str(tvb, offset3, 20));
4872             proto_item_append_text(ti, "Src: %s. ", tvb_bytes_to_str(tvb, offset3, 20));
4873             break;
4874
4875         case 4:
4876             offset4 = offset3 + 6;
4877             proto_tree_add_text(rsvp_object_tree, tvb, offset3, 6, "Source Transport Network addr: %s",
4878                                 tvb_bytes_to_str(tvb, offset3, 6));
4879             proto_item_append_text(ti, "Src: %s. ", tvb_bytes_to_str(tvb, offset3, 6));
4880             break;
4881
4882         case 0x7F:
4883             offset4 = offset3 + len;
4884             proto_tree_add_text(rsvp_object_tree, tvb, offset3, len, "Source Transport Network addr: %s",
4885                                 tvb_bytes_to_str(tvb, offset3, len));
4886             proto_item_append_text(ti, "Src: %s. ", tvb_bytes_to_str(tvb, offset3, len));
4887             break;
4888
4889         default:
4890             offset4 = offset3 + len;
4891             proto_tree_add_text(rsvp_object_tree, tvb, offset3, len, "Unknown Transport Network type: %d",
4892                                 type);
4893         }
4894
4895         proto_tree_add_text(rsvp_object_tree, tvb, offset4, 8, "Local Identifier: %s",
4896                             tvb_bytes_to_str(tvb, offset4, 8));
4897         proto_item_append_text(ti, "Local ID: %s. ", tvb_bytes_to_str(tvb, offset4, 8));
4898         break;
4899
4900     default:
4901         proto_item_append_text(ti, " Unknown");
4902         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4903                             "C-type: Unknown (%u)", type);
4904         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
4905                             "Data (%d bytes)", obj_length - 4);
4906         break;
4907     }
4908 }
4909
4910 /*------------------------------------------------------------------------------
4911  * RESTART CAPABILITY
4912  *------------------------------------------------------------------------------*/
4913 static void
4914 dissect_rsvp_restart_cap (proto_tree *ti, proto_tree *rsvp_object_tree,
4915                           tvbuff_t *tvb,
4916                           int offset, int obj_length,
4917                           int class _U_, int type)
4918 {
4919     int offset2 = offset + 4;
4920
4921     proto_item_set_text(ti, "RESTART CAPABILITY: ");
4922     switch(type) {
4923     case 1:
4924         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4925                             "C-type: 1");
4926         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4,
4927                             "Restart Time: %d ms",
4928                             tvb_get_ntohl(tvb, offset2));
4929         proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4,
4930                             "Recovery Time: %d ms",
4931                             tvb_get_ntohl(tvb, offset2+4));
4932         proto_item_append_text(ti, "Restart Time: %d ms. Recovery Time: %d ms.",
4933                             tvb_get_ntohl(tvb, offset2), tvb_get_ntohl(tvb, offset2+4));
4934         break;
4935
4936     default:
4937         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4938                             "C-type: Unknown (%u)",
4939                             type);
4940         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
4941                             "Data (%d bytes)", obj_length - 4);
4942         break;
4943     }
4944 }
4945
4946 /*------------------------------------------------------------------------------
4947  * PROTECTION INFORMATION
4948  *------------------------------------------------------------------------------*/
4949 static void
4950 dissect_rsvp_protection_info (proto_tree *ti, proto_tree *rsvp_object_tree,
4951                               tvbuff_t *tvb,
4952                               int offset, int obj_length,
4953                               int class _U_, int type)
4954 {
4955     guint8 flags, flag;
4956     proto_tree *ti2, *rsvp_pi_flags_tree;
4957     int offset2 = offset + 4;
4958
4959     proto_item_set_text(ti, "PROTECTION_INFO: ");
4960     switch(type) {
4961     case 1:
4962         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
4963                             "C-type: 1 - Protection");
4964         flag = tvb_get_guint8(tvb, offset2);
4965         proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1,
4966                             "Secondary LSP: %s",
4967                             decode_boolean_bitfield(flag, 0x80, 8, "Yes", "No"));
4968
4969         flags = tvb_get_guint8(tvb, offset2+3);
4970         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+3, 1,
4971                                   "Link Flags: 0x%02x", flags);
4972         rsvp_pi_flags_tree = proto_item_add_subtree(ti2,
4973                                                     TREE(TT_PROTECTION_INFO));
4974         proto_tree_add_text(rsvp_pi_flags_tree, tvb, offset2+3, 1, "%s",
4975                             decode_boolean_bitfield(flags, 0x01, 8,
4976                                                     "Extra Traffic desired",
4977                                                     "Extra Traffic not desired"));
4978         proto_tree_add_text(rsvp_pi_flags_tree, tvb, offset2+3, 1, "%s",
4979                             decode_boolean_bitfield(flags, 0x02, 8,
4980                                                     "Unprotected desired",
4981                                                     "Unprotected not desired"));
4982         proto_tree_add_text(rsvp_pi_flags_tree, tvb, offset2+3, 1, "%s",
4983                             decode_boolean_bitfield(flags, 0x04, 8,
4984                                                     "Shared desired",
4985                                                     "Shared not desired"));
4986         proto_tree_add_text(rsvp_pi_flags_tree, tvb, offset2+3, 1, "%s",
4987                             decode_boolean_bitfield(flags, 0x08, 8,
4988                                                     "Dedicated 1:1 desired",
4989                                                     "Dedicated 1:1 not desired"));
4990         proto_tree_add_text(rsvp_pi_flags_tree, tvb, offset2+3, 1, "%s",
4991                             decode_boolean_bitfield(flags, 0x10, 8,
4992                                                     "Dedicated 1+1 desired",
4993                                                     "Dedicated 1+1 not desired"));
4994         proto_tree_add_text(rsvp_pi_flags_tree, tvb, offset2+3, 1, "%s",
4995                             decode_boolean_bitfield(flags, 0x20, 8,
4996                                                     "Enhanced desired",
4997                                                     "Enhanced not desired"));
4998         proto_item_append_text(ti, "%s%s%s%s%s%s%s.",
4999                                flag  &0x80 ? "SecondaryLSP " : "",
5000                                flags &0x01 ? "ExtraTraffic " : "",
5001                                flags &0x02 ? "Unprotected " : "",
5002                                flags &0x04 ? "Shared " : "",
5003                                flags &0x08 ? "Dedicated1:1 " : "",
5004                                flags &0x10 ? "Dedicated1+1 " : "",
5005                                flags &0x20 ? "Enhanced " : "");
5006         break;
5007
5008     default:
5009         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
5010                             "C-type: Unknown (%u)",
5011                             type);
5012         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
5013                             "Data (%d bytes)", obj_length - 4);
5014         break;
5015     }
5016 }
5017
5018 /*------------------------------------------------------------------------------
5019  * FAST REROUTE
5020  *------------------------------------------------------------------------------*/
5021 static void
5022 dissect_rsvp_fast_reroute (proto_tree *ti, proto_tree *rsvp_object_tree,
5023                            tvbuff_t *tvb,
5024                            int offset, int obj_length,
5025                            int class _U_, int type)
5026 {
5027     guint8 flags;
5028     proto_tree *ti2, *rsvp_frr_flags_tree;
5029
5030     proto_item_set_text(ti, "FAST_REROUTE: ");
5031     switch(type) {
5032     case 1:
5033     case 7:
5034         if ((type==1 && obj_length!=24) || (type==7 && obj_length!=20)) {
5035             proto_tree_add_text(rsvp_object_tree, tvb, offset, obj_length,
5036                                 "<<<Invalid length: cannot decode>>>");
5037             proto_item_append_text(ti, "Invalid length");
5038             break;
5039         }
5040         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
5041                             "C-type: %u", type);
5042         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, 1,
5043                             "Setup Priority: %d", tvb_get_guint8(tvb, offset+4));
5044         proto_tree_add_text(rsvp_object_tree, tvb, offset+5, 1,
5045                             "Hold Priority: %d", tvb_get_guint8(tvb, offset+5));
5046         proto_tree_add_text(rsvp_object_tree, tvb, offset+6, 1,
5047                             "Hop Limit: %d", tvb_get_guint8(tvb, offset+6));
5048
5049         flags = tvb_get_guint8(tvb, offset+7);
5050         ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset+7, 1,
5051                                   "Flags: 0x%02x", flags);
5052         rsvp_frr_flags_tree = proto_item_add_subtree(ti2,
5053                                                      TREE(TT_FAST_REROUTE_FLAGS));
5054         proto_tree_add_text(rsvp_frr_flags_tree, tvb, offset+7, 1, "%s",
5055                             decode_boolean_bitfield(flags, 0x01, 8,
5056                                                     "One-to-One Backup desired",
5057                                                     "One-to-One Backup not desired"));
5058         proto_tree_add_text(rsvp_frr_flags_tree, tvb, offset+7, 1, "%s",
5059                             decode_boolean_bitfield(flags, 0x02, 8,
5060                                                     "Facility Backup desired",
5061                                                     "Facility Backup not desired"));
5062         proto_tree_add_text(rsvp_object_tree, tvb, offset+8, 4,
5063                             "Bandwidth: %.10g", tvb_get_ntohieee_float(tvb, offset+8));
5064         proto_tree_add_text(rsvp_object_tree, tvb, offset+12, 4,
5065                             "Include-Any: 0x%0x", tvb_get_ntohl(tvb, offset+12));
5066         proto_tree_add_text(rsvp_object_tree, tvb, offset+16, 4,
5067                             "Exclude-Any: 0x%0x", tvb_get_ntohl(tvb, offset+16));
5068         if (type==1) {
5069             proto_tree_add_text(rsvp_object_tree, tvb, offset+20, 4,
5070                                 "Include-All: 0x%0x", tvb_get_ntohl(tvb, offset+20));
5071         }
5072
5073         proto_item_append_text(ti, "%s%s",
5074                                flags &0x01 ? "One-to-One Backup, " : "",
5075                                flags &0x02 ? "Facility Backup" : "");
5076         break;
5077
5078     default:
5079         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
5080                             "C-type: Unknown (%u)",
5081                             type);
5082         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, obj_length - 4,
5083                             "Data (%d bytes)", obj_length - 4);
5084         break;
5085     }
5086 }
5087
5088 /*------------------------------------------------------------------------------
5089  * DETOUR
5090  *------------------------------------------------------------------------------*/
5091 static void
5092 dissect_rsvp_detour (proto_tree *ti, proto_tree *rsvp_object_tree,
5093                      tvbuff_t *tvb,
5094                      int offset, int obj_length,
5095                      int class _U_, int type)
5096 {
5097     int remaining_length, count;
5098     int iter;
5099
5100     proto_item_set_text(ti, "DETOUR: ");
5101     switch(type) {
5102     case 7:
5103         iter = 0;
5104         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
5105                             "C-type: %u", type);
5106         for (remaining_length = obj_length - 4, count = 1;
5107              remaining_length > 0; remaining_length -= 8, count++) {
5108             if (remaining_length < 8) {
5109                 proto_tree_add_text(rsvp_object_tree, tvb, offset+remaining_length,
5110                                     obj_length-remaining_length,
5111                                     "<<<Invalid length: cannot decode>>>");
5112                 proto_item_append_text(ti, "Invalid length");
5113                 break;
5114             }
5115             iter++;
5116             proto_tree_add_text(rsvp_object_tree, tvb, offset+(4*iter), 4,
5117                                 "PLR ID %d: %s", count,
5118                                 ip_to_str(tvb_get_ptr(tvb, offset+(4*iter), 4)));
5119             iter++;
5120             proto_tree_add_text(rsvp_object_tree, tvb, offset+(4*iter), 4,
5121                                 "Avoid Node ID %d: %s", count,
5122                                 ip_to_str(tvb_get_ptr(tvb, offset+(4*iter), 4)));
5123         }
5124         break;
5125
5126     default:
5127         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
5128                             "C-type: Unknown (%u)",
5129                             type);
5130         proto_tree_add_text(rsvp_object_tree, tvb, offset+4, obj_length - 4,
5131                             "Data (%d bytes)", obj_length - 4);
5132         break;
5133     }
5134 }
5135
5136 /*------------------------------------------------------------------------------
5137  * DIFFSERV
5138  *------------------------------------------------------------------------------*/
5139 static void
5140 dissect_rsvp_diffserv (proto_tree *ti, proto_tree *rsvp_object_tree,
5141                        tvbuff_t *tvb,
5142                        int offset, int obj_length,
5143                        int class _U_, int type)
5144 {
5145     int mapnb, count;
5146     int *hfindexes[] = {
5147         &hf_rsvp_filter[RSVPF_DIFFSERV_MAP],
5148         &hf_rsvp_filter[RSVPF_DIFFSERV_MAP_EXP],
5149         &hf_rsvp_filter[RSVPF_DIFFSERV_PHBID],
5150         &hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_DSCP],
5151         &hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_CODE],
5152         &hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_BIT14],
5153         &hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_BIT15]
5154     };
5155     gint *etts[] = {
5156         &TREE(TT_DIFFSERV_MAP),
5157         &TREE(TT_DIFFSERV_MAP_PHBID)
5158     };
5159
5160     proto_item_set_text(ti, "DIFFSERV: ");
5161     offset += 3;
5162     switch (type) {
5163     case 1:
5164         proto_tree_add_text(rsvp_object_tree, tvb, offset, 1,
5165                             "C-type: 1 - E-LSP");
5166         proto_tree_add_uint(rsvp_object_tree, hf_rsvp_filter[RSVPF_DIFFSERV_MAPNB],
5167                             tvb, offset + 4, 1,
5168                             mapnb = tvb_get_guint8(tvb, offset + 4) & 15);
5169         proto_item_append_text(ti, "E-LSP, %u MAP%s", mapnb,
5170                                (mapnb == 0) ? "" : "s");
5171         offset += 5;
5172
5173         for (count = 0; count < mapnb; count++) {
5174             dissect_diffserv_mpls_common(tvb, rsvp_object_tree, type,
5175                                          offset, hfindexes, etts);
5176             offset += 4;
5177         }
5178         break;
5179     case 2:
5180         proto_item_append_text(ti, "L-LSP");
5181         proto_tree_add_text(rsvp_object_tree, tvb, offset, 1,
5182                             "C-type: 2 - L-LSP");
5183         dissect_diffserv_mpls_common(tvb, rsvp_object_tree, type,
5184                                      offset + 3, hfindexes, etts);
5185         break;
5186     default:
5187         proto_tree_add_text(rsvp_object_tree, tvb, offset, 1,
5188                             "C-type: Unknown (%u)", type);
5189         proto_tree_add_text(rsvp_object_tree, tvb, offset + 1, obj_length - 4,
5190                             "Data (%d bytes)", obj_length - 4);
5191     }
5192 }
5193
5194 /*------------------------------------------------------------------------------
5195  * CLASSTYPE
5196  *------------------------------------------------------------------------------*/
5197 static void
5198 dissect_rsvp_diffserv_aware_te(proto_tree *ti, proto_tree *rsvp_object_tree,
5199                                tvbuff_t *tvb,
5200                                int offset, int obj_length,
5201                                int class _U_, int type)
5202 {
5203     proto_item *hidden_item;
5204     int offset2 = offset + 4;
5205     guint8 ct = 0;
5206
5207     hidden_item = proto_tree_add_item(rsvp_object_tree,
5208                                hf_rsvp_filter[RSVPF_DSTE],
5209                                tvb, offset, 8, FALSE);
5210     PROTO_ITEM_SET_HIDDEN(hidden_item);
5211
5212     switch(type) {
5213     case 1:
5214         ct = tvb_get_guint8(tvb, offset2+3);
5215         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1");
5216         proto_tree_add_item(rsvp_object_tree,
5217                             hf_rsvp_filter[RSVPF_DSTE_CLASSTYPE],
5218                             tvb, offset2+3, 1, FALSE);
5219         proto_item_set_text(ti, "CLASSTYPE: CT %u", ct);
5220         break;
5221     default:
5222         proto_item_set_text(ti, "CLASSTYPE: (Unknown C-type)");
5223         proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1,
5224                             "C-type: Unknown (%u)", type);
5225         proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
5226                             "Data (%d bytes)", obj_length - 4);
5227         break;
5228     }
5229 }
5230
5231 /*------------------------------------------------------------------------------
5232  * Dissect a single RSVP message in a tree
5233  *------------------------------------------------------------------------------*/
5234 static void
5235 dissect_rsvp_msg_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5236                       int tree_mode, rsvp_conversation_info *rsvph)
5237 {
5238     proto_tree *rsvp_tree = NULL;
5239     proto_tree *rsvp_header_tree;
5240     proto_tree *rsvp_object_tree;
5241     proto_tree *ti;
5242     proto_item *hidden_item;
5243     guint16 cksum, computed_cksum;
5244     vec_t cksum_vec[1];
5245     int offset = 0;
5246     int len;
5247     guint8 ver_flags;
5248     guint8 message_type;
5249     int session_off, tempfilt_off;
5250     int msg_length;
5251     int obj_length;
5252     int offset2;
5253
5254     offset = 0;
5255     len = 0;
5256     ver_flags = tvb_get_guint8(tvb, 0);
5257     msg_length = tvb_get_ntohs(tvb, 6);
5258     message_type = tvb_get_guint8(tvb, 1);
5259
5260     ti = proto_tree_add_item(tree, proto_rsvp, tvb, offset, msg_length,
5261                              FALSE);
5262     rsvp_tree = proto_item_add_subtree(ti, tree_mode);
5263     if (pinfo->ipproto == IP_PROTO_RSVPE2EI)
5264         proto_item_append_text(rsvp_tree, " (E2E-IGNORE)");
5265     proto_item_append_text(rsvp_tree, ": ");
5266     proto_item_append_text(rsvp_tree, "%s", val_to_str(message_type, message_type_vals,
5267                                                  "Unknown (%u). "));
5268     find_rsvp_session_tempfilt(tvb, 0, &session_off, &tempfilt_off);
5269     if (session_off)
5270         proto_item_append_text(rsvp_tree, "%s", summary_session(tvb, session_off));
5271     if (tempfilt_off)
5272         proto_item_append_text(rsvp_tree, "%s", summary_template(tvb, tempfilt_off));
5273
5274     ti = proto_tree_add_text(rsvp_tree, tvb, offset, 8, "RSVP Header. %s",
5275                              val_to_str(message_type, message_type_vals,
5276                                         "Unknown Message (%u). "));
5277     if (pinfo->ipproto == IP_PROTO_RSVPE2EI)
5278         proto_item_append_text(ti, " (E2E-IGNORE)");
5279     rsvp_header_tree = proto_item_add_subtree(ti, TREE(TT_HDR));
5280
5281     proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "RSVP Version: %u",
5282                         (ver_flags & 0xf0)>>4);
5283     proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "Flags: %02x",
5284                         ver_flags & 0xf);
5285     proto_tree_add_uint(rsvp_header_tree, hf_rsvp_filter[RSVPF_MSG], tvb,
5286                         offset+1, 1, message_type);
5287     switch (RSVPF_MSG + message_type) {
5288
5289     case RSVPF_PATH:
5290     case RSVPF_RESV:
5291     case RSVPF_PATHERR:
5292     case RSVPF_RESVERR:
5293     case RSVPF_PATHTEAR:
5294     case RSVPF_RESVTEAR:
5295     case RSVPF_RCONFIRM:
5296     case RSVPF_RTEARCONFIRM:
5297     case RSVPF_BUNDLE:
5298     case RSVPF_ACK:
5299     case RSVPF_SREFRESH:
5300     case RSVPF_HELLO:
5301     case RSVPF_NOTIFY:
5302         hidden_item = proto_tree_add_boolean(rsvp_header_tree, hf_rsvp_filter[RSVPF_MSG + message_type], tvb,
5303                                       offset+1, 1, 1);
5304         PROTO_ITEM_SET_HIDDEN(hidden_item);
5305         break;
5306
5307     default:
5308         proto_tree_add_protocol_format(rsvp_header_tree, proto_malformed, tvb, offset+1, 1,
5309                                        "Invalid message type: %u", message_type);
5310         return;
5311     }
5312
5313     cksum = tvb_get_ntohs(tvb, offset+2);
5314     if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) {
5315         /* The packet isn't part of a fragmented datagram and isn't
5316            truncated, so we can checksum it. */
5317         cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length);
5318         cksum_vec[0].len = msg_length;
5319         computed_cksum = in_cksum(&cksum_vec[0], 1);
5320         if (computed_cksum == 0) {
5321             proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
5322                                 "Message Checksum: 0x%04x [correct]",
5323                                 cksum);
5324         } else {
5325             proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
5326                                 "Message Checksum: 0x%04x [incorrect, should be 0x%04x]",
5327                                 cksum,
5328                                 in_cksum_shouldbe(cksum, computed_cksum));
5329         }
5330     } else {
5331         proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2,
5332                             "Message Checksum: 0x%04x",
5333                             cksum);
5334     }
5335     proto_tree_add_text(rsvp_header_tree, tvb, offset+4, 1,
5336                         "Sending TTL: %u",
5337                         tvb_get_guint8(tvb, offset+4));
5338     proto_tree_add_text(rsvp_header_tree, tvb, offset+6, 2,
5339                         "Message length: %u", msg_length);
5340
5341     offset = 8;
5342     len = 8;
5343
5344     if (message_type == RSVP_MSG_BUNDLE) {
5345         /* Bundle message. Dissect component messages */
5346         if (rsvp_bundle_dissect) {
5347             int len = 8;
5348             while (len < msg_length) {
5349                 gint sub_len;
5350                 tvbuff_t *tvb_sub;
5351                 sub_len = tvb_get_ntohs(tvb, len+6);
5352                 tvb_sub = tvb_new_subset(tvb, len, sub_len, sub_len);
5353                 dissect_rsvp_msg_tree(tvb_sub, pinfo, rsvp_tree, TREE(TT_BUNDLE_COMPMSG), rsvph);
5354                 len += sub_len;
5355             }
5356         } else {
5357             proto_tree_add_text(rsvp_tree, tvb, offset, msg_length - len,
5358                                 "Bundle Component Messages Not Dissected");
5359         }
5360         return;
5361     }
5362
5363     while (len < msg_length) {
5364         guint8 class;
5365         guint8 type;
5366
5367         obj_length = tvb_get_ntohs(tvb, offset);
5368         class = tvb_get_guint8(tvb, offset+2);
5369         type = tvb_get_guint8(tvb, offset+3);
5370         ti = proto_tree_add_item(rsvp_tree, hf_rsvp_filter[rsvp_class_to_filter_num(class)],
5371                                  tvb, offset, obj_length, FALSE);
5372         rsvp_object_tree = proto_item_add_subtree(ti, TREE(rsvp_class_to_tree_type(class)));
5373         if (obj_length < 4) {
5374             proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
5375                                 "Length: %u (bogus, must be >= 4)", obj_length);
5376             break;
5377         }
5378         proto_tree_add_text(rsvp_object_tree, tvb, offset, 2,
5379                             "Length: %u", obj_length);
5380         proto_tree_add_uint(rsvp_object_tree, hf_rsvp_filter[RSVPF_OBJECT], tvb,
5381                             offset+2, 1, class);
5382
5383         offset2 = offset+4;
5384
5385         switch(class) {
5386
5387         case RSVP_CLASS_SESSION:
5388             dissect_rsvp_session(ti, rsvp_object_tree, tvb, offset, obj_length, class, type, rsvph);
5389             break;
5390
5391         case RSVP_CLASS_HOP:
5392             dissect_rsvp_hop(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5393             break;
5394
5395         case RSVP_CLASS_TIME_VALUES:
5396             dissect_rsvp_time_values(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5397             break;
5398
5399         case RSVP_CLASS_ERROR:
5400             dissect_rsvp_error(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5401             break;
5402
5403         case RSVP_CLASS_SCOPE:
5404             dissect_rsvp_scope(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5405             break;
5406
5407         case RSVP_CLASS_STYLE:
5408             dissect_rsvp_style(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5409             break;
5410
5411         case RSVP_CLASS_CONFIRM:
5412             dissect_rsvp_confirm(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5413             break;
5414
5415         case RSVP_CLASS_SENDER_TEMPLATE:
5416         case RSVP_CLASS_FILTER_SPEC:
5417             dissect_rsvp_template_filter(ti, rsvp_object_tree, tvb, offset, obj_length, class, type, rsvph);
5418             break;
5419
5420         case RSVP_CLASS_SENDER_TSPEC:
5421             dissect_rsvp_tspec(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5422             break;
5423
5424         case RSVP_CLASS_FLOWSPEC:
5425             dissect_rsvp_flowspec(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5426             break;
5427
5428         case RSVP_CLASS_ADSPEC:
5429             dissect_rsvp_adspec(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5430             break;
5431
5432         case RSVP_CLASS_INTEGRITY:
5433             dissect_rsvp_integrity(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5434             break;
5435
5436         case RSVP_CLASS_POLICY:
5437             dissect_rsvp_policy(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5438             break;
5439
5440         case RSVP_CLASS_LABEL_REQUEST:
5441             dissect_rsvp_label_request(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5442             break;
5443
5444         case RSVP_CLASS_RECOVERY_LABEL:
5445         case RSVP_CLASS_UPSTREAM_LABEL:
5446         case RSVP_CLASS_SUGGESTED_LABEL:
5447         case RSVP_CLASS_LABEL:
5448             dissect_rsvp_label(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5449             break;
5450
5451         case RSVP_CLASS_LABEL_SET:
5452             dissect_rsvp_label_set(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5453             break;
5454
5455         case RSVP_CLASS_SESSION_ATTRIBUTE:
5456             dissect_rsvp_session_attribute(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5457             break;
5458
5459         case RSVP_CLASS_EXPLICIT_ROUTE:
5460             dissect_rsvp_explicit_route(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5461             break;
5462
5463         case RSVP_CLASS_RECORD_ROUTE:
5464             dissect_rsvp_record_route(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5465             break;
5466
5467         case RSVP_CLASS_MESSAGE_ID:
5468             dissect_rsvp_message_id(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5469             break;
5470
5471         case RSVP_CLASS_MESSAGE_ID_ACK:
5472             dissect_rsvp_message_id_ack(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5473             break;
5474
5475         case RSVP_CLASS_MESSAGE_ID_LIST:
5476             dissect_rsvp_message_id_list(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5477             break;
5478
5479         case RSVP_CLASS_HELLO:
5480             dissect_rsvp_hello(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5481             break;
5482
5483         case RSVP_CLASS_DCLASS:
5484             dissect_rsvp_dclass(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5485             break;
5486
5487         case RSVP_CLASS_ADMIN_STATUS:
5488             dissect_rsvp_admin_status(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5489             break;
5490
5491         case RSVP_CLASS_ASSOCIATION:
5492             dissect_rsvp_association(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5493             break;
5494
5495         case RSVP_CLASS_LSP_TUNNEL_IF_ID:
5496             dissect_rsvp_lsp_tunnel_if_id(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5497             break;
5498
5499         case RSVP_CLASS_NOTIFY_REQUEST:
5500             dissect_rsvp_notify_request(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5501             break;
5502
5503         case RSVP_CLASS_GENERALIZED_UNI:
5504             dissect_rsvp_gen_uni(ti, rsvp_object_tree, tvb, offset, obj_length, class, type, rsvph);
5505             break;
5506
5507         case RSVP_CLASS_CALL_ID:
5508             dissect_rsvp_call_id(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5509             break;
5510
5511         case RSVP_CLASS_RESTART_CAP:
5512             dissect_rsvp_restart_cap(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5513             break;
5514
5515         case RSVP_CLASS_PROTECTION:
5516             dissect_rsvp_protection_info(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5517             break;
5518
5519         case RSVP_CLASS_FAST_REROUTE:
5520             dissect_rsvp_fast_reroute(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5521             break;
5522
5523         case RSVP_CLASS_DETOUR:
5524             dissect_rsvp_detour(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5525             break;
5526
5527         case RSVP_CLASS_DIFFSERV:
5528             dissect_rsvp_diffserv(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5529             break;
5530
5531         case RSVP_CLASS_CLASSTYPE:
5532             dissect_rsvp_diffserv_aware_te(ti, rsvp_object_tree, tvb, offset, obj_length, class, type);
5533             break;
5534
5535         case RSVP_CLASS_NULL:
5536         default:
5537             proto_tree_add_text(rsvp_object_tree, tvb, offset2, obj_length - 4,
5538                                 "Data (%d bytes)", obj_length - 4);
5539             break;
5540         }
5541
5542         offset += obj_length;
5543         len += obj_length;
5544     }
5545 }
5546
5547 /*------------------------------------------------------------------------------
5548  * The main loop
5549  *------------------------------------------------------------------------------*/
5550 static void
5551 dissect_rsvp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5552 {
5553     guint8 ver_flags;
5554     guint8 message_type;
5555     int msg_length;
5556     int session_off, tempfilt_off;
5557     rsvp_conversation_info *rsvph;
5558
5559
5560     conversation_t *conversation;
5561     struct rsvp_request_key request_key, *new_request_key;
5562     struct rsvp_request_val *request_val = NULL;
5563
5564         col_set_str(pinfo->cinfo, COL_PROTOCOL,
5565                     (pinfo->ipproto == IP_PROTO_RSVPE2EI) ? "RSVP-E2EI" : "RSVP");
5566     col_clear(pinfo->cinfo, COL_INFO);
5567
5568     ver_flags = tvb_get_guint8(tvb, 0);
5569     message_type = tvb_get_guint8(tvb, 1);
5570     msg_length = tvb_get_ntohs(tvb, 6);
5571
5572     rsvph = ep_alloc0(sizeof(rsvp_conversation_info));
5573
5574     /* Copy over the source and destination addresses from the pinfo strucutre */
5575     SET_ADDRESS(&rsvph->source, pinfo->src.type, pinfo->src.len, pinfo->src.data);
5576     SET_ADDRESS(&rsvph->destination, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
5577
5578     col_add_str(pinfo->cinfo, COL_INFO,
5579           val_to_str(message_type, message_type_vals, "Unknown (%u). "));
5580         find_rsvp_session_tempfilt(tvb, 0, &session_off, &tempfilt_off);
5581         if (session_off)
5582             col_append_str(pinfo->cinfo, COL_INFO, summary_session(tvb, session_off));
5583         if (tempfilt_off)
5584             col_append_str(pinfo->cinfo, COL_INFO, summary_template(tvb, tempfilt_off));
5585     
5586
5587         col_add_str(pinfo->cinfo, COL_INFO,
5588                     val_to_str(message_type, message_type_vals, "Unknown (%u). "));
5589         if (message_type == RSVP_MSG_BUNDLE) {
5590             col_set_str(pinfo->cinfo, COL_INFO,
5591                         rsvp_bundle_dissect ?
5592                         "Component Messages Dissected" :
5593                         "Component Messages Not Dissected");
5594         } else {
5595             find_rsvp_session_tempfilt(tvb, 0, &session_off, &tempfilt_off);
5596             if (session_off)
5597                         col_append_str(pinfo->cinfo, COL_INFO, summary_session(tvb, session_off));
5598             if (tempfilt_off)
5599                         col_append_str(pinfo->cinfo, COL_INFO, summary_template(tvb, tempfilt_off));
5600         }
5601
5602     if (tree) {
5603                 dissect_rsvp_msg_tree(tvb, pinfo, tree, TREE(TT_RSVP), rsvph);
5604     }
5605
5606     /* Find out what conversation this packet is part of. */
5607     conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
5608                                      pinfo->ptype, pinfo->srcport,
5609                                      pinfo->destport, 0);
5610
5611     if (conversation == NULL) {
5612         /* Not part of any conversation; create a new one. */
5613         conversation =
5614             conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
5615                              pinfo->ptype, pinfo->srcport,
5616                              pinfo->destport, 0);
5617     }
5618
5619     /* Now build the request key */
5620     memset(&request_key, 0, sizeof(request_key));
5621     request_key.conversation = conversation->index;
5622     request_key.session_type = rsvph->session_type;
5623
5624     switch (request_key.session_type) {
5625     case RSVP_SESSION_TYPE_IPV4:
5626         SET_ADDRESS(&request_key.u.session_ipv4.destination,
5627                     rsvph->destination.type, rsvph->destination.len,
5628                     rsvph->destination.data);
5629         request_key.u.session_ipv4.protocol = rsvph->protocol;
5630         request_key.u.session_ipv4.udp_dest_port = rsvph->udp_dest_port;
5631         break;
5632
5633     case RSVP_SESSION_TYPE_IPV6:
5634         /* Not supported yet */
5635         break;
5636
5637     case RSVP_SESSION_TYPE_IPV4_LSP:
5638         SET_ADDRESS(&request_key.u.session_ipv4_lsp.destination,
5639                     rsvph->destination.type, rsvph->destination.len,
5640                     rsvph->destination.data);
5641         request_key.u.session_ipv4_lsp.udp_dest_port = rsvph->udp_dest_port;
5642         request_key.u.session_ipv4_lsp.ext_tunnel_id = rsvph->ext_tunnel_id;
5643         break;
5644
5645     case RSVP_SESSION_TYPE_AGGREGATE_IPV4:
5646         SET_ADDRESS(&request_key.u.session_agg_ipv4.destination,
5647                     rsvph->destination.type, rsvph->destination.len,
5648                     rsvph->destination.data);
5649         request_key.u.session_agg_ipv4.dscp = rsvph->dscp;
5650         break;
5651
5652     case RSVP_SESSION_TYPE_IPV4_UNI:
5653         SET_ADDRESS(&request_key.u.session_ipv4_uni.destination,
5654                     rsvph->destination.type, rsvph->destination.len,
5655                     rsvph->destination.data);
5656         request_key.u.session_ipv4_uni.udp_dest_port = rsvph->udp_dest_port;
5657         request_key.u.session_ipv4_uni.ext_tunnel_id = rsvph->ext_tunnel_id;
5658         break;
5659
5660     case RSVP_SESSION_TYPE_IPV4_E_NNI:
5661         SET_ADDRESS(&request_key.u.session_ipv4_enni.destination,
5662                     rsvph->destination.type, rsvph->destination.len,
5663                     rsvph->destination.data);
5664         request_key.u.session_ipv4_enni.udp_dest_port = rsvph->udp_dest_port;
5665         request_key.u.session_ipv4_enni.ext_tunnel_id = rsvph->ext_tunnel_id;
5666         break;
5667     default:
5668         /* This should never happen. */
5669         if (tree) {
5670             proto_tree_add_text(tree, tvb, 0, 0, "Unknown session type");
5671         }
5672         break;
5673     }
5674
5675     SE_COPY_ADDRESS(&request_key.source_info.source, &rsvph->source);
5676     request_key.source_info.udp_source_port = rsvph->udp_source_port;
5677
5678     /* See if a request with this key already exists */
5679     request_val =
5680         (struct rsvp_request_val *) g_hash_table_lookup(rsvp_request_hash,
5681                                                         &request_key);
5682
5683     /* If not, insert the new request key into the hash table */
5684     if (!request_val) {
5685                 new_request_key = se_memdup(&request_key, sizeof(struct rsvp_request_key));
5686
5687                 request_val = se_alloc(sizeof(struct rsvp_request_val));
5688                 request_val->value = conversation->index;
5689
5690                 g_hash_table_insert(rsvp_request_hash, new_request_key, request_val);
5691     }
5692
5693     tap_queue_packet(rsvp_tap, pinfo, rsvph);
5694 }
5695
5696 static void
5697 register_rsvp_prefs (void)
5698 {
5699     module_t *rsvp_module;
5700
5701     rsvp_module = prefs_register_protocol(proto_rsvp, NULL);
5702     prefs_register_bool_preference(
5703         rsvp_module, "process_bundle",
5704         "Dissect sub-messages in BUNDLE message",
5705         "Specifies whether Wireshark should decode and display sub-messages within BUNDLE messages",
5706         &rsvp_bundle_dissect);
5707 }
5708
5709 void
5710 proto_register_rsvp(void)
5711 {
5712     gint i;
5713
5714         static hf_register_info rsvpf_info[] = {
5715
5716                 /* Message type number */
5717                 {&hf_rsvp_filter[RSVPF_MSG],
5718                  { "Message Type", "rsvp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0,
5719                         NULL, HFILL }},
5720
5721                 /* Message type shorthands */
5722                 {&hf_rsvp_filter[RSVPF_PATH],
5723                  { "Path Message", "rsvp.path", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5724                         NULL, HFILL }},
5725
5726                 {&hf_rsvp_filter[RSVPF_RESV],
5727                  { "Resv Message", "rsvp.resv", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5728                         NULL, HFILL }},
5729
5730                 {&hf_rsvp_filter[RSVPF_PATHERR],
5731                  { "Path Error Message", "rsvp.perr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5732                         NULL, HFILL }},
5733
5734                 {&hf_rsvp_filter[RSVPF_RESVERR],
5735                  { "Resv Error Message", "rsvp.rerr", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5736                         NULL, HFILL }},
5737
5738                 {&hf_rsvp_filter[RSVPF_PATHTEAR],
5739                  { "Path Tear Message", "rsvp.ptear", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5740                         NULL, HFILL }},
5741
5742                 {&hf_rsvp_filter[RSVPF_RESVTEAR],
5743                  { "Resv Tear Message", "rsvp.rtear", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5744                         NULL, HFILL }},
5745
5746                 {&hf_rsvp_filter[RSVPF_RCONFIRM],
5747                  { "Resv Confirm Message", "rsvp.resvconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5748                         NULL, HFILL }},
5749
5750                 {&hf_rsvp_filter[RSVPF_RTEARCONFIRM],
5751                  { "Resv Tear Confirm Message", "rsvp.rtearconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5752                         NULL, HFILL }},
5753
5754                 {&hf_rsvp_filter[RSVPF_BUNDLE],
5755                  { "Bundle Message", "rsvp.bundle", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5756                         NULL, HFILL }},
5757
5758                 {&hf_rsvp_filter[RSVPF_ACK],
5759                  { "Ack Message", "rsvp.ack", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5760                         NULL, HFILL }},
5761
5762                 {&hf_rsvp_filter[RSVPF_SREFRESH],
5763                  { "Srefresh Message", "rsvp.srefresh", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5764                         NULL, HFILL }},
5765
5766                 {&hf_rsvp_filter[RSVPF_HELLO],
5767                  { "HELLO Message", "rsvp.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5768                         NULL, HFILL }},
5769
5770                 /* Object class */
5771                 {&hf_rsvp_filter[RSVPF_OBJECT],
5772                  { "Object class", "rsvp.object", FT_UINT8, BASE_DEC, VALS(rsvp_class_vals), 0x0,
5773                         NULL, HFILL }},
5774
5775                 {&hf_rsvp_filter[RSVPF_NOTIFY],
5776                  { "Notify Message", "rsvp.notify", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5777                    NULL, HFILL }},
5778
5779                 /* Object present shorthands */
5780                 {&hf_rsvp_filter[RSVPF_SESSION],
5781                  { "SESSION", "rsvp.session", FT_NONE, BASE_NONE, NULL, 0x0,
5782                         NULL, HFILL }},
5783
5784                 {&hf_rsvp_filter[RSVPF_HOP],
5785                  { "HOP", "rsvp.hop", FT_NONE, BASE_NONE, NULL, 0x0,
5786                         NULL, HFILL }},
5787
5788                 {&hf_rsvp_filter[RSVPF_HELLO_OBJ],
5789                  { "HELLO Request/Ack", "rsvp.hello_obj", FT_NONE, BASE_NONE, NULL, 0x0,
5790                         NULL, HFILL }},
5791
5792                 {&hf_rsvp_filter[RSVPF_INTEGRITY],
5793                  { "INTEGRITY", "rsvp.integrity", FT_NONE, BASE_NONE, NULL, 0x0,
5794                         NULL, HFILL }},
5795
5796                 {&hf_rsvp_filter[RSVPF_TIME_VALUES],
5797                  { "TIME VALUES", "rsvp.time", FT_NONE, BASE_NONE, NULL, 0x0,
5798                         NULL, HFILL }},
5799
5800                 {&hf_rsvp_filter[RSVPF_ERROR],
5801                  { "ERROR", "rsvp.error", FT_NONE, BASE_NONE, NULL, 0x0,
5802                         NULL, HFILL }},
5803
5804                 {&hf_rsvp_filter[RSVPF_SCOPE],
5805                  { "SCOPE", "rsvp.scope", FT_NONE, BASE_NONE, NULL, 0x0,
5806                         NULL, HFILL }},
5807
5808                 {&hf_rsvp_filter[RSVPF_STYLE],
5809                  { "STYLE", "rsvp.style", FT_NONE, BASE_NONE, NULL, 0x0,
5810                         NULL, HFILL }},
5811
5812                 {&hf_rsvp_filter[RSVPF_FLOWSPEC],
5813                  { "FLOWSPEC", "rsvp.flowspec", FT_NONE, BASE_NONE, NULL, 0x0,
5814                         NULL, HFILL }},
5815
5816                 {&hf_rsvp_filter[RSVPF_FILTER_SPEC],
5817                  { "FILTERSPEC", "rsvp.filter", FT_NONE, BASE_NONE, NULL, 0x0,
5818                         NULL, HFILL }},
5819
5820                 {&hf_rsvp_filter[RSVPF_SENDER],
5821                  { "SENDER TEMPLATE", "rsvp.sender", FT_NONE, BASE_NONE, NULL, 0x0,
5822                         NULL, HFILL }},
5823
5824                 {&hf_rsvp_filter[RSVPF_TSPEC],
5825                  { "SENDER TSPEC", "rsvp.tspec", FT_NONE, BASE_NONE, NULL, 0x0,
5826                         NULL, HFILL }},
5827
5828                 {&hf_rsvp_filter[RSVPF_ADSPEC],
5829                  { "ADSPEC", "rsvp.adspec", FT_NONE, BASE_NONE, NULL, 0x0,
5830                         NULL, HFILL }},
5831
5832                 {&hf_rsvp_filter[RSVPF_POLICY],
5833                  { "POLICY", "rsvp.policy", FT_NONE, BASE_NONE, NULL, 0x0,
5834                         NULL, HFILL }},
5835
5836                 {&hf_rsvp_filter[RSVPF_CONFIRM],
5837                  { "CONFIRM", "rsvp.confirm", FT_NONE, BASE_NONE, NULL, 0x0,
5838                         NULL, HFILL }},
5839
5840                 {&hf_rsvp_filter[RSVPF_LABEL],
5841                  { "LABEL", "rsvp.label", FT_NONE, BASE_NONE, NULL, 0x0,
5842                         NULL, HFILL }},
5843
5844                 {&hf_rsvp_filter[RSVPF_RECOVERY_LABEL],
5845                  { "RECOVERY LABEL", "rsvp.recovery_label", FT_NONE, BASE_NONE, NULL, 0x0,
5846                         NULL, HFILL }},
5847
5848                 {&hf_rsvp_filter[RSVPF_UPSTREAM_LABEL],
5849                  { "UPSTREAM LABEL", "rsvp.upstream_label", FT_NONE, BASE_NONE, NULL, 0x0,
5850                         NULL, HFILL }},
5851
5852                 {&hf_rsvp_filter[RSVPF_SUGGESTED_LABEL],
5853                  { "SUGGESTED LABEL", "rsvp.suggested_label", FT_NONE, BASE_NONE, NULL, 0x0,
5854                         NULL, HFILL }},
5855
5856                 {&hf_rsvp_filter[RSVPF_LABEL_SET],
5857                  { "LABEL SET", "rsvp.label_set", FT_NONE, BASE_NONE, NULL, 0x0,
5858                         NULL, HFILL }},
5859
5860                 {&hf_rsvp_filter[RSVPF_ACCEPTABLE_LABEL_SET],
5861                  { "ACCEPTABLE LABEL SET", "rsvp.acceptable_label_set", FT_NONE, BASE_NONE, NULL, 0x0,
5862                         NULL, HFILL }},
5863
5864                 {&hf_rsvp_filter[RSVPF_PROTECTION],
5865                  { "PROTECTION", "rsvp.protection", FT_NONE, BASE_NONE, NULL, 0x0,
5866                         NULL, HFILL }},
5867
5868                 {&hf_rsvp_filter[RSVPF_DIFFSERV],
5869                  { "DIFFSERV", "rsvp.diffserv", FT_NONE, BASE_NONE, NULL, 0x0,
5870                         NULL, HFILL }},
5871
5872                 {&hf_rsvp_filter[RSVPF_DSTE],
5873                  { "CLASSTYPE", "rsvp.dste", FT_NONE, BASE_NONE, NULL, 0x0,
5874                    NULL, HFILL }},
5875
5876                 {&hf_rsvp_filter[RSVPF_RESTART_CAP],
5877                  { "RESTART CAPABILITY", "rsvp.restart", FT_NONE, BASE_NONE, NULL, 0x0,
5878                         NULL, HFILL }},
5879
5880                 {&hf_rsvp_filter[RSVPF_LABEL_REQUEST],
5881                  { "LABEL REQUEST", "rsvp.label_request", FT_NONE, BASE_NONE, NULL, 0x0,
5882                         NULL, HFILL }},
5883
5884                 {&hf_rsvp_filter[RSVPF_SESSION_ATTRIBUTE],
5885                  { "SESSION ATTRIBUTE", "rsvp.session_attribute", FT_NONE, BASE_NONE, NULL, 0x0,
5886                         NULL, HFILL }},
5887
5888                 {&hf_rsvp_filter[RSVPF_EXPLICIT_ROUTE],
5889                  { "EXPLICIT ROUTE", "rsvp.explicit_route", FT_NONE, BASE_NONE, NULL, 0x0,
5890                         NULL, HFILL }},
5891
5892                 {&hf_rsvp_filter[RSVPF_RECORD_ROUTE],
5893                  { "RECORD ROUTE", "rsvp.record_route", FT_NONE, BASE_NONE, NULL, 0x0,
5894                         NULL, HFILL }},
5895
5896                 {&hf_rsvp_filter[RSVPF_MESSAGE_ID],
5897                  { "MESSAGE-ID", "rsvp.msgid", FT_NONE, BASE_NONE, NULL, 0x0,
5898                         NULL, HFILL }},
5899
5900                 {&hf_rsvp_filter[RSVPF_MESSAGE_ID_ACK],
5901                  { "MESSAGE-ID ACK", "rsvp.ack", FT_NONE, BASE_NONE, NULL, 0x0,
5902                         NULL, HFILL }},
5903
5904                 {&hf_rsvp_filter[RSVPF_MESSAGE_ID_LIST],
5905                  { "MESSAGE-ID LIST", "rsvp.msgid_list", FT_NONE, BASE_NONE, NULL, 0x0,
5906                         NULL, HFILL }},
5907
5908                 {&hf_rsvp_filter[RSVPF_DCLASS],
5909                  { "DCLASS", "rsvp.dclass", FT_NONE, BASE_NONE, NULL, 0x0,
5910                         NULL, HFILL }},
5911
5912                 {&hf_rsvp_filter[RSVPF_LSP_TUNNEL_IF_ID],
5913                  { "LSP INTERFACE-ID", "rsvp.lsp_tunnel_if_id", FT_NONE, BASE_NONE, NULL, 0x0,
5914                         NULL, HFILL }},
5915
5916                 {&hf_rsvp_filter[RSVPF_ADMIN_STATUS],
5917                  { "ADMIN STATUS", "rsvp.admin_status", FT_NONE, BASE_NONE, NULL, 0x0,
5918                         NULL, HFILL }},
5919
5920                 {&hf_rsvp_filter[RSVPF_ASSOCIATION],
5921                  { "ASSOCIATION", "rsvp.association", FT_NONE, BASE_NONE, NULL, 0x0,
5922                         NULL, HFILL }},
5923
5924                 {&hf_rsvp_filter[RSVPF_NOTIFY_REQUEST],
5925                  { "NOTIFY REQUEST", "rsvp.notify_request", FT_NONE, BASE_NONE, NULL, 0x0,
5926                         NULL, HFILL }},
5927
5928                 {&hf_rsvp_filter[RSVPF_GENERALIZED_UNI],
5929                  { "GENERALIZED UNI", "rsvp.generalized_uni", FT_NONE, BASE_NONE, NULL, 0x0,
5930                         NULL, HFILL }},
5931
5932                 {&hf_rsvp_filter[RSVPF_CALL_ID],
5933                  { "CALL ID", "rsvp.call_id", FT_NONE, BASE_NONE, NULL, 0x0,
5934                         NULL, HFILL }},
5935
5936                 {&hf_rsvp_filter[RSVPF_UNKNOWN_OBJ],
5937                  { "Unknown object", "rsvp.obj_unknown", FT_NONE, BASE_NONE, NULL, 0x0,
5938                         NULL, HFILL }},
5939
5940                 /* Session fields */
5941                 {&hf_rsvp_filter[RSVPF_SESSION_IP],
5942                  { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
5943                         NULL, HFILL }},
5944
5945                 {&hf_rsvp_filter[RSVPF_SESSION_PORT],
5946                  { "Port number", "rsvp.session.port", FT_UINT16, BASE_DEC, NULL, 0x0,
5947                         NULL, HFILL }},
5948
5949                 {&hf_rsvp_filter[RSVPF_SESSION_PROTO],
5950                  { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_DEC, VALS(proto_vals), 0x0,
5951                         NULL, HFILL }},
5952
5953                 {&hf_rsvp_filter[RSVPF_SESSION_TUNNEL_ID],
5954                  { "Tunnel ID", "rsvp.session.tunnel_id", FT_UINT16, BASE_DEC, NULL, 0x0,
5955                         NULL, HFILL }},
5956
5957                 {&hf_rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID],
5958                  { "Extended tunnel ID", "rsvp.session.ext_tunnel_id", FT_UINT32, BASE_DEC, NULL, 0x0,
5959                         NULL, HFILL }},
5960
5961                 /* Sender template/Filterspec fields */
5962                 {&hf_rsvp_filter[RSVPF_SENDER_IP],
5963                  { "Sender IPv4 address", "rsvp.sender.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
5964                         NULL, HFILL }},
5965
5966                 {&hf_rsvp_filter[RSVPF_SENDER_PORT],
5967                  { "Sender port number", "rsvp.sender.port", FT_UINT16, BASE_DEC, NULL, 0x0,
5968                    NULL, HFILL }},
5969
5970                 {&hf_rsvp_filter[RSVPF_SENDER_LSP_ID],
5971                  { "Sender LSP ID", "rsvp.sender.lsp_id", FT_UINT16, BASE_DEC, NULL, 0x0,
5972                         NULL, HFILL }},
5973
5974                 /* Diffserv object fields */
5975                 {&hf_rsvp_filter[RSVPF_DIFFSERV_MAPNB],
5976                  { "MAPnb", "rsvp.diffserv.mapnb", FT_UINT8, BASE_DEC, NULL, 0x0,
5977                    MAPNB_DESCRIPTION, HFILL }},
5978
5979                 {&hf_rsvp_filter[RSVPF_DIFFSERV_MAP],
5980                  { "MAP", "rsvp.diffserv.map", FT_NONE, BASE_NONE, NULL, 0x0,
5981                    MAP_DESCRIPTION, HFILL }},
5982
5983                 {&hf_rsvp_filter[RSVPF_DIFFSERV_MAP_EXP],
5984                  { "EXP", "rsvp.diffserv.map.exp", FT_UINT8, BASE_DEC, NULL, 0x0,
5985                    EXP_DESCRIPTION, HFILL }},
5986
5987                 {&hf_rsvp_filter[RSVPF_DIFFSERV_PHBID],
5988                  { PHBID_DESCRIPTION, "rsvp.diffserv.phbid", FT_NONE, BASE_NONE, NULL, 0x0,
5989                    NULL, HFILL }},
5990
5991                 {&hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_DSCP],
5992                  { PHBID_DSCP_DESCRIPTION, "rsvp.diffserv.phbid.dscp", FT_UINT16,
5993                    BASE_DEC, NULL, PHBID_DSCP_MASK, NULL, HFILL }},
5994
5995                 {&hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_CODE],
5996                  { PHBID_CODE_DESCRIPTION, "rsvp.diffserv.phbid.code", FT_UINT16,
5997                    BASE_DEC, NULL, PHBID_CODE_MASK, NULL, HFILL }},
5998
5999                 {&hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_BIT14],
6000                  { PHBID_BIT14_DESCRIPTION, "rsvp.diffserv.phbid.bit14", FT_UINT16,
6001                    BASE_DEC, VALS(phbid_bit14_vals), PHBID_BIT14_MASK, NULL, HFILL }},
6002
6003                 {&hf_rsvp_filter[RSVPF_DIFFSERV_PHBID_BIT15],
6004                  { PHBID_BIT15_DESCRIPTION, "rsvp.diffserv.phbid.bit15", FT_UINT16,
6005                    BASE_DEC, VALS(phbid_bit15_vals), PHBID_BIT15_MASK, NULL, HFILL }},
6006
6007                 /* Diffserv-aware TE object field */
6008                 {&hf_rsvp_filter[RSVPF_DSTE_CLASSTYPE],
6009                  { "CT", "rsvp.dste.classtype", FT_UINT8, BASE_DEC, NULL, 0x0,
6010                    NULL, HFILL }},
6011
6012                 /* Generalized UNI object field */
6013                 {&hf_rsvp_filter[RSVPF_GUNI_SRC_IPV4],
6014                  { "Source TNA", "rsvp.guni.srctna.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
6015                         NULL, HFILL }},
6016
6017                 {&hf_rsvp_filter[RSVPF_GUNI_DST_IPV4],
6018                  { "Destination TNA", "rsvp.guni.dsttna.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0,
6019                         NULL, HFILL }},
6020
6021                 {&hf_rsvp_filter[RSVPF_GUNI_SRC_IPV6],
6022                  { "Source TNA", "rsvp.guni.srctna.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0,
6023                         NULL, HFILL }},
6024
6025                 {&hf_rsvp_filter[RSVPF_GUNI_DST_IPV6],
6026                  { "Destination TNA", "rsvp.guni.dsttna.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0,
6027                         NULL, HFILL }},
6028
6029                 /* Generalized UNI object field */
6030                 {&hf_rsvp_filter[RSVPF_CALL_ID_SRC_ADDR_IPV4],
6031                  { "Source Transport Network Address", "rsvp.callid.srcaddr.ipv4", FT_IPv4,
6032                         BASE_NONE, NULL, 0x0, NULL, HFILL }},
6033
6034                 {&hf_rsvp_filter[RSVPF_CALL_ID_SRC_ADDR_IPV6],
6035                  { "Source Transport Network Address", "rsvp.callid.srcaddr.ipv6", FT_IPv6,
6036                         BASE_NONE, NULL, 0x0, NULL, HFILL }}
6037         };
6038
6039     gint *ett_tree[TT_MAX];
6040
6041     /* Build the tree array */
6042     for (i=0; i<TT_MAX; i++) {
6043         ett_treelist[i] = -1;
6044         ett_tree[i] = &(ett_treelist[i]);
6045     }
6046     proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)",
6047                                          "RSVP", "rsvp");
6048     proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info));
6049     proto_register_subtree_array(ett_tree, array_length(ett_tree));
6050     register_rsvp_prefs();
6051
6052     rsvp_dissector_table = register_dissector_table("rsvp.proto", "RSVP Protocol",
6053                                                     FT_UINT8, BASE_DEC);
6054
6055     /* Initialization routine for RSVP conversations */
6056     register_init_routine(&rsvp_init_protocol);
6057 }
6058
6059 void
6060 proto_reg_handoff_rsvp(void)
6061 {
6062     dissector_handle_t rsvp_handle;
6063
6064     rsvp_handle = create_dissector_handle(dissect_rsvp, proto_rsvp);
6065     dissector_add("ip.proto", IP_PROTO_RSVP, rsvp_handle);
6066     dissector_add("ip.proto", IP_PROTO_RSVPE2EI, rsvp_handle);
6067     dissector_add("udp.port", UDP_PORT_PRSVP, rsvp_handle);
6068     rsvp_tap = register_tap("rsvp");
6069 }