/* packet-rsvp.c * Routines for RSVP packet disassembly * * (c) Copyright Ashok Narayanan * * $Id: packet-rsvp.c,v 1.62 2002/04/25 06:34:42 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * NOTES * * This module defines routines to disassemble RSVP packets, as defined in * RFC 2205. All objects from RFC2205 are supported, in IPv4 and IPv6 mode. * In addition, the Integrated Services traffic specification objects * defined in RFC2210 are also supported. * * IPv6 support is not completely tested * * Mar 3, 2000: Added support for MPLS/TE objects, as defined in * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #ifdef HAVE_UNISTD_H #include #endif #include #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif #include #ifdef NEED_SNPRINTF_H # include "snprintf.h" #endif #include #include #include "in_cksum.h" #include "etypes.h" #include "ipproto.h" #include "packet-rsvp.h" #include "packet-ip.h" static int proto_rsvp = -1; static gint ett_rsvp = -1; static gint ett_rsvp_hdr = -1; static gint ett_rsvp_session = -1; static gint ett_rsvp_hop = -1; static gint ett_rsvp_time_values = -1; static gint ett_rsvp_error = -1; static gint ett_rsvp_scope = -1; static gint ett_rsvp_style = -1; static gint ett_rsvp_confirm = -1; static gint ett_rsvp_sender_template = -1; static gint ett_rsvp_filter_spec = -1; static gint ett_rsvp_sender_tspec = -1; static gint ett_rsvp_sender_tspec_subtree = -1; static gint ett_rsvp_flowspec = -1; static gint ett_rsvp_flowspec_subtree = -1; static gint ett_rsvp_adspec = -1; static gint ett_rsvp_adspec_subtree = -1; static gint ett_rsvp_integrity = -1; static gint ett_rsvp_dclass = -1; static gint ett_rsvp_lsp_tunnel_if_id = -1; static gint ett_rsvp_policy = -1; static gint ett_rsvp_label = -1; static gint ett_rsvp_label_request = -1; static gint ett_rsvp_session_attribute = -1; static gint ett_rsvp_session_attribute_flags = -1; static gint ett_rsvp_hello_obj = -1; static gint ett_rsvp_explicit_route = -1; static gint ett_rsvp_explicit_route_subobj = -1; static gint ett_rsvp_record_route = -1; static gint ett_rsvp_record_route_subobj = -1; static gint ett_rsvp_hop_subobj = -1; static gint ett_rsvp_admin_status = -1; static gint ett_rsvp_admin_status_flags = -1; static gint ett_rsvp_unknown_class = -1; /* * RSVP message types */ typedef enum { RSVP_MSG_PATH=1, RSVP_MSG_RESV, RSVP_MSG_PERR, RSVP_MSG_RERR, RSVP_MSG_PTEAR, RSVP_MSG_RTEAR, RSVP_MSG_CONFIRM, RSVP_MSG_RTEAR_CONFIRM=10, RSVP_MSG_BUNDLE = 12, RSVP_MSG_ACK, RSVP_MSG_SREFRESH = 15, RSVP_MSG_HELLO = 20 } rsvp_message_types; static value_string message_type_vals[] = { {RSVP_MSG_PATH, "PATH Message. "}, {RSVP_MSG_RESV, "RESV Message. "}, {RSVP_MSG_PERR, "PATH ERROR Message. "}, {RSVP_MSG_RERR, "RESV ERROR Message. "}, {RSVP_MSG_PTEAR, "PATH TEAR Message. "}, {RSVP_MSG_RTEAR, "RESV TEAR Message. "}, {RSVP_MSG_CONFIRM, "CONFIRM Message. "}, {RSVP_MSG_RTEAR_CONFIRM, "RESV TEAR CONFIRM Message. "}, {RSVP_MSG_BUNDLE, "BUNDLE Message. "}, {RSVP_MSG_ACK, "ACK Message. "}, {RSVP_MSG_SREFRESH, "SREFRESH Message. "}, {RSVP_MSG_HELLO, "HELLO Message. "}, {0, NULL} }; /* * RSVP classes */ #define MAX_RSVP_CLASS 15 enum rsvp_classes { RSVP_CLASS_NULL=0, RSVP_CLASS_SESSION, RSVP_CLASS_HOP=3, RSVP_CLASS_INTEGRITY, RSVP_CLASS_TIME_VALUES, RSVP_CLASS_ERROR, RSVP_CLASS_SCOPE, RSVP_CLASS_STYLE, RSVP_CLASS_FLOWSPEC, RSVP_CLASS_FILTER_SPEC, RSVP_CLASS_SENDER_TEMPLATE, RSVP_CLASS_SENDER_TSPEC, RSVP_CLASS_ADSPEC, RSVP_CLASS_POLICY, RSVP_CLASS_CONFIRM, RSVP_CLASS_LABEL, RSVP_CLASS_LABEL_REQUEST=19, RSVP_CLASS_EXPLICIT_ROUTE, RSVP_CLASS_RECORD_ROUTE, RSVP_CLASS_HELLO, RSVP_CLASS_MESSAGE_ID, RSVP_CLASS_MESSAGE_ID_ACK, RSVP_CLASS_MESSAGE_ID_LIST, RSVP_CLASS_RECOVERY_LABEL = 34, RSVP_CLASS_UPSTREAM_LABEL, RSVP_CLASS_LABEL_SET, RSVP_CLASS_PROTECTION, RSVP_CLASS_SUGGESTED_LABEL = 129, RSVP_CLASS_ACCEPTABLE_LABEL_SET, RSVP_CLASS_RESTART_CAP, RSVP_CLASS_NOTIFY_REQUEST = 195, RSVP_CLASS_ADMIN_STATUS, RSVP_CLASS_SESSION_ATTRIBUTE = 207, RSVP_CLASS_DCLASS = 225, RSVP_CLASS_LSP_TUNNEL_IF_ID = 227, }; static value_string rsvp_class_vals[] = { {RSVP_CLASS_NULL, "NULL object"}, {RSVP_CLASS_SESSION, "SESSION object"}, {RSVP_CLASS_HOP, "HOP object"}, {RSVP_CLASS_INTEGRITY, "INTEGRITY object"}, {RSVP_CLASS_TIME_VALUES, "TIME VALUES object"}, {RSVP_CLASS_ERROR, "ERROR object"}, {RSVP_CLASS_SCOPE, "SCOPE object"}, {RSVP_CLASS_STYLE, "STYLE object"}, {RSVP_CLASS_FLOWSPEC, "FLOWSPEC object"}, {RSVP_CLASS_FILTER_SPEC, "FILTER SPEC object"}, {RSVP_CLASS_SENDER_TEMPLATE, "SENDER TEMPLATE object"}, {RSVP_CLASS_SENDER_TSPEC, "SENDER TSPEC object"}, {RSVP_CLASS_ADSPEC, "ADSPEC object"}, {RSVP_CLASS_POLICY, "POLICY object"}, {RSVP_CLASS_CONFIRM, "CONFIRM object"}, {RSVP_CLASS_LABEL, "LABEL object"}, {RSVP_CLASS_LABEL_REQUEST, "LABEL REQUEST object"}, {RSVP_CLASS_EXPLICIT_ROUTE, "EXPLICIT ROUTE object"}, {RSVP_CLASS_RECORD_ROUTE, "RECORD ROUTE object"}, {RSVP_CLASS_SESSION_ATTRIBUTE, "SESSION ATTRIBUTE object"}, {RSVP_CLASS_MESSAGE_ID, "MESSAGE-ID object"}, {RSVP_CLASS_MESSAGE_ID_ACK, "MESSAGE-ID ACK/NACK object"}, {RSVP_CLASS_MESSAGE_ID_LIST, "MESSAGE-ID LIST object"}, {RSVP_CLASS_HELLO, "HELLO object"}, {RSVP_CLASS_RECOVERY_LABEL, "RECOVERY-LABEL object"}, {RSVP_CLASS_UPSTREAM_LABEL, "UPSTREAM-LABEL object"}, {RSVP_CLASS_LABEL_SET, "LABEL-SET object"}, {RSVP_CLASS_PROTECTION, "PROTECTION object"}, {RSVP_CLASS_SUGGESTED_LABEL, "SUGGESTED-LABEL object"}, {RSVP_CLASS_ACCEPTABLE_LABEL_SET, "ACCEPTABLE-LABEL-SET object"}, {RSVP_CLASS_RESTART_CAP, "RESTART-CAPABILITY object"}, {RSVP_CLASS_DCLASS, "DCLASS object"}, {RSVP_CLASS_LSP_TUNNEL_IF_ID, "LSP-TUNNEL INTERFACE-ID object"}, {RSVP_CLASS_NOTIFY_REQUEST, "NOTIFY-REQUEST object"}, {RSVP_CLASS_ADMIN_STATUS, "ADMIN-STATUS object"}, {0, NULL} }; /* * RSVP error values */ enum rsvp_error_types { RSVP_ERROR_CONFIRM = 0, RSVP_ERROR_ADMISSION, RSVP_ERROR_POLICY, RSVP_ERROR_NO_PATH, RSVP_ERROR_NO_SENDER, RSVP_ERROR_CONFLICT_RESV_STYLE, RSVP_ERROR_UNKNOWN_RESV_STYLE, RSVP_ERROR_CONFLICT_DEST_PORTS, RSVP_ERROR_CONFLICT_SRC_PORTS, RSVP_ERROR_PREEMPTED=12, RSVP_ERROR_UNKNOWN_CLASS, RSVP_ERROR_UNKNOWN_C_TYPE, RSVP_ERROR_TRAFFIC = 21, RSVP_ERROR_TRAFFIC_SYSTEM, RSVP_ERROR_SYSTEM, RSVP_ERROR_ROUTING, RSVP_ERROR_NOTIFY }; static value_string rsvp_error_vals[] = { {RSVP_ERROR_CONFIRM, "Confirmation"}, {RSVP_ERROR_ADMISSION, "Admission Control Failure "}, {RSVP_ERROR_POLICY, "Policy Control Failure"}, {RSVP_ERROR_NO_PATH, "No PATH information for this RESV message"}, {RSVP_ERROR_NO_SENDER, "No sender information for this RESV message"}, {RSVP_ERROR_CONFLICT_RESV_STYLE, "Conflicting reservation styles"}, {RSVP_ERROR_UNKNOWN_RESV_STYLE, "Unknown reservation style"}, {RSVP_ERROR_CONFLICT_DEST_PORTS, "Conflicting destination ports"}, {RSVP_ERROR_CONFLICT_SRC_PORTS, "Conflicting source ports"}, {RSVP_ERROR_PREEMPTED, "Service preempted"}, {RSVP_ERROR_UNKNOWN_CLASS, "Unknown object class"}, {RSVP_ERROR_UNKNOWN_C_TYPE, "Unknown object C-type"}, {RSVP_ERROR_TRAFFIC, "Traffic Control Error"}, {RSVP_ERROR_TRAFFIC_SYSTEM, "Traffic Control System Error"}, {RSVP_ERROR_SYSTEM, "RSVP System Error"}, {RSVP_ERROR_ROUTING, "Routing Error"}, {RSVP_ERROR_NOTIFY, "RSVP Notify Error"}, {0, NULL} }; /* * Defines the reservation style plus style-specific information that * is not a FLOWSPEC or FILTER_SPEC object, in a RESV message. */ #define RSVP_DISTINCT (1 << 3) #define RSVP_SHARED (2 << 3) #define RSVP_SHARING_MASK (RSVP_DISTINCT | RSVP_SHARED) #define RSVP_SCOPE_WILD 1 #define RSVP_SCOPE_EXPLICIT 2 #define RSVP_SCOPE_MASK 0x07 #define RSVP_WF (RSVP_SHARED | RSVP_SCOPE_WILD) #define RSVP_FF (RSVP_DISTINCT | RSVP_SCOPE_EXPLICIT) #define RSVP_SE (RSVP_SHARED | RSVP_SCOPE_EXPLICIT) static value_string style_vals[] = { { RSVP_WF, "Wildcard Filter" }, { RSVP_FF, "Fixed Filter" }, { RSVP_SE, "Shared-Explicit" }, { 0, NULL } }; /* * Defines a desired QoS, in a RESV message. */ enum qos_service_type { QOS_QUALITATIVE = 128, /* Qualitative service */ QOS_NULL = 6, /* Null service (RFC2997) */ QOS_CONTROLLED_LOAD= 5, /* Controlled Load Service */ QOS_GUARANTEED = 2, /* Guaranteed service */ QOS_TSPEC = 1 /* Traffic specification */ }; static value_string qos_vals[] = { { QOS_QUALITATIVE, "Qualitative QoS" }, { QOS_NULL, "Null-Service QoS" }, { QOS_CONTROLLED_LOAD, "Controlled-load QoS" }, { QOS_GUARANTEED, "Guaranteed rate QoS" }, { QOS_TSPEC, "Traffic specification" }, { 0, NULL } }; static value_string svc_vals[] = { { 126, "Compression Hint" }, { 127, "Token bucket" }, { 128, "Null Service" }, { 130, "Guaranteed-rate RSpec" }, { 0, NULL } }; enum rsvp_spec_types { INTSRV = 2 }; enum intsrv_services { INTSRV_GENERAL = 1, INTSRV_GTD = 2, INTSRV_CLOAD = 5, INTSRV_NULL = 6, INTSRV_QUALITATIVE = 128 }; static value_string intsrv_services_str[] = { {INTSRV_GENERAL, "Default General Parameters"}, {INTSRV_GTD, "Guaranteed Rate"}, {INTSRV_CLOAD, "Controlled Load"}, {INTSRV_NULL, "Null Service"}, {INTSRV_QUALITATIVE, "Null Service"}, { 0, NULL } }; #if 0 enum intsrv_field_name { INTSRV_NON_IS_HOPS = 1, INTSRV_COMPOSED_NON_IS_HOPS, INTSRV_IS_HOPS, INTSRV_COMPOSED_IS_HOPS, INTSRV_PATH_BANDWIDTH, INTSRV_MIN_PATH_BANDWIDTH, INTSRV_IF_LATENCY, INTSRV_PATH_LATENCY, INTSRV_MTU, INTSRV_COMPOSED_MTU, INTSRV_TOKEN_BUCKET_TSPEC = 127, INTSRV_QUALITATIVE_TSPEC = 128, INTSRV_GTD_RSPEC = 130, INTSRV_DELAY = 131, /* Gtd Parameter C - Max Delay Bound - bytes */ INTSRV_MAX_JITTER, /* Gtd Parameter D - Max Jitter */ INTSRV_E2E_DELAY, /* Gtd Parameter Ctot */ INTSRV_E2E_MAX_JITTER, /* Gtd Parameter Dtot */ INTSRV_SHP_DELAY, /* Gtd Parameter Csum */ INTSRV_SHP_MAX_JITTER /* Gtd Parameter Dsum */ }; #endif static value_string adspec_params[] = { {4, "IS Hop Count"}, {6, "Path b/w estimate"}, {8, "Minimum path latency"}, {10, "Composed MTU"}, {133, "End-to-end composed value for C"}, {134, "End-to-end composed value for D"}, {135, "Since-last-reshaping point composed C"}, {136, "Since-last-reshaping point composed D"}, { 0, NULL } }; const value_string gmpls_lsp_enc_str[] = { { 1, "Packet"}, { 2, "Ethernet v2/DIX"}, { 3, "ANSI PDH"}, { 4, "ETSI PDH"}, { 5, "SDH ITU-T G.707"}, { 6, "SONET ANSI T1.105"}, { 7, "Digital Wrapper"}, { 8, "Lambda (photonic)"}, { 9, "Fiber"}, {10, "Ethernet 802.3"}, {11, "FiberChannel"}, { 0, NULL } }; const value_string gmpls_switching_type_str[] = { { 1, "Packet-Switch Capable-1 (PSC-1)"}, { 2, "Packet-Switch Capable-2 (PSC-2)"}, { 3, "Packet-Switch Capable-3 (PSC-3)"}, { 4, "Packet-Switch Capable-4 (PSC-4)"}, { 51, "Layer-2 Switch Capable (L2SC)"}, {100, "Time-Division-Multiplex Capable (TDM)"}, {150, "Lambda-Switch Capable (LSC)"}, {200, "Fiber-Switch Capable (FSC)"}, { 0, NULL } }; static const value_string gmpls_gpid_str[] = { { 5, "Asynchronous mapping of E3 (SONET, SDH)"}, { 8, "Bit synchronous mapping of E3 (SDH)"}, { 9, "Byte synchronous mapping of E3 (SDH)"}, {10, "Asynchronous mapping of DS2/T2 (SONET, SDH)"}, {11, "Bit synchronous mapping of DS2/T2 (SONET, SDH)"}, {13, "Asynchronous mapping of E1 (SONET, SDH)"}, {14, "Byte synchronous mapping of E1 (SONET, SDH)"}, {15, "Byte synchronous mapping of 31 * DS0 (SONET, SDH)"}, {16, "Asynchronous mapping of DS1/T1 (SONET, SDH)"}, {17, "Bit synchronous mapping of DS1/T1 (SONET, SDH)"}, {18, "Byte synchronous mapping of DS1/T1 (SONET, SDH)"}, {19, "VC-11 in VC-12 (SDH)"}, {22, "DS1 SF Asynchronous (SONET)"}, {23, "DS1 ESF Asynchronous (SONET)"}, {24, "DS3 M23 Asynchronous (SONET)"}, {25, "DS3 C-Bit Parity Asynchronous (SONET)"}, {26, "VT/LOVC (SONET, SDH)"}, {27, "STS SPE/HOVC (SONET, SDH)"}, {28, "POS - No Scrambling, 16 bit CRC (SONET, SDH)"}, {29, "POS - No Scrambling, 32 bit CRC (SONET, SDH)"}, {30, "POS - Scrambling, 16 bit CRC (SONET, SDH)"}, {31, "POS - Scrambling, 32 bit CRC (SONET, SDH)"}, {32, "ATM Mapping (SONET, SDH)"}, {33, "Ethernet (SDH, Lambda, Fiber)"}, {34, "SDH (Lambda, Fiber)"}, {35, "SONET (Lambda, Fiber)"}, {36, "Digital Wrapper (Lambda, Fiber)"}, {37, "Lambda (Fiber)"}, {38, "ETSI PDH (SDH)"}, {39, "ANSI PDH (SONET, SDH)"}, {40, "Link Access Protocol SDH: LAPS - X.85 and X.86 (SONET, SDH)"}, {41, "FDDI (SONET, SDH, Lambda, Fiber)"}, {42, "DQDB: ETSI ETS 300 216 (SONET, SDH)"}, {43, "FiberChannel-3 Services (FiberChannel)"}, { 0, NULL }, }; /* -------------------- Stuff for MPLS/TE objects -------------------- */ static const value_string proto_vals[] = { {IP_PROTO_ICMP, "ICMP"}, {IP_PROTO_IGMP, "IGMP"}, {IP_PROTO_TCP, "TCP" }, {IP_PROTO_UDP, "UDP" }, {IP_PROTO_OSPF, "OSPF"}, {0, NULL } }; /* Filter keys */ enum rsvp_filter_keys { /* Message types */ RSVPF_MSG, /* Message type */ /* Shorthand for message types */ RSVPF_PATH, RSVPF_RESV, RSVPF_PATHERR, RSVPF_RESVERR, RSVPF_PATHTEAR, RSVPF_RESVTEAR, RSVPF_RCONFIRM, RSVPF_JUNK_MSG8, RSVPF_JUNK_MSG9, RSVPF_RTEARCONFIRM, RSVPF_JUNK11, RSVPF_BUNDLE, RSVPF_ACK, RSVPF_JUNK14, RSVPF_SREFRESH, RSVPF_HELLO, /* Does the message contain an object of this type? */ RSVPF_OBJECT, /* Object present shorthands */ RSVPF_SESSION, RSVPF_DUMMY_1, RSVPF_HOP, RSVPF_INTEGRITY, RSVPF_TIME_VALUES, RSVPF_ERROR, RSVPF_SCOPE, RSVPF_STYLE, RSVPF_FLOWSPEC, RSVPF_FILTER_SPEC, RSVPF_SENDER, RSVPF_TSPEC, RSVPF_ADSPEC, RSVPF_POLICY, RSVPF_CONFIRM, RSVPF_LABEL, RSVPF_DUMMY_2, RSVPF_DUMMY_3, RSVPF_LABEL_REQUEST, RSVPF_EXPLICIT_ROUTE, RSVPF_RECORD_ROUTE, RSVPF_HELLO_OBJ, RSVPF_MESSAGE_ID, RSVPF_MESSAGE_ID_ACK, RSVPF_MESSAGE_ID_LIST, RSVPF_RECOVERY_LABEL, RSVPF_UPSTREAM_LABEL, RSVPF_LABEL_SET, RSVPF_PROTECTION, RSVPF_SUGGESTED_LABEL, RSVPF_ACCEPTABLE_LABEL_SET, RSVPF_RESTART_CAP, RSVPF_SESSION_ATTRIBUTE, RSVPF_DCLASS, RSVPF_LSP_TUNNEL_IF_ID, RSVPF_NOTIFY_REQUEST, RSVPF_ADMIN_STATUS, RSVPF_UNKNOWN_OBJ, /* Session object */ RSVPF_SESSION_IP, RSVPF_SESSION_PROTO, RSVPF_SESSION_PORT, RSVPF_SESSION_TUNNEL_ID, RSVPF_SESSION_EXT_TUNNEL_ID, /* Sender template */ RSVPF_SENDER_IP, RSVPF_SENDER_PORT, RSVPF_SENDER_LSP_ID, /* Sentinel */ RSVPF_MAX }; static int rsvp_filter[RSVPF_MAX]; static hf_register_info rsvpf_info[] = { /* Message type number */ {&rsvp_filter[RSVPF_MSG], { "Message Type", "rsvp.msg", FT_UINT8, BASE_DEC, VALS(message_type_vals), 0x0, "", HFILL }}, /* Message type shorthands */ {&rsvp_filter[RSVPF_PATH], { "Path Message", "rsvp.path", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_HELLO], { "HELLO Message", "rsvp.hello", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RESV], { "Resv Message", "rsvp.resv", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_PATHERR], { "Path Error Message", "rsvp.perr", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RESVERR], { "Resv Error Message", "rsvp.rerr", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_PATHTEAR], { "Path Tear Message", "rsvp.ptear", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RESVTEAR], { "Resv Tear Message", "rsvp.rtear", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RCONFIRM], { "Resv Confirm Message", "rsvp.resvconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RTEARCONFIRM], { "Resv Tear Confirm Message", "rsvp.rtearconf", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "", HFILL }}, /* Object class */ {&rsvp_filter[RSVPF_OBJECT], { "Object class", "rsvp.object", FT_UINT8, BASE_DEC, VALS(rsvp_class_vals), 0x0, "", HFILL }}, /* Object present shorthands */ {&rsvp_filter[RSVPF_SESSION], { "SESSION", "rsvp.session", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_HOP], { "HOP", "rsvp.hop", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_HELLO_OBJ], { "HELLO Request/Ack", "rsvp.hello_obj", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_INTEGRITY], { "INTEGRITY", "rsvp.integrity", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_TIME_VALUES], { "TIME VALUES", "rsvp.time", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_ERROR], { "ERROR", "rsvp.error", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SCOPE], { "SCOPE", "rsvp.scope", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_STYLE], { "STYLE", "rsvp.style", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_FLOWSPEC], { "FLOWSPEC", "rsvp.flowspec", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_FILTER_SPEC], { "FILTERSPEC", "rsvp.filter", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SENDER], { "SENDER TEMPLATE", "rsvp.sender", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_TSPEC], { "SENDER TSPEC", "rsvp.tspec", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_ADSPEC], { "ADSPEC", "rsvp.adspec", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_POLICY], { "POLICY", "rsvp.policy", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_CONFIRM], { "CONFIRM", "rsvp.confirm", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_LABEL], { "LABEL", "rsvp.label", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RECOVERY_LABEL], { "RECOVERY LABEL", "rsvp.recovery_label", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_UPSTREAM_LABEL], { "UPSTREAM LABEL", "rsvp.upstream_label", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SUGGESTED_LABEL], { "SUGGESTED LABEL", "rsvp.suggested_label", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_LABEL_SET], { "RESTRICTED LABEL SET", "rsvp.label_set", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_ACCEPTABLE_LABEL_SET], { "ACCEPTABLE LABEL SET", "rsvp.acceptable_label_set", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_PROTECTION], { "PROTECTION", "rsvp.protection", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RESTART_CAP], { "RESTART CAPABILITY", "rsvp.restart", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_LABEL_REQUEST], { "LABEL REQUEST", "rsvp.label_request", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SESSION_ATTRIBUTE], { "SESSION ATTRIBUTE", "rsvp.session_attribute", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_EXPLICIT_ROUTE], { "EXPLICIT ROUTE", "rsvp.explicit_route", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_RECORD_ROUTE], { "RECORD ROUTE", "rsvp.record_route", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_MESSAGE_ID], { "MESSAGE-ID", "rsvp.msgid", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_MESSAGE_ID_ACK], { "MESSAGE-ID ACK", "rsvp.ack", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_MESSAGE_ID_LIST], { "MESSAGE-ID LIST", "rsvp.msgid_list", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_HELLO_OBJ], { "HELLO", "rsvp.hello", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_DCLASS], { "DCLASS", "rsvp.dclass", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_LSP_TUNNEL_IF_ID], { "LSP INTERFACE-ID", "rsvp.lsp_tunnel_if_id", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_ADMIN_STATUS], { "ADMIN STATUS", "rsvp.admin_status", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_NOTIFY_REQUEST], { "NOTIFY REQUEST", "rsvp.notify_request", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_UNKNOWN_OBJ], { "Unknown object", "rsvp.obj_unknown", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }}, /* Session fields */ {&rsvp_filter[RSVPF_SESSION_IP], { "Destination address", "rsvp.session.ip", FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SESSION_PORT], { "Port number", "rsvp.session.port", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SESSION_PROTO], { "Protocol", "rsvp.session.proto", FT_UINT8, BASE_DEC, VALS(proto_vals), 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SESSION_TUNNEL_ID], { "Tunnel ID", "rsvp.session.tunnel_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID], { "Extended tunnel ID", "rsvp.session.ext_tunnel_id", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}, /* Sender template/Filterspec fields */ {&rsvp_filter[RSVPF_SENDER_IP], { "Sender IPv4 address", "rsvp.sender.ip", FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SENDER_PORT], { "Sender port number", "rsvp.sender.port", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, {&rsvp_filter[RSVPF_SENDER_LSP_ID], { "Sender LSP ID", "rsvp.sender.lsp_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }} }; static inline int rsvp_class_to_filter_num(int classnum) { switch(classnum) { case RSVP_CLASS_SESSION : case RSVP_CLASS_HOP : case RSVP_CLASS_INTEGRITY : case RSVP_CLASS_TIME_VALUES : case RSVP_CLASS_ERROR : case RSVP_CLASS_SCOPE : case RSVP_CLASS_STYLE : case RSVP_CLASS_FLOWSPEC : case RSVP_CLASS_FILTER_SPEC : case RSVP_CLASS_SENDER_TEMPLATE : case RSVP_CLASS_SENDER_TSPEC : case RSVP_CLASS_ADSPEC : case RSVP_CLASS_POLICY : case RSVP_CLASS_CONFIRM : case RSVP_CLASS_LABEL : case RSVP_CLASS_LABEL_REQUEST : case RSVP_CLASS_HELLO : case RSVP_CLASS_EXPLICIT_ROUTE : case RSVP_CLASS_RECORD_ROUTE : case RSVP_CLASS_MESSAGE_ID : case RSVP_CLASS_MESSAGE_ID_ACK : case RSVP_CLASS_MESSAGE_ID_LIST : return classnum + RSVPF_OBJECT; break; case RSVP_CLASS_RECOVERY_LABEL : case RSVP_CLASS_UPSTREAM_LABEL : case RSVP_CLASS_LABEL_SET : case RSVP_CLASS_PROTECTION : return RSVPF_RECOVERY_LABEL + (classnum - RSVP_CLASS_RECOVERY_LABEL); case RSVP_CLASS_SUGGESTED_LABEL : case RSVP_CLASS_ACCEPTABLE_LABEL_SET : case RSVP_CLASS_RESTART_CAP : return RSVPF_SUGGESTED_LABEL + (classnum - RSVP_CLASS_SUGGESTED_LABEL); case RSVP_CLASS_NOTIFY_REQUEST : case RSVP_CLASS_ADMIN_STATUS : return RSVPF_NOTIFY_REQUEST + (classnum - RSVP_CLASS_NOTIFY_REQUEST); case RSVP_CLASS_SESSION_ATTRIBUTE : return RSVPF_SESSION_ATTRIBUTE; case RSVP_CLASS_DCLASS : return RSVPF_DCLASS; case RSVP_CLASS_LSP_TUNNEL_IF_ID : return RSVPF_LSP_TUNNEL_IF_ID; default: return RSVPF_UNKNOWN_OBJ; } } static void find_rsvp_session_tempfilt(tvbuff_t *tvb, int hdr_offset, int *session_offp, int *tempfilt_offp) { int s_off = 0, t_off = 0; int len, off; if (!tvb) goto done; len = tvb_get_ntohs(tvb, hdr_offset+6) + hdr_offset; off = hdr_offset + 8; for (off = hdr_offset + 8; off < len; off += tvb_get_ntohs(tvb, off)) { switch(tvb_get_guint8(tvb, off+2)) { case RSVP_CLASS_SESSION: s_off = off; break; case RSVP_CLASS_SENDER_TEMPLATE: case RSVP_CLASS_FILTER_SPEC: t_off = off; break; default: break; } } done: if (session_offp) *session_offp = s_off; if (tempfilt_offp) *tempfilt_offp = t_off; } static char *summary_session (tvbuff_t *tvb, int offset) { static char buf[80]; switch(tvb_get_guint8(tvb, offset+3)) { case 1: snprintf(buf, 80, "SESSION: IPv4, Destination %s, Protocol %d, Port %d. ", ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), tvb_get_guint8(tvb, offset+8), tvb_get_ntohs(tvb, offset+10)); break; case 7: snprintf(buf, 80, "SESSION: IPv4-LSP, Destination %s, Tunnel ID %d, Ext ID %0x. ", ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), tvb_get_ntohs(tvb, offset+10), tvb_get_ntohl(tvb, offset+12)); break; default: snprintf(buf, 80, "SESSION: Type %d. ", tvb_get_guint8(tvb, offset+3)); } return buf; } static char *summary_template (tvbuff_t *tvb, int offset) { static char buf[80]; char *objtype; if (tvb_get_guint8(tvb, offset+2) == RSVP_CLASS_FILTER_SPEC) objtype = "FILTERSPEC"; else objtype = "SENDER TEMPLATE"; switch(tvb_get_guint8(tvb, offset+3)) { case 1: snprintf(buf, 80, "%s: IPv4, Sender %s, Port %d. ", objtype, ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), tvb_get_ntohs(tvb, offset+10)); break; case 7: snprintf(buf, 80, "%s: IPv4-LSP, Tunnel Source: %s, LSP ID: %d. ", objtype, ip_to_str(tvb_get_ptr(tvb, offset+4, 4)), tvb_get_ntohs(tvb, offset+10)); break; default: snprintf(buf, 80, "%s: Type %d. ", objtype, tvb_get_guint8(tvb, offset+3)); } return buf; } static void dissect_rsvp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; proto_tree *rsvp_tree = NULL, *ti, *ti2; proto_tree *rsvp_header_tree; proto_tree *rsvp_object_tree; proto_tree *rsvp_sa_flags_tree; proto_tree *rsvp_ero_subtree; proto_tree *rsvp_admin_subtree; proto_tree *rsvp_hop_subtree; guint8 ver_flags; guint8 message_type; guint16 cksum, computed_cksum; vec_t cksum_vec[1]; int i, j, k, l, len; int msg_length; int obj_length; int mylen; int offset2; int session_off, tempfilt_off; if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "RSVP"); if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO); ver_flags = tvb_get_guint8(tvb, offset+0); message_type = tvb_get_guint8(tvb, offset+1); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(message_type, message_type_vals, "Unknown (%u). ")); find_rsvp_session_tempfilt(tvb, offset, &session_off, &tempfilt_off); if (session_off) col_append_str(pinfo->cinfo, COL_INFO, summary_session(tvb, session_off)); if (tempfilt_off) col_append_str(pinfo->cinfo, COL_INFO, summary_template(tvb, tempfilt_off)); } if (tree) { msg_length = tvb_get_ntohs(tvb, offset+6); ti = proto_tree_add_item(tree, proto_rsvp, tvb, offset, msg_length, FALSE); rsvp_tree = proto_item_add_subtree(ti, ett_rsvp); ti = proto_tree_add_text(rsvp_tree, tvb, offset, 8, "RSVP Header. %s", val_to_str(message_type, message_type_vals, "Unknown Message (%u). ")); rsvp_header_tree = proto_item_add_subtree(ti, ett_rsvp_hdr); proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "RSVP Version: %u", (ver_flags & 0xf0)>>4); proto_tree_add_text(rsvp_header_tree, tvb, offset, 1, "Flags: %02x", ver_flags & 0xf); proto_tree_add_uint(rsvp_header_tree, rsvp_filter[RSVPF_MSG], tvb, offset+1, 1, message_type); if (message_type <= RSVPF_RTEARCONFIRM && message_type != RSVPF_JUNK_MSG8 && message_type != RSVPF_JUNK_MSG9 ) { proto_tree_add_boolean_hidden(rsvp_header_tree, rsvp_filter[RSVPF_MSG + message_type], tvb, offset+1, 1, 1); } cksum = tvb_get_ntohs(tvb, offset+2); if (!pinfo->fragmented && (int) tvb_length(tvb) >= msg_length) { /* The packet isn't part of a fragmented datagram and isn't truncated, so we can checksum it. */ cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, msg_length); cksum_vec[0].len = msg_length; computed_cksum = in_cksum(&cksum_vec[0], 1); if (computed_cksum == 0) { proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2, "Message Checksum: 0x%04x (correct)", cksum); } else { proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2, "Message Checksum: 0x%04x (incorrect, should be 0x%04x)", cksum, in_cksum_shouldbe(cksum, computed_cksum)); } } else { proto_tree_add_text(rsvp_header_tree, tvb, offset+2, 2, "Message Checksum: 0x%04x", cksum); } proto_tree_add_text(rsvp_header_tree, tvb, offset+4, 1, "Sending TTL: %u", tvb_get_guint8(tvb, offset+4)); proto_tree_add_text(rsvp_header_tree, tvb, offset+6, 2, "Message length: %u", msg_length); offset += 8; len = 8; while (len < msg_length) { guint8 class; guint8 type; char *object_type; obj_length = tvb_get_ntohs(tvb, offset); class = tvb_get_guint8(tvb, offset+2); type = tvb_get_guint8(tvb, offset+3); object_type = val_to_str(class, rsvp_class_vals, "Unknown"); proto_tree_add_uint_hidden(rsvp_tree, rsvp_filter[RSVPF_OBJECT], tvb, offset, obj_length, class); ti = proto_tree_add_item(rsvp_tree, rsvp_filter[rsvp_class_to_filter_num(class)], tvb, offset, obj_length, FALSE); offset2 = offset+4; switch(class) { case RSVP_CLASS_SESSION : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_session); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; proto_item_set_text(ti, summary_session(tvb, offset)); switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_IP], tvb, offset2, 4, FALSE); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_PROTO], tvb, offset2+4, 1, FALSE); proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1, "Flags: %x", tvb_get_guint8(tvb, offset2+5)); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_PORT], tvb, offset2+6, 2, FALSE); break; } case 2: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 - IPv6"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, "Destination address: %s", ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1, "Protocol: %u", tvb_get_guint8(tvb, offset2+16)); proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1, "Flags: %x", tvb_get_guint8(tvb, offset2+17)); proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2, "Destination port: %u", tvb_get_ntohs(tvb, offset2+18)); break; } case 7: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 7 - IPv4 LSP"); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_IP], tvb, offset2, 4, FALSE); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_TUNNEL_ID], tvb, offset2+6, 2, FALSE); proto_tree_add_text(rsvp_object_tree, tvb, offset2+8, 4, "Extended Tunnel ID: %u (%s)", tvb_get_ntohl(tvb, offset2+8), ip_to_str(tvb_get_ptr(tvb, offset2+8, 4))); proto_tree_add_item_hidden(rsvp_object_tree, rsvp_filter[RSVPF_SESSION_EXT_TUNNEL_ID], tvb, offset2+8, 4, FALSE); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); } } break; case RSVP_CLASS_HOP : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_hop); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Neighbor address: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4, "Logical interface: %u", tvb_get_ntohl(tvb, offset2+4)); proto_item_set_text(ti, "HOP: IPv4, %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); break; } case 2: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 - IPv6"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, "Neighbor address: %s", ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 4, "Logical interface: 0x%08x", tvb_get_ntohl(tvb, offset2+16)); break; } case 3: { guint16 tlv_off; guint16 tlv_type; guint16 tlv_len; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 3 - IPv4 Out-Of-Band"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Neighbor address: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4, "Logical interface: %u", tvb_get_ntohl(tvb, offset2+4)); for (tlv_off = 0; tlv_off < mylen - 8; ) { tlv_type = tvb_get_ntohs(tvb, offset2+8+tlv_off); tlv_len = tvb_get_ntohs(tvb, offset2+8+tlv_off+2); switch(tlv_type) { case 1: ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+8+tlv_off, 8, "IPv4 TLV - %s", ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4))); rsvp_hop_subtree = proto_item_add_subtree(ti2, ett_rsvp_hop_subobj); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off, 2, "Type: 1 (IPv4)"); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+2, 2, "Length: %u", tvb_get_ntohs(tvb, offset2+8+tlv_off+2)); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+4, 4, "IPv4 address: %s", ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4))); proto_item_set_text(ti, "HOP: Out-of-band. Control IPv4: %s. Data IPv4: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4)), ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4))); break; case 3: ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2+8+tlv_off, 12, "Interface-Index TLV - %s, %d", ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)), tvb_get_ntohl(tvb, offset2+8+tlv_off+8)); rsvp_hop_subtree = proto_item_add_subtree(ti2, ett_rsvp_hop_subobj); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off, 2, "Type: 3 (Interface Index)"); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+2, 2, "Length: %u", tvb_get_ntohs(tvb, offset2+8+tlv_off+2)); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+4, 4, "IPv4 address: %s", ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4))); proto_tree_add_text(rsvp_hop_subtree, tvb, offset2+8+tlv_off+8, 4, "Interface-ID: %d", tvb_get_ntohl(tvb, offset2+8+tlv_off+8)); proto_item_set_text(ti, "HOP: Out-of-band. Control IPv4: %s. Data If-Index: %s, %d", ip_to_str(tvb_get_ptr(tvb, offset2, 4)), ip_to_str(tvb_get_ptr(tvb, offset2+8+tlv_off+4, 4)), tvb_get_ntohl(tvb, offset2+8+tlv_off+8)); break; default: proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4, "Logical interface: %u", tvb_get_ntohl(tvb, offset2+4)); } tlv_off += tlv_len; } break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); } } break; case RSVP_CLASS_TIME_VALUES : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_time_values); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Refresh interval: %u ms (%u seconds)", tvb_get_ntohl(tvb, offset2), tvb_get_ntohl(tvb, offset2)/1000); proto_item_set_text(ti, "TIME VALUES: %d ms", tvb_get_ntohl(tvb, offset2)); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; } } break; case RSVP_CLASS_ERROR : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_error); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { guint8 error_code; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Error node: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 1, "Flags: 0x%02x", tvb_get_guint8(tvb, offset2+4)); error_code = tvb_get_guint8(tvb, offset2+5); proto_tree_add_text(rsvp_object_tree, tvb, offset2+5, 1, "Error code: %u - %s", error_code, val_to_str(error_code, rsvp_error_vals, "Unknown (%d)")); proto_tree_add_text(rsvp_object_tree, tvb, offset2+6, 2, "Error value: %u", tvb_get_ntohs(tvb, offset2+6)); proto_item_set_text(ti, "ERROR: IPv4, Error code: %s, Value: %d, Error Node: %s", val_to_str(error_code, rsvp_error_vals, "Unknown (%d)"), tvb_get_ntohs(tvb, offset2+6), ip_to_str(tvb_get_ptr(tvb, offset2, 4))); break; } case 2: { guint8 error_code; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 - IPv6"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, "Error node: %s", ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+16, 1, "Flags: 0x%02x", tvb_get_guint8(tvb, offset2+16)); error_code = tvb_get_guint8(tvb, offset2+17); proto_tree_add_text(rsvp_object_tree, tvb, offset2+17, 1, "Error code: %u - %s", error_code, val_to_str(error_code, rsvp_error_vals, "Unknown")); proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2, "Error value: %u", tvb_get_ntohs(tvb, offset2+18)); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); } } break; case RSVP_CLASS_SCOPE : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_scope); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); while (mylen > 0) { proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "IPv4 Address: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); offset2 += 4; mylen -= 4; } break; } case 2: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 - IPv6"); while (mylen > 0) { proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, "IPv6 Address: %s", ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16))); offset2 += 16; mylen -= 16; } break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); } } break; case RSVP_CLASS_STYLE : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_style); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { guint32 style; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Flags: 0x%02x", tvb_get_guint8(tvb, offset2)); style = tvb_get_ntoh24(tvb, offset2+1); proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 3, "Style: 0x%06X - %s", style, val_to_str(style, style_vals, "Unknown")); proto_item_set_text(ti, "STYLE: %s (%d)", val_to_str(style, style_vals, "Unknown"), style); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; } } break; case RSVP_CLASS_CONFIRM : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_confirm); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Receiver address: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); proto_item_set_text(ti, "CONFIRM: Receiver %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); break; } case 2: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 - IPv6"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, "Receiver address: %s", ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16))); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); } } break; case RSVP_CLASS_SENDER_TEMPLATE : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_template); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); goto common_template; case RSVP_CLASS_FILTER_SPEC : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_filter_spec); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); common_template: mylen = obj_length - 4; proto_item_set_text(ti, summary_template(tvb, offset)); switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SENDER_IP], tvb, offset2, 4, FALSE); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SENDER_PORT], tvb, offset2+6, 2, FALSE); break; } case 2: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 - IPv6"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 16, "Source address: %s", ip6_to_str((struct e_in6_addr *)tvb_get_ptr(tvb, offset2, 16))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+18, 2, "Source port: %u", tvb_get_ntohs(tvb, offset2+18)); break; } case 7: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 7 - IPv4 LSP"); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SENDER_IP], tvb, offset2, 4, FALSE); proto_tree_add_item(rsvp_object_tree, rsvp_filter[RSVPF_SENDER_LSP_ID], tvb, offset2+6, 2, FALSE); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); } } break; case RSVP_CLASS_SENDER_TSPEC : { proto_tree *tspec_tree; rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_sender_tspec); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Message format version: %u", tvb_get_guint8(tvb, offset2)>>4); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "Data length: %u words, not including header", tvb_get_ntohs(tvb, offset2+2)); mylen -= 4; offset2 += 4; proto_item_set_text(ti, "SENDER TSPEC: "); while (mylen > 0) { guint8 service_num; guint8 param_id; guint16 param_len; guint16 param_len_processed; guint16 length; service_num = tvb_get_guint8(tvb, offset2); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Service header: %u - %s", service_num, val_to_str(service_num, qos_vals, "Unknown")); length = tvb_get_ntohs(tvb, offset2+2); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "Length of service %u data: %u words, " "not including header", service_num, length); mylen -= 4; offset2 += 4; /* Process all known service headers as a set of parameters */ param_len_processed = 0; while (param_len_processed < length) { param_id = tvb_get_guint8(tvb, offset2); param_len = tvb_get_ntohs(tvb, offset2+2) + 1; switch(param_id) { case 127: /* Token Bucket */ ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Token Bucket TSpec: "); tspec_tree = proto_item_add_subtree(ti2, ett_rsvp_sender_tspec_subtree); proto_tree_add_text(tspec_tree, tvb, offset2, 1, "Parameter %u - %s", param_id, val_to_str(param_id, svc_vals, "Unknown")); proto_tree_add_text(tspec_tree, tvb, offset2+1, 1, "Parameter %u flags: 0x%02x", param_id, tvb_get_guint8(tvb, offset2+1)); proto_tree_add_text(tspec_tree, tvb, offset2+2, 2, "Parameter %u data length: %u words, " "not including header", param_id, tvb_get_ntohs(tvb, offset2+2)); proto_tree_add_text(tspec_tree, tvb, offset2+4, 4, "Token bucket rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+4)); proto_tree_add_text(tspec_tree, tvb, offset2+8, 4, "Token bucket size: %.10g", tvb_get_ntohieee_float(tvb, offset2+8)); proto_tree_add_text(tspec_tree, tvb, offset2+12, 4, "Peak data rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+12)); proto_tree_add_text(tspec_tree, tvb, offset2+16, 4, "Minimum policed unit [m]: %u", tvb_get_ntohl(tvb, offset2+16)); proto_tree_add_text(tspec_tree, tvb, offset2+20, 4, "Maximum packet size [M]: %u", tvb_get_ntohl(tvb, offset2+20)); proto_item_append_text(ti, "Token Bucket, %.10g bytes/sec. ", tvb_get_ntohieee_float(tvb, offset2+4)); proto_item_append_text(ti2, "Rate=%.10g Burst=%.10g Peak=%.10g m=%u M=%u", tvb_get_ntohieee_float(tvb, offset2+4), tvb_get_ntohieee_float(tvb, offset2+8), tvb_get_ntohieee_float(tvb, offset2+12), tvb_get_ntohl(tvb, offset2+16), tvb_get_ntohl(tvb, offset2+20)); break; case 128: /* Null Service (RFC2997) */ ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Null Service TSpec: "); tspec_tree = proto_item_add_subtree(ti2, ett_rsvp_sender_tspec_subtree); proto_tree_add_text(tspec_tree, tvb, offset2, 1, "Parameter %u - %s", param_id, val_to_str(param_id, svc_vals, "Unknown")); proto_tree_add_text(tspec_tree, tvb, offset2+1, 1, "Parameter %u flags: %x", param_id, tvb_get_guint8(tvb, offset2+1)); proto_tree_add_text(tspec_tree, tvb, offset2+2, 2, "Parameter %u data length: %u words, " "not including header", param_id, tvb_get_ntohs(tvb, offset2+2)); proto_tree_add_text(tspec_tree, tvb, offset2+4, 4, "Maximum packet size [M]: %u", tvb_get_ntohl(tvb, offset2+4)); proto_item_append_text(ti, "Null Service. M=%u", tvb_get_ntohl(tvb, offset2+4)); proto_item_append_text(ti2, "Max pkt size=%u", tvb_get_ntohl(tvb, offset2+4)); break; case 126: /* Compression hint (RFC3006) */ ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Compression Hint: "); tspec_tree = proto_item_add_subtree(ti2, ett_rsvp_sender_tspec_subtree); proto_tree_add_text(tspec_tree, tvb, offset2, 1, "Parameter %u - %s", param_id, val_to_str(param_id, svc_vals, "Unknown")); proto_tree_add_text(tspec_tree, tvb, offset2+1, 1, "Parameter %u flags: %x", param_id, tvb_get_guint8(tvb, offset2+1)); proto_tree_add_text(tspec_tree, tvb, offset2+2, 2, "Parameter %u data length: %u words, " "not including header", param_id, tvb_get_ntohs(tvb, offset2+2)); proto_tree_add_text(tspec_tree, tvb, offset2+4, 4, "Hint: %u", tvb_get_ntohl(tvb, offset2+4)); proto_tree_add_text(tspec_tree, tvb, offset2+4, 4, "Compression Factor: %u", tvb_get_ntohl(tvb, offset2+8)); proto_item_append_text(ti, "Compression Hint. Hint=%u, Factor=%u", tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8)); proto_item_append_text(ti2, "Hint=%u, Factor=%u", tvb_get_ntohl(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8)); break; default: proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Unknown parameter %d, %d words", param_id, param_len); break; } param_len_processed += param_len; offset2 += param_len*4; } /* offset2 += length*4; */ mylen -= length*4; } break; } case RSVP_CLASS_FLOWSPEC : { proto_tree *flowspec_tree; rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_flowspec); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Message format version: %u", tvb_get_guint8(tvb, offset2)>>4); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "Data length: %u words, not including header", tvb_get_ntohs(tvb, offset2+2)); proto_item_set_text(ti, "FLOWSPEC: "); mylen -= 4; offset2+= 4; while (mylen > 0) { guint8 service_num; guint16 length; guint8 param_id; guint16 param_len; guint16 param_len_processed; service_num = tvb_get_guint8(tvb, offset2); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Service header: %u - %s", service_num, val_to_str(service_num, intsrv_services_str, "Unknown")); length = tvb_get_ntohs(tvb, offset2+2); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "Length of service %u data: %u words, " "not including header", service_num, length); mylen -= 4; offset2 += 4; proto_item_append_text(ti, "%s: ", val_to_str(service_num, intsrv_services_str, "Unknown (%d)")); /* Process all known service headers as a set of parameters */ param_len_processed = 0; while (param_len_processed < length) { param_id = tvb_get_guint8(tvb, offset2); param_len = tvb_get_ntohs(tvb, offset2+2) + 1; switch(param_id) { case 127: /* Token Bucket */ ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Token Bucket: "); flowspec_tree = proto_item_add_subtree(ti2, ett_rsvp_flowspec_subtree); proto_tree_add_text(flowspec_tree, tvb, offset2, 1, "Parameter %u - %s", param_id, val_to_str(param_id, svc_vals, "Unknown")); proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1, "Parameter %u flags: 0x%02x", param_id, tvb_get_guint8(tvb, offset2+1)); proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2, "Parameter %u data length: %u words, " "not including header", param_id, tvb_get_ntohs(tvb, offset2+2)); proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4, "Token bucket rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+4)); proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "Token bucket size: %.10g", tvb_get_ntohieee_float(tvb, offset2+8)); proto_tree_add_text(flowspec_tree, tvb, offset2+12, 4, "Peak data rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+12)); proto_tree_add_text(flowspec_tree, tvb, offset2+16, 4, "Minimum policed unit [m]: %u", tvb_get_ntohl(tvb, offset2+16)); proto_tree_add_text(flowspec_tree, tvb, offset2+20, 4, "Maximum packet size [M]: %u", tvb_get_ntohl(tvb, offset2+20)); proto_item_append_text(ti, "Token Bucket, %.10g bytes/sec. ", tvb_get_ntohieee_float(tvb, offset2+4)); proto_item_append_text(ti2, "Rate=%.10g Burst=%.10g Peak=%.10g m=%u M=%u", tvb_get_ntohieee_float(tvb, offset2+4), tvb_get_ntohieee_float(tvb, offset2+8), tvb_get_ntohieee_float(tvb, offset2+12), tvb_get_ntohl(tvb, offset2+16), tvb_get_ntohl(tvb, offset2+20)); break; case 130: /* Guaranteed-rate RSpec */ ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Guaranteed-Rate RSpec: "); flowspec_tree = proto_item_add_subtree(ti2, ett_rsvp_flowspec_subtree); proto_tree_add_text(flowspec_tree, tvb, offset2, 1, "Parameter %u - %s", param_id, val_to_str(param_id, svc_vals, "Unknown")); proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1, "Parameter %u flags: %x", param_id, tvb_get_guint8(tvb, offset2+1)); proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2, "Parameter %u data length: %u words, " "not including header", param_id, tvb_get_ntohs(tvb, offset2+2)); proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4, "Rate: %.10g", tvb_get_ntohieee_float(tvb, offset2+4)); proto_tree_add_text(flowspec_tree, tvb, offset2+8, 4, "Slack term: %u", tvb_get_ntohl(tvb, offset2+8)); proto_item_append_text(ti, "RSpec, %.10g bytes/sec. ", tvb_get_ntohieee_float(tvb, offset2+4)); proto_item_append_text(ti2, "R=%.10g, s=%u", tvb_get_ntohieee_float(tvb, offset2+4), tvb_get_ntohl(tvb, offset2+8)); break; case 128: /* Null Service (RFC2997) */ ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Null Service Flowspec: "); flowspec_tree = proto_item_add_subtree(ti2, ett_rsvp_flowspec_subtree); proto_tree_add_text(flowspec_tree, tvb, offset2, 1, "Parameter %u - %s", param_id, val_to_str(param_id, svc_vals, "Unknown")); proto_tree_add_text(flowspec_tree, tvb, offset2+1, 1, "Parameter %u flags: %x", param_id, tvb_get_guint8(tvb, offset2+1)); proto_tree_add_text(flowspec_tree, tvb, offset2+2, 2, "Parameter %u data length: %u words, " "not including header", param_id, tvb_get_ntohs(tvb, offset2+2)); proto_tree_add_text(flowspec_tree, tvb, offset2+4, 4, "Maximum packet size [M]: %u", tvb_get_ntohl(tvb, offset2+4)); proto_item_append_text(ti, "Null Service. M=%u", tvb_get_ntohl(tvb, offset2+4)); proto_item_append_text(ti2, "Max pkt size=%u", tvb_get_ntohl(tvb, offset2+4)); break; default: proto_tree_add_text(rsvp_object_tree, tvb, offset2, param_len*4, "Unknown parameter %d, %d words", param_id, param_len); break; } param_len_processed += param_len; offset2 += param_len * 4; } /* offset2 += length*4; */ mylen -= length*4; } break; } case RSVP_CLASS_ADSPEC : { proto_tree *adspec_tree; rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_adspec); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "Message format version: %u", tvb_get_guint8(tvb, offset2)>>4); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "Data length: %u words, not including header", tvb_get_ntohs(tvb, offset2+2)); mylen -= 4; offset2 += 4; while (mylen > 0) { guint8 service_num; guint8 break_bit; guint16 length; char *str; service_num = tvb_get_guint8(tvb, offset2); str = val_to_str(service_num, intsrv_services_str, "Unknown"); break_bit = tvb_get_guint8(tvb, offset2+1); length = tvb_get_ntohs(tvb, offset2+2); ti = proto_tree_add_text(rsvp_object_tree, tvb, offset2, (length+1)*4, str); adspec_tree = proto_item_add_subtree(ti, ett_rsvp_adspec_subtree); proto_tree_add_text(adspec_tree, tvb, offset2, 1, "Service header %u - %s", service_num, str); proto_tree_add_text(adspec_tree, tvb, offset2+1, 1, (break_bit&0x80)? "Break bit set":"Break bit not set"); proto_tree_add_text(adspec_tree, tvb, offset2+2, 2, "Data length: %u words, not including header", length); mylen -= 4; offset2 += 4; i = length*4; while (i > 0) { guint8 id; guint16 phdr_length; id = tvb_get_guint8(tvb, offset2); phdr_length = tvb_get_ntohs(tvb, offset2+2); str = match_strval(id, adspec_params); if (str) { switch(id) { case 4: case 8: case 10: case 133: case 134: case 135: case 136: /* 32-bit unsigned integer */ proto_tree_add_text(adspec_tree, tvb, offset2, (phdr_length+1)<<2, "%s - %u (type %u, length %u)", str, tvb_get_ntohl(tvb, offset2+4), id, phdr_length); break; case 6: /* IEEE float */ proto_tree_add_text(adspec_tree, tvb, offset2, (phdr_length+1)<<2, "%s - %.10g (type %u, length %u)", str, tvb_get_ntohieee_float(tvb, offset2+4), id, phdr_length); break; default: proto_tree_add_text(adspec_tree, tvb, offset2, (phdr_length+1)<<2, "%s (type %u, length %u)", str, id, phdr_length); } } else { proto_tree_add_text(adspec_tree, tvb, offset2, (phdr_length+1)<<2, "Unknown (type %u, length %u)", id, phdr_length); } offset2 += (phdr_length+1)<<2; i -= (phdr_length+1)<<2; mylen -= (phdr_length+1)<<2; } } break; } case RSVP_CLASS_INTEGRITY : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_integrity); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); goto default_class; case RSVP_CLASS_POLICY : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_policy); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); goto default_class; case RSVP_CLASS_LABEL_REQUEST : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_label_request); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2); proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1"); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "L3PID: %s (0x%04x)", val_to_str(l3pid, etype_vals, "Unknown"), l3pid); proto_item_set_text(ti, "LABEL REQUEST: %s (0x%04x)", val_to_str(l3pid, etype_vals, "Unknown"), l3pid); break; } case 4: { unsigned short l3pid = tvb_get_ntohs(tvb, offset2+2); unsigned char lsp_enc = tvb_get_guint8(tvb,offset2); proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 4 (Generalized Label Request)"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 1, "LSP Encoding Type: %s", val_to_str(lsp_enc, gmpls_lsp_enc_str, "Unknown (%d)")); proto_tree_add_text(rsvp_object_tree, tvb, offset2+1, 1, "Switching Type: %s", val_to_str(tvb_get_guint8(tvb,offset2+1), gmpls_switching_type_str, "Unknown (%d)")); proto_tree_add_text(rsvp_object_tree, tvb, offset2+2, 2, "G-PID: %s (0x%0x)", val_to_str(l3pid, gmpls_gpid_str, val_to_str(l3pid, etype_vals, "Unknown G-PID(0x%04x)")), l3pid); proto_item_set_text(ti, "LABEL REQUEST: Generalized: LSP Encoding=%s, " "Switching Type=%s, G-PID=%s ", val_to_str(lsp_enc, gmpls_lsp_enc_str, "Unknown (%d)"), val_to_str(tvb_get_guint8(tvb,offset2+1), gmpls_switching_type_str, "Unknown (%d)"), val_to_str(l3pid, gmpls_gpid_str, val_to_str(l3pid, etype_vals, "Unknown (0x%04x)"))); break; } default: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; } } break; case RSVP_CLASS_UPSTREAM_LABEL : case RSVP_CLASS_SUGGESTED_LABEL : case RSVP_CLASS_LABEL : { char *name; name = (class==RSVP_CLASS_SUGGESTED_LABEL ? "SUGGESTED LABEL" : (class==RSVP_CLASS_UPSTREAM_LABEL ? "UPSTREAM LABEL" : "LABEL")); rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_label); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); mylen = obj_length - 4; switch(type) { case 1: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 (Packet Label)"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Label: %u", tvb_get_ntohl(tvb, offset2)); proto_item_set_text(ti, "%s: %d", name, tvb_get_ntohl(tvb, offset2)); break; } case 2: { proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 2 (Generalized Label)"); proto_item_set_text(ti, "%s: Generalized: ", name); for (i = 0; i < mylen; i += 4) { proto_tree_add_text(rsvp_object_tree, tvb, offset2+i, 4, "Generalized Label: %u", tvb_get_ntohl(tvb, offset2+i)); if (i < 16) { proto_item_append_text(ti, "%d%s", tvb_get_ntohl(tvb, offset2+i), i+4>2, mylen==obj_length-4 ? "" : mylen<16 ? ", " : mylen==16 ? ", ..." : ""); } break; default: mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; } break; case RSVP_CLASS_ADMIN_STATUS: { guint32 status; rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_admin_status); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); proto_item_set_text(ti, "ADMIN STATUS: "); switch(type) { case 1: proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1"); status = tvb_get_ntohl(tvb, offset2); ti2 = proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Admin Status: 0x%08x", status); rsvp_admin_subtree = proto_item_add_subtree(ti2, ett_rsvp_admin_status_flags); proto_tree_add_text(rsvp_admin_subtree, tvb, offset2, 1, (status & (1<<31)) ? "R: 1. Reflect" : "R: 0. Do not reflect"); proto_tree_add_text(rsvp_admin_subtree, tvb, offset2+3, 1, (status & (1<<2)) ? "T: 1. Testing" : "T: 0. "); proto_tree_add_text(rsvp_admin_subtree, tvb, offset2+3, 1, (status & (1<<1)) ? "A: 1. Administratively down" : "A: 0. "); proto_tree_add_text(rsvp_admin_subtree, tvb, offset2+3, 1, (status & 1) ? "D: 1. Deletion in progress" : "D: 0. "); proto_item_set_text(ti, "ADMIN-STATUS: %s %s %s %s", (status & (1<<31)) ? "Reflect" : "", (status & (1<<2)) ? "Testing" : "", (status & (1<<1)) ? "Admin-Down" : "", (status & (1<<0)) ? "Deleting" : ""); break; default: mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; } } break; case RSVP_CLASS_LSP_TUNNEL_IF_ID: rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_lsp_tunnel_if_id); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); proto_item_set_text(ti, "LSP INTERFACE-ID: "); switch(type) { case 1: proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: 1 - IPv4"); proto_tree_add_text(rsvp_object_tree, tvb, offset2, 4, "Router ID: %s", ip_to_str(tvb_get_ptr(tvb, offset2, 4))); proto_tree_add_text(rsvp_object_tree, tvb, offset2+4, 4, "Interface ID: %u", tvb_get_ntohl(tvb, offset2+4)); proto_item_set_text(ti, "LSP INTERFACE-ID: IPv4, Router-ID %s, Interface-ID %d", ip_to_str(tvb_get_ptr(tvb, offset2, 4)), tvb_get_ntohl(tvb, offset2+4)); break; default: mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset+3, 1, "C-type: Unknown (%u)", type); proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; } break; default : rsvp_object_tree = proto_item_add_subtree(ti, ett_rsvp_unknown_class); proto_tree_add_text(rsvp_object_tree, tvb, offset, 2, "Length: %u", obj_length); proto_tree_add_text(rsvp_object_tree, tvb, offset+2, 1, "Class number: %u - %s", class, object_type); default_class: mylen = obj_length - 4; proto_tree_add_text(rsvp_object_tree, tvb, offset2, mylen, "Data (%d bytes)", mylen); break; case RSVP_CLASS_NULL : break; } offset += obj_length; len += obj_length; } } } void proto_register_rsvp(void) { static gint *ett[] = { &ett_rsvp, &ett_rsvp_hdr, &ett_rsvp_session, &ett_rsvp_hop, &ett_rsvp_hop_subobj, &ett_rsvp_time_values, &ett_rsvp_error, &ett_rsvp_scope, &ett_rsvp_style, &ett_rsvp_confirm, &ett_rsvp_sender_template, &ett_rsvp_filter_spec, &ett_rsvp_sender_tspec, &ett_rsvp_sender_tspec_subtree, &ett_rsvp_flowspec, &ett_rsvp_flowspec_subtree, &ett_rsvp_adspec, &ett_rsvp_adspec_subtree, &ett_rsvp_integrity, &ett_rsvp_policy, &ett_rsvp_label, &ett_rsvp_label_request, &ett_rsvp_session_attribute, &ett_rsvp_session_attribute_flags, &ett_rsvp_explicit_route, &ett_rsvp_explicit_route_subobj, &ett_rsvp_record_route, &ett_rsvp_record_route_subobj, &ett_rsvp_hello_obj, &ett_rsvp_dclass, &ett_rsvp_lsp_tunnel_if_id, &ett_rsvp_admin_status, &ett_rsvp_admin_status_flags, &ett_rsvp_unknown_class, }; proto_rsvp = proto_register_protocol("Resource ReserVation Protocol (RSVP)", "RSVP", "rsvp"); proto_register_field_array(proto_rsvp, rsvpf_info, array_length(rsvpf_info)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_rsvp(void) { dissector_handle_t rsvp_handle; rsvp_handle = create_dissector_handle(dissect_rsvp, proto_rsvp); dissector_add("ip.proto", IP_PROTO_RSVP, rsvp_handle); }