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