2 * Routines for RSVP packet disassembly
4 * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
6 * $Id: packet-rsvp.c,v 1.9 1999/10/12 06:20:16 gram Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
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.
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.
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.
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.
36 * IPv6 support is not completely tested
53 #ifdef HAVE_SYS_TYPES_H
54 # include <sys/types.h>
57 #ifdef HAVE_NETINET_IN_H
58 # include <netinet/in.h>
61 #ifdef NEED_SNPRINTF_H
67 # include "snprintf.h"
72 #include "packet-ip.h"
73 #include "packet-ipv6.h"
74 #include "packet-rsvp.h"
76 static int proto_rsvp = -1;
78 /* Stuff for IEEE float handling */
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 */
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
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)
93 #define MINUS_INFINITY (signed)0x80000000L
94 #define PLUS_INFINITY 0x7FFFFFFF
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"},
104 enum rsvp_filter_keys {
107 RSVPF_MSG, /* Message type */
108 /* Shorthand for message types */
117 /* Does the message contain an object of this type? */
119 /* Object present shorthands */
142 /* Sender template */
150 static int rsvp_filter[RSVPF_MAX];
152 static hf_register_info rsvpf_info[] = {
154 /* Message type number */
155 {&rsvp_filter[RSVPF_MSG],
156 { "Message Type", "rsvp.msg", FT_UINT8, BASE_NONE, message_type_vals, 0x0,
159 /* Message type shorthands */
160 {&rsvp_filter[RSVPF_PATH],
161 { "Path Message", "rsvp.path", FT_UINT8, BASE_NONE, NULL, 0x0,
164 {&rsvp_filter[RSVPF_RESV],
165 { "Resv Message", "rsvp.resv", FT_UINT8, BASE_NONE, NULL, 0x0,
168 {&rsvp_filter[RSVPF_PATHERR],
169 { "Path Error Message", "rsvp.perr", FT_UINT8, BASE_NONE, NULL, 0x0,
172 {&rsvp_filter[RSVPF_RESVERR],
173 { "Resv Error Message", "rsvp.rerr", FT_UINT8, BASE_NONE, NULL, 0x0,
176 {&rsvp_filter[RSVPF_PATHTEAR],
177 { "Path Tear Message", "rsvp.ptear", FT_UINT8, BASE_NONE, NULL, 0x0,
180 {&rsvp_filter[RSVPF_RESVTEAR],
181 { "Resv Tear Message", "rsvp.rtear", FT_UINT8, BASE_NONE, NULL, 0x0,
184 {&rsvp_filter[RSVPF_RCONFIRM],
185 { "Resv Confirm Message", "rsvp.resvconf", FT_UINT8, BASE_NONE, NULL, 0x0,
189 {&rsvp_filter[RSVPF_OBJECT],
190 { "", "rsvp.object", FT_UINT8, BASE_NONE, rsvp_class_vals, 0x0,
193 /* Object present shorthands */
194 {&rsvp_filter[RSVPF_SESSION],
195 { "SESSION", "rsvp.session", FT_UINT8, BASE_NONE, NULL, 0x0,
198 {&rsvp_filter[RSVPF_HOP],
199 { "HOP", "rsvp.hop", FT_UINT8, BASE_NONE, NULL, 0x0,
202 {&rsvp_filter[RSVPF_INTEGRITY],
203 { "INTEGRITY", "rsvp.integrity", FT_UINT8, BASE_NONE, NULL, 0x0,
206 {&rsvp_filter[RSVPF_TIME_VALUES],
207 { "TIME VALUES", "rsvp.time", FT_UINT8, BASE_NONE, NULL, 0x0,
210 {&rsvp_filter[RSVPF_ERROR],
211 { "ERROR", "rsvp.error", FT_UINT8, BASE_NONE, NULL, 0x0,
214 {&rsvp_filter[RSVPF_SCOPE],
215 { "SCOPE", "rsvp.scope", FT_UINT8, BASE_NONE, NULL, 0x0,
218 {&rsvp_filter[RSVPF_STYLE],
219 { "STYLE", "rsvp.style", FT_UINT8, BASE_NONE, NULL, 0x0,
222 {&rsvp_filter[RSVPF_FLOWSPEC],
223 { "FLOWSPEC", "rsvp.flowspec", FT_UINT8, BASE_NONE, NULL, 0x0,
226 {&rsvp_filter[RSVPF_FILTER_SPEC],
227 { "FILTERSPEC", "rsvp.filter", FT_UINT8, BASE_NONE, NULL, 0x0,
230 {&rsvp_filter[RSVPF_SENDER],
231 { "SENDER TEMPLATE", "rsvp.sender", FT_UINT8, BASE_NONE, NULL, 0x0,
234 {&rsvp_filter[RSVPF_TSPEC],
235 { "SENDER TSPEC", "rsvp.tspec", FT_UINT8, BASE_NONE, NULL, 0x0,
238 {&rsvp_filter[RSVPF_ADSPEC],
239 { "ADSPEC", "rsvp.adspec", FT_UINT8, BASE_NONE, NULL, 0x0,
242 {&rsvp_filter[RSVPF_POLICY],
243 { "POLICY", "rsvp.policy", FT_UINT8, BASE_NONE, NULL, 0x0,
246 {&rsvp_filter[RSVPF_CONFIRM],
247 { "CONFIRM", "rsvp.confirm", FT_UINT8, BASE_NONE, NULL, 0x0,
250 {&rsvp_filter[RSVPF_UNKNOWN_OBJ],
251 { "Unknown object", "rsvp.obj_unknown", FT_UINT8, BASE_NONE, NULL, 0x0,
255 {&rsvp_filter[RSVPF_SESSION_IP],
256 { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
259 {&rsvp_filter[RSVPF_SESSION_PORT],
260 { "Port number", "rsvp.session.port", FT_UINT16, BASE_NONE, NULL, 0x0,
263 {&rsvp_filter[RSVPF_SESSION_PROTO],
264 { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_NONE, VALS(proto_vals), 0x0,
267 /* Sender template fields */
268 {&rsvp_filter[RSVPF_SENDER_IP],
269 { "Sender Template IPv4 address", "rsvp.template.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
272 {&rsvp_filter[RSVPF_SENDER_PORT],
273 { "Sender Template port number", "rsvp.template.port", FT_UINT16, BASE_NONE, NULL, 0x0,
277 static inline int rsvp_class_to_filter_num(int 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;
297 return RSVPF_UNKNOWN_OBJ;
301 static inline int ieee_float_is_zero (long number)
303 return(!(number & ~IEEE_SIGN_MASK));
307 * simple conversion: ieee floating point to long
309 static long ieee_to_long (const void *p)
317 sign = number & IEEE_SIGN_MASK;
318 exponent = number & IEEE_EXPONENT_MASK;
319 mantissa = number & IEEE_MANTISSA_MASK;
321 if (ieee_float_is_zero(number)) {
322 /* number is zero, unnormalized, or not-a-number */
325 if (IEEE_INFINITY == exponent) {
326 /* number is positive or negative infinity, or a special value */
327 return (sign? MINUS_INFINITY: PLUS_INFINITY);
330 exponent = (exponent >> IEEE_MANTISSA_WIDTH) - IEEE_BIAS;
332 /* number is between zero and one */
336 mantissa |= IEEE_IMPLIED_BIT;
337 if (exponent <= IEEE_MANTISSA_WIDTH)
338 mantissa >>= IEEE_MANTISSA_WIDTH - exponent;
340 mantissa <<= exponent - IEEE_MANTISSA_WIDTH;
349 dissect_rsvp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
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;
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);
370 col_add_fstr(fd, COL_INFO, "Unknown (%d)", hdr->message_type);
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);
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);
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],
391 proto_tree_add_text(rsvp_header_tree, offset+1, 1, "Message Type: %d - %s",
393 packet_type?packet_type:"Unknown");
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",
398 proto_tree_add_text(rsvp_header_tree, offset + 6 , 2, "Message length: %d",
401 offset += sizeof(rsvp_header);
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");
412 object_type = match_strval(obj->class, rsvp_class_vals);
413 if (!object_type) object_type = "Unknown";
415 ti = proto_tree_add_text(rsvp_tree, offset,
417 "%s (%d)", object_type, obj->class);
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);
424 offset2 = offset + sizeof(rsvp_object);
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",
432 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
433 "Class number: %d - %s",
434 obj->class, object_type);
437 /*rsvp_session_ipv4 *sess = (rsvp_session_ipv4 *)obj;*/
438 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
441 proto_tree_add_text(rsvp_object_tree, offset2, 4,
442 "Destination address: %s",
443 ip_to_str((guint8 *) &(sess->destination)));
445 proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_IP],
446 offset2, 4, pntohl(pd+offset2));
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));
463 rsvp_session_ipv6 *sess = (rsvp_session_ipv6 *)obj;
464 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
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));
480 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
481 "C-type: Unknown (%d)",
483 i = obj_length - sizeof(rsvp_object);
484 proto_tree_add_text(rsvp_object_tree, offset2, i,
485 "Data (%d bytes)", i);
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",
494 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
495 "Class number: %d - %s",
496 obj->class, object_type);
499 rsvp_hop_ipv4 *hop = (rsvp_hop_ipv4 *)obj;
500 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
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));
512 rsvp_hop_ipv6 *hop = (rsvp_hop_ipv6 *)obj;
513 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
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));
525 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
526 "C-type: Unknown (%d)",
528 i = obj_length - sizeof(rsvp_object);
529 proto_tree_add_text(rsvp_object_tree, offset2, i,
530 "Data (%d bytes)", i);
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",
539 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
540 "Class number: %d - %s",
541 obj->class, object_type);
544 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
546 proto_tree_add_text(rsvp_object_tree, offset2, 4,
547 "Refresh interval: %u ms (%u seconds)",
549 pntohl(pd+offset2)/1000);
554 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
555 "C-type: Unknown (%d)",
557 i = obj_length - sizeof(rsvp_object);
558 proto_tree_add_text(rsvp_object_tree, offset2, i,
559 "Data (%d bytes)", i);
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",
569 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
570 "Class number: %d - %s",
571 obj->class, object_type);
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";
578 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
580 proto_tree_add_text(rsvp_object_tree, offset2, 4,
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,
588 proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
589 "Error value: %d", pntohs(pd+offset2+6));
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,
600 proto_tree_add_text(rsvp_object_tree, offset2, 4,
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,
608 proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
609 "Error value: %d", pntohs(pd+offset2+18));
615 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
616 "C-type: Unknown (%d)",
618 i = obj_length - sizeof(rsvp_object);
619 proto_tree_add_text(rsvp_object_tree, offset2, i,
620 "Data (%d bytes)", i);
626 case RSVP_CLASS_SCOPE :
628 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_SCOPE);
629 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
631 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
632 "Class number: %d - %s",
633 obj->class, object_type);
637 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
639 while (mylen > sizeof(rsvp_object)) {
640 ip = pntohl(pd+offset2);
641 proto_tree_add_text(rsvp_object_tree, offset2, 4,
643 ip_to_str((guint8 *) &ip));
651 struct e_in6_addr *ip;
652 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
654 while (mylen>sizeof(rsvp_object)) {
655 ip = (struct e_in6_addr *)pd+offset2;
656 proto_tree_add_text(rsvp_object_tree, offset2, 16,
666 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
667 "C-type: Unknown (%d)",
669 i = obj_length - sizeof(rsvp_object);
670 proto_tree_add_text(rsvp_object_tree, offset2, i,
671 "Data (%d bytes)", i);
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",
680 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
681 "Class number: %d - %s",
682 obj->class, object_type);
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,
690 proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
691 "Style: %ld - %s", ip, style_str);
696 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
697 "C-type: Unknown (%d)",
699 i = obj_length - sizeof(rsvp_object);
700 proto_tree_add_text(rsvp_object_tree, offset2, i,
701 "Data (%d bytes)", i);
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",
711 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
712 "Class number: %d - %s",
713 obj->class, object_type);
716 rsvp_confirm_ipv4 *confirm = (rsvp_confirm_ipv4 *)obj;
717 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
719 proto_tree_add_text(rsvp_object_tree, offset2, 4,
720 "Receiver address: %s",
721 ip_to_str((guint8 *) &(confirm->receiver)));
726 rsvp_confirm_ipv6 *confirm = (rsvp_confirm_ipv6 *)obj;
727 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
729 proto_tree_add_text(rsvp_object_tree, offset2, 16,
730 "Receiver address: %s",
731 ip6_to_str(&(confirm->receiver)));
736 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
737 "C-type: Unknown (%d)",
739 i = obj_length - sizeof(rsvp_object);
740 proto_tree_add_text(rsvp_object_tree, offset2, i,
741 "Data (%d bytes)", i);
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",
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",
758 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
759 "Class number: %d - %s",
760 obj->class, object_type);
764 rsvp_template_ipv4 *tem = (rsvp_template_ipv4 *)obj;
765 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
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));
776 rsvp_template_ipv6 *tem = (rsvp_template_ipv6 *)obj;
777 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
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));
788 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
789 "C-type: Unknown (%d)",
791 i = obj_length - sizeof(rsvp_object);
792 proto_tree_add_text(rsvp_object_tree, offset2, i,
793 "Data (%d bytes)", i);
798 case RSVP_CLASS_SENDER_TSPEC : {
799 rsvp_tspec *tspec = (rsvp_tspec *)obj;
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",
809 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
810 "Class number: %d - %s",
811 obj->class, object_type);
813 proto_tree_add_text(rsvp_object_tree, offset2, 1,
814 "Message format version: %d",
816 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
817 "Data length: %d words, not including header",
818 pntohs(pd+offset2+2));
823 sh = (service_hdr *)(pd+offset2);
824 str = match_strval(sh->service_num, qos_vals);
825 if (!str) str = "Unknown";
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",
836 offset2+=4; mylen -=4;
838 switch(sh->service_num) {
841 ist = (IS_tspec *)sh;
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,
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",
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));
876 case QOS_QUALITATIVE :
877 qt = (QUAL_tspec *)sh;
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,
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",
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));
901 offset2 += ntohs(sh->length)*4;
902 mylen -= ntohs(sh->length)*4;
908 case RSVP_CLASS_FLOWSPEC : {
909 rsvp_flowspec *flowspec = (rsvp_flowspec *)obj;
918 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_FLOWSPEC);
919 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
921 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
922 "Class number: %d - %s",
923 obj->class, object_type);
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));
935 sh = (service_hdr *)(pd+offset2);
936 str = match_strval(sh->service_num, intsrv_services_str);
937 if (!str) str = "Unknown";
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",
948 offset2+=4; mylen -=4;
950 switch(sh->service_num) {
952 case QOS_CONTROLLED_LOAD :
953 case QOS_GUARANTEED :
954 /* Treat both these the same for now */
955 isf = (IS_flowspec *)sh;
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,
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",
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)
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,
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));
1003 proto_tree_add_text(rsvp_object_tree, offset2+28, 4,
1005 ieee_to_long(pd+offset2+28));
1006 proto_tree_add_text(rsvp_object_tree, offset2+32, 4,
1008 pntohl(pd+offset2+32));
1011 case QOS_QUALITATIVE :
1012 qf = (QUAL_flowspec *)sh;
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",
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",
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));
1033 offset2 += ntohs(sh->length)*4;
1034 mylen -= ntohs(sh->length)*4;
1040 case RSVP_CLASS_ADSPEC : {
1041 proto_tree *adspec_tree;
1049 rsvp_object_tree = proto_item_add_subtree(ti, ETT_RSVP_ADSPEC);
1050 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
1052 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1053 "Class number: %d - %s",
1054 obj->class, object_type);
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));
1063 tree_num=ETT_RSVP_ADSPEC_SUBTREE1;
1066 shdr = (service_hdr *)(pd + offset2);
1067 str = match_strval(shdr->service_num, intsrv_services_str);
1069 ti = proto_tree_add_text(rsvp_object_tree, offset2,
1070 (pntohs(&shdr->length)+1)<<2,
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;
1084 phdr = (param_hdr *)(pd + offset2);
1085 str = match_strval(phdr->id, adspec_params);
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)",
1100 (unsigned long)pntohl(&phdr->dataval),
1101 phdr->id, pntohs(&phdr->length));
1106 proto_tree_add_text(adspec_tree, offset2,
1107 (pntohs(&phdr->length)+1)<<2,
1108 "%s - %lu (type %d, length %d)",
1110 ieee_to_long(&phdr->dataval),
1111 phdr->id, pntohs(&phdr->length));
1114 proto_tree_add_text(adspec_tree, offset2,
1115 (pntohs(&phdr->length)+1)<<2,
1116 "%s (type %d, length %d)",
1118 phdr->id, pntohs(&phdr->length));
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));
1126 offset2+=(pntohs(&phdr->length)+1)<<2;
1127 i-=(pntohs(&phdr->length)+1)<<2;
1128 mylen-=(pntohs(&phdr->length)+1)<<2;
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",
1138 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1139 "Class number: %d - %s",
1140 obj->class, object_type);
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",
1147 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1148 "Class number: %d - %s",
1149 obj->class, object_type);
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",
1156 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1157 "Class number: %d - %s",
1158 obj->class, object_type);
1160 i = obj_length - sizeof(rsvp_object);
1161 proto_tree_add_text(rsvp_object_tree, offset2, i,
1162 "Data (%d bytes)", i);
1165 case RSVP_CLASS_NULL :
1170 offset += obj_length;
1177 proto_register_rsvp(void)
1179 proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)", "rsvp");
1180 proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info));