]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-rsvp.c
This commit was generated by cvs2svn to compensate for changes in r168777,
[FreeBSD/FreeBSD.git] / contrib / tcpdump / 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.8 2005/09/22 14:52:40 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 #define FALSE 0
420 #define TRUE  1
421
422
423 static int rsvp_intserv_print(const u_char *, u_short);
424
425 /* 
426  * this is a dissector for all the intserv defined
427  * specs as defined per rfc2215
428  * it is called from various rsvp objects;
429  * returns the amount of bytes being processed
430  */
431 static int
432 rsvp_intserv_print(const u_char *tptr, u_short obj_tlen) {
433
434     int parameter_id,parameter_length;
435     union {
436         float f;
437         u_int32_t i;
438     } bw;
439
440     if (obj_tlen < 4)
441         return 0;
442     parameter_id = *(tptr);
443     parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */
444
445     printf("\n\t      Parameter ID: %s (%u), length: %u, Flags: [0x%02x]",
446            tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id),
447            parameter_id,
448            parameter_length,
449            *(tptr+1));
450
451     if (obj_tlen < parameter_length+4)
452         return 0;
453     switch(parameter_id) { /* parameter_id */
454
455     case 4:
456        /*
457         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
458         * |    4 (e)      |    (f)        |           1 (g)               |
459         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
460         * |        IS hop cnt (32-bit unsigned integer)                   |
461         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
462         */
463         if (parameter_length == 4)
464             printf("\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr+4));
465         break;
466
467     case 6:
468        /*
469         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
470         * |    6 (h)      |    (i)        |           1 (j)               |
471         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
472         * |  Path b/w estimate  (32-bit IEEE floating point number)       |
473         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
474         */
475         if (parameter_length == 4) {
476             bw.i = EXTRACT_32BITS(tptr+4);
477             printf("\n\t\tPath b/w estimate: %.10g Mbps", bw.f/125000);
478         }
479         break;
480
481     case 8:
482        /*
483         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
484         * |     8 (k)     |    (l)        |           1 (m)               |
485         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
486         * |        Minimum path latency (32-bit integer)                  |
487         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
488         */
489         if (parameter_length == 4) {
490             printf("\n\t\tMinimum path latency: ");
491             if (EXTRACT_32BITS(tptr+4) == 0xffffffff)
492                 printf("don't care");
493             else
494                 printf("%u", EXTRACT_32BITS(tptr+4));
495         }
496         break;
497
498     case 10:
499
500        /*
501         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
502         * |     10 (n)    |      (o)      |           1 (p)               |
503         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
504         * |      Composed MTU (32-bit unsigned integer)                   |
505         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
506         */
507         if (parameter_length == 4)
508             printf("\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr+4));
509         break;
510     case 127:
511        /* 
512         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
513         * |   127 (e)     |    0 (f)      |             5 (g)             |
514         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
515         * |  Token Bucket Rate [r] (32-bit IEEE floating point number)    |
516         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
517         * |  Token Bucket Size [b] (32-bit IEEE floating point number)    |
518         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
519         * |  Peak Data Rate [p] (32-bit IEEE floating point number)       |
520         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
521         * |  Minimum Policed Unit [m] (32-bit integer)                    |
522         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
523         * |  Maximum Packet Size [M]  (32-bit integer)                    |
524         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
525         */
526
527         if (parameter_length == 20) {
528             bw.i = EXTRACT_32BITS(tptr+4);
529             printf("\n\t\tToken Bucket Rate: %.10g Mbps", bw.f/125000);
530             bw.i = EXTRACT_32BITS(tptr+8);
531             printf("\n\t\tToken Bucket Size: %.10g bytes", bw.f);
532             bw.i = EXTRACT_32BITS(tptr+12);
533             printf("\n\t\tPeak Data Rate: %.10g Mbps", bw.f/125000);
534             printf("\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr+16));
535             printf("\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr+20));
536         }
537         break;
538
539     case 130:
540        /* 
541         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
542         * |     130 (h)   |    0 (i)      |            2 (j)              |
543         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
544         * |  Rate [R]  (32-bit IEEE floating point number)                |
545         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
546         * |  Slack Term [S]  (32-bit integer)                             |
547         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
548         */
549
550         if (parameter_length == 8) {
551             bw.i = EXTRACT_32BITS(tptr+4);
552             printf("\n\t\tRate: %.10g Mbps", bw.f/125000);
553             printf("\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr+8));
554         }
555         break;
556
557     case 133:
558     case 134:
559     case 135:
560     case 136:
561         if (parameter_length == 4)
562             printf("\n\t\tValue: %u", EXTRACT_32BITS(tptr+4));
563         break;
564
565     default:
566         if (vflag <= 1)
567             print_unknown_data(tptr+4,"\n\t\t",parameter_length);
568     }
569     return (parameter_length+4); /* header length 4 bytes */
570 }
571
572 static int
573 rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
574
575     const struct rsvp_object_header *rsvp_obj_header;
576     const u_char *obj_tptr;
577     union {
578         const struct rsvp_obj_integrity_t *rsvp_obj_integrity;
579         const struct rsvp_obj_frr_t *rsvp_obj_frr;
580     } obj_ptr;
581
582     u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen;
583     int hexdump,processed,padbytes,error_code,error_value,i;
584     union {
585         float f;
586         u_int32_t i;
587     } bw;
588     u_int8_t namelen;
589
590     while(tlen>=sizeof(struct rsvp_object_header)) {
591         /* did we capture enough for fully decoding the object header ? */
592         if (!TTEST2(*tptr, sizeof(struct rsvp_object_header)))
593             goto trunc;
594
595         rsvp_obj_header = (const struct rsvp_object_header *)tptr;
596         rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length);
597         rsvp_obj_ctype=rsvp_obj_header->ctype;
598
599         if(rsvp_obj_len % 4) {
600             printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len);
601             return -1;
602         }
603         if(rsvp_obj_len < sizeof(struct rsvp_object_header)) {
604             printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len,
605                    (unsigned long)sizeof(const struct rsvp_object_header));
606             return -1;
607         }
608
609         printf("%s%s Object (%u) Flags: [%s",
610                ident,
611                tok2str(rsvp_obj_values,
612                        "Unknown",
613                        rsvp_obj_header->class_num),
614                rsvp_obj_header->class_num,
615                ((rsvp_obj_header->class_num)&0x80) ? "ignore" : "reject");
616
617         if (rsvp_obj_header->class_num > 128)
618             printf(" %s",
619                    ((rsvp_obj_header->class_num)&0x40) ? "and forward" : "silently");
620
621         printf(" if unknown], Class-Type: %s (%u), length: %u",
622                tok2str(rsvp_ctype_values,
623                        "Unknown",
624                        ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype),
625                rsvp_obj_ctype,
626                rsvp_obj_len);
627     
628         if(tlen < rsvp_obj_len) {
629             printf("%sERROR: object goes past end of objects TLV", ident);
630             return -1;
631         }
632
633         obj_tptr=tptr+sizeof(struct rsvp_object_header);
634         obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header);
635
636         /* did we capture enough for fully decoding the object ? */
637         if (!TTEST2(*tptr, rsvp_obj_len))
638             return -1;
639         hexdump=FALSE;
640
641         switch(rsvp_obj_header->class_num) {
642         case RSVP_OBJ_SESSION:
643             switch(rsvp_obj_ctype) {
644             case RSVP_CTYPE_IPV4:
645                 if (obj_tlen < 8)
646                     return -1;
647                 printf("%s  IPv4 DestAddress: %s, Protocol ID: 0x%02x",
648                        ident,
649                        ipaddr_string(obj_tptr),
650                        *(obj_tptr+sizeof(struct in_addr)));
651                 printf("%s  Flags: [0x%02x], DestPort %u",
652                        ident,
653                        *(obj_tptr+5),
654                        EXTRACT_16BITS(obj_tptr+6));
655                 obj_tlen-=8;
656                 obj_tptr+=8;                
657                 break;
658 #ifdef INET6
659             case RSVP_CTYPE_IPV6:
660                 if (obj_tlen < 20)
661                     return -1;
662                 printf("%s  IPv6 DestAddress: %s, Protocol ID: 0x%02x",
663                        ident,
664                        ip6addr_string(obj_tptr),
665                        *(obj_tptr+sizeof(struct in6_addr)));
666                 printf("%s  Flags: [0x%02x], DestPort %u",
667                        ident,
668                        *(obj_tptr+sizeof(struct in6_addr)+1),
669                        EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2));
670                 obj_tlen-=20;
671                 obj_tptr+=20;                
672                 break;
673
674             case RSVP_CTYPE_TUNNEL_IPV6:
675                 if (obj_tlen < 36)
676                     return -1;
677                 printf("%s  IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
678                        ident,
679                        ip6addr_string(obj_tptr),
680                        EXTRACT_16BITS(obj_tptr+18),
681                        ip6addr_string(obj_tptr+20));
682                 obj_tlen-=36;
683                 obj_tptr+=36;                
684                 break;
685 #endif
686             case RSVP_CTYPE_TUNNEL_IPV4:
687                 if (obj_tlen < 12)
688                     return -1;
689                 printf("%s  IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
690                        ident,
691                        ipaddr_string(obj_tptr),
692                        EXTRACT_16BITS(obj_tptr+6),
693                        ipaddr_string(obj_tptr+8));
694                 obj_tlen-=12;
695                 obj_tptr+=12;                
696                 break;
697             default:
698                 hexdump=TRUE;
699             }
700             break;
701
702         case RSVP_OBJ_CONFIRM:
703             switch(rsvp_obj_ctype) {
704             case RSVP_CTYPE_IPV4:
705                 if (obj_tlen < sizeof(struct in_addr))
706                     return -1;
707                 printf("%s  IPv4 Receiver Address: %s",
708                        ident,
709                        ipaddr_string(obj_tptr));
710                 obj_tlen-=sizeof(struct in_addr);
711                 obj_tptr+=sizeof(struct in_addr);                
712                 break;
713 #ifdef INET6
714             case RSVP_CTYPE_IPV6:
715                 if (obj_tlen < sizeof(struct in6_addr))
716                     return -1;
717                 printf("%s  IPv6 Receiver Address: %s",
718                        ident,
719                        ip6addr_string(obj_tptr));
720                 obj_tlen-=sizeof(struct in6_addr);
721                 obj_tptr+=sizeof(struct in6_addr);                
722                 break;
723 #endif
724             default:
725                 hexdump=TRUE;
726             }
727             break;
728
729         case RSVP_OBJ_NOTIFY_REQ:
730             switch(rsvp_obj_ctype) {
731             case RSVP_CTYPE_IPV4:
732                 if (obj_tlen < sizeof(struct in_addr))
733                     return -1;
734                 printf("%s  IPv4 Notify Node Address: %s",
735                        ident,
736                        ipaddr_string(obj_tptr));
737                 obj_tlen-=sizeof(struct in_addr);
738                 obj_tptr+=sizeof(struct in_addr);                
739                 break;
740 #ifdef INET6
741             case RSVP_CTYPE_IPV6:
742                 if (obj_tlen < sizeof(struct in6_addr))
743                     return-1;
744                 printf("%s  IPv6 Notify Node Address: %s",
745                        ident,
746                        ip6addr_string(obj_tptr));
747                 obj_tlen-=sizeof(struct in6_addr);
748                 obj_tptr+=sizeof(struct in6_addr);                
749                 break;
750 #endif
751             default:
752                 hexdump=TRUE;
753             }
754             break;
755
756         case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */
757         case RSVP_OBJ_UPSTREAM_LABEL:  /* fall through */
758         case RSVP_OBJ_RECOVERY_LABEL:  /* fall through */
759         case RSVP_OBJ_LABEL:
760             switch(rsvp_obj_ctype) {
761             case RSVP_CTYPE_1:
762                 while(obj_tlen >= 4 ) {
763                     printf("%s  Label: %u", ident, EXTRACT_32BITS(obj_tptr));
764                     obj_tlen-=4;
765                     obj_tptr+=4;
766                 }
767                 break;
768             case RSVP_CTYPE_2:
769                 if (obj_tlen < 4)
770                     return-1;
771                 printf("%s  Generalized Label: %u",
772                        ident,
773                        EXTRACT_32BITS(obj_tptr));
774                 obj_tlen-=4;
775                 obj_tptr+=4;
776                 break;
777             case RSVP_CTYPE_3:
778                 if (obj_tlen < 12)
779                     return-1;
780                 printf("%s  Waveband ID: %u%s  Start Label: %u, Stop Label: %u",
781                        ident,
782                        EXTRACT_32BITS(obj_tptr),
783                        ident,
784                        EXTRACT_32BITS(obj_tptr+4),
785                        EXTRACT_32BITS(obj_tptr+8));
786                 obj_tlen-=12;
787                 obj_tptr+=12;
788                 break;
789             default:
790                 hexdump=TRUE;
791             }
792             break;
793
794         case RSVP_OBJ_STYLE:
795             switch(rsvp_obj_ctype) {
796             case RSVP_CTYPE_1:
797                 if (obj_tlen < 4)
798                     return-1;
799                 printf("%s  Reservation Style: %s, Flags: [0x%02x]",
800                        ident,
801                        tok2str(rsvp_resstyle_values,
802                                "Unknown",
803                                EXTRACT_24BITS(obj_tptr+1)),
804                        *(obj_tptr));
805                 obj_tlen-=4;
806                 obj_tptr+=4;
807                 break;
808             default:
809                 hexdump=TRUE;
810             }
811             break;
812
813         case RSVP_OBJ_SENDER_TEMPLATE:
814             switch(rsvp_obj_ctype) {
815             case RSVP_CTYPE_IPV4:
816                 if (obj_tlen < 8)
817                     return-1;
818                 printf("%s  Source Address: %s, Source Port: %u",
819                        ident,
820                        ipaddr_string(obj_tptr),
821                        EXTRACT_16BITS(obj_tptr+6));
822                 obj_tlen-=8;
823                 obj_tptr+=8;
824                 break;
825 #ifdef INET6
826             case RSVP_CTYPE_IPV6:
827                 if (obj_tlen < 20)
828                     return-1;
829                 printf("%s  Source Address: %s, Source Port: %u",
830                        ident,
831                        ip6addr_string(obj_tptr),
832                        EXTRACT_16BITS(obj_tptr+18));
833                 obj_tlen-=20;
834                 obj_tptr+=20;
835                 break;
836 #endif
837             case RSVP_CTYPE_TUNNEL_IPV4:
838                 if (obj_tlen < 8)
839                     return-1;
840                 printf("%s  IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x",
841                        ident,
842                        ipaddr_string(obj_tptr),
843                        EXTRACT_16BITS(obj_tptr+6));
844                 obj_tlen-=8;
845                 obj_tptr+=8;
846                 break;
847             default:
848                 hexdump=TRUE;
849             }
850             break;
851
852         case RSVP_OBJ_LABEL_REQ:
853             switch(rsvp_obj_ctype) {
854             case RSVP_CTYPE_1:
855                 while(obj_tlen >= 4 ) {
856                     printf("%s  L3 Protocol ID: %s",
857                            ident,
858                            tok2str(ethertype_values,
859                                    "Unknown Protocol (0x%04x)",
860                                    EXTRACT_16BITS(obj_tptr+2)));
861                     obj_tlen-=4;
862                     obj_tptr+=4;
863                 }
864                 break;
865             case RSVP_CTYPE_2:
866                 if (obj_tlen < 12)
867                     return-1;
868                 printf("%s  L3 Protocol ID: %s",
869                        ident,
870                        tok2str(ethertype_values,
871                                "Unknown Protocol (0x%04x)",
872                                EXTRACT_16BITS(obj_tptr+2)));
873                 printf(",%s merge capability",((*(obj_tptr+4))&0x80) ? "no" : "" );
874                 printf("%s  Minimum VPI/VCI: %u/%u",
875                        ident,
876                        (EXTRACT_16BITS(obj_tptr+4))&0xfff,
877                        (EXTRACT_16BITS(obj_tptr+6))&0xfff);
878                 printf("%s  Maximum VPI/VCI: %u/%u",
879                        ident,
880                        (EXTRACT_16BITS(obj_tptr+8))&0xfff,
881                        (EXTRACT_16BITS(obj_tptr+10))&0xfff);
882                 obj_tlen-=12;
883                 obj_tptr+=12;
884                 break;
885             case RSVP_CTYPE_3:
886                 if (obj_tlen < 12)
887                     return-1;
888                 printf("%s  L3 Protocol ID: %s",
889                        ident,
890                        tok2str(ethertype_values,
891                                "Unknown Protocol (0x%04x)",
892                                EXTRACT_16BITS(obj_tptr+2)));
893                 printf("%s  Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI",
894                        ident,
895                        (EXTRACT_32BITS(obj_tptr+4))&0x7fffff,
896                        (EXTRACT_32BITS(obj_tptr+8))&0x7fffff,
897                        (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "",
898                        (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 2 ) ? "23" : "");
899                 obj_tlen-=12;
900                 obj_tptr+=12;
901                 break;
902             case RSVP_CTYPE_4:
903                 if (obj_tlen < 8)
904                     return-1;
905                 printf("%s  LSP Encoding Type: %s (%u)",
906                        ident,
907                        tok2str(gmpls_encoding_values,
908                                "Unknown",
909                                *obj_tptr),
910                        *obj_tptr);
911                 printf("%s  Switching Type: %s (%u), Payload ID: %s (0x%04x)",
912                        ident,
913                        tok2str(gmpls_switch_cap_values,
914                                "Unknown",
915                                *(obj_tptr+1)),
916                        *(obj_tptr+1),
917                        tok2str(gmpls_payload_values,
918                                "Unknown",
919                                EXTRACT_16BITS(obj_tptr+2)),
920                        EXTRACT_16BITS(obj_tptr+2));
921                 obj_tlen-=8;
922                 obj_tptr+=8;
923                 break;
924             default:
925                 hexdump=TRUE;
926             }
927             break;
928
929         case RSVP_OBJ_RRO:
930         case RSVP_OBJ_ERO:
931             switch(rsvp_obj_ctype) {
932             case RSVP_CTYPE_IPV4:
933                 while(obj_tlen >= 4 ) {
934                     printf("%s  Subobject Type: %s, length %u",
935                            ident,
936                            tok2str(rsvp_obj_xro_values,
937                                    "Unknown %u",
938                                    RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)),
939                            *(obj_tptr+1));                
940
941                     if (*(obj_tptr+1) == 0) { /* prevent infinite loops */
942                         printf("%s  ERROR: zero length ERO subtype",ident);
943                         break;
944                     }
945
946                     switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) {
947                     case RSVP_OBJ_XRO_IPV4:
948                         printf(", %s, %s/%u, Flags: [%s]",
949                                RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict",
950                                ipaddr_string(obj_tptr+2),
951                                *(obj_tptr+6),
952                                bittok2str(rsvp_obj_rro_flag_values,
953                                    "none",
954                                    *(obj_tptr+7))); /* rfc3209 says that this field is rsvd. */
955                     }
956                     obj_tlen-=*(obj_tptr+1);
957                     obj_tptr+=*(obj_tptr+1);
958                 }
959                 break;
960             default:
961                 hexdump=TRUE;
962             }
963             break;
964
965         case RSVP_OBJ_HELLO:
966             switch(rsvp_obj_ctype) {
967             case RSVP_CTYPE_1:
968             case RSVP_CTYPE_2:
969                 if (obj_tlen < 8)
970                     return-1;
971                 printf("%s  Source Instance: 0x%08x, Destination Instance: 0x%08x",
972                        ident,
973                        EXTRACT_32BITS(obj_tptr),
974                        EXTRACT_32BITS(obj_tptr+4));
975                 obj_tlen-=8;
976                 obj_tptr+=8;
977                 break;
978             default:
979                 hexdump=TRUE;
980             }
981             break;
982
983         case RSVP_OBJ_RESTART_CAPABILITY:
984             switch(rsvp_obj_ctype) {
985             case RSVP_CTYPE_1:
986                 if (obj_tlen < 8)
987                     return-1;
988                 printf("%s  Restart  Time: %ums, Recovery Time: %ums",
989                        ident,
990                        EXTRACT_32BITS(obj_tptr),
991                        EXTRACT_32BITS(obj_tptr+4));
992                 obj_tlen-=8;
993                 obj_tptr+=8;
994                 break;
995             default:
996                 hexdump=TRUE;
997             }
998             break;
999
1000         case RSVP_OBJ_SESSION_ATTRIBUTE:
1001             switch(rsvp_obj_ctype) {
1002             case RSVP_CTYPE_TUNNEL_IPV4:
1003                 if (obj_tlen < 4)
1004                     return-1;
1005                 namelen = *(obj_tptr+3);
1006                 if (obj_tlen < 4+namelen)
1007                     return-1;
1008                 printf("%s  Session Name: ", ident);
1009                 for (i = 0; i < namelen; i++)
1010                     safeputchar(*(obj_tptr+4+i));
1011                 printf("%s  Setup Priority: %u, Holding Priority: %u, Flags: [%s]",
1012                        ident,
1013                        (int)*obj_tptr,
1014                        (int)*(obj_tptr+1),
1015                        tok2str(rsvp_session_attribute_flag_values,
1016                                   "none",
1017                                   *(obj_tptr+2)));
1018
1019                 obj_tlen-=4+*(obj_tptr+3);
1020                 obj_tptr+=4+*(obj_tptr+3);
1021                 break;
1022             default:
1023                 hexdump=TRUE;
1024             }
1025             break;
1026
1027         case RSVP_OBJ_RSVP_HOP:
1028             switch(rsvp_obj_ctype) {
1029             case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
1030             case RSVP_CTYPE_IPV4:
1031                 if (obj_tlen < 8)
1032                     return-1;
1033                 printf("%s  Previous/Next Interface: %s, Logical Interface Handle: 0x%08x",
1034                        ident,
1035                        ipaddr_string(obj_tptr),
1036                        EXTRACT_32BITS(obj_tptr+4));
1037                 obj_tlen-=8;
1038                 obj_tptr+=8;
1039                 if (obj_tlen)
1040                     hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
1041                 break;
1042 #ifdef INET6
1043             case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
1044             case RSVP_CTYPE_IPV6:
1045                 if (obj_tlen < 20)
1046                     return-1;
1047                 printf("%s  Previous/Next Interface: %s, Logical Interface Handle: 0x%08x",
1048                        ident,
1049                        ip6addr_string(obj_tptr),
1050                        EXTRACT_32BITS(obj_tptr+16));
1051                 obj_tlen-=20;
1052                 obj_tptr+=20;
1053                 hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
1054                 break;
1055 #endif
1056             default:
1057                 hexdump=TRUE;
1058             }
1059             break;
1060
1061         case RSVP_OBJ_TIME_VALUES:
1062             switch(rsvp_obj_ctype) {
1063             case RSVP_CTYPE_1:
1064                 if (obj_tlen < 4)
1065                     return-1;
1066                 printf("%s  Refresh Period: %ums",
1067                        ident,
1068                        EXTRACT_32BITS(obj_tptr));
1069                 obj_tlen-=4;
1070                 obj_tptr+=4;
1071                 break;
1072             default:
1073                 hexdump=TRUE;
1074             }
1075             break;
1076
1077         /* those three objects do share the same semantics */
1078         case RSVP_OBJ_SENDER_TSPEC:
1079         case RSVP_OBJ_ADSPEC:
1080         case RSVP_OBJ_FLOWSPEC:
1081             switch(rsvp_obj_ctype) {
1082             case RSVP_CTYPE_2:
1083                 if (obj_tlen < 4)
1084                     return-1;
1085                 printf("%s  Msg-Version: %u, length: %u",
1086                        ident,
1087                        (*obj_tptr & 0xf0) >> 4,
1088                        EXTRACT_16BITS(obj_tptr+2)<<2);
1089                 obj_tptr+=4; /* get to the start of the service header */
1090                 obj_tlen-=4;
1091
1092                 while (obj_tlen >= 4) {
1093                     intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2;
1094                     printf("%s  Service Type: %s (%u), break bit %s set, Service length: %u",
1095                            ident,
1096                            tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)),
1097                            *(obj_tptr),
1098                            (*(obj_tptr+1)&0x80) ? "" : "not",
1099                            intserv_serv_tlen);
1100                     
1101                     obj_tptr+=4; /* get to the start of the parameter list */
1102                     obj_tlen-=4;
1103
1104                     while (intserv_serv_tlen>=4) {
1105                         processed = rsvp_intserv_print(obj_tptr, obj_tlen);
1106                         if (processed == 0)
1107                             break;
1108                         obj_tlen-=processed;
1109                         intserv_serv_tlen-=processed;
1110                         obj_tptr+=processed;
1111                     }
1112                 }
1113                 break;
1114             default:
1115                 hexdump=TRUE;
1116             }
1117             break;
1118
1119         case RSVP_OBJ_FILTERSPEC:
1120             switch(rsvp_obj_ctype) {
1121             case RSVP_CTYPE_IPV4:
1122                 if (obj_tlen < 8)
1123                     return-1;
1124                 printf("%s  Source Address: %s, Source Port: %u",
1125                        ident,
1126                        ipaddr_string(obj_tptr),
1127                        EXTRACT_16BITS(obj_tptr+6));
1128                 obj_tlen-=8;
1129                 obj_tptr+=8;
1130                 break;
1131 #ifdef INET6
1132             case RSVP_CTYPE_IPV6:
1133                 if (obj_tlen < 20)
1134                     return-1;
1135                 printf("%s  Source Address: %s, Source Port: %u",
1136                        ident,
1137                        ip6addr_string(obj_tptr),
1138                        EXTRACT_16BITS(obj_tptr+18));
1139                 obj_tlen-=20;
1140                 obj_tptr+=20;
1141                 break;
1142             case RSVP_CTYPE_3:
1143                 if (obj_tlen < 20)
1144                     return-1;
1145                 printf("%s  Source Address: %s, Flow Label: %u",
1146                        ident,
1147                        ip6addr_string(obj_tptr),
1148                        EXTRACT_24BITS(obj_tptr+17));
1149                 obj_tlen-=20;
1150                 obj_tptr+=20;
1151                 break;
1152             case RSVP_CTYPE_TUNNEL_IPV6:
1153                 if (obj_tlen < 20)
1154                     return-1;
1155                 printf("%s  Source Address: %s, LSP-ID: 0x%04x",
1156                        ident,
1157                        ipaddr_string(obj_tptr),
1158                        EXTRACT_16BITS(obj_tptr+18));
1159                 obj_tlen-=20;
1160                 obj_tptr+=20;
1161                 break;
1162 #endif
1163             case RSVP_CTYPE_TUNNEL_IPV4:
1164                 if (obj_tlen < 8)
1165                     return-1;
1166                 printf("%s  Source Address: %s, LSP-ID: 0x%04x",
1167                        ident,
1168                        ipaddr_string(obj_tptr),
1169                        EXTRACT_16BITS(obj_tptr+6));
1170                 obj_tlen-=8;
1171                 obj_tptr+=8;
1172                 break;
1173             default:
1174                 hexdump=TRUE;
1175             }
1176             break;
1177
1178         case RSVP_OBJ_FASTREROUTE:
1179             /* the differences between c-type 1 and 7 are minor */
1180             obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
1181             bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
1182
1183             switch(rsvp_obj_ctype) {
1184             case RSVP_CTYPE_1: /* new style */
1185                 if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
1186                     return-1;
1187                 printf("%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
1188                        ident,
1189                        (int)obj_ptr.rsvp_obj_frr->setup_prio,
1190                        (int)obj_ptr.rsvp_obj_frr->hold_prio,
1191                        (int)obj_ptr.rsvp_obj_frr->hop_limit,
1192                         bw.f*8/1000000);              
1193                 printf("%s  Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x",
1194                        ident,
1195                        EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
1196                        EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any),
1197                        EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all));
1198                 obj_tlen-=sizeof(struct rsvp_obj_frr_t);
1199                 obj_tptr+=sizeof(struct rsvp_obj_frr_t);
1200                 break;
1201
1202             case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
1203                 if (obj_tlen < 16)
1204                     return-1;
1205                 printf("%s  Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
1206                        ident,
1207                        (int)obj_ptr.rsvp_obj_frr->setup_prio,
1208                        (int)obj_ptr.rsvp_obj_frr->hold_prio,
1209                        (int)obj_ptr.rsvp_obj_frr->hop_limit,
1210                         bw.f*8/1000000);              
1211                 printf("%s  Include Colors: 0x%08x, Exclude Colors: 0x%08x",
1212                        ident,
1213                        EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
1214                        EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any));
1215                 obj_tlen-=16;
1216                 obj_tptr+=16;
1217                 break;
1218
1219             default:
1220                 hexdump=TRUE;
1221             }
1222             break;
1223
1224         case RSVP_OBJ_DETOUR:
1225             switch(rsvp_obj_ctype) {
1226             case RSVP_CTYPE_TUNNEL_IPV4:
1227                 while(obj_tlen >= 8) {
1228                     printf("%s  PLR-ID: %s, Avoid-Node-ID: %s",
1229                            ident,
1230                            ipaddr_string(obj_tptr),
1231                            ipaddr_string(obj_tptr+4));              
1232                     obj_tlen-=8;
1233                     obj_tptr+=8;
1234                 }
1235                 break;
1236             default:
1237                 hexdump=TRUE;
1238             }
1239             break;
1240
1241         case RSVP_OBJ_CLASSTYPE:
1242         case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */
1243             switch(rsvp_obj_ctype) {
1244             case RSVP_CTYPE_1:
1245                 printf("%s  CT: %u",
1246                        ident,
1247                        EXTRACT_32BITS(obj_tptr)&0x7);              
1248                 obj_tlen-=4;
1249                 obj_tptr+=4;
1250                 break;
1251             default:
1252                 hexdump=TRUE;
1253             }
1254             break;
1255
1256         case RSVP_OBJ_ERROR_SPEC:
1257             switch(rsvp_obj_ctype) {
1258             case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
1259             case RSVP_CTYPE_IPV4:
1260                 if (obj_tlen < 8)
1261                     return-1;
1262                 error_code=*(obj_tptr+5);
1263                 error_value=EXTRACT_16BITS(obj_tptr+6);
1264                 printf("%s  Error Node Address: %s, Flags: [0x%02x]%s  Error Code: %s (%u)",
1265                        ident,
1266                        ipaddr_string(obj_tptr),
1267                        *(obj_tptr+4),
1268                        ident,
1269                        tok2str(rsvp_obj_error_code_values,"unknown",error_code),
1270                        error_code);
1271                 switch (error_code) {
1272                 case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING:
1273                     printf(", Error Value: %s (%u)",
1274                            tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
1275                            error_value);
1276                     break;
1277                 case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */
1278                 case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD:
1279                     printf(", Error Value: %s (%u)",
1280                            tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value),
1281                            error_value);
1282                     break;
1283                 default:
1284                     printf(", Unknown Error Value (%u)", error_value);
1285                     break;
1286                 }
1287                 obj_tlen-=8;
1288                 obj_tptr+=8;
1289                 break;
1290 #ifdef INET6
1291             case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
1292             case RSVP_CTYPE_IPV6:
1293                 if (obj_tlen < 20)
1294                     return-1;
1295                 error_code=*(obj_tptr+17);
1296                 error_value=EXTRACT_16BITS(obj_tptr+18);
1297                 printf("%s  Error Node Address: %s, Flags: [0x%02x]%s  Error Code: %s (%u)",
1298                        ident,
1299                        ip6addr_string(obj_tptr),
1300                        *(obj_tptr+16),
1301                        ident,
1302                        tok2str(rsvp_obj_error_code_values,"unknown",error_code),
1303                        error_code);
1304
1305                 switch (error_code) {
1306                 case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING:
1307                     printf(", Error Value: %s (%u)",
1308                            tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
1309                            error_value);
1310                     break;
1311                 default:
1312                     break;
1313                 }
1314                 obj_tlen-=20;
1315                 obj_tptr+=20;
1316                 break;
1317 #endif
1318             default:
1319                 hexdump=TRUE;
1320             }
1321             break;
1322
1323         case RSVP_OBJ_PROPERTIES:
1324             switch(rsvp_obj_ctype) {
1325             case RSVP_CTYPE_1:
1326                 if (obj_tlen < 4)
1327                     return-1;
1328                 padbytes = EXTRACT_16BITS(obj_tptr+2);
1329                 printf("%s  TLV count: %u, padding bytes: %u",
1330                        ident,
1331                        EXTRACT_16BITS(obj_tptr),
1332                        padbytes);
1333                 obj_tlen-=4;
1334                 obj_tptr+=4;
1335                 /* loop through as long there is anything longer than the TLV header (2) */
1336                 while(obj_tlen >= 2 + padbytes) {
1337                     printf("%s    %s TLV (0x%02x), length: %u", /* length includes header */
1338                            ident,
1339                            tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr),
1340                            *obj_tptr,
1341                            *(obj_tptr+1));
1342                     if (obj_tlen < *(obj_tptr+1))
1343                         return-1;
1344                     if (*(obj_tptr+1) < 2)
1345                         return -1;
1346                     print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2);
1347                     obj_tlen-=*(obj_tptr+1);
1348                     obj_tptr+=*(obj_tptr+1);
1349                 }
1350                 break;
1351             default:
1352                 hexdump=TRUE;
1353             }
1354             break;
1355
1356         case RSVP_OBJ_MESSAGE_ID:     /* fall through */
1357         case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */
1358         case RSVP_OBJ_MESSAGE_ID_LIST:
1359             switch(rsvp_obj_ctype) {
1360             case RSVP_CTYPE_1:
1361                 if (obj_tlen < 8)
1362                     return-1;
1363                 printf("%s  Flags [0x%02x], epoch: %u",
1364                        ident,
1365                        *obj_tptr,
1366                        EXTRACT_24BITS(obj_tptr+1));
1367                 obj_tlen-=4;
1368                 obj_tptr+=4;
1369                 /* loop through as long there are no messages left */
1370                 while(obj_tlen >= 4) {
1371                     printf("%s    Message-ID 0x%08x (%u)",
1372                            ident,
1373                            EXTRACT_32BITS(obj_tptr),
1374                            EXTRACT_32BITS(obj_tptr));
1375                     obj_tlen-=4;
1376                     obj_tptr+=4;
1377                 }
1378                 break;
1379             default:
1380                 hexdump=TRUE;
1381             }
1382             break;
1383
1384         case RSVP_OBJ_INTEGRITY:
1385             switch(rsvp_obj_ctype) {
1386             case RSVP_CTYPE_1:
1387                 if (obj_tlen < sizeof(struct rsvp_obj_integrity_t))
1388                     return-1;
1389                 obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr;
1390                 printf("%s  Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]",
1391                        ident,
1392                        EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id),
1393                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2),
1394                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence),
1395                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4),
1396                        bittok2str(rsvp_obj_integrity_flag_values,
1397                                   "none",
1398                                   obj_ptr.rsvp_obj_integrity->flags));
1399                 printf("%s  MD5-sum 0x%08x%08x%08x%08x (unverified)",
1400                        ident,
1401                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest),
1402                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4),
1403                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8),
1404                        EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12));
1405                 obj_tlen+=sizeof(struct rsvp_obj_integrity_t);
1406                 obj_tptr+=sizeof(struct rsvp_obj_integrity_t);
1407                 break;
1408             default:
1409                 hexdump=TRUE;
1410             }
1411             break;           
1412
1413         /*
1414          *  FIXME those are the defined objects that lack a decoder
1415          *  you are welcome to contribute code ;-)
1416          */
1417
1418         case RSVP_OBJ_SCOPE:
1419         case RSVP_OBJ_POLICY_DATA:
1420         case RSVP_OBJ_LABEL_SET:
1421         case RSVP_OBJ_ACCEPT_LABEL_SET:
1422         case RSVP_OBJ_PROTECTION:
1423         default:
1424             if (vflag <= 1)
1425                 print_unknown_data(obj_tptr,"\n\t    ",obj_tlen); /* FIXME indentation */
1426             break;
1427         }
1428         /* do we also want to see a hex dump ? */
1429         if (vflag > 1 || hexdump==TRUE)
1430             print_unknown_data(tptr+sizeof(sizeof(struct rsvp_object_header)),"\n\t    ", /* FIXME indentation */
1431                                rsvp_obj_len-sizeof(struct rsvp_object_header));
1432
1433         tptr+=rsvp_obj_len;
1434         tlen-=rsvp_obj_len;
1435     }
1436     return 0;
1437 trunc:
1438     printf("\n\t\t packet exceeded snapshot");
1439     return -1;
1440 }
1441
1442
1443 void
1444 rsvp_print(register const u_char *pptr, register u_int len) {
1445
1446     const struct rsvp_common_header *rsvp_com_header;
1447     const u_char *tptr,*subtptr;
1448     u_short tlen,subtlen;
1449
1450     tptr=pptr;
1451
1452     rsvp_com_header = (const struct rsvp_common_header *)pptr;
1453     TCHECK(*rsvp_com_header);
1454
1455     /*
1456      * Sanity checking of the header.
1457      */
1458     if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) {
1459         printf("ERROR: RSVP version %u packet not supported",
1460                RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags));
1461         return;
1462     }
1463
1464     /* in non-verbose mode just lets print the basic Message Type*/
1465     if (vflag < 1) {
1466         printf("RSVPv%u %s Message, length: %u",
1467                RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
1468                tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type),
1469                len);
1470         return;
1471     }
1472
1473     /* ok they seem to want to know everything - lets fully decode it */
1474
1475     tlen=EXTRACT_16BITS(rsvp_com_header->length);
1476
1477     printf("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x",
1478            RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
1479            tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type),
1480            rsvp_com_header->msg_type,
1481            bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)),
1482            tlen,
1483            rsvp_com_header->ttl,
1484            EXTRACT_16BITS(rsvp_com_header->checksum));
1485
1486     if (tlen < sizeof(const struct rsvp_common_header)) {
1487         printf("ERROR: common header too short %u < %lu", tlen,
1488                (unsigned long)sizeof(const struct rsvp_common_header));
1489         return;
1490     }
1491
1492     tptr+=sizeof(const struct rsvp_common_header);
1493     tlen-=sizeof(const struct rsvp_common_header);
1494
1495     switch(rsvp_com_header->msg_type) {
1496
1497     case RSVP_MSGTYPE_AGGREGATE:
1498         while(tlen > 0) {
1499             subtptr=tptr;
1500             rsvp_com_header = (const struct rsvp_common_header *)subtptr;
1501             TCHECK(*rsvp_com_header);
1502
1503             /*
1504              * Sanity checking of the header.
1505              */
1506             if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) {
1507                 printf("ERROR: RSVP version %u packet not supported",
1508                        RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags));
1509                 return;
1510             }
1511             subtlen=EXTRACT_16BITS(rsvp_com_header->length);
1512             
1513             printf("\n\t  RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x",
1514                    RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
1515                    tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type),
1516                    rsvp_com_header->msg_type,
1517                    bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)),
1518                    subtlen,
1519                    rsvp_com_header->ttl,
1520                    EXTRACT_16BITS(rsvp_com_header->checksum));
1521             
1522             if (subtlen < sizeof(const struct rsvp_common_header)) {
1523                 printf("ERROR: common header too short %u < %lu", subtlen,
1524                        (unsigned long)sizeof(const struct rsvp_common_header));
1525                 return;
1526             }
1527
1528             if (tlen < subtlen) {
1529                 printf("ERROR: common header too large %u > %u", subtlen,
1530                        tlen);
1531                 return;
1532             }
1533
1534             subtptr+=sizeof(const struct rsvp_common_header);
1535             subtlen-=sizeof(const struct rsvp_common_header);
1536
1537             if (rsvp_obj_print(subtptr,"\n\t    ", subtlen) == -1)
1538                 return;
1539
1540             tptr+=subtlen+sizeof(const struct rsvp_common_header);
1541             tlen-=subtlen+sizeof(const struct rsvp_common_header);
1542         }
1543
1544         break;
1545
1546     case RSVP_MSGTYPE_PATH:
1547     case RSVP_MSGTYPE_RESV:
1548     case RSVP_MSGTYPE_PATHERR:
1549     case RSVP_MSGTYPE_RESVERR:
1550     case RSVP_MSGTYPE_PATHTEAR:
1551     case RSVP_MSGTYPE_RESVTEAR:
1552     case RSVP_MSGTYPE_RESVCONF:
1553     case RSVP_MSGTYPE_HELLO_OLD:
1554     case RSVP_MSGTYPE_HELLO:
1555     case RSVP_MSGTYPE_ACK:
1556     case RSVP_MSGTYPE_SREFRESH:
1557         if (rsvp_obj_print(tptr,"\n\t  ", tlen) == -1)
1558             return;
1559         break;
1560
1561     default: 
1562         print_unknown_data(tptr,"\n\t    ",tlen);  
1563         break;
1564     }
1565
1566     return;
1567 trunc:
1568     printf("\n\t\t packet exceeded snapshot");
1569 }