2 * Routines for RSVP packet disassembly
4 * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
6 * $Id: packet-rsvp.c,v 1.11 1999/12/13 19:59:29 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 static gint ett_rsvp = -1;
79 static gint ett_rsvp_hdr = -1;
80 static gint ett_rsvp_session = -1;
81 static gint ett_rsvp_hop = -1;
82 static gint ett_rsvp_time_values = -1;
83 static gint ett_rsvp_error = -1;
84 static gint ett_rsvp_scope = -1;
85 static gint ett_rsvp_style = -1;
86 static gint ett_rsvp_confirm = -1;
87 static gint ett_rsvp_sender_template = -1;
88 static gint ett_rsvp_filter_spec = -1;
89 static gint ett_rsvp_sender_tspec = -1;
90 static gint ett_rsvp_flowspec = -1;
91 static gint ett_rsvp_adspec = -1;
92 static gint ett_rsvp_adspec_subtree = -1;
93 static gint ett_rsvp_integrity = -1;
94 static gint ett_rsvp_policy = -1;
95 static gint ett_rsvp_unknown_class = -1;
97 /* Stuff for IEEE float handling */
99 #define IEEE_NUMBER_WIDTH 32 /* bits in number */
100 #define IEEE_EXP_WIDTH 8 /* bits in exponent */
101 #define IEEE_MANTISSA_WIDTH 23 /* IEEE_NUMBER_WIDTH - 1 - IEEE_EXP_WIDTH */
103 #define IEEE_SIGN_MASK 0x80000000
104 #define IEEE_EXPONENT_MASK 0x7F800000
105 #define IEEE_MANTISSA_MASK 0x007FFFFF
106 #define IEEE_INFINITY IEEE_EXPONENT_MASK
108 #define IEEE_IMPLIED_BIT (1 << IEEE_MANTISSA_WIDTH)
109 #define IEEE_INFINITE ((1 << IEEE_EXP_WIDTH) - 1)
110 #define IEEE_BIAS ((1 << (IEEE_EXP_WIDTH - 1)) - 1)
112 #define MINUS_INFINITY (signed)0x80000000L
113 #define PLUS_INFINITY 0x7FFFFFFF
115 static const value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"},
116 {IP_PROTO_IGMP, "IGMP"},
117 {IP_PROTO_TCP, "TCP" },
118 {IP_PROTO_UDP, "UDP" },
119 {IP_PROTO_OSPF, "OSPF"},
123 enum rsvp_filter_keys {
126 RSVPF_MSG, /* Message type */
127 /* Shorthand for message types */
136 /* Does the message contain an object of this type? */
138 /* Object present shorthands */
161 /* Sender template */
169 static int rsvp_filter[RSVPF_MAX];
171 static hf_register_info rsvpf_info[] = {
173 /* Message type number */
174 {&rsvp_filter[RSVPF_MSG],
175 { "Message Type", "rsvp.msg", FT_UINT8, BASE_NONE, message_type_vals, 0x0,
178 /* Message type shorthands */
179 {&rsvp_filter[RSVPF_PATH],
180 { "Path Message", "rsvp.path", FT_UINT8, BASE_NONE, NULL, 0x0,
183 {&rsvp_filter[RSVPF_RESV],
184 { "Resv Message", "rsvp.resv", FT_UINT8, BASE_NONE, NULL, 0x0,
187 {&rsvp_filter[RSVPF_PATHERR],
188 { "Path Error Message", "rsvp.perr", FT_UINT8, BASE_NONE, NULL, 0x0,
191 {&rsvp_filter[RSVPF_RESVERR],
192 { "Resv Error Message", "rsvp.rerr", FT_UINT8, BASE_NONE, NULL, 0x0,
195 {&rsvp_filter[RSVPF_PATHTEAR],
196 { "Path Tear Message", "rsvp.ptear", FT_UINT8, BASE_NONE, NULL, 0x0,
199 {&rsvp_filter[RSVPF_RESVTEAR],
200 { "Resv Tear Message", "rsvp.rtear", FT_UINT8, BASE_NONE, NULL, 0x0,
203 {&rsvp_filter[RSVPF_RCONFIRM],
204 { "Resv Confirm Message", "rsvp.resvconf", FT_UINT8, BASE_NONE, NULL, 0x0,
208 {&rsvp_filter[RSVPF_OBJECT],
209 { "", "rsvp.object", FT_UINT8, BASE_NONE, rsvp_class_vals, 0x0,
212 /* Object present shorthands */
213 {&rsvp_filter[RSVPF_SESSION],
214 { "SESSION", "rsvp.session", FT_UINT8, BASE_NONE, NULL, 0x0,
217 {&rsvp_filter[RSVPF_HOP],
218 { "HOP", "rsvp.hop", FT_UINT8, BASE_NONE, NULL, 0x0,
221 {&rsvp_filter[RSVPF_INTEGRITY],
222 { "INTEGRITY", "rsvp.integrity", FT_UINT8, BASE_NONE, NULL, 0x0,
225 {&rsvp_filter[RSVPF_TIME_VALUES],
226 { "TIME VALUES", "rsvp.time", FT_UINT8, BASE_NONE, NULL, 0x0,
229 {&rsvp_filter[RSVPF_ERROR],
230 { "ERROR", "rsvp.error", FT_UINT8, BASE_NONE, NULL, 0x0,
233 {&rsvp_filter[RSVPF_SCOPE],
234 { "SCOPE", "rsvp.scope", FT_UINT8, BASE_NONE, NULL, 0x0,
237 {&rsvp_filter[RSVPF_STYLE],
238 { "STYLE", "rsvp.style", FT_UINT8, BASE_NONE, NULL, 0x0,
241 {&rsvp_filter[RSVPF_FLOWSPEC],
242 { "FLOWSPEC", "rsvp.flowspec", FT_UINT8, BASE_NONE, NULL, 0x0,
245 {&rsvp_filter[RSVPF_FILTER_SPEC],
246 { "FILTERSPEC", "rsvp.filter", FT_UINT8, BASE_NONE, NULL, 0x0,
249 {&rsvp_filter[RSVPF_SENDER],
250 { "SENDER TEMPLATE", "rsvp.sender", FT_UINT8, BASE_NONE, NULL, 0x0,
253 {&rsvp_filter[RSVPF_TSPEC],
254 { "SENDER TSPEC", "rsvp.tspec", FT_UINT8, BASE_NONE, NULL, 0x0,
257 {&rsvp_filter[RSVPF_ADSPEC],
258 { "ADSPEC", "rsvp.adspec", FT_UINT8, BASE_NONE, NULL, 0x0,
261 {&rsvp_filter[RSVPF_POLICY],
262 { "POLICY", "rsvp.policy", FT_UINT8, BASE_NONE, NULL, 0x0,
265 {&rsvp_filter[RSVPF_CONFIRM],
266 { "CONFIRM", "rsvp.confirm", FT_UINT8, BASE_NONE, NULL, 0x0,
269 {&rsvp_filter[RSVPF_UNKNOWN_OBJ],
270 { "Unknown object", "rsvp.obj_unknown", FT_UINT8, BASE_NONE, NULL, 0x0,
274 {&rsvp_filter[RSVPF_SESSION_IP],
275 { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
278 {&rsvp_filter[RSVPF_SESSION_PORT],
279 { "Port number", "rsvp.session.port", FT_UINT16, BASE_NONE, NULL, 0x0,
282 {&rsvp_filter[RSVPF_SESSION_PROTO],
283 { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_NONE, VALS(proto_vals), 0x0,
286 /* Sender template fields */
287 {&rsvp_filter[RSVPF_SENDER_IP],
288 { "Sender Template IPv4 address", "rsvp.template.ip", FT_IPv4, BASE_NONE, NULL, 0x0,
291 {&rsvp_filter[RSVPF_SENDER_PORT],
292 { "Sender Template port number", "rsvp.template.port", FT_UINT16, BASE_NONE, NULL, 0x0,
296 static inline int rsvp_class_to_filter_num(int classnum)
299 case RSVP_CLASS_SESSION :
300 case RSVP_CLASS_HOP :
301 case RSVP_CLASS_INTEGRITY :
302 case RSVP_CLASS_TIME_VALUES :
303 case RSVP_CLASS_ERROR :
304 case RSVP_CLASS_SCOPE :
305 case RSVP_CLASS_STYLE :
306 case RSVP_CLASS_FLOWSPEC :
307 case RSVP_CLASS_FILTER_SPEC :
308 case RSVP_CLASS_SENDER_TEMPLATE :
309 case RSVP_CLASS_SENDER_TSPEC :
310 case RSVP_CLASS_ADSPEC :
311 case RSVP_CLASS_POLICY :
312 case RSVP_CLASS_CONFIRM :
313 return classnum + RSVPF_OBJECT;
316 return RSVPF_UNKNOWN_OBJ;
320 static inline int ieee_float_is_zero (long number)
322 return(!(number & ~IEEE_SIGN_MASK));
326 * simple conversion: ieee floating point to long
328 static long ieee_to_long (const void *p)
336 sign = number & IEEE_SIGN_MASK;
337 exponent = number & IEEE_EXPONENT_MASK;
338 mantissa = number & IEEE_MANTISSA_MASK;
340 if (ieee_float_is_zero(number)) {
341 /* number is zero, unnormalized, or not-a-number */
344 if (IEEE_INFINITY == exponent) {
345 /* number is positive or negative infinity, or a special value */
346 return (sign? MINUS_INFINITY: PLUS_INFINITY);
349 exponent = (exponent >> IEEE_MANTISSA_WIDTH) - IEEE_BIAS;
351 /* number is between zero and one */
355 mantissa |= IEEE_IMPLIED_BIT;
356 if (exponent <= IEEE_MANTISSA_WIDTH)
357 mantissa >>= IEEE_MANTISSA_WIDTH - exponent;
359 mantissa <<= exponent - IEEE_MANTISSA_WIDTH;
368 dissect_rsvp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
370 proto_tree *rsvp_tree = NULL, *ti;
371 proto_tree *rsvp_header_tree;
372 proto_tree *rsvp_object_tree;
373 char *packet_type, *object_type;
381 hdr = (rsvp_header *)&pd[offset];
382 packet_type = match_strval(hdr->message_type, message_type_vals);
383 if (check_col(fd, COL_PROTOCOL))
384 col_add_str(fd, COL_PROTOCOL, "RSVP");
385 if (check_col(fd, COL_INFO)) {
386 if (packet_type != NULL)
387 col_add_str(fd, COL_INFO, packet_type);
389 col_add_fstr(fd, COL_INFO, "Unknown (%d)", hdr->message_type);
393 msg_length = pntohs(pd+offset+6);
394 ti = proto_tree_add_item(tree, proto_rsvp, offset, msg_length, NULL);
395 rsvp_tree = proto_item_add_subtree(ti, ett_rsvp);
397 ti = proto_tree_add_text(rsvp_tree, offset,
398 sizeof(rsvp_header), "RSVP Header");
399 rsvp_header_tree = proto_item_add_subtree(ti, ett_rsvp_hdr);
401 proto_tree_add_text(rsvp_header_tree, offset, 1, "RSVP Version: %d",
402 (hdr->ver_flags & 0xf0)>>4);
403 proto_tree_add_text(rsvp_header_tree, offset, 1, "Flags: %02X",
404 hdr->ver_flags & 0xf);
405 proto_tree_add_item(rsvp_header_tree, rsvp_filter[RSVPF_MSG],
406 offset+1, 1, hdr->message_type);
407 if (hdr->message_type >= RSVPF_MAX) {
408 proto_tree_add_text(rsvp_header_tree, offset+1, 1, "Message Type: %d - Unknown",
412 proto_tree_add_item_hidden(rsvp_header_tree, rsvp_filter[RSVPF_MSG + hdr->message_type],
414 proto_tree_add_text(rsvp_header_tree, offset + 2 , 2, "Message Checksum");
415 proto_tree_add_text(rsvp_header_tree, offset + 4 , 1, "Sending TTL: %d",
417 proto_tree_add_text(rsvp_header_tree, offset + 6 , 2, "Message length: %d",
420 offset += sizeof(rsvp_header);
422 while (len + sizeof(rsvp_header) < msg_length) {
423 obj = (rsvp_object *)&pd[offset];
424 obj_length = pntohs(pd+offset);
425 if (offset + obj_length > fd->cap_len) {
426 proto_tree_add_text(rsvp_tree, offset, 1,
427 "Further data not captured");
431 object_type = match_strval(obj->class, rsvp_class_vals);
432 if (!object_type) object_type = "Unknown";
434 ti = proto_tree_add_text(rsvp_tree, offset,
436 "%s (%d)", object_type, obj->class);
438 ti = proto_tree_add_item_hidden(rsvp_tree, rsvp_filter[RSVPF_OBJECT],
439 offset, obj_length, obj->class);
440 ti = proto_tree_add_item(rsvp_tree, rsvp_filter[rsvp_class_to_filter_num(obj->class)],
441 offset, obj_length, obj->class);
443 offset2 = offset + sizeof(rsvp_object);
447 case RSVP_CLASS_SESSION :
448 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_session);
449 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
451 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
452 "Class number: %d - %s",
453 obj->class, object_type);
456 /*rsvp_session_ipv4 *sess = (rsvp_session_ipv4 *)obj;*/
457 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
460 proto_tree_add_text(rsvp_object_tree, offset2, 4,
461 "Destination address: %s",
462 ip_to_str((guint8 *) &(sess->destination)));
464 proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_IP],
465 offset2, 4, pntohl(pd+offset2));
467 /* proto_tree_add_text(rsvp_object_tree, offset2+4, 1,
468 "Protocol: %d", sess->protocol);*/
469 proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_PROTO],
470 offset2+4, 1, pntohs(pd+offset2+4));
471 proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
472 "Flags: %d", pntohs(pd+offset2+5));
473 /* proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
474 "Destination port: %d",
475 pntohs(pd+offset2+6)); */
476 proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_PORT],
477 offset2+6, 2, pntohs(pd+offset2+6));
482 rsvp_session_ipv6 *sess = (rsvp_session_ipv6 *)obj;
483 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
485 proto_tree_add_text(rsvp_object_tree, offset2, 4,
486 "Destination address: %s",
487 ip6_to_str(&(sess->destination)));
488 proto_tree_add_text(rsvp_object_tree, offset2+16, 1,
489 "Protocol: %d", sess->protocol);
490 proto_tree_add_text(rsvp_object_tree, offset2+17, 1,
491 "Flags: %d", sess->flags);
492 proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
493 "Destination port: %d",
494 pntohs(pd+offset2+18));
499 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
500 "C-type: Unknown (%d)",
502 i = obj_length - sizeof(rsvp_object);
503 proto_tree_add_text(rsvp_object_tree, offset2, i,
504 "Data (%d bytes)", i);
509 case RSVP_CLASS_HOP :
510 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_hop);
511 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
513 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
514 "Class number: %d - %s",
515 obj->class, object_type);
518 rsvp_hop_ipv4 *hop = (rsvp_hop_ipv4 *)obj;
519 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
521 proto_tree_add_text(rsvp_object_tree, offset2, 4,
522 "Neighbor address: %s",
523 ip_to_str((guint8 *) &(hop->neighbor)));
524 proto_tree_add_text(rsvp_object_tree, offset2+4, 4,
525 "Logical interface: %0x",
526 pntohl(pd+offset2+4));
531 rsvp_hop_ipv6 *hop = (rsvp_hop_ipv6 *)obj;
532 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
534 proto_tree_add_text(rsvp_object_tree, offset2, 4,
535 "Neighbor address: %s",
536 ip6_to_str(&(hop->neighbor)));
537 proto_tree_add_text(rsvp_object_tree, offset2+16, 4,
538 "Logical interface: %0x",
539 pntohl(pd+offset2+16));
544 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
545 "C-type: Unknown (%d)",
547 i = obj_length - sizeof(rsvp_object);
548 proto_tree_add_text(rsvp_object_tree, offset2, i,
549 "Data (%d bytes)", i);
554 case RSVP_CLASS_TIME_VALUES :
555 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_time_values);
556 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
558 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
559 "Class number: %d - %s",
560 obj->class, object_type);
563 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
565 proto_tree_add_text(rsvp_object_tree, offset2, 4,
566 "Refresh interval: %u ms (%u seconds)",
568 pntohl(pd+offset2)/1000);
573 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
574 "C-type: Unknown (%d)",
576 i = obj_length - sizeof(rsvp_object);
577 proto_tree_add_text(rsvp_object_tree, offset2, i,
578 "Data (%d bytes)", i);
584 case RSVP_CLASS_ERROR :
585 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_error);
586 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
588 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
589 "Class number: %d - %s",
590 obj->class, object_type);
593 rsvp_error_ipv4 *err = (rsvp_error_ipv4 *)obj;
594 char *err_str = match_strval(err->error_code, rsvp_error_vals);
595 if (!err_str) err_str = "Unknown";
597 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
599 proto_tree_add_text(rsvp_object_tree, offset2, 4,
601 ip_to_str((guint8 *) &(err->error_node)));
602 proto_tree_add_text(rsvp_object_tree, offset2+4, 1,
603 "Flags: %02x", err->flags);
604 proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
605 "Error code: %d - %s", err->error_code,
607 proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
608 "Error value: %d", pntohs(pd+offset2+6));
614 rsvp_error_ipv6 *err = (rsvp_error_ipv6 *)obj;
615 char *err_str = match_strval(err->error_code, rsvp_error_vals);
616 if (!err_str) err_str = "Unknown";
617 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
619 proto_tree_add_text(rsvp_object_tree, offset2, 4,
621 ip6_to_str(&(err->error_node)));
622 proto_tree_add_text(rsvp_object_tree, offset2+16, 1,
623 "Flags: %02x", err->flags);
624 proto_tree_add_text(rsvp_object_tree, offset2+17, 1,
625 "Error code: %d - %s", err->error_code,
627 proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
628 "Error value: %d", pntohs(pd+offset2+18));
634 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
635 "C-type: Unknown (%d)",
637 i = obj_length - sizeof(rsvp_object);
638 proto_tree_add_text(rsvp_object_tree, offset2, i,
639 "Data (%d bytes)", i);
645 case RSVP_CLASS_SCOPE :
647 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_scope);
648 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
650 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
651 "Class number: %d - %s",
652 obj->class, object_type);
656 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
658 while (mylen > sizeof(rsvp_object)) {
659 ip = pntohl(pd+offset2);
660 proto_tree_add_text(rsvp_object_tree, offset2, 4,
662 ip_to_str((guint8 *) &ip));
670 struct e_in6_addr *ip;
671 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
673 while (mylen>sizeof(rsvp_object)) {
674 ip = (struct e_in6_addr *)pd+offset2;
675 proto_tree_add_text(rsvp_object_tree, offset2, 16,
685 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
686 "C-type: Unknown (%d)",
688 i = obj_length - sizeof(rsvp_object);
689 proto_tree_add_text(rsvp_object_tree, offset2, i,
690 "Data (%d bytes)", i);
695 case RSVP_CLASS_STYLE :
696 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_style);
697 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
699 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
700 "Class number: %d - %s",
701 obj->class, object_type);
704 unsigned long ip = pntohl(pd+offset2);
705 char *style_str = match_strval(ip, style_vals);
706 if (!style_str) style_str = "Unknown";
707 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
709 proto_tree_add_text(rsvp_object_tree, offset2+5, 1,
710 "Style: %ld - %s", ip, style_str);
715 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
716 "C-type: Unknown (%d)",
718 i = obj_length - sizeof(rsvp_object);
719 proto_tree_add_text(rsvp_object_tree, offset2, i,
720 "Data (%d bytes)", i);
726 case RSVP_CLASS_CONFIRM :
727 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_confirm);
728 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
730 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
731 "Class number: %d - %s",
732 obj->class, object_type);
735 rsvp_confirm_ipv4 *confirm = (rsvp_confirm_ipv4 *)obj;
736 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
738 proto_tree_add_text(rsvp_object_tree, offset2, 4,
739 "Receiver address: %s",
740 ip_to_str((guint8 *) &(confirm->receiver)));
745 rsvp_confirm_ipv6 *confirm = (rsvp_confirm_ipv6 *)obj;
746 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
748 proto_tree_add_text(rsvp_object_tree, offset2, 16,
749 "Receiver address: %s",
750 ip6_to_str(&(confirm->receiver)));
755 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
756 "C-type: Unknown (%d)",
758 i = obj_length - sizeof(rsvp_object);
759 proto_tree_add_text(rsvp_object_tree, offset2, i,
760 "Data (%d bytes)", i);
765 case RSVP_CLASS_SENDER_TEMPLATE :
766 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_template);
767 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
769 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
770 "Class number: %d - %s",
771 obj->class, object_type);
772 goto common_template;
773 case RSVP_CLASS_FILTER_SPEC :
774 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_filter_spec);
775 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
777 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
778 "Class number: %d - %s",
779 obj->class, object_type);
783 rsvp_template_ipv4 *tem = (rsvp_template_ipv4 *)obj;
784 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
786 proto_tree_add_text(rsvp_object_tree, offset2, 4,
787 "Source address: %s",
788 ip_to_str((guint8 *) &(tem->source)));
789 proto_tree_add_text(rsvp_object_tree, offset2+6, 2,
790 "Source port: %d", pntohs(pd+offset2+6));
795 rsvp_template_ipv6 *tem = (rsvp_template_ipv6 *)obj;
796 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
798 proto_tree_add_text(rsvp_object_tree, offset2, 16,
799 "Source address: %s",
800 ip6_to_str(&(tem->source)));
801 proto_tree_add_text(rsvp_object_tree, offset2+18, 2,
802 "Source port: %d", pntohs(pd+offset2+18));
807 proto_tree_add_text(rsvp_object_tree, offset+3, 1,
808 "C-type: Unknown (%d)",
810 i = obj_length - sizeof(rsvp_object);
811 proto_tree_add_text(rsvp_object_tree, offset2, i,
812 "Data (%d bytes)", i);
817 case RSVP_CLASS_SENDER_TSPEC : {
818 rsvp_tspec *tspec = (rsvp_tspec *)obj;
825 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_tspec);
826 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
828 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
829 "Class number: %d - %s",
830 obj->class, object_type);
832 proto_tree_add_text(rsvp_object_tree, offset2, 1,
833 "Message format version: %d",
835 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
836 "Data length: %d words, not including header",
837 pntohs(pd+offset2+2));
842 sh = (service_hdr *)(pd+offset2);
843 str = match_strval(sh->service_num, qos_vals);
844 if (!str) str = "Unknown";
846 proto_tree_add_text(rsvp_object_tree, offset2, 1,
847 "Service header: %d - %s",
848 sh->service_num, str);
849 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
850 "Length of service %d data: %d words, "
851 "not including header",
855 offset2+=4; mylen -=4;
857 switch(sh->service_num) {
860 ist = (IS_tspec *)sh;
862 /* Token bucket TSPEC */
863 str = match_strval(ist->param_id, svc_vals);
864 if (!str) str = "Unknown";
865 proto_tree_add_text(rsvp_object_tree, offset2, 1,
868 proto_tree_add_text(rsvp_object_tree, offset2+1, 1,
869 "Parameter %d flags: %d",
870 ist->param_id, ist->flags_tspec);
871 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
872 "Parameter %d data length: %d words, "
873 "not including header",
875 /* pntohs(pd+offset2+10)); */
876 ntohs(ist->parameter_length));
877 proto_tree_add_text(rsvp_object_tree, offset2+4, 4,
878 "Token bucket rate: %ld",
879 ieee_to_long(pd+offset2+4));
880 proto_tree_add_text(rsvp_object_tree, offset2+8, 4,
881 "Token bucket size: %ld",
882 ieee_to_long(pd+offset2+8));
883 proto_tree_add_text(rsvp_object_tree, offset2+12, 4,
884 "Peak data rate: %ld",
885 ieee_to_long(pd+offset2+12));
886 proto_tree_add_text(rsvp_object_tree, offset2+16, 4,
887 "Minimum policed unit: %d",
888 pntohl(pd+offset2+16));
889 proto_tree_add_text(rsvp_object_tree, offset2+20, 4,
890 "Maximum policed unit: %d",
891 pntohl(pd+offset2+20));
895 case QOS_QUALITATIVE :
896 qt = (QUAL_tspec *)sh;
898 /* Token bucket TSPEC */
899 str = match_strval(qt->param_id, svc_vals);
900 if (!str) str = "Unknown";
901 proto_tree_add_text(rsvp_object_tree, offset2, 1,
904 proto_tree_add_text(rsvp_object_tree, offset2+1, 1,
905 "Parameter %d flags: %d",
906 qt->param_id, qt->flags_tspec);
907 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
908 "Parameter %d data length: %d words, "
909 "not including header",
911 /* pntohs(pd+offset2+10)); */
912 ntohs(qt->parameter_length));
913 proto_tree_add_text(rsvp_object_tree, offset2+4, 4,
914 "Maximum policed unit: %d",
915 pntohl(pd+offset2+4));
920 offset2 += ntohs(sh->length)*4;
921 mylen -= ntohs(sh->length)*4;
927 case RSVP_CLASS_FLOWSPEC : {
928 rsvp_flowspec *flowspec = (rsvp_flowspec *)obj;
937 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_flowspec);
938 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
940 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
941 "Class number: %d - %s",
942 obj->class, object_type);
944 proto_tree_add_text(rsvp_object_tree, offset2, 1,
945 "Message format version: %d",
946 flowspec->version>>4);
947 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
948 "Data length: %d words, not including header",
949 pntohs(pd+offset2+2));
954 sh = (service_hdr *)(pd+offset2);
955 str = match_strval(sh->service_num, intsrv_services_str);
956 if (!str) str = "Unknown";
958 proto_tree_add_text(rsvp_object_tree, offset2, 1,
959 "Service header: %d - %s",
960 sh->service_num, str);
961 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
962 "Length of service %d data: %d words, "
963 "not including header",
967 offset2+=4; mylen -=4;
969 switch(sh->service_num) {
971 case QOS_CONTROLLED_LOAD :
972 case QOS_GUARANTEED :
973 /* Treat both these the same for now */
974 isf = (IS_flowspec *)sh;
976 str = match_strval(isf->tspec.param_id, svc_vals);
977 if (!str) str = "Unknown";
978 proto_tree_add_text(rsvp_object_tree, offset2, 1,
980 isf->tspec.param_id, str);
981 proto_tree_add_text(rsvp_object_tree, offset2+1, 1,
982 "Parameter %d flags: %d",
983 isf->tspec.param_id, isf->tspec.flags_tspec);
984 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
985 "Parameter %d data length: %d words, "
986 "not including header",
988 ntohs(isf->tspec.parameter_length));
989 proto_tree_add_text(rsvp_object_tree, offset2+4, 4,
990 "Token bucket rate: %ld",
991 ieee_to_long(pd+offset2+4));
992 proto_tree_add_text(rsvp_object_tree, offset2+8, 4,
993 "Token bucket size: %ld",
994 ieee_to_long(pd+offset2+8));
995 proto_tree_add_text(rsvp_object_tree, offset2+12, 4,
996 "Peak data rate: %ld",
997 ieee_to_long(pd+offset2+12));
998 proto_tree_add_text(rsvp_object_tree, offset2+16, 4,
999 "Minimum policed unit: %d",
1000 pntohl(pd+offset2+16));
1001 proto_tree_add_text(rsvp_object_tree, offset2+20, 4,
1002 "Maximum policed unit: %d",
1003 pntohl(pd+offset2+20));
1004 if (sh->service_num!=QOS_GUARANTEED)
1007 /* Guaranteed-rate RSpec */
1008 str = match_strval(isf->rspec.param_id, svc_vals);
1009 if (!str) str="Unknown";
1010 proto_tree_add_text(rsvp_object_tree, offset2+24, 1,
1011 "Parameter %d - %s",
1012 isf->rspec.param_id, str);
1013 proto_tree_add_text(rsvp_object_tree, offset2+25, 1,
1014 "Parameter %d flags: %d",
1015 isf->rspec.param_id, isf->rspec.flags_rspec);
1016 proto_tree_add_text(rsvp_object_tree, offset2+26, 2,
1017 "Parameter %d data length: %d words, "
1018 "not including header",
1019 isf->rspec.param_id,
1020 ntohs(isf->rspec.param2_length));
1022 proto_tree_add_text(rsvp_object_tree, offset2+28, 4,
1024 ieee_to_long(pd+offset2+28));
1025 proto_tree_add_text(rsvp_object_tree, offset2+32, 4,
1027 pntohl(pd+offset2+32));
1030 case QOS_QUALITATIVE :
1031 qf = (QUAL_flowspec *)sh;
1033 str = match_strval(qf->param_id, svc_vals);
1034 if (!str) str = "Unknown";
1035 proto_tree_add_text(rsvp_object_tree, offset2, 1,
1036 "Parameter %d - %s",
1038 proto_tree_add_text(rsvp_object_tree, offset2+1, 1,
1039 "Parameter %d flags: %d",
1040 qf->param_id, qf->flags_tspec);
1041 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
1042 "Parameter %d data length: %d words, "
1043 "not including header",
1045 ntohs(qf->parameter_length));
1046 proto_tree_add_text(rsvp_object_tree, offset2+4, 4,
1047 "Maximum policed unit: %ld",
1048 pntohl(pd+offset2+4));
1052 offset2 += ntohs(sh->length)*4;
1053 mylen -= ntohs(sh->length)*4;
1059 case RSVP_CLASS_ADSPEC : {
1060 proto_tree *adspec_tree;
1067 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_adspec);
1068 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
1070 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1071 "Class number: %d - %s",
1072 obj->class, object_type);
1074 proto_tree_add_text(rsvp_object_tree, offset2, 1,
1075 "Message format version: %d",
1076 (*((unsigned char *)pd+offset2))>>4);
1077 proto_tree_add_text(rsvp_object_tree, offset2+2, 2,
1078 "Data length: %d words, not including header",
1079 pntohs(pd+offset2+2));
1083 shdr = (service_hdr *)(pd + offset2);
1084 str = match_strval(shdr->service_num, intsrv_services_str);
1086 ti = proto_tree_add_text(rsvp_object_tree, offset2,
1087 (pntohs(&shdr->length)+1)<<2,
1089 adspec_tree = proto_item_add_subtree(ti,
1090 ett_rsvp_adspec_subtree);
1091 proto_tree_add_text(adspec_tree, offset2, 1,
1092 "Service header %d - %s",
1093 shdr->service_num, str);
1094 proto_tree_add_text(adspec_tree, offset2+1, 1,
1095 (shdr->break_bit&0x80)?
1096 "Break bit set":"Break bit not set");
1097 proto_tree_add_text(adspec_tree, offset2+2, 2,
1098 "Data length: %d words, not including header",
1099 pntohs(&shdr->length));
1100 offset2+=4; i=(pntohs(&shdr->length)+1)<<2; mylen-=4;
1102 phdr = (param_hdr *)(pd + offset2);
1103 str = match_strval(phdr->id, adspec_params);
1113 /* 32-bit unsigned integer */
1114 proto_tree_add_text(adspec_tree, offset2,
1115 (pntohs(&phdr->length)+1)<<2,
1116 "%s - %lu (type %d, length %d)",
1118 (unsigned long)pntohl(&phdr->dataval),
1119 phdr->id, pntohs(&phdr->length));
1124 proto_tree_add_text(adspec_tree, offset2,
1125 (pntohs(&phdr->length)+1)<<2,
1126 "%s - %lu (type %d, length %d)",
1128 ieee_to_long(&phdr->dataval),
1129 phdr->id, pntohs(&phdr->length));
1132 proto_tree_add_text(adspec_tree, offset2,
1133 (pntohs(&phdr->length)+1)<<2,
1134 "%s (type %d, length %d)",
1136 phdr->id, pntohs(&phdr->length));
1139 proto_tree_add_text(adspec_tree, offset2,
1140 (pntohs(&phdr->length)+1)<<2,
1141 "Unknown (type %d, length %d)",
1142 phdr->id, pntohs(&phdr->length));
1144 offset2+=(pntohs(&phdr->length)+1)<<2;
1145 i-=(pntohs(&phdr->length)+1)<<2;
1146 mylen-=(pntohs(&phdr->length)+1)<<2;
1152 case RSVP_CLASS_INTEGRITY :
1153 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_integrity);
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);
1161 case RSVP_CLASS_POLICY :
1162 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy);
1163 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
1165 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1166 "Class number: %d - %s",
1167 obj->class, object_type);
1171 rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_unknown_class);
1172 proto_tree_add_text(rsvp_object_tree, offset, 2, "Length: %d",
1174 proto_tree_add_text(rsvp_object_tree, offset+2, 1,
1175 "Class number: %d - %s",
1176 obj->class, object_type);
1178 i = obj_length - sizeof(rsvp_object);
1179 proto_tree_add_text(rsvp_object_tree, offset2, i,
1180 "Data (%d bytes)", i);
1183 case RSVP_CLASS_NULL :
1188 offset += obj_length;
1195 proto_register_rsvp(void)
1197 static gint *ett[] = {
1202 &ett_rsvp_time_values,
1207 &ett_rsvp_sender_template,
1208 &ett_rsvp_filter_spec,
1209 &ett_rsvp_sender_tspec,
1212 &ett_rsvp_adspec_subtree,
1213 &ett_rsvp_integrity,
1215 &ett_rsvp_unknown_class,
1218 proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)", "rsvp");
1219 proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info));
1220 proto_register_subtree_array(ett, array_length(ett));