/* packet-mtp3mg.c * Routines for Message Transfer Part Level 3 Management and Test dissection * * It is (hopefully) compliant to: * ANSI T1.111.4-1996 * ITU-T Q.704 7/1996 * ITU-T Q.707 7/1996 and ANSI T1.111.7-1996 (for SLT message formats) * portions of ITU-T Q.2210 7/1996 (for XCO/XCA message formats) * GF 001-9001 (Chinese ITU variant) * * Copyright 2003, Jeff Morriss * * $Id: packet-mtp3mg.c,v 1.12 2004/02/02 17:57:20 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * Copied from packet-mtp3.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #ifdef NEED_SNPRINTF_H #include "snprintf.h" #endif #include #include "prefs.h" #include /* MTP3 Service Indicators used by this dissector */ #define MTP3MG_SI 0 #define MTP3MG_ITU_TEST_SI 1 #define MTP3MG_ANSI_TEST_SI 2 #define H0H1_LENGTH 1 #define H0_MASK 0x0f #define H1_MASK 0xf0 #define H1_SHIFT 4 #define H0_CHM 0x01 #define H0_ECM 0x02 #define H0_FCM 0x03 #define H0_TFM 0x04 #define H0_RSM 0x05 #define H0_MIM 0x06 #define H0_TRM 0x07 #define H0_DLM 0x08 #define H0_UFC 0x0a static const value_string h0_message_type_values[] = { { H0_CHM, "Changeover and changeback messages" }, { H0_ECM, "Emergency changeover messages" }, { H0_FCM, "Transfer-controlled and signalling route set congestion messages" }, { H0_TFM, "Transfer prohibited-allowed-restricted messages" }, { H0_RSM, "Signalling-route-set-test messages" }, { H0_MIM, "Management inhibit messages" }, { H0_TRM, "Traffic restart messages" }, { H0_DLM, "Signalling-data-link-connection messages" }, { H0_UFC, "User part flow control messages" }, { 0, NULL } }; #define TEST_H0_SLT 0x1 static const value_string test_h0_message_type_values[] = { { TEST_H0_SLT, "Test messages" }, { 0, NULL } }; #define CHM_H1_COO 0x01 #define CHM_H1_COA 0x02 #define CHM_H1_XCO 0x03 #define CHM_H1_XCA 0x04 #define CHM_H1_CBD 0x05 #define CHM_H1_CBA 0x06 static const value_string chm_h1_message_type_values[] = { { CHM_H1_COO, "Changeover-order signal" }, { CHM_H1_COA, "Changeover-ack signal" }, { CHM_H1_XCO, "Extended changeover-order signal" }, { CHM_H1_XCA, "Extended changeover-ack signal" }, { CHM_H1_CBD, "Changeback-declaration signal" }, { CHM_H1_CBA, "Changeback-ack signal" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string chm_h1_message_type_acro_values[] = { { CHM_H1_COO, "COO" }, { CHM_H1_COA, "COA" }, { CHM_H1_XCO, "XCO" }, { CHM_H1_XCA, "XCA" }, { CHM_H1_CBD, "CBD" }, { CHM_H1_CBA, "CBA" }, { 0, NULL } }; #define ECM_H1_ECO 0x01 #define ECM_H1_ECA 0x02 static const value_string ecm_h1_message_type_values[] = { { ECM_H1_ECO, "Emergency-changeover-order signal" }, { ECM_H1_ECA, "Emergency-changeover-ack signal" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string ecm_h1_message_type_acro_values[] = { { ECM_H1_ECO, "ECO" }, { ECM_H1_ECA, "ECA" }, { 0, NULL } }; #define FCM_H1_RCT 0x01 #define FCM_H1_TFC 0x02 static const value_string fcm_h1_message_type_values[] = { { FCM_H1_RCT, "Signalling-route-set-congestion-test signal" }, { FCM_H1_TFC, "Transfer-controlled signal" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string fcm_h1_message_type_acro_values[] = { { FCM_H1_RCT, "RCT" }, { FCM_H1_TFC, "TFC" }, { 0, NULL } }; #define TFM_H1_TFP 0x01 #define TFM_H1_TCP 0x02 /* ANSI only */ #define TFM_H1_TFR 0x03 #define TFM_H1_TCR 0x04 /* ANSI only */ #define TFM_H1_TFA 0x05 #define TFM_H1_TCA 0x06 /* ANSI only */ static const value_string tfm_h1_message_type_values[] = { { TFM_H1_TFP, "Transfer-prohibited signal" }, { TFM_H1_TCP, "Transfer-cluster-prohibited signal (ANSI only)" }, { TFM_H1_TFR, "Transfer-restricted signal" }, { TFM_H1_TCR, "Transfer-cluster-restricted signal (ANSI only)" }, { TFM_H1_TFA, "Transfer-allowed signal" }, { TFM_H1_TCA, "Transfer-cluster-allowed signal (ANSI only)" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string tfm_h1_message_type_acro_values[] = { { TFM_H1_TFP, "TFP" }, { TFM_H1_TCP, "TCP" }, { TFM_H1_TFR, "TFR" }, { TFM_H1_TCR, "TCR" }, { TFM_H1_TFA, "TFA" }, { TFM_H1_TCA, "TCA" }, { 0, NULL } }; #define RSM_H1_RST 0x01 #define RSM_H1_RSR 0x02 #define RSM_H1_RCP 0x03 /* ANSI only */ #define RSM_H1_RCR 0x04 /* ANSI only */ static const value_string rsm_h1_message_type_values[] = { { RSM_H1_RST, "Signalling-route-set-test prohibited signal" }, { RSM_H1_RSR, "Signalling-route-set-test restricted signal" }, { RSM_H1_RCP, "Signalling-route-set-test cluster-prohibited signal (ANSI only)" }, { RSM_H1_RCR, "Signalling-route-set-test cluster-restricted signal (ANSI only)" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string rsm_h1_message_type_acro_values[] = { { RSM_H1_RST, "RST" }, { RSM_H1_RSR, "RSR" }, { RSM_H1_RCP, "RCP" }, { RSM_H1_RCR, "RCR" }, { 0, NULL } }; #define MIM_H1_LIN 0x01 #define MIM_H1_LUN 0x02 #define MIM_H1_LIA 0x03 #define MIM_H1_LUA 0x04 #define MIM_H1_LID 0x05 #define MIM_H1_LFU 0x06 #define MIM_H1_LLT 0x07 /* LLI in ANSI */ #define MIM_H1_LRT 0x08 /* LRI in ANSI */ static const value_string mim_h1_message_type_values[] = { { MIM_H1_LIN, "Link inhibit signal" }, { MIM_H1_LUN, "Link uninhibit signal" }, { MIM_H1_LIA, "Link inhibit ack signal" }, { MIM_H1_LUA, "Link uninhibit ack signal" }, { MIM_H1_LID, "Link inhibit denied signal" }, { MIM_H1_LFU, "Link forced uninhibit signal" }, { MIM_H1_LLT, "Link local inhibit test signal" }, { MIM_H1_LRT, "Link remote inhibit test signal" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string mim_h1_message_type_acro_values[] = { { MIM_H1_LIN, "LIN" }, { MIM_H1_LUN, "LUN" }, { MIM_H1_LIA, "LIA" }, { MIM_H1_LUA, "LUA" }, { MIM_H1_LID, "LID" }, { MIM_H1_LFU, "LFU" }, { MIM_H1_LLT, "LLT (LLI)" }, { MIM_H1_LRT, "LRT (LRI)" }, { 0, NULL } }; #define TRM_H1_TRA 0x01 #define TRM_H1_TRW 0x02 /* ANSI only */ static const value_string trm_h1_message_type_values[] = { { TRM_H1_TRA, "Traffic-restart-allowed signal" }, { TRM_H1_TRW, "Traffic-restart-waiting signal (ANSI only)" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string trm_h1_message_type_acro_values[] = { { TRM_H1_TRA, "TRA" }, { TRM_H1_TRW, "TRW" }, { 0, NULL } }; #define DLM_H1_DLC 0x01 #define DLM_H1_CSS 0x02 #define DLM_H1_CNS 0x03 #define DLM_H1_CNP 0x04 static const value_string dlm_h1_message_type_values[] = { { DLM_H1_DLC, "Signalling-data-link-connection-order signal" }, { DLM_H1_CSS, "Connection-successful signal" }, { DLM_H1_CNS, "Connection-not-successful signal" }, { DLM_H1_CNP, "Connection-not-possible signal" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string dlm_h1_message_type_acro_values[] = { { DLM_H1_DLC, "DLC" }, { DLM_H1_CSS, "CSS" }, { DLM_H1_CNS, "CNS" }, { DLM_H1_CNP, "CNP" }, { 0, NULL } }; #define UFC_H1_UPU 0x01 static const value_string ufc_h1_message_type_values[] = { { UFC_H1_UPU, "User part unavailable signal" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string ufc_h1_message_type_acro_values[] = { { UFC_H1_UPU, "UPU" }, { 0, NULL } }; static const value_string upu_cause_values[] = { { 0x0, "Unknown" }, { 0x1, "Unequipped remote user" }, { 0x2, "Inaccessible remote user" }, { 0, NULL } }; #define TEST_H1_SLTM 0x1 #define TEST_H1_SLTA 0x2 static const value_string test_h1_message_type_values[] = { { TEST_H1_SLTM, "Signalling link test message" }, { TEST_H1_SLTA, "Signalling link test acknowledgement message" }, { 0, NULL } }; /* Same as above but in acronym form (for the Info column) */ static const value_string test_h1_message_type_acro_values[] = { { TEST_H1_SLTM, "SLTM" }, { TEST_H1_SLTA, "SLTA" }, { 0, NULL } }; #define COO_LENGTH 2 #define ANSI_COO_SLC_MASK 0x000f #define ANSI_COO_FSN_MASK 0x07f0 #define ITU_COO_FSN_MASK 0x007f #define ANSI_XCO_LENGTH 4 #define ANSI_XCO_SLC_MASK 0x0000000f #define ANSI_XCO_FSN_MASK 0x0ffffff0 #define ITU_XCO_LENGTH 3 #define ANSI_CBD_LENGTH 2 #define ANSI_CBD_SLC_MASK 0x000f #define ANSI_CBD_CBC_MASK 0x0ff0 #define ITU_CBD_LENGTH 1 #define ANSI_ECO_LENGTH 1 #define ANSI_ECO_SLC_MASK 0x0f #define ANSI_TFC_STATUS_LENGTH 1 #define ANSI_TFC_STATUS_OFFSET ANSI_PC_LENGTH #define ANSI_TFC_STATUS_MASK 0x03 #define ITU_TFC_STATUS_LENGTH ITU_PC_LENGTH #define ITU_TFC_STATUS_MASK 0xc000 #define ANSI_MIM_LENGTH 1 #define ANSI_MIM_SLC_MASK 0x0f #define ANSI_DLC_LENGTH 3 #define ANSI_DLC_SLC_MASK 0x0000f #define ANSI_DLC_LINK_MASK 0x3fff0 #define ITU_DLC_LENGTH 2 #define ITU_DLC_LINK_MASK 0x0fff #define ANSI_UPU_USER_OFFSET ANSI_PC_LENGTH #define UPU_USER_LENGTH 1 #define UPU_USER_MASK 0x0f #define UPU_CAUSE_MASK 0xf0 #define ITU_UPU_USER_OFFSET ITU_PC_LENGTH #define TEST_LENGTH 1 #define TEST_LENGTH_MASK 0xf0 #define TEST_LENGTH_SHIFT 4 #define TEST_PATTERN_OFFSET TEST_LENGTH #define ANSI_TEST_SLC_MASK 0x000f /* This list is slightly different from that in packet-mtp3.c */ static const value_string service_indicator_code_vals[] = { { 0x0, "Spare" }, { 0x1, "Spare"}, { 0x2, "Spare" }, { 0x3, "SCCP" }, { 0x4, "TUP" }, { 0x5, "ISUP" }, { 0x6, "DUP (call and circuit related messages)" }, { 0x7, "DUP (facility registration and cancellation message)" }, { 0x8, "MTP testing user part" }, { 0x9, "Spare" }, { 0xa, "Spare" }, { 0xb, "Spare" }, { 0xc, "Spare" }, { 0xd, "Spare" }, { 0xe, "Spare" }, { 0xf, "Spare" }, { 0, NULL } }; /* Initialize the protocol and registered fields */ static int proto_mtp3mg = -1; static int hf_mtp3mg_h0 = -1; static int hf_mtp3mg_chm_h1 = -1; static int hf_mtp3mg_ecm_h1 = -1; static int hf_mtp3mg_fcm_h1 = -1; static int hf_mtp3mg_tfm_h1 = -1; static int hf_mtp3mg_rsm_h1 = -1; static int hf_mtp3mg_mim_h1 = -1; static int hf_mtp3mg_trm_h1 = -1; static int hf_mtp3mg_dlm_h1 = -1; static int hf_mtp3mg_ufc_h1 = -1; static int hf_mtp3mg_coo_ansi_slc = -1; static int hf_mtp3mg_coo_ansi_fsn = -1; static int hf_mtp3mg_coo_itu_fsn = -1; static int hf_mtp3mg_xco_ansi_slc = -1; static int hf_mtp3mg_xco_ansi_fsn = -1; static int hf_mtp3mg_xco_itu_fsn = -1; static int hf_mtp3mg_cbd_ansi_slc = -1; static int hf_mtp3mg_cbd_ansi_cbc = -1; static int hf_mtp3mg_cbd_itu_cbc = -1; static int hf_mtp3mg_eco_ansi_slc = -1; static int hf_mtp3mg_tfc_ansi_apc = -1; static int hf_mtp3mg_tfc_apc_member = -1; static int hf_mtp3mg_tfc_apc_cluster = -1; static int hf_mtp3mg_tfc_apc_network = -1; static int hf_mtp3mg_tfc_ansi_status = -1; static int hf_mtp3mg_tfc_itu_apc = -1; static int hf_mtp3mg_tfc_itu_status = -1; static int hf_mtp3mg_tfc_chinese_apc = -1; static int hf_mtp3mg_tfm_ansi_apc = -1; static int hf_mtp3mg_tfm_apc_member = -1; static int hf_mtp3mg_tfm_apc_cluster = -1; static int hf_mtp3mg_tfm_apc_network = -1; static int hf_mtp3mg_tfm_itu_apc = -1; static int hf_mtp3mg_tfm_chinese_apc = -1; static int hf_mtp3mg_rsm_ansi_apc = -1; static int hf_mtp3mg_rsm_apc_member = -1; static int hf_mtp3mg_rsm_apc_cluster = -1; static int hf_mtp3mg_rsm_apc_network = -1; static int hf_mtp3mg_rsm_itu_apc = -1; static int hf_mtp3mg_rsm_chinese_apc = -1; static int hf_mtp3mg_mim_ansi_slc = -1; static int hf_mtp3mg_dlc_ansi_slc = -1; static int hf_mtp3mg_dlc_ansi_link = -1; static int hf_mtp3mg_dlc_itu_link = -1; static int hf_mtp3mg_upu_ansi_apc = -1; static int hf_mtp3mg_upu_apc_member = -1; static int hf_mtp3mg_upu_apc_cluster = -1; static int hf_mtp3mg_upu_apc_network = -1; static int hf_mtp3mg_upu_itu_apc = -1; static int hf_mtp3mg_upu_chinese_apc = -1; static int hf_mtp3mg_upu_user = -1; static int hf_mtp3mg_upu_cause = -1; static int hf_mtp3test_h0 = -1; static int hf_mtp3mg_test_h1 = -1; static int hf_mtp3mg_test_ansi_slc = -1; static int hf_mtp3mg_test_length = -1; /* Initialize the subtree pointers */ static gint ett_mtp3mg = -1; static gint ett_mtp3mg_fcm_apc = -1; static gint ett_mtp3mg_tfm_apc = -1; static gint ett_mtp3mg_rsm_apc = -1; static gint ett_mtp3mg_upu_apc = -1; static void dissect_mtp3mg_unknown_message(tvbuff_t *tvb, proto_tree *tree) { guint8 message_length; message_length = tvb_length_remaining(tvb, 0); proto_tree_add_text(tree, tvb, 0, message_length, "Unknown message (%u byte%s)", message_length, plurality(message_length, "", "s")); } static void dissect_mtp3mg_chm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, chm_h1_message_type_acro_values, "Unknown")); switch (h1) { case CHM_H1_COO: case CHM_H1_COA: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_coo_ansi_slc, tvb, 0, COO_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_coo_ansi_fsn, tvb, 0, COO_LENGTH, TRUE); } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ { proto_tree_add_item(tree, hf_mtp3mg_coo_itu_fsn, tvb, 0, COO_LENGTH, TRUE); } break; case CHM_H1_XCO: case CHM_H1_XCA: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_xco_ansi_slc, tvb, 0, ANSI_XCO_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_xco_ansi_fsn, tvb, 0, ANSI_XCO_LENGTH, TRUE); } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ { proto_tree_add_item(tree, hf_mtp3mg_xco_itu_fsn, tvb, 0, ITU_XCO_LENGTH, TRUE); } break; case CHM_H1_CBD: case CHM_H1_CBA: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_cbd_ansi_slc, tvb, 0, ANSI_CBD_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_cbd_ansi_cbc, tvb, 0, ANSI_CBD_LENGTH, TRUE); } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ { proto_tree_add_item(tree, hf_mtp3mg_cbd_itu_cbc, tvb, 0, ITU_CBD_LENGTH, TRUE); } break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_ecm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, ecm_h1_message_type_acro_values, "Unknown")); switch (h1) { case ECM_H1_ECO: case ECM_H1_ECA: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_eco_ansi_slc, tvb, 0, ANSI_ECO_LENGTH, TRUE); } /* else: nothing to dissect */ break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_3byte_pc(tvbuff_t *tvb, proto_tree *tree, gint *ett_pc, int *hf_pc, int *hf_pc_member, int *hf_pc_cluster, int *hf_pc_network) { guint32 apc; proto_item *apc_item; proto_tree *apc_tree; char pc[ANSI_PC_STRING_LENGTH]; apc = tvb_get_ntoh24(tvb, 0); snprintf(pc, sizeof(pc), "%d-%d-%d", (apc & ANSI_NETWORK_MASK), ((apc & ANSI_CLUSTER_MASK) >> 8), ((apc & ANSI_MEMBER_MASK) >> 16)); apc_item = proto_tree_add_string_format(tree, *hf_pc, tvb, 0, ANSI_PC_LENGTH, pc, "Affected PC (%s)", pc); apc_tree = proto_item_add_subtree(apc_item, *ett_pc); proto_tree_add_uint(apc_tree, *hf_pc_member, tvb, ANSI_MEMBER_OFFSET, ANSI_NCM_LENGTH, apc); proto_tree_add_uint(apc_tree, *hf_pc_cluster, tvb, ANSI_CLUSTER_OFFSET, ANSI_NCM_LENGTH, apc); proto_tree_add_uint(apc_tree, *hf_pc_network, tvb, ANSI_NETWORK_OFFSET, ANSI_NCM_LENGTH, apc); } static void dissect_mtp3mg_fcm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, fcm_h1_message_type_acro_values, "Unknown")); switch (h1) { case FCM_H1_RCT: /* nothing to dissect */ break; case FCM_H1_TFC: if (mtp3_standard == ITU_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_tfc_itu_apc, tvb, 0, ITU_PC_LENGTH, TRUE); /* Congestion level is a national option */ proto_tree_add_item(tree, hf_mtp3mg_tfc_itu_status, tvb, 0, ITU_TFC_STATUS_LENGTH, TRUE); } else /* ANSI_STANDARD and CHINESE_ITU_STANDARD */ { int *hf_apc_string; if (mtp3_standard == ANSI_STANDARD) { hf_apc_string = &hf_mtp3mg_tfc_ansi_apc; } else /* CHINESE_ITU_STANDARD */ { hf_apc_string = &hf_mtp3mg_tfc_chinese_apc; } dissect_mtp3mg_3byte_pc(tvb, tree, &ett_mtp3mg_fcm_apc, hf_apc_string, &hf_mtp3mg_tfc_apc_member, &hf_mtp3mg_tfc_apc_cluster, &hf_mtp3mg_tfc_apc_network); proto_tree_add_item(tree, hf_mtp3mg_tfc_ansi_status, tvb, ANSI_TFC_STATUS_OFFSET, ANSI_TFC_STATUS_LENGTH, TRUE); } break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_tfm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, tfm_h1_message_type_acro_values, "Unknown")); switch (h1) { case TFM_H1_TFP: case TFM_H1_TCP: case TFM_H1_TFR: case TFM_H1_TCR: case TFM_H1_TFA: case TFM_H1_TCA: if (mtp3_standard == ANSI_STANDARD) { dissect_mtp3mg_3byte_pc(tvb, tree, &ett_mtp3mg_tfm_apc, &hf_mtp3mg_tfm_ansi_apc, &hf_mtp3mg_tfm_apc_member, &hf_mtp3mg_tfm_apc_cluster, &hf_mtp3mg_tfm_apc_network); } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ { if (h1 == TFM_H1_TCP || h1 == TFM_H1_TCR || h1 == TFM_H1_TCA) dissect_mtp3mg_unknown_message(tvb, tree); else if (mtp3_standard == ITU_STANDARD) proto_tree_add_item(tree, hf_mtp3mg_tfm_itu_apc, tvb, 0, ITU_PC_LENGTH, TRUE); else /* CHINESE_ITU_STANDARD */ dissect_mtp3mg_3byte_pc(tvb, tree, &ett_mtp3mg_tfm_apc, &hf_mtp3mg_tfm_chinese_apc, &hf_mtp3mg_tfm_apc_member, &hf_mtp3mg_tfm_apc_cluster, &hf_mtp3mg_tfm_apc_network); } break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_rsm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, rsm_h1_message_type_acro_values, "Unknown")); switch (h1) { case RSM_H1_RST: case RSM_H1_RSR: case RSM_H1_RCP: case RSM_H1_RCR: if (mtp3_standard == ANSI_STANDARD) { dissect_mtp3mg_3byte_pc(tvb, tree, &ett_mtp3mg_rsm_apc, &hf_mtp3mg_rsm_ansi_apc, &hf_mtp3mg_rsm_apc_member, &hf_mtp3mg_rsm_apc_cluster, &hf_mtp3mg_rsm_apc_network); } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ { if (h1 == RSM_H1_RST || h1 == RSM_H1_RSR) { if (mtp3_standard == ITU_STANDARD) proto_tree_add_item(tree, hf_mtp3mg_rsm_itu_apc, tvb, 0, ITU_PC_LENGTH, TRUE); else /* CHINESE_ITU_STANDARD */ dissect_mtp3mg_3byte_pc(tvb, tree, &ett_mtp3mg_rsm_apc, &hf_mtp3mg_rsm_chinese_apc, &hf_mtp3mg_rsm_apc_member, &hf_mtp3mg_rsm_apc_cluster, &hf_mtp3mg_rsm_apc_network); } else dissect_mtp3mg_unknown_message(tvb, tree); } break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_mim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, mim_h1_message_type_acro_values, "Unknown")); switch (h1) { case MIM_H1_LIN: case MIM_H1_LUN: case MIM_H1_LIA: case MIM_H1_LUA: case MIM_H1_LID: case MIM_H1_LFU: case MIM_H1_LLT: case MIM_H1_LRT: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_mim_ansi_slc, tvb, 0, ANSI_MIM_LENGTH, TRUE); } /* else: nothing to dissect */ break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_trm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, trm_h1_message_type_acro_values, "Unknown")); switch (h1) { case TRM_H1_TRA: /* nothing to dissect */ break; case TRM_H1_TRW: if (mtp3_standard != ANSI_STANDARD) dissect_mtp3mg_unknown_message(tvb, tree); /* else: nothing to dissect */ break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_dlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, dlm_h1_message_type_acro_values, "Unknown")); switch (h1) { case DLM_H1_DLC: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_dlc_ansi_slc, tvb, 0, ANSI_DLC_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_dlc_ansi_link, tvb, 0, ANSI_DLC_LENGTH, TRUE); } else /* ITU_STANDARD and CHINESE_ITU_STANDARD */ { proto_tree_add_item(tree, hf_mtp3mg_dlc_itu_link, tvb, 0, ITU_DLC_LENGTH, TRUE); } break; case DLM_H1_CSS: case DLM_H1_CNS: case DLM_H1_CNP: /* nothing to dissect */ break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_ufc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, ufc_h1_message_type_acro_values, "Unknown")); switch (h1) { case UFC_H1_UPU: if (mtp3_standard == ANSI_STANDARD || mtp3_standard == CHINESE_ITU_STANDARD) { int *hf_apc; if (mtp3_standard == ANSI_STANDARD) hf_apc = &hf_mtp3mg_upu_ansi_apc; else /* CHINESE_ITU_STANDARD */ hf_apc = &hf_mtp3mg_upu_chinese_apc; dissect_mtp3mg_3byte_pc(tvb, tree, &ett_mtp3mg_upu_apc, hf_apc, &hf_mtp3mg_rsm_apc_member, &hf_mtp3mg_rsm_apc_cluster, &hf_mtp3mg_rsm_apc_network); proto_tree_add_item(tree, hf_mtp3mg_upu_user, tvb, ANSI_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_upu_cause, tvb, ANSI_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE); } else /* ITU_STANDARD */ { proto_tree_add_item(tree, hf_mtp3mg_upu_itu_apc, tvb, 0, ITU_PC_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_upu_user, tvb, ITU_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE); proto_tree_add_item(tree, hf_mtp3mg_upu_cause, tvb, ITU_UPU_USER_OFFSET, UPU_USER_LENGTH, TRUE); } break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg_test(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 h1) { guint8 length; if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(h1, test_h1_message_type_acro_values, "Unknown")); switch (h1) { case TEST_H1_SLTM: case TEST_H1_SLTA: if (mtp3_standard == ANSI_STANDARD) { proto_tree_add_item(tree, hf_mtp3mg_test_ansi_slc, tvb, 0, TEST_LENGTH, TRUE); } proto_tree_add_item(tree, hf_mtp3mg_test_length, tvb, 0, TEST_LENGTH, TRUE); length = tvb_get_guint8(tvb, 0) >> TEST_LENGTH_SHIFT; proto_tree_add_text(tree, tvb, TEST_PATTERN_OFFSET, length, "Test pattern (%u byte%s)", length, plurality(length, "", "s")); break; default: dissect_mtp3mg_unknown_message(tvb, tree); } } static void dissect_mtp3mg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 h0, h1; tvbuff_t *payload_tvb; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *mtp3mg_item = NULL; proto_tree *mtp3mg_tree = NULL; /* Make entries in Protocol column on summary display */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) switch(mtp3_standard) { case ITU_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (Int. ITU)"); break; case ANSI_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (ANSI)"); break; case CHINESE_ITU_STANDARD: col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3MG (Chin. ITU)"); break; }; if (tree) { /* create display subtree for the protocol */ mtp3mg_item = proto_tree_add_item(tree, proto_mtp3mg, tvb, 0, -1, TRUE); mtp3mg_tree = proto_item_add_subtree(mtp3mg_item, ett_mtp3mg); } /* * Dissect the message */ if(pinfo->private_data == (void *)MTP3MG_ANSI_TEST_SI || pinfo->private_data == (void *)MTP3MG_ITU_TEST_SI) { /* Test messages */ proto_tree_add_item(mtp3mg_tree, hf_mtp3test_h0, tvb, 0, H0H1_LENGTH, TRUE); /* H1 is added below */ h0 = tvb_get_guint8(tvb, 0) & H0_MASK; h1 = (tvb_get_guint8(tvb, 0) & H1_MASK) >> H1_SHIFT; payload_tvb = tvb_new_subset(tvb, H0H1_LENGTH, -1, -1); switch (h0) { case TEST_H0_SLT: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_test_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_test(payload_tvb, pinfo, mtp3mg_tree, h1); break; default: if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown "); dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree); } /* switch */ } else { /* Real management messages */ proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_h0, tvb, 0, H0H1_LENGTH, TRUE); /* H1 is added below */ h0 = tvb_get_guint8(tvb, 0) & H0_MASK; h1 = (tvb_get_guint8(tvb, 0) & H1_MASK) >> H1_SHIFT; payload_tvb = tvb_new_subset(tvb, H0H1_LENGTH, -1, -1); switch (h0) { case H0_CHM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_chm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_chm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_ECM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_ecm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_ecm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_FCM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_fcm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_fcm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_TFM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_tfm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_tfm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_RSM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_rsm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_rsm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_MIM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_mim_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_mim(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_TRM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_trm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_trm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_DLM: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_dlm_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_dlm(payload_tvb, pinfo, mtp3mg_tree, h1); break; case H0_UFC: proto_tree_add_item(mtp3mg_tree, hf_mtp3mg_ufc_h1, tvb, 0, H0H1_LENGTH, TRUE); dissect_mtp3mg_ufc(payload_tvb, pinfo, mtp3mg_tree, h1); break; default: if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown "); dissect_mtp3mg_unknown_message(tvb, mtp3mg_tree); } /* switch */ } /* else */ } void proto_register_mtp3mg(void) { /* Setup list of header fields See Section 1.6.1 for details*/ static hf_register_info hf[] = { { &hf_mtp3mg_h0, { "H0 (Message Group)", "mtp3mg.h0", FT_UINT8, BASE_HEX, VALS(h0_message_type_values), H0_MASK, "Message group identifier", HFILL }}, { &hf_mtp3mg_chm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(chm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_ecm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(ecm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_fcm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(fcm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_tfm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(tfm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_rsm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(rsm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_mim_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(mim_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_trm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(trm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_dlm_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(dlm_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_ufc_h1, { "H1 (Message)", "mtp3mg.h1", FT_UINT8, BASE_HEX, VALS(ufc_h1_message_type_values), H1_MASK, "Message type", HFILL }}, { &hf_mtp3mg_coo_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT8, BASE_DEC, NULL, ANSI_COO_SLC_MASK, "SLC of affected link", HFILL }}, { &hf_mtp3mg_coo_ansi_fsn, { "Forward Sequence Number", "mtp3mg.fsn", FT_UINT8, BASE_DEC, NULL, ANSI_COO_FSN_MASK, "Forward Sequence Number of last accepted message", HFILL }}, { &hf_mtp3mg_coo_itu_fsn, { "Forward Sequence Number", "mtp3mg.fsn", FT_UINT8, BASE_DEC, NULL, ITU_COO_FSN_MASK, "Forward Sequence Number of last accepted message", HFILL }}, { &hf_mtp3mg_xco_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT32, BASE_DEC, NULL, ANSI_XCO_SLC_MASK, "SLC of affected link", HFILL }}, { &hf_mtp3mg_xco_ansi_fsn, { "Forward Sequence Number", "mtp3mg.fsn", FT_UINT32, BASE_DEC, NULL, ANSI_XCO_FSN_MASK, "Forward Sequence Number of last accepted message", HFILL }}, { &hf_mtp3mg_xco_itu_fsn, { "Forward Sequence Number", "mtp3mg.fsn", FT_UINT24, BASE_DEC, NULL, 0x0, "Forward Sequence Number of last accepted message", HFILL }}, { &hf_mtp3mg_cbd_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT16, BASE_DEC, NULL, ANSI_CBD_SLC_MASK, "SLC of affected link", HFILL }}, { &hf_mtp3mg_cbd_ansi_cbc, { "Change Back Code", "mtp3mg.cbc", FT_UINT16, BASE_DEC, NULL, ANSI_CBD_CBC_MASK, "", HFILL }}, { &hf_mtp3mg_cbd_itu_cbc, { "Change Back Code", "mtp3mg.cbc", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_eco_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT8, BASE_DEC, NULL, ANSI_ECO_SLC_MASK, "SLC of affected link", HFILL }}, { &hf_mtp3mg_tfc_ansi_apc, { "Affected Point Code", "mtp3mg.ansi_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_tfc_apc_member, { "Affected Point Code member", "mtp3mg.apc.member", FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, "", HFILL }}, { &hf_mtp3mg_tfc_apc_cluster, { "Affected Point Code cluster", "mtp3mg.apc.cluster", FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, "", HFILL }}, { &hf_mtp3mg_tfc_apc_network, { "Affected Point Code network", "mtp3mg.apc.network", FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, "", HFILL }}, { &hf_mtp3mg_tfc_ansi_status, { "Status", "mtp3mg.status", FT_UINT8, BASE_DEC, NULL, ANSI_TFC_STATUS_MASK, "Congestion status", HFILL }}, { &hf_mtp3mg_tfc_itu_apc, { "Affected Point Code (ITU)", "mtp3mg.apc", FT_UINT8, BASE_DEC, NULL, ITU_PC_MASK, "", HFILL }}, { &hf_mtp3mg_tfc_itu_status, { "Status", "mtp3mg.status", FT_UINT8, BASE_DEC, NULL, ITU_TFC_STATUS_MASK, "Congestion status", HFILL }}, { &hf_mtp3mg_tfc_chinese_apc, { "Affected Point Code", "mtp3mg.chinese_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_tfm_ansi_apc, { "Affected Point Code", "mtp3mg.ansi_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_tfm_apc_member, { "Affected Point Code member", "mtp3mg.apc.member", FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, "", HFILL }}, { &hf_mtp3mg_tfm_apc_cluster, { "Affected Point Code cluster", "mtp3mg.apc.cluster", FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, "", HFILL }}, { &hf_mtp3mg_tfm_apc_network, { "Affected Point Code network", "mtp3mg.apc.network", FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, "", HFILL }}, { &hf_mtp3mg_tfm_itu_apc, { "Affected Point Code (ITU)", "mtp3mg.apc", FT_UINT8, BASE_DEC, NULL, ITU_PC_MASK, "", HFILL }}, { &hf_mtp3mg_tfm_chinese_apc, { "Affected Point Code", "mtp3mg.chinese_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_rsm_ansi_apc, { "Affected Point Code", "mtp3mg.ansi_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_rsm_apc_member, { "Affected Point Code member", "mtp3mg.apc.member", FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, "", HFILL }}, { &hf_mtp3mg_rsm_apc_cluster, { "Affected Point Code cluster", "mtp3mg.apc.cluster", FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, "", HFILL }}, { &hf_mtp3mg_rsm_apc_network, { "Affected Point Code network", "mtp3mg.apc.network", FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, "", HFILL }}, { &hf_mtp3mg_rsm_itu_apc, { "Affected Point Code (ITU)", "mtp3mg.apc", FT_UINT8, BASE_DEC, NULL, ITU_PC_MASK, "", HFILL }}, { &hf_mtp3mg_rsm_chinese_apc, { "Affected Point Code", "mtp3mg.chinese_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_mim_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT8, BASE_DEC, NULL, ANSI_MIM_SLC_MASK, "SLC of affected link", HFILL }}, { &hf_mtp3mg_dlc_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT8, BASE_DEC, NULL, ANSI_DLC_SLC_MASK, "SLC of affected link", HFILL }}, { &hf_mtp3mg_dlc_ansi_link, { "Link", "mtp3mg.link", FT_UINT8, BASE_DEC, NULL, ANSI_DLC_LINK_MASK, "CIC of BIC used to carry data", HFILL }}, { &hf_mtp3mg_dlc_itu_link, { "Link", "mtp3mg.link", FT_UINT8, BASE_DEC, NULL, ITU_DLC_LINK_MASK, "CIC of BIC used to carry data", HFILL }}, { &hf_mtp3mg_upu_ansi_apc, { "Affected Point Code", "mtp3mg.ansi_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_upu_apc_member, { "Affected Point Code member", "mtp3mg.apc.member", FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK, "", HFILL }}, { &hf_mtp3mg_upu_apc_cluster, { "Affected Point Code cluster", "mtp3mg.apc.cluster", FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK, "", HFILL }}, { &hf_mtp3mg_upu_apc_network, { "Affected Point Code network", "mtp3mg.apc.network", FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK, "", HFILL }}, { &hf_mtp3mg_upu_itu_apc, { "Affected Point Code", "mtp3mg.apc", FT_UINT8, BASE_DEC, NULL, ITU_PC_MASK, "", HFILL }}, { &hf_mtp3mg_upu_chinese_apc, { "Affected Point Code", "mtp3mg.chinese_apc", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}, { &hf_mtp3mg_upu_user, { "User", "mtp3mg.user", FT_UINT8, BASE_HEX, VALS(service_indicator_code_vals), UPU_USER_MASK, "Unavailable user part", HFILL }}, { &hf_mtp3mg_upu_cause, { "Cause", "mtp3mg.cause", FT_UINT8, BASE_HEX, VALS(upu_cause_values), UPU_CAUSE_MASK, "Cause of user unavailability", HFILL }}, { &hf_mtp3test_h0, { "H0 (Message Group)", "mtp3mg.test.h0", FT_UINT8, BASE_HEX, VALS(test_h0_message_type_values), H0_MASK, "Message group identifier", HFILL }}, { &hf_mtp3mg_test_h1, { "H1 (Message)", "mtp3mg.test.h1", FT_UINT8, BASE_HEX, VALS(test_h1_message_type_values), H1_MASK, "SLT message type", HFILL }}, { &hf_mtp3mg_test_length, { "Test length", "mtp3mg.test.length", FT_UINT8, BASE_DEC, NULL, H1_MASK, "Signalling link test pattern length", HFILL }}, { &hf_mtp3mg_test_ansi_slc, { "Signalling Link Code", "mtp3mg.slc", FT_UINT8, BASE_DEC, NULL, ANSI_TEST_SLC_MASK, "SLC of affected link", HFILL }} }; /* Setup protocol subtree array */ static gint *ett[] = { &ett_mtp3mg, &ett_mtp3mg_fcm_apc, &ett_mtp3mg_tfm_apc, &ett_mtp3mg_rsm_apc, &ett_mtp3mg_upu_apc }; /* Register the protocol name and description */ proto_mtp3mg = proto_register_protocol("Message Transfer Part Level 3 Management", "MTP3MG", "mtp3mg"); register_dissector("mtp3mg", dissect_mtp3mg, proto_mtp3mg); /* Required calls to register the header fields and subtrees used */ proto_register_field_array(proto_mtp3mg, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); } void proto_reg_handoff_mtp3mg(void) { dissector_handle_t mtp3mg_handle; mtp3mg_handle = create_dissector_handle(dissect_mtp3mg, proto_mtp3mg); dissector_add("mtp3.service_indicator", MTP3MG_SI, mtp3mg_handle); /* SI 1 is unused in ANSI and SI 2 is unused in ITU, so it's okay for us * to grab both (regardless of mtp3.standard setting) here. */ dissector_add("mtp3.service_indicator", MTP3MG_ITU_TEST_SI, mtp3mg_handle); dissector_add("mtp3.service_indicator", MTP3MG_ANSI_TEST_SI, mtp3mg_handle); }