/* packet-qcdiag_msg.c * Routines for Qualcomm DIAG MSG packet handling * * (C) 2016-2017 by Harald Welte * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "packet-qcdiag.h" static int proto_qcdiag_msg = -1; static int hf_qcdiag_msg_ts_type = -1; static int hf_qcdiag_msg_num_args = -1; static int hf_qcdiag_msg_drop_cnt = -1; static int hf_qcdiag_msg_line_nr = -1; static int hf_qcdiag_msg_subsys_id = -1; static int hf_qcdiag_msg_subsys_mask = -1; static int hf_qcdiag_msg_fmt_str = -1; static int hf_qcdiag_msg_file_name = -1; static int hf_qcdiag_msg_argument = -1; static gint ett_qcdiag_msg = -1; #define MAX_ARGS 16 static int dissect_qcdiag_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * data _U_) { proto_item *ti; proto_tree *diag_msg_tree; gint offset = 1; /* command already dissected by proto-qcdiag.c */ guint num_args, line_nr, subsys_id, subsys_mask, i; const guint8 *fmtstr, *file_name; guint args[MAX_ARGS]; col_set_str(pinfo->cinfo, COL_PROTOCOL, "QCDIAG-MSG"); ti = proto_tree_add_item(tree, proto_qcdiag_msg, tvb, 0, -1, ENC_NA); diag_msg_tree = proto_item_add_subtree(ti, ett_qcdiag_msg); proto_tree_add_item(diag_msg_tree, hf_qcdiag_msg_ts_type, tvb, offset++, 1, ENC_NA); proto_tree_add_item_ret_uint(diag_msg_tree, hf_qcdiag_msg_num_args, tvb, offset++, 1, ENC_NA, &num_args); proto_tree_add_item(diag_msg_tree, hf_qcdiag_msg_drop_cnt, tvb, offset++, 1, ENC_NA); /* timestamp */ offset += 8; proto_tree_add_item_ret_uint(diag_msg_tree, hf_qcdiag_msg_line_nr, tvb, offset, 2, ENC_LITTLE_ENDIAN, &line_nr); offset += 2; proto_tree_add_item_ret_uint(diag_msg_tree, hf_qcdiag_msg_subsys_id, tvb, offset, 2, ENC_LITTLE_ENDIAN, &subsys_id); offset += 2; proto_tree_add_item_ret_uint(diag_msg_tree, hf_qcdiag_msg_subsys_mask, tvb, offset, 4, ENC_LITTLE_ENDIAN, &subsys_mask); offset += 4; /* Append all arguments */ for (i = 0; i < num_args; i++) { if (i < MAX_ARGS) proto_tree_add_item_ret_uint(diag_msg_tree, hf_qcdiag_msg_argument, tvb, offset, 4, ENC_LITTLE_ENDIAN, &args[i]); else proto_tree_add_item(diag_msg_tree, hf_qcdiag_msg_argument, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; } proto_tree_add_item_ret_string(diag_msg_tree, hf_qcdiag_msg_fmt_str, tvb, offset, -1, ENC_ASCII, wmem_packet_scope(), &fmtstr); offset += tvb_strsize(tvb, offset); proto_tree_add_item_ret_string(diag_msg_tree, hf_qcdiag_msg_file_name, tvb, offset, -1, ENC_ASCII, wmem_packet_scope(), &file_name); offset += tvb_strsize(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, "%s:%u ", file_name, line_nr); switch (num_args) { case 0: col_append_str(pinfo->cinfo, COL_INFO, fmtstr); break; case 1: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0]); break; case 2: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1]); break; case 3: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2]); break; case 4: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3]); break; case 5: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4]); break; case 6: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5]); break; case 7: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; case 8: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); break; case 9: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); break; case 10: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); break; case 11: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]); break; case 12: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11]); break; case 13: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12]); break; case 14: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13]); break; case 15: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13], args[14]); break; case 16: col_append_fstr(pinfo->cinfo, COL_INFO, fmtstr, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], args[12], args[13], args[14], args[15]); break; } return tvb_captured_length(tvb); } void proto_register_qcdiag_msg(void) { static hf_register_info hf[] = { { &hf_qcdiag_msg_ts_type, { "Timestamp Type", "qcdiag_msg.ts_type", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_num_args, { "Number of Arguments", "qcdiag_msg.num_args", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_drop_cnt, { "Dropped message count", "qcdiag_msg.num_drop_cnt", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_line_nr, { "Line Number", "qcdiag_msg.line_nr", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_subsys_id, { "Subsystem ID", "qcdiag_msg.subsys_id", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_subsys_mask, { "Subsystem Mask", "qcdiag_msg.subsys_mask", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_fmt_str, { "Format String", "qcdiag_msg.fmt_str", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_file_name, { "File Name", "qcdiag_msg.fmt_str", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_qcdiag_msg_argument, { "Argument", "qcdiag_msg.argument", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } }, }; static gint *ett[] = { &ett_qcdiag_msg }; proto_qcdiag_msg = proto_register_protocol("Qualcomm DIAG Msg", "QCDIAG MSG", "qcdiag_msg"); proto_register_field_array(proto_qcdiag_msg, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_qcdiag_msg(void) { dissector_handle_t qcdiag_msg_handle; qcdiag_msg_handle = create_dissector_handle(dissect_qcdiag_msg, proto_qcdiag_msg); dissector_add_uint("qcdiag.cmd", DIAG_EXT_MSG_F, qcdiag_msg_handle); } /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 8 * tab-width: 8 * indent-tabs-mode: t * End: * * vi: set shiftwidth=8 tabstop=8 noexpandtab: * :indentSize=8:tabSize=8:noTabs=false: */