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