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