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