1/*
2 * Copyright (c) 1998-2007 The TCPDUMP project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that: (1) source code
6 * distributions retain the above copyright notice and this paragraph
7 * in its entirety, and (2) distributions including binary code include
8 * the above copyright notice and this paragraph in its entirety in
9 * the documentation or other materials provided with the distribution.
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
14 *
15 * Original code by Hannes Gredler (hannes@juniper.net)
16 */
17
18#include <sys/cdefs.h>
19#ifndef lint
20#if 0
21static const char rcsid[] _U_ =
22    "@(#) Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.50 2008-08-16 11:36:20 hannes Exp";
23#else
24__RCSID("$NetBSD: print-rsvp.c,v 1.3 2012/01/16 17:34:18 christos Exp $");
25#endif
26#endif
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <tcpdump-stdinc.h>
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "interface.h"
39#include "extract.h"
40#include "addrtoname.h"
41#include "ethertype.h"
42#include "gmpls.h"
43#include "af.h"
44#include "signature.h"
45
46/*
47 * RFC 2205 common header
48 *
49 *               0             1              2             3
50 *        +-------------+-------------+-------------+-------------+
51 *        | Vers | Flags|  Msg Type   |       RSVP Checksum       |
52 *        +-------------+-------------+-------------+-------------+
53 *        |  Send_TTL   | (Reserved)  |        RSVP Length        |
54 *        +-------------+-------------+-------------+-------------+
55 *
56 */
57
58struct rsvp_common_header {
59    u_int8_t version_flags;
60    u_int8_t msg_type;
61    u_int8_t checksum[2];
62    u_int8_t ttl;
63    u_int8_t reserved;
64    u_int8_t length[2];
65};
66
67/*
68 * RFC2205 object header
69 *
70 *
71 *               0             1              2             3
72 *        +-------------+-------------+-------------+-------------+
73 *        |       Length (bytes)      |  Class-Num  |   C-Type    |
74 *        +-------------+-------------+-------------+-------------+
75 *        |                                                       |
76 *        //                  (Object contents)                   //
77 *        |                                                       |
78 *        +-------------+-------------+-------------+-------------+
79 */
80
81struct rsvp_object_header {
82    u_int8_t length[2];
83    u_int8_t class_num;
84    u_int8_t ctype;
85};
86
87#define RSVP_VERSION            1
88#define	RSVP_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
89#define	RSVP_EXTRACT_FLAGS(x)   ((x)&0x0f)
90
91#define	RSVP_MSGTYPE_PATH       1
92#define	RSVP_MSGTYPE_RESV       2
93#define	RSVP_MSGTYPE_PATHERR    3
94#define	RSVP_MSGTYPE_RESVERR    4
95#define	RSVP_MSGTYPE_PATHTEAR   5
96#define	RSVP_MSGTYPE_RESVTEAR   6
97#define	RSVP_MSGTYPE_RESVCONF   7
98#define RSVP_MSGTYPE_AGGREGATE  12
99#define RSVP_MSGTYPE_ACK        13
100#define RSVP_MSGTYPE_HELLO_OLD  14      /* ancient Hellos */
101#define RSVP_MSGTYPE_SREFRESH   15
102#define	RSVP_MSGTYPE_HELLO      20
103
104static const struct tok rsvp_msg_type_values[] = {
105    { RSVP_MSGTYPE_PATH,	"Path" },
106    { RSVP_MSGTYPE_RESV,	"Resv" },
107    { RSVP_MSGTYPE_PATHERR,	"PathErr" },
108    { RSVP_MSGTYPE_RESVERR,	"ResvErr" },
109    { RSVP_MSGTYPE_PATHTEAR,	"PathTear" },
110    { RSVP_MSGTYPE_RESVTEAR,	"ResvTear" },
111    { RSVP_MSGTYPE_RESVCONF,	"ResvConf" },
112    { RSVP_MSGTYPE_AGGREGATE,	"Aggregate" },
113    { RSVP_MSGTYPE_ACK,	        "Acknowledgement" },
114    { RSVP_MSGTYPE_HELLO_OLD,	"Hello (Old)" },
115    { RSVP_MSGTYPE_SREFRESH,	"Refresh" },
116    { RSVP_MSGTYPE_HELLO,	"Hello" },
117    { 0, NULL}
118};
119
120static const struct tok rsvp_header_flag_values[] = {
121    { 0x01,	              "Refresh reduction capable" }, /* rfc2961 */
122    { 0, NULL}
123};
124
125#define	RSVP_OBJ_SESSION            1   /* rfc2205 */
126#define	RSVP_OBJ_RSVP_HOP           3   /* rfc2205, rfc3473 */
127#define	RSVP_OBJ_INTEGRITY          4   /* rfc2747 */
128#define	RSVP_OBJ_TIME_VALUES        5   /* rfc2205 */
129#define	RSVP_OBJ_ERROR_SPEC         6
130#define	RSVP_OBJ_SCOPE              7
131#define	RSVP_OBJ_STYLE              8   /* rfc2205 */
132#define	RSVP_OBJ_FLOWSPEC           9   /* rfc2215 */
133#define	RSVP_OBJ_FILTERSPEC         10  /* rfc2215 */
134#define	RSVP_OBJ_SENDER_TEMPLATE    11
135#define	RSVP_OBJ_SENDER_TSPEC       12  /* rfc2215 */
136#define	RSVP_OBJ_ADSPEC             13  /* rfc2215 */
137#define	RSVP_OBJ_POLICY_DATA        14
138#define	RSVP_OBJ_CONFIRM            15  /* rfc2205 */
139#define	RSVP_OBJ_LABEL              16  /* rfc3209 */
140#define	RSVP_OBJ_LABEL_REQ          19  /* rfc3209 */
141#define	RSVP_OBJ_ERO                20  /* rfc3209 */
142#define	RSVP_OBJ_RRO                21  /* rfc3209 */
143#define	RSVP_OBJ_HELLO              22  /* rfc3209 */
144#define	RSVP_OBJ_MESSAGE_ID         23  /* rfc2961 */
145#define	RSVP_OBJ_MESSAGE_ID_ACK     24  /* rfc2961 */
146#define	RSVP_OBJ_MESSAGE_ID_LIST    25  /* rfc2961 */
147#define	RSVP_OBJ_RECOVERY_LABEL     34  /* rfc3473 */
148#define	RSVP_OBJ_UPSTREAM_LABEL     35  /* rfc3473 */
149#define	RSVP_OBJ_LABEL_SET          36  /* rfc3473 */
150#define	RSVP_OBJ_PROTECTION         37  /* rfc3473 */
151#define RSVP_OBJ_S2L                50  /* rfc4875 */
152#define	RSVP_OBJ_DETOUR             63  /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */
153#define	RSVP_OBJ_CLASSTYPE          66  /* rfc4124 */
154#define RSVP_OBJ_CLASSTYPE_OLD      125 /* draft-ietf-tewg-diff-te-proto-07 */
155#define	RSVP_OBJ_SUGGESTED_LABEL    129 /* rfc3473 */
156#define	RSVP_OBJ_ACCEPT_LABEL_SET   130 /* rfc3473 */
157#define	RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */
158#define	RSVP_OBJ_NOTIFY_REQ         195 /* rfc3473 */
159#define	RSVP_OBJ_ADMIN_STATUS       196 /* rfc3473 */
160#define	RSVP_OBJ_PROPERTIES         204 /* juniper proprietary */
161#define	RSVP_OBJ_FASTREROUTE        205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */
162#define	RSVP_OBJ_SESSION_ATTRIBUTE  207 /* rfc3209 */
163#define RSVP_OBJ_GENERALIZED_UNI    229 /* OIF RSVP extensions UNI 1.0 Signaling, Rel. 2 */
164#define RSVP_OBJ_CALL_ID            230 /* rfc3474 */
165#define RSVP_OBJ_CALL_OPS           236 /* rfc3474 */
166
167static const struct tok rsvp_obj_values[] = {
168    { RSVP_OBJ_SESSION,            "Session" },
169    { RSVP_OBJ_RSVP_HOP,           "RSVP Hop" },
170    { RSVP_OBJ_INTEGRITY,          "Integrity" },
171    { RSVP_OBJ_TIME_VALUES,        "Time Values" },
172    { RSVP_OBJ_ERROR_SPEC,         "Error Spec" },
173    { RSVP_OBJ_SCOPE,              "Scope" },
174    { RSVP_OBJ_STYLE,              "Style" },
175    { RSVP_OBJ_FLOWSPEC,           "Flowspec" },
176    { RSVP_OBJ_FILTERSPEC,         "FilterSpec" },
177    { RSVP_OBJ_SENDER_TEMPLATE,    "Sender Template" },
178    { RSVP_OBJ_SENDER_TSPEC,       "Sender TSpec" },
179    { RSVP_OBJ_ADSPEC,             "Adspec" },
180    { RSVP_OBJ_POLICY_DATA,        "Policy Data" },
181    { RSVP_OBJ_CONFIRM,            "Confirm" },
182    { RSVP_OBJ_LABEL,              "Label" },
183    { RSVP_OBJ_LABEL_REQ,          "Label Request" },
184    { RSVP_OBJ_ERO,                "ERO" },
185    { RSVP_OBJ_RRO,                "RRO" },
186    { RSVP_OBJ_HELLO,              "Hello" },
187    { RSVP_OBJ_MESSAGE_ID,         "Message ID" },
188    { RSVP_OBJ_MESSAGE_ID_ACK,     "Message ID Ack" },
189    { RSVP_OBJ_MESSAGE_ID_LIST,    "Message ID List" },
190    { RSVP_OBJ_RECOVERY_LABEL,     "Recovery Label" },
191    { RSVP_OBJ_UPSTREAM_LABEL,     "Upstream Label" },
192    { RSVP_OBJ_LABEL_SET,          "Label Set" },
193    { RSVP_OBJ_ACCEPT_LABEL_SET,   "Acceptable Label Set" },
194    { RSVP_OBJ_DETOUR,             "Detour" },
195    { RSVP_OBJ_CLASSTYPE,          "Class Type" },
196    { RSVP_OBJ_CLASSTYPE_OLD,      "Class Type (old)" },
197    { RSVP_OBJ_SUGGESTED_LABEL,    "Suggested Label" },
198    { RSVP_OBJ_PROPERTIES,         "Properties" },
199    { RSVP_OBJ_FASTREROUTE,        "Fast Re-Route" },
200    { RSVP_OBJ_SESSION_ATTRIBUTE,  "Session Attribute" },
201    { RSVP_OBJ_GENERALIZED_UNI,    "Generalized UNI" },
202    { RSVP_OBJ_CALL_ID,            "Call-ID" },
203    { RSVP_OBJ_CALL_OPS,           "Call Capability" },
204    { RSVP_OBJ_RESTART_CAPABILITY, "Restart Capability" },
205    { RSVP_OBJ_NOTIFY_REQ,         "Notify Request" },
206    { RSVP_OBJ_PROTECTION,         "Protection" },
207    { RSVP_OBJ_ADMIN_STATUS,       "Administrative Status" },
208    { RSVP_OBJ_S2L,                "Sub-LSP to LSP" },
209    { 0, NULL}
210};
211
212#define	RSVP_CTYPE_IPV4        1
213#define	RSVP_CTYPE_IPV6        2
214#define	RSVP_CTYPE_TUNNEL_IPV4 7
215#define	RSVP_CTYPE_TUNNEL_IPV6 8
216#define	RSVP_CTYPE_UNI_IPV4    11 /* OIF RSVP extensions UNI 1.0 Signaling Rel. 2 */
217#define RSVP_CTYPE_1           1
218#define RSVP_CTYPE_2           2
219#define RSVP_CTYPE_3           3
220#define RSVP_CTYPE_4           4
221#define RSVP_CTYPE_12         12
222#define RSVP_CTYPE_13         13
223#define RSVP_CTYPE_14         14
224
225/*
226 * the ctypes are not globally unique so for
227 * translating it to strings we build a table based
228 * on objects offsetted by the ctype
229 */
230
231static const struct tok rsvp_ctype_values[] = {
232    { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV4,	             "IPv4" },
233    { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV6,	             "IPv6" },
234    { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_3,	             "IPv4 plus opt. TLVs" },
235    { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_4,	             "IPv6 plus opt. TLVs" },
236    { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV4,	             "IPv4" },
237    { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV6,	             "IPv6" },
238    { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV4,	             "IPv4" },
239    { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV6,	             "IPv6" },
240    { 256*RSVP_OBJ_TIME_VALUES+RSVP_CTYPE_1,	             "1" },
241    { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_1,	             "obsolete" },
242    { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_2,	             "IntServ" },
243    { 256*RSVP_OBJ_SENDER_TSPEC+RSVP_CTYPE_2,	             "IntServ" },
244    { 256*RSVP_OBJ_ADSPEC+RSVP_CTYPE_2,	                     "IntServ" },
245    { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV4,	             "IPv4" },
246    { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV6,	             "IPv6" },
247    { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_3,	             "IPv6 Flow-label" },
248    { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_TUNNEL_IPV4,	     "Tunnel IPv4" },
249    { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_12,                 "IPv4 P2MP LSP Tunnel" },
250    { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_13,                 "IPv6 P2MP LSP Tunnel" },
251    { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV4,	             "IPv4" },
252    { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV6,	             "IPv6" },
253    { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_TUNNEL_IPV4,           "Tunnel IPv4" },
254    { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_UNI_IPV4,              "UNI IPv4" },
255    { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_13,                    "IPv4 P2MP LSP Tunnel" },
256    { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_14,                    "IPv6 P2MP LSP Tunnel" },
257    { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV4,          "IPv4" },
258    { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV6,          "IPv6" },
259    { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_TUNNEL_IPV4,   "Tunnel IPv4" },
260    { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_12,            "IPv4 P2MP LSP Tunnel" },
261    { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_13,            "IPv6 P2MP LSP Tunnel" },
262    { 256*RSVP_OBJ_MESSAGE_ID+RSVP_CTYPE_1,                  "1" },
263    { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_1,              "Message id ack" },
264    { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_2,              "Message id nack" },
265    { 256*RSVP_OBJ_MESSAGE_ID_LIST+RSVP_CTYPE_1,             "1" },
266    { 256*RSVP_OBJ_STYLE+RSVP_CTYPE_1,                       "1" },
267    { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_1,                       "Hello Request" },
268    { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_2,                       "Hello Ack" },
269    { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_1,	             "without label range" },
270    { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_2,	             "with ATM label range" },
271    { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_3,                   "with FR label range" },
272    { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_4,                   "Generalized Label" },
273    { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_1,                       "Label" },
274    { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_2,                       "Generalized Label" },
275    { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_3,                       "Waveband Switching" },
276    { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_1,             "Label" },
277    { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_2,             "Generalized Label" },
278    { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_3,             "Waveband Switching" },
279    { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_1,              "Label" },
280    { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_2,              "Generalized Label" },
281    { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_3,              "Waveband Switching" },
282    { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_1,              "Label" },
283    { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_2,              "Generalized Label" },
284    { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_3,              "Waveband Switching" },
285    { 256*RSVP_OBJ_ERO+RSVP_CTYPE_IPV4,                      "IPv4" },
286    { 256*RSVP_OBJ_RRO+RSVP_CTYPE_IPV4,                      "IPv4" },
287    { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV4,               "IPv4" },
288    { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV6,               "IPv6" },
289    { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_3,                  "IPv4 plus opt. TLVs" },
290    { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4,                  "IPv6 plus opt. TLVs" },
291    { 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1,          "IPv4" },
292    { 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
293    { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4,       "Tunnel IPv4" }, /* old style*/
294    { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1,                 "1" }, /* new style */
295    { 256*RSVP_OBJ_DETOUR+RSVP_CTYPE_TUNNEL_IPV4,            "Tunnel IPv4" },
296    { 256*RSVP_OBJ_PROPERTIES+RSVP_CTYPE_1,                  "1" },
297    { 256*RSVP_OBJ_ADMIN_STATUS+RSVP_CTYPE_1,                "1" },
298    { 256*RSVP_OBJ_CLASSTYPE+RSVP_CTYPE_1,                   "1" },
299    { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1,               "1" },
300    { 256*RSVP_OBJ_LABEL_SET+RSVP_CTYPE_1,                   "1" },
301    { 256*RSVP_OBJ_GENERALIZED_UNI+RSVP_CTYPE_1,             "1" },
302    { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV4,                      "IPv4 sub-LSP" },
303    { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV6,                      "IPv6 sub-LSP" },
304    { 0, NULL}
305};
306
307struct rsvp_obj_integrity_t {
308    u_int8_t flags;
309    u_int8_t res;
310    u_int8_t key_id[6];
311    u_int8_t sequence[8];
312    u_int8_t digest[16];
313};
314
315static const struct tok rsvp_obj_integrity_flag_values[] = {
316    { 0x80, "Handshake" },
317    { 0, NULL}
318};
319
320struct rsvp_obj_frr_t {
321    u_int8_t setup_prio;
322    u_int8_t hold_prio;
323    u_int8_t hop_limit;
324    u_int8_t flags;
325    u_int8_t bandwidth[4];
326    u_int8_t include_any[4];
327    u_int8_t exclude_any[4];
328    u_int8_t include_all[4];
329};
330
331
332#define RSVP_OBJ_XRO_MASK_SUBOBJ(x)   ((x)&0x7f)
333#define RSVP_OBJ_XRO_MASK_LOOSE(x)    ((x)&0x80)
334
335#define	RSVP_OBJ_XRO_RES       0
336#define	RSVP_OBJ_XRO_IPV4      1
337#define	RSVP_OBJ_XRO_IPV6      2
338#define	RSVP_OBJ_XRO_LABEL     3
339#define	RSVP_OBJ_XRO_ASN       32
340#define	RSVP_OBJ_XRO_MPLS      64
341
342static const struct tok rsvp_obj_xro_values[] = {
343    { RSVP_OBJ_XRO_RES,	      "Reserved" },
344    { RSVP_OBJ_XRO_IPV4,      "IPv4 prefix" },
345    { RSVP_OBJ_XRO_IPV6,      "IPv6 prefix" },
346    { RSVP_OBJ_XRO_LABEL,     "Label" },
347    { RSVP_OBJ_XRO_ASN,       "Autonomous system number" },
348    { RSVP_OBJ_XRO_MPLS,      "MPLS label switched path termination" },
349    { 0, NULL}
350};
351
352/* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */
353static const struct tok rsvp_obj_rro_flag_values[] = {
354    { 0x01,	              "Local protection available" },
355    { 0x02,                   "Local protection in use" },
356    { 0x04,                   "Bandwidth protection" },
357    { 0x08,                   "Node protection" },
358    { 0, NULL}
359};
360
361/* RFC3209 */
362static const struct tok rsvp_obj_rro_label_flag_values[] = {
363    { 0x01,                   "Global" },
364    { 0, NULL}
365};
366
367static const struct tok rsvp_resstyle_values[] = {
368    { 17,	              "Wildcard Filter" },
369    { 10,                     "Fixed Filter" },
370    { 18,                     "Shared Explicit" },
371    { 0, NULL}
372};
373
374#define RSVP_OBJ_INTSERV_GUARANTEED_SERV 2
375#define RSVP_OBJ_INTSERV_CONTROLLED_LOAD 5
376
377static const struct tok rsvp_intserv_service_type_values[] = {
378    { 1,                                "Default/Global Information" },
379    { RSVP_OBJ_INTSERV_GUARANTEED_SERV, "Guaranteed Service" },
380    { RSVP_OBJ_INTSERV_CONTROLLED_LOAD,	"Controlled Load" },
381    { 0, NULL}
382};
383
384static const struct tok rsvp_intserv_parameter_id_values[] = {
385    { 4,                     "IS hop cnt" },
386    { 6,                     "Path b/w estimate" },
387    { 8,                     "Minimum path latency" },
388    { 10,                    "Composed MTU" },
389    { 127,                   "Token Bucket TSpec" },
390    { 130,                   "Guaranteed Service RSpec" },
391    { 133,                   "End-to-end composed value for C" },
392    { 134,                   "End-to-end composed value for D" },
393    { 135,                   "Since-last-reshaping point composed C" },
394    { 136,                   "Since-last-reshaping point composed D" },
395    { 0, NULL}
396};
397
398static struct tok rsvp_session_attribute_flag_values[] = {
399    { 0x01,	              "Local Protection" },
400    { 0x02,                   "Label Recording" },
401    { 0x04,                   "SE Style" },
402    { 0x08,                   "Bandwidth protection" }, /* RFC4090 */
403    { 0x10,                   "Node protection" },      /* RFC4090 */
404    { 0, NULL}
405};
406
407static struct tok rsvp_obj_prop_tlv_values[] = {
408    { 0x01,                   "Cos" },
409    { 0x02,                   "Metric 1" },
410    { 0x04,                   "Metric 2" },
411    { 0x08,                   "CCC Status" },
412    { 0x10,                   "Path Type" },
413    { 0, NULL}
414};
415
416#define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24
417#define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY  25
418#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 28
419#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD 125
420
421static struct tok rsvp_obj_error_code_values[] = {
422    { RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" },
423    { RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY,  "Notify Error" },
424    { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" },
425    { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD, "Diffserv TE Error (Old)" },
426    { 0, NULL}
427};
428
429static struct tok rsvp_obj_error_code_routing_values[] = {
430    { 1,                      "Bad EXPLICIT_ROUTE object" },
431    { 2,                      "Bad strict node" },
432    { 3,                      "Bad loose node" },
433    { 4,                      "Bad initial subobject" },
434    { 5,                      "No route available toward destination" },
435    { 6,                      "Unacceptable label value" },
436    { 7,                      "RRO indicated routing loops" },
437    { 8,                      "non-RSVP-capable router in the path" },
438    { 9,                      "MPLS label allocation failure" },
439    { 10,                     "Unsupported L3PID" },
440    { 0, NULL}
441};
442
443static struct tok rsvp_obj_error_code_diffserv_te_values[] = {
444    { 1,                      "Unexpected CT object" },
445    { 2,                      "Unsupported CT" },
446    { 3,                      "Invalid CT value" },
447    { 4,                      "CT/setup priority do not form a configured TE-Class" },
448    { 5,                      "CT/holding priority do not form a configured TE-Class" },
449    { 6,                      "CT/setup priority and CT/holding priority do not form a configured TE-Class" },
450    { 7,                      "Inconsistency between signaled PSC and signaled CT" },
451    { 8,                      "Inconsistency between signaled PHBs and signaled CT" },
452   { 0, NULL}
453};
454
455/* rfc3473 / rfc 3471 */
456static const struct tok rsvp_obj_admin_status_flag_values[] = {
457    { 0x80000000, "Reflect" },
458    { 0x00000004, "Testing" },
459    { 0x00000002, "Admin-down" },
460    { 0x00000001, "Delete-in-progress" },
461    { 0, NULL}
462};
463
464/* label set actions - rfc3471 */
465#define LABEL_SET_INCLUSIVE_LIST  0
466#define LABEL_SET_EXCLUSIVE_LIST  1
467#define LABEL_SET_INCLUSIVE_RANGE 2
468#define LABEL_SET_EXCLUSIVE_RANGE 3
469
470static const struct tok rsvp_obj_label_set_action_values[] = {
471    { LABEL_SET_INCLUSIVE_LIST, "Inclusive list" },
472    { LABEL_SET_EXCLUSIVE_LIST, "Exclusive list" },
473    { LABEL_SET_INCLUSIVE_RANGE, "Inclusive range" },
474    { LABEL_SET_EXCLUSIVE_RANGE, "Exclusive range" },
475    { 0, NULL}
476};
477
478/* OIF RSVP extensions UNI 1.0 Signaling, release 2 */
479#define RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS	    1
480#define RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS 2
481#define RSVP_GEN_UNI_SUBOBJ_DIVERSITY		    3
482#define RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL            4
483#define RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL           5
484
485static const struct tok rsvp_obj_generalized_uni_values[] = {
486    { RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS, "Source TNA address" },
487    { RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS, "Destination TNA address" },
488    { RSVP_GEN_UNI_SUBOBJ_DIVERSITY, "Diversity" },
489    { RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL, "Egress label" },
490    { RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL, "Service level" },
491    { 0, NULL}
492};
493
494static int rsvp_intserv_print(const u_char *, u_short);
495
496/*
497 * this is a dissector for all the intserv defined
498 * specs as defined per rfc2215
499 * it is called from various rsvp objects;
500 * returns the amount of bytes being processed
501 */
502static int
503rsvp_intserv_print(const u_char *tptr, u_short obj_tlen) {
504
505    int parameter_id,parameter_length;
506    union {
507	float f;
508	u_int32_t i;
509    } bw;
510
511    if (obj_tlen < 4)
512        return 0;
513    parameter_id = *(tptr);
514    parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */
515
516    printf("\n\t      Parameter ID: %s (%u), length: %u, Flags: [0x%02x]",
517           tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id),
518           parameter_id,
519           parameter_length,
520           *(tptr+1));
521
522    if (obj_tlen < parameter_length+4)
523        return 0;
524    switch(parameter_id) { /* parameter_id */
525
526    case 4:
527       /*
528        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
529        * |    4 (e)      |    (f)        |           1 (g)               |
530        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
531        * |        IS hop cnt (32-bit unsigned integer)                   |
532        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
533        */
534        if (parameter_length == 4)
535            printf("\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr+4));
536        break;
537
538    case 6:
539       /*
540        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
541        * |    6 (h)      |    (i)        |           1 (j)               |
542        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
543        * |  Path b/w estimate  (32-bit IEEE floating point number)       |
544        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
545        */
546        if (parameter_length == 4) {
547            bw.i = EXTRACT_32BITS(tptr+4);
548            printf("\n\t\tPath b/w estimate: %.10g Mbps", bw.f/125000);
549        }
550        break;
551
552    case 8:
553       /*
554        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
555        * |     8 (k)     |    (l)        |           1 (m)               |
556        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
557        * |        Minimum path latency (32-bit integer)                  |
558        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
559        */
560        if (parameter_length == 4) {
561            printf("\n\t\tMinimum path latency: ");
562            if (EXTRACT_32BITS(tptr+4) == 0xffffffff)
563                printf("don't care");
564            else
565                printf("%u", EXTRACT_32BITS(tptr+4));
566        }
567        break;
568
569    case 10:
570
571       /*
572        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
573        * |     10 (n)    |      (o)      |           1 (p)               |
574        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
575        * |      Composed MTU (32-bit unsigned integer)                   |
576        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
577        */
578        if (parameter_length == 4)
579            printf("\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr+4));
580        break;
581    case 127:
582       /*
583        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
584        * |   127 (e)     |    0 (f)      |             5 (g)             |
585        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
586        * |  Token Bucket Rate [r] (32-bit IEEE floating point number)    |
587        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
588        * |  Token Bucket Size [b] (32-bit IEEE floating point number)    |
589        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
590        * |  Peak Data Rate [p] (32-bit IEEE floating point number)       |
591        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
592        * |  Minimum Policed Unit [m] (32-bit integer)                    |
593        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
594        * |  Maximum Packet Size [M]  (32-bit integer)                    |
595        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
596        */
597
598        if (parameter_length == 20) {
599            bw.i = EXTRACT_32BITS(tptr+4);
600            printf("\n\t\tToken Bucket Rate: %.10g Mbps", bw.f/125000);
601            bw.i = EXTRACT_32BITS(tptr+8);
602            printf("\n\t\tToken Bucket Size: %.10g bytes", bw.f);
603            bw.i = EXTRACT_32BITS(tptr+12);
604            printf("\n\t\tPeak Data Rate: %.10g Mbps", bw.f/125000);
605            printf("\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr+16));
606            printf("\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr+20));
607        }
608        break;
609
610    case 130:
611       /*
612        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
613        * |     130 (h)   |    0 (i)      |            2 (j)              |
614        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
615        * |  Rate [R]  (32-bit IEEE floating point number)                |
616        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
617        * |  Slack Term [S]  (32-bit integer)                             |
618        * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
619        */
620
621        if (parameter_length == 8) {
622            bw.i = EXTRACT_32BITS(tptr+4);
623            printf("\n\t\tRate: %.10g Mbps", bw.f/125000);
624            printf("\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr+8));
625        }
626        break;
627
628    case 133:
629    case 134:
630    case 135:
631    case 136:
632        if (parameter_length == 4)
633            printf("\n\t\tValue: %u", EXTRACT_32BITS(tptr+4));
634        break;
635
636    default:
637        if (vflag <= 1)
638            print_unknown_data(tptr+4,"\n\t\t",parameter_length);
639    }
640    return (parameter_length+4); /* header length 4 bytes */
641}
642
643static int
644rsvp_obj_print (const u_char *pptr
645#ifndef HAVE_LIBCRYPTO
646_U_
647#endif
648, u_int plen
649#ifndef HAVE_LIBCRYPTO
650_U_
651#endif
652, const u_char *tptr,
653                const char *ident, u_int tlen) {
654
655    const struct rsvp_object_header *rsvp_obj_header;
656    const u_char *obj_tptr;
657    union {
658        const struct rsvp_obj_integrity_t *rsvp_obj_integrity;
659        const struct rsvp_obj_frr_t *rsvp_obj_frr;
660    } obj_ptr;
661
662    u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen;
663    int hexdump,processed,padbytes,error_code,error_value,i,sigcheck;
664    union {
665	float f;
666	u_int32_t i;
667    } bw;
668    u_int8_t namelen;
669
670    u_int action, subchannel;
671
672    while(tlen>=sizeof(struct rsvp_object_header)) {
673        /* did we capture enough for fully decoding the object header ? */
674        if (!TTEST2(*tptr, sizeof(struct rsvp_object_header)))
675            goto trunc;
676
677        rsvp_obj_header = (const struct rsvp_object_header *)tptr;
678        rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length);
679        rsvp_obj_ctype=rsvp_obj_header->ctype;
680
681        if(rsvp_obj_len % 4) {
682            printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len);
683            return -1;
684        }
685        if(rsvp_obj_len < sizeof(struct rsvp_object_header)) {
686            printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len,
687                   (unsigned long)sizeof(const struct rsvp_object_header));
688            return -1;
689        }
690
691        printf("%s%s Object (%u) Flags: [%s",
692               ident,
693               tok2str(rsvp_obj_values,
694                       "Unknown",
695                       rsvp_obj_header->class_num),
696               rsvp_obj_header->class_num,
697               ((rsvp_obj_header->class_num)&0x80) ? "ignore" : "reject");
698
699        if (rsvp_obj_header->class_num > 128)
700            printf(" %s",
701                   ((rsvp_obj_header->class_num)&0x40) ? "and forward" : "silently");
702
703        printf(" if unknown], Class-Type: %s (%u), length: %u",
704               tok2str(rsvp_ctype_values,
705                       "Unknown",
706                       ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype),
707               rsvp_obj_ctype,
708               rsvp_obj_len);
709
710        if(tlen < rsvp_obj_len) {
711            printf("%sERROR: object goes past end of objects TLV", ident);
712            return -1;
713        }
714
715        obj_tptr=tptr+sizeof(struct rsvp_object_header);
716        obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header);
717
718        /* did we capture enough for fully decoding the object ? */
719        if (!TTEST2(*tptr, rsvp_obj_len))
720            return -1;
721        hexdump=FALSE;
722
723        switch(rsvp_obj_header->class_num) {
724        case RSVP_OBJ_SESSION:
725            switch(rsvp_obj_ctype) {
726            case RSVP_CTYPE_IPV4:
727                if (obj_tlen < 8)
728                    return -1;
729                printf("%s  IPv4 DestAddress: %s, Protocol ID: 0x%02x",
730                       ident,
731                       ipaddr_string(obj_tptr),
732                       *(obj_tptr+sizeof(struct in_addr)));
733                printf("%s  Flags: [0x%02x], DestPort %u",
734                       ident,
735                       *(obj_tptr+5),
736                       EXTRACT_16BITS(obj_tptr+6));
737                obj_tlen-=8;
738                obj_tptr+=8;
739                break;
740#ifdef INET6
741            case RSVP_CTYPE_IPV6:
742                if (obj_tlen < 20)
743                    return -1;
744                printf("%s  IPv6 DestAddress: %s, Protocol ID: 0x%02x",
745                       ident,
746                       ip6addr_string(obj_tptr),
747                       *(obj_tptr+sizeof(struct in6_addr)));
748                printf("%s  Flags: [0x%02x], DestPort %u",
749                       ident,
750                       *(obj_tptr+sizeof(struct in6_addr)+1),
751                       EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2));
752                obj_tlen-=20;
753                obj_tptr+=20;
754                break;
755
756            case RSVP_CTYPE_TUNNEL_IPV6:
757                if (obj_tlen < 36)
758                    return -1;
759                printf("%s  IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
760                       ident,
761                       ip6addr_string(obj_tptr),
762                       EXTRACT_16BITS(obj_tptr+18),
763                       ip6addr_string(obj_tptr+20));
764                obj_tlen-=36;
765                obj_tptr+=36;
766                break;
767
768            case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */
769                if (obj_tlen < 26)
770                    return -1;
771                printf("%s  IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
772                       ident,
773                       EXTRACT_32BITS(obj_tptr),
774                       EXTRACT_16BITS(obj_tptr+6),
775                       ip6addr_string(obj_tptr+8));
776                obj_tlen-=26;
777                obj_tptr+=26;
778                break;
779#endif
780            case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */
781                if (obj_tlen < 12)
782                    return -1;
783                printf("%s  IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
784                       ident,
785                       ipaddr_string(obj_tptr),
786                       EXTRACT_16BITS(obj_tptr+6),
787                       ipaddr_string(obj_tptr+8));
788                obj_tlen-=12;
789                obj_tptr+=12;
790                break;
791            case RSVP_CTYPE_TUNNEL_IPV4:
792            case RSVP_CTYPE_UNI_IPV4:
793                if (obj_tlen < 12)
794                    return -1;
795                printf("%s  IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
796                       ident,
797                       ipaddr_string(obj_tptr),
798                       EXTRACT_16BITS(obj_tptr+6),
799                       ipaddr_string(obj_tptr+8));
800                obj_tlen-=12;
801                obj_tptr+=12;
802                break;
803            default:
804                hexdump=TRUE;
805            }
806            break;
807
808        case RSVP_OBJ_CONFIRM:
809            switch(rsvp_obj_ctype) {
810            case RSVP_CTYPE_IPV4:
811                if (obj_tlen < sizeof(struct in_addr))
812                    return -1;
813                printf("%s  IPv4 Receiver Address: %s",
814                       ident,
815                       ipaddr_string(obj_tptr));
816                obj_tlen-=sizeof(struct in_addr);
817                obj_tptr+=sizeof(struct in_addr);
818                break;
819#ifdef INET6
820            case RSVP_CTYPE_IPV6:
821                if (obj_tlen < sizeof(struct in6_addr))
822                    return -1;
823                printf("%s  IPv6 Receiver Address: %s",
824                       ident,
825                       ip6addr_string(obj_tptr));
826                obj_tlen-=sizeof(struct in6_addr);
827                obj_tptr+=sizeof(struct in6_addr);
828                break;
829#endif
830            default:
831                hexdump=TRUE;
832            }
833            break;
834
835        case RSVP_OBJ_NOTIFY_REQ:
836            switch(rsvp_obj_ctype) {
837            case RSVP_CTYPE_IPV4:
838                if (obj_tlen < sizeof(struct in_addr))
839                    return -1;
840                printf("%s  IPv4 Notify Node Address: %s",
841                       ident,
842                       ipaddr_string(obj_tptr));
843                obj_tlen-=sizeof(struct in_addr);
844                obj_tptr+=sizeof(struct in_addr);
845                break;
846#ifdef INET6
847            case RSVP_CTYPE_IPV6:
848                if (obj_tlen < sizeof(struct in6_addr))
849                    return-1;
850                printf("%s  IPv6 Notify Node Address: %s",
851                       ident,
852                       ip6addr_string(obj_tptr));
853                obj_tlen-=sizeof(struct in6_addr);
854                obj_tptr+=sizeof(struct in6_addr);
855                break;
856#endif
857            default:
858                hexdump=TRUE;
859            }
860            break;
861
862        case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */
863        case RSVP_OBJ_UPSTREAM_LABEL:  /* fall through */
864        case RSVP_OBJ_RECOVERY_LABEL:  /* fall through */
865        case RSVP_OBJ_LABEL:
866            switch(rsvp_obj_ctype) {
867            case RSVP_CTYPE_1:
868                while(obj_tlen >= 4 ) {
869                    printf("%s  Label: %u", ident, EXTRACT_32BITS(obj_tptr));
870                    obj_tlen-=4;
871                    obj_tptr+=4;
872                }
873                break;
874            case RSVP_CTYPE_2:
875                if (obj_tlen < 4)
876                    return-1;
877                printf("%s  Generalized Label: %u",
878                       ident,
879                       EXTRACT_32BITS(obj_tptr));
880                obj_tlen-=4;
881                obj_tptr+=4;
882                break;
883            case RSVP_CTYPE_3:
884                if (obj_tlen < 12)
885                    return-1;
886                printf("%s  Waveband ID: %u%s  Start Label: %u, Stop Label: %u",
887                       ident,
888                       EXTRACT_32BITS(obj_tptr),
889                       ident,
890                       EXTRACT_32BITS(obj_tptr+4),
891                       EXTRACT_32BITS(obj_tptr+8));
892                obj_tlen-=12;
893                obj_tptr+=12;
894                break;
895            default:
896                hexdump=TRUE;
897            }
898            break;
899
900        case RSVP_OBJ_STYLE:
901            switch(rsvp_obj_ctype) {
902            case RSVP_CTYPE_1:
903                if (obj_tlen < 4)
904                    return-1;
905                printf("%s  Reservation Style: %s, Flags: [0x%02x]",
906                       ident,
907                       tok2str(rsvp_resstyle_values,
908                               "Unknown",
909                               EXTRACT_24BITS(obj_tptr+1)),
910                       *(obj_tptr));
911                obj_tlen-=4;
912                obj_tptr+=4;
913                break;
914            default:
915                hexdump=TRUE;
916            }
917            break;
918
919        case RSVP_OBJ_SENDER_TEMPLATE:
920            switch(rsvp_obj_ctype) {
921            case RSVP_CTYPE_IPV4:
922                if (obj_tlen < 8)
923                    return-1;
924                printf("%s  Source Address: %s, Source Port: %u",
925                       ident,
926                       ipaddr_string(obj_tptr),
927                       EXTRACT_16BITS(obj_tptr+6));
928                obj_tlen-=8;
929                obj_tptr+=8;
930                break;
931#ifdef INET6
932            case RSVP_CTYPE_IPV6:
933                if (obj_tlen < 20)
934                    return-1;
935                printf("%s  Source Address: %s, Source Port: %u",
936                       ident,
937                       ip6addr_string(obj_tptr),
938                       EXTRACT_16BITS(obj_tptr+18));
939                obj_tlen-=20;
940                obj_tptr+=20;
941                break;
942            case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */
943                if (obj_tlen < 40)
944                    return-1;
945                printf("%s  IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x"
946                       "%s  Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
947                       ident,
948                       ip6addr_string(obj_tptr),
949                       EXTRACT_16BITS(obj_tptr+18),
950                       ident,
951                       ip6addr_string(obj_tptr+20),
952                       EXTRACT_16BITS(obj_tptr+38));
953                obj_tlen-=40;
954                obj_tptr+=40;
955                break;
956#endif
957            case RSVP_CTYPE_TUNNEL_IPV4:
958                if (obj_tlen < 8)
959                    return-1;
960                printf("%s  IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x",
961                       ident,
962                       ipaddr_string(obj_tptr),
963                       EXTRACT_16BITS(obj_tptr+6));
964                obj_tlen-=8;
965                obj_tptr+=8;
966                break;
967            case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */
968                if (obj_tlen < 16)
969                    return-1;
970                printf("%s  IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x"
971                       "%s  Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
972                       ident,
973                       ipaddr_string(obj_tptr),
974                       EXTRACT_16BITS(obj_tptr+6),
975                       ident,
976                       ipaddr_string(obj_tptr+8),
977                       EXTRACT_16BITS(obj_tptr+12));
978                obj_tlen-=16;
979                obj_tptr+=16;
980                break;
981            default:
982                hexdump=TRUE;
983            }
984            break;
985
986        case RSVP_OBJ_LABEL_REQ:
987            switch(rsvp_obj_ctype) {
988            case RSVP_CTYPE_1:
989                while(obj_tlen >= 4 ) {
990                    printf("%s  L3 Protocol ID: %s",
991                           ident,
992                           tok2str(ethertype_values,
993                                   "Unknown Protocol (0x%04x)",
994                                   EXTRACT_16BITS(obj_tptr+2)));
995                    obj_tlen-=4;
996                    obj_tptr+=4;
997                }
998                break;
999            case RSVP_CTYPE_2:
1000                if (obj_tlen < 12)
1001                    return-1;
1002                printf("%s  L3 Protocol ID: %s",
1003                       ident,
1004                       tok2str(ethertype_values,
1005                               "Unknown Protocol (0x%04x)",
1006                               EXTRACT_16BITS(obj_tptr+2)));
1007                printf(",%s merge capability",((*(obj_tptr+4))&0x80) ? "no" : "" );
1008                printf("%s  Minimum VPI/VCI: %u/%u",
1009                       ident,
1010                       (EXTRACT_16BITS(obj_tptr+4))&0xfff,
1011                       (EXTRACT_16BITS(obj_tptr+6))&0xfff);
1012                printf("%s  Maximum VPI/VCI: %u/%u",
1013                       ident,
1014                       (EXTRACT_16BITS(obj_tptr+8))&0xfff,
1015                       (EXTRACT_16BITS(obj_tptr+10))&0xfff);
1016                obj_tlen-=12;
1017                obj_tptr+=12;
1018                break;
1019            case RSVP_CTYPE_3:
1020                if (obj_tlen < 12)
1021                    return-1;
1022                printf("%s  L3 Protocol ID: %s",
1023                       ident,
1024                       tok2str(ethertype_values,
1025                               "Unknown Protocol (0x%04x)",
1026                               EXTRACT_16BITS(obj_tptr+2)));
1027                printf("%s  Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI",
1028                       ident,
1029                       (EXTRACT_32BITS(obj_tptr+4))&0x7fffff,
1030                       (EXTRACT_32BITS(obj_tptr+8))&0x7fffff,
1031                       (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "",
1032                       (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 2 ) ? "23" : "");
1033                obj_tlen-=12;
1034                obj_tptr+=12;
1035                break;
1036            case RSVP_CTYPE_4:
1037                if (obj_tlen < 4)
1038                    return-1;
1039                printf("%s  LSP Encoding Type: %s (%u)",
1040                       ident,
1041                       tok2str(gmpls_encoding_values,
1042                               "Unknown",
1043                               *obj_tptr),
1044		       *obj_tptr);
1045                printf("%s  Switching Type: %s (%u), Payload ID: %s (0x%04x)",
1046                       ident,
1047                       tok2str(gmpls_switch_cap_values,
1048                               "Unknown",
1049                               *(obj_tptr+1)),
1050		       *(obj_tptr+1),
1051                       tok2str(gmpls_payload_values,
1052                               "Unknown",
1053                               EXTRACT_16BITS(obj_tptr+2)),
1054		       EXTRACT_16BITS(obj_tptr+2));
1055                obj_tlen-=4;
1056                obj_tptr+=4;
1057                break;
1058            default:
1059                hexdump=TRUE;
1060            }
1061            break;
1062
1063        case RSVP_OBJ_RRO:
1064        case RSVP_OBJ_ERO:
1065            switch(rsvp_obj_ctype) {
1066            case RSVP_CTYPE_IPV4:
1067                while(obj_tlen >= 4 ) {
1068                    printf("%s  Subobject Type: %s, length %u",
1069                           ident,
1070                           tok2str(rsvp_obj_xro_values,
1071                                   "Unknown %u",
1072                                   RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)),
1073                           *(obj_tptr+1));
1074
1075                    if (*(obj_tptr+1) == 0) { /* prevent infinite loops */
1076                        printf("%s  ERROR: zero length ERO subtype",ident);
1077                        break;
1078                    }
1079
1080                    switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) {
1081                    case RSVP_OBJ_XRO_IPV4:
1082                        printf(", %s, %s/%u, Flags: [%s]",
1083                               RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict",
1084                               ipaddr_string(obj_tptr+2),
1085                               *(obj_tptr+6),
1086                               bittok2str(rsvp_obj_rro_flag_values,
1087                                   "none",
1088                                   *(obj_tptr+7))); /* rfc3209 says that this field is rsvd. */
1089                    break;
1090                    case RSVP_OBJ_XRO_LABEL:
1091                        printf(", Flags: [%s] (%#x), Class-Type: %s (%u), %u",
1092                               bittok2str(rsvp_obj_rro_label_flag_values,
1093                                   "none",
1094                                   *(obj_tptr+2)),
1095                               *(obj_tptr+2),
1096                               tok2str(rsvp_ctype_values,
1097                                       "Unknown",
1098                                       *(obj_tptr+3) + 256*RSVP_OBJ_RRO),
1099                               *(obj_tptr+3),
1100                               EXTRACT_32BITS(obj_tptr+4));
1101                    }
1102                    obj_tlen-=*(obj_tptr+1);
1103                    obj_tptr+=*(obj_tptr+1);
1104                }
1105                break;
1106            default:
1107                hexdump=TRUE;
1108            }
1109            break;
1110
1111        case RSVP_OBJ_HELLO:
1112            switch(rsvp_obj_ctype) {
1113            case RSVP_CTYPE_1:
1114            case RSVP_CTYPE_2:
1115                if (obj_tlen < 8)
1116                    return-1;
1117                printf("%s  Source Instance: 0x%08x, Destination Instance: 0x%08x",
1118                       ident,
1119                       EXTRACT_32BITS(obj_tptr),
1120                       EXTRACT_32BITS(obj_tptr+4));
1121                obj_tlen-=8;
1122                obj_tptr+=8;
1123                break;
1124            default:
1125                hexdump=TRUE;
1126            }
1127            break;
1128
1129        case RSVP_OBJ_RESTART_CAPABILITY:
1130            switch(rsvp_obj_ctype) {
1131            case RSVP_CTYPE_1:
1132                if (obj_tlen < 8)
1133                    return-1;
1134                printf("%s  Restart  Time: %ums, Recovery Time: %ums",
1135                       ident,
1136                       EXTRACT_32BITS(obj_tptr),
1137                       EXTRACT_32BITS(obj_tptr+4));
1138                obj_tlen-=8;
1139                obj_tptr+=8;
1140                break;
1141            default:
1142                hexdump=TRUE;
1143            }
1144            break;
1145
1146        case RSVP_OBJ_SESSION_ATTRIBUTE:
1147            switch(rsvp_obj_ctype) {
1148            case RSVP_CTYPE_TUNNEL_IPV4:
1149                if (obj_tlen < 4)
1150                    return-1;
1151                namelen = *(obj_tptr+3);
1152                if (obj_tlen < 4+namelen)
1153                    return-1;
1154                printf("%s  Session Name: ", ident);
1155                for (i = 0; i < namelen; i++)
1156                    safeputchar(*(obj_tptr+4+i));
1157                printf("%s  Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)",
1158                       ident,
1159                       (int)*obj_tptr,
1160                       (int)*(obj_tptr+1),
1161                       bittok2str(rsvp_session_attribute_flag_values,
1162                                  "none",
1163                                  *(obj_tptr+2)),
1164                       *(obj_tptr+2));
1165                obj_tlen-=4+*(obj_tptr+3);
1166                obj_tptr+=4+*(obj_tptr+3);
1167                break;
1168            default:
1169                hexdump=TRUE;
1170            }
1171            break;
1172
1173	case RSVP_OBJ_GENERALIZED_UNI:
1174            switch(rsvp_obj_ctype) {
1175		int subobj_type,af,subobj_len,total_subobj_len;
1176
1177            case RSVP_CTYPE_1:
1178
1179                if (obj_tlen < 4)
1180                    return-1;
1181
1182		/* read variable length subobjects */
1183		total_subobj_len = obj_tlen;
1184                while(total_subobj_len > 0) {
1185                    subobj_len  = EXTRACT_16BITS(obj_tptr);
1186                    subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8;
1187                    af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF;
1188
1189                    printf("%s  Subobject Type: %s (%u), AF: %s (%u), length: %u",
1190                           ident,
1191                           tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type),
1192                           subobj_type,
1193                           tok2str(af_values, "Unknown", af), af,
1194                           subobj_len);
1195
1196                    switch(subobj_type) {
1197                    case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS:
1198                    case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS:
1199
1200                        switch(af) {
1201                        case AFNUM_INET:
1202                            if (subobj_len < 8)
1203                                return -1;
1204                            printf("%s    UNI IPv4 TNA address: %s",
1205                                   ident, ipaddr_string(obj_tptr+4));
1206                            break;
1207#ifdef INET6
1208                        case AFNUM_INET6:
1209                            if (subobj_len < 20)
1210                                return -1;
1211                            printf("%s    UNI IPv6 TNA address: %s",
1212                                   ident, ip6addr_string(obj_tptr+4));
1213                            break;
1214#endif
1215                        case AFNUM_NSAP:
1216                            if (subobj_len) {
1217                                /* unless we have a TLV parser lets just hexdump */
1218                                hexdump=TRUE;
1219                            }
1220                            break;
1221                        }
1222                        break;
1223
1224                    case RSVP_GEN_UNI_SUBOBJ_DIVERSITY:
1225                        if (subobj_len) {
1226                            /* unless we have a TLV parser lets just hexdump */
1227                            hexdump=TRUE;
1228                        }
1229                        break;
1230
1231                    case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL:
1232                        if (subobj_len < 16) {
1233                            return -1;
1234                        }
1235
1236                        printf("%s    U-bit: %x, Label type: %u, Logical port id: %u, Label: %u",
1237                               ident,
1238                               ((EXTRACT_32BITS(obj_tptr+4))>>31),
1239                               ((EXTRACT_32BITS(obj_tptr+4))&0xFF),
1240                               EXTRACT_32BITS(obj_tptr+8),
1241                               EXTRACT_32BITS(obj_tptr+12));
1242                        break;
1243
1244                    case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL:
1245                        if (subobj_len < 8) {
1246                            return -1;
1247                        }
1248
1249                        printf("%s    Service level: %u",
1250                               ident, (EXTRACT_32BITS(obj_tptr+4))>>24);
1251                        break;
1252
1253                    default:
1254                        hexdump=TRUE;
1255                        break;
1256                    }
1257                    total_subobj_len-=subobj_len;
1258                    obj_tptr+=subobj_len;
1259                    obj_tlen+=subobj_len;
1260		}
1261
1262                if (total_subobj_len) {
1263                    /* unless we have a TLV parser lets just hexdump */
1264                    hexdump=TRUE;
1265                }
1266                break;
1267
1268            default:
1269                hexdump=TRUE;
1270            }
1271            break;
1272
1273        case RSVP_OBJ_RSVP_HOP:
1274            switch(rsvp_obj_ctype) {
1275            case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
1276            case RSVP_CTYPE_IPV4:
1277                if (obj_tlen < 8)
1278                    return-1;
1279                printf("%s  Previous/Next Interface: %s, Logical Interface Handle: 0x%08x",
1280                       ident,
1281                       ipaddr_string(obj_tptr),
1282                       EXTRACT_32BITS(obj_tptr+4));
1283                obj_tlen-=8;
1284                obj_tptr+=8;
1285                if (obj_tlen)
1286                    hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
1287                break;
1288#ifdef INET6
1289            case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
1290            case RSVP_CTYPE_IPV6:
1291                if (obj_tlen < 20)
1292                    return-1;
1293                printf("%s  Previous/Next Interface: %s, Logical Interface Handle: 0x%08x",
1294                       ident,
1295                       ip6addr_string(obj_tptr),
1296                       EXTRACT_32BITS(obj_tptr+16));
1297                obj_tlen-=20;
1298                obj_tptr+=20;
1299                hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
1300                break;
1301#endif
1302            default:
1303                hexdump=TRUE;
1304            }
1305            break;
1306
1307        case RSVP_OBJ_TIME_VALUES:
1308            switch(rsvp_obj_ctype) {
1309            case RSVP_CTYPE_1:
1310                if (obj_tlen < 4)
1311                    return-1;
1312                printf("%s  Refresh Period: %ums",
1313                       ident,
1314                       EXTRACT_32BITS(obj_tptr));
1315                obj_tlen-=4;
1316                obj_tptr+=4;
1317                break;
1318            default:
1319                hexdump=TRUE;
1320            }
1321            break;
1322
1323        /* those three objects do share the same semantics */
1324        case RSVP_OBJ_SENDER_TSPEC:
1325        case RSVP_OBJ_ADSPEC:
1326        case RSVP_OBJ_FLOWSPEC:
1327            switch(rsvp_obj_ctype) {
1328            case RSVP_CTYPE_2:
1329                if (obj_tlen < 4)
1330                    return-1;
1331                printf("%s  Msg-Version: %u, length: %u",
1332                       ident,
1333                       (*obj_tptr & 0xf0) >> 4,
1334                       EXTRACT_16BITS(obj_tptr+2)<<2);
1335                obj_tptr+=4; /* get to the start of the service header */
1336                obj_tlen-=4;
1337
1338                while (obj_tlen >= 4) {
1339                    intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2;
1340                    printf("%s  Service Type: %s (%u), break bit %s set, Service length: %u",
1341                           ident,
1342                           tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)),
1343                           *(obj_tptr),
1344                           (*(obj_tptr+1)&0x80) ? "" : "not",
1345                           intserv_serv_tlen);
1346
1347                    obj_tptr+=4; /* get to the start of the parameter list */
1348                    obj_tlen-=4;
1349
1350                    while (intserv_serv_tlen>=4) {
1351                        processed = rsvp_intserv_print(obj_tptr, obj_tlen);
1352                        if (processed == 0)
1353                            break;
1354                        obj_tlen-=processed;
1355                        intserv_serv_tlen-=processed;
1356                        obj_tptr+=processed;
1357                    }
1358                }
1359                break;
1360            default:
1361                hexdump=TRUE;
1362            }
1363            break;
1364
1365        case RSVP_OBJ_FILTERSPEC:
1366            switch(rsvp_obj_ctype) {
1367            case RSVP_CTYPE_IPV4:
1368                if (obj_tlen < 8)
1369                    return-1;
1370                printf("%s  Source Address: %s, Source Port: %u",
1371                       ident,
1372                       ipaddr_string(obj_tptr),
1373                       EXTRACT_16BITS(obj_tptr+6));
1374                obj_tlen-=8;
1375                obj_tptr+=8;
1376                break;
1377#ifdef INET6
1378            case RSVP_CTYPE_IPV6:
1379                if (obj_tlen < 20)
1380                    return-1;
1381                printf("%s  Source Address: %s, Source Port: %u",
1382                       ident,
1383                       ip6addr_string(obj_tptr),
1384                       EXTRACT_16BITS(obj_tptr+18));
1385                obj_tlen-=20;
1386                obj_tptr+=20;
1387                break;
1388            case RSVP_CTYPE_3:
1389                if (obj_tlen < 20)
1390                    return-1;
1391                printf("%s  Source Address: %s, Flow Label: %u",
1392                       ident,
1393                       ip6addr_string(obj_tptr),
1394                       EXTRACT_24BITS(obj_tptr+17));
1395                obj_tlen-=20;
1396                obj_tptr+=20;
1397                break;
1398            case RSVP_CTYPE_TUNNEL_IPV6:
1399                if (obj_tlen < 20)
1400                    return-1;
1401                printf("%s  Source Address: %s, LSP-ID: 0x%04x",
1402                       ident,
1403                       ipaddr_string(obj_tptr),
1404                       EXTRACT_16BITS(obj_tptr+18));
1405                obj_tlen-=20;
1406                obj_tptr+=20;
1407                break;
1408            case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */
1409                if (obj_tlen < 40)
1410                    return-1;
1411                printf("%s  IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x"
1412                       "%s  Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
1413                       ident,
1414                       ip6addr_string(obj_tptr),
1415                       EXTRACT_16BITS(obj_tptr+18),
1416                       ident,
1417                       ip6addr_string(obj_tptr+20),
1418                       EXTRACT_16BITS(obj_tptr+38));
1419                obj_tlen-=40;
1420                obj_tptr+=40;
1421                break;
1422#endif
1423            case RSVP_CTYPE_TUNNEL_IPV4:
1424                if (obj_tlen < 8)
1425                    return-1;
1426                printf("%s  Source Address: %s, LSP-ID: 0x%04x",
1427                       ident,
1428                       ipaddr_string(obj_tptr),
1429                       EXTRACT_16BITS(obj_tptr+6));
1430                obj_tlen-=8;
1431                obj_tptr+=8;
1432                break;
1433            case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */
1434                if (obj_tlen < 16)
1435                    return-1;
1436                printf("%s  IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x"
1437                       "%s  Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
1438                       ident,
1439                       ipaddr_string(obj_tptr),
1440                       EXTRACT_16BITS(obj_tptr+6),
1441                       ident,
1442                       ipaddr_string(obj_tptr+8),
1443                       EXTRACT_16BITS(obj_tptr+12));
1444                obj_tlen-=16;
1445                obj_tptr+=16;
1446                break;
1447            default:
1448                hexdump=TRUE;
1449            }
1450            break;
1451
1452        case RSVP_OBJ_FASTREROUTE:
1453            /* the differences between c-type 1 and 7 are minor */
1454            obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
1455            bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
1456
1457            switch(rsvp_obj_ctype) {
1458            case RSVP_CTYPE_1: /* new style */
1459                if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
1460                    return-1;
1461                printf("%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
1462                       ident,
1463                       (int)obj_ptr.rsvp_obj_frr->setup_prio,
1464                       (int)obj_ptr.rsvp_obj_frr->hold_prio,
1465                       (int)obj_ptr.rsvp_obj_frr->hop_limit,
1466                        bw.f*8/1000000);
1467                printf("%s  Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x",
1468                       ident,
1469                       EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
1470                       EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any),
1471                       EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all));
1472                obj_tlen-=sizeof(struct rsvp_obj_frr_t);
1473                obj_tptr+=sizeof(struct rsvp_obj_frr_t);
1474                break;
1475
1476            case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
1477                if (obj_tlen < 16)
1478                    return-1;
1479                printf("%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
1480                       ident,
1481                       (int)obj_ptr.rsvp_obj_frr->setup_prio,
1482                       (int)obj_ptr.rsvp_obj_frr->hold_prio,
1483                       (int)obj_ptr.rsvp_obj_frr->hop_limit,
1484                        bw.f*8/1000000);
1485                printf("%s  Include Colors: 0x%08x, Exclude Colors: 0x%08x",
1486                       ident,
1487                       EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
1488                       EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any));
1489                obj_tlen-=16;
1490                obj_tptr+=16;
1491                break;
1492
1493            default:
1494                hexdump=TRUE;
1495            }
1496            break;
1497
1498        case RSVP_OBJ_DETOUR:
1499            switch(rsvp_obj_ctype) {
1500            case RSVP_CTYPE_TUNNEL_IPV4:
1501                while(obj_tlen >= 8) {
1502                    printf("%s  PLR-ID: %s, Avoid-Node-ID: %s",
1503                           ident,
1504                           ipaddr_string(obj_tptr),
1505                           ipaddr_string(obj_tptr+4));
1506                    obj_tlen-=8;
1507                    obj_tptr+=8;
1508                }
1509                break;
1510            default:
1511                hexdump=TRUE;
1512            }
1513            break;
1514
1515        case RSVP_OBJ_CLASSTYPE:
1516        case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */
1517            switch(rsvp_obj_ctype) {
1518            case RSVP_CTYPE_1:
1519                printf("%s  CT: %u",
1520                       ident,
1521                       EXTRACT_32BITS(obj_tptr)&0x7);
1522                obj_tlen-=4;
1523                obj_tptr+=4;
1524                break;
1525            default:
1526                hexdump=TRUE;
1527            }
1528            break;
1529
1530        case RSVP_OBJ_ERROR_SPEC:
1531            switch(rsvp_obj_ctype) {
1532            case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
1533            case RSVP_CTYPE_IPV4:
1534                if (obj_tlen < 8)
1535                    return-1;
1536                error_code=*(obj_tptr+5);
1537                error_value=EXTRACT_16BITS(obj_tptr+6);
1538                printf("%s  Error Node Address: %s, Flags: [0x%02x]%s  Error Code: %s (%u)",
1539                       ident,
1540                       ipaddr_string(obj_tptr),
1541                       *(obj_tptr+4),
1542                       ident,
1543                       tok2str(rsvp_obj_error_code_values,"unknown",error_code),
1544                       error_code);
1545                switch (error_code) {
1546                case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING:
1547                    printf(", Error Value: %s (%u)",
1548                           tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
1549                           error_value);
1550                    break;
1551                case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */
1552                case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD:
1553                    printf(", Error Value: %s (%u)",
1554                           tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value),
1555                           error_value);
1556                    break;
1557                default:
1558                    printf(", Unknown Error Value (%u)", error_value);
1559                    break;
1560                }
1561                obj_tlen-=8;
1562                obj_tptr+=8;
1563                break;
1564#ifdef INET6
1565            case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
1566            case RSVP_CTYPE_IPV6:
1567                if (obj_tlen < 20)
1568                    return-1;
1569                error_code=*(obj_tptr+17);
1570                error_value=EXTRACT_16BITS(obj_tptr+18);
1571                printf("%s  Error Node Address: %s, Flags: [0x%02x]%s  Error Code: %s (%u)",
1572                       ident,
1573                       ip6addr_string(obj_tptr),
1574                       *(obj_tptr+16),
1575                       ident,
1576                       tok2str(rsvp_obj_error_code_values,"unknown",error_code),
1577                       error_code);
1578
1579                switch (error_code) {
1580                case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING:
1581                    printf(", Error Value: %s (%u)",
1582                           tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
1583			   error_value);
1584                    break;
1585                default:
1586                    break;
1587                }
1588                obj_tlen-=20;
1589                obj_tptr+=20;
1590                break;
1591#endif
1592            default:
1593                hexdump=TRUE;
1594            }
1595            break;
1596
1597        case RSVP_OBJ_PROPERTIES:
1598            switch(rsvp_obj_ctype) {
1599            case RSVP_CTYPE_1:
1600                if (obj_tlen < 4)
1601                    return-1;
1602                padbytes = EXTRACT_16BITS(obj_tptr+2);
1603                printf("%s  TLV count: %u, padding bytes: %u",
1604                       ident,
1605                       EXTRACT_16BITS(obj_tptr),
1606                       padbytes);
1607                obj_tlen-=4;
1608                obj_tptr+=4;
1609                /* loop through as long there is anything longer than the TLV header (2) */
1610                while(obj_tlen >= 2 + padbytes) {
1611                    printf("%s    %s TLV (0x%02x), length: %u", /* length includes header */
1612                           ident,
1613                           tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr),
1614                           *obj_tptr,
1615                           *(obj_tptr+1));
1616                    if (obj_tlen < *(obj_tptr+1))
1617                        return-1;
1618                    if (*(obj_tptr+1) < 2)
1619                        return -1;
1620                    print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2);
1621                    obj_tlen-=*(obj_tptr+1);
1622                    obj_tptr+=*(obj_tptr+1);
1623                }
1624                break;
1625            default:
1626                hexdump=TRUE;
1627            }
1628            break;
1629
1630        case RSVP_OBJ_MESSAGE_ID:     /* fall through */
1631        case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */
1632        case RSVP_OBJ_MESSAGE_ID_LIST:
1633            switch(rsvp_obj_ctype) {
1634            case RSVP_CTYPE_1:
1635            case RSVP_CTYPE_2:
1636                if (obj_tlen < 8)
1637                    return-1;
1638                printf("%s  Flags [0x%02x], epoch: %u",
1639                       ident,
1640                       *obj_tptr,
1641                       EXTRACT_24BITS(obj_tptr+1));
1642                obj_tlen-=4;
1643                obj_tptr+=4;
1644                /* loop through as long there are no messages left */
1645                while(obj_tlen >= 4) {
1646                    printf("%s    Message-ID 0x%08x (%u)",
1647                           ident,
1648                           EXTRACT_32BITS(obj_tptr),
1649                           EXTRACT_32BITS(obj_tptr));
1650                    obj_tlen-=4;
1651                    obj_tptr+=4;
1652                }
1653                break;
1654            default:
1655                hexdump=TRUE;
1656            }
1657            break;
1658
1659        case RSVP_OBJ_INTEGRITY:
1660            switch(rsvp_obj_ctype) {
1661            case RSVP_CTYPE_1:
1662                if (obj_tlen < sizeof(struct rsvp_obj_integrity_t))
1663                    return-1;
1664                obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr;
1665                printf("%s  Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]",
1666                       ident,
1667                       EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id),
1668                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2),
1669                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence),
1670                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4),
1671                       bittok2str(rsvp_obj_integrity_flag_values,
1672                                  "none",
1673                                  obj_ptr.rsvp_obj_integrity->flags));
1674                printf("%s  MD5-sum 0x%08x%08x%08x%08x ",
1675                       ident,
1676                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest),
1677                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4),
1678                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8),
1679                       EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12));
1680
1681#ifdef HAVE_LIBCRYPTO
1682                sigcheck = signature_verify(pptr, plen, (unsigned char *)obj_ptr.\
1683                                             rsvp_obj_integrity->digest);
1684#else
1685                sigcheck = CANT_CHECK_SIGNATURE;
1686#endif
1687                printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck));
1688
1689                obj_tlen+=sizeof(struct rsvp_obj_integrity_t);
1690                obj_tptr+=sizeof(struct rsvp_obj_integrity_t);
1691                break;
1692            default:
1693                hexdump=TRUE;
1694            }
1695            break;
1696
1697        case RSVP_OBJ_ADMIN_STATUS:
1698            switch(rsvp_obj_ctype) {
1699            case RSVP_CTYPE_1:
1700                if (obj_tlen < 4)
1701                    return-1;
1702                printf("%s  Flags [%s]", ident,
1703                       bittok2str(rsvp_obj_admin_status_flag_values, "none",
1704                                  EXTRACT_32BITS(obj_tptr)));
1705                obj_tlen-=4;
1706                obj_tptr+=4;
1707                break;
1708            default:
1709                hexdump=TRUE;
1710            }
1711            break;
1712
1713        case RSVP_OBJ_LABEL_SET:
1714            switch(rsvp_obj_ctype) {
1715            case RSVP_CTYPE_1:
1716                if (obj_tlen < 4)
1717                    return-1;
1718                action = (EXTRACT_16BITS(obj_tptr)>>8);
1719
1720                printf("%s  Action: %s (%u), Label type: %u", ident,
1721                       tok2str(rsvp_obj_label_set_action_values, "Unknown", action),
1722                       action, ((EXTRACT_32BITS(obj_tptr) & 0x7F)));
1723
1724                switch (action) {
1725                case LABEL_SET_INCLUSIVE_RANGE:
1726                case LABEL_SET_EXCLUSIVE_RANGE: /* fall through */
1727
1728		    /* only a couple of subchannels are expected */
1729		    if (obj_tlen < 12)
1730			return -1;
1731		    printf("%s  Start range: %u, End range: %u", ident,
1732                           EXTRACT_32BITS(obj_tptr+4),
1733                           EXTRACT_32BITS(obj_tptr+8));
1734		    obj_tlen-=12;
1735		    obj_tptr+=12;
1736                    break;
1737
1738                default:
1739                    obj_tlen-=4;
1740                    obj_tptr+=4;
1741                    subchannel = 1;
1742                    while(obj_tlen >= 4 ) {
1743                        printf("%s  Subchannel #%u: %u", ident, subchannel,
1744                               EXTRACT_32BITS(obj_tptr));
1745                        obj_tptr+=4;
1746                        obj_tlen-=4;
1747                        subchannel++;
1748                    }
1749                    break;
1750                }
1751                break;
1752            default:
1753                hexdump=TRUE;
1754            }
1755
1756        case RSVP_OBJ_S2L:
1757            switch (rsvp_obj_ctype) {
1758            case RSVP_CTYPE_IPV4:
1759                if (obj_tlen < 4)
1760                    return-1;
1761                printf("%s  Sub-LSP destination address: %s",
1762                       ident, ipaddr_string(obj_tptr));
1763
1764                obj_tlen-=4;
1765                obj_tptr+=4;
1766                break;
1767#ifdef INET6
1768            case RSVP_CTYPE_IPV6:
1769                if (obj_tlen < 16)
1770                    return-1;
1771                printf("%s  Sub-LSP destination address: %s",
1772                       ident, ip6addr_string(obj_tptr));
1773
1774                obj_tlen-=16;
1775                obj_tptr+=16;
1776                break;
1777#endif
1778            default:
1779                hexdump=TRUE;
1780            }
1781
1782        /*
1783         *  FIXME those are the defined objects that lack a decoder
1784         *  you are welcome to contribute code ;-)
1785         */
1786
1787        case RSVP_OBJ_SCOPE:
1788        case RSVP_OBJ_POLICY_DATA:
1789        case RSVP_OBJ_ACCEPT_LABEL_SET:
1790        case RSVP_OBJ_PROTECTION:
1791        default:
1792            if (vflag <= 1)
1793                print_unknown_data(obj_tptr,"\n\t    ",obj_tlen); /* FIXME indentation */
1794            break;
1795        }
1796        /* do we also want to see a hex dump ? */
1797        if (vflag > 1 || hexdump==TRUE)
1798            print_unknown_data(tptr+sizeof(struct rsvp_object_header),"\n\t    ", /* FIXME indentation */
1799                               rsvp_obj_len-sizeof(struct rsvp_object_header));
1800
1801        tptr+=rsvp_obj_len;
1802        tlen-=rsvp_obj_len;
1803    }
1804    return 0;
1805trunc:
1806    printf("\n\t\t packet exceeded snapshot");
1807    return -1;
1808}
1809
1810
1811void
1812rsvp_print(register const u_char *pptr, register u_int len) {
1813
1814    struct rsvp_common_header *rsvp_com_header;
1815    const u_char *tptr,*subtptr;
1816    u_short plen, tlen, subtlen;
1817
1818    tptr=pptr;
1819
1820    rsvp_com_header = (struct rsvp_common_header *)pptr;
1821    TCHECK(*rsvp_com_header);
1822
1823    /*
1824     * Sanity checking of the header.
1825     */
1826    if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) {
1827	printf("ERROR: RSVP version %u packet not supported",
1828               RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags));
1829	return;
1830    }
1831
1832    /* in non-verbose mode just lets print the basic Message Type*/
1833    if (vflag < 1) {
1834        printf("RSVPv%u %s Message, length: %u",
1835               RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
1836               tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type),
1837               len);
1838        return;
1839    }
1840
1841    /* ok they seem to want to know everything - lets fully decode it */
1842
1843    plen = tlen = EXTRACT_16BITS(rsvp_com_header->length);
1844
1845    printf("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x",
1846           RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
1847           tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type),
1848           rsvp_com_header->msg_type,
1849           bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)),
1850           tlen,
1851           rsvp_com_header->ttl,
1852           EXTRACT_16BITS(rsvp_com_header->checksum));
1853
1854    /*
1855     * Clear checksum prior to signature verification.
1856     */
1857    rsvp_com_header->checksum[0] = 0;
1858    rsvp_com_header->checksum[1] = 0;
1859
1860    if (tlen < sizeof(const struct rsvp_common_header)) {
1861        printf("ERROR: common header too short %u < %lu", tlen,
1862               (unsigned long)sizeof(const struct rsvp_common_header));
1863        return;
1864    }
1865
1866    tptr+=sizeof(const struct rsvp_common_header);
1867    tlen-=sizeof(const struct rsvp_common_header);
1868
1869    switch(rsvp_com_header->msg_type) {
1870
1871    case RSVP_MSGTYPE_AGGREGATE:
1872        while(tlen > 0) {
1873            subtptr=tptr;
1874            rsvp_com_header = (struct rsvp_common_header *)subtptr;
1875            TCHECK(*rsvp_com_header);
1876
1877            /*
1878             * Sanity checking of the header.
1879             */
1880            if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) {
1881                printf("ERROR: RSVP version %u packet not supported",
1882                       RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags));
1883                return;
1884            }
1885            subtlen=EXTRACT_16BITS(rsvp_com_header->length);
1886
1887            printf("\n\t  RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x",
1888                   RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
1889                   tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type),
1890                   rsvp_com_header->msg_type,
1891                   bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)),
1892                   subtlen,
1893                   rsvp_com_header->ttl,
1894                   EXTRACT_16BITS(rsvp_com_header->checksum));
1895
1896            /*
1897             * Clear checksum prior to signature verification.
1898             */
1899            rsvp_com_header->checksum[0] = 0;
1900            rsvp_com_header->checksum[1] = 0;
1901
1902            if (subtlen < sizeof(const struct rsvp_common_header)) {
1903                printf("ERROR: common header too short %u < %lu", subtlen,
1904                       (unsigned long)sizeof(const struct rsvp_common_header));
1905                return;
1906            }
1907
1908            if (tlen < subtlen) {
1909                printf("ERROR: common header too large %u > %u", subtlen,
1910                       tlen);
1911                return;
1912            }
1913
1914            subtptr+=sizeof(const struct rsvp_common_header);
1915            subtlen-=sizeof(const struct rsvp_common_header);
1916
1917            if (rsvp_obj_print(pptr, plen, subtptr,"\n\t    ", subtlen) == -1)
1918                return;
1919
1920            tptr+=subtlen+sizeof(const struct rsvp_common_header);
1921            tlen-=subtlen+sizeof(const struct rsvp_common_header);
1922        }
1923
1924        break;
1925
1926    case RSVP_MSGTYPE_PATH:
1927    case RSVP_MSGTYPE_RESV:
1928    case RSVP_MSGTYPE_PATHERR:
1929    case RSVP_MSGTYPE_RESVERR:
1930    case RSVP_MSGTYPE_PATHTEAR:
1931    case RSVP_MSGTYPE_RESVTEAR:
1932    case RSVP_MSGTYPE_RESVCONF:
1933    case RSVP_MSGTYPE_HELLO_OLD:
1934    case RSVP_MSGTYPE_HELLO:
1935    case RSVP_MSGTYPE_ACK:
1936    case RSVP_MSGTYPE_SREFRESH:
1937        if (rsvp_obj_print(pptr, plen, tptr,"\n\t  ", tlen) == -1)
1938            return;
1939        break;
1940
1941    default:
1942        print_unknown_data(tptr,"\n\t    ",tlen);
1943        break;
1944    }
1945
1946    return;
1947trunc:
1948    printf("\n\t\t packet exceeded snapshot");
1949}
1950