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