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