New proto_tree header_field_info stuff. Header_field_infos now contain
[obnox/wireshark/wip.git] / packet-rsvp.c
1 /* packet-rsvp.c
2  * Routines for RSVP packet disassembly
3  *
4  * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
5  *
6  * $Id: packet-rsvp.c,v 1.9 1999/10/12 06:20:16 gram Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  * 
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 /*
29  * NOTES
30  *
31  * This module defines routines to disassemble RSVP packets, as defined in
32  * RFC 2205. All objects from RC2205 are supported, in IPv4 and IPv6 mode.
33  * In addition, the Integrated Services traffic specification objects
34  * defined in RFC2210 are also supported. 
35  *
36  * IPv6 support is not completely tested
37  */
38
39  
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <stdio.h>
45
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49
50 #include <stdlib.h>
51 #include <string.h>
52
53 #ifdef HAVE_SYS_TYPES_H
54 # include <sys/types.h>
55 #endif
56
57 #ifdef HAVE_NETINET_IN_H
58 # include <netinet/in.h>
59 #endif
60
61 #ifdef NEED_SNPRINTF_H
62 # ifdef HAVE_STDARG_H
63 #  include <stdarg.h>
64 # else
65 #  include <varargs.h>
66 # endif
67 # include "snprintf.h"
68 #endif
69
70 #include <glib.h>
71 #include "packet.h"
72 #include "packet-ip.h"
73 #include "packet-ipv6.h"
74 #include "packet-rsvp.h"
75
76 static int proto_rsvp = -1;
77
78 /* Stuff for IEEE float handling */
79
80 #define IEEE_NUMBER_WIDTH       32      /* bits in number */
81 #define IEEE_EXP_WIDTH          8       /* bits in exponent */
82 #define IEEE_MANTISSA_WIDTH     23      /* IEEE_NUMBER_WIDTH - 1 - IEEE_EXP_WIDTH */
83
84 #define IEEE_SIGN_MASK          0x80000000
85 #define IEEE_EXPONENT_MASK      0x7F800000
86 #define IEEE_MANTISSA_MASK      0x007FFFFF
87 #define IEEE_INFINITY           IEEE_EXPONENT_MASK
88
89 #define IEEE_IMPLIED_BIT (1 << IEEE_MANTISSA_WIDTH)
90 #define IEEE_INFINITE ((1 << IEEE_EXP_WIDTH) - 1)
91 #define IEEE_BIAS ((1 << (IEEE_EXP_WIDTH - 1)) - 1)
92
93 #define MINUS_INFINITY (signed)0x80000000L
94 #define PLUS_INFINITY  0x7FFFFFFF
95
96 static const value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"},
97                                            {IP_PROTO_IGMP, "IGMP"},
98                                            {IP_PROTO_TCP,  "TCP" },
99                                            {IP_PROTO_UDP,  "UDP" },
100                                            {IP_PROTO_OSPF, "OSPF"},
101                                            {0,             NULL  } };
102
103 /* Filter keys */
104 enum rsvp_filter_keys {
105
106     /* Message types */
107     RSVPF_MSG,          /* Message type */
108     /* Shorthand for message types */
109     RSVPF_PATH,
110     RSVPF_RESV,
111     RSVPF_PATHERR,
112     RSVPF_RESVERR,
113     RSVPF_PATHTEAR,
114     RSVPF_RESVTEAR,
115     RSVPF_RCONFIRM,
116
117     /* Does the message contain an object of this type? */
118     RSVPF_OBJECT,
119     /* Object present shorthands */
120     RSVPF_SESSION,
121     RSVPF_DUMMY_1,
122     RSVPF_HOP,
123     RSVPF_INTEGRITY,
124     RSVPF_TIME_VALUES,
125     RSVPF_ERROR,
126     RSVPF_SCOPE,
127     RSVPF_STYLE,
128     RSVPF_FLOWSPEC,
129     RSVPF_FILTER_SPEC,
130     RSVPF_SENDER,
131     RSVPF_TSPEC,
132     RSVPF_ADSPEC,
133     RSVPF_POLICY,
134     RSVPF_CONFIRM,
135     RSVPF_UNKNOWN_OBJ, 
136
137     /* Session object */
138     RSVPF_SESSION_IP,
139     RSVPF_SESSION_PROTO,
140     RSVPF_SESSION_PORT,
141
142     /* Sender template */
143     RSVPF_SENDER_IP,
144     RSVPF_SENDER_PORT,
145
146     /* Sentinel */
147     RSVPF_MAX
148 };
149
150 static int rsvp_filter[RSVPF_MAX];
151
152 static hf_register_info rsvpf_info[] = {
153
154     /* Message type number */
155     {&rsvp_filter[RSVPF_MSG], 
156      { "Message Type", "rsvp.msg", FT_UINT8, BASE_NONE, message_type_vals, 0x0,
157         "" }},
158
159     /* Message type shorthands */
160     {&rsvp_filter[RSVPF_PATH], 
161      { "Path Message", "rsvp.path", FT_UINT8, BASE_NONE, NULL, 0x0,
162         "" }},
163
164     {&rsvp_filter[RSVPF_RESV], 
165      { "Resv Message", "rsvp.resv", FT_UINT8, BASE_NONE, NULL, 0x0,
166         "" }},
167
168     {&rsvp_filter[RSVPF_PATHERR], 
169      { "Path Error Message", "rsvp.perr", FT_UINT8, BASE_NONE, NULL, 0x0,
170         "" }},
171
172     {&rsvp_filter[RSVPF_RESVERR], 
173      { "Resv Error Message", "rsvp.rerr", FT_UINT8, BASE_NONE, NULL, 0x0,
174         "" }},
175
176     {&rsvp_filter[RSVPF_PATHTEAR], 
177      { "Path Tear Message", "rsvp.ptear", FT_UINT8, BASE_NONE, NULL, 0x0,
178         "" }},
179
180     {&rsvp_filter[RSVPF_RESVTEAR], 
181      { "Resv Tear Message", "rsvp.rtear", FT_UINT8, BASE_NONE, NULL, 0x0,
182         "" }},
183
184     {&rsvp_filter[RSVPF_RCONFIRM], 
185      { "Resv Confirm Message", "rsvp.resvconf", FT_UINT8, BASE_NONE, NULL, 0x0,
186         "" }},
187
188     /* Object present */
189     {&rsvp_filter[RSVPF_OBJECT], 
190      { "", "rsvp.object", FT_UINT8, BASE_NONE, rsvp_class_vals, 0x0,
191         "" }},
192
193     /* Object present shorthands */
194     {&rsvp_filter[RSVPF_SESSION], 
195      { "SESSION", "rsvp.session", FT_UINT8, BASE_NONE, NULL, 0x0,
196         "" }},
197
198     {&rsvp_filter[RSVPF_HOP], 
199      { "HOP", "rsvp.hop", FT_UINT8, BASE_NONE, NULL, 0x0,
200         "" }},
201
202     {&rsvp_filter[RSVPF_INTEGRITY], 
203      { "INTEGRITY", "rsvp.integrity", FT_UINT8, BASE_NONE, NULL, 0x0,
204         "" }},
205
206     {&rsvp_filter[RSVPF_TIME_VALUES], 
207      { "TIME VALUES", "rsvp.time", FT_UINT8, BASE_NONE, NULL, 0x0,
208         "" }},
209
210     {&rsvp_filter[RSVPF_ERROR], 
211      { "ERROR", "rsvp.error", FT_UINT8, BASE_NONE, NULL, 0x0,
212         "" }},
213
214     {&rsvp_filter[RSVPF_SCOPE], 
215      { "SCOPE", "rsvp.scope", FT_UINT8, BASE_NONE, NULL, 0x0,
216         "" }},
217
218     {&rsvp_filter[RSVPF_STYLE], 
219      { "STYLE", "rsvp.style", FT_UINT8, BASE_NONE, NULL, 0x0,
220         "" }},
221
222     {&rsvp_filter[RSVPF_FLOWSPEC], 
223      { "FLOWSPEC", "rsvp.flowspec", FT_UINT8, BASE_NONE, NULL, 0x0,
224         "" }},
225
226     {&rsvp_filter[RSVPF_FILTER_SPEC], 
227      { "FILTERSPEC", "rsvp.filter", FT_UINT8, BASE_NONE, NULL, 0x0,
228         "" }},
229
230     {&rsvp_filter[RSVPF_SENDER], 
231      { "SENDER TEMPLATE", "rsvp.sender", FT_UINT8, BASE_NONE, NULL, 0x0,
232         "" }},
233
234     {&rsvp_filter[RSVPF_TSPEC], 
235      { "SENDER TSPEC", "rsvp.tspec", FT_UINT8, BASE_NONE, NULL, 0x0,
236         "" }},
237
238     {&rsvp_filter[RSVPF_ADSPEC], 
239      { "ADSPEC", "rsvp.adspec", FT_UINT8, BASE_NONE, NULL, 0x0,
240         "" }},
241
242     {&rsvp_filter[RSVPF_POLICY], 
243      { "POLICY", "rsvp.policy", FT_UINT8, BASE_NONE, NULL, 0x0,
244         "" }},
245
246     {&rsvp_filter[RSVPF_CONFIRM], 
247      { "CONFIRM", "rsvp.confirm", FT_UINT8, BASE_NONE, NULL, 0x0,
248         "" }},
249
250     {&rsvp_filter[RSVPF_UNKNOWN_OBJ], 
251      { "Unknown object", "rsvp.obj_unknown", FT_UINT8, BASE_NONE, NULL, 0x0,
252         "" }},
253
254     /* Session fields */
255     {&rsvp_filter[RSVPF_SESSION_IP], 
256      { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
257         "" }},
258
259     {&rsvp_filter[RSVPF_SESSION_PORT], 
260      { "Port number", "rsvp.session.port", FT_UINT16, BASE_NONE, NULL, 0x0,
261         "" }},
262
263     {&rsvp_filter[RSVPF_SESSION_PROTO], 
264      { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_NONE, VALS(proto_vals), 0x0,
265         "" }},
266
267     /* Sender template fields */
268     {&rsvp_filter[RSVPF_SENDER_IP], 
269      { "Sender Template IPv4 address", "rsvp.template.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
270         "" }},
271
272     {&rsvp_filter[RSVPF_SENDER_PORT], 
273      { "Sender Template port number", "rsvp.template.port", FT_UINT16, BASE_NONE, NULL, 0x0,
274         "" }}
275 };
276
277 static inline int rsvp_class_to_filter_num(int classnum)
278 {
279     switch(classnum) {
280     case RSVP_CLASS_SESSION :
281     case RSVP_CLASS_HOP :
282     case RSVP_CLASS_INTEGRITY :
283     case RSVP_CLASS_TIME_VALUES :
284     case RSVP_CLASS_ERROR :
285     case RSVP_CLASS_SCOPE :
286     case RSVP_CLASS_STYLE :
287     case RSVP_CLASS_FLOWSPEC :
288     case RSVP_CLASS_FILTER_SPEC :
289     case RSVP_CLASS_SENDER_TEMPLATE :
290     case RSVP_CLASS_SENDER_TSPEC :
291     case RSVP_CLASS_ADSPEC :
292     case RSVP_CLASS_POLICY :
293     case RSVP_CLASS_CONFIRM :
294         return classnum + RSVPF_OBJECT;
295         
296     default:
297         return RSVPF_UNKNOWN_OBJ;
298     }
299 }
300
301 static inline int ieee_float_is_zero (long number)
302 {
303     return(!(number & ~IEEE_SIGN_MASK));
304 }
305
306 /*
307  * simple conversion: ieee floating point to long
308  */
309 static long ieee_to_long (const void *p)
310 {
311     long number;
312     long sign;
313     long exponent;
314     long mantissa;
315
316     number = pntohl(p);
317     sign = number & IEEE_SIGN_MASK;
318     exponent = number & IEEE_EXPONENT_MASK;
319     mantissa = number & IEEE_MANTISSA_MASK;
320
321     if (ieee_float_is_zero(number)) {
322         /* number is zero, unnormalized, or not-a-number */
323         return 0;
324     }
325     if (IEEE_INFINITY == exponent) {
326         /* number is positive or negative infinity, or a special value */
327         return (sign? MINUS_INFINITY: PLUS_INFINITY);
328     }
329
330     exponent = (exponent >> IEEE_MANTISSA_WIDTH) - IEEE_BIAS;
331     if (exponent < 0) {
332         /* number is between zero and one */
333         return 0;
334     }
335
336     mantissa |= IEEE_IMPLIED_BIT;
337     if (exponent <= IEEE_MANTISSA_WIDTH)
338         mantissa >>= IEEE_MANTISSA_WIDTH - exponent;
339     else
340         mantissa <<= exponent - IEEE_MANTISSA_WIDTH;
341
342     if (sign)
343         return -mantissa;
344     else
345         return mantissa;
346 }
347
348 void 
349 dissect_rsvp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) 
350 {
351     proto_tree *rsvp_tree = NULL, *ti; 
352     proto_tree *rsvp_header_tree;
353     proto_tree *rsvp_object_tree;
354     char *packet_type, *object_type;
355     rsvp_header *hdr;
356     rsvp_object *obj;
357     int i, len, mylen;
358     int msg_length;
359     int obj_length;
360     int offset2;
361
362     hdr = (rsvp_header *)&pd[offset];
363     packet_type = match_strval(hdr->message_type, message_type_vals);
364     if (check_col(fd, COL_PROTOCOL))
365         col_add_str(fd, COL_PROTOCOL, "RSVP");
366     if (check_col(fd, COL_INFO)) {
367         if (packet_type != NULL)
368             col_add_str(fd, COL_INFO, packet_type); 
369         else
370             col_add_fstr(fd, COL_INFO, "Unknown (%d)", hdr->message_type); 
371     }
372
373     if (tree) {
374         msg_length = pntohs(pd+offset+6);
375         ti = proto_tree_add_item(tree, proto_rsvp, offset, msg_length, NULL);
376         rsvp_tree = proto_item_add_subtree(ti, ETT_RSVP);
377
378         ti = proto_tree_add_text(rsvp_tree, offset, 
379                               sizeof(rsvp_header), "RSVP Header"); 
380         rsvp_header_tree = proto_item_add_subtree(ti, ETT_RSVP_HDR);
381
382         proto_tree_add_text(rsvp_header_tree, offset, 1, "RSVP Version: %d", 
383                          (hdr->ver_flags & 0xf0)>>4);  
384         proto_tree_add_text(rsvp_header_tree, offset, 1, "Flags: %02X",
385                          hdr->ver_flags & 0xf);  
386         proto_tree_add_item(rsvp_header_tree, rsvp_filter[RSVPF_MSG], 
387                             offset+1, 1, hdr->message_type);
388         proto_tree_add_item_hidden(rsvp_header_tree, rsvp_filter[RSVPF_MSG + hdr->message_type], 
389                             offset+1, 1, 1);
390 /*
391         proto_tree_add_text(rsvp_header_tree, offset+1, 1, "Message Type: %d - %s",
392                          hdr->message_type, 
393                          packet_type?packet_type:"Unknown");
394 */
395         proto_tree_add_text(rsvp_header_tree, offset + 2 , 2, "Message Checksum");
396         proto_tree_add_text(rsvp_header_tree, offset + 4 , 1, "Sending TTL: %d",
397                          hdr->sending_ttl);
398         proto_tree_add_text(rsvp_header_tree, offset + 6 , 2, "Message length: %d",
399                          msg_length);
400
401         offset += sizeof(rsvp_header);
402         len = 0;
403         while (len + sizeof(rsvp_header) < msg_length) {
404             obj = (rsvp_object *)&pd[offset];
405             obj_length = pntohs(pd+offset);
406             if (offset + obj_length > fd->cap_len) {
407                 proto_tree_add_text(rsvp_tree, offset, 1, 
408                                  "Further data not captured");
409                 break;
410             }
411             
412             object_type = match_strval(obj->class, rsvp_class_vals);
413             if (!object_type) object_type = "Unknown";
414             /*
415             ti = proto_tree_add_text(rsvp_tree, offset, 
416                                   obj_length, 
417                                   "%s (%d)", object_type, obj->class);
418             */
419             ti = proto_tree_add_item_hidden(rsvp_tree, rsvp_filter[RSVPF_OBJECT], 
420                                      offset, obj_length, obj->class);
421             ti = proto_tree_add_item(rsvp_tree, rsvp_filter[rsvp_class_to_filter_num(obj->class)], 
422                                      offset, obj_length, obj->class);
423
424             offset2 = offset + sizeof(rsvp_object);
425
426             switch(obj->class) {
427
428             case RSVP_CLASS_SESSION :           
429                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_SESSION);
430                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
431                                     obj_length);
432                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
433                                     "Class number: %d - %s", 
434                                     obj->class, object_type);
435                 switch(obj->type) {
436                 case 1: {
437                     /*rsvp_session_ipv4 *sess = (rsvp_session_ipv4 *)obj;*/
438                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
439                                         "C-type: 1 - IPv4");
440                     /*
441                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
442                                         "Destination address: %s", 
443                                         ip_to_str((guint8 *) &(sess->destination)));
444                     */
445                     proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_IP], 
446                                         offset2, 4, pntohl(pd+offset2));
447
448                     /* proto_tree_add_text(rsvp_object_tree, offset2+4, 1,
449                        "Protocol: %d", sess->protocol);*/
450                     proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_PROTO], 
451                                         offset2+4, 1, pntohs(pd+offset2+4));
452                     proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
453                                         "Flags: %d", pntohs(pd+offset2+5));
454                     /* proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
455                                         "Destination port: %d", 
456                                         pntohs(pd+offset2+6)); */
457                     proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_PORT], 
458                                         offset2+6, 2, pntohs(pd+offset2+6));
459                     break;
460                 }
461
462                 case 2: {
463                     rsvp_session_ipv6 *sess = (rsvp_session_ipv6 *)obj;
464                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
465                                         "C-type: 2 - IPv6");
466                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
467                                         "Destination address: %s", 
468                                         ip6_to_str(&(sess->destination)));
469                     proto_tree_add_text(rsvp_object_tree, offset2+16, 1,
470                                         "Protocol: %d", sess->protocol);
471                     proto_tree_add_text(rsvp_object_tree, offset2+17, 1,
472                                         "Flags: %d", sess->flags);
473                     proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
474                                         "Destination port: %d", 
475                                         pntohs(pd+offset2+18));
476                     break;
477                 }
478                 
479                 default: {
480                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
481                                         "C-type: Unknown (%d)",
482                                         obj->type);
483                     i = obj_length - sizeof(rsvp_object);
484                     proto_tree_add_text(rsvp_object_tree, offset2, i,
485                                         "Data (%d bytes)", i);
486                 }
487                 }
488                 break;
489                 
490             case RSVP_CLASS_HOP :               
491                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_HOP);
492                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
493                                     obj_length);
494                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
495                                     "Class number: %d - %s", 
496                                     obj->class, object_type);
497                 switch(obj->type) {
498                 case 1: {
499                     rsvp_hop_ipv4 *hop = (rsvp_hop_ipv4 *)obj;
500                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
501                                         "C-type: 1 - IPv4");
502                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
503                                         "Neighbor address: %s", 
504                                         ip_to_str((guint8 *) &(hop->neighbor)));
505                     proto_tree_add_text(rsvp_object_tree, offset2+4, 4,
506                                         "Logical interface: %0x", 
507                                         pntohl(pd+offset2+4));
508                     break;
509                 }
510
511                 case 2: {
512                     rsvp_hop_ipv6 *hop = (rsvp_hop_ipv6 *)obj;
513                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
514                                         "C-type: 2 - IPv6");
515                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
516                                         "Neighbor address: %s", 
517                                         ip6_to_str(&(hop->neighbor)));
518                     proto_tree_add_text(rsvp_object_tree, offset2+16, 4,
519                                         "Logical interface: %0x", 
520                                         pntohl(pd+offset2+16));
521                     break;
522                 }
523                 
524                 default: {
525                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
526                                         "C-type: Unknown (%d)",
527                                         obj->type);
528                     i = obj_length - sizeof(rsvp_object);
529                     proto_tree_add_text(rsvp_object_tree, offset2, i,
530                                         "Data (%d bytes)", i);
531                 }
532                 }
533                 break;
534                 
535             case RSVP_CLASS_TIME_VALUES : 
536                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_TIME_VALUES);
537                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
538                                     obj_length);
539                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
540                                     "Class number: %d - %s", 
541                                     obj->class, object_type);
542                 switch(obj->type) {
543                 case 1: {
544                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
545                                         "C-type: 1");
546                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
547                                         "Refresh interval: %u ms (%u seconds)",
548                                         pntohl(pd+offset2),
549                                         pntohl(pd+offset2)/1000);
550                     break;
551                 }
552
553                 default: {
554                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
555                                         "C-type: Unknown (%d)",
556                                         obj->type);
557                     i = obj_length - sizeof(rsvp_object);
558                     proto_tree_add_text(rsvp_object_tree, offset2, i,
559                                         "Data (%d bytes)", i);
560                     break;
561                 }
562                 }
563                 break;
564
565             case RSVP_CLASS_ERROR :
566                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_ERROR);
567                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
568                                     obj_length);
569                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
570                                     "Class number: %d - %s", 
571                                     obj->class, object_type);
572                 switch(obj->type) {
573                 case 1: {
574                     rsvp_error_ipv4 *err = (rsvp_error_ipv4 *)obj;
575                     char *err_str = match_strval(err->error_code, rsvp_error_vals);
576                     if (!err_str) err_str = "Unknown";
577
578                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
579                                         "C-type: 1 - IPv4");
580                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
581                                         "Error node: %s",
582                                         ip_to_str((guint8 *) &(err->error_node)));
583                     proto_tree_add_text(rsvp_object_tree, offset2+4, 1,
584                                         "Flags: %02x", err->flags);
585                     proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
586                                         "Error code: %d - %s", err->error_code,
587                                         err_str);
588                     proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
589                                         "Error value: %d", pntohs(pd+offset2+6));
590                     
591                     break;
592                 }
593
594                 case 2: {
595                     rsvp_error_ipv6 *err = (rsvp_error_ipv6 *)obj;
596                     char *err_str = match_strval(err->error_code, rsvp_error_vals);
597                     if (!err_str) err_str = "Unknown";
598                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
599                                         "C-type: 2 - IPv6");
600                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
601                                         "Error node: %s",
602                                         ip6_to_str(&(err->error_node)));
603                     proto_tree_add_text(rsvp_object_tree, offset2+16, 1,
604                                         "Flags: %02x", err->flags);
605                     proto_tree_add_text(rsvp_object_tree, offset2+17, 1,
606                                         "Error code: %d - %s", err->error_code,
607                                         err_str);
608                     proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
609                                         "Error value: %d", pntohs(pd+offset2+18));
610                     
611                     break;
612                 }
613                 
614                 default: {
615                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
616                                         "C-type: Unknown (%d)",
617                                         obj->type);
618                     i = obj_length - sizeof(rsvp_object);
619                     proto_tree_add_text(rsvp_object_tree, offset2, i,
620                                         "Data (%d bytes)", i);
621                 }
622                 }
623                 break;
624                 
625
626             case RSVP_CLASS_SCOPE : 
627                 mylen = obj_length;
628                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_SCOPE);
629                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
630                                     obj_length);
631                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
632                                     "Class number: %d - %s", 
633                                     obj->class, object_type);
634                 switch(obj->type) {
635                 case 1: {
636                     unsigned long ip;
637                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
638                                         "C-type: 1 - IPv4");
639                     while (mylen > sizeof(rsvp_object)) {
640                         ip = pntohl(pd+offset2);
641                         proto_tree_add_text(rsvp_object_tree, offset2, 4, 
642                                             "IPv4 Address: %s",
643                                             ip_to_str((guint8 *) &ip));
644                         offset2 += 4;
645                         mylen -= 4;
646                     }
647                     break;
648                 }
649
650                 case 2: {
651                     struct e_in6_addr *ip;
652                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
653                                         "C-type: 2 - IPv6");
654                     while (mylen>sizeof(rsvp_object)) {
655                         ip = (struct e_in6_addr *)pd+offset2;
656                         proto_tree_add_text(rsvp_object_tree, offset2, 16, 
657                                             "IPv6 Address: %s",
658                                             ip6_to_str(ip));
659                         offset2 += 16;
660                         mylen -= 16;
661                     }
662                     break;
663                 }
664                 
665                 default: {
666                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
667                                         "C-type: Unknown (%d)",
668                                         obj->type);
669                     i = obj_length - sizeof(rsvp_object);
670                     proto_tree_add_text(rsvp_object_tree, offset2, i,
671                                         "Data (%d bytes)", i);
672                 }
673                 }
674                 break;
675                 
676             case RSVP_CLASS_STYLE : 
677                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_STYLE);
678                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
679                                     obj_length);
680                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
681                                     "Class number: %d - %s", 
682                                     obj->class, object_type);
683                 switch(obj->type) {
684                 case 1: {
685                     unsigned long ip = pntohl(pd+offset2);
686                     char *style_str = match_strval(ip, style_vals);
687                     if (!style_str) style_str = "Unknown";
688                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
689                                         "C-type: 1");
690                     proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
691                                         "Style: %ld - %s", ip, style_str);
692                     break;
693                 }
694
695                 default: {
696                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
697                                         "C-type: Unknown (%d)",
698                                         obj->type);
699                     i = obj_length - sizeof(rsvp_object);
700                     proto_tree_add_text(rsvp_object_tree, offset2, i,
701                                         "Data (%d bytes)", i);
702                     break;
703                 }
704                 }
705                 break;
706             
707             case RSVP_CLASS_CONFIRM :           
708                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_CONFIRM);
709                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
710                                     obj_length);
711                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
712                                     "Class number: %d - %s", 
713                                     obj->class, object_type);
714                 switch(obj->type) {
715                 case 1: {
716                     rsvp_confirm_ipv4 *confirm = (rsvp_confirm_ipv4 *)obj;
717                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
718                                         "C-type: 1 - IPv4");
719                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
720                                         "Receiver address: %s", 
721                                         ip_to_str((guint8 *) &(confirm->receiver)));
722                     break;
723                 }
724
725                 case 2: {
726                     rsvp_confirm_ipv6 *confirm = (rsvp_confirm_ipv6 *)obj;
727                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
728                                         "C-type: 2 - IPv6");
729                     proto_tree_add_text(rsvp_object_tree, offset2, 16, 
730                                         "Receiver address: %s", 
731                                         ip6_to_str(&(confirm->receiver)));
732                     break;
733                 }
734
735                 default: {
736                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
737                                         "C-type: Unknown (%d)",
738                                         obj->type);
739                     i = obj_length - sizeof(rsvp_object);
740                     proto_tree_add_text(rsvp_object_tree, offset2, i,
741                                         "Data (%d bytes)", i);
742                 }
743                 }
744                 break;
745
746             case RSVP_CLASS_SENDER_TEMPLATE :
747                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_SENDER_TEMPLATE);
748                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
749                                     obj_length);
750                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
751                                     "Class number: %d - %s", 
752                                     obj->class, object_type);
753                 goto common_template;
754             case RSVP_CLASS_FILTER_SPEC :
755                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_FILTER_SPEC);
756                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
757                                     obj_length);
758                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
759                                     "Class number: %d - %s", 
760                                     obj->class, object_type);
761             common_template:
762                 switch(obj->type) {
763                 case 1: {
764                     rsvp_template_ipv4 *tem = (rsvp_template_ipv4 *)obj;
765                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
766                                         "C-type: 1 - IPv4");
767                     proto_tree_add_text(rsvp_object_tree, offset2, 4, 
768                                         "Source address: %s", 
769                                         ip_to_str((guint8 *) &(tem->source)));
770                     proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
771                                         "Source port: %d", pntohs(pd+offset2+6));
772                     break;
773                 }
774
775                 case 2: {
776                     rsvp_template_ipv6 *tem = (rsvp_template_ipv6 *)obj;
777                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
778                                         "C-type: 2 - IPv6");
779                     proto_tree_add_text(rsvp_object_tree, offset2, 16, 
780                                         "Source address: %s", 
781                                         ip6_to_str(&(tem->source)));
782                     proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
783                                         "Source port: %d", pntohs(pd+offset2+18));
784                     break;
785                 }
786                 
787                 default: {
788                     proto_tree_add_text(rsvp_object_tree, offset+3, 1, 
789                                         "C-type: Unknown (%d)",
790                                         obj->type);
791                     i = obj_length - sizeof(rsvp_object);
792                     proto_tree_add_text(rsvp_object_tree, offset2, i,
793                                         "Data (%d bytes)", i);
794                 }
795                 }
796                 break;
797
798             case RSVP_CLASS_SENDER_TSPEC : {
799                 rsvp_tspec *tspec = (rsvp_tspec *)obj;
800                 IS_tspec *ist;
801                 QUAL_tspec *qt;
802                 service_hdr  *sh;
803                 char *str;
804
805                 mylen = obj_length;
806                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_SENDER_TSPEC);
807                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
808                                     obj_length);
809                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
810                                     "Class number: %d - %s", 
811                                     obj->class, object_type);
812
813                 proto_tree_add_text(rsvp_object_tree, offset2, 1, 
814                                  "Message format version: %d", 
815                                  tspec->version>>4);
816                 proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
817                                  "Data length: %d words, not including header", 
818                                  pntohs(pd+offset2+2));
819
820                 mylen -=4;
821                 offset2 +=4;
822                 while (mylen > 4) {
823                     sh = (service_hdr *)(pd+offset2);
824                     str = match_strval(sh->service_num, qos_vals);
825                     if (!str) str = "Unknown";
826
827                     proto_tree_add_text(rsvp_object_tree, offset2, 1, 
828                                         "Service header: %d - %s", 
829                                         sh->service_num, str);
830                     proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
831                                  "Length of service %d data: %d words, " 
832                                  "not including header", 
833                                  sh->service_num,
834                                  ntohs(sh->length));
835
836                     offset2+=4; mylen -=4; 
837
838                     switch(sh->service_num) {
839                         
840                     case QOS_TSPEC :
841                         ist = (IS_tspec *)sh;
842
843                         /* Token bucket TSPEC */
844                         str = match_strval(ist->param_id, svc_vals);
845                         if (!str) str = "Unknown";
846                         proto_tree_add_text(rsvp_object_tree, offset2, 1, 
847                                             "Parameter %d - %s", 
848                                             ist->param_id, str);
849                         proto_tree_add_text(rsvp_object_tree, offset2+1, 1, 
850                                             "Parameter %d flags: %d", 
851                                             ist->param_id, ist->flags_tspec);
852                         proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
853                                             "Parameter %d data length: %d words, " 
854                                             "not including header",
855                                             ist->param_id,
856                                             /* pntohs(pd+offset2+10)); */
857                                             ntohs(ist->parameter_length));
858                         proto_tree_add_text(rsvp_object_tree, offset2+4, 4, 
859                                             "Token bucket rate: %ld", 
860                                             ieee_to_long(pd+offset2+4));
861                         proto_tree_add_text(rsvp_object_tree, offset2+8, 4, 
862                                             "Token bucket size: %ld", 
863                                             ieee_to_long(pd+offset2+8));
864                         proto_tree_add_text(rsvp_object_tree, offset2+12, 4, 
865                                             "Peak data rate: %ld", 
866                                             ieee_to_long(pd+offset2+12));
867                         proto_tree_add_text(rsvp_object_tree, offset2+16, 4, 
868                                             "Minimum policed unit: %d", 
869                                             pntohl(pd+offset2+16));
870                         proto_tree_add_text(rsvp_object_tree, offset2+20, 4, 
871                                             "Maximum policed unit: %d", 
872                                             pntohl(pd+offset2+20));
873
874                         break;
875
876                     case QOS_QUALITATIVE :
877                         qt = (QUAL_tspec *)sh;
878
879                         /* Token bucket TSPEC */
880                         str = match_strval(qt->param_id, svc_vals);
881                         if (!str) str = "Unknown";
882                         proto_tree_add_text(rsvp_object_tree, offset2, 1, 
883                                             "Parameter %d - %s", 
884                                             qt->param_id, str);
885                         proto_tree_add_text(rsvp_object_tree, offset2+1, 1, 
886                                             "Parameter %d flags: %d", 
887                                             qt->param_id, qt->flags_tspec);
888                         proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
889                                             "Parameter %d data length: %d words, " 
890                                             "not including header",
891                                             qt->param_id,
892                                             /* pntohs(pd+offset2+10)); */
893                                             ntohs(qt->parameter_length));
894                         proto_tree_add_text(rsvp_object_tree, offset2+4, 4, 
895                                             "Maximum policed unit: %d", 
896                                             pntohl(pd+offset2+4));
897
898                         break;
899
900                     }
901                     offset2 += ntohs(sh->length)*4; 
902                     mylen -= ntohs(sh->length)*4;
903                 }
904                     
905                 break;
906             }
907
908             case RSVP_CLASS_FLOWSPEC : {
909                 rsvp_flowspec *flowspec = (rsvp_flowspec *)obj;
910                 IS_flowspec *isf;
911                 QUAL_flowspec *qf;
912                 service_hdr *sh;
913                 int mylen;
914
915                 char *str;
916
917                 mylen = obj_length;
918                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_FLOWSPEC);
919                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
920                                     obj_length);
921                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
922                                     "Class number: %d - %s", 
923                                     obj->class, object_type);
924
925                 proto_tree_add_text(rsvp_object_tree, offset2, 1, 
926                                  "Message format version: %d", 
927                                  flowspec->version>>4);
928                 proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
929                                  "Data length: %d words, not including header", 
930                                  pntohs(pd+offset2+2));
931
932                 mylen -=4;
933                 offset2+=4;
934                 while (mylen > 4) {
935                     sh = (service_hdr *)(pd+offset2);
936                     str = match_strval(sh->service_num, intsrv_services_str);
937                     if (!str) str = "Unknown";
938
939                     proto_tree_add_text(rsvp_object_tree, offset2, 1, 
940                                         "Service header: %d - %s", 
941                                         sh->service_num, str);
942                     proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
943                                  "Length of service %d data: %d words, " 
944                                  "not including header", 
945                                  sh->service_num,
946                                  ntohs(sh->length));
947
948                     offset2+=4; mylen -=4; 
949
950                     switch(sh->service_num) {
951
952                     case QOS_CONTROLLED_LOAD :
953                     case QOS_GUARANTEED :
954                         /* Treat both these the same for now */
955                         isf = (IS_flowspec *)sh;
956
957                         str = match_strval(isf->tspec.param_id, svc_vals);
958                         if (!str) str = "Unknown";
959                         proto_tree_add_text(rsvp_object_tree, offset2, 1, 
960                                             "Parameter %d - %s", 
961                                             isf->tspec.param_id, str);
962                         proto_tree_add_text(rsvp_object_tree, offset2+1, 1, 
963                                             "Parameter %d flags: %d", 
964                                             isf->tspec.param_id, isf->tspec.flags_tspec);
965                         proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
966                                             "Parameter %d data length: %d words, " 
967                                             "not including header",
968                                             isf->tspec.param_id,
969                                             ntohs(isf->tspec.parameter_length));
970                         proto_tree_add_text(rsvp_object_tree, offset2+4, 4, 
971                                             "Token bucket rate: %ld", 
972                                             ieee_to_long(pd+offset2+4));
973                         proto_tree_add_text(rsvp_object_tree, offset2+8, 4, 
974                                             "Token bucket size: %ld", 
975                                             ieee_to_long(pd+offset2+8));
976                         proto_tree_add_text(rsvp_object_tree, offset2+12, 4, 
977                                             "Peak data rate: %ld", 
978                                             ieee_to_long(pd+offset2+12));
979                         proto_tree_add_text(rsvp_object_tree, offset2+16, 4, 
980                                             "Minimum policed unit: %d", 
981                                             pntohl(pd+offset2+16));
982                         proto_tree_add_text(rsvp_object_tree, offset2+20, 4, 
983                                             "Maximum policed unit: %d", 
984                                             pntohl(pd+offset2+20));
985                         if (sh->service_num!=QOS_GUARANTEED)
986                             break;
987                         
988                         /* Guaranteed-rate RSpec */
989                         str = match_strval(isf->rspec.param_id, svc_vals);
990                         if (!str) str="Unknown";
991                         proto_tree_add_text(rsvp_object_tree, offset2+24, 1, 
992                                             "Parameter %d - %s", 
993                                             isf->rspec.param_id, str);
994                         proto_tree_add_text(rsvp_object_tree, offset2+25, 1, 
995                                             "Parameter %d flags: %d", 
996                                             isf->rspec.param_id, isf->rspec.flags_rspec);
997                         proto_tree_add_text(rsvp_object_tree, offset2+26, 2, 
998                                             "Parameter %d data length: %d words, " 
999                                             "not including header",
1000                                             isf->rspec.param_id,
1001                                             ntohs(isf->rspec.param2_length));
1002
1003                         proto_tree_add_text(rsvp_object_tree, offset2+28, 4, 
1004                                             "Rate: %ld", 
1005                                             ieee_to_long(pd+offset2+28));
1006                         proto_tree_add_text(rsvp_object_tree, offset2+32, 4, 
1007                                             "Slack term: %d", 
1008                                             pntohl(pd+offset2+32));
1009                         break;
1010
1011                     case QOS_QUALITATIVE :
1012                         qf = (QUAL_flowspec *)sh;
1013
1014                         str = match_strval(qf->param_id, svc_vals);
1015                         if (!str) str = "Unknown";
1016                         proto_tree_add_text(rsvp_object_tree, offset2, 1, 
1017                                             "Parameter %d - %s", 
1018                                             qf->param_id, str);
1019                         proto_tree_add_text(rsvp_object_tree, offset2+1, 1, 
1020                                             "Parameter %d flags: %d", 
1021                                             qf->param_id, qf->flags_tspec);
1022                         proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
1023                                             "Parameter %d data length: %d words, " 
1024                                             "not including header",
1025                                             qf->param_id,
1026                                             ntohs(qf->parameter_length));
1027                         proto_tree_add_text(rsvp_object_tree, offset2+4, 4, 
1028                                             "Maximum policed unit: %ld", 
1029                                             pntohl(pd+offset2+4));
1030                         
1031                         break;
1032                     }
1033                     offset2 += ntohs(sh->length)*4;
1034                     mylen -= ntohs(sh->length)*4;
1035                 }
1036
1037                 break;
1038             }
1039
1040             case RSVP_CLASS_ADSPEC : {
1041                 proto_tree *adspec_tree;
1042                 service_hdr *shdr;
1043                 param_hdr *phdr; 
1044
1045                 char *str;
1046                 int tree_num;
1047
1048                 mylen = obj_length;
1049                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_ADSPEC);
1050                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
1051                                     obj_length);
1052                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
1053                                     "Class number: %d - %s", 
1054                                     obj->class, object_type);
1055                 
1056                 proto_tree_add_text(rsvp_object_tree, offset2, 1, 
1057                                     "Message format version: %d", 
1058                                     (*((unsigned char *)pd+offset2))>>4);
1059                 proto_tree_add_text(rsvp_object_tree, offset2+2, 2, 
1060                                     "Data length: %d words, not including header", 
1061                                     pntohs(pd+offset2+2));
1062                 offset2+=4;
1063                 tree_num=ETT_RSVP_ADSPEC_SUBTREE1;
1064                 mylen -= 4;
1065                 while (mylen > 4) {
1066                     shdr = (service_hdr *)(pd + offset2);
1067                     str = match_strval(shdr->service_num, intsrv_services_str);
1068
1069                     ti = proto_tree_add_text(rsvp_object_tree, offset2, 
1070                                              (pntohs(&shdr->length)+1)<<2,
1071                                              str?str:"Unknown");
1072                     adspec_tree = proto_item_add_subtree(ti, tree_num++);
1073                     proto_tree_add_text(adspec_tree, offset2, 1,
1074                                         "Service header %d - %s",
1075                                         shdr->service_num, str);
1076                     proto_tree_add_text(adspec_tree, offset2+1, 1,
1077                                         (shdr->break_bit&0x80)?
1078                                         "Break bit set":"Break bit not set");
1079                     proto_tree_add_text(adspec_tree, offset2+2, 2, 
1080                                         "Data length: %d words, not including header", 
1081                                         pntohs(&shdr->length));
1082                     offset2+=4; i=(pntohs(&shdr->length)+1)<<2; mylen-=4;
1083                     while (i>4) {
1084                         phdr = (param_hdr *)(pd + offset2);
1085                         str = match_strval(phdr->id, adspec_params);
1086                         if (str) {
1087                             switch(phdr->id) {
1088                             case 4:
1089                             case 8:
1090                             case 10:
1091                             case 133:
1092                             case 134:
1093                             case 135:
1094                             case 136:
1095                                 /* 32-bit unsigned integer */
1096                                 proto_tree_add_text(adspec_tree, offset2, 
1097                                                     (pntohs(&phdr->length)+1)<<2,
1098                                                     "%s - %lu (type %d, length %d)",
1099                                                     str, 
1100                                                     (unsigned long)pntohl(&phdr->dataval), 
1101                                                     phdr->id, pntohs(&phdr->length));
1102                                 break;
1103                                 
1104                             case 6:
1105                                 /* IEEE float */
1106                                 proto_tree_add_text(adspec_tree, offset2, 
1107                                                     (pntohs(&phdr->length)+1)<<2,
1108                                                     "%s - %lu (type %d, length %d)",
1109                                                     str, 
1110                                                     ieee_to_long(&phdr->dataval), 
1111                                                     phdr->id, pntohs(&phdr->length));
1112                                 break;
1113                             default: 
1114                                 proto_tree_add_text(adspec_tree, offset2, 
1115                                                     (pntohs(&phdr->length)+1)<<2,
1116                                                     "%s (type %d, length %d)",
1117                                                     str, 
1118                                                     phdr->id, pntohs(&phdr->length));
1119                             }
1120                         } else {
1121                             proto_tree_add_text(adspec_tree, offset2, 
1122                                                 (pntohs(&phdr->length)+1)<<2,
1123                                                 "Unknown (type %d, length %d)",
1124                                                 phdr->id, pntohs(&phdr->length));
1125                         }
1126                         offset2+=(pntohs(&phdr->length)+1)<<2;
1127                         i-=(pntohs(&phdr->length)+1)<<2;
1128                         mylen-=(pntohs(&phdr->length)+1)<<2;
1129                     }
1130                 }
1131                 break;
1132             }
1133
1134             case RSVP_CLASS_INTEGRITY :
1135                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_INTEGRITY);
1136                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
1137                                     obj_length);
1138                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
1139                                     "Class number: %d - %s", 
1140                                     obj->class, object_type);
1141                 goto default_class;
1142
1143             case RSVP_CLASS_POLICY :
1144                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_POLICY);
1145                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
1146                                     obj_length);
1147                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
1148                                     "Class number: %d - %s", 
1149                                     obj->class, object_type);
1150                 goto default_class;
1151
1152             default :
1153                 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_UNKNOWN_CLASS);
1154                 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d", 
1155                                     obj_length);
1156                 proto_tree_add_text(rsvp_object_tree, offset+2, 1, 
1157                                     "Class number: %d - %s", 
1158                                     obj->class, object_type);
1159             default_class:
1160                 i = obj_length - sizeof(rsvp_object);
1161                 proto_tree_add_text(rsvp_object_tree, offset2, i,
1162                                  "Data (%d bytes)", i);
1163                 break;
1164
1165             case RSVP_CLASS_NULL :
1166                 break;
1167
1168             }  
1169             
1170             offset += obj_length;
1171             len += obj_length;
1172         }
1173     }
1174 }
1175
1176 void
1177 proto_register_rsvp(void)
1178 {
1179         proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)", "rsvp");
1180         proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info));
1181 }