1a768b36b4
From Marc Petit-Huguenin: - Removed directResponseForwarding. - The certificate_type enum is now defined as RFC 6091's CertificateType so moved the definition to packet-ssl-utils.[ch]. - Fixed invalid values for CERTIFICATE_BY_NODE and CERTIFICATE_BY_USER Kinds. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5967 svn path=/trunk/; revision=37452
2761 lines
114 KiB
C
2761 lines
114 KiB
C
/* packet-reload.c
|
|
* Routines forREsource LOcation And Discovery (RELOAD) Base Protocol
|
|
* Author: Stephane Bryant <sbryant@glycon.org>
|
|
* Copyright 2010 Stonyfish Inc.
|
|
*
|
|
* $Id$
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* 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.
|
|
*
|
|
* Please refer to the following specs for protocol detail:
|
|
* - draft-ietf-p2psip-base-15
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <epan/conversation.h>
|
|
#include <epan/prefs.h>
|
|
#include <epan/reassemble.h>
|
|
#include <epan/expert.h>
|
|
#include <epan/asn1.h>
|
|
#include <epan/dissectors/packet-x509af.h>
|
|
#include <packet-tcp.h>
|
|
#include <packet-ssl-utils.h>
|
|
|
|
/* Initialize the protocol and registered fields */
|
|
static int proto_reload = -1;
|
|
|
|
static gboolean reload_defragment = TRUE;
|
|
static guint reload_nodeid_length = 16;
|
|
|
|
static int hf_reload_response_in = -1;
|
|
static int hf_reload_response_to = -1;
|
|
static int hf_reload_time = -1;
|
|
static int hf_reload_duplicate = -1;
|
|
static int hf_reload_token = -1;
|
|
static int hf_reload_forwarding = -1;
|
|
static int hf_reload_overlay = -1;
|
|
static int hf_reload_configuration_sequence = -1;
|
|
static int hf_reload_version = -1;
|
|
static int hf_reload_ttl = -1;
|
|
static int hf_reload_fragment_flag = -1;
|
|
static int hf_reload_fragment_fragmented = -1;
|
|
static int hf_reload_fragment_last_fragment = -1;
|
|
static int hf_reload_fragment_reserved = -1;
|
|
static int hf_reload_fragment_offset = -1;
|
|
static int hf_reload_length = -1;
|
|
static int hf_reload_trans_id = -1;
|
|
static int hf_reload_max_response_length = -1;
|
|
static int hf_reload_via_list_length = -1;
|
|
static int hf_reload_destination_list_length = -1;
|
|
static int hf_reload_options_length = -1;
|
|
static int hf_reload_via_list = -1;
|
|
static int hf_reload_destination = -1;
|
|
static int hf_reload_destination_compressed = -1;
|
|
static int hf_reload_destination_type = -1;
|
|
static int hf_reload_destination_length = -1;
|
|
static int hf_reload_nodeid = -1;
|
|
static int hf_reload_resource_id = -1;
|
|
static int hf_reload_destination_data_compressed_id = -1;
|
|
static int hf_reload_destination_list = -1;
|
|
static int hf_reload_forwarding_option = -1;
|
|
static int hf_reload_forwarding_option_type = -1;
|
|
static int hf_reload_forwarding_option_flags = -1;
|
|
static int hf_reload_forwarding_option_flag_response_copy = -1;
|
|
static int hf_reload_forwarding_option_flag_destination_critical = -1;
|
|
static int hf_reload_forwarding_option_flag_forward_critical = -1;
|
|
static int hf_reload_forwarding_option_length = -1;
|
|
static int hf_reload_forwarding_option_data = -1;
|
|
static int hf_reload_attachreqans = -1;
|
|
static int hf_reload_ufrag = -1;
|
|
static int hf_reload_password = -1;
|
|
static int hf_reload_role = -1;
|
|
static int hf_reload_sendupdate = -1;
|
|
static int hf_reload_icecandidates = -1;
|
|
static int hf_reload_icecandidates_length = -1;
|
|
static int hf_reload_icecandidate = -1;
|
|
static int hf_reload_icecandidate_srflx_addr = -1;
|
|
static int hf_reload_icecandidate_prflx_addr = -1;
|
|
static int hf_reload_icecandidate_relay_addr = -1;
|
|
static int hf_reload_icecandidate_foundation = -1;
|
|
static int hf_reload_icecandidate_priority = -1;
|
|
static int hf_reload_icecandidate_type = -1;
|
|
static int hf_reload_overlaylink_type = -1;
|
|
static int hf_reload_icecandidate_extensions_length = -1;
|
|
static int hf_reload_iceextension = -1;
|
|
static int hf_reload_iceextension_name = -1;
|
|
static int hf_reload_iceextension_value = -1;
|
|
static int hf_reload_ipaddressport = -1;
|
|
static int hf_reload_ipaddressport_type = -1;
|
|
static int hf_reload_ipaddressport_length = -1;
|
|
static int hf_reload_ipv4addr = -1;
|
|
static int hf_reload_port = -1;
|
|
static int hf_reload_ipv6addr = -1;
|
|
static int hf_reload_message_contents = -1;
|
|
static int hf_reload_message_code = -1;
|
|
static int hf_reload_message_body = -1;
|
|
static int hf_reload_message_extensions_length = -1;
|
|
static int hf_reload_message_extension = -1;
|
|
static int hf_reload_message_extension_type = -1;
|
|
static int hf_reload_message_extension_critical = -1;
|
|
static int hf_reload_message_extension_content = -1;
|
|
static int hf_reload_error_response = -1;
|
|
static int hf_reload_error_response_code = -1;
|
|
static int hf_reload_error_response_info = -1;
|
|
static int hf_reload_security_block = -1;
|
|
static int hf_reload_certificates_length = -1;
|
|
static int hf_reload_certificates = -1;
|
|
static int hf_reload_certificate_type = -1;
|
|
static int hf_reload_certificate = -1;
|
|
static int hf_reload_signature = -1;
|
|
static int hf_reload_hash_algorithm = -1;
|
|
static int hf_reload_signature_algorithm = -1;
|
|
static int hf_reload_signature_identity = -1;
|
|
static int hf_reload_signature_identity_type = -1;
|
|
static int hf_reload_signature_identity_length = -1;
|
|
static int hf_reload_signature_identity_value = -1;
|
|
static int hf_reload_signature_identity_value_certificate_hash = -1;
|
|
static int hf_reload_signature_value = -1;
|
|
static int hf_reload_opaque_length_uint8 = -1;
|
|
static int hf_reload_opaque_length_uint16 = -1;
|
|
static int hf_reload_opaque_length_uint32 = -1;
|
|
static int hf_reload_opaque_data = -1;
|
|
static int hf_reload_routequeryreq = -1;
|
|
static int hf_reload_overlay_specific = -1;
|
|
static int hf_reload_probereq = -1;
|
|
static int hf_reload_probe_information_type = -1;
|
|
static int hf_reload_probe_information = -1;
|
|
static int hf_reload_responsible_set = -1;
|
|
static int hf_reload_num_resources = -1;
|
|
static int hf_reload_uptime = -1;
|
|
static int hf_reload_probeans = -1;
|
|
static int hf_reload_appattach = -1;
|
|
static int hf_reload_application = -1;
|
|
static int hf_reload_ping_response_id = -1;
|
|
static int hf_reload_ping_time = -1;
|
|
static int hf_reload_storeddata = -1;
|
|
static int hf_reload_storeddata_length = -1;
|
|
static int hf_reload_storeddata_storage_time = -1;
|
|
static int hf_reload_storeddata_lifetime = -1;
|
|
static int hf_reload_kinddata = -1;
|
|
static int hf_reload_kindid = -1;
|
|
static int hf_reload_kinddata_generation_counter = -1;
|
|
static int hf_reload_kinddata_values_length = -1;
|
|
static int hf_reload_storereq = -1;
|
|
static int hf_reload_store_replica_num = -1;
|
|
static int hf_reload_store_kind_data_length = -1;
|
|
static int hf_reload_storeans_kind_responses = -1;
|
|
static int hf_reload_storeans_kind_responses_length = -1;
|
|
static int hf_reload_storekindresponse = -1;
|
|
static int hf_reload_storekindresponse_replicas = -1;
|
|
static int hf_reload_storeddataspecifiers = -1;
|
|
static int hf_reload_fetchans = -1;
|
|
static int hf_reload_kind_responses_length = -1;
|
|
static int hf_reload_statans = -1;
|
|
static int hf_reload_findreq_kinds_length = -1;
|
|
static int hf_reload_findkinddata = -1;
|
|
static int hf_reload_findans_results_length = -1;
|
|
static int hf_reload_fragments = -1;
|
|
static int hf_reload_fragment = -1;
|
|
static int hf_reload_fragment_overlap = -1;
|
|
static int hf_reload_fragment_overlap_conflict = -1;
|
|
static int hf_reload_fragment_multiple_tails = -1;
|
|
static int hf_reload_fragment_too_long_fragment = -1;
|
|
static int hf_reload_fragment_error = -1;
|
|
static int hf_reload_fragment_count = -1;
|
|
static int hf_reload_reassembled_in = -1;
|
|
static int hf_reload_reassembled_length = -1;
|
|
static int hf_reload_configupdatereq = -1;
|
|
static int hf_reload_configupdatereq_type = -1;
|
|
static int hf_reload_configupdatereq_length = -1;
|
|
static int hf_reload_configupdatereq_configdata = -1;
|
|
static int hf_reload_configupdatereq_kinds = -1;
|
|
static int hf_reload_padding = -1;
|
|
|
|
|
|
static dissector_handle_t data_handle;
|
|
|
|
/* Structure containing transaction specific information */
|
|
typedef struct _reload_transaction_t {
|
|
guint32 req_frame;
|
|
guint32 rep_frame;
|
|
nstime_t req_time;
|
|
} reload_transaction_t;
|
|
|
|
/* Structure containing conversation specific information */
|
|
typedef struct _reload_conv_info_t {
|
|
emem_tree_t *transaction_pdus;
|
|
} reload_conv_info_t;
|
|
|
|
|
|
/* RELOAD Message classes = (message_code & 0x1) (response = request +1) */
|
|
#define RELOAD_REQUEST 0x0001
|
|
#define RELOAD_RESPONSE 0x0000
|
|
|
|
#define RELOAD_ERROR 0xffff
|
|
|
|
/* RELOAD Message Methods = (message_code +1) & 0xfffe*/
|
|
#define METHOD_INVALID 0
|
|
#define METHOD_PROBE 2
|
|
#define METHOD_ATTACH 4
|
|
#define METHOD_STORE 8
|
|
#define METHOD_FETCH 10
|
|
#define METHOD_REMOVE 12
|
|
#define METHOD_FIND 14
|
|
#define METHOD_JOIN 16
|
|
#define METHOD_LEAVE 18
|
|
#define METHOD_UPDATE 20
|
|
#define METHOD_ROUTEQUERY 22
|
|
#define METHOD_PING 24
|
|
#define METHOD_STAT 26
|
|
#define METHOD_APPATTACH 30
|
|
#define METHOD_CONFIGUPDATE 34
|
|
|
|
|
|
/* RELOAD Destinationtype */
|
|
#define DESTINATIONTYPE_RESERVED 0
|
|
#define DESTINATIONTYPE_NODE 1
|
|
#define DESTINATIONTYPE_RESOURCE 2
|
|
#define DESTINATIONTYPE_COMPRESSED 3
|
|
|
|
/* RELOAD forwarding option type */
|
|
#define OPTIONTYPE_RESERVED 0
|
|
|
|
/* RELOAD CandTypes */
|
|
#define CANDTYPE_RESERVED 0
|
|
#define CANDTYPE_HOST 1
|
|
#define CANDTYPE_SRFLX 2
|
|
#define CANDTYPE_PRFLX 3
|
|
#define CANDTYPE_RELAY 4
|
|
|
|
/* IpAddressPort types */
|
|
#define IPADDRESSPORTTYPE_RESERVED 0
|
|
#define IPADDRESSPORTTYPE_IPV4 1
|
|
#define IPADDRESSPORTTYPE_IPV6 2
|
|
|
|
/* OverlayLink types */
|
|
#define OVERLAYLINKTYPE_RESERVEDOVERLAYLINK 0
|
|
#define OVERLAYLINKTYPE_DTLS_UDP_SR 1
|
|
#define OVERLAYLINKTYPE_DTLS_UDP_SR_NO_ICE 3
|
|
#define OVERLAYLINKTYPE_TLS_TCP_FH_NO_ICE 4
|
|
|
|
#define ERRORCODE_INVALID 0
|
|
#define ERRORCODE_UNUSED 1
|
|
#define ERRORCODE_FORBIDDEN 2
|
|
#define ERRORCODE_NOTFOUND 3
|
|
#define ERRORCODE_REQUESTTIMEOUT 4
|
|
#define ERRORCODE_GENERATIONCOUNTERTOOLOW 5
|
|
#define ERRORCODE_INCOMPATIBLEWITHOVERLAY 6
|
|
#define ERRORCODE_UNSUPPORTEDFORWARDINGOPTION 7
|
|
#define ERRORCODE_DATATOOLARGE 8
|
|
#define ERRORCODE_DATATOOOLD 9
|
|
#define ERRORCODE_TTLEXCEEDED 10
|
|
#define ERRORCODE_MESSAGETOOLARGE 11
|
|
#define ERRORCODE_UNKNOWNKIND 12
|
|
#define ERRORCODE_UNKNOWNEXTENSION 13
|
|
#define ERRORCODE_RESPONSETOOLARGE 14
|
|
#define ERRORCODE_CONFIGTOOOLD 15
|
|
#define ERRORCODE_CONFIGTOONEW 16
|
|
|
|
#define SIGNATUREIDENTITYTYPE_RESERVED 0
|
|
#define SIGNATUREIDENTITYTYPE_CERTHASH 1
|
|
#define SIGNATUREIDENTITYTYPE_CERTHASHNODEID 2
|
|
#define SIGNATUREIDENTITYTYPE_NONE 3
|
|
|
|
/* Probe information type */
|
|
#define PROBEINFORMATIONTYPE_RESERVED 0
|
|
#define PROBEINFORMATIONTYPE_RESPONSIBLESET 1
|
|
#define PROBEINFORMATIONTYPE_NUMRESOURCES 2
|
|
#define PROBEINFORMATIONTYPE_UPTIME 3
|
|
|
|
/* Data Kind ID */
|
|
#define DATAKINDID_INVALID 0
|
|
#define DATAKINDID_TURNSERVICE 2
|
|
#define DATAKINDID_CERTIFICATE_BY_NODE 3
|
|
#define DATAKINDID_CERTIFICATE_BY_USER 16
|
|
|
|
/* Message Extension Type */
|
|
#define MESSAGEEXTENSIONTYPE_RESERVED 0
|
|
|
|
/* Config Update Type */
|
|
#define CONFIGUPDATETYPE_RESERVED 0
|
|
#define CONFIGUPDATETYPE_CONFIG 1
|
|
#define CONFIGUPDATETYPE_KIND 2
|
|
|
|
/* Initialize the subtree pointers */
|
|
static gint ett_reload = -1;
|
|
static gint ett_reload_forwarding = -1;
|
|
static gint ett_reload_message = -1;
|
|
static gint ett_reload_security=-1;
|
|
static gint ett_reload_fragment_flag=-1;
|
|
static gint ett_reload_destination = -1;
|
|
static gint ett_reload_via_list = -1;
|
|
static gint ett_reload_destination_list = -1;
|
|
static gint ett_reload_forwarding_option = -1;
|
|
static gint ett_reload_forwarding_option_flags = -1;
|
|
static gint ett_reload_forwarding_option_directresponseforwarding = -1;
|
|
static gint ett_reload_attachreqans = -1;
|
|
static gint ett_reload_icecandidates = -1;
|
|
static gint ett_reload_icecandidate = -1;
|
|
static gint ett_reload_icecandidate_computed_address = -1;
|
|
static gint ett_reload_iceextension = -1;
|
|
static gint ett_reload_ipaddressport = -1;
|
|
static gint ett_reload_message_contents = -1;
|
|
static gint ett_reload_message_extension = -1;
|
|
static gint ett_reload_error_response = -1;
|
|
static gint ett_reload_security_block = -1;
|
|
static gint ett_reload_certificate = -1;
|
|
static gint ett_reload_signature = -1;
|
|
static gint ett_reload_signature_identity = -1;
|
|
static gint ett_reload_signature_identity_value = -1;
|
|
static gint ett_reload_opaque = -1;
|
|
static gint ett_reload_message_body = -1;
|
|
static gint ett_reload_routequeryreq = -1;
|
|
static gint ett_reload_probereq = -1;
|
|
static gint ett_reload_probe_information = -1;
|
|
static gint ett_reload_probeans = -1;
|
|
static gint ett_reload_appattach = -1;
|
|
static gint ett_reload_storeddata = -1;
|
|
static gint ett_reload_kinddata = -1;
|
|
static gint ett_reload_storereq = -1;
|
|
static gint ett_reload_storeans_kind_responses = -1;
|
|
static gint ett_reload_storekindresponse = -1;
|
|
static gint ett_reload_fetchans = -1;
|
|
static gint ett_reload_statans = -1;
|
|
static gint ett_reload_findkinddata = -1;
|
|
static gint ett_reload_fragments = -1;
|
|
static gint ett_reload_fragment = -1;
|
|
static gint ett_reload_configupdatereq = -1;
|
|
static gint ett_reload_storekindresponse_replicas = -1;
|
|
|
|
static const fragment_items reload_frag_items = {
|
|
&ett_reload_fragment,
|
|
&ett_reload_fragments,
|
|
&hf_reload_fragments,
|
|
&hf_reload_fragment,
|
|
&hf_reload_fragment_overlap,
|
|
&hf_reload_fragment_overlap_conflict,
|
|
&hf_reload_fragment_multiple_tails,
|
|
&hf_reload_fragment_too_long_fragment,
|
|
&hf_reload_fragment_error,
|
|
&hf_reload_fragment_count,
|
|
&hf_reload_reassembled_in,
|
|
&hf_reload_reassembled_length,
|
|
"RELOAD fragments"
|
|
};
|
|
|
|
|
|
#define MSG_LENGH_OFFSET 16
|
|
#define MIN_HDR_LENGTH 38 /* Forwarding header till options_length member (included) */
|
|
|
|
#define RELOAD_TOKEN 0xd2454c4f
|
|
|
|
#define IS_REQUEST(code) (code & 0x0001)
|
|
#define MSGCODE_TO_METHOD(code) ((code + 1) & 0xfffe)
|
|
#define MSGCODE_TO_CLASS(code) (code & 0x0001)
|
|
|
|
|
|
static const value_string classes[] = {
|
|
{RELOAD_REQUEST, "Request"},
|
|
{RELOAD_RESPONSE, "Answer"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string methods[] = {
|
|
{METHOD_INVALID, "invalid"},
|
|
{METHOD_PROBE, "Probe"},
|
|
{METHOD_ATTACH, "Attach"},
|
|
{METHOD_STORE, "Store"},
|
|
{METHOD_FETCH, "Fetch"},
|
|
{METHOD_REMOVE, "Remove"},
|
|
{METHOD_FIND, "Find"},
|
|
{METHOD_JOIN, "Join"},
|
|
{METHOD_LEAVE, "Leave"},
|
|
{METHOD_UPDATE, "Update"},
|
|
{METHOD_ROUTEQUERY, "RouteQuery"},
|
|
{METHOD_PING, "Ping"},
|
|
{METHOD_STAT, "Stat"},
|
|
{METHOD_APPATTACH, "AppAttach"},
|
|
{METHOD_CONFIGUPDATE, "ConfigUpdate"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string destinationtypes[] = {
|
|
{DESTINATIONTYPE_RESERVED, "reserved"},
|
|
{DESTINATIONTYPE_NODE, "Node"},
|
|
{DESTINATIONTYPE_RESOURCE, "Resource"},
|
|
{DESTINATIONTYPE_COMPRESSED, "Compressed"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string forwardingoptiontypes[] = {
|
|
{OPTIONTYPE_RESERVED, "reserved"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string candtypes[] = {
|
|
{CANDTYPE_RESERVED, "reserved"},
|
|
{CANDTYPE_HOST, "host"},
|
|
{CANDTYPE_SRFLX, "srflx"},
|
|
{CANDTYPE_PRFLX, "prflx"},
|
|
{CANDTYPE_RELAY, "relay"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string ipaddressporttypes [] = {
|
|
{IPADDRESSPORTTYPE_RESERVED, "reserved"},
|
|
{IPADDRESSPORTTYPE_IPV4, "IPV4"},
|
|
{IPADDRESSPORTTYPE_IPV6, "IPV6"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string overlaylinktypes [] ={
|
|
{OVERLAYLINKTYPE_RESERVEDOVERLAYLINK, "reserved"},
|
|
{OVERLAYLINKTYPE_DTLS_UDP_SR, "DTLS-UDP-SR"},
|
|
{OVERLAYLINKTYPE_DTLS_UDP_SR_NO_ICE, "DTLS-UDP-SR-NO-ICE"},
|
|
{OVERLAYLINKTYPE_TLS_TCP_FH_NO_ICE, "TLS-TCP-FH-NO-ICE"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string errorcodes [] ={
|
|
{ERRORCODE_INVALID, "invalid"},
|
|
{ERRORCODE_UNUSED, "Unused"},
|
|
{ERRORCODE_FORBIDDEN, "Forbidden"},
|
|
{ERRORCODE_NOTFOUND, "Not Found"},
|
|
{ERRORCODE_REQUESTTIMEOUT, "Request Timeout"},
|
|
{ERRORCODE_GENERATIONCOUNTERTOOLOW, "Generation Counter Too Low"},
|
|
{ERRORCODE_INCOMPATIBLEWITHOVERLAY, "Incompatible with Overlay"},
|
|
{ERRORCODE_UNSUPPORTEDFORWARDINGOPTION, "Unsupported Forwarding Option"},
|
|
{ERRORCODE_DATATOOLARGE, "Data Too Large"},
|
|
{ERRORCODE_DATATOOOLD, "Data Too Old"},
|
|
{ERRORCODE_TTLEXCEEDED, "TTL Exceeded"},
|
|
{ERRORCODE_MESSAGETOOLARGE, "Message Too Large"},
|
|
{ERRORCODE_UNKNOWNKIND, "Unknown Kind"},
|
|
{ERRORCODE_UNKNOWNEXTENSION, "Unknown Extension"},
|
|
{ERRORCODE_RESPONSETOOLARGE, "Response Too Large"},
|
|
{ERRORCODE_CONFIGTOOOLD, "Config Too Old"},
|
|
{ERRORCODE_CONFIGTOONEW, "Config Too New"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string signatureidentitytypes[] = {
|
|
{SIGNATUREIDENTITYTYPE_RESERVED, "reserved"},
|
|
{SIGNATUREIDENTITYTYPE_CERTHASH, "CERT_HASH"},
|
|
{SIGNATUREIDENTITYTYPE_CERTHASHNODEID, "CERT_HASH_NODE_ID"},
|
|
{SIGNATUREIDENTITYTYPE_NONE, "NONE"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string probeinformationtypes[] = {
|
|
{PROBEINFORMATIONTYPE_RESERVED, "reserved"},
|
|
{PROBEINFORMATIONTYPE_RESPONSIBLESET, "responsible_set"},
|
|
{PROBEINFORMATIONTYPE_NUMRESOURCES, "num_resources"},
|
|
{PROBEINFORMATIONTYPE_UPTIME, "uptime"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string datakindids[] = {
|
|
{DATAKINDID_INVALID, "invalid"},
|
|
{DATAKINDID_TURNSERVICE, "TURN-SERVICE"},
|
|
{DATAKINDID_CERTIFICATE_BY_NODE, "CERTIFICATE_BY_NODE"},
|
|
{DATAKINDID_CERTIFICATE_BY_USER, "CERTIFICATE_BY_USER"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string messageextensiontypes[] = {
|
|
{MESSAGEEXTENSIONTYPE_RESERVED, "reserved"},
|
|
{0x00, NULL}
|
|
};
|
|
|
|
static const value_string configupdatetypes[] = {
|
|
{CONFIGUPDATETYPE_RESERVED, "reserved"},
|
|
{CONFIGUPDATETYPE_CONFIG, "config"},
|
|
{CONFIGUPDATETYPE_KIND, "kind"},
|
|
{0x00, NULL}
|
|
};
|
|
/*
|
|
* defragmentation of IPv4
|
|
*/
|
|
static GHashTable *reload_fragment_table = NULL;
|
|
static GHashTable *reload_reassembled_table = NULL;
|
|
|
|
static void
|
|
reload_defragment_init(void)
|
|
{
|
|
fragment_table_init(&reload_fragment_table);
|
|
reassembled_table_init(&reload_reassembled_table);
|
|
}
|
|
|
|
|
|
static guint
|
|
get_reload_message_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
|
|
{
|
|
guint32 length = tvb_get_ntohl(tvb, offset + MSG_LENGH_OFFSET);
|
|
return length;
|
|
}
|
|
|
|
static int
|
|
get_opaque_length(tvbuff_t *tvb, guint16 offset, guint16 length_size)
|
|
{
|
|
int length = -1;
|
|
|
|
switch (length_size) {
|
|
case 1:
|
|
length = (gint32)tvb_get_guint8(tvb,offset);
|
|
break;
|
|
case 2:
|
|
length = (gint32)tvb_get_ntohs(tvb, offset);
|
|
break;
|
|
case 4:
|
|
length = (gint32)tvb_get_ntohl(tvb, offset);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
static int
|
|
dissect_opaque(tvbuff_t *tvb, packet_info *pinfo,proto_tree *tree, int anchor_index, guint16 offset, guint16 length_size, gint32 max_field_length)
|
|
{
|
|
proto_tree *opaque_tree;
|
|
proto_item *ti_anchor;
|
|
gint length_index = -1;
|
|
gint32 length = -1;
|
|
|
|
switch (length_size) {
|
|
case 1:
|
|
length_index = hf_reload_opaque_length_uint8;
|
|
length = (gint32)tvb_get_guint8(tvb,offset);
|
|
break;
|
|
case 2:
|
|
length_index = hf_reload_opaque_length_uint16;
|
|
length = (gint32)tvb_get_ntohs(tvb, offset);
|
|
break;
|
|
case 3:
|
|
length_index = hf_reload_opaque_length_uint32;
|
|
length = ((gint32) (tvb_get_ntohs(tvb, offset) <<8) + (tvb_get_guint8(tvb, offset+2)));
|
|
break;
|
|
case 4:
|
|
length_index = hf_reload_opaque_length_uint32;
|
|
length = (gint32)tvb_get_ntohl(tvb, offset);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (length_index < 0) return 0;
|
|
|
|
ti_anchor = proto_tree_add_item(tree, anchor_index, tvb, offset, length_size + length, FALSE);
|
|
|
|
if (max_field_length > 0) {
|
|
if ((length + length_size) > max_field_length) {
|
|
expert_add_info_format(pinfo, ti_anchor, PI_PROTOCOL, PI_ERROR, "Computed length > max_field length");
|
|
length = max_field_length - length_size;
|
|
}
|
|
}
|
|
|
|
opaque_tree = proto_item_add_subtree(ti_anchor, ett_reload_opaque);
|
|
proto_tree_add_uint(opaque_tree, length_index, tvb, offset, length_size, (guint)length);
|
|
proto_tree_add_item(opaque_tree, hf_reload_opaque_data, tvb, offset + length_size, length, FALSE);
|
|
|
|
return (length_size + length);
|
|
}
|
|
|
|
static int
|
|
dissect_destination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
guint8 destination_length;
|
|
guint8 destination_type;
|
|
|
|
destination_type = tvb_get_guint8(tvb,offset);
|
|
|
|
if (destination_type & 0x80) {
|
|
/* simple compressed case */
|
|
destination_length = 2;
|
|
proto_tree_add_item(tree, hf_reload_destination_compressed, tvb, offset, 2, FALSE);
|
|
return 2;
|
|
}
|
|
else {
|
|
/* normal case */
|
|
proto_tree *destination_tree;
|
|
proto_item *ti_destination;
|
|
|
|
destination_length = tvb_get_guint8(tvb,offset+1);
|
|
ti_destination = proto_tree_add_item(tree, hf_reload_destination, tvb, offset, 2+destination_length, FALSE);
|
|
destination_tree = proto_item_add_subtree(ti_destination, ett_reload_destination);
|
|
proto_item_append_text(ti_destination, " (%s)", val_to_str(destination_type, destinationtypes, "Unknown"));
|
|
|
|
proto_tree_add_item(destination_tree, hf_reload_destination_type, tvb, offset, 1, FALSE);
|
|
proto_tree_add_uint(destination_tree, hf_reload_destination_length, tvb, offset+1, 1, destination_length);
|
|
if (2 + destination_length > length) {
|
|
expert_add_info_format(pinfo, ti_destination, PI_PROTOCOL, PI_ERROR, "Truncated destination field");
|
|
return length;
|
|
}
|
|
switch(destination_type) {
|
|
case DESTINATIONTYPE_NODE:
|
|
{
|
|
proto_item *ti_nodeid;
|
|
guint nodeid_length = destination_length;
|
|
/* We don't know the node ID. Just assume that all the data is part of it */
|
|
if (nodeid_length < reload_nodeid_length) {
|
|
expert_add_info_format(pinfo, ti_destination, PI_PROTOCOL, PI_ERROR, "Truncated node id");
|
|
}
|
|
else {
|
|
nodeid_length = reload_nodeid_length;
|
|
}
|
|
ti_nodeid = proto_tree_add_item(destination_tree, hf_reload_nodeid, tvb, offset+ 2, nodeid_length, FALSE);
|
|
if ((nodeid_length < 16) || (nodeid_length > 20)) {
|
|
expert_add_info_format(pinfo, ti_nodeid, PI_PROTOCOL, PI_ERROR, "Node ID length is not in the correct range");
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DESTINATIONTYPE_RESOURCE:
|
|
dissect_opaque(tvb, pinfo, destination_tree, hf_reload_resource_id, offset +2, 1, destination_length);
|
|
break;
|
|
|
|
case DESTINATIONTYPE_COMPRESSED:
|
|
dissect_opaque(tvb, pinfo, destination_tree, hf_reload_destination_data_compressed_id, offset+2, 1, destination_length);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return (2+destination_length);
|
|
}
|
|
|
|
|
|
static int
|
|
dissect_destination_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *list_tree, guint16 offset, guint16 length)
|
|
{
|
|
gint local_offset = 0;
|
|
gint local_increment;
|
|
while (local_offset +2 <= length) {
|
|
local_increment = dissect_destination(tvb, pinfo, list_tree, offset + local_offset, length-local_offset);
|
|
if (local_increment == 0) break;
|
|
local_offset += local_increment;
|
|
}
|
|
return local_offset;
|
|
}
|
|
|
|
static int
|
|
dissect_probe_information(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_probe_information;
|
|
proto_tree *probe_information_tree;
|
|
guint8 type;
|
|
guint8 probe_length;
|
|
|
|
type = tvb_get_guint8(tvb, offset);
|
|
probe_length = tvb_get_guint8(tvb, offset + 1);
|
|
|
|
if (probe_length + 2 > length) {
|
|
ti_probe_information = proto_tree_add_item(tree, hf_reload_probe_information, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated probe information");
|
|
return length;
|
|
}
|
|
ti_probe_information = proto_tree_add_item(tree, hf_reload_probe_information, tvb, offset, 2 + probe_length, FALSE);
|
|
probe_information_tree = proto_item_add_subtree(ti_probe_information, ett_reload_probe_information);
|
|
|
|
proto_tree_add_item(probe_information_tree, hf_reload_probe_information_type, tvb, offset, 1, FALSE);
|
|
proto_tree_add_uint(probe_information_tree, hf_reload_opaque_length_uint8, tvb, offset + 1, 1, probe_length);
|
|
|
|
switch(type) {
|
|
case PROBEINFORMATIONTYPE_RESPONSIBLESET:
|
|
if (probe_length < 4) {
|
|
expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated responsible set info");
|
|
return 2 + probe_length;
|
|
}
|
|
proto_tree_add_item(probe_information_tree, hf_reload_responsible_set, tvb, offset + 2, 4, FALSE);
|
|
break;
|
|
case PROBEINFORMATIONTYPE_NUMRESOURCES:
|
|
if (probe_length < 4) {
|
|
expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated num resource info");
|
|
return 2 + probe_length;
|
|
}
|
|
proto_tree_add_item(probe_information_tree, hf_reload_num_resources, tvb, offset + 2, 4, FALSE);
|
|
break;
|
|
case PROBEINFORMATIONTYPE_UPTIME:
|
|
if (probe_length < 4) {
|
|
expert_add_info_format(pinfo, ti_probe_information, PI_PROTOCOL, PI_ERROR, "Truncated uptime info");
|
|
return 2 + probe_length;
|
|
}
|
|
proto_tree_add_item(probe_information_tree, hf_reload_uptime, tvb, offset + 2, 4, FALSE);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return probe_length + 2;
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
dissect_ipaddressport(tvbuff_t *tvb, proto_tree *tree, guint16 offset)
|
|
{
|
|
proto_item *ti_ipaddressport;
|
|
proto_tree *ipaddressport_tree;
|
|
guint8 ipaddressport_type;
|
|
guint8 ipaddressport_length;
|
|
|
|
ipaddressport_length = tvb_get_guint8(tvb, offset+1);
|
|
ti_ipaddressport = proto_tree_add_item(tree, hf_reload_ipaddressport, tvb, offset, ipaddressport_length+2, FALSE);
|
|
ipaddressport_type = tvb_get_guint8(tvb, offset);
|
|
proto_item_append_text(ti_ipaddressport, " %s ", val_to_str(ipaddressport_type, ipaddressporttypes,"Unknown Type"));
|
|
ipaddressport_tree = proto_item_add_subtree(ti_ipaddressport, ett_reload_ipaddressport);
|
|
proto_tree_add_item(ipaddressport_tree, hf_reload_ipaddressport_type, tvb, offset, 1, FALSE);
|
|
offset +=1;
|
|
proto_tree_add_uint(ipaddressport_tree, hf_reload_ipaddressport_length, tvb, offset, 1, ipaddressport_length);
|
|
offset +=1;
|
|
switch (ipaddressport_type) {
|
|
case IPADDRESSPORTTYPE_IPV4:
|
|
proto_tree_add_item(ipaddressport_tree, hf_reload_ipv4addr, tvb, offset, 4, FALSE);
|
|
proto_tree_add_item(ipaddressport_tree, hf_reload_port, tvb, offset + 4, 2, FALSE);
|
|
break;
|
|
|
|
case IPADDRESSPORTTYPE_IPV6:
|
|
proto_tree_add_item(ipaddressport_tree, hf_reload_ipv6addr, tvb, offset, 16, FALSE);
|
|
proto_tree_add_item(ipaddressport_tree, hf_reload_port, tvb, offset + 16, 2, FALSE);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return (int) (2 + ipaddressport_length);
|
|
}
|
|
|
|
static int
|
|
dissect_icecandidates(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_icecandidates;
|
|
proto_tree *icecandidates_tree;
|
|
guint16 icecandidates_offset = 0;
|
|
guint16 icecandidates_length;
|
|
guint16 local_offset = 0;
|
|
|
|
icecandidates_length = tvb_get_ntohs(tvb, offset);
|
|
/* Precalculate the length of the icecandidate list */
|
|
if (2+icecandidates_length > length) {
|
|
ti_icecandidates = proto_tree_add_item(tree, hf_reload_icecandidates, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_icecandidates, PI_PROTOCOL, PI_ERROR, "Truncated ice candidates");
|
|
return length;
|
|
}
|
|
|
|
ti_icecandidates = proto_tree_add_item(tree, hf_reload_icecandidates, tvb, offset, 2+icecandidates_length, FALSE);
|
|
icecandidates_tree = proto_item_add_subtree(ti_icecandidates, ett_reload_icecandidates);
|
|
proto_tree_add_uint(icecandidates_tree, hf_reload_icecandidates_length, tvb, offset+local_offset, 2, icecandidates_length);
|
|
local_offset += 2;
|
|
while (icecandidates_offset < icecandidates_length) {
|
|
proto_item *ti_icecandidate;
|
|
proto_tree *icecandidate_tree;
|
|
guint8 ipaddressport_length;
|
|
guint8 computed_ipaddressport_length;
|
|
guint16 iceextensions_length;
|
|
guint8 foundation_length;
|
|
guint8 candtype;
|
|
guint16 icecandidate_offset = 0;
|
|
/* compute the length */
|
|
ipaddressport_length = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+1);
|
|
icecandidate_offset += 2 + ipaddressport_length;
|
|
icecandidate_offset += 1;/* OverlayLink */
|
|
foundation_length = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset);
|
|
icecandidate_offset += 1 + foundation_length;
|
|
icecandidate_offset += 4;/* priority */
|
|
candtype = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset);
|
|
icecandidate_offset += 1;/* candType */
|
|
computed_ipaddressport_length = 0;
|
|
switch (candtype) {
|
|
case CANDTYPE_HOST:
|
|
break;
|
|
case CANDTYPE_SRFLX:
|
|
case CANDTYPE_PRFLX:
|
|
case CANDTYPE_RELAY:
|
|
/* IpAddressPort */
|
|
computed_ipaddressport_length = tvb_get_guint8(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+1);
|
|
icecandidate_offset += computed_ipaddressport_length+2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
iceextensions_length = tvb_get_ntohs(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset);
|
|
icecandidate_offset += iceextensions_length + 2;
|
|
|
|
/* icecandidate_offset is now equal to the length of this icecandicate */
|
|
if (icecandidates_offset + icecandidate_offset > icecandidates_length) {
|
|
expert_add_info_format(pinfo, ti_icecandidates, PI_PROTOCOL, PI_ERROR, "Truncated ice candidate");
|
|
break;
|
|
}
|
|
ti_icecandidate = proto_tree_add_item(icecandidates_tree, hf_reload_icecandidate, tvb, offset+local_offset+ icecandidates_offset, icecandidate_offset, FALSE);
|
|
icecandidate_tree = proto_item_add_subtree(ti_icecandidate, ett_reload_icecandidate);
|
|
/* parse from start */
|
|
icecandidate_offset = 0;
|
|
dissect_ipaddressport(tvb, icecandidate_tree, offset+local_offset+icecandidates_offset+icecandidate_offset);
|
|
icecandidate_offset += 2 + ipaddressport_length;
|
|
|
|
proto_tree_add_item(icecandidate_tree, hf_reload_overlaylink_type, tvb,
|
|
offset+local_offset+icecandidates_offset+icecandidate_offset, 1, FALSE);
|
|
|
|
icecandidate_offset += 1;
|
|
icecandidate_offset += dissect_opaque(tvb, pinfo,icecandidate_tree, hf_reload_icecandidate_foundation,offset+local_offset+icecandidates_offset + icecandidate_offset, 1, -1);
|
|
|
|
{
|
|
guint32 priority;
|
|
|
|
priority = tvb_get_ntohl(tvb, offset+local_offset + icecandidates_offset);
|
|
proto_tree_add_item(icecandidate_tree, hf_reload_icecandidate_priority, tvb, offset+local_offset + icecandidates_offset, 4, FALSE);
|
|
icecandidate_offset += 4;
|
|
proto_tree_add_item(icecandidate_tree, hf_reload_icecandidate_type, tvb,
|
|
offset+local_offset+icecandidates_offset+icecandidate_offset, 1, FALSE);
|
|
proto_item_append_text(ti_icecandidate, ": %s, priority=%d", val_to_str(candtype, candtypes, "Unknown"), priority);
|
|
}
|
|
icecandidate_offset += 1;
|
|
{
|
|
int item_index = -1;
|
|
switch (candtype) {
|
|
case CANDTYPE_HOST:
|
|
break;
|
|
case CANDTYPE_SRFLX:
|
|
item_index = hf_reload_icecandidate_srflx_addr;
|
|
break;
|
|
case CANDTYPE_PRFLX:
|
|
item_index = hf_reload_icecandidate_prflx_addr;
|
|
break;
|
|
case CANDTYPE_RELAY:
|
|
item_index = hf_reload_icecandidate_relay_addr;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
if (item_index != -1) {
|
|
proto_item *ti_computed_address;
|
|
proto_tree *computed_address_tree;
|
|
ti_computed_address =
|
|
proto_tree_add_item(icecandidate_tree, item_index, tvb,
|
|
offset+local_offset+icecandidates_offset+icecandidate_offset, computed_ipaddressport_length + 2, FALSE);
|
|
computed_address_tree = proto_item_add_subtree(ti_computed_address, ett_reload_icecandidate_computed_address);
|
|
dissect_ipaddressport(tvb, computed_address_tree,
|
|
offset+local_offset+icecandidates_offset+icecandidate_offset);
|
|
icecandidate_offset += computed_ipaddressport_length + 2;
|
|
}
|
|
}
|
|
/* Ice extensions */
|
|
{
|
|
guint16 iceextensions_offset = 0;
|
|
proto_item *ti_iceextension, *ti_iceextensions_length;
|
|
proto_tree *iceextension_tree;
|
|
guint16 iceextension_name_length;
|
|
guint16 iceextension_value_length;
|
|
ti_iceextensions_length =
|
|
proto_tree_add_uint(icecandidate_tree, hf_reload_icecandidate_extensions_length, tvb,
|
|
offset+local_offset+icecandidates_offset+icecandidate_offset, 2,
|
|
iceextensions_length);
|
|
icecandidate_offset += 2;
|
|
while (iceextensions_offset < iceextensions_length) {
|
|
iceextension_name_length =
|
|
tvb_get_ntohs(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+iceextensions_offset);
|
|
iceextension_value_length =
|
|
tvb_get_ntohs(tvb, offset+local_offset+icecandidates_offset+icecandidate_offset+iceextensions_offset+iceextension_name_length + 2);
|
|
if ((iceextensions_offset + 4 + iceextension_name_length + iceextension_value_length) > iceextensions_length) {
|
|
expert_add_info_format(pinfo, ti_iceextensions_length, PI_PROTOCOL, PI_ERROR, "Truncated ice extension");
|
|
break;
|
|
}
|
|
ti_iceextension =
|
|
proto_tree_add_item(icecandidate_tree, hf_reload_iceextension, tvb,
|
|
offset+local_offset + icecandidates_offset + icecandidate_offset + iceextensions_offset, 4 + iceextension_name_length + iceextension_value_length, FALSE);
|
|
iceextension_tree = proto_item_add_subtree(ti_iceextension, ett_reload_iceextension);
|
|
proto_tree_add_item(iceextension_tree, hf_reload_iceextension_name, tvb,
|
|
offset+local_offset+ icecandidates_offset + icecandidate_offset + iceextensions_offset, 2 + iceextension_name_length, FALSE);
|
|
proto_tree_add_item(iceextension_tree, hf_reload_iceextension_value, tvb,
|
|
offset+local_offset + icecandidates_offset + icecandidate_offset + iceextensions_offset +2 + iceextension_name_length, 2 + iceextension_value_length, FALSE);
|
|
iceextensions_offset += 4 + iceextension_name_length + iceextension_value_length;
|
|
}
|
|
}
|
|
icecandidate_offset += iceextensions_length;
|
|
icecandidates_offset += icecandidate_offset;
|
|
}
|
|
return (2 + icecandidates_length);
|
|
}
|
|
|
|
static int
|
|
dissect_attachreqans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_attachreqans;
|
|
proto_tree *attachreqans_tree;
|
|
guint8 ufrag_length;
|
|
guint8 password_length;
|
|
guint8 role_length;
|
|
guint16 icecandidates_length;
|
|
guint16 local_offset = 0;
|
|
|
|
/* variable length structures: must 1st compute the length ... */
|
|
ufrag_length = tvb_get_guint8(tvb,offset+local_offset);
|
|
local_offset += 1;
|
|
if (local_offset + ufrag_length > length) {
|
|
ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
|
|
return length;
|
|
}
|
|
local_offset += ufrag_length;
|
|
password_length = tvb_get_guint8(tvb,offset+local_offset);
|
|
local_offset += 1;
|
|
if (local_offset + password_length > length) {
|
|
ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
|
|
return length;
|
|
}
|
|
local_offset += password_length;
|
|
role_length = tvb_get_guint8(tvb,offset+local_offset);
|
|
local_offset += 1;
|
|
if (local_offset + role_length > length) {
|
|
ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
|
|
return length;
|
|
}
|
|
local_offset += role_length;
|
|
icecandidates_length = tvb_get_ntohs(tvb, offset+local_offset);
|
|
local_offset += 2;
|
|
if (local_offset +icecandidates_length > length) {
|
|
ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_attachreqans, PI_PROTOCOL, PI_ERROR, "Truncated attach_reqans");
|
|
return length;
|
|
}
|
|
local_offset += icecandidates_length;
|
|
|
|
ti_attachreqans = proto_tree_add_item(tree, hf_reload_attachreqans, tvb, offset, local_offset, FALSE);
|
|
attachreqans_tree = proto_item_add_subtree(ti_attachreqans, ett_reload_attachreqans);
|
|
|
|
/* restart parsing, field by field */
|
|
local_offset = 0;
|
|
local_offset += dissect_opaque(tvb, pinfo,attachreqans_tree, hf_reload_ufrag,offset+local_offset, 1, -1);
|
|
local_offset += dissect_opaque(tvb, pinfo,attachreqans_tree, hf_reload_password,offset+local_offset, 1, -1);
|
|
local_offset += dissect_opaque(tvb, pinfo,attachreqans_tree, hf_reload_role,offset+local_offset, 1, -1);
|
|
local_offset += dissect_icecandidates(tvb, pinfo, attachreqans_tree, offset + local_offset, 2+icecandidates_length);
|
|
|
|
proto_tree_add_item(attachreqans_tree, hf_reload_sendupdate, tvb, offset+local_offset, 1, FALSE);
|
|
local_offset += 1;
|
|
|
|
return local_offset;
|
|
}
|
|
|
|
static int
|
|
dissect_storeddata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_storeddata;
|
|
proto_item *storeddata_tree;
|
|
guint32 storeddata_length;
|
|
guint32 local_offset = 0;
|
|
|
|
storeddata_length = tvb_get_ntohl(tvb, offset);
|
|
local_offset += 4;
|
|
|
|
if (storeddata_length + 4 > length) {
|
|
ti_storeddata = proto_tree_add_item(tree, hf_reload_storeddata, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_storeddata, PI_PROTOCOL, PI_ERROR, "Truncated storeddata");
|
|
return length;
|
|
}
|
|
|
|
local_offset = 0;
|
|
ti_storeddata = proto_tree_add_item(tree, hf_reload_storeddata, tvb, offset, 4 + storeddata_length, FALSE);
|
|
storeddata_tree = proto_item_add_subtree(ti_storeddata, ett_reload_storeddata);
|
|
|
|
proto_tree_add_uint(storeddata_tree, hf_reload_storeddata_length, tvb, offset + local_offset, 4, storeddata_length);
|
|
local_offset += 4;
|
|
proto_tree_add_item(storeddata_tree, hf_reload_storeddata_storage_time, tvb, offset + local_offset, 8, FALSE);
|
|
local_offset += 8;
|
|
proto_tree_add_item(storeddata_tree, hf_reload_storeddata_lifetime, tvb, offset + local_offset, 4, FALSE);
|
|
/* Can not parse the value and signature fields, as we do not know what is the data model for
|
|
a given kind id */
|
|
return (storeddata_length + 4);
|
|
}
|
|
|
|
static int
|
|
dissect_kinddata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_kinddata;
|
|
proto_item *kinddata_tree;
|
|
guint32 values_length;
|
|
guint32 local_offset = 0;
|
|
|
|
values_length = tvb_get_ntohl(tvb, offset + 4 + 8);
|
|
if (12 + values_length > length) {
|
|
ti_kinddata = proto_tree_add_item(tree, hf_reload_kinddata, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_kinddata, PI_PROTOCOL, PI_ERROR, "Truncated kind data");
|
|
return length;
|
|
}
|
|
ti_kinddata = proto_tree_add_item(tree, hf_reload_kinddata, tvb, offset, 12+values_length, FALSE);
|
|
kinddata_tree = proto_item_add_subtree(ti_kinddata, ett_reload_kinddata);
|
|
|
|
proto_tree_add_item(kinddata_tree, hf_reload_kindid, tvb, offset+local_offset, 4, FALSE);
|
|
local_offset += 4;
|
|
proto_tree_add_item(kinddata_tree, hf_reload_kinddata_generation_counter, tvb, offset+local_offset, 8, FALSE);
|
|
local_offset += 8;
|
|
proto_tree_add_uint(kinddata_tree, hf_reload_kinddata_values_length, tvb, offset +local_offset, 4, values_length);
|
|
local_offset += 4;
|
|
{
|
|
guint32 values_offset = 0;
|
|
guint32 values_increment;
|
|
while (values_offset < values_length) {
|
|
values_increment = dissect_storeddata(tvb, pinfo, kinddata_tree, offset+local_offset+values_offset, values_length - values_offset);
|
|
if (values_increment == 0) {
|
|
break;
|
|
}
|
|
values_offset += values_increment;
|
|
}
|
|
}
|
|
local_offset += values_length;
|
|
return local_offset;
|
|
}
|
|
|
|
static int
|
|
dissect_storereq(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item * ti_storereq;
|
|
proto_tree * storereq_tree;
|
|
guint32 local_offset = 0;
|
|
guint32 kind_data_length;
|
|
|
|
|
|
local_offset += get_opaque_length(tvb, offset, 1) + 1; /* resource id length */
|
|
if (local_offset > length) {
|
|
ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_storereq, PI_PROTOCOL, PI_ERROR, "Truncated storereq: resource too long");
|
|
return length;
|
|
}
|
|
|
|
local_offset += 1; /* replica_num */
|
|
if (local_offset > length) {
|
|
ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_storereq, PI_PROTOCOL, PI_ERROR, "Truncated storereq: no room for replica_number");
|
|
return length;
|
|
}
|
|
|
|
kind_data_length = tvb_get_ntohl(tvb, offset + local_offset);
|
|
local_offset += 4;
|
|
if (local_offset + kind_data_length > length) {
|
|
ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_storereq, PI_PROTOCOL, PI_ERROR, "Truncated storereq: kind_date too long");
|
|
return length;
|
|
}
|
|
local_offset += kind_data_length;
|
|
|
|
ti_storereq = proto_tree_add_item(tree, hf_reload_storereq, tvb, offset, local_offset, FALSE);
|
|
storereq_tree = proto_item_add_subtree(ti_storereq, ett_reload_storereq);
|
|
|
|
/* Parse from start */
|
|
local_offset = 0;
|
|
local_offset += dissect_opaque(tvb, pinfo, storereq_tree, hf_reload_resource_id, offset +local_offset, 1, length);
|
|
proto_tree_add_item(storereq_tree, hf_reload_store_replica_num, tvb, offset + local_offset, 1, FALSE);
|
|
local_offset += 1;
|
|
proto_tree_add_item(storereq_tree, hf_reload_store_kind_data_length, tvb, offset + local_offset, 4, FALSE);
|
|
local_offset += 4;
|
|
{
|
|
guint32 kind_data_offset = 0;
|
|
guint32 kind_data_increment;
|
|
while (kind_data_offset < kind_data_length) {
|
|
kind_data_increment = dissect_kinddata(tvb, pinfo, storereq_tree, offset+local_offset+kind_data_offset, kind_data_length - kind_data_offset);
|
|
if (kind_data_increment == 0) {
|
|
break;
|
|
}
|
|
kind_data_offset += kind_data_increment;
|
|
}
|
|
}
|
|
local_offset += kind_data_length;
|
|
|
|
return local_offset;
|
|
}
|
|
|
|
static int
|
|
dissect_fetchans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_fetchans;
|
|
proto_tree *fetchans_tree;
|
|
guint32 kind_responses_length;
|
|
guint32 kind_responses_offset = 0;
|
|
|
|
kind_responses_length = tvb_get_ntohl(tvb, offset);
|
|
if (4 + kind_responses_length > length) {
|
|
ti_fetchans = proto_tree_add_item(tree, hf_reload_fetchans, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_fetchans, PI_PROTOCOL, PI_ERROR, "Truncated storereq");
|
|
return length;
|
|
}
|
|
ti_fetchans = proto_tree_add_item(tree, hf_reload_fetchans, tvb, offset, 4 + kind_responses_length, FALSE);
|
|
fetchans_tree = proto_item_add_subtree(ti_fetchans, ett_reload_fetchans);
|
|
|
|
proto_tree_add_uint(fetchans_tree, hf_reload_kind_responses_length, tvb, offset, 4, FALSE);
|
|
|
|
while (kind_responses_offset < kind_responses_length) {
|
|
guint32 kind_responses_increment;
|
|
kind_responses_increment = dissect_kinddata(tvb, pinfo, fetchans_tree, offset + 4 + kind_responses_offset, kind_responses_length - kind_responses_offset);
|
|
if (kind_responses_increment == 0) {
|
|
break;
|
|
}
|
|
kind_responses_offset += kind_responses_increment;
|
|
}
|
|
|
|
return 4 + kind_responses_length;
|
|
}
|
|
|
|
|
|
static int
|
|
dissect_statans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 offset, guint16 length)
|
|
{
|
|
proto_item *ti_statans;
|
|
proto_tree *statans_tree;
|
|
guint32 kind_responses_length;
|
|
guint32 kind_responses_offset = 0;
|
|
|
|
kind_responses_length = tvb_get_ntohl(tvb, offset);
|
|
if (4 + kind_responses_length > length) {
|
|
ti_statans = proto_tree_add_item(tree, hf_reload_statans, tvb, offset, length, FALSE);
|
|
expert_add_info_format(pinfo, ti_statans, PI_PROTOCOL, PI_ERROR, "Truncated statans");
|
|
return length;
|
|
}
|
|
ti_statans = proto_tree_add_item(tree, hf_reload_statans, tvb, offset, 4 + kind_responses_length, FALSE);
|
|
statans_tree = proto_item_add_subtree(ti_statans, ett_reload_statans);
|
|
|
|
proto_tree_add_uint(statans_tree, hf_reload_kind_responses_length, tvb, offset, 4, FALSE);
|
|
|
|
while (kind_responses_offset < kind_responses_length) {
|
|
/* assume metadata is a form of stored data */
|
|
guint32 kind_responses_increment;
|
|
kind_responses_increment = dissect_kinddata(tvb, pinfo, statans_tree, offset + 4 + kind_responses_offset, kind_responses_length - kind_responses_offset);
|
|
if (kind_responses_increment == 0) {
|
|
break;
|
|
}
|
|
kind_responses_offset += kind_responses_increment;
|
|
}
|
|
|
|
return 4 + kind_responses_length;
|
|
}
|
|
|
|
static int
|
|
dissect_reload_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *reload_tree;
|
|
guint32 relo_token;
|
|
guint effective_length;
|
|
guint msg_length;
|
|
guint16 offset;
|
|
conversation_t *conversation;
|
|
reload_conv_info_t *reload_info;
|
|
reload_transaction_t * reload_trans;
|
|
emem_tree_key_t transaction_id_key[2];
|
|
guint32 transaction_id[2];
|
|
guint16 options_length;
|
|
guint16 via_list_length;
|
|
guint16 destination_list_length;
|
|
guint16 message_code;
|
|
guint16 error_code = 0;
|
|
guint32 forwarding_length;
|
|
proto_tree *reload_forwarding_tree;
|
|
const char *msg_class_str;
|
|
const char *msg_method_str = NULL;
|
|
gboolean fragmented = FALSE;
|
|
gboolean last_fragment = FALSE;
|
|
fragment_data *reload_fd_head = NULL;
|
|
gboolean save_fragmented;
|
|
guint32 fragment = 0;
|
|
gboolean update_col_info = TRUE;
|
|
|
|
offset = 0;
|
|
effective_length = tvb_length(tvb);
|
|
|
|
/* First, make sure we have enough data to do the check. */
|
|
if (effective_length < MIN_HDR_LENGTH)
|
|
return 0;
|
|
|
|
/*
|
|
* First check if the frame is really meant for us.
|
|
*/
|
|
relo_token = tvb_get_ntohl(tvb,0);
|
|
|
|
if (relo_token != RELOAD_TOKEN) {
|
|
return 0;
|
|
}
|
|
|
|
msg_length = get_reload_message_length(pinfo, tvb, offset);
|
|
|
|
if (effective_length < msg_length) {
|
|
/* The effective length is too small for the packet */
|
|
expert_add_info_format(pinfo, NULL, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
|
|
return 0;
|
|
}
|
|
|
|
/* The message seems to be a valid reLOAD message! */
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RELOAD");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
/* Create the transaction key which may be used to track the conversation */
|
|
transaction_id[0] = tvb_get_ntohl(tvb, 20);
|
|
transaction_id[1] = tvb_get_ntohl(tvb, 24);
|
|
|
|
transaction_id_key[0].length = 2;
|
|
transaction_id_key[0].key = transaction_id;
|
|
transaction_id_key[1].length = 0;
|
|
transaction_id_key[1].key = NULL;
|
|
|
|
via_list_length = tvb_get_ntohs(tvb, 32);
|
|
destination_list_length = tvb_get_ntohs(tvb, 34);
|
|
options_length = tvb_get_ntohs(tvb, 36);
|
|
|
|
forwarding_length = MIN_HDR_LENGTH + (via_list_length + destination_list_length + options_length);
|
|
|
|
message_code = tvb_get_ntohs(tvb, forwarding_length);
|
|
|
|
/* Do we already have a conversation ? */
|
|
conversation = find_or_create_conversation(pinfo);
|
|
|
|
/*
|
|
* Do we already have a state structure for this conv
|
|
*/
|
|
reload_info = conversation_get_proto_data(conversation, proto_reload);
|
|
if (!reload_info) {
|
|
/* No. Attach that information to the conversation, and add
|
|
* it to the list of information structures.
|
|
*/
|
|
reload_info = se_alloc(sizeof(reload_conv_info_t));
|
|
reload_info->transaction_pdus = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "reload_transaction_pdus");
|
|
conversation_add_proto_data(conversation, proto_reload, reload_info);
|
|
}
|
|
|
|
if (!pinfo->fd->flags.visited) {
|
|
if ((reload_trans =
|
|
se_tree_lookup32_array(reload_info->transaction_pdus, transaction_id_key)) == NULL) {
|
|
reload_trans = se_alloc(sizeof(reload_transaction_t));
|
|
reload_trans->req_frame = 0;
|
|
reload_trans->rep_frame = 0;
|
|
reload_trans->req_time = pinfo->fd->abs_ts;
|
|
se_tree_insert32_array(reload_info->transaction_pdus, transaction_id_key, (void *)reload_trans);
|
|
}
|
|
|
|
/* check whether the message is a request or a response */
|
|
|
|
if (IS_REQUEST(message_code) && (message_code != RELOAD_ERROR)) {
|
|
/* This is a request */
|
|
if (reload_trans->req_frame == 0) {
|
|
reload_trans->req_frame = pinfo->fd->num;
|
|
}
|
|
}
|
|
else {
|
|
/* This is a catch-all for all non-request messages */
|
|
if (reload_trans->rep_frame == 0) {
|
|
reload_trans->rep_frame = pinfo->fd->num;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
reload_trans=se_tree_lookup32_array(reload_info->transaction_pdus, transaction_id_key);
|
|
}
|
|
|
|
if (!reload_trans) {
|
|
/* create a "fake" pana_trans structure */
|
|
reload_trans = ep_alloc(sizeof(reload_transaction_t));
|
|
reload_trans->req_frame = 0;
|
|
reload_trans->rep_frame = 0;
|
|
reload_trans->req_time = pinfo->fd->abs_ts;
|
|
}
|
|
|
|
ti = proto_tree_add_item(tree, proto_reload, tvb, 0, -1, FALSE);
|
|
|
|
if (message_code == RELOAD_ERROR) {
|
|
error_code = tvb_get_ntohs(tvb, forwarding_length + 2);
|
|
msg_class_str = "ERROR Response";
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, " %s %s", msg_class_str, val_to_str(error_code, errorcodes, "Unknown"));
|
|
proto_item_append_text(ti, ": %s %s", msg_class_str, val_to_str(error_code, errorcodes, "Unknown"));
|
|
}
|
|
else {
|
|
msg_class_str = val_to_str(MSGCODE_TO_CLASS(message_code), classes, "Unknown %d");
|
|
msg_method_str = val_to_str(MSGCODE_TO_METHOD(message_code), methods, "Unknown %d");
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
|
|
msg_method_str, msg_class_str);
|
|
proto_item_append_text(ti, ": %s %s", msg_method_str, msg_class_str);
|
|
}
|
|
|
|
reload_tree = proto_item_add_subtree(ti, ett_reload);
|
|
|
|
/* Retransmission control */
|
|
if (IS_REQUEST(message_code) && (message_code != RELOAD_ERROR)) {
|
|
if (reload_trans->req_frame != pinfo->fd->num) {
|
|
proto_item *it;
|
|
it = proto_tree_add_uint(reload_tree, hf_reload_duplicate, tvb, 0, 0, reload_trans->req_frame);
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
}
|
|
if (reload_trans->rep_frame) {
|
|
proto_item *it;
|
|
it = proto_tree_add_uint(reload_tree, hf_reload_response_in, tvb, 0, 0, reload_trans->rep_frame);
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
}
|
|
}
|
|
else {
|
|
/* This is a response */
|
|
if (reload_trans->rep_frame != pinfo->fd->num) {
|
|
proto_item *it;
|
|
it = proto_tree_add_uint(reload_tree, hf_reload_duplicate, tvb, 0, 0, reload_trans->rep_frame);
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
}
|
|
|
|
if (reload_trans->req_frame) {
|
|
proto_item *it;
|
|
nstime_t ns;
|
|
|
|
it = proto_tree_add_uint(reload_tree, hf_reload_response_to, tvb, 0, 0, reload_trans->req_frame);
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
|
|
nstime_delta(&ns, &pinfo->fd->abs_ts, &reload_trans->req_time);
|
|
it = proto_tree_add_time(reload_tree, hf_reload_time, tvb, 0, 0, &ns);
|
|
PROTO_ITEM_SET_GENERATED(it);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Message dissection
|
|
*/
|
|
|
|
/*
|
|
* Forwarding Header
|
|
*/
|
|
ti = proto_tree_add_item(reload_tree, hf_reload_forwarding, tvb, 0, forwarding_length, FALSE);
|
|
reload_forwarding_tree = proto_item_add_subtree(ti, ett_reload_forwarding);
|
|
|
|
proto_tree_add_uint(reload_forwarding_tree, hf_reload_token, tvb, 0, 4, relo_token);
|
|
proto_tree_add_item(reload_forwarding_tree, hf_reload_overlay, tvb, 4, 4, FALSE);
|
|
proto_tree_add_item(reload_forwarding_tree, hf_reload_configuration_sequence, tvb, 8, 2, FALSE);
|
|
{
|
|
guint8 version =
|
|
tvb_get_guint8(tvb,10);
|
|
proto_tree_add_uint_format_value(reload_forwarding_tree, hf_reload_version, tvb, 10, 1,
|
|
version, "%u.%u", (version & 0xF0)>>4, (version & 0xF));
|
|
}
|
|
proto_tree_add_item(reload_forwarding_tree, hf_reload_ttl, tvb, 11, 1, FALSE);
|
|
{
|
|
proto_item *ti_fragment;
|
|
proto_tree *fragment_tree;
|
|
guint32 bit_offset;
|
|
|
|
fragment = tvb_get_ntohl(tvb,12);
|
|
|
|
ti_fragment = proto_tree_add_uint(reload_forwarding_tree, hf_reload_fragment_flag, tvb, 12, 4, fragment);
|
|
fragment_tree = proto_item_add_subtree(ti_fragment, ett_reload_fragment_flag);
|
|
bit_offset = (12) * 8;
|
|
|
|
if (fragment & 0x80000000) {
|
|
proto_item_append_text(ti_fragment, " (Fragment)");
|
|
fragmented = TRUE;
|
|
}
|
|
if (fragment & 0x40000000) {
|
|
proto_item_append_text(ti_fragment, " (Last)");
|
|
last_fragment = TRUE;
|
|
}
|
|
proto_tree_add_bits_item(fragment_tree, hf_reload_fragment_fragmented, tvb, bit_offset, 1, FALSE);
|
|
proto_tree_add_bits_item(fragment_tree, hf_reload_fragment_last_fragment, tvb, bit_offset+1, 1, FALSE);
|
|
proto_tree_add_bits_item(fragment_tree, hf_reload_fragment_reserved, tvb, bit_offset+2, 6, FALSE);
|
|
fragment = fragment & 0x00ffffff;
|
|
proto_tree_add_uint(fragment_tree, hf_reload_fragment_offset, tvb, 13, 3, fragment);
|
|
}
|
|
|
|
/* msg_length is already parsed */
|
|
proto_tree_add_uint(reload_forwarding_tree, hf_reload_length, tvb, 16, 4, msg_length);
|
|
proto_tree_add_item(reload_forwarding_tree, hf_reload_trans_id, tvb, 20, 8, FALSE);
|
|
proto_tree_add_item(reload_forwarding_tree, hf_reload_max_response_length, tvb, 28, 4, FALSE);
|
|
/* variable lengths fields lengths are already parsed */
|
|
proto_tree_add_uint(reload_forwarding_tree, hf_reload_via_list_length, tvb, 32, 2, via_list_length);
|
|
proto_tree_add_uint(reload_forwarding_tree, hf_reload_destination_list_length, tvb, 34, 2, destination_list_length);
|
|
proto_tree_add_uint(reload_forwarding_tree, hf_reload_options_length, tvb, 36, 2, options_length);
|
|
|
|
offset += MIN_HDR_LENGTH;
|
|
|
|
if (((guint)offset + via_list_length) > msg_length) {
|
|
expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
|
|
return MIN_HDR_LENGTH;
|
|
}
|
|
|
|
if (via_list_length > 0) {
|
|
proto_item *ti_vialist;
|
|
proto_tree *vialist_tree;
|
|
ti_vialist = proto_tree_add_item(reload_forwarding_tree, hf_reload_via_list, tvb, offset, via_list_length, FALSE);
|
|
vialist_tree = proto_item_add_subtree(ti_vialist, ett_reload_via_list);
|
|
|
|
dissect_destination_list(tvb, pinfo, vialist_tree, offset, via_list_length);
|
|
}
|
|
offset += via_list_length;
|
|
|
|
if (((guint)offset + destination_list_length) > msg_length) {
|
|
expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
|
|
return offset;
|
|
}
|
|
|
|
if (destination_list_length > 0) {
|
|
proto_item *ti_destination_list;
|
|
proto_tree *destination_list_tree;
|
|
ti_destination_list = proto_tree_add_item(reload_forwarding_tree, hf_reload_destination_list, tvb, offset, destination_list_length, FALSE);
|
|
destination_list_tree = proto_item_add_subtree(ti_destination_list, ett_reload_destination_list);
|
|
|
|
dissect_destination_list(tvb, pinfo, destination_list_tree, offset, destination_list_length);
|
|
}
|
|
offset += destination_list_length;
|
|
|
|
if (((guint)offset + options_length) > msg_length) {
|
|
expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_ERROR, "Truncated RELOAD packet");
|
|
return offset;
|
|
}
|
|
|
|
if (options_length > 0) {
|
|
guint16 local_offset = 0;
|
|
while ((local_offset +4) <= options_length) {
|
|
proto_item *ti_option;
|
|
guint8 option_type = tvb_get_guint8(tvb,offset+local_offset);
|
|
guint8 option_flags = tvb_get_guint8(tvb, offset+local_offset + 1);
|
|
guint16 option_length = tvb_get_ntohs(tvb, offset+local_offset + 2);
|
|
proto_tree *option_tree;
|
|
|
|
ti_option = proto_tree_add_item(reload_forwarding_tree, hf_reload_forwarding_option, tvb, offset+local_offset, option_length + 4, FALSE);
|
|
proto_item_append_text(ti_option, " type=%s, flags=%02x, length=%d", val_to_str(option_type, forwardingoptiontypes, "Unknown"), option_flags, option_length);
|
|
|
|
option_tree = proto_item_add_subtree(ti_option, ett_reload_forwarding_option);
|
|
proto_tree_add_item(option_tree, hf_reload_forwarding_option_type, tvb, offset+local_offset, 1, FALSE);
|
|
{
|
|
proto_item *ti_flags;
|
|
proto_tree *flags_tree;
|
|
guint32 bit_offset;
|
|
ti_flags = proto_tree_add_uint(option_tree, hf_reload_forwarding_option_flags, tvb, offset+local_offset+1, 1, option_flags);
|
|
flags_tree = proto_item_add_subtree(ti_flags, ett_reload_forwarding_option_flags);
|
|
bit_offset = 8*(offset+local_offset+1);
|
|
proto_tree_add_bits_item(flags_tree, hf_reload_forwarding_option_flag_response_copy, tvb, bit_offset+5, 1, FALSE);
|
|
proto_tree_add_bits_item(flags_tree, hf_reload_forwarding_option_flag_destination_critical, tvb, bit_offset+6, 1, FALSE);
|
|
proto_tree_add_bits_item(flags_tree, hf_reload_forwarding_option_flag_forward_critical, tvb, bit_offset+7, 1, FALSE);
|
|
}
|
|
proto_tree_add_uint(option_tree, hf_reload_forwarding_option_length, tvb, offset+local_offset+2, 2, option_length);
|
|
local_offset += 4;
|
|
if (local_offset + option_length > options_length) {
|
|
expert_add_info_format(pinfo, ti_option, PI_PROTOCOL, PI_ERROR, "Bad option len");
|
|
break;
|
|
}
|
|
|
|
switch (option_type) {
|
|
default:
|
|
proto_tree_add_item(option_tree, hf_reload_forwarding_option_data, tvb, offset+local_offset, option_length, FALSE);
|
|
break;
|
|
}
|
|
local_offset += option_length;
|
|
}
|
|
}
|
|
offset += options_length;
|
|
|
|
save_fragmented = pinfo->fragmented;
|
|
if ((reload_defragment) && ((fragmented != FALSE) && !((fragment == 0) && (last_fragment)))) {
|
|
tvbuff_t *next_tvb = NULL;
|
|
|
|
pinfo->fragmented = TRUE;
|
|
if (tvb_bytes_exist(tvb, offset, msg_length - offset)) {
|
|
fragment_add_check(tvb, offset, pinfo,
|
|
transaction_id[0]^transaction_id[1],
|
|
reload_fragment_table,
|
|
reload_reassembled_table,
|
|
fragment,
|
|
msg_length - offset,
|
|
!last_fragment);
|
|
|
|
next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled RELOAD",
|
|
reload_fd_head, &reload_frag_items, &update_col_info, reload_tree);
|
|
}
|
|
if (next_tvb == NULL) {
|
|
/* Just show this as a fragment. */
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Fragmented RELOAD protocol (trans id=%x%x off=%u)",
|
|
transaction_id[0],transaction_id[1], fragment);
|
|
if (reload_fd_head && reload_fd_head->reassembled_in != pinfo->fd->num) {
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled in #%u]",
|
|
reload_fd_head->reassembled_in);
|
|
}
|
|
call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
|
|
pinfo->fragmented = save_fragmented;
|
|
return effective_length;
|
|
}
|
|
tvb = next_tvb;
|
|
offset = 0;
|
|
}
|
|
else {
|
|
pinfo->fragmented = FALSE;
|
|
}
|
|
|
|
|
|
|
|
/* Message Contents */
|
|
{
|
|
guint32 message_body_length;
|
|
guint32 extensions_length;
|
|
proto_item *ti_message_contents;
|
|
proto_tree *message_contents_tree;
|
|
|
|
message_body_length = tvb_get_ntohl(tvb, offset + 2);
|
|
extensions_length = tvb_get_ntohl(tvb, offset + 2 + 4 + message_body_length);
|
|
if (forwarding_length + 2 + 4 + message_body_length + 4 + extensions_length > msg_length) {
|
|
ti_message_contents = proto_tree_add_item(reload_tree, hf_reload_message_contents, tvb, offset, (msg_length - forwarding_length), FALSE);
|
|
expert_add_info_format(pinfo, ti_message_contents, PI_PROTOCOL, PI_ERROR, "Truncated message contents");
|
|
return msg_length;
|
|
}
|
|
|
|
ti_message_contents = proto_tree_add_item(reload_tree, hf_reload_message_contents, tvb, offset, 2 + 4 + message_body_length + 4 + extensions_length, FALSE);
|
|
message_contents_tree = proto_item_add_subtree(ti_message_contents, ett_reload_message_contents);
|
|
|
|
if (message_code != RELOAD_ERROR) {
|
|
proto_item *ti_message_body;
|
|
proto_tree *message_body_tree;
|
|
|
|
/* message_code was already parsed */
|
|
proto_tree_add_uint_format_value(message_contents_tree, hf_reload_message_code, tvb,
|
|
offset, 2,
|
|
message_code,
|
|
"%s-%s", msg_method_str, msg_class_str);
|
|
offset += 2;
|
|
/* Message body */
|
|
ti_message_body = proto_tree_add_item(message_contents_tree, hf_reload_message_body, tvb, offset, 4 + message_body_length, FALSE);
|
|
message_body_tree = proto_item_add_subtree(ti_message_body, ett_reload_message_body);
|
|
proto_tree_add_uint(message_body_tree, hf_reload_opaque_length_uint32, tvb, offset, 4, message_body_length);
|
|
offset +=4;
|
|
|
|
switch(MSGCODE_TO_METHOD(message_code)) {
|
|
case METHOD_ROUTEQUERY:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
{
|
|
proto_item * ti_routequeryreq;
|
|
proto_tree * routequeryreq_tree;
|
|
int destination_length;
|
|
ti_routequeryreq = proto_tree_add_item(message_body_tree, hf_reload_routequeryreq, tvb, offset, message_body_length, FALSE);
|
|
routequeryreq_tree = proto_item_add_subtree(ti_routequeryreq, ett_reload_routequeryreq);
|
|
proto_tree_add_item(routequeryreq_tree, hf_reload_sendupdate, tvb, offset, 1, FALSE);
|
|
destination_length = dissect_destination(tvb, pinfo, routequeryreq_tree, offset + 1, message_body_length - 1 - 2);
|
|
dissect_opaque(tvb, pinfo, routequeryreq_tree, hf_reload_overlay_specific, offset + 1 + destination_length, 2, (message_body_length - 1 - destination_length));
|
|
}
|
|
}
|
|
/* Answer is entirely Overlay-specific */
|
|
}
|
|
break;
|
|
|
|
case METHOD_PROBE:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
proto_item * ti_probereq;
|
|
proto_tree * probereq_tree;
|
|
guint8 info_list_length = 0;
|
|
ti_probereq = proto_tree_add_item(message_body_tree, hf_reload_probereq, tvb, offset, message_body_length, FALSE);
|
|
probereq_tree = proto_item_add_subtree(ti_probereq, ett_reload_probereq);
|
|
info_list_length = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_uint(probereq_tree, hf_reload_opaque_length_uint8, tvb, offset, 1, info_list_length);
|
|
|
|
if (info_list_length > message_body_length - 1) {
|
|
expert_add_info_format(pinfo, ti_probereq, PI_PROTOCOL, PI_ERROR, "Requested info list too long for field size");
|
|
info_list_length = message_body_length - 1;
|
|
}
|
|
{
|
|
int probe_offset = 0;
|
|
while (probe_offset < info_list_length) {
|
|
proto_tree_add_item(probereq_tree, hf_reload_probe_information_type, tvb, offset + 1 + probe_offset, 1, FALSE);
|
|
probe_offset += 1;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
/* response */
|
|
proto_item * ti_probeans;
|
|
proto_tree * probeans_tree;
|
|
guint16 info_list_length = 0;
|
|
|
|
ti_probeans = proto_tree_add_item(message_body_tree, hf_reload_probeans, tvb, offset, message_body_length, FALSE);
|
|
probeans_tree = proto_item_add_subtree(ti_probeans, ett_reload_probeans);
|
|
info_list_length = tvb_get_ntohs(tvb, offset);
|
|
|
|
proto_tree_add_uint(probeans_tree, hf_reload_opaque_length_uint16, tvb, offset, 2, info_list_length);
|
|
|
|
if (info_list_length > message_body_length - 2) {
|
|
expert_add_info_format(pinfo, ti_probeans, PI_PROTOCOL, PI_ERROR, "Requested info list too long for field size");
|
|
info_list_length = message_body_length - 2;
|
|
}
|
|
{
|
|
int probe_offset = 0;
|
|
int probe_increment;
|
|
while (probe_offset < info_list_length) {
|
|
probe_increment = dissect_probe_information(tvb, pinfo, probeans_tree, offset + 2 + probe_offset, info_list_length - probe_offset);
|
|
if (probe_increment == 0) {
|
|
break;
|
|
}
|
|
probe_offset += probe_increment;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case METHOD_ATTACH:
|
|
{
|
|
dissect_attachreqans(tvb, pinfo, message_body_tree, offset, message_body_length);
|
|
}
|
|
break;
|
|
|
|
case METHOD_APPATTACH:
|
|
{
|
|
/* Parse AppAttachReq/Ans */
|
|
|
|
{
|
|
guint16 local_offset = 0;
|
|
proto_item *ti_appattach;
|
|
proto_tree *appattach_tree;
|
|
ti_appattach = proto_tree_add_item(message_body_tree, hf_reload_appattach, tvb, offset+local_offset, message_body_length, FALSE);
|
|
appattach_tree = proto_item_add_subtree(ti_appattach, ett_reload_appattach);
|
|
local_offset += dissect_opaque(tvb, pinfo,appattach_tree, hf_reload_ufrag,offset+local_offset, 1, message_body_length-local_offset);
|
|
local_offset += dissect_opaque(tvb, pinfo,appattach_tree, hf_reload_password,offset+local_offset, 1, message_body_length-local_offset);
|
|
proto_tree_add_item(appattach_tree, hf_reload_application, tvb, offset+local_offset, 2, FALSE);
|
|
local_offset += 2;
|
|
local_offset += dissect_opaque(tvb, pinfo,appattach_tree, hf_reload_role,offset+local_offset, 1, message_body_length-local_offset);
|
|
dissect_icecandidates(tvb, pinfo, appattach_tree, offset+local_offset, message_body_length-local_offset);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case METHOD_PING:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_padding, offset, 2, message_body_length);
|
|
}
|
|
else {
|
|
if (message_body_length < 16) {
|
|
expert_add_info_format(pinfo, ti_message_contents, PI_PROTOCOL, PI_ERROR, "Truncated ping answer");
|
|
}
|
|
else {
|
|
proto_tree_add_item(message_body_tree, hf_reload_ping_response_id, tvb, offset, 8, FALSE);
|
|
proto_tree_add_item(message_body_tree, hf_reload_ping_time, tvb, offset + 8, 8, FALSE);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case METHOD_CONFIGUPDATE:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
guint16 local_offset = 0;
|
|
proto_item *ti_configupdate;
|
|
proto_tree *configupdate_tree;
|
|
guint8 configupdate_type;
|
|
guint32 configupdate_length;
|
|
ti_configupdate = proto_tree_add_item(message_body_tree, hf_reload_configupdatereq, tvb, offset+local_offset, message_body_length, FALSE);
|
|
configupdate_tree = proto_item_add_subtree(ti_configupdate, ett_reload_configupdatereq);
|
|
configupdate_type = tvb_get_guint8(tvb, offset + local_offset);
|
|
proto_tree_add_uint(configupdate_tree, hf_reload_configupdatereq_type, tvb, offset+local_offset, 1, configupdate_type);
|
|
local_offset += 1;
|
|
configupdate_length = tvb_get_ntohl(tvb, offset + local_offset);
|
|
proto_tree_add_uint(configupdate_tree, hf_reload_configupdatereq_length, tvb, offset + local_offset, 4, configupdate_length);
|
|
if (5 + configupdate_length > message_body_length) {
|
|
expert_add_info_format(pinfo, ti_configupdate, PI_PROTOCOL, PI_ERROR, "Truncated ConfigUpdateReq");
|
|
break;
|
|
}
|
|
local_offset += 4;
|
|
switch(configupdate_type) {
|
|
case CONFIGUPDATETYPE_CONFIG:
|
|
local_offset +=
|
|
dissect_opaque(tvb, pinfo, configupdate_tree, hf_reload_configupdatereq_configdata,
|
|
offset + local_offset, 3, configupdate_length);
|
|
|
|
break;
|
|
|
|
case CONFIGUPDATETYPE_KIND:
|
|
local_offset +=
|
|
dissect_opaque(tvb, pinfo, configupdate_tree, hf_reload_configupdatereq_kinds,
|
|
offset + local_offset, 3, configupdate_length);
|
|
break;
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
case METHOD_STORE:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
dissect_storereq(tvb, pinfo, message_body_tree, offset, message_body_length);
|
|
}
|
|
else {
|
|
guint16 storeans_kind_responses_length;
|
|
guint32 local_offset = 0;
|
|
proto_item *ti_storeans_kind_responses;
|
|
proto_tree *storeans_kind_responses_tree;
|
|
ti_storeans_kind_responses = proto_tree_add_item(message_body_tree, hf_reload_storeans_kind_responses, tvb, offset, message_body_length, FALSE);
|
|
storeans_kind_responses_tree = proto_item_add_subtree(ti_storeans_kind_responses, ett_reload_storeans_kind_responses);
|
|
storeans_kind_responses_length = tvb_get_ntohs(tvb, offset);
|
|
proto_tree_add_uint(storeans_kind_responses_tree, hf_reload_storeans_kind_responses_length, tvb, offset, 2, storeans_kind_responses_length);
|
|
if ((guint32)storeans_kind_responses_length + 2 > message_body_length) {
|
|
expert_add_info_format(pinfo, ti_storeans_kind_responses, PI_PROTOCOL, PI_ERROR, "Truncated StoreAns");
|
|
break;
|
|
}
|
|
while (local_offset + 4 + 8 + 2< storeans_kind_responses_length) {
|
|
proto_item *ti_storekindresponse;
|
|
proto_tree *storekindresponse_tree;
|
|
guint16 replicas_length;
|
|
replicas_length = tvb_get_ntohs(tvb, offset + 2 + local_offset +4 + 8);
|
|
if (local_offset + 4/*kindId*/ + 8/*generationcounter*/ + 2 +replicas_length > storeans_kind_responses_length) {
|
|
expert_add_info_format(pinfo, ti_storeans_kind_responses, PI_PROTOCOL, PI_ERROR, "Truncated StoreKindResponse");
|
|
break;
|
|
}
|
|
ti_storekindresponse =
|
|
proto_tree_add_item(storeans_kind_responses_tree, hf_reload_storekindresponse, tvb, offset+2+local_offset, 4+ 8 + 2 + replicas_length, FALSE);
|
|
storekindresponse_tree = proto_item_add_subtree(ti_storekindresponse, ett_reload_storekindresponse);
|
|
proto_tree_add_item(storekindresponse_tree, hf_reload_kindid, tvb, offset+2+local_offset, 4, FALSE);
|
|
local_offset += 4;
|
|
proto_tree_add_item(storekindresponse_tree, hf_reload_kinddata_generation_counter, tvb, offset+2+local_offset, 8, FALSE);
|
|
local_offset += 8;
|
|
{
|
|
guint16 replicas_length;
|
|
proto_item *ti_replicas;
|
|
proto_tree *replicas_tree;
|
|
guint16 replicas_offset = 0;
|
|
replicas_length = tvb_get_ntohs(tvb, offset + 2 + local_offset);
|
|
ti_replicas = proto_tree_add_item(storekindresponse_tree, hf_reload_storekindresponse_replicas, tvb,
|
|
offset+2+local_offset, 2 + replicas_length, FALSE);
|
|
replicas_tree = proto_item_add_subtree(storekindresponse_tree, ett_reload_storekindresponse_replicas);
|
|
proto_tree_add_uint(replicas_tree, hf_reload_opaque_length_uint16, tvb, offset + 2+local_offset, 2, replicas_length);
|
|
local_offset +=2;
|
|
while (replicas_offset < replicas_length) {
|
|
if ((replicas_offset + reload_nodeid_length) > replicas_length) {
|
|
expert_add_info_format(pinfo, ti_replicas, PI_PROTOCOL, PI_ERROR, "Truncated NodeID");
|
|
break;
|
|
}
|
|
proto_tree_add_item(replicas_tree, hf_reload_nodeid, tvb, offset+2+local_offset+replicas_offset,
|
|
reload_nodeid_length, FALSE);
|
|
replicas_offset += reload_nodeid_length;
|
|
}
|
|
local_offset += replicas_length;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case METHOD_FETCH:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
guint16 fetch_offset = 0;
|
|
fetch_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_resource_id, offset, 1, message_body_length);
|
|
fetch_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_storeddataspecifiers, offset + fetch_offset,
|
|
2, message_body_length - fetch_offset);
|
|
}
|
|
else {
|
|
/* response */
|
|
dissect_fetchans(tvb, pinfo, message_body_tree, offset, message_body_length);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case METHOD_STAT:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
guint16 stat_offset = 0;
|
|
stat_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_resource_id, offset, 1, message_body_length);
|
|
stat_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_storeddataspecifiers, offset + stat_offset,
|
|
2, message_body_length - stat_offset);
|
|
}
|
|
else {
|
|
dissect_statans(tvb, pinfo, message_body_tree, offset, message_body_length);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case METHOD_FIND:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
guint32 find_offset = 0;
|
|
guint8 kinds_length;
|
|
find_offset += dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_resource_id, offset, 1, message_body_length);
|
|
kinds_length = tvb_get_guint8(tvb, offset + find_offset);
|
|
if (find_offset + 1 + kinds_length > message_body_length) {
|
|
expert_add_info_format(pinfo, ti_message_body, PI_PROTOCOL, PI_ERROR, "Truncated FindRequest");
|
|
break;
|
|
}
|
|
proto_tree_add_uint(message_body_tree, hf_reload_findreq_kinds_length, tvb, offset + find_offset, 1, kinds_length);
|
|
find_offset += 1;
|
|
{
|
|
guint8 kinds_offset = 0;
|
|
while (kinds_offset < kinds_length) {
|
|
proto_tree_add_item(message_body_tree, hf_reload_kindid, tvb, offset+find_offset+kinds_offset, 4, FALSE);
|
|
|
|
kinds_offset += 4;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
guint16 results_length;
|
|
|
|
results_length = tvb_get_ntohs(tvb, offset);
|
|
if ((guint32)results_length + 2 > message_body_length) {
|
|
expert_add_info_format(pinfo, ti_message_body, PI_PROTOCOL, PI_ERROR, "Truncated FindAnswer");
|
|
break;
|
|
}
|
|
proto_tree_add_uint(message_body_tree, hf_reload_findans_results_length, tvb, offset, 2, results_length);
|
|
{
|
|
guint16 results_offset = 0;
|
|
while (results_offset < results_length) {
|
|
proto_item *ti_findkinddata;
|
|
proto_tree *findkinddata_tree;
|
|
guint16 findkinddata_length;
|
|
findkinddata_length = 4/*kind id */ + 1 + get_opaque_length(tvb,offset + 2 + results_offset + 4, 1)/* resourceId */;
|
|
if (results_offset + findkinddata_length > results_length) {
|
|
ti_findkinddata = proto_tree_add_item(message_body_tree, hf_reload_findkinddata, tvb, offset + results_offset, results_length - results_offset, FALSE);
|
|
expert_add_info_format(pinfo, ti_findkinddata, PI_PROTOCOL, PI_ERROR, "Truncated FindKindData");
|
|
break;
|
|
}
|
|
ti_findkinddata = proto_tree_add_item(message_body_tree, hf_reload_findkinddata, tvb, offset + 2 + results_offset, findkinddata_length, FALSE);
|
|
findkinddata_tree = proto_item_add_subtree(ti_findkinddata, ett_reload_findkinddata);
|
|
|
|
proto_tree_add_item(findkinddata_tree, hf_reload_kindid, tvb, offset + 2 + results_offset, 4, FALSE);
|
|
dissect_opaque(tvb, pinfo, findkinddata_tree, hf_reload_resource_id, offset + 2 + results_offset + 4, 1, results_length - 4 - results_offset);
|
|
|
|
results_offset += findkinddata_length;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case METHOD_LEAVE:
|
|
case METHOD_JOIN:
|
|
{
|
|
if (IS_REQUEST(message_code)) {
|
|
proto_tree_add_item(message_body_tree, hf_reload_nodeid, tvb, offset, reload_nodeid_length, FALSE);
|
|
dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_overlay_specific, offset + reload_nodeid_length, 2,
|
|
message_body_length - reload_nodeid_length);
|
|
}
|
|
else {
|
|
dissect_opaque(tvb, pinfo, message_body_tree, hf_reload_overlay_specific, offset, 2, message_body_length);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
/* Error Response */
|
|
guint16 error_length;
|
|
proto_item *ti_message_body;
|
|
proto_tree *message_body_tree;
|
|
proto_item *ti_error;
|
|
proto_tree *error_tree;
|
|
|
|
/* message_code was already parsed */
|
|
proto_tree_add_uint_format_value(message_contents_tree, hf_reload_message_code, tvb, offset, 2, message_code, "ERROR Response");
|
|
offset += 2;
|
|
|
|
/* Message body */
|
|
ti_message_body = proto_tree_add_item(message_contents_tree, hf_reload_message_body, tvb, offset, 4 + message_body_length, FALSE);
|
|
message_body_tree = proto_item_add_subtree(ti_message_body, ett_reload_message_body);
|
|
proto_tree_add_uint(message_body_tree, hf_reload_opaque_length_uint32, tvb, offset, 4, message_body_length);
|
|
offset +=4;
|
|
|
|
error_length = tvb_get_ntohs(tvb, offset + 2);
|
|
if ((guint)offset + 2 + 2 + error_length > msg_length) {
|
|
expert_add_info_format(pinfo, ti_message_body, PI_PROTOCOL, PI_ERROR, "Truncated error message");
|
|
return msg_length;
|
|
}
|
|
|
|
ti_error = proto_tree_add_item(message_body_tree, hf_reload_error_response, tvb, offset, 2 + 2 + error_length, FALSE);
|
|
error_tree = proto_item_add_subtree(ti_error, ett_reload_error_response);
|
|
proto_tree_add_item(error_tree, hf_reload_error_response_code, tvb, offset, 2, FALSE);
|
|
dissect_opaque(tvb, pinfo, error_tree, hf_reload_error_response_info, offset+2, 2, -1);
|
|
proto_item_append_text(error_tree, ": %s (%s)", val_to_str(error_code, errorcodes, "Unknown"), tvb_get_ephemeral_string(tvb, offset+4, error_length));
|
|
}
|
|
offset += message_body_length;
|
|
{
|
|
proto_tree *extension_tree;
|
|
guint16 extension_offset = 0;
|
|
|
|
proto_tree_add_item(message_contents_tree, hf_reload_message_extensions_length, tvb, offset, 4, FALSE);
|
|
offset += 4;
|
|
while (extension_offset < extensions_length) {
|
|
proto_item *ti_extension;
|
|
guint32 extension_content_length = tvb_get_ntohl(tvb, offset + extension_offset + 3);
|
|
if ((extension_offset + 3 + 4 + extension_content_length) > extensions_length) {
|
|
expert_add_info_format(pinfo, ti_message_contents, PI_PROTOCOL, PI_ERROR, "Truncated message extensions");
|
|
break;
|
|
}
|
|
ti_extension = proto_tree_add_item(message_contents_tree, hf_reload_message_extension, tvb, offset+ extension_offset, 3 + 4 + extension_content_length, FALSE);
|
|
extension_tree = proto_item_add_subtree(ti_extension, ett_reload_message_extension);
|
|
proto_tree_add_item(extension_tree, hf_reload_message_extension_type, tvb, offset+ extension_offset, 2, FALSE);
|
|
proto_tree_add_item(extension_tree, hf_reload_message_extension_critical, tvb, offset+ extension_offset + 2, 1, FALSE);
|
|
dissect_opaque(tvb, pinfo, extension_tree, hf_reload_message_extension_content, offset + extension_offset + 3, 4, -1);
|
|
extension_offset += 3 + 4 + extension_content_length;
|
|
}
|
|
}
|
|
offset += extensions_length;
|
|
}
|
|
|
|
/* Security Block */
|
|
{
|
|
proto_item *ti_security_block;
|
|
proto_tree *security_block_tree;
|
|
guint16 certificates_length;
|
|
guint16 signatureidentityvalue_length;
|
|
guint16 signaturevalue_length;
|
|
guint16 security_block_offset = 0;
|
|
|
|
certificates_length = tvb_get_ntohs(tvb, offset);
|
|
security_block_offset += 2 + certificates_length;
|
|
security_block_offset += 2; /* SignatureAndHashAlgorithm algorithm; */
|
|
security_block_offset += 1; /* SignerIdentityType identity_type; */
|
|
signatureidentityvalue_length = tvb_get_ntohs(tvb, offset +security_block_offset);
|
|
security_block_offset += 2;
|
|
security_block_offset += signatureidentityvalue_length;
|
|
signaturevalue_length = tvb_get_ntohs(tvb, offset +security_block_offset);
|
|
security_block_offset += 2;
|
|
security_block_offset += signaturevalue_length;
|
|
|
|
ti_security_block = proto_tree_add_item(reload_tree, hf_reload_security_block, tvb, offset,
|
|
security_block_offset, FALSE);
|
|
security_block_tree = proto_item_add_subtree(ti_security_block, ett_reload_security_block);
|
|
/* start parsing from the beginning */
|
|
security_block_offset = 0;
|
|
proto_tree_add_uint(security_block_tree, hf_reload_certificates_length, tvb, offset, 2, certificates_length);
|
|
security_block_offset += 2;
|
|
/* certificates */
|
|
{
|
|
guint16 certificate_offset = 0;
|
|
while (certificate_offset < certificates_length) {
|
|
proto_item *ti_certificate;
|
|
proto_tree *certificate_tree;
|
|
guint16 certificate_length;
|
|
|
|
certificate_length = tvb_get_ntohs(tvb, offset + security_block_offset + certificate_offset + 1);
|
|
if (certificate_offset + 1 + 2 + certificate_length > certificates_length) {
|
|
expert_add_info_format(pinfo, ti_security_block, PI_PROTOCOL, PI_ERROR, "Truncated certificate");
|
|
break;
|
|
}
|
|
ti_certificate = proto_tree_add_item(security_block_tree,
|
|
hf_reload_certificates, tvb, offset + security_block_offset + certificate_offset,
|
|
1 + 2 + certificate_length,
|
|
FALSE);
|
|
certificate_tree = proto_item_add_subtree(ti_certificate, ett_reload_certificate);
|
|
|
|
proto_tree_add_item(certificate_tree, hf_reload_certificate_type, tvb,
|
|
offset + security_block_offset + certificate_offset, 1, FALSE);
|
|
switch (tvb_get_guint8(tvb, offset + security_block_offset + certificate_offset)) {
|
|
case 0: {
|
|
asn1_ctx_t asn1_ctx;
|
|
|
|
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
|
|
dissect_x509af_Certificate(FALSE, tvb, offset + security_block_offset + certificate_offset + 1 + 2, &asn1_ctx,
|
|
certificate_tree, hf_reload_certificate);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dissect_opaque(tvb, pinfo, certificate_tree, hf_reload_certificate, offset + security_block_offset + certificate_offset + 1,
|
|
2, -1);
|
|
}
|
|
certificate_offset += 1 + 2 + certificate_length;
|
|
}
|
|
}
|
|
security_block_offset += certificates_length;
|
|
|
|
/* Signature */
|
|
{
|
|
proto_item *ti_signature;
|
|
proto_tree *signature_tree;
|
|
|
|
ti_signature = proto_tree_add_item(security_block_tree,
|
|
hf_reload_signature, tvb, offset+security_block_offset ,
|
|
2 +/* SignatureAndHashAlgorithm */
|
|
1 + 2 + signatureidentityvalue_length +/* SignatureIdenty length*/
|
|
2 + signaturevalue_length,
|
|
FALSE);
|
|
signature_tree = proto_item_add_subtree(ti_signature, ett_reload_signature);
|
|
proto_tree_add_item(signature_tree, hf_reload_hash_algorithm, tvb,
|
|
offset + security_block_offset, 1, FALSE);
|
|
security_block_offset += 1;
|
|
proto_tree_add_item(signature_tree, hf_reload_signature_algorithm, tvb,
|
|
offset + security_block_offset, 1, FALSE);
|
|
security_block_offset += 1;
|
|
/* SignatureIdentity */
|
|
{
|
|
proto_item *ti_signatureidentity;
|
|
proto_tree *signatureidentity_tree;
|
|
guint8 identity_type;
|
|
ti_signatureidentity = proto_tree_add_item(signature_tree,
|
|
hf_reload_signature_identity,
|
|
tvb, offset+security_block_offset,
|
|
1 + 2 + signatureidentityvalue_length,
|
|
FALSE);
|
|
signatureidentity_tree = proto_item_add_subtree(ti_signatureidentity, ett_reload_signature_identity);
|
|
identity_type = tvb_get_guint8(tvb, offset + security_block_offset);
|
|
proto_tree_add_item(signatureidentity_tree, hf_reload_signature_identity_type, tvb,
|
|
offset + security_block_offset, 1, FALSE);
|
|
security_block_offset += 1;
|
|
proto_tree_add_uint(signatureidentity_tree, hf_reload_signature_identity_length, tvb,
|
|
offset + security_block_offset, 2, signatureidentityvalue_length);
|
|
security_block_offset += 2;
|
|
{
|
|
guint16 signatureidentityvalue_offset = 0;
|
|
while (signatureidentityvalue_offset < signatureidentityvalue_length) {
|
|
proto_item *ti_signatureidentityvalue;
|
|
proto_tree *signatureidentityvalue_tree;
|
|
if (identity_type == SIGNATUREIDENTITYTYPE_CERTHASH) {
|
|
guint8 certificate_hash_length;
|
|
|
|
certificate_hash_length = tvb_get_guint8(tvb, offset + security_block_offset + signatureidentityvalue_offset + 1);
|
|
if (signatureidentityvalue_offset + 1 + 1 + certificate_hash_length > signatureidentityvalue_length) {
|
|
expert_add_info_format(pinfo, ti_signatureidentity, PI_PROTOCOL, PI_ERROR, "Truncated signature identity value");
|
|
break;
|
|
}
|
|
ti_signatureidentityvalue= proto_tree_add_item(signatureidentity_tree,
|
|
hf_reload_signature_identity_value,
|
|
tvb, offset + security_block_offset + signatureidentityvalue_offset,
|
|
1 + 1 + certificate_hash_length,
|
|
FALSE);
|
|
signatureidentityvalue_tree = proto_item_add_subtree(ti_signatureidentityvalue, ett_reload_signature_identity_value);
|
|
proto_tree_add_item(signatureidentityvalue_tree, hf_reload_hash_algorithm, tvb,
|
|
offset + security_block_offset +signatureidentityvalue_offset, 1, FALSE);
|
|
dissect_opaque(tvb, pinfo, signatureidentityvalue_tree, hf_reload_signature_identity_value_certificate_hash, offset + security_block_offset + signatureidentityvalue_offset+1, 1, -1);
|
|
signatureidentityvalue_offset += 1 + 1 + certificate_hash_length;
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, ti_signatureidentity, PI_PROTOCOL, PI_ERROR, "Unknown identity type");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
security_block_offset += signatureidentityvalue_length;
|
|
}
|
|
dissect_opaque(tvb, pinfo, signature_tree, hf_reload_signature_value, offset + security_block_offset, 2, -1);
|
|
}
|
|
}
|
|
|
|
|
|
return msg_length;
|
|
}
|
|
|
|
static void
|
|
dissect_reload_message_no_return(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
{
|
|
dissect_reload_message(tvb, pinfo, tree);
|
|
}
|
|
|
|
static gboolean
|
|
dissect_reload_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
{
|
|
if (dissect_reload_message(tvb, pinfo, tree) == 0) {
|
|
/*
|
|
* It wasn't a valid RELOAD message, and wasn't
|
|
* dissected as such.
|
|
*/
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
proto_register_reload(void)
|
|
{
|
|
module_t *reload_module;
|
|
static hf_register_info hf[] = {
|
|
{ &hf_reload_response_in,
|
|
{ "Response in", "reload.response-in", FT_FRAMENUM,
|
|
BASE_NONE, NULL, 0x0, "The response to this RELOAD Request is in this frame", HFILL }
|
|
},
|
|
{ &hf_reload_response_to,
|
|
{ "Request in", "reload.response-to", FT_FRAMENUM,
|
|
BASE_NONE, NULL, 0x0, "This is a response to the RELOAD Request in this frame", HFILL }
|
|
},
|
|
{ &hf_reload_time,
|
|
{ "Time", "reload.time", FT_RELATIVE_TIME,
|
|
BASE_NONE, NULL, 0x0, "The time between the Request and the Response", HFILL }
|
|
},
|
|
{ &hf_reload_duplicate,
|
|
{ "Duplicated original message in", "reload.duplicate", FT_FRAMENUM,
|
|
BASE_NONE, NULL, 0x0, "This is a duplicate of RELOAD message in this frame", HFILL }
|
|
},
|
|
{ &hf_reload_forwarding,
|
|
{ "Forwarding header", "reload.forwarding", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_token,
|
|
{ "RELOAD token", "reload.forwarding.token", FT_UINT32,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_overlay,
|
|
{ "Overlay", "reload.forwarding.overlay", FT_UINT32,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_configuration_sequence,
|
|
{ "Configuration sequence", "reload.forwarding.configuration_sequence", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_version,
|
|
{ "Version", "reload.forwarding.version", FT_UINT8,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ttl,
|
|
{ "TTL", "reload.forwarding.ttl", FT_UINT8,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fragment_flag,
|
|
{ "Fragment", "reload.forwarding.fragment", FT_UINT32,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fragment_fragmented,
|
|
{ "Fragmented bit", "reload.forwarding.fragment.fragmented", FT_BOOLEAN, 1, TFS(&tfs_set_notset), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fragment_last_fragment,
|
|
{ "Last fragment bit", "reload.forwarding.fragment.last", FT_BOOLEAN, 1, TFS(&tfs_set_notset), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fragment_reserved,
|
|
{ "Reserved", "reload.forwarding.fragment.reserved", FT_BOOLEAN, 1, NULL, 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fragment_offset,
|
|
{ "Fragment offset","reload.forwarding.fragment.offset", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_length,
|
|
{ "Length", "reload.forwarding.length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_trans_id,
|
|
{ "Transaction ID", "reload.forwarding.trans_id", FT_UINT64,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_max_response_length,
|
|
{ "Max response length", "reload.forwarding.max_response_length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_via_list_length,
|
|
{ "Via-list length", "reload.forwarding.via_list.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination_list_length,
|
|
{ "Destination list length", "reload.forwarding.destination_list.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_options_length,
|
|
{ "Options length", "reload.forwarding.options.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_via_list,
|
|
{ "via list", "reload.forwarding.via_list", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination,
|
|
{ "Destination", "reload.forwarding.destination", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination_compressed,
|
|
{ "Destination (compressed)", "reload.forwarding.destination.compressed_id", FT_UINT16,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination_type,
|
|
{ "Destination type", "reload.forwarding.destination.type", FT_UINT8,
|
|
BASE_HEX, VALS(destinationtypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination_length,
|
|
{ "Destination length", "reload.forwarding.destination.length", FT_UINT8,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_nodeid,
|
|
{ "Node ID", "reload.nodeid", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_resource_id,
|
|
{ "Resource ID", "reload.resource_id", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination_data_compressed_id,
|
|
{ "Compressed ID", "reload.destination.data.compressed_id", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_destination_list,
|
|
{ "Destination list", "reload.forwarding.destination_list", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option,
|
|
{ "Forwarding option", "reload.forwarding.option", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_type,
|
|
{ "Forwarding option type", "reload.forwarding.option.type", FT_UINT8,
|
|
BASE_DEC, VALS(forwardingoptiontypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_flags,
|
|
{ "Forwarding option flags", "reload.forwarding.option.flags", FT_UINT8,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_length,
|
|
{ "Forwarding option length", "forwarding.option.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_data,
|
|
{ "Forwarding option data", "reload.forwarding.option.data", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_flag_response_copy,
|
|
{ "Response copy", "reload.forwarding.option.flag.response_copy", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_flag_destination_critical,
|
|
{ "Response destination critical", "reload.forwarding.option.flags.destination_critical", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_reload_forwarding_option_flag_forward_critical,
|
|
{ "Forward critical", "reload.forwarding.option.flags.forward_critical", FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x0,
|
|
NULL, HFILL }
|
|
},
|
|
{ &hf_reload_attachreqans,
|
|
{ "AttachReqAns", "reload.attachreqans", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ufrag,
|
|
{ "Ufrag", "reload.ufrag", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_password,
|
|
{ "Password", "reload.password", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_role,
|
|
{ "Role", "reload.role", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidates,
|
|
{ "Ice candidates", "reload.icecandidates", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidates_length,
|
|
{ "Ice candidates length", "reload.icecandidates.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate,
|
|
{ "Ice candidate", "reload.icecandidate", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_relay_addr,
|
|
{ "Relay address", "reload.icecandidate.relay_addr", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_srflx_addr,
|
|
{ "Srflx address", "reload.icecandidate.srflx_addr", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_prflx_addr,
|
|
{ "Prfkx address", "reload.icecandidate.prflx_addr", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ipaddressport,
|
|
{ "IP address port", "reload.ipaddressport", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ipaddressport_type,
|
|
{ "IP address-port type", "reload.ipaddressport.type", FT_UINT8,
|
|
BASE_HEX, VALS(ipaddressporttypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ipaddressport_length,
|
|
{ "IP address-port length", "reload.ipaddressport.length", FT_UINT8,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ipv4addr,
|
|
{ "IPv4 address", "reload.ipv4addr", FT_IPv4,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ipv6addr,
|
|
{ "IPv6 address", "reload.ipv6addr", FT_IPv6,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_port,
|
|
{ "Port", "reload.port", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_overlaylink_type,
|
|
{ "Overlay Link Type", "reload.overlaylink.type", FT_UINT8,
|
|
BASE_DEC, VALS(overlaylinktypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_foundation,
|
|
{ "Ice candidate foundation", "reload.icecandidate.foundation", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_priority,
|
|
{ "Ice candidate priority", "reload.icecandidate.priority", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_type,
|
|
{ "Ice candidate type", "reload.icecandidate.type", FT_UINT8,
|
|
BASE_DEC, VALS(candtypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_icecandidate_extensions_length,
|
|
{ "Ice candidate extensions length", "reload.icecandidate.extensions_length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_iceextension,
|
|
{ "Ice extension", "reload.iceextension", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_iceextension_name,
|
|
{ "Ice extension name", "reload.iceextension.name", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_iceextension_value,
|
|
{ "Ice extension value", "reload.iceextension.value", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_sendupdate,
|
|
{ "SendUpdate", "reload.sendupdate", FT_BOOLEAN,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_contents,
|
|
{ "Message contents", "reload.message.contents", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_code,
|
|
{ "Message code", "reload.message.code", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_body,
|
|
{ "Message body", "reload.message.body", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_extensions_length,
|
|
{ "Message extensions length", "reload.message.extensions.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_extension,
|
|
{ "Message extension", "reload.message_extension", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_extension_type,
|
|
{ "Message extension type", "reload.message_extension.type", FT_UINT16,
|
|
BASE_DEC, VALS(messageextensiontypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_extension_critical,
|
|
{ "Message extension critical", "reload.message_extension.critical", FT_BOOLEAN,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_message_extension_content,
|
|
{ "Message extension content", "reload.message_extension.content", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_error_response,
|
|
{ "Error response", "reload.error_response", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_error_response_code,
|
|
{ "Error code", "reload.error_response.code", FT_UINT16,
|
|
BASE_DEC, VALS(errorcodes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_error_response_info,
|
|
{ "Error info", "reload.error_response_info", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_security_block,
|
|
{ "Security block", "reload.security_block", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_certificates_length,
|
|
{ "Certificates length", "reload.certificates.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_certificates,
|
|
{ "Certificates", "reload.certificates", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_certificate_type,
|
|
{ "Certificate type", "reload.certificate.type", FT_UINT8,
|
|
BASE_DEC, VALS(tls_certificate_type), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_certificate,
|
|
{ "Certificate", "reload.certificate", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature,
|
|
{ "Signature", "reload.signature", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_hash_algorithm,
|
|
{ "Hash algorithm", "reload.hash_algorithm", FT_UINT8,
|
|
BASE_DEC, VALS(tls_hash_algorithm), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_algorithm,
|
|
{ "Signature algorithm", "reload.signature_algorithm", FT_UINT8,
|
|
BASE_DEC, VALS(tls_signature_algorithm), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_identity,
|
|
{ "Signature identity", "reload.signature.identity", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_identity_type,
|
|
{ "Signature identity type", "reload.signature.identity.type", FT_UINT8,
|
|
BASE_DEC, VALS(signatureidentitytypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_identity_length,
|
|
{ "Signature identity length", "reload.signature.identity.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_identity_value,
|
|
{ "Signature identity value", "reload.signature.identity.value", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_identity_value_certificate_hash,
|
|
{ "Signature identity value certificate hash", "reload.signature.identity.value.certificate_hash", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_signature_value,
|
|
{ "Signature value", "reload.signature.value.", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_opaque_length_uint8,
|
|
{ "Opaque length", "reload.opaque.length.8", FT_UINT8,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_opaque_length_uint16,
|
|
{ "Opaque length", "reload.opaque.length.16", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_opaque_length_uint32,
|
|
{ "Opaque length", "reload.opaque.length.32", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_opaque_data,
|
|
{ "Data", "reload.opaque.length.8", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_routequeryreq,
|
|
{ "RouteQueryReq", "reload.routequeryreq", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_overlay_specific,
|
|
{ "Overlay specific data", "reload.overlay.specific.data", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_probereq,
|
|
{ "ProbeReq", "reload.probereq", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_probe_information,
|
|
{ "Probe information", "reload.probe_information", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_probe_information_type,
|
|
{ "Probe information type", "reload.probe_information.type", FT_UINT8,
|
|
BASE_HEX, VALS(probeinformationtypes), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_responsible_set,
|
|
{ "Responsible set", "reload.responsible_set", FT_UINT32,
|
|
BASE_HEX, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_num_resources,
|
|
{ "Num resources", "reload.num_resources", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_uptime,
|
|
{ "Uptime", "reload.uptime", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_probeans,
|
|
{ "Probe ans", "reload.probeans", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_appattach,
|
|
{ "App attach req/ans", "reload.appattach", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_application,
|
|
{ "Application", "reload.application", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ping_response_id,
|
|
{ "Ping response ID", "reload.ping.response_id", FT_UINT64,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_ping_time,
|
|
{ "Ping time", "reload.ping.time", FT_UINT64,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeddata,
|
|
{ "Stored data", "reload.storeddata", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeddata_length,
|
|
{ "Stored data length", "reload.storeddata.length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeddata_storage_time,
|
|
{ "Stored data storage time", "reload.storeddata.storage_time", FT_UINT64,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeddata_lifetime,
|
|
{ "Stored lifetime", "reload.storeddata.lifetime", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_kinddata,
|
|
{ "Kind data", "reload.kinddata", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_kindid,
|
|
{ "Kind ID", "reload.kindid", FT_UINT32,
|
|
BASE_DEC, VALS(datakindids), 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_kinddata_generation_counter,
|
|
{ "Generation counter", "reload.kinddata.generation_counter", FT_UINT64,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_kinddata_values_length,
|
|
{ "Values length", "reload.kinddata.values_length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storereq,
|
|
{ "StoreReq", "reload.storereq", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_store_replica_num,
|
|
{ "Replica num", "reload.store.replica_num", FT_UINT8,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_store_kind_data_length,
|
|
{ "StoreReq kind data length", "reload.store.kind_data.length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeans_kind_responses,
|
|
{ "Kind responses", "reload.storeans.kind_responses", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeans_kind_responses_length,
|
|
{ "Kind responses length", "reload.storeans.kind_responses.length", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storekindresponse,
|
|
{ "Store kind response", "reload.storekindresponse", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storekindresponse_replicas,
|
|
{ "Store kind response replicas", "reload.storekindresponse.replicas", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_storeddataspecifiers,
|
|
{ "StoredDataSpecifiers", "reload.storeddataspecifiers", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fetchans,
|
|
{ "FetchAns", "reload.fetchans", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_kind_responses_length,
|
|
{ "Kind responses length", "reload.fetchans.kind_responses.length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_statans,
|
|
{ "StatAns", "reload.statans", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_findreq_kinds_length,
|
|
{ "Kinds length", "reload.findreq.kindslength", FT_UINT8,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_findans_results_length,
|
|
{ "Results length", "reload.findans.resultsslength", FT_UINT16,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_findkinddata,
|
|
{ "FindKindData", "reload.findkinddata", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
{ &hf_reload_fragment_overlap,
|
|
{ "Fragment overlap", "reload.fragment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
|
|
"Fragment overlaps with other fragments", HFILL }},
|
|
|
|
{ &hf_reload_fragment_overlap_conflict,
|
|
{ "Conflicting data in fragment overlap", "reload.fragment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
|
|
"Overlapping fragments contained conflicting data", HFILL }},
|
|
|
|
{ &hf_reload_fragment_multiple_tails,
|
|
{ "Multiple tail fragments found", "reload.fragment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
|
|
"Several tails were found when defragmenting the packet", HFILL }},
|
|
|
|
{ &hf_reload_fragment_too_long_fragment,
|
|
{ "Fragment too long", "reload.fragment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
|
|
"Fragment contained data past end of packet", HFILL }},
|
|
|
|
{ &hf_reload_fragment_error,
|
|
{ "Defragmentation error", "reload.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
|
"Defragmentation error due to illegal fragments", HFILL }},
|
|
|
|
{ &hf_reload_fragment_count,
|
|
{ "Fragment count", "reload.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL}},
|
|
|
|
{ &hf_reload_fragment,
|
|
{ "RELOAD fragment", "reload.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_reload_fragments,
|
|
{ "RELOAD fragments", "reload.fragments", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_reload_reassembled_in,
|
|
{ "Reassembled RELOAD in frame", "reload.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
|
|
"This RELOAD packet is reassembled in this frame", HFILL }},
|
|
|
|
{ &hf_reload_reassembled_length,
|
|
{ "Reassembled RELOAD length", "reload.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
"The total length of the reassembled payload", HFILL}},
|
|
|
|
{ &hf_reload_configupdatereq,
|
|
{ "ConfigUpdate req", "reload.configupdatereq.", FT_BYTES,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
|
|
{ &hf_reload_configupdatereq_type,
|
|
{ "ConfigUpdate req type", "reload.configupdatereq.type", FT_UINT8,
|
|
BASE_DEC, VALS(configupdatetypes), 0x0, NULL, HFILL }
|
|
},
|
|
|
|
{ &hf_reload_configupdatereq_length,
|
|
{ "ConfigUpdate req length", "reload.configupdatereq.length", FT_UINT32,
|
|
BASE_DEC, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
|
|
{ &hf_reload_configupdatereq_configdata,
|
|
{ "ConfigUpdate req config data", "reload.configupdatereq.config_data", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
|
|
{ &hf_reload_configupdatereq_kinds,
|
|
{ "ConfigUpdate req kinds", "reload.configupdatereq.kinds", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
|
|
{ &hf_reload_padding,
|
|
{ "Padding", "reload.padding", FT_NONE,
|
|
BASE_NONE, NULL, 0x0, NULL, HFILL }
|
|
},
|
|
|
|
};
|
|
|
|
/* Setup protocol subtree array */
|
|
static gint *ett[] = {
|
|
&ett_reload,
|
|
&ett_reload_forwarding,
|
|
&ett_reload_message,
|
|
&ett_reload_security,
|
|
&ett_reload_fragment_flag,
|
|
&ett_reload_destination,
|
|
&ett_reload_via_list,
|
|
&ett_reload_destination_list,
|
|
&ett_reload_forwarding_option,
|
|
&ett_reload_forwarding_option_flags,
|
|
&ett_reload_forwarding_option_directresponseforwarding,
|
|
&ett_reload_attachreqans,
|
|
&ett_reload_icecandidates,
|
|
&ett_reload_icecandidate,
|
|
&ett_reload_icecandidate_computed_address,
|
|
&ett_reload_iceextension,
|
|
&ett_reload_ipaddressport,
|
|
&ett_reload_message_contents,
|
|
&ett_reload_message_extension,
|
|
&ett_reload_error_response,
|
|
&ett_reload_security_block,
|
|
&ett_reload_certificate,
|
|
&ett_reload_signature,
|
|
&ett_reload_signature_identity,
|
|
&ett_reload_signature_identity_value,
|
|
&ett_reload_opaque,
|
|
&ett_reload_message_body,
|
|
&ett_reload_routequeryreq,
|
|
&ett_reload_probereq,
|
|
&ett_reload_probe_information,
|
|
&ett_reload_probeans,
|
|
&ett_reload_appattach,
|
|
&ett_reload_storeddata,
|
|
&ett_reload_kinddata,
|
|
&ett_reload_storereq,
|
|
&ett_reload_storeans_kind_responses,
|
|
&ett_reload_storekindresponse,
|
|
&ett_reload_fetchans,
|
|
&ett_reload_statans,
|
|
&ett_reload_findkinddata,
|
|
&ett_reload_fragments,
|
|
&ett_reload_fragment,
|
|
&ett_reload_configupdatereq,
|
|
&ett_reload_storekindresponse_replicas,
|
|
};
|
|
|
|
/* Register the protocol name and description */
|
|
proto_reload = proto_register_protocol("REsource LOcation And Discovery", "RELOAD", "reload");
|
|
register_dissector("reload", dissect_reload_message_no_return, proto_reload);
|
|
/* Required function calls to register the header fields and subtrees used */
|
|
proto_register_field_array(proto_reload, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
reload_module = prefs_register_protocol(proto_reload, NULL);
|
|
prefs_register_bool_preference(reload_module, "defragment",
|
|
"Reassemble fragmented reload datagrams",
|
|
"Whether fragmented RELOAD datagrams should be reassembled",
|
|
&reload_defragment);
|
|
prefs_register_uint_preference(reload_module, "nodeid_length",
|
|
"NodeId Length",
|
|
"Length of the NodeId as defined in the overlay.",
|
|
10,
|
|
&reload_nodeid_length);
|
|
|
|
|
|
register_init_routine(reload_defragment_init);
|
|
}
|
|
|
|
void
|
|
proto_reg_handoff_reload(void)
|
|
{
|
|
|
|
data_handle = find_dissector("data");
|
|
|
|
heur_dissector_add("udp", dissect_reload_heur, proto_reload);
|
|
heur_dissector_add("tcp", dissect_reload_heur, proto_reload);
|
|
|
|
}
|
|
|
|
/*
|
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
*
|
|
* Local variables:
|
|
* c-basic-offset: 2
|
|
* tab-width: 2
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* vi: set shiftwidth=2 tabstop=2 expandtab
|
|
* :indentSize=2:tabSize=2:noTabs=true:
|
|
*/
|