wireshark/epan/dissectors/packet-do-irp.c

2169 lines
82 KiB
C

/* packet-do-irp.c
* Dissector for Digital Object Identifier Resolution Protocol (DO-IRP)
*
* Copyright (c) 2023 by Martin Mayer <martin.mayer@m2-it-solutions.de>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/*
* This dissector is based on:
*
* - Title: Digital Object Identifier Resolution Protocol Specification
* Version: 3.0 (June 30, 2022)
* Author: DONA Foundation (https://www.dona.net)
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/expert.h>
#include "packet-tcp.h"
/* N.B. IANA has these ports registered for hdl-srv (name from original RFC) */
#define DO_IRP_UDP_PORT 2641
#define DO_IRP_TCP_PORT 2641
#define DO_IRP_ENVELOPE_LEN 20
#define DO_IRP_MAX_UDP_SIZE 512
void proto_register_do_irp(void);
void proto_reg_handoff_do_irp(void);
static dissector_handle_t do_irp_handle_udp;
static dissector_handle_t do_irp_handle_tcp;
static int proto_do_irp;
expert_module_t* expert_do_irp;
/* Fields Generic */
static int hf_do_irp_string_len;
static int hf_do_irp_string_value;
static int hf_do_irp_data_len;
static int hf_do_irp_data_value;
/* Fields Message Envelope */
static int hf_do_irp_envelope;
static int hf_do_irp_version_major;
static int hf_do_irp_version_minor;
static int hf_do_irp_flags;
static int hf_do_irp_flag_cp;
static int hf_do_irp_flag_ec;
static int hf_do_irp_flag_tc;
static int hf_do_irp_version_major_sugg;
static int hf_do_irp_version_minor_sugg;
static int hf_do_irp_sessid;
static int hf_do_irp_reqid;
static int hf_do_irp_seq;
static int hf_do_irp_msglen;
/* Fields Message Header */
static int hf_do_irp_header;
static int hf_do_irp_opcode;
static int hf_do_irp_responsecode;
static int hf_do_irp_opflags;
static int hf_do_irp_opflags_at;
static int hf_do_irp_opflags_ct;
static int hf_do_irp_opflags_enc;
static int hf_do_irp_opflags_rec;
static int hf_do_irp_opflags_ca;
static int hf_do_irp_opflags_cn;
static int hf_do_irp_opflags_kc;
static int hf_do_irp_opflags_po;
static int hf_do_irp_opflags_rd;
static int hf_do_irp_opflags_owe;
static int hf_do_irp_opflags_mns;
static int hf_do_irp_opflags_dnr;
static int hf_do_irp_sisn;
static int hf_do_irp_rcount;
static int hf_do_irp_expiration;
static int hf_do_irp_bodylen;
/* Fields Message Body */
static int hf_do_irp_body;
static int hf_do_irp_digest_algo;
static int hf_do_irp_digest;
static int hf_do_irp_error_msg;
static int hf_do_irp_error_idxcount;
static int hf_do_irp_error_idx;
static int hf_do_irp_ident;
static int hf_do_irp_idxcount;
static int hf_do_irp_idx;
static int hf_do_irp_typecount;
static int hf_do_irp_type;
static int hf_do_irp_identcount;
static int hf_do_irp_identrecord;
static int hf_do_irp_identrecord_idx;
static int hf_do_irp_identrecord_type;
static int hf_do_irp_identrecord_value;
static int hf_do_irp_identrecord_value_string;
static int hf_do_irp_identrecord_value_len;
static int hf_do_irp_identrecord_perm;
static int hf_do_irp_identrecord_perm_pw;
static int hf_do_irp_identrecord_perm_pr;
static int hf_do_irp_identrecord_perm_aw;
static int hf_do_irp_identrecord_perm_ar;
static int hf_do_irp_identrecord_ttl_type;
static int hf_do_irp_identrecord_ttl;
static int hf_do_irp_identrecord_ttl_absolute;
static int hf_do_irp_identrecord_ts;
static int hf_do_irp_identrecord_ts_utc;
static int hf_do_irp_identrecord_refcount;
static int hf_do_irp_identrecord_ref;
static int hf_do_irp_hsadmin_perm;
static int hf_do_irp_hsadmin_perm_ai;
static int hf_do_irp_hsadmin_perm_di;
static int hf_do_irp_hsadmin_perm_adp;
static int hf_do_irp_hsadmin_perm_me;
static int hf_do_irp_hsadmin_perm_de;
static int hf_do_irp_hsadmin_perm_ae;
static int hf_do_irp_hsadmin_perm_ma;
static int hf_do_irp_hsadmin_perm_ra;
static int hf_do_irp_hsadmin_perm_aa;
static int hf_do_irp_hsadmin_perm_ar;
static int hf_do_irp_hsadmin_perm_li;
static int hf_do_irp_hsadmin_perm_ldp;
static int hf_do_irp_hsadmin_idx;
static int hf_do_irp_hsadmin_ident;
static int hf_do_irp_body_hssite_version;
static int hf_do_irp_hssite_protoversion_major;
static int hf_do_irp_hssite_protoversion_minor;
static int hf_do_irp_hssite_serial;
static int hf_do_irp_hssite_primask;
static int hf_do_irp_hssite_primask_pri;
static int hf_do_irp_hssite_primask_multi;
static int hf_do_irp_hssite_hashoption;
static int hf_do_irp_hssite_hashfilter;
static int hf_do_irp_hssite_attr_count;
static int hf_do_irp_hssite_attr;
static int hf_do_irp_hssite_attr_key;
static int hf_do_irp_hssite_attr_value;
static int hf_do_irp_hssite_srvcount;
static int hf_do_irp_hssite_srv;
static int hf_do_irp_hssite_srv_id;
static int hf_do_irp_hssite_srv_addr;
static int hf_do_irp_pkrec;
static int hf_do_irp_pkrec_len;
static int hf_do_irp_pkrec_type;
static int hf_do_irp_pkrec_dsa_q;
static int hf_do_irp_pkrec_dsa_p;
static int hf_do_irp_pkrec_dsa_g;
static int hf_do_irp_pkrec_dsa_y;
static int hf_do_irp_pkrec_rsa_exp;
static int hf_do_irp_pkrec_rsa_mod;
static int hf_do_irp_pkrec_dh_p;
static int hf_do_irp_pkrec_dh_g;
static int hf_do_irp_pkrec_dh_y;
static int hf_do_irp_hssite_srv_if;
static int hf_do_irp_hssite_srv_ifcount;
static int hf_do_irp_hssite_srv_if_type;
static int hf_do_irp_hssite_srv_if_type_admin;
static int hf_do_irp_hssite_srv_if_type_res;
static int hf_do_irp_hssite_srv_if_proto;
static int hf_do_irp_hssite_srv_if_port;
static int hf_do_irp_hsserv_ident;
static int hf_do_irp_hsvlist_count;
static int hf_do_irp_hsvlist_ref;
static int hf_do_irp_hsalias;
static int hf_do_irp_hsnamespace;
static int hf_do_irp_hscert_jwt;
static int hf_do_irp_hssignature_jwt;
static int hf_do_irp_refident;
static int hf_do_irp_nonce;
static int hf_do_irp_authtype;
static int hf_do_irp_keyident;
static int hf_do_irp_keyidx;
static int hf_do_irp_challresp;
static int hf_do_irp_veri_result;
static int hf_do_irp_ignoredident;
static int hf_do_irp_keyexmode;
static int hf_do_irp_timeout;
/* Fields Message Credential */
static int hf_do_irp_credential;
static int hf_do_irp_credential_len;
static int hf_do_irp_credential_sesscounter;
static int hf_do_irp_credential_type;
static int hf_do_irp_credential_signedinfo;
static int hf_do_irp_credential_signedinfo_len;
static int hf_do_irp_credential_signedinfo_algo;
static int hf_do_irp_credential_signedinfo_sig;
/* Conversation */
static int hf_do_irp_response_in;
static int hf_do_irp_response_to;
/* Fragment handling */
static int hf_msg_fragments;
static int hf_msg_fragment;
static int hf_msg_fragment_overlap;
static int hf_msg_fragment_overlap_conflicts;
static int hf_msg_fragment_multiple_tails;
static int hf_msg_fragment_too_long_fragment;
static int hf_msg_fragment_error;
static int hf_msg_fragment_count;
static int hf_msg_reassembled_in;
static int hf_msg_reassembled_len;
static int hf_msg_reassembled_data;
/* Expert fields */
static expert_field ei_do_irp_digest_unknown;
static expert_field ei_do_irp_frag_wo_tc;
/* Trees */
static gint ett_do_irp;
static gint ett_do_irp_string;
static gint ett_do_irp_envelope;
static gint ett_do_irp_envelope_flags;
static gint ett_do_irp_header;
static gint ett_do_irp_header_flags;
static gint ett_do_irp_body;
static gint ett_do_irp_credential;
static gint ett_do_irp_credential_signedinfo;
static gint ett_do_irp_identifier_record;
static gint ett_do_irp_element_permission_flags;
static gint ett_do_irp_element_hsadmin_permission_flags;
static gint ett_do_irp_element_hsadmin_primary_flags;
static gint ett_do_irp_hsadmin;
static gint ett_do_irp_hssite;
static gint ett_do_irp_hssite_attribute;
static gint ett_do_irp_hssite_server;
static gint ett_do_irp_hssite_server_if;
static gint ett_do_irp_hssite_server_if_flags;
static gint ett_do_irp_pk;
static gint ett_msg_fragment;
static gint ett_msg_fragments;
static const fragment_items msg_frag_items = {
&ett_msg_fragment,
&ett_msg_fragments,
&hf_msg_fragments,
&hf_msg_fragment,
&hf_msg_fragment_overlap,
&hf_msg_fragment_overlap_conflicts,
&hf_msg_fragment_multiple_tails,
&hf_msg_fragment_too_long_fragment,
&hf_msg_fragment_error,
&hf_msg_fragment_count,
&hf_msg_reassembled_in,
&hf_msg_reassembled_len,
&hf_msg_reassembled_data,
"Message fragments"
};
/* Request Hashmap Key */
struct do_irp_request_hash_key {
guint32 conv_index;
guint32 reqid;
};
/* Request Hashmap Val */
struct do_irp_request_hash_val {
guint32 pnum;
guint32 pnum_resp;
guint32 opcode;
};
static wmem_map_t *do_irp_request_hash_map = NULL;
#define DO_IRP_OC_RESERVED 0
#define DO_IRP_OC_RESOLUTION 1
#define DO_IRP_OC_GET_SITEINFO 2
#define DO_IRP_OC_CREATE_ID 100
#define DO_IRP_OC_DELETE_ID 101
#define DO_IRP_OC_ADD_ELEMENT 102
#define DO_IRP_OC_REMOVE_ELEMENT 103
#define DO_IRP_OC_MODIFY_ELEMENT 104
#define DO_IRP_OC_LIST_IDS 105
#define DO_IRP_OC_LIST_DERIVED_PREFIXES 106
#define DO_IRP_OC_CHALLENGE_RESPONSE 200
#define DO_IRP_OC_VERIFY_RESPONSE 201
#define DO_IRP_OC_HOME_PREFIX 300
#define DO_IRP_OC_UNHOME_PREFIX 301
#define DO_IRP_OC_LIST_HOMED_PREFIXES 302
#define DO_IRP_OC_SESSION_SETUP 400
#define DO_IRP_OC_SESSION_TERMINATE 401
static const value_string opcode_vals[] = {
{ DO_IRP_OC_RESERVED, "RESERVED" },
{ DO_IRP_OC_RESOLUTION, "RESOLUTION" },
{ DO_IRP_OC_GET_SITEINFO, "GET_SITEINFO" },
{ DO_IRP_OC_CREATE_ID, "CREATE_ID" },
{ DO_IRP_OC_DELETE_ID, "DELETE_ID" },
{ DO_IRP_OC_ADD_ELEMENT, "ADD_ELEMENT" },
{ DO_IRP_OC_REMOVE_ELEMENT, "REMOVE_ELEMENT" },
{ DO_IRP_OC_MODIFY_ELEMENT, "MODIFY_ELEMENT" },
{ DO_IRP_OC_LIST_IDS, "LIST_IDS" },
{ DO_IRP_OC_LIST_DERIVED_PREFIXES, "LIST_DERIVED_PREFIXES" },
{ DO_IRP_OC_CHALLENGE_RESPONSE, "CHALLENGE_RESPONSE" },
{ DO_IRP_OC_VERIFY_RESPONSE, "VERIFY_RESPONSE" },
{ DO_IRP_OC_HOME_PREFIX, "HOME_PREFIX" },
{ DO_IRP_OC_UNHOME_PREFIX, "UNHOME_PREFIX" },
{ DO_IRP_OC_LIST_HOMED_PREFIXES, "LIST_HOMED_PREFIXES" },
{ DO_IRP_OC_SESSION_SETUP, "SESSION_SETUP" },
{ DO_IRP_OC_SESSION_TERMINATE, "SESSION_TERMINATE" },
{ 0, NULL },
};
#define DO_IRP_RC_RESERVED 0
#define DO_IRP_RC_SUCCESS 1
#define DO_IRP_RC_ERROR 2
#define DO_IRP_RC_SERVER_BUSY 3
#define DO_IRP_RC_PROTOCOL_ERROR 4
#define DO_IRP_RC_OPERATION_DENIED 5
#define DO_IRP_RC_RECUR_LIMIT_EXCEEDED 6
#define DO_IRP_RC_SERVER_BACKUP 7
#define DO_IRP_RC_ID_NOT_FOUND 100
#define DO_IRP_RC_ID_ALREADY_EXIST 101
#define DO_IRP_RC_INVALID_ID 102
#define DO_IRP_RC_ELEMENT_NOT_FOUND 200
#define DO_IRP_RC_ELEMENT_ALREADY_EXIST 201
#define DO_IRP_RC_ELEMENT_INVALID 202
#define DO_IRP_RC_EXPIRED_SITE_INFO 300
#define DO_IRP_RC_SERVER_NOT_RESP 301
#define DO_IRP_RC_SERVICE_REFERRAL 302
#define DO_IRP_RC_PREFIX_REFERRAL 303
#define DO_IRP_RC_INVALID_ADMIN 400
#define DO_IRP_RC_ACCESS_DENIED 401
#define DO_IRP_RC_AUTHEN_NEEDED 402
#define DO_IRP_RC_AUTHEN_FAILED 403
#define DO_IRP_RC_INVALID_CREDENTIAL 404
#define DO_IRP_RC_AUTHEN_TIMEOUT 405
#define DO_IRP_RC_UNABLE_TO_AUTHEN 406
#define DO_IRP_RC_SESSION_TIMEOUT 500
#define DO_IRP_RC_SESSION_FAILED 501
#define DO_IRP_RC_SESSION_KEY_INVALID 502
#define DO_IRP_RC_SESSION_MSG_REJECTED 505
static const value_string responsecode_vals[] = {
{ DO_IRP_RC_RESERVED, "RESERVED" },
{ DO_IRP_RC_SUCCESS, "SUCCESS" },
{ DO_IRP_RC_ERROR, "ERROR" },
{ DO_IRP_RC_SERVER_BUSY, "SERVER_BUSY" },
{ DO_IRP_RC_PROTOCOL_ERROR, "PROTOCOL_ERROR" },
{ DO_IRP_RC_OPERATION_DENIED, "OPERATION_DENIED" },
{ DO_IRP_RC_RECUR_LIMIT_EXCEEDED, "RECUR_LIMIT_EXCEEDED" },
{ DO_IRP_RC_SERVER_BACKUP, "SERVER_BACKUP" },
{ DO_IRP_RC_ID_NOT_FOUND, "ID_NOT_FOUND" },
{ DO_IRP_RC_ID_ALREADY_EXIST, "ID_ALREADY_EXIST" },
{ DO_IRP_RC_INVALID_ID, "INVALID_ID" },
{ DO_IRP_RC_ELEMENT_NOT_FOUND, "ELEMENT_NOT_FOUND" },
{ DO_IRP_RC_ELEMENT_ALREADY_EXIST, "ELEMENT_ALREADY_EXIST" },
{ DO_IRP_RC_ELEMENT_INVALID, "ELEMENT_INVALID" },
{ DO_IRP_RC_EXPIRED_SITE_INFO, "EXPIRED_SITE_INFO" },
{ DO_IRP_RC_SERVER_NOT_RESP, "SERVER_NOT_RESP" },
{ DO_IRP_RC_SERVICE_REFERRAL, "SERVICE_REFERRAL" },
{ DO_IRP_RC_PREFIX_REFERRAL, "PREFIX_REFERRAL" },
{ DO_IRP_RC_INVALID_ADMIN, "INVALID_ADMIN" },
{ DO_IRP_RC_ACCESS_DENIED, "ACCESS_DENIED" },
{ DO_IRP_RC_AUTHEN_NEEDED, "AUTHEN_NEEDED" },
{ DO_IRP_RC_AUTHEN_FAILED, "AUTHEN_FAILED" },
{ DO_IRP_RC_INVALID_CREDENTIAL, "INVALID_CREDENTIAL" },
{ DO_IRP_RC_AUTHEN_TIMEOUT, "AUTHEN_TIMEOUT" },
{ DO_IRP_RC_UNABLE_TO_AUTHEN, "UNABLE_TO_AUTHEN" },
{ DO_IRP_RC_SESSION_TIMEOUT, "SESSION_TIMEOUT" },
{ DO_IRP_RC_SESSION_FAILED, "SESSION_FAILED" },
{ DO_IRP_RC_SESSION_KEY_INVALID, "SESSION_KEY_INVALID" },
{ DO_IRP_RC_SESSION_MSG_REJECTED, "SESSION_MSG_REJECTED" },
{ 0, NULL },
};
#define DO_IRP_DIGEST_ALGO_MD5 1
#define DO_IRP_DIGEST_ALGO_SHA1 2
#define DO_IRP_DIGEST_ALGO_SHA256 3
static const value_string digest_algo_vals[] = {
{ DO_IRP_DIGEST_ALGO_MD5, "MD5" },
{ DO_IRP_DIGEST_ALGO_SHA1, "SHA-1" },
{ DO_IRP_DIGEST_ALGO_SHA256, "SHA-256" },
{ 0, NULL },
};
#define DO_IRP_TTL_RELATIVE 0
#define DO_IRP_TTL_ABSOLUTE 1
static const value_string ttl_vals[] = {
{ DO_IRP_TTL_RELATIVE, "relative" },
{ DO_IRP_TTL_ABSOLUTE, "absolute" },
{ 0, NULL },
};
static const value_string hashoption_vals[] = {
{ 0x0, "HASH_BY_PREFIX" },
{ 0x1, "HASH_BY_SUFFIX" },
{ 0x2, "HASH_BY_IDENTIFIER" },
{ 0, NULL },
};
static const value_string transportproto_vals[] = {
{ 0x0, "UDP" },
{ 0x1, "TCP" },
{ 0x2, "HTTP" },
{ 0x3, "HTTPS" },
{ 0, NULL },
};
static const value_string verification_resp_vals[] = {
{ 0x0, "Fail" },
{ 0x1, "Match" },
{ 0, NULL },
};
static const value_string key_exchange_vals[] = {
{ 0x4, "Diffie-Hellman" },
{ 0, NULL },
};
static reassembly_table do_irp_reassemble_table;
/* wmem hash/equal funcs */
static guint
do_irp_handle_hash (gconstpointer v)
{
const struct do_irp_request_hash_key *key = (const struct do_irp_request_hash_key *)v;
guint val;
val = key->conv_index + key->reqid;
return val;
}
static gint
do_irp_handle_equal(gconstpointer v, gconstpointer w)
{
const struct do_irp_request_hash_key *v1 = (const struct do_irp_request_hash_key *)v;
const struct do_irp_request_hash_key *v2 = (const struct do_irp_request_hash_key *)w;
if (
v1->conv_index == v2->conv_index &&
v1->reqid == v2->reqid
)
{
return 1;
}
return 0;
}
/*
* Decodes a string to the given hf and adds it to a tree
* All "strings" are defined as 4 octets representing the length of of the actual string,
* followed by the octets representing the actual string.
*
* Passed hf must be of any FT_STRING type
*
* Returns length of the dissected string
* length, value_of_string and string_tree can be used by the calling function.
*/
static gint
decode_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, int hf, const char **value_of_string)
{
guint32 len = tvb_get_gint32(tvb, offset, ENC_BIG_ENDIAN);
proto_item *ti;
const char *text = tvb_get_string_enc(pinfo->pool, tvb, offset+4, len, ENC_UTF_8);
if(len) {
ti = proto_tree_add_string_format_value(tree, hf, tvb, offset, len + 4, text, "%s, Len: %u", text, len);
} else {
ti = proto_tree_add_string_format_value(tree, hf, tvb, offset, len + 4, text, "empty, Len: %u", len);
}
proto_tree *string_tree = proto_item_add_subtree(ti, ett_do_irp_string);
proto_tree_add_item(string_tree, hf_do_irp_string_len, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(string_tree, hf_do_irp_string_value, tvb, offset + 4, len, ENC_UTF_8);
if(value_of_string != NULL) {
*value_of_string = text;
}
return len + 4;
}
/*
* Decodes generic byte-values to the given hf and adds it to a tree
*
* Returns length of the dissected value
*/
static gint
decode_generic_data(tvbuff_t *tvb, proto_tree *tree, gint offset, int hf)
{
guint32 len = tvb_get_gint32(tvb, offset, ENC_BIG_ENDIAN);
proto_item *ti = proto_tree_add_item(tree, hf, tvb, offset, len + 4, ENC_NA);
proto_tree *string_tree = proto_item_add_subtree(ti, ett_do_irp_string);
proto_tree_add_item(string_tree, hf_do_irp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(string_tree, hf_do_irp_data_value, tvb, offset + 4, len, ENC_NA);
return len + 4;
}
/*
* Decodes public key data (e.g. in HS_SITE, HS_PUBKEY)
*
* Returns length of the dissected data
*/
static gint
decode_pk_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
gint len = 0;
guint32 pk_len = tvb_get_guint32(tvb, offset + len, ENC_BIG_ENDIAN);
proto_item *ti = proto_tree_add_item(tree, hf_do_irp_pkrec, tvb, offset, pk_len + 4, ENC_NA);
proto_tree *pk_tree = proto_item_add_subtree(ti, ett_do_irp_pk);
proto_tree_add_item(pk_tree, hf_do_irp_pkrec_len, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
const char *pk_type;
gint pk_type_len = decode_string(tvb, pinfo, pk_tree, offset + len, hf_do_irp_pkrec_type, &pk_type);
len += pk_type_len;
len += 2; /* Reserved */
proto_item_append_text(pk_tree, " (%s)", pk_type);
if(!strcmp("DSA_PUB_KEY", pk_type)) {
len += decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dsa_q);
len += decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dsa_p);
len += decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dsa_g);
decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dsa_y);
}
else if(!strcmp("RSA_PUB_KEY", pk_type)) {
len += decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_rsa_exp);
decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_rsa_mod);
/* len += 4; */ /* unused, 4 empty bytes */
}
else if(!strcmp("DH_PUB_KEY", pk_type)) {
len += decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dh_y);
len += decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dh_p);
decode_generic_data(tvb, pk_tree, offset + len, hf_do_irp_pkrec_dh_g);
}
/* else: undefined, not dissectable */
return pk_len + 4;
}
/*
* Decodes a HS_ADMIN element
*
* Returns length of the dissected data
*/
static gint
decode_hsadmin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
gint len = 0;
proto_tree *ti_hsadmin = proto_tree_add_item(tree, hf_do_irp_identrecord_value, tvb, offset + len, -1, ENC_NA);
proto_tree *do_irp_hsadmin_tree = proto_item_add_subtree(ti_hsadmin, ett_do_irp_hsadmin);
proto_tree_add_item(do_irp_hsadmin_tree, hf_do_irp_identrecord_value_len, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
static int* const hsadmin_permission_bits[] = {
&hf_do_irp_hsadmin_perm_ldp,
&hf_do_irp_hsadmin_perm_li,
&hf_do_irp_hsadmin_perm_ar,
&hf_do_irp_hsadmin_perm_aa,
&hf_do_irp_hsadmin_perm_ra,
&hf_do_irp_hsadmin_perm_ma,
&hf_do_irp_hsadmin_perm_ae,
&hf_do_irp_hsadmin_perm_de,
&hf_do_irp_hsadmin_perm_me,
&hf_do_irp_hsadmin_perm_adp,
&hf_do_irp_hsadmin_perm_di,
&hf_do_irp_hsadmin_perm_ai,
NULL
};
proto_tree_add_bitmask(do_irp_hsadmin_tree, tvb, offset + len, hf_do_irp_hsadmin_perm, ett_do_irp_element_hsadmin_permission_flags, hsadmin_permission_bits, ENC_BIG_ENDIAN);
len += 2;
const char *admin_identifier;
len += decode_string(tvb, pinfo, do_irp_hsadmin_tree, offset + len, hf_do_irp_hsadmin_ident, &admin_identifier);
proto_tree_add_item(do_irp_hsadmin_tree, hf_do_irp_hsadmin_idx, tvb, offset + len, 4, ENC_BIG_ENDIAN);
proto_item_append_text(ti_hsadmin, " %s, Index: %u", admin_identifier, tvb_get_guint32(tvb, offset + len, ENC_BIG_ENDIAN));
len += 4;
proto_item_set_len(ti_hsadmin, len);
return len;
}
/*
* Decodes a HS_SITE element
*
* Returns length of the dissected data
*/
static gint
decode_hssite(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
gint len = 0;
proto_tree *ti_hssite = proto_tree_add_item(tree, hf_do_irp_identrecord_value, tvb, offset + len, -1, ENC_NA);
proto_tree *do_irp_hssite_tree = proto_item_add_subtree(ti_hssite, ett_do_irp_hssite);
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_identrecord_value_len, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_body_hssite_version, tvb, offset + len, 2, ENC_BIG_ENDIAN);
len += 2;
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_protoversion_major, tvb, offset + len, 1, ENC_BIG_ENDIAN);
len += 1;
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_protoversion_minor, tvb, offset + len, 1, ENC_BIG_ENDIAN);
len += 1;
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_serial, tvb, offset + len, 2, ENC_BIG_ENDIAN);
len += 2;
static int* const hssite_primary_bits[] = {
&hf_do_irp_hssite_primask_pri,
&hf_do_irp_hssite_primask_multi,
NULL
};
proto_tree_add_bitmask(do_irp_hssite_tree, tvb, offset + len, hf_do_irp_hssite_primask, ett_do_irp_element_hsadmin_primary_flags, hssite_primary_bits, ENC_BIG_ENDIAN);
len += 1;
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_hashoption, tvb, offset + len, 1, ENC_BIG_ENDIAN);
len += 1;
len += decode_string(tvb, pinfo, do_irp_hssite_tree, offset + len, hf_do_irp_hssite_hashfilter, NULL);
guint32 attr = tvb_get_guint32(tvb, offset + len, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_attr_count, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
for(guint32 i = 0; i < attr; i++) {
proto_tree *ti_hssite_attr = proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_attr, tvb, offset + len, -1, ENC_NA);
proto_tree *do_irp_hssite_attr_tree = proto_item_add_subtree(ti_hssite_attr, ett_do_irp_hssite_attribute);
gint attr_len = 0;
const char *attr_name;
attr_len += decode_string(tvb, pinfo, do_irp_hssite_attr_tree, offset + len + attr_len, hf_do_irp_hssite_attr_key, &attr_name);
attr_len += decode_string(tvb, pinfo, do_irp_hssite_attr_tree, offset + len + attr_len, hf_do_irp_hssite_attr_value, NULL);
len += attr_len;
proto_item_append_text(do_irp_hssite_attr_tree, " (%s)", attr_name);
proto_item_set_len(ti_hssite_attr, attr_len);
}
guint32 serv = tvb_get_guint32(tvb, offset + len, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_srvcount, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
for(guint32 i = 0; i < serv; i++) {
proto_tree *ti_hssite_serv = proto_tree_add_item(do_irp_hssite_tree, hf_do_irp_hssite_srv, tvb, offset + len, -1, ENC_NA);
proto_tree *do_irp_hssite_serv_tree = proto_item_add_subtree(ti_hssite_serv, ett_do_irp_hssite_server);
gint serv_len = 0;
proto_tree_add_item(do_irp_hssite_serv_tree, hf_do_irp_hssite_srv_id, tvb, offset + len + serv_len, 4, ENC_BIG_ENDIAN);
proto_item_append_text(do_irp_hssite_serv_tree, " (ID: %u)", tvb_get_guint32(tvb, offset + len + serv_len, ENC_BIG_ENDIAN));
serv_len += 4;
proto_tree_add_item(do_irp_hssite_serv_tree, hf_do_irp_hssite_srv_addr, tvb, offset + len + serv_len, 16, ENC_NA);
serv_len += 16;
serv_len += decode_pk_data(tvb, pinfo, do_irp_hssite_serv_tree, offset + len + serv_len);
guint32 servif = tvb_get_guint32(tvb, offset + len + serv_len, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_hssite_serv_tree, hf_do_irp_hssite_srv_ifcount, tvb, offset + len + serv_len, 4, ENC_BIG_ENDIAN);
serv_len += 4;
for(guint32 j = 0; j < servif; j++) {
proto_tree *ti_hssite_serv_if = proto_tree_add_item(do_irp_hssite_serv_tree, hf_do_irp_hssite_srv_if, tvb, offset + len + serv_len, 6, ENC_NA);
proto_tree *do_irp_hssite_serv_if_tree = proto_item_add_subtree(ti_hssite_serv_if, ett_do_irp_hssite_server_if);
static int* const hsadmin_srv_if_type_bits[] = {
&hf_do_irp_hssite_srv_if_type_res,
&hf_do_irp_hssite_srv_if_type_admin,
NULL
};
proto_tree_add_bitmask(do_irp_hssite_serv_if_tree, tvb, offset + len + serv_len, hf_do_irp_hssite_srv_if_type, ett_do_irp_hssite_server_if_flags, hsadmin_srv_if_type_bits, ENC_BIG_ENDIAN);
serv_len += 1;
guint8 serv_if_proto = tvb_get_guint8(tvb, offset + len + serv_len);
proto_tree_add_item(do_irp_hssite_serv_if_tree, hf_do_irp_hssite_srv_if_proto, tvb, offset + len + serv_len, 1, ENC_BIG_ENDIAN);
serv_len += 1;
guint32 serv_if_port = tvb_get_guint32(tvb, offset + len + serv_len, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_hssite_serv_if_tree, hf_do_irp_hssite_srv_if_port, tvb, offset + len + serv_len, 4, ENC_BIG_ENDIAN);
serv_len += 4;
proto_item_append_text(do_irp_hssite_serv_if_tree, " (%s:%u)",
val_to_str_const(serv_if_proto, transportproto_vals, "Unknown"),
serv_if_port
);
}
proto_item_set_len(ti_hssite_serv, serv_len);
len += serv_len;
}
proto_item_set_len(ti_hssite, len);
return len;
}
/*
* Decodes an identifier record
*
* Returns length of the dissected record
*/
static gint
decode_identifier_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
gint len = 0;
const char *type_string;
proto_item *ti = proto_tree_add_item(tree, hf_do_irp_identrecord, tvb, offset, -1, ENC_NA);
proto_tree *do_irp_record_tree = proto_item_add_subtree(ti, ett_do_irp_identifier_record);
proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_idx, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_ts, tvb, offset + len, 4, ENC_BIG_ENDIAN);
proto_item *ts = proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_ts_utc, tvb, offset + len, 4, ENC_TIME_SECS);
proto_item_set_generated(ts);
len += 4;
guint8 ttl_type = tvb_get_guint8(tvb, offset + len);
proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_ttl_type, tvb, offset + len, 1, ENC_BIG_ENDIAN);
len += 1;
proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_ttl, tvb, offset + len, 4, ENC_BIG_ENDIAN);
if(ttl_type == DO_IRP_TTL_ABSOLUTE) {
proto_item *ttl = proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_ttl_absolute, tvb, offset + len, 4, ENC_TIME_SECS);
proto_item_set_generated(ttl);
}
len += 4;
static int* const permission_bits[] = {
&hf_do_irp_identrecord_perm_ar,
&hf_do_irp_identrecord_perm_aw,
&hf_do_irp_identrecord_perm_pr,
&hf_do_irp_identrecord_perm_pw,
NULL
};
proto_tree_add_bitmask(do_irp_record_tree, tvb, offset + len, hf_do_irp_identrecord_perm, ett_do_irp_element_permission_flags, permission_bits, ENC_BIG_ENDIAN);
len += 1;
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_identrecord_type, &type_string);
proto_item_append_text(do_irp_record_tree, " (%s)", type_string);
if(!strcmp("HS_ADMIN", type_string)) {
len += decode_hsadmin(tvb, pinfo, do_irp_record_tree, offset + len);
}
else if(!strcmp("HS_SITE", type_string) || !strcmp("HS_SITE.PREFIX", type_string)) {
len += decode_hssite(tvb, pinfo, do_irp_record_tree, offset + len);
}
else if(!strcmp("HS_SERV", type_string) || !strcmp("HS_SERV.PREFIX", type_string)) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_hsserv_ident, NULL);
}
else if(!strcmp("HS_PUBKEY", type_string)) {
len += decode_pk_data(tvb, pinfo, do_irp_record_tree, offset + len);
}
else if(!strcmp("HS_VLIST", type_string)) {
guint32 refs = tvb_get_guint32(tvb, offset + len, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_record_tree, hf_do_irp_hsvlist_count, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
for(guint32 i = 0; i < refs; i++) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_hsvlist_ref, NULL);
}
}
else if(!strcmp("HS_NAMESPACE", type_string)) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_hsnamespace, NULL);
}
else if(!strcmp("HS_ALIAS", type_string)) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_hsalias, NULL);
}
else if(!strcmp("HS_CERT", type_string)) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_hscert_jwt, NULL);
}
else if(!strcmp("HS_SIGNATURE", type_string)) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_hssignature_jwt, NULL);
}
else if(
!strcmp("DESC", type_string) ||
!strcmp("EMAIL", type_string) ||
!strcmp("URL", type_string)
) {
/* generic string */
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_identrecord_value_string, NULL);
}
else {
/* generic data */
len += decode_generic_data(tvb, do_irp_record_tree, offset + len, hf_do_irp_identrecord_value);
}
guint32 references = tvb_get_guint32(tvb, offset + len, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_record_tree, hf_do_irp_identrecord_refcount, tvb, offset + len, 4, ENC_BIG_ENDIAN);
len += 4;
for(guint32 i = 0; i < references; i++) {
len += decode_string(tvb, pinfo, do_irp_record_tree, offset + len, hf_do_irp_identrecord_ref, NULL);
}
proto_item_set_len(ti, len);
return len;
}
/*
* Decodes message envelope
*
* Returns length of the dissected record
* It also sets reqid (Request ID) and encrypted (the encrypted bit)
*/
static int
decode_envelope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 *reqid, gboolean *encrypted)
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DO-IRP");
col_clear(pinfo->cinfo,COL_INFO);
gint offset = 0;
/* Message Envelope */
proto_item *ti_envelope = proto_tree_add_item(tree, hf_do_irp_envelope, tvb, offset, 20, ENC_NA);
proto_tree *do_irp_envelope_tree = proto_item_add_subtree(ti_envelope, ett_do_irp_envelope);
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_version_major, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_version_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
static int* const envelope_flag_bits[] = {
&hf_do_irp_flag_cp,
&hf_do_irp_flag_ec,
&hf_do_irp_flag_tc,
NULL
};
*encrypted = (gboolean)tvb_get_bits8(tvb, offset*8 + 1, 1);
proto_tree_add_bitmask(do_irp_envelope_tree, tvb, offset, hf_do_irp_flags, ett_do_irp_envelope_flags, envelope_flag_bits, ENC_BIG_ENDIAN);
proto_tree_add_bits_item(do_irp_envelope_tree, hf_do_irp_version_major_sugg, tvb, offset*8+3, 5, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_version_minor_sugg, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_sessid, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
*reqid = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_reqid, tvb, offset, 4, ENC_BIG_ENDIAN);
col_append_fstr(pinfo->cinfo, COL_INFO, "ReqID=%u", tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN));
offset += 4;
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_seq, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(do_irp_envelope_tree, hf_do_irp_msglen, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
return offset;
}
/*
* Decodes message header, body and credential record
*
* Returns length of the dissected record
*/
static int
decode_header_body_credential(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 reqid)
{
conversation_t *conversation;
struct do_irp_request_hash_key request_key, *new_request_key;
struct do_irp_request_hash_val *request_val = NULL;
proto_item *r_pkt;
/* Message Header */
proto_item *ti_header = proto_tree_add_item(tree, hf_do_irp_header, tvb, 0, 24, ENC_NA);
proto_tree *do_irp_header_tree = proto_item_add_subtree(ti_header, ett_do_irp_header);
gint offset = 0;
guint32 opcode = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_header_tree, hf_do_irp_opcode, tvb, offset, 4, ENC_BIG_ENDIAN);
const char *opcode_text = val_to_str_const(tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN), opcode_vals, "Unknown OpCode");
offset += 4;
guint32 respcode = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_header_tree, hf_do_irp_responsecode, tvb, offset, 4, ENC_BIG_ENDIAN);
const char *respcode_text = val_to_str_const(tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN), responsecode_vals, "Unknown RespCode");
offset += 4;
col_append_fstr(pinfo->cinfo, COL_INFO, " [%s, %s]", opcode_text, respcode_text);
static int* const header_flag_bits[] = {
&hf_do_irp_opflags_at,
&hf_do_irp_opflags_ct,
&hf_do_irp_opflags_enc,
&hf_do_irp_opflags_rec,
&hf_do_irp_opflags_ca,
&hf_do_irp_opflags_cn,
&hf_do_irp_opflags_kc,
&hf_do_irp_opflags_po,
&hf_do_irp_opflags_rd,
&hf_do_irp_opflags_owe,
&hf_do_irp_opflags_mns,
&hf_do_irp_opflags_dnr,
NULL
};
proto_tree_add_bitmask(do_irp_header_tree, tvb, offset, hf_do_irp_opflags, ett_do_irp_header_flags, header_flag_bits, ENC_BIG_ENDIAN);
guint32 header_opflags = tvb_get_ntohl(tvb, offset);
offset += 4;
proto_tree_add_item(do_irp_header_tree, hf_do_irp_sisn, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(do_irp_header_tree, hf_do_irp_rcount, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 2; /* One byte empty */
proto_tree_add_item(do_irp_header_tree, hf_do_irp_expiration, tvb, offset, 4, ENC_TIME_SECS);
offset += 4;
proto_tree_add_item(do_irp_header_tree, hf_do_irp_bodylen, tvb, offset, 4, ENC_BIG_ENDIAN);
guint32 body_len = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
offset += 4;
/* Message Body */
if(tvb_captured_length_remaining(tvb, offset) > 0 && body_len > 0) {
proto_item *ti_body = proto_tree_add_item(tree, hf_do_irp_body, tvb, offset, body_len, ENC_NA);
proto_tree *do_irp_body_tree = proto_item_add_subtree(ti_body, ett_do_irp_body);
gint body_start_offset = offset;
/* If RD bit is set, body must start with message digest (response only) */
if(header_opflags & 0x800000 && respcode > DO_IRP_RC_RESERVED) {
proto_tree_add_item(do_irp_body_tree, hf_do_irp_digest_algo, tvb, offset, 1, ENC_NA);
offset += 1;
switch (tvb_get_guint8(tvb, offset-1)) {
case DO_IRP_DIGEST_ALGO_MD5:
proto_tree_add_item(do_irp_body_tree, hf_do_irp_digest, tvb, offset, 16, ENC_NA);
offset += 16;
break;
case DO_IRP_DIGEST_ALGO_SHA1:
proto_tree_add_item(do_irp_body_tree, hf_do_irp_digest, tvb, offset, 20, ENC_NA);
offset += 20;
break;
case DO_IRP_DIGEST_ALGO_SHA256:
proto_tree_add_item(do_irp_body_tree, hf_do_irp_digest, tvb, offset, 32, ENC_NA);
offset += 32;
break;
default:
expert_add_info(pinfo, do_irp_body_tree, &ei_do_irp_digest_unknown);
/* We are now unable to dissect further because the fields now have variable length */
call_data_dissector(
tvb_new_subset_length(tvb, offset, -1), pinfo, do_irp_body_tree);
return tvb_captured_length(tvb);
}
}
if(opcode == DO_IRP_OC_RESOLUTION && respcode == DO_IRP_RC_RESERVED) { /* Query */
const char *identifier_text;
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ident, &identifier_text);
col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", identifier_text);
guint32 index_entries = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_idxcount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < index_entries; i++) {
proto_tree_add_item(do_irp_body_tree, hf_do_irp_idx, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
guint32 type_entries = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_typecount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < type_entries; i++) {
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_type, NULL);
}
}
else if(
(opcode == DO_IRP_OC_RESOLUTION && respcode == DO_IRP_RC_SUCCESS) || /* Successful query response */
(opcode == DO_IRP_OC_ADD_ELEMENT && respcode == DO_IRP_RC_RESERVED) || /* Add elements request */
(opcode == DO_IRP_OC_MODIFY_ELEMENT && respcode == DO_IRP_RC_RESERVED) || /* Modify elements request */
(opcode == DO_IRP_OC_CREATE_ID && respcode == DO_IRP_RC_RESERVED) /* Create identifier request */
) {
const char *identifier_text;
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ident, &identifier_text);
col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", identifier_text);
guint32 element_entries = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_identcount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < element_entries; i++) {
offset += decode_identifier_record(tvb, pinfo, do_irp_body_tree, offset);
}
}
if(opcode == DO_IRP_OC_REMOVE_ELEMENT && respcode == DO_IRP_RC_RESERVED) { /* Remove elements request */
const char *identifier_text;
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ident, &identifier_text);
col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", identifier_text);
guint32 index_entries = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_idxcount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < index_entries; i++) {
proto_tree_add_item(do_irp_body_tree, hf_do_irp_idx, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
}
else if( /* Referral response */
(opcode == DO_IRP_OC_RESOLUTION && respcode == DO_IRP_RC_SERVICE_REFERRAL) ||
(opcode == DO_IRP_OC_RESOLUTION && respcode == DO_IRP_RC_PREFIX_REFERRAL)
) {
const char *refident;
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_refident, &refident);
/* The following identifier records only exist if ReferralIdentifier is not provided, otherwise it must be empty */
if(strlen(refident) == 0) {
guint32 element_entries = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_identcount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < element_entries; i++) {
offset += decode_identifier_record(tvb, pinfo, do_irp_body_tree, offset);
}
}
}
else if(opcode == DO_IRP_OC_VERIFY_RESPONSE && respcode == DO_IRP_RC_SUCCESS) { /* Challenge response verification response */
proto_tree_add_item(do_irp_body_tree, hf_do_irp_veri_result, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
}
else if(opcode == DO_IRP_OC_VERIFY_RESPONSE && respcode == DO_IRP_RC_RESERVED) { /* Challenge response verification */
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_keyident, NULL);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_keyidx, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
offset += decode_generic_data(tvb, do_irp_body_tree, offset, hf_do_irp_nonce);
offset += decode_generic_data(tvb, do_irp_body_tree, offset, hf_do_irp_digest);
offset += decode_generic_data(tvb, do_irp_body_tree, offset, hf_do_irp_challresp);
}
else if(opcode == DO_IRP_OC_CHALLENGE_RESPONSE && respcode == DO_IRP_RC_RESERVED) { /* Challenge response (client -> server) */
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_authtype, NULL);
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_keyident, NULL);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_keyidx, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
offset += decode_generic_data(tvb, do_irp_body_tree, offset, hf_do_irp_challresp);
}
else if(respcode == DO_IRP_RC_AUTHEN_NEEDED) { /* Challenge (server -> client) */
offset += decode_generic_data(tvb, do_irp_body_tree, offset, hf_do_irp_nonce);
}
else if(
(opcode == DO_IRP_OC_GET_SITEINFO && respcode == DO_IRP_RC_RESERVED) || /* GetSiteInfo request */
(opcode == DO_IRP_OC_LIST_HOMED_PREFIXES && respcode == DO_IRP_RC_RESERVED) /* List homed prefixes request */
) {
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ignoredident, NULL);
}
else if(opcode == DO_IRP_OC_GET_SITEINFO && respcode == DO_IRP_RC_SUCCESS) { /* GetSiteInfo response */
offset += decode_hssite(tvb, pinfo, do_irp_body_tree, offset);
}
else if(
(opcode == DO_IRP_OC_CREATE_ID && respcode == DO_IRP_RC_SUCCESS) || /* Create identifier response */
(opcode == DO_IRP_OC_DELETE_ID && respcode == DO_IRP_RC_RESERVED) || /* Delete identifier request */
(opcode == DO_IRP_OC_LIST_IDS && respcode == DO_IRP_RC_RESERVED) || /* List IDs request */
(opcode == DO_IRP_OC_LIST_DERIVED_PREFIXES && respcode == DO_IRP_RC_RESERVED) || /* List der. prefixes request */
(opcode == DO_IRP_OC_HOME_PREFIX && respcode == DO_IRP_RC_RESERVED) || /* Home prefix request */
(opcode == DO_IRP_OC_UNHOME_PREFIX && respcode == DO_IRP_RC_RESERVED) /* Unhome prefix request */
) {
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ident, NULL);
}
else if(
(opcode == DO_IRP_OC_LIST_IDS && respcode == DO_IRP_RC_SUCCESS) || /* List IDs response */
(opcode == DO_IRP_OC_LIST_DERIVED_PREFIXES && respcode == DO_IRP_RC_SUCCESS) || /* List der. prefixes response */
(opcode == DO_IRP_OC_LIST_HOMED_PREFIXES && respcode == DO_IRP_RC_SUCCESS) /* List homed prefixes response */
) {
guint32 element_entries = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_identcount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < element_entries; i++) {
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ident, NULL);
}
}
else if(opcode == DO_IRP_OC_SESSION_SETUP && respcode == DO_IRP_RC_RESERVED) { /* Session setup request */
proto_tree_add_item(do_irp_body_tree, hf_do_irp_keyexmode, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(do_irp_body_tree, hf_do_irp_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_ident, NULL);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_idx, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
offset += decode_pk_data(tvb, pinfo, do_irp_body_tree, offset);
}
else if(opcode == DO_IRP_OC_SESSION_SETUP && respcode == DO_IRP_RC_SUCCESS) { /* Session setup response */
proto_tree_add_item(do_irp_body_tree, hf_do_irp_keyexmode, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
offset += decode_pk_data(tvb, pinfo, do_irp_body_tree, offset);
}
/* All error resposes */
else if(
(respcode >= DO_IRP_RC_ERROR && respcode <= DO_IRP_RC_SERVER_NOT_RESP) ||
(respcode >= DO_IRP_RC_INVALID_ADMIN && respcode <= DO_IRP_RC_ACCESS_DENIED) ||
(respcode >= DO_IRP_RC_AUTHEN_FAILED && respcode <= DO_IRP_RC_SESSION_MSG_REJECTED)
) {
if(tvb_ensure_captured_length_remaining(tvb, offset) >= 4 ) {
offset += decode_string(tvb, pinfo, do_irp_body_tree, offset, hf_do_irp_error_msg, NULL);
}
/* If body length has not been reached, there must be error indices*/
if((guint32)(offset - body_start_offset) < body_len) {
guint32 err_indices = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_tree_add_item(do_irp_body_tree, hf_do_irp_error_idxcount, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
for(guint32 i = 0; i < err_indices; i++) {
proto_tree_add_item(do_irp_body_tree, hf_do_irp_error_idx, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
}
}
else {
/* unsupported codes */
gint unhandled_bytes = body_len - (offset - body_start_offset);
call_data_dissector(
tvb_new_subset_length(tvb, offset, unhandled_bytes),
pinfo, do_irp_body_tree
);
offset += unhandled_bytes;
}
}
/* Message Credential */
if(tvb_captured_length_remaining(tvb, offset) >= 4) {
guint32 cred_len = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
proto_item *ti_cred = proto_tree_add_item(tree, hf_do_irp_credential, tvb, offset, cred_len + 4, ENC_NA);
proto_tree *do_irp_cred_tree = proto_item_add_subtree(ti_cred, ett_do_irp_credential);
proto_tree_add_item(do_irp_cred_tree, hf_do_irp_credential_len, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
if(cred_len > 0) { /* If credential length is 0, is ends here */
offset += 8; /* Reserved */
proto_tree_add_item(do_irp_cred_tree, hf_do_irp_credential_sesscounter, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
offset += decode_string(tvb, pinfo, do_irp_cred_tree, offset, hf_do_irp_credential_type, NULL);
guint32 sig_len = tvb_get_guint32(tvb, offset, ENC_BIG_ENDIAN);
if(sig_len) {
proto_item *ti_signedinfo = proto_tree_add_item(do_irp_cred_tree, hf_do_irp_credential_signedinfo, tvb, offset, sig_len + 4, ENC_NA);
proto_tree *do_irp_signedinfo_tree = proto_item_add_subtree(ti_signedinfo, ett_do_irp_credential_signedinfo);
proto_tree_add_item(do_irp_signedinfo_tree, hf_do_irp_credential_signedinfo_len, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
const char *algo;
offset += decode_string(tvb, pinfo, do_irp_signedinfo_tree, offset, hf_do_irp_credential_signedinfo_algo, &algo);
proto_item_append_text(do_irp_signedinfo_tree, " (%s)", algo);
offset += decode_generic_data(tvb, do_irp_signedinfo_tree, offset, hf_do_irp_credential_signedinfo_sig);
}
}
}
/* Conversation Handling */
conversation = find_or_create_conversation(pinfo);
request_key.conv_index = conversation->conv_index;
request_key.reqid = reqid;
request_val = (struct do_irp_request_hash_val *) wmem_map_lookup(do_irp_request_hash_map, &request_key);
/* If this packet is a request WITHOUT a registered request */
if(respcode == DO_IRP_RC_RESERVED && !request_val) {
new_request_key = wmem_new(wmem_file_scope(), struct do_irp_request_hash_key);
*new_request_key = request_key;
request_val = wmem_new(wmem_file_scope(), struct do_irp_request_hash_val);
request_val->pnum = pinfo->num;
request_val->pnum_resp = 0;
request_val->opcode = opcode;
wmem_map_insert(do_irp_request_hash_map, new_request_key, request_val);
}
/* If this packet is a request WITH a registered request */
else if(respcode == DO_IRP_RC_RESERVED && request_val) {
if(request_val->pnum_resp > 0) {
r_pkt = proto_tree_add_uint(tree , hf_do_irp_response_in, tvb, 0, 0, request_val->pnum_resp);
proto_item_set_generated(r_pkt);
}
}
/* If this packet is a response to a registered request */
else if(respcode != DO_IRP_RC_RESERVED && request_val) {
request_val->pnum_resp = pinfo->num;
r_pkt = proto_tree_add_uint(tree , hf_do_irp_response_to, tvb, 0, 0, request_val->pnum);
proto_item_set_generated(r_pkt);
}
return offset;
}
static gboolean
test_do_irp(tvbuff_t *tvb)
{
/* Minimum length (envelope must be present) */
if(tvb_captured_length(tvb) < DO_IRP_ENVELOPE_LEN)
return FALSE;
/* Supported versions (2, 3) */
guint8 majorversion = tvb_get_guint8(tvb, 0);
if(majorversion < 2 || majorversion > 3)
return FALSE;
/* Message Length must not be 0 */
if(tvb_get_guint32(tvb, 16, ENC_BIG_ENDIAN) == 0)
return FALSE;
return TRUE;
}
static guint
get_do_irp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
return (tvb_get_guint32(tvb, offset + 16, ENC_BIG_ENDIAN) + DO_IRP_ENVELOPE_LEN);
}
static int
dissect_do_irp_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
/* Do some basic tests */
if(!test_do_irp(tvb))
return 0;
proto_item *ti = proto_tree_add_item(tree, proto_do_irp, tvb, 0, -1, ENC_NA);
proto_tree *do_irp_tree = proto_item_add_subtree(ti, ett_do_irp);
guint32 reqid;
gboolean encrypted;
tvbuff_t *new_tvb = NULL;
gint offset = 0;
/*
* RFC 3652 defines `<MessageFlag>` in 2.2.1.2 as two octets containing three flags.
* | MessageFlag (3 bits) | Reserved (13 bits) |
*
* DO-IRP v3.0 divided this field into three fields in 6.2.1 ff. while maintaining backward compatibility.
* | Flag (3 bits) | SuggMajor (5 bits) | SuggMinor (8 bits) |
*
* Both documents state that in case of fragmentation, each fragment must contain an envelope with the truncated bit (TC) set.
* In the wild the TC-flag is often ignored or not set. Therefore, reassembly is not (only) based on the TC-bit here,
* to be able to generate expert info when protocol specs are violated.
*/
guint32 msg_len = tvb_get_guint32(tvb, 16, ENC_BIG_ENDIAN); /* Length of over-all message, excluding envelope */
guint8 env_flags = tvb_get_guint8(tvb, 2);
/* Envelope is always present */
offset += decode_envelope(tvb, pinfo, do_irp_tree, &reqid, &encrypted);
if (
msg_len > (DO_IRP_MAX_UDP_SIZE - DO_IRP_ENVELOPE_LEN) || /* Message does not fit into one packet */
env_flags & 0x20 /* TC-bit set */
) {
/* fragmented */
fragment_head *frag_msg = NULL;
gboolean first_frag = FALSE;
guint16 msg_reqid = tvb_get_guint32(tvb, 8, ENC_BIG_ENDIAN);
guint16 msg_seqid = tvb_get_guint32(tvb, 12, ENC_BIG_ENDIAN);
if( !(env_flags & 0x20) ) {
expert_add_info(pinfo, do_irp_tree, &ei_do_irp_frag_wo_tc);
}
/* Check if it's the first fragment, to set expected packets after first fragment_add */
if(fragment_get_tot_len(&do_irp_reassemble_table, pinfo, msg_reqid, NULL) == 0) {
first_frag = TRUE;
}
pinfo->fragmented = TRUE;
frag_msg = fragment_add_seq_check(&do_irp_reassemble_table, tvb, offset, pinfo,
msg_reqid, NULL,
msg_seqid,
tvb_captured_length_remaining(tvb, offset),
TRUE /* Expected packet count set */
);
if(first_frag) {
uint32_t expected_packets = msg_len / (DO_IRP_MAX_UDP_SIZE - DO_IRP_ENVELOPE_LEN);
if ((msg_len % (DO_IRP_MAX_UDP_SIZE - DO_IRP_ENVELOPE_LEN)) != 0) expected_packets++;
fragment_set_tot_len(&do_irp_reassemble_table, pinfo, msg_reqid, NULL, expected_packets-1); /* Set expected packet count (0-index) */
}
new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message", frag_msg, &msg_frag_items, NULL, do_irp_tree);
if (new_tvb) { /* Packet reassembled */
if(!encrypted) {
offset += decode_header_body_credential(new_tvb, pinfo, do_irp_tree, reqid);
} else {
/* Encrypted message can't be decoded */
col_append_str(pinfo->cinfo, COL_INFO, " (encrypted)");
call_data_dissector(new_tvb, pinfo, do_irp_tree);
offset = tvb_captured_length(tvb);
}
col_append_fstr(pinfo->cinfo, COL_INFO, " (Frag=%u, Reassembled)", msg_seqid+1);
} else { /* Packet fragment */
call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, do_irp_tree);
col_append_fstr(pinfo->cinfo, COL_INFO, " (Frag=%u)", msg_seqid+1);
offset = tvb_captured_length(tvb);
}
}
else {
/* No fragmentation */
new_tvb = tvb_new_subset_remaining(tvb, offset);
if(!encrypted) {
offset += decode_header_body_credential(new_tvb, pinfo, do_irp_tree, reqid);
} else {
/* Encrypted message can't be decoded */
col_append_str(pinfo->cinfo, COL_INFO, " (encrypted)");
call_data_dissector(new_tvb, pinfo, do_irp_tree);
offset = tvb_captured_length(tvb);
}
}
return offset;
}
static int
dissect_do_irp_tcp_full_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_item *ti = proto_tree_add_item(tree, proto_do_irp, tvb, 0, -1, ENC_NA);
proto_tree *do_irp_tree = proto_item_add_subtree(ti, ett_do_irp);
guint32 reqid;
gboolean enc;
gint offset = 0;
offset += decode_envelope(tvb, pinfo, do_irp_tree, &reqid, &enc);
offset += decode_header_body_credential(tvb_new_subset_remaining(tvb, offset), pinfo, do_irp_tree, reqid);
return offset;
}
static int
dissect_do_irp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
/* Do some basic tests */
if(!test_do_irp(tvb))
return 0;
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, DO_IRP_ENVELOPE_LEN, get_do_irp_message_len, dissect_do_irp_tcp_full_message, data);
return tvb_reported_length(tvb);
}
void
proto_register_do_irp(void)
{
static hf_register_info hf[] = {
/* Fragment handling */
{&hf_msg_fragments,
{ "Message fragments", "do-irp.fragments",
FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment,
{ "Message fragment", "do-irp.fragment",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment_overlap,
{ "Message fragment overlap", "do-irp.fragment.overlap",
FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment_overlap_conflicts,
{ "Message fragment overlapping with conflicting data", "do-irp.fragment.overlap.conflicts",
FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment_multiple_tails,
{ "Message has multiple tail fragments", "do-irp.fragment.multiple_tails",
FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment_too_long_fragment,
{ "Message fragment too long", "do-irp.fragment.too_long_fragment",
FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment_error,
{ "Message defragmentation error", "do-irp.fragment.error",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_fragment_count,
{ "Message fragment count", "do-irp.fragment.count",
FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_reassembled_in,
{ "Reassembled in", "do-irp.reassembled.in",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_reassembled_len,
{ "Reassembled length", "do-irp.reassembled.len",
FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
},
{&hf_msg_reassembled_data,
{ "Reassembled data", "do-irp.reassembled.data",
FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL }
},
/* Generic */
{ &hf_do_irp_string_len,
{ "Length", "do-irp.string.len",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_string_value,
{ "Value", "do-irp.string.value",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_data_len,
{ "Length", "do-irp.data.len",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_data_value,
{ "Value", "do-irp.data.value",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
/* Message Envelope */
{ &hf_do_irp_envelope,
{ "Message Envelope", "do-irp.envelope",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_version_major,
{ "Version (Major)", "do-irp.version.major",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_version_minor,
{ "Version (Minor)", "do-irp.version.minor",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_flags,
{ "Flags", "do-irp.flags",
FT_UINT8, BASE_HEX, NULL, 0xE0, NULL, HFILL }
},
{ &hf_do_irp_flag_cp,
{ "Compressed", "do-irp.flags.cp",
FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }
},
{ &hf_do_irp_flag_ec,
{ "Encrypted", "do-irp.flags.ec",
FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }
},
{ &hf_do_irp_flag_tc,
{ "Truncated", "do-irp.flags.tc",
FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }
},
{ &hf_do_irp_version_major_sugg,
{ "Version (Major, suggested)", "do-irp.version.major_sugg",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_version_minor_sugg,
{ "Version (Minor, suggested)", "do-irp.version.minor_sugg",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_sessid,
{ "Session ID", "do-irp.sessid",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_reqid,
{ "Request ID", "do-irp.reqid",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_seq,
{ "Sequence No.", "do-irp.seq",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_msglen,
{ "Message Length", "do-irp.msglen",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
/* Message Header */
{ &hf_do_irp_header,
{ "Message Header", "do-irp.header",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_opcode,
{ "Operation Code", "do-irp.opcode",
FT_UINT32, BASE_DEC, VALS(opcode_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_responsecode,
{ "Response Code", "do-irp.responsecode",
FT_UINT32, BASE_DEC, VALS(responsecode_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_opflags,
{ "Flags", "do-irp.opflags",
FT_UINT32, BASE_HEX, NULL, 0xFFF00000, NULL, HFILL }
},
{ &hf_do_irp_opflags_at,
{ "Authoritative", "do-irp.opflags.at",
FT_BOOLEAN, 32, NULL, 0x80000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_ct,
{ "Certified", "do-irp.opflags.ct",
FT_BOOLEAN, 32, NULL, 0x40000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_enc,
{ "Encryption", "do-irp.opflags.enc",
FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_rec,
{ "Recursive", "do-irp.opflags.rec",
FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_ca,
{ "Cache Authentication", "do-irp.opflags.ca",
FT_BOOLEAN, 32, NULL, 0x08000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_cn,
{ "Continuous", "do-irp.opflags.cn",
FT_BOOLEAN, 32, NULL, 0x04000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_kc,
{ "Keep Connection", "do-irp.opflags.kc",
FT_BOOLEAN, 32, NULL, 0x02000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_po,
{ "Public Only", "do-irp.opflags.po",
FT_BOOLEAN, 32, NULL, 0x01000000, NULL, HFILL }
},
{ &hf_do_irp_opflags_rd,
{ "Request-Digest", "do-irp.opflags.rd",
FT_BOOLEAN, 32, NULL, 0x00800000, NULL, HFILL }
},
{ &hf_do_irp_opflags_owe,
{ "Overwrite when exists", "do-irp.opflags.owe",
FT_BOOLEAN, 32, NULL, 0x00400000, NULL, HFILL }
},
{ &hf_do_irp_opflags_mns,
{ "Mint new suffix", "do-irp.opflags.mns",
FT_BOOLEAN, 32, NULL, 0x00200000, NULL, HFILL }
},
{ &hf_do_irp_opflags_dnr,
{ "Do not refer", "do-irp.opflags.dnr",
FT_BOOLEAN, 32, NULL, 0x00100000, NULL, HFILL }
},
{ &hf_do_irp_sisn,
{ "Site Info Serial No.", "do-irp.sisn",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_rcount,
{ "Recursion Count", "do-irp.recursioncount",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_expiration,
{ "Expiration Time", "do-irp.exp",
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_bodylen,
{ "Body Length", "do-irp.bodylen",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
/* Message Body */
{ &hf_do_irp_body,
{ "Message Body", "do-irp.body",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_digest_algo,
{ "Message Digest Algorithm", "do-irp.digest_algo",
FT_UINT8, BASE_DEC, VALS(digest_algo_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_digest,
{ "Message Digest", "do-irp.digest",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_error_msg,
{ "Error Message", "do-irp.error.msg",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_error_idxcount,
{ "Error Indices", "do-irp.error.idxcount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_error_idx,
{ "Error Index", "do-irp.error.idx",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_ident,
{ "Identifier", "do-irp.ident",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_idxcount,
{ "Index Count", "do-irp.idxcount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_idx,
{ "Index", "do-irp.idx",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_typecount,
{ "Type Count", "do-irp.typecount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_type,
{ "Type Entry", "do-irp.type",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identcount,
{ "Identifier Records", "do-irp.identcount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord,
{ "Identifier Record", "do-irp.identrecord",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_idx,
{ "Index", "do-irp.identrecord.idx",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_type,
{ "Type", "do-irp.identrecord.type",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_value,
{ "Value", "do-irp.identrecord.value",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_value_string,
{ "Value", "do-irp.identrecord.value.string",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_value_len,
{ "Length", "do-irp.identrecord.value.len",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_perm,
{ "Permission", "do-irp.identrecord.perm",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_perm_ar,
{ "ADMIN_READ", "do-irp.identrecord.perm.ar",
FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }
},
{ &hf_do_irp_identrecord_perm_aw,
{ "ADMIN_WRITE", "do-irp.identrecord.perm.aw",
FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }
},
{ &hf_do_irp_identrecord_perm_pr,
{ "PUBLIC_READ", "do-irp.identrecord.perm.pr",
FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }
},
{ &hf_do_irp_identrecord_perm_pw,
{ "PUBLIC_WRITE", "do-irp.identrecord.perm.pw",
FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }
},
{ &hf_do_irp_identrecord_ts,
{ "Timestamp", "do-irp.identrecord.ts",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_ts_utc,
{ "Timestamp (UTC)", "do-irp.identrecord.ts_utc",
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_ttl_type,
{ "TTL Type", "do-irp.identrecord.ttl_type",
FT_UINT8, BASE_DEC, VALS(ttl_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_ttl,
{ "TTL", "do-irp.identrecord.ttl",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_ttl_absolute,
{ "TTL (until)", "do-irp.identrecord.ttl_absolute",
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_refcount,
{ "Reference Count", "do-irp.identrecord.refcount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_identrecord_ref,
{ "Reference", "do-irp.identrecord.ref",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm,
{ "Permission", "do-irp.hsadmin.perm",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_ai,
{ "Add Identifier", "do-irp.hsadmin.perm.ai",
FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_di,
{ "Delete Identifier", "do-irp.hsadmin.perm.di",
FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_adp,
{ "Add Derived Prefix", "do-irp.hsadmin.perm.adp",
FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_me,
{ "Modify Element", "do-irp.hsadmin.perm.me",
FT_BOOLEAN, 16, NULL, 0x0010, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_de,
{ "Delete Element", "do-irp.hsadmin.perm.de",
FT_BOOLEAN, 16, NULL, 0x0020, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_ae,
{ "Add Element", "do-irp.hsadminp.perm.ae",
FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_ma,
{ "Modify Admin", "do-irp.hsadmin.perm.ma",
FT_BOOLEAN, 16, NULL, 0x0080, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_ra,
{ "Remove Admin", "do-irp.hsadmin.perm.ra",
FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_aa,
{ "Add Admin", "do-irp.hsadmin.perm.aa",
FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_ar,
{ "Authorized Read", "do-irp.hsadmin.perm.ar",
FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_li,
{ "List Identifiers", "do-irp.hsadmin.perm.li",
FT_BOOLEAN, 16, NULL, 0x0800, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_perm_ldp,
{ "List Derived Prefixes", "do-irp.hsadmin.perm.ldp",
FT_BOOLEAN, 16, NULL, 0x1000, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_idx,
{ "Index", "do-irp.hsadmin.idx",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsadmin_ident,
{ "Identifier", "do-irp.hsadmin.ident",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_body_hssite_version,
{ "Version", "do-irp.hssite.version",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_protoversion_major,
{ "Protocol Version (Major)", "do-irp.hssite.protoversion.major",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_protoversion_minor,
{ "Protocol Version (Minor)", "do-irp.hssite.protoversion.minor",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_serial,
{ "Serial", "do-irp.hssite.serial",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_primask,
{ "Primary Mask", "do-irp.hssite.primask",
FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }
},
{ &hf_do_irp_hssite_primask_pri,
{ "Primary Site", "do-irp.hssite.primask.pri",
FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }
},
{ &hf_do_irp_hssite_primask_multi,
{ "Multi Primary", "do-irp.hssite.primask.multi",
FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }
},
{ &hf_do_irp_hssite_hashoption,
{ "Hash Option", "do-irp.hssite.hashoption",
FT_UINT8, BASE_HEX, VALS(hashoption_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_hashfilter,
{ "Hash Filter", "do-irp.hssite.hashfilter",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_attr_count,
{ "Attributes", "do-irp.hssite.attr.num",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_attr,
{ "Attribute", "do-irp.hssite.attr",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_attr_key,
{ "Key", "do-irp.hssite.attr.key",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_attr_value,
{ "Value", "do-irp.hssite.attr.value",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srvcount,
{ "Server Count", "do-irp.hssite.srvcount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv,
{ "Server", "do-irp.hssite.srv",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_id,
{ "ID", "do-irp.hssite.srv.id",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_addr,
{ "Address", "do-irp.hssite.srv.addr",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_ifcount,
{ "Interface Count", "do-irp.hssite.srv.ifcount",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_if,
{ "Interface", "do-irp.hssite.srv.if",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_if_type,
{ "Type", "do-irp.hssite.srv.if.type",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_if_type_admin,
{ "Administration", "do-irp.hssite.srv.if.type.admin",
FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_if_type_res,
{ "Resolution", "do-irp.hssite.srv.if.type.res",
FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_if_proto,
{ "Protocol", "do-irp.hssite.srv.if.proto",
FT_UINT8, BASE_HEX, VALS(transportproto_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssite_srv_if_port,
{ "Port", "do-irp.hssite.srv.if.port",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec,
{ "Public Key Data", "do-irp.pk",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_len,
{ "Public Key Length", "do-irp.pk.len",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_type,
{ "Public Key Type", "do-irp.pk.type",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dsa_q,
{ "DSA (q)", "do-irp.pk.dsa.q",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dsa_p,
{ "DSA (p)", "do-irp.pk.dsa.p",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dsa_g,
{ "DSA (g)", "do-irp.pk.dsa.g",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dsa_y,
{ "DSA (y)", "do-irp.pk.dsa.y",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dh_p,
{ "DH (p)", "do-irp.pk.dh.p",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dh_g,
{ "DH (g)", "do-irp.pk.dh.g",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_dh_y,
{ "DH (y)", "do-irp.pk.dh.y",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_rsa_exp,
{ "RSA (Exponent)", "do-irp.pk.rsa.exp",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_pkrec_rsa_mod,
{ "RSA (Modulo)", "do-irp.pk.rsa.mod",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsserv_ident,
{ "Identifier", "do-irp.hsserv.ident",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsvlist_count,
{ "Reference Count", "do-irp.vlist.count",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsvlist_ref,
{ "Reference", "do-irp.vlist.ref",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsalias,
{ "Alias", "do-irp.hsalias",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hsnamespace,
{ "Namespace", "do-irp.hsnamespace",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hscert_jwt,
{ "JWT", "do-irp.hscert.jwt",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_hssignature_jwt,
{ "JWT", "do-irp.hssignature.jwt",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_refident,
{ "Referral Identifier", "do-irp.refident",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_nonce,
{ "Nonce", "do-irp.nonce",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_authtype,
{ "Authentication Type", "do-irp.authtype",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_keyident,
{ "Key Identifier", "do-irp.keyident",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_keyidx,
{ "Key Index", "do-irp.keyidx",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_challresp,
{ "Challenge Response", "do-irp.challresp",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_veri_result,
{ "Verification Result", "do-irp.veri_result",
FT_UINT8, BASE_DEC, VALS(verification_resp_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_ignoredident,
{ "Ignored Identifier", "do-irp.ignoredident",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_keyexmode,
{ "Key Exchange Mode", "do-irp.keyexmode",
FT_UINT16, BASE_DEC, VALS(key_exchange_vals), 0x0, NULL, HFILL }
},
{ &hf_do_irp_timeout,
{ "Timeout", "do-irp.timeout",
FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_seconds, 0x0, NULL, HFILL }
},
/* Message Credential */
{ &hf_do_irp_credential,
{ "Message Credential", "do-irp.credential",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_len,
{ "Length", "do-irp.credential.len",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_sesscounter,
{ "Session Counter", "do-irp.credential.sesscounter",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_type,
{ "Type", "do-irp.credential.type",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_signedinfo,
{ "SignedInfo", "do-irp.credential.signedinfo",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_signedinfo_len,
{ "Length", "do-irp.credential.signedinfo.len",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_signedinfo_algo,
{ "Algorithm", "do-irp.credential.signedinfo.algo",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_credential_signedinfo_sig,
{ "Signature", "do-irp.credential.signedinfo.sig",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
/* Conversation */
{ &hf_do_irp_response_in,
{ "Response in", "do-irp.response_in",
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL }
},
{ &hf_do_irp_response_to,
{ "Request in", "do-irp.response_to",
FT_FRAMENUM, BASE_NONE, NULL, 0x0, NULL, HFILL }
}
};
static ei_register_info ei[] = {
{ &ei_do_irp_digest_unknown,
{ "do-irp.header.digest.unknown", PI_MALFORMED, PI_WARN,
"Invalid digest algorithm", EXPFILL }
},
{ &ei_do_irp_frag_wo_tc,
{ "do-irp.envelope.tc_missing", PI_MALFORMED, PI_ERROR,
"Fragmentation without TC bit set", EXPFILL }
}
};
static gint *ett[] = {
&ett_msg_fragment,
&ett_msg_fragments,
&ett_do_irp,
&ett_do_irp_string,
&ett_do_irp_envelope,
&ett_do_irp_envelope_flags,
&ett_do_irp_header,
&ett_do_irp_header_flags,
&ett_do_irp_body,
&ett_do_irp_credential,
&ett_do_irp_credential_signedinfo,
&ett_do_irp_identifier_record,
&ett_do_irp_element_permission_flags,
&ett_do_irp_element_hsadmin_permission_flags,
&ett_do_irp_element_hsadmin_primary_flags,
&ett_do_irp_hsadmin,
&ett_do_irp_hssite,
&ett_do_irp_hssite_attribute,
&ett_do_irp_hssite_server,
&ett_do_irp_hssite_server_if,
&ett_do_irp_hssite_server_if_flags,
&ett_do_irp_pk
};
do_irp_request_hash_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), do_irp_handle_hash, do_irp_handle_equal);
proto_do_irp = proto_register_protocol("Digital Object Identifier Resolution Protocol", "DO-IRP", "do-irp");
expert_do_irp = expert_register_protocol(proto_do_irp);
proto_register_field_array(proto_do_irp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_register_field_array(expert_do_irp, ei, array_length(ei));
reassembly_table_register(&do_irp_reassemble_table, &addresses_ports_reassembly_table_functions);
do_irp_handle_udp = register_dissector("do-irp_udp", dissect_do_irp_udp, proto_do_irp);
do_irp_handle_tcp = register_dissector("do-irp_tcp", dissect_do_irp_tcp, proto_do_irp);
}
void
proto_reg_handoff_do_irp(void)
{
dissector_add_uint_with_preference("udp.port", DO_IRP_UDP_PORT, do_irp_handle_udp);
dissector_add_uint_with_preference("tcp.port", DO_IRP_TCP_PORT, do_irp_handle_tcp);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/