![Alexis La Goutte](/assets/img/avatar_default.png)
(Using sed : sed -i '/^ \* \$Id\$/,+1 d') Fix manually some typo (in export_object_dicom.c and crc16-plain.c) Change-Id: I4c1ae68d1c4afeace8cb195b53c715cf9e1227a8 Reviewed-on: https://code.wireshark.org/review/497 Reviewed-by: Anders Broman <a.broman58@gmail.com>
2280 lines
78 KiB
C
2280 lines
78 KiB
C
/* packet-pcp.c
|
|
* Routines for Performace Co-Pilot protocol dissection
|
|
*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <epan/packet.h>
|
|
#include <epan/expert.h>
|
|
#include "packet-tcp.h"
|
|
|
|
void proto_register_pcp(void);
|
|
void proto_reg_handoff_pcp(void);
|
|
|
|
#define PCP_PORT 44321
|
|
#define PCP_HEADER_LEN 12
|
|
|
|
|
|
static int proto_pcp = -1;
|
|
static int hf_pcp_pdu_length = -1;
|
|
static int hf_pcp_pdu_type = -1;
|
|
static int hf_pcp_pdu_pid = -1;
|
|
static int hf_pcp_pdu_error = -1;
|
|
static int hf_pcp_pdu_padding = -1;
|
|
static int hf_pcp_creds_number_of = -1;
|
|
static int hf_pcp_creds_type = -1;
|
|
static int hf_pcp_creds_vala = -1;
|
|
static int hf_pcp_creds_valb = -1;
|
|
static int hf_pcp_creds_valc = -1;
|
|
static int hf_pcp_start = -1;
|
|
static int hf_pcp_start_status = -1;
|
|
static int hf_pcp_start_zero = -1;
|
|
static int hf_pcp_start_version = -1;
|
|
static int hf_pcp_start_licensed = -1;
|
|
static int hf_pcp_start_authorize = -1;
|
|
static int hf_pcp_pmns_traverse = -1;
|
|
static int hf_pcp_pmns_subtype = -1;
|
|
static int hf_pcp_pmns_namelen = -1;
|
|
static int hf_pcp_pmns_name = -1;
|
|
static int hf_pcp_pmns_names = -1;
|
|
static int hf_pcp_pmns_names_nstrbytes = -1;
|
|
static int hf_pcp_pmns_names_numstatus = -1;
|
|
static int hf_pcp_pmns_names_numnames = -1;
|
|
static int hf_pcp_pmns_names_nametree = -1;
|
|
static int hf_pcp_pmns_names_nametree_status = -1;
|
|
static int hf_pcp_pmns_names_nametree_namelen = -1;
|
|
static int hf_pcp_pmns_names_nametree_name = -1;
|
|
static int hf_pcp_pmns_ids = -1;
|
|
static int hf_pcp_pmns_ids_status = -1;
|
|
static int hf_pcp_pmns_ids_numids = -1;
|
|
static int hf_pcp_pmns_child = -1;
|
|
static int hf_pcp_pmid = -1;
|
|
static int hf_pcp_pmid_flag = -1;
|
|
static int hf_pcp_pmid_domain = -1;
|
|
static int hf_pcp_pmid_cluster = -1;
|
|
static int hf_pcp_pmid_item = -1;
|
|
static int hf_pcp_pmid_type = -1;
|
|
static int hf_pcp_pmid_sem = -1;
|
|
static int hf_pcp_pmid_inst = -1;
|
|
static int hf_pcp_profile = -1;
|
|
static int hf_pcp_ctxnum = -1;
|
|
static int hf_pcp_profile_g_state = -1;
|
|
static int hf_pcp_profile_numprof = -1;
|
|
static int hf_pcp_profile_profile = -1;
|
|
static int hf_pcp_profile_profile_state = -1;
|
|
static int hf_pcp_profile_profile_numinst = -1;
|
|
static int hf_pcp_fetch = -1;
|
|
static int hf_pcp_fetch_numpmid = -1;
|
|
static int hf_pcp_when = -1;
|
|
static int hf_pcp_when_sec = -1;
|
|
static int hf_pcp_when_usec = -1;
|
|
static int hf_pcp_desc = -1;
|
|
static int hf_pcp_desc_req = -1;
|
|
static int hf_pcp_units = -1;
|
|
static int hf_pcp_units_dimspace = -1;
|
|
static int hf_pcp_units_dimtime = -1;
|
|
static int hf_pcp_units_dimcount = -1;
|
|
static int hf_pcp_units_scalespace = -1;
|
|
static int hf_pcp_units_scaletime = -1;
|
|
static int hf_pcp_units_scalecount = -1;
|
|
static int hf_pcp_instance = -1;
|
|
static int hf_pcp_instance_req = -1;
|
|
static int hf_pcp_instance_namelen = -1;
|
|
static int hf_pcp_instance_name = -1;
|
|
static int hf_pcp_instance_indom = -1;
|
|
static int hf_pcp_instance_valoffset = -1;
|
|
static int hf_pcp_instance_vallength = -1;
|
|
static int hf_pcp_instance_value_insitu = -1;
|
|
static int hf_pcp_instance_value_ptr = -1;
|
|
static int hf_pcp_instance_value_int = -1;
|
|
static int hf_pcp_instance_value_uint = -1;
|
|
static int hf_pcp_instance_value_int64 = -1;
|
|
static int hf_pcp_instance_value_uint64 = -1;
|
|
static int hf_pcp_instance_value_float = -1;
|
|
static int hf_pcp_instance_value_double = -1;
|
|
static int hf_pcp_instance_value_aggr = -1;
|
|
static int hf_pcp_instances = -1;
|
|
static int hf_pcp_instances_numinst = -1;
|
|
static int hf_pcp_results = -1;
|
|
static int hf_pcp_results_numpmid = -1;
|
|
static int hf_pcp_result = -1;
|
|
static int hf_pcp_result_numval = -1;
|
|
static int hf_pcp_result_valfmt = -1;
|
|
static int hf_pcp_text_req = -1;
|
|
static int hf_pcp_text_type = -1;
|
|
static int hf_pcp_text_type_format = -1;
|
|
static int hf_pcp_text_type_ident = -1;
|
|
static int hf_pcp_text = -1;
|
|
static int hf_pcp_text_ident = -1;
|
|
static int hf_pcp_text_buflen = -1;
|
|
static int hf_pcp_text_buffer = -1;
|
|
|
|
|
|
static gint ett_pcp = -1;
|
|
static gint ett_pcp_pdu_length = -1;
|
|
static gint ett_pcp_pdu_type = -1;
|
|
static gint ett_pcp_pdu_pid = -1;
|
|
static gint ett_pcp_pdu_error = -1;
|
|
static gint ett_pcp_pdu_padding = -1;
|
|
static gint ett_pcp_creds_number_of = -1;
|
|
static gint ett_pcp_creds_type = -1;
|
|
static gint ett_pcp_creds_vala = -1;
|
|
static gint ett_pcp_creds_valb = -1;
|
|
static gint ett_pcp_creds_valc = -1;
|
|
static gint ett_pcp_start = -1;
|
|
static gint ett_pcp_start_status = -1;
|
|
static gint ett_pcp_start_zero = -1;
|
|
static gint ett_pcp_start_version = -1;
|
|
static gint ett_pcp_start_licensed = -1;
|
|
static gint ett_pcp_start_authorize = -1;
|
|
static gint ett_pcp_pmns_traverse = -1;
|
|
static gint ett_pcp_pmns_subtype = -1;
|
|
static gint ett_pcp_pmns_namelen = -1;
|
|
static gint ett_pcp_pmns_name = -1;
|
|
static gint ett_pcp_pmns_names = -1;
|
|
static gint ett_pcp_pmns_names_nstrbytes = -1;
|
|
static gint ett_pcp_pmns_names_numstatus = -1;
|
|
static gint ett_pcp_pmns_names_numnames = -1;
|
|
static gint ett_pcp_pmns_names_nametree = -1;
|
|
static gint ett_pcp_pmns_names_nametree_status = -1;
|
|
static gint ett_pcp_pmns_names_nametree_namelen = -1;
|
|
static gint ett_pcp_pmns_names_nametree_name = -1;
|
|
static gint ett_pcp_pmns_ids = -1;
|
|
static gint ett_pcp_pmns_ids_status = -1;
|
|
static gint ett_pcp_pmns_ids_numids = -1;
|
|
static gint ett_pcp_pmns_child = -1;
|
|
static gint ett_pcp_pmid = -1;
|
|
static gint ett_pcp_pmid_flag = -1;
|
|
static gint ett_pcp_pmid_domain = -1;
|
|
static gint ett_pcp_pmid_cluster = -1;
|
|
static gint ett_pcp_pmid_item = -1;
|
|
static gint ett_pcp_pmid_type = -1;
|
|
static gint ett_pcp_pmid_sem = -1;
|
|
static gint ett_pcp_profile = -1;
|
|
static gint ett_pcp_ctxnum = -1;
|
|
static gint ett_pcp_profile_g_state = -1;
|
|
static gint ett_pcp_profile_numprof = -1;
|
|
static gint ett_pcp_profile_profile = -1;
|
|
static gint ett_pcp_profile_profile_state = -1;
|
|
static gint ett_pcp_profile_profile_numinst = -1;
|
|
static gint ett_pcp_fetch = -1;
|
|
static gint ett_pcp_fetch_numpmid = -1;
|
|
static gint ett_pcp_when = -1;
|
|
static gint ett_pcp_when_sec = -1;
|
|
static gint ett_pcp_when_usec = -1;
|
|
static gint ett_pcp_desc_req = -1;
|
|
static gint ett_pcp_units = -1;
|
|
static gint ett_pcp_units_dimspace = -1;
|
|
static gint ett_pcp_units_dimtime = -1;
|
|
static gint ett_pcp_units_dimcount = -1;
|
|
static gint ett_pcp_units_scalespace = -1;
|
|
static gint ett_pcp_units_scaletime = -1;
|
|
static gint ett_pcp_units_scalecount = -1;
|
|
static gint ett_pcp_instance = -1;
|
|
static gint ett_pcp_instance_req = -1;
|
|
static gint ett_pcp_instance_namelen = -1;
|
|
static gint ett_pcp_instance_name = -1;
|
|
static gint ett_pcp_instance_inst = -1;
|
|
static gint ett_pcp_instance_indom = -1;
|
|
static gint ett_pcp_instance_valoffset = -1;
|
|
static gint ett_pcp_instance_vallength = -1;
|
|
static gint ett_pcp_instance_value_insitu = -1;
|
|
static gint ett_pcp_instance_value_ptr = -1;
|
|
static gint ett_pcp_instance_value_int = -1;
|
|
static gint ett_pcp_instance_value_uint = -1;
|
|
static gint ett_pcp_instance_value_int64 = -1;
|
|
static gint ett_pcp_instance_value_uint64 = -1;
|
|
static gint ett_pcp_instance_value_float = -1;
|
|
static gint ett_pcp_instance_value_double = -1;
|
|
static gint ett_pcp_instance_value_aggr = -1;
|
|
static gint ett_pcp_instances = -1;
|
|
static gint ett_pcp_instances_numinst = -1;
|
|
static gint ett_pcp_results = -1;
|
|
static gint ett_pcp_results_numpmid = -1;
|
|
static gint ett_pcp_result = -1;
|
|
static gint ett_pcp_result_numval = -1;
|
|
static gint ett_pcp_result_valfmt = -1;
|
|
static gint ett_pcp_text_req = -1;
|
|
static gint ett_pcp_text_type = -1;
|
|
static gint ett_pcp_text_type_format = -1;
|
|
static gint ett_pcp_text_type_ident = -1;
|
|
static gint ett_pcp_text = -1;
|
|
static gint ett_pcp_text_ident = -1;
|
|
static gint ett_pcp_text_buflen = -1;
|
|
static gint ett_pcp_text_buffer = -1;
|
|
|
|
static expert_field ei_pcp_type_event_unimplemented = EI_INIT;
|
|
static expert_field ei_pcp_type_nosupport_unsupported = EI_INIT;
|
|
static expert_field ei_pcp_type_unknown_unknown_value = EI_INIT;
|
|
static expert_field ei_pcp_unimplemented_value = EI_INIT;
|
|
static expert_field ei_pcp_unimplemented_packet_type = EI_INIT;
|
|
|
|
/* packet types */
|
|
static const value_string packettypenames[] = {
|
|
#define START_OR_ERROR 0x7000
|
|
{ 0x7000, "START/ERROR" },
|
|
#define RESULT 0x7001
|
|
{ 0x7001, "RESULT" },
|
|
#define PROFILE 0x7002
|
|
{ 0x7002, "PROFILE"},
|
|
#define FETCH 0x7003
|
|
{ 0x7003, "FETCH"},
|
|
#define DESC_REQ 0x7004
|
|
{ 0x7004, "DESC_REQ"},
|
|
#define DESC 0x7005
|
|
{ 0x7005, "DESC"},
|
|
#define INSTANCE_REQ 0x7006
|
|
{ 0x7006, "INSTANCE_REQ" },
|
|
#define INSTANCE 0x7007
|
|
{ 0x7007, "INSTANCE" },
|
|
#define TEXT_REQ 0x7008
|
|
{ 0x7008, "TEXT_REQ" },
|
|
#define TEXT 0x7009
|
|
{ 0x7009, "TEXT" },
|
|
#define CONTROL_REQ 0x700a
|
|
{ 0x700a, "CONTROL_REQ" }, /* unimplemented (pmlc/pmlogger only) */
|
|
#define DATA_X 0x700b
|
|
{ 0x700b, "DATA_X" }, /* unimplemented (pmlc/pmlogger only) */
|
|
#define CREDS 0x700c
|
|
{ 0x700c, "CREDS" },
|
|
#define PMNS_IDS 0x700d
|
|
{ 0x700d, "PMNS_IDS" },
|
|
#define PMNS_NAMES 0x700e
|
|
{ 0x700e, "PMNS_NAMES" },
|
|
#define PMNS_CHILD 0x700f
|
|
{ 0x700f, "PMNS_CHILD" },
|
|
#define PMNS_TRAVERSE 0x7010 /*also type FINISH as per pcp headers, but I can not see it used */
|
|
{ 0x7010, "PMNS_TRAVERSE" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_pm_units_space[] = {
|
|
{ 0, "PM_SPACE_BYTE" },
|
|
{ 1, "PM_SPACE_KBYTE" },
|
|
{ 2, "PM_SPACE_MBYTE" },
|
|
{ 3, "PM_SPACE_GBYTE" },
|
|
{ 4, "PM_SPACE_TBYTE" },
|
|
{ 5, "PM_SPACE_PBYTE" },
|
|
{ 6, "PM_SPACE_EBYTE" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_pm_units_time[] = {
|
|
{ 0, "PM_TIME_NSEC" },
|
|
{ 1, "PM_TIME_USEC" },
|
|
{ 2, "PM_TIME_MSEC" },
|
|
{ 3, "PM_TIME_SEC" },
|
|
{ 4, "PM_TIME_MIN" },
|
|
{ 5, "PM_TIME_HOUR" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_pm_types[] = {
|
|
#define PM_TYPE_NOSUPPORT -1
|
|
{ -1, "PM_TYPE_NOSUPPORT" },
|
|
#define PM_TYPE_32 0
|
|
{ 0, "PM_TYPE_32" },
|
|
#define PM_TYPE_U32 1
|
|
{ 1, "PM_TYPE_U32" },
|
|
#define PM_TYPE_64 2
|
|
{ 2, "PM_TYPE_64" },
|
|
#define PM_TYPE_U64 3
|
|
{ 3, "PM_TYPE_U64" },
|
|
#define PM_TYPE_FLOAT 4
|
|
{ 4, "PM_TYPE_FLOAT" },
|
|
#define PM_TYPE_DOUBLE 5
|
|
{ 5, "PM_TYPE_DOUBLE" },
|
|
#define PM_TYPE_STRING 6
|
|
{ 6, "PM_TYPE_STRING" },
|
|
#define PM_TYPE_AGGREGATE 7
|
|
{ 7, "PM_TYPE_AGGREGATE" },
|
|
#define PM_TYPE_AGGREGATE_STATIC 8
|
|
{ 8, "PM_TYPE_AGGREGATE_STATIC" },
|
|
#define PM_TYPE_EVENT 9
|
|
{ 9, "PM_TYPE_EVENT" },
|
|
#define PM_TYPE_UNKNOWN 255
|
|
{ 255, "PM_TYPE_UNKNOWN" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_pm_types_sem[] = {
|
|
{ 1, "PM_SEM_COUNTER" },
|
|
{ 3, "PM_SEM_INSTANT" },
|
|
{ 4, "PM_SEM_DISCRETE" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_text_type_format[] = {
|
|
#define PM_TEXT_ONELINE 1
|
|
{ 1, "PM_TEXT_ONELINE" },
|
|
#define PM_TEXT_HELP 2
|
|
{ 2, "PM_TEXT_HELP" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_text_type_ident[] = {
|
|
#define PM_TEXT_PMID 4
|
|
{ 1, "PM_TEXT_PMID" },
|
|
#define PM_TEXT_INDOM 8
|
|
{ 2, "PM_TEXT_INDOM" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_valfmt[] = {
|
|
#define PM_VAL_INSITU 0
|
|
{ 0, "PM_VAL_INSITU" },
|
|
#define PM_VAL_DPTR 1
|
|
{ 1, "PM_VAL_DPTR" },
|
|
#define PM_VAL_SPTR 2
|
|
{ 2, "PM_VAL_SPTR" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_errors[] = {
|
|
{ -12345, "PM_ERR_GENERIC" },
|
|
{ -12346, "PM_ERR_PMNS" },
|
|
{ -12347, "PM_ERR_NOPMNS" },
|
|
{ -12348, "PM_ERR_DUPPMNS" },
|
|
{ -12349, "PM_ERR_TEXT" },
|
|
{ -12350, "PM_ERR_APPVERSION" },
|
|
{ -12351, "PM_ERR_VALUE" },
|
|
{ -12352, "PM_ERR_LICENSE" },
|
|
{ -12353, "PM_ERR_TIMEOUT" },
|
|
{ -12354, "PM_ERR_NODATA" },
|
|
{ -12355, "PM_ERR_RESET" },
|
|
{ -12356, "PM_ERR_FILE" },
|
|
{ -12357, "PM_ERR_NAME" },
|
|
{ -12358, "PM_ERR_PMID" },
|
|
{ -12359, "PM_ERR_INDOM" },
|
|
{ -12360, "PM_ERR_INST" },
|
|
{ -12361, "PM_ERR_UNIT" },
|
|
{ -12362, "PM_ERR_CONV" },
|
|
{ -12363, "PM_ERR_TRUNC" },
|
|
{ -12364, "PM_ERR_SIGN" },
|
|
{ -12365, "PM_ERR_PROFILE" },
|
|
{ -12366, "PM_ERR_IPC" },
|
|
{ -12367, "PM_ERR_NOASCII" },
|
|
{ -12368, "PM_ERR_EOF" },
|
|
{ -12369, "PM_ERR_NOTHOST" },
|
|
{ -12370, "PM_ERR_EOL" },
|
|
{ -12371, "PM_ERR_MODE" },
|
|
{ -12372, "PM_ERR_LABEL" },
|
|
{ -12373, "PM_ERR_LOGREC" },
|
|
{ -12374, "PM_ERR_NOTARCHIVE" },
|
|
{ -12375, "PM_ERR_LOGFILE" },
|
|
{ -12376, "PM_ERR_NOCONTEXT" },
|
|
{ -12377, "PM_ERR_PROFILESPEC" },
|
|
{ -12378, "PM_ERR_PMID_LOG" },
|
|
{ -12379, "PM_ERR_INDOM_LOG" },
|
|
{ -12380, "PM_ERR_INST_LOG" },
|
|
{ -12381, "PM_ERR_NOPROFILE" },
|
|
{ -12386, "PM_ERR_NOAGENT" },
|
|
{ -12387, "PM_ERR_PERMISSION" },
|
|
{ -12388, "PM_ERR_CONNLIMIT" },
|
|
{ -12389, "PM_ERR_AGAIN" },
|
|
{ -12390, "PM_ERR_ISCONN" },
|
|
{ -12391, "PM_ERR_NOTCONN" },
|
|
{ -12392, "PM_ERR_NEEDPORT" },
|
|
{ -12393, "PM_ERR_WANTACK" },
|
|
{ -12394, "PM_ERR_NONLEAF" },
|
|
{ -12395, "PM_ERR_OBJSTYLE" },
|
|
{ -12396, "PM_ERR_PMCDLICENSE" },
|
|
{ -12397, "PM_ERR_TYPE" },
|
|
{ -12442, "PM_ERR_CTXBUSY" },
|
|
{ -12443, "PM_ERR_TOOSMALL" },
|
|
{ -12444, "PM_ERR_TOOBIG" },
|
|
{ -13393, "PM_ERR_PMDAREADY" },
|
|
{ -13394, "PM_ERR_PMDANOTREADY" },
|
|
{ -21344, "PM_ERR_NYI" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string packettypenames_creds[]= {
|
|
{ 1, "CVERSION" },
|
|
{ 2, "CAUTH" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/* function prototypes */
|
|
static guint get_pcp_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
|
|
static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset);
|
|
|
|
/* message length for dissect_tcp */
|
|
static guint get_pcp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
|
|
{
|
|
/* length is at the very start of the packet, after tcp header */
|
|
return (guint)tvb_get_ntohl(tvb, offset);
|
|
}
|
|
|
|
static int dissect_pcp_message_creds(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
guint32 creds_length;
|
|
guint32 i;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
|
|
val_to_str(CREDS, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
/* first is the number of creds */
|
|
proto_tree_add_item(tree, hf_pcp_creds_number_of, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
/* store the number of creds so we know how long to interate for */
|
|
creds_length = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
/* go through each __pmCreds struct */
|
|
for (i = 0; i < creds_length; i++) {
|
|
/* __pmCred.c_type */
|
|
proto_tree_add_item(tree, hf_pcp_creds_type, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
/* __pmCred.c_vala - Usually the PDU version */
|
|
proto_tree_add_item(tree, hf_pcp_creds_vala, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
/* __pmCred.c_valb - Unused */
|
|
proto_tree_add_item(tree, hf_pcp_creds_valb, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
/* __pmCred.c_valc - Unused */
|
|
proto_tree_add_item(tree, hf_pcp_creds_valc, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* ERROR packet format:
|
|
signed int error
|
|
*/
|
|
static int dissect_pcp_message_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
gint32 error_num;
|
|
|
|
/* append the type of packet, we can't look this up as it clashes with START */
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[ERROR] ");
|
|
|
|
/* add the error item to the tree and column */
|
|
proto_tree_add_item(tree, hf_pcp_pdu_error, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
error_num = tvb_get_ntohl(tvb, 4);
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "error=%s ",
|
|
val_to_str(error_num, packettypenames_errors, "Unknown Error:%i"));
|
|
offset += 4;
|
|
return offset;
|
|
}
|
|
|
|
/* START packet format:
|
|
unsigned int sts,
|
|
struct __pmPDUInfo
|
|
|
|
|
|> unsigned int zero : 1 bit
|
|
unsigned int version : 7 bits
|
|
unsigned int licensed : 8 bits
|
|
unsigned int authorize : 16 bits
|
|
*/
|
|
static int dissect_pcp_message_start(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
/* create a start tree tree to hold the information*/
|
|
proto_item *pcp_start_item;
|
|
proto_tree *pcp_start_tree;
|
|
guint32 bits_offset;
|
|
|
|
pcp_start_item = proto_tree_add_item(tree, hf_pcp_start, tvb, 0, -1, ENC_NA);
|
|
pcp_start_tree = proto_item_add_subtree(pcp_start_item, ett_pcp);
|
|
|
|
bits_offset = offset*8;
|
|
|
|
/* append the type of packet, we can't look this up as it clashes with ERROR */
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[START]");
|
|
|
|
/* status */
|
|
proto_tree_add_item(pcp_start_tree, hf_pcp_start_status, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
bits_offset += 32; /* 4 bytes */
|
|
/* zero bit and version bits */
|
|
proto_tree_add_bits_item(pcp_start_tree, hf_pcp_start_zero, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_bits_item(pcp_start_tree, hf_pcp_start_version, tvb, bits_offset+1, 7, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
/*bits_offset += 8;*/
|
|
/* licensed */
|
|
proto_tree_add_item(pcp_start_tree, hf_pcp_start_licensed, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
/* authorize */
|
|
proto_tree_add_item(pcp_start_tree, hf_pcp_start_authorize, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
return offset;
|
|
}
|
|
|
|
/* PMNS_TRAVERSE packet format:
|
|
guint32 subtype
|
|
guint32 namelen
|
|
char name[sizeof(namelen)] + padding
|
|
*/
|
|
static int dissect_pcp_message_pmns_traverse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_pmns_traverse_item;
|
|
proto_tree *pcp_pmns_traverse_tree;
|
|
guint32 name_len;
|
|
guint32 padding;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
|
|
val_to_str(PMNS_TRAVERSE, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_pmns_traverse_item = proto_tree_add_item(tree, hf_pcp_pmns_traverse, tvb, offset, -1, ENC_NA);
|
|
pcp_pmns_traverse_tree = proto_item_add_subtree(pcp_pmns_traverse_item, ett_pcp);
|
|
|
|
/* subtype */
|
|
proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
/* namelen */
|
|
proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
name_len = tvb_get_ntohl(tvb, offset); /* get the actual length out so we can use it in the next item */
|
|
offset += 4;
|
|
/* name */
|
|
proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
|
|
offset += name_len; /* increment by whatever the length of the name string was */
|
|
|
|
/* "padding" (not really padding, just what is left over in the old buffer) */
|
|
padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
|
|
if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
|
|
padding = 4 - padding; /* we want the inverse of the remainder */
|
|
|
|
proto_tree_add_item(pcp_pmns_traverse_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
|
|
offset += padding;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* PMNS_NAMES packet format:
|
|
guint32 nstrbytes (number of str bytes)
|
|
guint32 numstatus (0 if no status. Also, if 0, use name_t, otherwise use name_status_t )
|
|
guint32 numnames
|
|
__pmPDU names (if numstatus = 0, filled with name_t, otherwise name_status_t)
|
|
| |
|
|
| |> -- name_t --
|
|
| int namelen
|
|
| char name[sizeof(namelen)]
|
|
|
|
|
|> -- name_status_t --
|
|
int status
|
|
int namelen
|
|
char name[sizeof(namelen)]
|
|
*/
|
|
static int dissect_pcp_message_pmns_names(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_pmns_names_item;
|
|
proto_tree *pcp_pmns_names_tree;
|
|
proto_item *pcp_pmns_names_name_item;
|
|
proto_tree *pcp_pmns_names_name_tree;
|
|
guint32 is_pmns_names_status;
|
|
guint32 num_names;
|
|
guint32 name_len;
|
|
guint32 full_name_len;
|
|
guint32 padding;
|
|
guint32 i;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PMNS_NAMES, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_pmns_names_item = proto_tree_add_item(tree, hf_pcp_pmns_names, tvb, offset, -1, ENC_NA);
|
|
pcp_pmns_names_tree = proto_item_add_subtree(pcp_pmns_names_item, ett_pcp);
|
|
|
|
/* nstrbytes */
|
|
proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nstrbytes, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* numstatus */
|
|
proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numstatus, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
is_pmns_names_status = tvb_get_ntohl(tvb, offset); /* is the status also present in this PDU? */
|
|
offset += 4;
|
|
|
|
/* numnames */
|
|
proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_numnames, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_names = tvb_get_ntohl(tvb, offset); /* get the number of names to iterate through */
|
|
offset += 4;
|
|
|
|
/* nametrees */
|
|
for (i=0; i < num_names; i++) {
|
|
/* find out the size of the name_t/name_status_t before we create the tree */
|
|
if (is_pmns_names_status) {
|
|
name_len = tvb_get_ntohl(tvb, offset+4);
|
|
full_name_len = name_len + 8;
|
|
} else {
|
|
name_len = tvb_get_ntohl(tvb, offset);
|
|
full_name_len = name_len + 4;
|
|
}
|
|
/* add a new subtree for each name */
|
|
pcp_pmns_names_name_item = proto_tree_add_item(pcp_pmns_names_tree, hf_pcp_pmns_names_nametree,
|
|
tvb, offset, full_name_len, ENC_NA);
|
|
pcp_pmns_names_name_tree = proto_item_add_subtree(pcp_pmns_names_name_item, ett_pcp);
|
|
|
|
if (is_pmns_names_status) {
|
|
/* print out the name status and increment if we're supposed to have it */
|
|
proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_status,
|
|
tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
/* namelen */
|
|
proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_namelen,
|
|
tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
/* name */
|
|
proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pmns_names_nametree_name,
|
|
tvb, offset, name_len, ENC_ASCII|ENC_NA);
|
|
offset += name_len;
|
|
/* padding */
|
|
padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
|
|
if (padding != 0) {
|
|
padding = 4 - padding; /* we want the inverse of the remainder */
|
|
/* if there is padding, keep going till the remainder of mod 8 */
|
|
proto_tree_add_item(pcp_pmns_names_name_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
|
|
offset += padding;
|
|
}
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* PMNS_CHILD packet format:
|
|
guint32 subtype
|
|
guint32 namelen
|
|
char name[namelen]
|
|
*/
|
|
static int dissect_pcp_message_pmns_child(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_pmns_child_item;
|
|
proto_tree *pcp_pmns_child_tree;
|
|
guint32 name_len;
|
|
|
|
pcp_pmns_child_item = proto_tree_add_item(tree, hf_pcp_pmns_child, tvb, offset, -1, ENC_NA);
|
|
pcp_pmns_child_tree = proto_item_add_subtree(pcp_pmns_child_item, ett_pcp);
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PMNS_CHILD, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
/* subtype */
|
|
proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_subtype, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* namelen */
|
|
proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
name_len = tvb_get_ntohl(tvb, offset); /* length of the next value */
|
|
offset += 4;
|
|
|
|
/* name */
|
|
proto_tree_add_item(pcp_pmns_child_tree, hf_pcp_pmns_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
|
|
offset += 4;
|
|
return offset;
|
|
}
|
|
|
|
/* PMNS_IDS packet format
|
|
guint32 status
|
|
guint32 numids
|
|
pmID idlist[numids] (where pmID = uint32)
|
|
|
|
*/
|
|
static int dissect_pcp_message_pmns_ids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_pmns_ids_item;
|
|
proto_tree *pcp_pmns_ids_tree;
|
|
guint32 num_ids;
|
|
guint32 i;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
|
|
val_to_str(PMNS_IDS, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_pmns_ids_item = proto_tree_add_item(tree, hf_pcp_pmns_ids, tvb, offset, -1, ENC_NA);
|
|
pcp_pmns_ids_tree = proto_item_add_subtree(pcp_pmns_ids_item, ett_pcp);
|
|
|
|
/* status */
|
|
proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_status, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* numids */
|
|
proto_tree_add_item(pcp_pmns_ids_tree, hf_pcp_pmns_ids_numids, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_ids = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* pmIDs */
|
|
for (i=0; i<num_ids; i++) {
|
|
/* pmID */
|
|
offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_pmns_ids_tree, offset);
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* PROFILE packet format
|
|
guint32 ctxnum;
|
|
guint32 g_state;
|
|
guint32 numprof;
|
|
guint32 pad;
|
|
pmProfile profiles[numprof]
|
|
|
|
|
|> pmInDom indom;
|
|
int state;
|
|
int numinst;
|
|
int pad;
|
|
*/
|
|
static int dissect_pcp_message_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_profile_item;
|
|
proto_tree *pcp_profile_tree;
|
|
proto_item *pcp_profile_profile_item;
|
|
proto_tree *pcp_profile_profile_tree;
|
|
guint32 num_prof;
|
|
guint32 i;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(PROFILE, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_profile_item = proto_tree_add_item(tree, hf_pcp_profile, tvb, offset, -1, ENC_NA);
|
|
pcp_profile_tree = proto_item_add_subtree(pcp_profile_item, ett_pcp);
|
|
|
|
/* ctxnum */
|
|
proto_tree_add_item(pcp_profile_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* g_state */
|
|
proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_g_state, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* numprof */
|
|
proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_numprof, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_prof = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* pad */
|
|
proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
|
|
offset += 4;
|
|
|
|
/* iterate through each profile */
|
|
for (i=0; i<num_prof; i++) {
|
|
/* subtree for each profile */
|
|
pcp_profile_profile_item = proto_tree_add_item(pcp_profile_tree, hf_pcp_profile_profile, tvb, offset, 32, ENC_NA);
|
|
pcp_profile_profile_tree = proto_item_add_subtree(pcp_profile_profile_item, ett_pcp);
|
|
|
|
/* indom */
|
|
proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* state - include/exclude */
|
|
proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_state, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* numinst - number of instances to follow */
|
|
proto_tree_add_item(pcp_profile_profile_tree, hf_pcp_profile_profile_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* padding */
|
|
proto_tree_add_item(pcp_profile_tree, hf_pcp_pdu_padding, tvb, offset, 4, ENC_NA);
|
|
offset += 4;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* FETCH packet format
|
|
guint32 cxtnum
|
|
__pmTimeval when (unsigned int tv_sec, unsigned int tv_usec)
|
|
guint32 numpmid
|
|
pmID pmidlist[1-x] (unsigned int)
|
|
*/
|
|
static int dissect_pcp_message_fetch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_fetch_item;
|
|
proto_tree *pcp_fetch_tree;
|
|
guint32 num_pmid;
|
|
guint32 i;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]",
|
|
val_to_str(FETCH, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_fetch_item = proto_tree_add_item(tree, hf_pcp_fetch, tvb, offset, -1, ENC_NA);
|
|
pcp_fetch_tree = proto_item_add_subtree(pcp_fetch_item, ett_pcp);
|
|
|
|
/* ctxnum */
|
|
proto_tree_add_item(pcp_fetch_tree, hf_pcp_ctxnum, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* when */
|
|
offset = dissect_pcp_partial_when(tvb, pinfo, pcp_fetch_tree, offset);
|
|
|
|
/* numpmid */
|
|
proto_tree_add_item(pcp_fetch_tree, hf_pcp_fetch_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_pmid = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* pmIDs*/
|
|
for (i=0; i<num_pmid; i++) {
|
|
/* decode partial PMID message */
|
|
offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_fetch_tree, offset);
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* RESULT packet format
|
|
|
|
__pmTimeval when (unsigned int tv_sec, unsigned int tv_usec)
|
|
int numpmid
|
|
_pmPDU data[1-n] (contains v_list types)
|
|
|
|
|
|> pmID pmid
|
|
int numval
|
|
int valfmt
|
|
__pmValue_PDU vlist[1-n] (contains pmValue PDUs)
|
|
|
|
|
|> int inst
|
|
int offset/value
|
|
(if valfmt == PTR type)
|
|
int8 type
|
|
int24 length
|
|
char value[length]
|
|
*/
|
|
static int dissect_pcp_message_result(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_results_item;
|
|
proto_tree *pcp_results_tree;
|
|
proto_item *pcp_result_item;
|
|
proto_tree *pcp_result_tree;
|
|
proto_item *pcp_result_instance_item;
|
|
proto_tree *pcp_result_instance_tree;
|
|
guint32 num_pmid;
|
|
guint32 num_val;
|
|
guint32 offset_start;
|
|
guint32 valfmt_type;
|
|
guint32 value_type;
|
|
guint32 pmvalueblock_offset;
|
|
guint32 pmvalueblock_value_length;
|
|
guint32 i;
|
|
guint32 j;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(RESULT, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_results_item = proto_tree_add_item(tree, hf_pcp_results, tvb, offset, -1, ENC_NA);
|
|
pcp_results_tree = proto_item_add_subtree(pcp_results_item, ett_pcp);
|
|
|
|
/* when */
|
|
offset = dissect_pcp_partial_when(tvb, pinfo, pcp_results_tree, offset);
|
|
|
|
/* numpmid */
|
|
proto_tree_add_item(pcp_results_tree, hf_pcp_results_numpmid, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_pmid = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* result */
|
|
for (i=0; i<num_pmid; i++) {
|
|
/* work out how long each result should be - set starting offset */
|
|
offset_start = offset;
|
|
|
|
pcp_result_item = proto_tree_add_item(pcp_results_tree, hf_pcp_result, tvb, offset, -1, ENC_NA);
|
|
pcp_result_tree = proto_item_add_subtree(pcp_result_item, ett_pcp);
|
|
|
|
/* pmID */
|
|
offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_result_tree, offset);
|
|
|
|
/* numval */
|
|
proto_tree_add_item(pcp_result_tree, hf_pcp_result_numval, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_val = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* if there are no numvals, then the valfmt isn't sent */
|
|
if (num_val > 0) {
|
|
|
|
/* valfmt */
|
|
proto_tree_add_item(pcp_result_tree, hf_pcp_result_valfmt, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
valfmt_type = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* instance */
|
|
for (j=0; j<num_val; j++) {
|
|
/* give the subtree name length of inst (int) + offset/va (int) */
|
|
pcp_result_instance_item = proto_tree_add_item(pcp_result_tree, hf_pcp_instance,
|
|
tvb, offset, 8, ENC_NA);
|
|
pcp_result_instance_tree = proto_item_add_subtree(pcp_result_instance_item, ett_pcp);
|
|
|
|
/* inst */
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* valoffset/value: depending on the format, the next 32 bits is the value _OR_ the offset to where
|
|
the value is */
|
|
if (valfmt_type == PM_VAL_INSITU) {
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_insitu,
|
|
tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
} else {
|
|
/* offset in the packet to find pmValueBlock */
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_valoffset,
|
|
tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
/* get the offset (not the offset of the count we are at) but where we should look */
|
|
pmvalueblock_offset = tvb_get_ntohl(tvb, offset);
|
|
pmvalueblock_offset = pmvalueblock_offset * 4; /* offset values are in 32bit units */
|
|
|
|
/* type */
|
|
value_type = tvb_get_guint8(tvb, pmvalueblock_offset);
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_pmid_type,
|
|
tvb, pmvalueblock_offset, 1, ENC_BIG_ENDIAN);
|
|
pmvalueblock_offset += 1;
|
|
|
|
/* length */
|
|
pmvalueblock_value_length = tvb_get_ntoh24(tvb, pmvalueblock_offset);
|
|
/* can't add a tree item the ususal way as it is outside of the tree */
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_vallength,
|
|
tvb, pmvalueblock_offset, 3, ENC_BIG_ENDIAN);
|
|
pmvalueblock_offset += 3;
|
|
|
|
/* value - note we go up to the pmvalueblock_value_length - 4,
|
|
as this value includes the previous 4 bytes */
|
|
switch (value_type) {
|
|
case PM_TYPE_32:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case PM_TYPE_U32:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case PM_TYPE_64:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_int64, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case PM_TYPE_U64:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_uint64, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case PM_TYPE_FLOAT:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_float, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case PM_TYPE_DOUBLE:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_double, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case PM_TYPE_STRING:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_ptr, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case PM_TYPE_AGGREGATE:
|
|
case PM_TYPE_AGGREGATE_STATIC:
|
|
proto_tree_add_item(pcp_result_instance_tree, hf_pcp_instance_value_aggr, tvb,
|
|
pmvalueblock_offset, pmvalueblock_value_length-4, ENC_NA);
|
|
break;
|
|
case PM_TYPE_EVENT:
|
|
expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_event_unimplemented);
|
|
break;
|
|
case PM_TYPE_NOSUPPORT:
|
|
expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_nosupport_unsupported);
|
|
break;
|
|
case PM_TYPE_UNKNOWN:
|
|
expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_type_unknown_unknown_value);
|
|
break;
|
|
default:
|
|
expert_add_info(pinfo, pcp_result_instance_tree, &ei_pcp_unimplemented_value);
|
|
break;
|
|
}
|
|
}
|
|
/* bump the offset after the instance value _or_ the offset into
|
|
the packet (pcp.instance.valoffset) , each being 4 bytes */
|
|
offset += 4;
|
|
}
|
|
|
|
}
|
|
/* we now know how long the field is */
|
|
proto_item_set_len(pcp_result_tree, offset-offset_start);
|
|
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* DESC_REQ pcaket format
|
|
pmID pmid (32bit int)
|
|
*/
|
|
static int dissect_pcp_message_desc_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_desc_req_item;
|
|
proto_tree *pcp_desc_req_tree;
|
|
proto_item *pcp_desc_req_pmid_item;
|
|
proto_tree *pcp_desc_req_pmid_tree;
|
|
guint32 bits_offset;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(DESC_REQ, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
bits_offset = offset*8;
|
|
/* subtree for packet type */
|
|
pcp_desc_req_item = proto_tree_add_item(tree, hf_pcp_desc_req, tvb, offset, -1, ENC_NA);
|
|
pcp_desc_req_tree = proto_item_add_subtree(pcp_desc_req_item, ett_pcp);
|
|
|
|
/* subtree for pmid */
|
|
pcp_desc_req_pmid_item = proto_tree_add_item(pcp_desc_req_tree, hf_pcp_pmid, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
pcp_desc_req_pmid_tree = proto_item_add_subtree(pcp_desc_req_pmid_item, ett_pcp);
|
|
|
|
/* flag - 1 bit */
|
|
proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_flag, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
|
|
bits_offset += 1;
|
|
/* domain - 9 bits */
|
|
proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_domain, tvb, bits_offset, 9, ENC_BIG_ENDIAN);
|
|
bits_offset += 9;
|
|
/* cluster - 12 bits */
|
|
proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_cluster, tvb, bits_offset, 12, ENC_BIG_ENDIAN);
|
|
bits_offset += 12;
|
|
/* item - 10 bits */
|
|
proto_tree_add_bits_item(pcp_desc_req_pmid_tree, hf_pcp_pmid_item, tvb, bits_offset, 10, ENC_BIG_ENDIAN);
|
|
/*bits_offset += 10;*/
|
|
offset += 4; /* the bytes offset should now be the same as the bits offset, not that we need this anymore */
|
|
return offset;
|
|
|
|
}
|
|
|
|
/* DESC packet format
|
|
pmID pmid
|
|
int type (base data type)
|
|
pmInDom indom
|
|
int sem (semantics of the value: instant? counter? etc..)
|
|
pmUnits units
|
|
|
|
|
v
|
|
signed int dimSpace : 4
|
|
signed int dimTime : 4
|
|
signed int dimCount : 4
|
|
unsigned int scaleSpace : 4
|
|
unsigned int scaleTime : 4
|
|
signed int scaleCount : 4
|
|
unsigned int pad : 8
|
|
*/
|
|
static int dissect_pcp_message_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_desc_item;
|
|
proto_tree *pcp_desc_tree;
|
|
proto_item *pcp_desc_units_item;
|
|
proto_tree *pcp_desc_units_tree;
|
|
guint32 bits_offset;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(DESC, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
/* root desc tree */
|
|
pcp_desc_item = proto_tree_add_item(tree, hf_pcp_desc, tvb, offset, 4, ENC_NA);
|
|
pcp_desc_tree = proto_item_add_subtree(pcp_desc_item, ett_pcp);
|
|
|
|
/* pmID */
|
|
offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_desc_tree, offset);
|
|
|
|
/* type */
|
|
proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_type, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* indom */
|
|
proto_tree_add_item(pcp_desc_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* sem */
|
|
proto_tree_add_item(pcp_desc_tree, hf_pcp_pmid_sem, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* pmUnits */
|
|
bits_offset = offset*8; /* create the bits offset */
|
|
pcp_desc_units_item = proto_tree_add_item(pcp_desc_tree, hf_pcp_units, tvb, offset, -1, ENC_NA);
|
|
pcp_desc_units_tree = proto_item_add_subtree(pcp_desc_units_item, ett_pcp);
|
|
|
|
/* dimspace */
|
|
proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimspace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
|
|
bits_offset += 4;
|
|
/* dimtime */
|
|
proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimtime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
|
|
bits_offset += 4;
|
|
/* dimcount */
|
|
proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_dimcount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
|
|
bits_offset += 4;
|
|
/* scalespace */
|
|
proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalespace, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
|
|
bits_offset += 4;
|
|
/* scaletime */
|
|
proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scaletime, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
|
|
bits_offset += 4;
|
|
/* scalecount */
|
|
proto_tree_add_bits_item(pcp_desc_units_tree, hf_pcp_units_scalecount, tvb, bits_offset, 4, ENC_BIG_ENDIAN);
|
|
/*bits_offset += 4;*/
|
|
/* padding */
|
|
offset += 3; /* total offset of pmunits before */
|
|
proto_tree_add_item(pcp_desc_units_tree, hf_pcp_pdu_padding, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
/*bits_offset += 8;*/
|
|
return offset;
|
|
|
|
}
|
|
|
|
/* INSTANCE_REQ packet format
|
|
pmInDom indom
|
|
__pmTimeval when
|
|
int inst
|
|
int namelen
|
|
char name
|
|
*/
|
|
static int dissect_pcp_message_instance_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_instance_req_item;
|
|
proto_tree *pcp_instance_req_tree;
|
|
guint32 name_len;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(INSTANCE_REQ, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_instance_req_item = proto_tree_add_item(tree, hf_pcp_instance_req, tvb, offset, -1, ENC_NA);
|
|
pcp_instance_req_tree = proto_item_add_subtree(pcp_instance_req_item, ett_pcp);
|
|
|
|
/* indom */
|
|
proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* when */
|
|
offset = dissect_pcp_partial_when(tvb, pinfo, pcp_instance_req_tree, offset);
|
|
|
|
/* inst */
|
|
proto_tree_add_item(pcp_instance_req_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* namelen */
|
|
proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
name_len = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* name */
|
|
if (name_len > 0) {
|
|
proto_tree_add_item(pcp_instance_req_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
|
|
offset += name_len;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* TEXT_REQ packet format
|
|
int ident
|
|
int type
|
|
*/
|
|
static int dissect_pcp_message_text_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_text_req_item;
|
|
proto_tree *pcp_text_req_tree;
|
|
proto_item *pcp_text_req_type_item;
|
|
proto_tree *pcp_text_req_type_tree;
|
|
guint32 bits_offset;
|
|
guint32 type;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(TEXT_REQ, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_text_req_item = proto_tree_add_item(tree, hf_pcp_text_req, tvb, offset, -1, ENC_NA);
|
|
pcp_text_req_tree = proto_item_add_subtree(pcp_text_req_item, ett_pcp);
|
|
|
|
/* peek at type to decode ident correctly */
|
|
type = tvb_get_ntohl(tvb, offset + 4);
|
|
|
|
/* ident */
|
|
if (type & PM_TEXT_PMID) {
|
|
offset = dissect_pcp_partial_pmid(tvb, pinfo, pcp_text_req_tree, offset);
|
|
} else if (type & PM_TEXT_INDOM) {
|
|
proto_tree_add_item(pcp_text_req_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
|
|
/* type */
|
|
pcp_text_req_type_item = proto_tree_add_item(pcp_text_req_tree, hf_pcp_text_type, tvb, offset, 4, ENC_NA);
|
|
pcp_text_req_type_tree = proto_item_add_subtree(pcp_text_req_type_item, ett_pcp);
|
|
bits_offset = offset * 8 + 28;
|
|
proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_ident, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
|
|
bits_offset += 2;
|
|
proto_tree_add_bits_item(pcp_text_req_type_tree, hf_pcp_text_type_format, tvb, bits_offset, 2, ENC_BIG_ENDIAN);
|
|
|
|
offset += 4;
|
|
return offset;
|
|
}
|
|
|
|
/* TEXT packet format
|
|
int ident
|
|
int buflen
|
|
char buffer
|
|
*/
|
|
static int dissect_pcp_message_text(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_text_item;
|
|
proto_tree *pcp_text_tree;
|
|
guint32 buflen;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(TEXT, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_text_item = proto_tree_add_item(tree, hf_pcp_text, tvb, offset, -1, ENC_NA);
|
|
pcp_text_tree = proto_item_add_subtree(pcp_text_item, ett_pcp);
|
|
|
|
/* ident */
|
|
proto_tree_add_item(pcp_text_tree, hf_pcp_text_ident, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* buflen */
|
|
buflen = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(pcp_text_tree, hf_pcp_text_buflen, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* buffer */
|
|
proto_tree_add_item(pcp_text_tree, hf_pcp_text_buffer, tvb, offset, buflen, ENC_ASCII|ENC_NA);
|
|
offset += buflen;
|
|
|
|
return offset;
|
|
}
|
|
|
|
/* INSTANCE packet type
|
|
pmInDom indom
|
|
int numinst
|
|
instlist_t instlist[numinst]
|
|
|
|
|
|> int inst
|
|
int namelen
|
|
char name
|
|
*/
|
|
static int dissect_pcp_message_instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_instances_item;
|
|
proto_tree *pcp_instances_tree;
|
|
proto_item *pcp_instance_item;
|
|
proto_tree *pcp_instance_tree;
|
|
guint32 num_inst;
|
|
guint32 i;
|
|
guint32 name_len;
|
|
guint32 padding;
|
|
|
|
/* append the type of packet */
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "[%s]", val_to_str(INSTANCE, packettypenames, "Unknown Type:0x%02x"));
|
|
|
|
pcp_instances_item = proto_tree_add_item(tree, hf_pcp_instances, tvb, offset, -1, ENC_NA);
|
|
pcp_instances_tree = proto_item_add_subtree(pcp_instances_item, ett_pcp);
|
|
|
|
/* indom */
|
|
proto_tree_add_item(pcp_instances_tree, hf_pcp_instance_indom, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
/* numinst */
|
|
proto_tree_add_item(pcp_instances_tree, hf_pcp_instances_numinst, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
num_inst = tvb_get_ntohl(tvb, offset);
|
|
offset += 4;
|
|
|
|
/* instlist */
|
|
for (i=0; i<num_inst; i++) {
|
|
/* get the size of the name first, so we know how much offset to give */
|
|
name_len = tvb_get_ntohl(tvb, offset+4);
|
|
|
|
/* give the subtree name length + 2 ints */
|
|
pcp_instance_item = proto_tree_add_item(pcp_instances_tree, hf_pcp_instance, tvb, offset, name_len+8, ENC_NA);
|
|
pcp_instance_tree = proto_item_add_subtree(pcp_instance_item, ett_pcp);
|
|
|
|
/* inst */
|
|
proto_tree_add_item(pcp_instance_tree, hf_pcp_pmid_inst, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* namelen */
|
|
proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_namelen, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* name */
|
|
if (name_len > 0) {
|
|
proto_tree_add_item(pcp_instance_tree, hf_pcp_instance_name, tvb, offset, name_len, ENC_ASCII|ENC_NA);
|
|
offset += name_len;
|
|
}
|
|
|
|
/* padding */
|
|
padding = name_len % 4; /* names are padded to the nearest 4 byte boundary */
|
|
if (padding != 0) { /* if there is padding, keep going till the remainder of mod 4 */
|
|
padding = 4 - padding; /* we want the inverse of the remainder */
|
|
|
|
proto_tree_add_item(pcp_instance_tree, hf_pcp_pdu_padding, tvb, offset, padding, ENC_NA);
|
|
offset += padding;
|
|
}
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/* PARTIAL DISSECTOR ROUTINES
|
|
these routines are called by dissect_pcp_message_* as needed
|
|
*/
|
|
|
|
static int dissect_pcp_partial_pmid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_pmid_item;
|
|
proto_tree *pcp_pmid_tree;
|
|
guint32 bits_offset;
|
|
|
|
bits_offset = offset * 8;
|
|
|
|
/* subtree for pmid */
|
|
pcp_pmid_item = proto_tree_add_item(tree, hf_pcp_pmid, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
pcp_pmid_tree = proto_item_add_subtree(pcp_pmid_item, ett_pcp);
|
|
|
|
/* flag - 1 bit */
|
|
proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_flag, tvb, bits_offset, 1, ENC_BIG_ENDIAN);
|
|
bits_offset += 1;
|
|
/* domain - 9 bits */
|
|
proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_domain, tvb, bits_offset, 9, ENC_BIG_ENDIAN);
|
|
bits_offset += 9;
|
|
/* cluster - 12 bits */
|
|
proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_cluster, tvb, bits_offset, 12, ENC_BIG_ENDIAN);
|
|
bits_offset += 12;
|
|
/* item - 10 bits */
|
|
proto_tree_add_bits_item(pcp_pmid_tree, hf_pcp_pmid_item, tvb, bits_offset, 10, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
return offset;
|
|
}
|
|
|
|
static int dissect_pcp_partial_when(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
|
|
{
|
|
proto_item *pcp_when_item;
|
|
proto_tree *pcp_when_tree;
|
|
|
|
/* when - create a new subtree for each val */
|
|
pcp_when_item = proto_tree_add_item(tree, hf_pcp_when, tvb, offset, 8, ENC_NA);
|
|
pcp_when_tree = proto_item_add_subtree(pcp_when_item, ett_pcp);
|
|
|
|
/* when tv_sec */
|
|
proto_tree_add_item(pcp_when_tree, hf_pcp_when_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
/* when tv_usec */
|
|
proto_tree_add_item(pcp_when_tree, hf_pcp_when_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
return offset;
|
|
}
|
|
|
|
/* MAIN DISSECTING ROUTINE (after passed from dissect_tcp, all packets hit function) */
|
|
static int dissect_pcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
|
{
|
|
proto_item *root_pcp_item;
|
|
proto_tree *pcp_tree;
|
|
guint32 packet_type;
|
|
gint32 err_bytes;
|
|
int offset = 0;
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCP");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
|
|
root_pcp_item = proto_tree_add_item(tree, proto_pcp, tvb, 0, -1, ENC_NA);
|
|
pcp_tree = proto_item_add_subtree(root_pcp_item, ett_pcp);
|
|
|
|
packet_type = tvb_get_ntohl(tvb, 4);
|
|
|
|
/* check if we are the client requesting or the server */
|
|
if (pinfo->srcport == PCP_PORT) {
|
|
col_set_str(pinfo->cinfo, COL_INFO, "Server > Client ");
|
|
} else {
|
|
col_set_str(pinfo->cinfo, COL_INFO, "Client > Server ");
|
|
}
|
|
|
|
/* PCP packet length */
|
|
proto_tree_add_item(pcp_tree, hf_pcp_pdu_length, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
/* PCP Packet type */
|
|
proto_tree_add_item(pcp_tree, hf_pcp_pdu_type, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
/* PCP Remote PID */
|
|
proto_tree_add_item(pcp_tree, hf_pcp_pdu_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
|
|
/* dissect the rest of the packet depending on the type */
|
|
switch (packet_type) {
|
|
case CREDS:
|
|
dissect_pcp_message_creds(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case START_OR_ERROR:
|
|
err_bytes = tvb_get_ntohl(tvb, offset); /* get the first 4 bytes, determine if this is an error or not */
|
|
/* errors are signed and are all negative so check for a negative number.
|
|
It's the only way we can differentiate between start/error packets */
|
|
if (err_bytes < 0) {
|
|
dissect_pcp_message_error(tvb, pinfo, pcp_tree, offset);
|
|
} else {
|
|
dissect_pcp_message_start(tvb, pinfo, pcp_tree, offset);
|
|
}
|
|
break;
|
|
|
|
case PMNS_TRAVERSE:
|
|
dissect_pcp_message_pmns_traverse(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case PMNS_NAMES:
|
|
dissect_pcp_message_pmns_names(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case PMNS_CHILD:
|
|
dissect_pcp_message_pmns_child(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case PMNS_IDS:
|
|
dissect_pcp_message_pmns_ids(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case PROFILE:
|
|
dissect_pcp_message_profile(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case FETCH:
|
|
dissect_pcp_message_fetch(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case RESULT:
|
|
dissect_pcp_message_result(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case DESC_REQ:
|
|
dissect_pcp_message_desc_req(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case DESC:
|
|
dissect_pcp_message_desc(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case INSTANCE_REQ:
|
|
dissect_pcp_message_instance_req(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case INSTANCE:
|
|
dissect_pcp_message_instance(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case TEXT_REQ:
|
|
dissect_pcp_message_text_req(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
case TEXT:
|
|
dissect_pcp_message_text(tvb, pinfo, pcp_tree, offset);
|
|
break;
|
|
|
|
default:
|
|
/* append the type of packet */
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[UNIMPLEMENTED TYPE]");
|
|
/* if we got here, then we didn't get a packet type that we know of */
|
|
expert_add_info(pinfo, pcp_tree, &ei_pcp_unimplemented_packet_type);
|
|
break;
|
|
}
|
|
return tvb_length(tvb);
|
|
}
|
|
|
|
static int dissect_pcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
|
|
{
|
|
/* pass all packets through TCP-reassembally */
|
|
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, PCP_HEADER_LEN, get_pcp_message_len, dissect_pcp_message, data);
|
|
return tvb_length(tvb);
|
|
}
|
|
|
|
/* setup the dissecting */
|
|
void proto_register_pcp(void)
|
|
{
|
|
static hf_register_info hf[] = {
|
|
{ &hf_pcp_pdu_length,
|
|
{ "PDU Length", "pcp.length",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pdu_type,
|
|
{ "Type", "pcp.type",
|
|
FT_UINT32, BASE_HEX,
|
|
VALS(packettypenames), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pdu_pid,
|
|
{ "From", "pcp.from",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pdu_error,
|
|
{ "Error", "pcp.error",
|
|
FT_INT32, BASE_DEC,
|
|
VALS(packettypenames_errors), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pdu_padding,
|
|
{ "Padding", "pcp.padding",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_creds_number_of,
|
|
{ "Number of Credentials", "pcp.creds.number",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_creds_type,
|
|
{ "Credentials Type", "pcp.creds.type",
|
|
FT_UINT8, BASE_DEC,
|
|
VALS(packettypenames_creds), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_creds_vala,
|
|
{ "Credentials Value A", "pcp.creds.vala",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_creds_valb,
|
|
{ "Credentials Value B", "pcp.creds.valb",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_creds_valc,
|
|
{ "Credentials Value C", "pcp.creds.valc",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_start,
|
|
{ "Start", "pcp.start",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_start_zero,
|
|
{ "Start Compatibility Bit", "pcp.start.zero",
|
|
FT_BOOLEAN, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_start_version,
|
|
{ "Version", "pcp.start.version",
|
|
FT_UINT8, BASE_DEC, /* not a real 8 bit int, only uses 7 bits */
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_start_status,
|
|
{ "Start Status", "pcp.start.status",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_start_licensed,
|
|
{ "Licensed", "pcp.start.licensed",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_start_authorize,
|
|
{ "Authorize", "pcp.start.authorize",
|
|
FT_UINT16, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_traverse,
|
|
{ "PMNS Traverse", "pcp.pmns_traverse",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_subtype,
|
|
{ "Subtype", "pcp.pmns.subtype",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_namelen,
|
|
{ "Name Length", "pcp.pmns.namelen",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_name,
|
|
{ "Name", "pcp.pmns.name",
|
|
FT_STRING, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names,
|
|
{ "PMNS Names", "pcp.pmns_names",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_nstrbytes,
|
|
{ "String Bytes", "pcp.pmns_names.nstrbytes",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_numstatus,
|
|
{ "Status", "pcp.pmns_names.numstatus",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_numnames,
|
|
{ "Number of Names", "pcp.pmns_names.numnames",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_nametree,
|
|
{ "Names", "pcp.pmns_names.nametree",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_nametree_status,
|
|
{ "Status", "pcp.pmns_names.nametree.status",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_nametree_namelen,
|
|
{ "Length", "pcp.pmns_names.nametree.namelen",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_names_nametree_name,
|
|
{ "Name", "pcp.pmns_names.nametree.name",
|
|
FT_STRING, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_ids,
|
|
{ "PMNS IDs", "pcp.pmns_ids",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_ids_status,
|
|
{ "Status", "pcp.pmns_ids.status",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_ids_numids,
|
|
{ "Number of IDs", "pcp.pmns_ids.numids",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmns_child,
|
|
{ "PMID Child", "pcp.pmns.child",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid,
|
|
{ "PMID", "pcp.pmid",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_flag,
|
|
{ "Flag", "pcp.pmid.flag",
|
|
FT_BOOLEAN, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_domain,
|
|
{ "Domain", "pcp.pmid.domain",
|
|
FT_UINT16, BASE_DEC, /* uses 9 bits */
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_cluster,
|
|
{ "Cluster", "pcp.pmid.cluster",
|
|
FT_UINT16, BASE_DEC, /* uses 12 bits */
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_item,
|
|
{ "Item", "pcp.pmid.item",
|
|
FT_UINT16, BASE_DEC, /* uses 10 bits */
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_type,
|
|
{ "Type", "pcp.pmid.type",
|
|
FT_INT8, BASE_DEC,
|
|
VALS(packettypenames_pm_types), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_sem,
|
|
{ "Type Semantics", "pcp.pmid.sem",
|
|
FT_UINT32, BASE_DEC,
|
|
VALS(packettypenames_pm_types_sem), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_pmid_inst,
|
|
{ "Instance", "pcp.pmid.inst",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_profile,
|
|
{ "Profile", "pcp.profile",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_ctxnum,
|
|
{ "Context Number", "pcp.ctxnum",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_profile_g_state,
|
|
{ "Global Include/Exclude State", "pcp.profile.g_state",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_profile_numprof,
|
|
{ "Number of Profiles", "pcp.profile.numprof",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_profile_profile,
|
|
{ "Each Profile", "pcp.profile.profile",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_profile_profile_state,
|
|
{ "Include/Exclude State", "pcp.profile.profile.state",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_profile_profile_numinst,
|
|
{ "Number Instances to Follow", "pcp.profile.profile.numinst",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_fetch,
|
|
{ "Fetch", "pcp.fetch",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_fetch_numpmid,
|
|
{ "Number PMIDs", "pcp.fetch.numpmid",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_when,
|
|
{ "Time Value", "pcp.when",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_when_sec,
|
|
{ "Seconds", "pcp.when.sec",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_when_usec,
|
|
{ "Microseconds", "pcp.when.usec",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_desc_req,
|
|
{ "Description Request", "pcp.desc_req",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_desc,
|
|
{ "Description Response", "pcp.desc",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units,
|
|
{ "PMID Units", "pcp.units",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units_dimspace,
|
|
{ "Dimension Space", "pcp.units.dimspace",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units_dimtime,
|
|
{ "Dimension Time", "pcp.units.dimtime",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units_dimcount,
|
|
{ "Dimension Count", "pcp.units.dimcount",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units_scalespace,
|
|
{ "Scale Space", "pcp.units.scalespace",
|
|
FT_UINT8, BASE_DEC,
|
|
VALS(packettypenames_pm_units_space), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units_scaletime,
|
|
{ "Scale Time", "pcp.units.scalespace",
|
|
FT_UINT8, BASE_DEC,
|
|
VALS(packettypenames_pm_units_time), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_units_scalecount,
|
|
{ "Scale Count", "pcp.units.scalecount",
|
|
FT_UINT8, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_req,
|
|
{ "Instance Request", "pcp.instance_req",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instances,
|
|
{ "Instance Response", "pcp.instances",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instances_numinst,
|
|
{ "Number of Instances", "pcp.instance_resp.numinst",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance,
|
|
{ "Instance", "pcp.instance",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_namelen,
|
|
{ "Name Length", "pcp.instance.namelen",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_name,
|
|
{ "Name", "pcp.instance.name",
|
|
FT_STRING, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_indom,
|
|
{ "Instance Domain", "pcp.instance.indom",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_valoffset,
|
|
{ "Instance Offset", "pcp.instance.valoffset",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_vallength,
|
|
{ "Instance Value Length", "pcp.instance.vallength",
|
|
FT_INT24, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_insitu,
|
|
{ "Instance Value", "pcp.instance.value.uint",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_ptr,
|
|
{ "Instance Value", "pcp.instance.value.string",
|
|
FT_STRING, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_int,
|
|
{ "Instance Value", "pcp.instance.value.int",
|
|
FT_INT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_uint,
|
|
{ "Instance Value", "pcp.instance.value.uint",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_int64,
|
|
{ "Instance Value", "pcp.instance.value.int64",
|
|
FT_INT64, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_uint64,
|
|
{ "Instance Value", "pcp.instance.value.uint64",
|
|
FT_UINT64, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_float,
|
|
{ "Instance Value", "pcp.instance.value.float",
|
|
FT_FLOAT, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_double,
|
|
{ "Instance Value", "pcp.instance.value.float",
|
|
FT_DOUBLE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_instance_value_aggr,
|
|
{ "Instance Value", "pcp.instance.value.bytes",
|
|
FT_BYTES, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_results,
|
|
{ "Fetch Results", "pcp.results",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_results_numpmid,
|
|
{ "Number of PMIDs", "pcp.results.numpmid",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_result,
|
|
{ "Result", "pcp.result",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_result_numval,
|
|
{ "Number of Values", "pcp.result.numval",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_result_valfmt,
|
|
{ "Value Encoding Format", "pcp.result.valfmt",
|
|
FT_UINT32, BASE_DEC,
|
|
VALS(packettypenames_valfmt), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_req,
|
|
{ "Text Request", "pcp.text_req",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_type,
|
|
{ "Help Text Type", "pcp.text.type",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_type_format,
|
|
{ "Text Type Format", "pcp.text.type.format",
|
|
FT_UINT8, BASE_DEC,
|
|
VALS(packettypenames_text_type_format), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_type_ident,
|
|
{ "Text Type Ident", "pcp.text.type.ident",
|
|
FT_UINT8, BASE_DEC,
|
|
VALS(packettypenames_text_type_ident), 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text,
|
|
{ "Text Response", "pcp.text",
|
|
FT_NONE, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_ident,
|
|
{ "Text Ident (raw)", "pcp.text.ident",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_buflen,
|
|
{ "Text Buffer Length", "pcp.text.buflen",
|
|
FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
{ &hf_pcp_text_buffer,
|
|
{ "Text Buffer", "pcp.text.buffer",
|
|
FT_STRING, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL
|
|
}
|
|
},
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
&ett_pcp,
|
|
&ett_pcp_pdu_length,
|
|
&ett_pcp_pdu_type,
|
|
&ett_pcp_pdu_pid,
|
|
&ett_pcp_pdu_error,
|
|
&ett_pcp_pdu_padding,
|
|
&ett_pcp_creds_number_of,
|
|
&ett_pcp_creds_type,
|
|
&ett_pcp_creds_vala,
|
|
&ett_pcp_creds_valb,
|
|
&ett_pcp_creds_valc,
|
|
&ett_pcp_start,
|
|
&ett_pcp_start_status,
|
|
&ett_pcp_start_zero,
|
|
&ett_pcp_start_version,
|
|
&ett_pcp_start_licensed,
|
|
&ett_pcp_start_authorize,
|
|
&ett_pcp_pmns_traverse,
|
|
&ett_pcp_pmns_subtype,
|
|
&ett_pcp_pmns_namelen,
|
|
&ett_pcp_pmns_name,
|
|
&ett_pcp_pmns_names,
|
|
&ett_pcp_pmns_names_nstrbytes,
|
|
&ett_pcp_pmns_names_numstatus,
|
|
&ett_pcp_pmns_names_numnames,
|
|
&ett_pcp_pmns_names_nametree,
|
|
&ett_pcp_pmns_names_nametree_status,
|
|
&ett_pcp_pmns_names_nametree_namelen,
|
|
&ett_pcp_pmns_names_nametree_name,
|
|
&ett_pcp_pmns_ids,
|
|
&ett_pcp_pmns_ids_status,
|
|
&ett_pcp_pmns_ids_numids,
|
|
&ett_pcp_pmns_child,
|
|
&ett_pcp_pmid,
|
|
&ett_pcp_pmid_flag,
|
|
&ett_pcp_pmid_domain,
|
|
&ett_pcp_pmid_cluster,
|
|
&ett_pcp_pmid_item,
|
|
&ett_pcp_pmid_type,
|
|
&ett_pcp_pmid_sem,
|
|
&ett_pcp_profile,
|
|
&ett_pcp_ctxnum,
|
|
&ett_pcp_profile_g_state,
|
|
&ett_pcp_profile_numprof,
|
|
&ett_pcp_profile_profile,
|
|
&ett_pcp_profile_profile_state,
|
|
&ett_pcp_profile_profile_numinst,
|
|
&ett_pcp_fetch,
|
|
&ett_pcp_fetch_numpmid,
|
|
&ett_pcp_when,
|
|
&ett_pcp_when_sec,
|
|
&ett_pcp_when_usec,
|
|
&ett_pcp_desc_req,
|
|
&ett_pcp_units,
|
|
&ett_pcp_units_dimspace,
|
|
&ett_pcp_units_dimtime,
|
|
&ett_pcp_units_dimcount,
|
|
&ett_pcp_units_scalespace,
|
|
&ett_pcp_units_scaletime,
|
|
&ett_pcp_units_scalecount,
|
|
&ett_pcp_instance,
|
|
&ett_pcp_instance_req,
|
|
&ett_pcp_instance_namelen,
|
|
&ett_pcp_instance_name,
|
|
&ett_pcp_instance_indom,
|
|
&ett_pcp_instance_inst,
|
|
&ett_pcp_instance_valoffset,
|
|
&ett_pcp_instance_vallength,
|
|
&ett_pcp_instance_value_insitu,
|
|
&ett_pcp_instance_value_ptr,
|
|
&ett_pcp_instance_value_int,
|
|
&ett_pcp_instance_value_uint,
|
|
&ett_pcp_instance_value_int64,
|
|
&ett_pcp_instance_value_uint64,
|
|
&ett_pcp_instance_value_float,
|
|
&ett_pcp_instance_value_double,
|
|
&ett_pcp_instance_value_aggr,
|
|
&ett_pcp_instances,
|
|
&ett_pcp_instances_numinst,
|
|
&ett_pcp_results,
|
|
&ett_pcp_results_numpmid,
|
|
&ett_pcp_result,
|
|
&ett_pcp_result_numval,
|
|
&ett_pcp_result_valfmt,
|
|
&ett_pcp_text_req,
|
|
&ett_pcp_text_type,
|
|
&ett_pcp_text_type_format,
|
|
&ett_pcp_text_type_ident,
|
|
&ett_pcp_text,
|
|
&ett_pcp_text_ident,
|
|
&ett_pcp_text_buflen,
|
|
&ett_pcp_text_buffer,
|
|
};
|
|
|
|
static ei_register_info ei[] = {
|
|
{ &ei_pcp_type_event_unimplemented, { "pcp.pmid.type.event.unimplemented", PI_UNDECODED, PI_WARN, "PM_TYPE_EVENT: Unimplemented Value Type", EXPFILL }},
|
|
{ &ei_pcp_type_nosupport_unsupported, { "pcp.pmid.type.nosupport.unsupported", PI_UNDECODED, PI_WARN, "PM_TYPE_NOSUPPORT: Unsupported Value Type", EXPFILL }},
|
|
{ &ei_pcp_type_unknown_unknown_value, { "pcp.pmid.type.unknown.unknown_value", PI_UNDECODED, PI_WARN, "PM_TYPE_UNKNOWN: Unknown Value Type", EXPFILL }},
|
|
{ &ei_pcp_unimplemented_value, { "pcp.pmid.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Value Type", EXPFILL }},
|
|
{ &ei_pcp_unimplemented_packet_type, { "pcp.type.unimplemented", PI_UNDECODED, PI_WARN, "Unimplemented Packet Type", EXPFILL }},
|
|
};
|
|
|
|
expert_module_t* expert_pcp;
|
|
|
|
expert_pcp = expert_register_protocol(proto_pcp);
|
|
expert_register_field_array(expert_pcp, ei, array_length(ei));
|
|
|
|
proto_pcp = proto_register_protocol("Performance Co-Pilot", "PCP", "pcp");
|
|
|
|
proto_register_field_array(proto_pcp, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
}
|
|
|
|
void proto_reg_handoff_pcp(void)
|
|
{
|
|
dissector_handle_t pcp_handle;
|
|
|
|
pcp_handle = new_create_dissector_handle(dissect_pcp, proto_pcp);
|
|
dissector_add_uint("tcp.port", PCP_PORT, pcp_handle);
|
|
}
|
|
|
|
/*
|
|
* Editor modelines - http://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=4 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|