aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-09-08 10:13:56 +0200
committerHarald Welte <laforge@gnumonks.org>2018-09-20 08:15:54 +0200
commitcb2d33347d928fc7056342fa8c4b2e1793baef47 (patch)
treee31ff761a53b15811bfc84bd168453b2e831ebb2
parent69c692c771a6d982534fc8e794d96e83c26c4815 (diff)
WIP: 3GPP CBSP (Cell Broadcast Service Protocol) dissector
This protocol is spoken between the BSC (Base Station Controller) and the CBC (Cell Broadcast Centre). It runs over TCP Port 48049 and is specified in 3GPP TS 48.049. Change-Id: I183e4741e2db5b9cc4dfe2b89f7920a32af67971
-rw-r--r--docbook/release-notes.asciidoc1
-rw-r--r--epan/dissectors/CMakeLists.txt1
-rw-r--r--epan/dissectors/packet-gsm_cbsp.c610
3 files changed, 612 insertions, 0 deletions
diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc
index f0c0de8..59c3de2 100644
--- a/docbook/release-notes.asciidoc
+++ b/docbook/release-notes.asciidoc
@@ -77,6 +77,7 @@ E1AP (5G) protocol
EVS (3GPP TS 26.445 A.2 EVS RTP)
Exablaze trailers
GLOW Lawo Emberplus Data format
+GSM/3GPP CBSP (Cell Broadcast Service Protocol)
GSM-R protocol (User-to-User Information Element usage)
GSUP (Osmocom Generic Subscriber Update Protocol)
MsgPack protocol
diff --git a/epan/dissectors/CMakeLists.txt b/epan/dissectors/CMakeLists.txt
index 4b42de4..f3fadca 100644
--- a/epan/dissectors/CMakeLists.txt
+++ b/epan/dissectors/CMakeLists.txt
@@ -1070,6 +1070,7 @@ set(DISSECTOR_SRC
${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_bsslap.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_bssmap_le.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_cbch.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_cbsp.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_gsup.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_ipa.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-gsm_osmux.c
diff --git a/epan/dissectors/packet-gsm_cbsp.c b/epan/dissectors/packet-gsm_cbsp.c
new file mode 100644
index 0000000..61b8cce
--- /dev/null
+++ b/epan/dissectors/packet-gsm_cbsp.c
@@ -0,0 +1,610 @@
+/* packet-gsm_cbsp.c
+ * Dissector for GSM / 3GPP TS 48.049 Cell Broadcast Service Protocol (CBSP)
+ *
+ * (C) 2018 by Harald Welte <laforge@gnumonks.org>
+ *
+ * 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/conversation.h>
+
+#include "packet-e164.h"
+#include "packet-e212.h"
+
+/***********************************************************************
+ * TLV related definitions
+ ***********************************************************************/
+
+/*! Entry in a TLV parser array */
+struct tlv_p_entry {
+ guint16 len; /*!< length */
+ const guint8 *val; /*!< pointer to value */
+};
+
+/*! TLV type */
+enum tlv_type {
+ TLV_TYPE_NONE, /*!< no type */
+ TLV_TYPE_FIXED, /*!< fixed-length value-only */
+ TLV_TYPE_TV, /*!< tag-value (8bit) */
+ TLV_TYPE_TLV, /*!< tag-length-value */
+ TLV_TYPE_TL16V, /*!< tag, 16 bit length, value */
+};
+
+/*! Definition of a single IE (Information Element) */
+struct tlv_def {
+ enum tlv_type type; /*!< TLV type */
+ guint8 fixed_len; /*!< length in case of \ref TLV_TYPE_FIXED */
+};
+
+/*! Definition of All 256 IE / TLV */
+struct tlv_definition {
+ struct tlv_def def[256];
+};
+
+
+/***********************************************************************
+ * CBSP Protocol Definitions, see libosmocore/include/gsm/protocol/gsm_48_049.h
+ ***********************************************************************/
+
+#define CBSP_TCP_PORT 48049
+
+/* 8.2.1 Information Element Identifiers */
+enum cbsp_iei {
+ CBSP_IEI_MSG_CONTENT = 0x01,
+ CBSP_IEI_OLD_SERIAL_NR = 0x02,
+ CBSP_IEI_NEW_SERIAL_NR = 0x03,
+ CBSP_IEI_CELL_LIST = 0x04,
+ CBSP_IEI_CATEGORY = 0x05,
+ CBSP_IEI_REP_PERIOD = 0x06,
+ CBSP_IEI_NUM_BCAST_REQ = 0x07,
+ CBSP_IEI_NUM_BCAST_COMPL_LIST = 0x08,
+ CBSP_IEI_FAILURE_LIST = 0x09,
+ CBSP_IEI_RR_LOADING_LIST = 0x0a,
+ CBSP_IEI_CAUSE = 0x0b,
+ CBSP_IEI_DCS = 0x0c,
+ CBSP_IEI_RECOVERY_IND = 0x0d,
+ CBSP_IEI_MSG_ID = 0x0e,
+ CBSP_IEI_EMERG_IND = 0x0f,
+ CBSP_IEI_WARN_TYPE = 0x10,
+ CBSP_IEI_WARN_SEC_INFO = 0x11,
+ CBSP_IEI_CHANNEL_IND = 0x12,
+ CBSP_IEI_NUM_OF_PAGES = 0x13,
+ CBSP_IEI_SCHEDULE_PERIOD = 0x14,
+ CBSP_IEI_NUM_OF_RES_SLOTS = 0x15,
+ CBSP_IEI_BCAST_MSG_TYPE = 0x16,
+ CBSP_IEI_WARNING_PERIOD = 0x17,
+ CBSP_IEI_KEEP_ALIVE_REP_PERIOD = 0x18,
+};
+
+/* 8.2.2 Message Type */
+enum cbsp_msg_type {
+ CBSP_MSGT_WRITE_REPLACE = 0x01,
+ CBSP_MSGT_WRITE_REPLACE_COMPL = 0x02,
+ CBSP_MSGT_WRITE_REPLACE_FAIL = 0x03,
+ CBSP_MSGT_KILL = 0x04,
+ CBSP_MSGT_KILL_COMPL = 0x05,
+ CBSP_MSGT_KILL_FAIL = 0x06,
+ CBSP_MSGT_LOAD_QUERY = 0x07,
+ CBSP_MSGT_LOAD_QUERY_COMPL = 0x08,
+ CBSP_MSGT_LOAD_QUERY_FAIL = 0x09,
+ CBSP_MSGT_MSG_STATUS_QUERY = 0x0a,
+ CBSP_MSGT_MSG_STATUS_QUERY_COMPL= 0x0b,
+ CBSP_MSGT_MSG_STATUS_QUERY_FAIL = 0x0c,
+ CBSP_MSGT_SET_DRX = 0x0d,
+ CBSP_MSGT_SET_DRX_COMPL = 0x0e,
+ CBSP_MSGT_SET_DRX_FAIL = 0x0f,
+ CBSP_MSGT_RESET = 0x10,
+ CBSP_MSGT_RESET_COMPL = 0x11,
+ CBSP_MSGT_RESET_FAIL = 0x12,
+ CBSP_MSGT_RESTART = 0x13,
+ CBSP_MSGT_FAILURE = 0x14,
+ CBSP_MSGT_ERROR_IND = 0x15,
+ CBSP_MSGT_KEEP_ALIVE = 0x16,
+ CBSP_MSGT_KEEP_ALIVE_COMPL = 0x17,
+};
+
+/* 8.2.7 Category */
+enum cbsp_category {
+ CBSP_CATEG_HIGH_PRIO = 0x00,
+ CBSP_CATEG_BACKGROUND = 0x01,
+ CBSP_CATEG_NORMAL = 0x02,
+};
+
+/* Cell ID Discriminator (8.2.11, ...) */
+enum cbsp_cell_id_disc {
+ CBSP_CIDD_WHOLE_CGI = 0x0,
+ CBSP_CIDD_LAC_CI = 0x1,
+ CBSP_CIDD_CI = 0x2,
+ CBSP_CIDD_LAI = 0x4,
+ CBSP_CIDD_LAC = 0x5,
+ CBSP_CIDD_ALL_IN_BSC = 0x6,
+};
+
+/* 8.2.13 Cause */
+enum cbsp_cause {
+ CBSP_CAUSE_PARAM_NOT_RECOGNISED = 0x00,
+ CBSP_CAUSE_PARAM_VAL_INVALID = 0x01,
+ CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED = 0x02,
+ CBSP_CAUSE_CELL_ID_NOT_VALID = 0x03,
+ CBSP_CAUSE_UNRECOGNISED_MSG = 0x04,
+ CBSP_CAUSE_MISSING_MAND_IE = 0x05,
+ CBSP_CAUSE_BSC_CAPACITY_EXCEEDED = 0x06,
+ CBSP_CAUSE_CELL_MEMORY_EXCEEDED = 0x07,
+ CBSP_CAUSE_BSC_MEMORY_EXCEEDED = 0x08,
+ CBSP_CAUSE_CB_NOT_SUPPORTED = 0x09,
+ CBSP_CAUSE_CB_NOT_OPERATIONAL = 0x0a,
+ CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM = 0x0b,
+ CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED = 0x0c,
+ CBSP_CAUSE_MSG_REF_ALREADY_USED = 0x0d,
+ CBSP_CAUSE_UNSPECIFIED_ERROR = 0x0e,
+ CBSP_CAUSE_LAI_OR_LAC_NPT_VALID = 0x0f,
+};
+
+/* 8.2.15 */
+static const value_string cbsp_recov_ind_vals[] = {
+ { 0x0, "CBS/emergency message data available" },
+ { 0x1, "CBS/emergency message data lost" },
+ { 0, NULL }
+};
+
+/* 8.2.17 */
+static const value_string cbsp_emerg_ind_vals[] = {
+ { 0x0, "reserved" },
+ { 0x1, "ETWS information available" },
+ { 0, NULL }
+};
+
+/* 8.2.20 */
+static const value_string cbsp_chan_ind_vals[] = {
+ { 0x0, "basic channel" },
+ { 0x1, "extended channel" },
+ { 0, NULL }
+};
+
+/* 8.2.24 */
+static const value_string cbsp_bcast_msg_type_vals[] = {
+ { 0x0, "CBS message broadcasting" },
+ { 0x1, "emergency message broadcasting" },
+ { 0, NULL }
+};
+
+/* conversion function from 8.2.25 warning period to seconds */
+static int cbsp_warn_period_to_secs(guint8 warn_per)
+{
+ if (warn_per <= 0x0a)
+ return warn_per;
+ else if (warn_per <= 0x14)
+ return 10 + (warn_per-0x0a)*2;
+ else if (warn_per <= 0x26)
+ return 30 + (warn_per-0x14)*5;
+ else if (warn_per <= 0x56)
+ return 120 + (warn_per-0x26)*10;
+ else if (warn_per <= 0xba)
+ return 600 + (warn_per-0x56)*60;
+ else
+ return -1;
+}
+
+static const value_string cbsp_iei_names[] = {
+ { CBSP_IEI_MSG_CONTENT, "Message Content" },
+ { CBSP_IEI_OLD_SERIAL_NR, "Old Serial Number" },
+ { CBSP_IEI_NEW_SERIAL_NR, "New Serial Number" },
+ { CBSP_IEI_CELL_LIST, "Cell List" },
+ { CBSP_IEI_CATEGORY, "Category" },
+ { CBSP_IEI_REP_PERIOD, "Repetition Period" },
+ { CBSP_IEI_NUM_BCAST_REQ, "Number of Broadcasts Requested" },
+ { CBSP_IEI_NUM_BCAST_COMPL_LIST,"Nomber of Broadcasts Completed List" },
+ { CBSP_IEI_FAILURE_LIST, "Failure List" },
+ { CBSP_IEI_RR_LOADING_LIST, "Radio Resource Loading List" },
+ { CBSP_IEI_CAUSE, "Cause" },
+ { CBSP_IEI_DCS, "Data Coding Scheme" },
+ { CBSP_IEI_RECOVERY_IND, "Recovery Indication" },
+ { CBSP_IEI_MSG_ID, "Message Identifier" },
+ { CBSP_IEI_EMERG_IND, "Emergency Indicator" },
+ { CBSP_IEI_WARN_TYPE, "Warning Type" },
+ { CBSP_IEI_WARN_SEC_INFO, "Warning Security Information" },
+ { CBSP_IEI_CHANNEL_IND, "Channel Indicator" },
+ { CBSP_IEI_NUM_OF_PAGES, "Number of Pages" },
+ { CBSP_IEI_SCHEDULE_PERIOD, "Schedule Period" },
+ { CBSP_IEI_NUM_OF_RES_SLOTS, "Number of Reserved Slots" },
+ { CBSP_IEI_BCAST_MSG_TYPE, "Broadcast Message Type" },
+ { CBSP_IEI_WARNING_PERIOD, "Waring Period" },
+ { CBSP_IEI_KEEP_ALIVE_REP_PERIOD, "Keep Alive Repetition Period" },
+ { 0, NULL }
+};
+
+static const value_string cbsp_msg_type_names[] = {
+ { CBSP_MSGT_WRITE_REPLACE, "WRITE-REPLACE" },
+ { CBSP_MSGT_WRITE_REPLACE_COMPL, "WRITE-REPLACE COMPLETE" },
+ { CBSP_MSGT_WRITE_REPLACE_FAIL, "WRITE-REPLACE FAILURE" },
+ { CBSP_MSGT_KILL, "KILL" },
+ { CBSP_MSGT_KILL_COMPL, "KILL COMPLETE" },
+ { CBSP_MSGT_KILL_FAIL, "KILL FAILURE" },
+ { CBSP_MSGT_LOAD_QUERY, "LOAD QUERY" },
+ { CBSP_MSGT_LOAD_QUERY_COMPL, "LOAD QUERY COMPLETE" },
+ { CBSP_MSGT_LOAD_QUERY_FAIL, "LOAD QUERY FAILURE" },
+ { CBSP_MSGT_MSG_STATUS_QUERY, "MESSAGE STATUS QUERY" },
+ { CBSP_MSGT_MSG_STATUS_QUERY_COMPL, "MESSAGE STATUS QUERY COMPLETE" },
+ { CBSP_MSGT_MSG_STATUS_QUERY_FAIL, "MESSAGE STATUS QUERY FAILURE" },
+ { CBSP_MSGT_SET_DRX, "SET-DRX" },
+ { CBSP_MSGT_SET_DRX_COMPL, "SET-DRX COMPLETE" },
+ { CBSP_MSGT_SET_DRX_FAIL, "SET-DRX FAILURE" },
+ { CBSP_MSGT_RESET, "RESET" },
+ { CBSP_MSGT_RESET_COMPL, "RESET COMPLETE" },
+ { CBSP_MSGT_RESET_FAIL, "RESET FAILURE" },
+ { CBSP_MSGT_RESTART, "RESETART" },
+ { CBSP_MSGT_FAILURE, "FAILURE" },
+ { CBSP_MSGT_ERROR_IND, "ERROR INDICATION" },
+ { CBSP_MSGT_KEEP_ALIVE, "KEEP-ALIVE" },
+ { CBSP_MSGT_KEEP_ALIVE_COMPL, "KEEP-ALIVE COMPLETE" },
+ { 0, NULL }
+};
+
+static const value_string cbsp_category_names[] = {
+ { CBSP_CATEG_HIGH_PRIO, "High Priority" },
+ { CBSP_CATEG_BACKGROUND, "Background" },
+ { CBSP_CATEG_NORMAL, "Normal" },
+ { 0, NULL }
+};
+
+/* 8.2.13 */
+static const value_string cbsp_cause_vals[] = {
+ { CBSP_CAUSE_PARAM_NOT_RECOGNISED, "Parameter-not-recognized" },
+ { CBSP_CAUSE_PARAM_VAL_INVALID, "Parameter-value-invalid" },
+ { CBSP_CAUSE_MSG_REF_NOT_IDENTIFIED, "Message-reference-not-identified" },
+ { CBSP_CAUSE_CELL_ID_NOT_VALID, "Cell-identity-not-valid" },
+ { CBSP_CAUSE_UNRECOGNISED_MSG, "Unrecognised-message" },
+ { CBSP_CAUSE_MISSING_MAND_IE, "Missing-mandatory-element" },
+ { CBSP_CAUSE_BSC_CAPACITY_EXCEEDED, "BSC-capacity-exceeded" },
+ { CBSP_CAUSE_CELL_MEMORY_EXCEEDED, "Cell-memory-exceeded" },
+ { CBSP_CAUSE_BSC_MEMORY_EXCEEDED, "BSC-memory-exceeded" },
+ { CBSP_CAUSE_CB_NOT_SUPPORTED, "Cell-broadcast-not-supported" },
+ { CBSP_CAUSE_CB_NOT_OPERATIONAL, "Cell-broadcast-not-operational" },
+ { CBSP_CAUSE_INCOMPATIBLE_DRX_PARAM, "Incompatible-DRX-parameter" },
+ { CBSP_CAUSE_EXT_CHAN_NOT_SUPPORTED, "Extended-channel-not-supported" },
+ { CBSP_CAUSE_MSG_REF_ALREADY_USED, "Message-reference-already-used" },
+ { CBSP_CAUSE_UNSPECIFIED_ERROR, "Unspecified-error" },
+ { CBSP_CAUSE_LAI_OR_LAC_NPT_VALID, "LAI-or-LAC-not-valid" },
+ { 0, NULL }
+};
+
+static const struct tlv_definition cbsp_att_tlvdef = {
+ .def = {
+ [CBSP_IEI_MSG_CONTENT] = { TLV_TYPE_TLV, 0 },
+ [CBSP_IEI_OLD_SERIAL_NR] = { TLV_TYPE_FIXED, 2 },
+ [CBSP_IEI_NEW_SERIAL_NR] = { TLV_TYPE_FIXED, 2 },
+ [CBSP_IEI_CELL_LIST] = { TLV_TYPE_TL16V, 0 },
+ [CBSP_IEI_CATEGORY] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_REP_PERIOD] = { TLV_TYPE_FIXED, 2 },
+ [CBSP_IEI_NUM_BCAST_REQ] = { TLV_TYPE_FIXED, 2 },
+ [CBSP_IEI_NUM_BCAST_COMPL_LIST] = { TLV_TYPE_TL16V, 0 },
+ [CBSP_IEI_FAILURE_LIST] = { TLV_TYPE_TL16V, 0 },
+ [CBSP_IEI_RR_LOADING_LIST] = { TLV_TYPE_TL16V, 0 },
+ [CBSP_IEI_CAUSE] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_DCS] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_RECOVERY_IND] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_MSG_ID] = { TLV_TYPE_FIXED, 2 },
+ [CBSP_IEI_EMERG_IND] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_WARN_TYPE] = { TLV_TYPE_FIXED, 2 },
+ [CBSP_IEI_WARN_SEC_INFO] = { TLV_TYPE_FIXED, 50 },
+ [CBSP_IEI_CHANNEL_IND] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_NUM_OF_PAGES] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_SCHEDULE_PERIOD] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_NUM_OF_RES_SLOTS] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_BCAST_MSG_TYPE] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_WARNING_PERIOD] = { TLV_TYPE_TV, 0 },
+ [CBSP_IEI_KEEP_ALIVE_REP_PERIOD] = { TLV_TYPE_TV, 0 },
+ },
+};
+
+/***********************************************************************
+ * Wireshark Dissector Implementation
+ ***********************************************************************/
+
+void proto_register_cbsp(void);
+void proto_reg_handoff_cbsp(void);
+
+static int proto_cbsp = -1;
+
+static int hf_cbsp_msg_type = -1;
+static int hf_cbsp_msg_len = -1;
+static int hf_cbsp_iei = -1;
+static int hf_cbsp_ie_len = -1;
+static int hf_cbsp_ie_payload = -1;
+
+static int hf_cbsp_old_serial_nr = -1;
+static int hf_cbsp_new_serial_nr = -1;
+static int hf_cbsp_category = -1;
+static int hf_cbsp_rep_period = -1;
+static int hf_cbsp_num_bcast_req = -1;
+static int hf_cbsp_cause = -1;
+static int hf_cbsp_dcs = -1;
+static int hf_cbsp_recovery_ind = -1;
+static int hf_cbsp_msg_id = -1;
+static int hf_cbsp_emerg_ind = -1;
+static int hf_cbsp_warn_type = -1;
+static int hf_cbsp_channel_ind = -1;
+static int hf_cbsp_num_of_pages = -1;
+static int hf_cbsp_sched_period = -1;
+static int hf_cbsp_num_of_res_slots = -1;
+static int hf_cbsp_bcast_msg_type = -1;
+static int hf_cbsp_warning_period = -1;
+static int hf_cbsp_keepalive_period = -1;
+
+static gint ett_cbsp = -1;
+static gint ett_cbsp_ie = -1;
+
+static dissector_handle_t gsm_cbs_handle;
+
+static void
+dissect_cbsp_content_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, gint len, proto_tree *tree)
+{
+ tvbuff_t *next_tvb = tvb_new_subset_length(tvb, offset, len);
+ call_dissector(gsm_cbs_handle, next_tvb, pinfo, tree);
+}
+
+static gint
+dissect_cbsp_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree)
+{
+ int offset = base_offs;
+
+ while (offset - base_offs < length) {
+ guint8 tag; /* Information Element Identifier */
+ unsigned int len; /* Length of payload */
+ unsigned int len_len = 0;/* Length of "length" field (may be 0) */
+ proto_item *ti;
+ proto_tree *att_tree;
+ int secs;
+
+ tag = tvb_get_guint8(tvb, offset);
+ offset++;
+
+ switch (cbsp_att_tlvdef.def[tag].type) {
+ case TLV_TYPE_TV:
+ len = 1;
+ len_len = 0;
+ break;
+ case TLV_TYPE_FIXED:
+ len = cbsp_att_tlvdef.def[tag].fixed_len;
+ len_len = 0;
+ break;
+ case TLV_TYPE_TLV:
+ len = tvb_get_guint8(tvb, offset);
+ break;
+ case TLV_TYPE_TL16V:
+ len = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN);
+ len_len = 2;
+ break;
+ default:
+ return length;
+ }
+
+ att_tree = proto_tree_add_subtree_format(tree, tvb, offset-1, 1+len_len+len,
+ ett_cbsp_ie, &ti, "IE: %s",
+ val_to_str(tag, cbsp_iei_names, "Unknown 0x%02x"));
+ proto_tree_add_item(att_tree, hf_cbsp_iei, tvb, offset-1, 1, ENC_NA);
+ if (len_len)
+ proto_tree_add_uint(att_tree, hf_cbsp_ie_len, tvb, offset, len_len, len);
+
+ offset += len_len;
+
+ switch (tag) {
+ case CBSP_IEI_MSG_CONTENT:
+ dissect_cbsp_content_ie(tvb, pinfo, offset, len, att_tree);
+ break;
+ case CBSP_IEI_OLD_SERIAL_NR:
+ proto_tree_add_item(att_tree, hf_cbsp_old_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN);
+ break;
+ case CBSP_IEI_NEW_SERIAL_NR:
+ proto_tree_add_item(att_tree, hf_cbsp_new_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN);
+ break;
+ case CBSP_IEI_CATEGORY:
+ proto_tree_add_item(att_tree, hf_cbsp_category, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_REP_PERIOD:
+ proto_tree_add_item(att_tree, hf_cbsp_rep_period, tvb, offset, len, ENC_BIG_ENDIAN);
+ break;
+ case CBSP_IEI_NUM_BCAST_REQ:
+ proto_tree_add_item(att_tree, hf_cbsp_num_bcast_req, tvb, offset, len, ENC_BIG_ENDIAN);
+ break;
+ case CBSP_IEI_CAUSE:
+ proto_tree_add_item(att_tree, hf_cbsp_cause, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_DCS:
+ proto_tree_add_item(att_tree, hf_cbsp_dcs, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_RECOVERY_IND:
+ proto_tree_add_item(att_tree, hf_cbsp_recovery_ind, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_MSG_ID:
+ proto_tree_add_item(att_tree, hf_cbsp_msg_id, tvb, offset, len, ENC_BIG_ENDIAN);
+ break;
+ case CBSP_IEI_EMERG_IND:
+ proto_tree_add_item(att_tree, hf_cbsp_emerg_ind, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_WARN_TYPE:
+ proto_tree_add_item(att_tree, hf_cbsp_warn_type, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_CHANNEL_IND:
+ proto_tree_add_item(att_tree, hf_cbsp_channel_ind, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_NUM_OF_PAGES:
+ proto_tree_add_item(att_tree, hf_cbsp_num_of_pages, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_SCHEDULE_PERIOD:
+ proto_tree_add_item(att_tree, hf_cbsp_sched_period, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_NUM_OF_RES_SLOTS:
+ proto_tree_add_item(att_tree, hf_cbsp_num_of_res_slots, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_BCAST_MSG_TYPE:
+ proto_tree_add_item(att_tree, hf_cbsp_bcast_msg_type, tvb, offset, len, ENC_NA);
+ break;
+ case CBSP_IEI_WARNING_PERIOD:
+ secs = cbsp_warn_period_to_secs(tvb_get_guint8(tvb, offset));
+ proto_tree_add_uint(att_tree, hf_cbsp_warning_period, tvb, offset, len, secs);
+ break;
+ case CBSP_IEI_KEEP_ALIVE_REP_PERIOD:
+ secs = cbsp_warn_period_to_secs(tvb_get_guint8(tvb, offset));
+ proto_tree_add_uint(att_tree, hf_cbsp_keepalive_period, tvb, offset, len, secs);
+ break;
+ case CBSP_IEI_CELL_LIST:
+ case CBSP_IEI_NUM_BCAST_COMPL_LIST:
+ case CBSP_IEI_FAILURE_LIST:
+ case CBSP_IEI_RR_LOADING_LIST:
+ /* FIXME: actually implement proper dissection of those above lists */
+ case CBSP_IEI_WARN_SEC_INFO:
+ /* this element is bogus / not used anyway, no need for a dissector */
+ default:
+ /* Unknown/unsupported IE: Print raw payload in addition to IEI + Length printed above */
+ proto_tree_add_item(att_tree, hf_cbsp_ie_payload, tvb, offset, len, ENC_NA);
+ break;
+ }
+
+ offset += len;
+ }
+
+ return offset;
+}
+
+static int
+dissect_cbsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ int len_ind, offset = 0;
+ proto_item *ti;
+ proto_tree *cbsp_tree = NULL;
+ guint8 msg_type;
+ const char *str;
+
+
+ //len = tvb_reported_length(tvb);
+ msg_type = tvb_get_guint8(tvb, offset + 0);
+ len_ind = tvb_get_guint24(tvb, offset + 1, ENC_BIG_ENDIAN);
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "CBSP");
+
+ col_clear(pinfo->cinfo, COL_INFO);
+ str = val_to_str(msg_type, cbsp_msg_type_names, "Unknown CBSP Message Type 0x%02x");
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
+
+ if (tree) {
+ ti = proto_tree_add_protocol_format(tree, proto_cbsp, tvb, 0, len_ind+4, "CBSP %s", str);
+ cbsp_tree = proto_item_add_subtree(ti, ett_cbsp);
+
+ proto_tree_add_item(cbsp_tree, hf_cbsp_msg_type,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+
+ proto_tree_add_item(cbsp_tree, hf_cbsp_msg_len, tvb, offset, 3, ENC_BIG_ENDIAN);
+ offset += 3;
+
+ dissect_cbsp_tlvs(tvb, offset, tvb_reported_length_remaining(tvb, offset), pinfo,
+ cbsp_tree);
+ }
+
+ return tvb_captured_length(tvb);
+}
+
+void
+proto_register_cbsp(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_cbsp_msg_type, { "Message Type", "cbsp.msg_type",
+ FT_UINT8, BASE_DEC, VALS(cbsp_msg_type_names), 0, NULL, HFILL } },
+ { &hf_cbsp_msg_len, { "Message Length", "cbsp.msg_len",
+ FT_UINT24, BASE_DEC, NULL, 0, NULL, HFILL } },
+
+ { &hf_cbsp_iei, { "Information Element Identifier", "cbsp.ie.iei",
+ FT_UINT8, BASE_DEC, VALS(cbsp_iei_names), 0, NULL, HFILL } },
+ { &hf_cbsp_ie_len, { "Information Element Length", "cbsp.ie.len",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_ie_payload, { "Information Element Payload", "cbsp.ie.payload",
+ FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
+
+ { &hf_cbsp_old_serial_nr, { "Old Serial Number", "cbsp.old_serial_nr",
+ FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_new_serial_nr, { "New Serial Number", "cbsp.new_serial_nr",
+ FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_category, { "Category", "cbsp.category",
+ FT_UINT8, BASE_HEX, VALS(cbsp_category_names), 0, NULL, HFILL } },
+ { &hf_cbsp_rep_period, { "Repetition Period (units of 1.883s)", "cbsp.rep_period",
+ FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_num_bcast_req, { "Number of Broadcasts Requested", "cbsp.num_bcast_req",
+ FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_cause, { "Cause", "cbsp.cause",
+ FT_UINT8, BASE_HEX, VALS(cbsp_cause_vals), 0, NULL, HFILL } },
+ { &hf_cbsp_dcs, { "Data Coding Scheme", "cbsp.dcs",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_recovery_ind, { "Recovery Indication", "cbsp.recovery_ind",
+ FT_UINT8, BASE_HEX, VALS(cbsp_recov_ind_vals), 0, NULL, HFILL } },
+ { &hf_cbsp_msg_id, { "Message Identifier", "cbsp.message_id",
+ FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_emerg_ind, { "Emergency Indicator", "cbsp.emergency_ind",
+ FT_UINT8, BASE_HEX, VALS(cbsp_emerg_ind_vals), 0, NULL, HFILL } },
+ { &hf_cbsp_warn_type, { "Warning Type", "cbsp.warn_type",
+ FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_channel_ind, { "Channel Indicator", "cbsp.channel_ind",
+ FT_UINT8, BASE_HEX, VALS(cbsp_chan_ind_vals), 0, NULL, HFILL } },
+ { &hf_cbsp_num_of_pages, { "Number of Pages", "cbsp.num_of_pages",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_sched_period, { "Schedule Period", "cbsp.schedu_period",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_num_of_res_slots, { "Number of Reserved Slots", "cbsp.num_of_res_slots",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_bcast_msg_type, { "Broadcast Message Type", "cbsp.bcast_msg_type",
+ FT_UINT8, BASE_DEC, VALS(cbsp_bcast_msg_type_vals), 0, NULL, HFILL } },
+ { &hf_cbsp_warning_period, { "Warning Period", "cbsp.warning_period",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_cbsp_keepalive_period, { "Keepalive Repetition Period", "cbsp.keepalive_rep_period",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ };
+ static gint *ett[] = {
+ &ett_cbsp,
+ &ett_cbsp_ie,
+ };
+
+ proto_cbsp = proto_register_protocol("3GPP/GSM Cell Broadcast Service Protocol", "cbsp", "cbsp");
+ proto_register_field_array(proto_cbsp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_cbsp(void)
+{
+ dissector_handle_t cbsp_handle;
+ cbsp_handle = create_dissector_handle(dissect_cbsp, proto_cbsp);
+ dissector_add_uint_with_preference("tcp.port", CBSP_TCP_PORT, cbsp_handle);
+ gsm_cbs_handle = find_dissector_add_dependency("gsm_cbs", proto_cbsp);
+}
+
+/*
+ * 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:
+ */