2018-09-08 08:13:56 +00:00
|
|
|
/* packet-gsm_cbsp.c
|
|
|
|
* Dissector for GSM / 3GPP TS 48.049 Cell Broadcast Service Protocol (CBSP)
|
|
|
|
*
|
|
|
|
* (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/conversation.h>
|
|
|
|
#include <epan/asn1.h>
|
|
|
|
|
|
|
|
#include "packet-e164.h"
|
|
|
|
#include "packet-e212.h"
|
|
|
|
#include "packet-gsm_map.h"
|
|
|
|
#include "packet-cell_broadcast.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 */
|
2019-07-11 10:23:07 +00:00
|
|
|
guint8 fixed_len; /*!< length in case of TLV_TYPE_FIXED */
|
2018-09-08 08:13:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*! 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,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 8.2.9 Number of Brodacast Info */
|
|
|
|
enum cbsp_num_bcast_info {
|
|
|
|
CBSP_NUM_BCAST_INFO_VALID = 0x0,
|
|
|
|
CBSP_NUM_BCAST_INFO_OVERFLOW = 0x1,
|
|
|
|
CBSP_NUM_BCAST_INFO_UNKNOWN = 0x2,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string cbsp_num_bcast_info_vals[] = {
|
|
|
|
{ CBSP_NUM_BCAST_INFO_VALID, "Number of Broadcasts Complete is Valid" },
|
|
|
|
{ CBSP_NUM_BCAST_INFO_OVERFLOW, "Number of Broadcasts Complete has Overflown" },
|
|
|
|
{ CBSP_NUM_BCAST_INFO_UNKNOWN, "Number of Broadcasts Complete is undefined" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string cbsp_num_bcast_shortinfo_vals[] = {
|
|
|
|
{ CBSP_NUM_BCAST_INFO_VALID, "Valid" },
|
|
|
|
{ CBSP_NUM_BCAST_INFO_OVERFLOW, "Overflow" },
|
|
|
|
{ CBSP_NUM_BCAST_INFO_UNKNOWN, "Unknown" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 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_cell_id_disc_vals[] = {
|
|
|
|
{ CBSP_CIDD_WHOLE_CGI, "CGI" },
|
|
|
|
{ CBSP_CIDD_LAC_CI, "LAC+CI" },
|
|
|
|
{ CBSP_CIDD_CI, "CI" },
|
|
|
|
{ CBSP_CIDD_LAI, "LAI" },
|
|
|
|
{ CBSP_CIDD_LAC, "LAC" },
|
|
|
|
{ CBSP_CIDD_ALL_IN_BSC, "BSS" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
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,"Number 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, "RESTART" },
|
|
|
|
{ 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_FIXED, 83 },
|
|
|
|
[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_cb_msg_page = -1;
|
|
|
|
static int hf_cbsp_cbs_page_content = -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 int hf_cbsp_user_info_length = -1;
|
|
|
|
static int hf_cbsp_cell_id_disc = -1;
|
|
|
|
static int hf_cbsp_cell_load1 = -1;
|
|
|
|
static int hf_cbsp_cell_load2 = -1;
|
|
|
|
static int hf_cbsp_num_bcast_compl = -1;
|
|
|
|
static int hf_cbsp_num_bcast_info = -1;
|
|
|
|
static int hf_cbsp_lac = -1;
|
|
|
|
static int hf_cbsp_ci = -1;
|
|
|
|
|
|
|
|
static gint ett_cbsp = -1;
|
|
|
|
static gint ett_cbsp_ie = -1;
|
|
|
|
static gint ett_cbsp_cbs_data_coding = -1;
|
|
|
|
static gint ett_cbsp_cbs_page_content = -1;
|
|
|
|
static gint ett_cbsp_cell_list = -1;
|
|
|
|
static gint ett_cbsp_fail_list = -1;
|
|
|
|
static gint ett_cbsp_load_list = -1;
|
|
|
|
static gint ett_cbsp_num_bcast_compl_list = -1;
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_cbsp_content_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, gint len, proto_tree *tree,
|
|
|
|
guint8 sms_encoding, proto_item *ti)
|
|
|
|
{
|
|
|
|
proto_item *cbs_page_item;
|
|
|
|
tvbuff_t *next_tvb, *unpacked_tvb;
|
|
|
|
const guint8 *pstr;
|
|
|
|
|
|
|
|
proto_tree_add_item(tree, hf_cbsp_user_info_length, tvb, offset, 1, ENC_NA);
|
|
|
|
cbs_page_item = proto_tree_add_item(tree, hf_cbsp_cb_msg_page, tvb, offset+1, len-1, ENC_NA);
|
|
|
|
next_tvb = tvb_new_subset_length(tvb, offset+1, len-1);
|
|
|
|
|
|
|
|
unpacked_tvb = dissect_cbs_data(sms_encoding, next_tvb, tree, pinfo, 0);
|
|
|
|
if (tree) {
|
|
|
|
guint captured_len = tvb_captured_length(unpacked_tvb);
|
|
|
|
proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_cbsp_cbs_page_content);
|
|
|
|
proto_tree_add_item_ret_string(cbs_page_subtree, hf_cbsp_cbs_page_content, unpacked_tvb,
|
|
|
|
0, captured_len, ENC_UTF_8|ENC_NA, wmem_packet_scope(),
|
|
|
|
&pstr);
|
|
|
|
proto_item_append_text(ti, ": '%s'", pstr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Section 8.2.6 Cell List */
|
|
|
|
static gint
|
|
|
|
dissect_cell_id_elem(guint8 discr, tvbuff_t *tvb, packet_info *pinfo, guint offset, gint len _U_,
|
|
|
|
proto_tree *tree, proto_item *ti)
|
|
|
|
{
|
|
|
|
guint base_offs = offset;
|
|
|
|
gchar *mcc_mnc;
|
|
|
|
guint32 lac, ci;
|
|
|
|
|
|
|
|
switch (discr) {
|
|
|
|
case CBSP_CIDD_WHOLE_CGI:
|
|
|
|
mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, TRUE);
|
|
|
|
offset += 3;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
|
|
|
|
offset += 2;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci);
|
|
|
|
offset += 2;
|
|
|
|
proto_item_append_text(ti, ": %s, LAC 0x%04x, CI 0x%04x", mcc_mnc, lac, ci);
|
|
|
|
break;
|
|
|
|
case CBSP_CIDD_LAC_CI:
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
|
|
|
|
offset += 2;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci);
|
|
|
|
offset += 2;
|
|
|
|
proto_item_append_text(ti, ": LAC 0%04x, CI 0x%04x", lac, ci);
|
|
|
|
break;
|
|
|
|
case CBSP_CIDD_CI:
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_ci, tvb, offset, 2, ENC_NA, &ci);
|
|
|
|
offset += 2;
|
|
|
|
proto_item_append_text(ti, ": CI 0x%04x", ci);
|
|
|
|
break;
|
|
|
|
case CBSP_CIDD_LAI:
|
|
|
|
mcc_mnc = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, offset, E212_NONE, TRUE);
|
|
|
|
offset += 3;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
|
|
|
|
offset += 2;
|
|
|
|
proto_item_append_text(ti, ": %s, LAC 0x%04x", mcc_mnc, lac);
|
|
|
|
break;
|
|
|
|
case CBSP_CIDD_LAC:
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_lac, tvb, offset, 2, ENC_NA, &lac);
|
|
|
|
offset += 2;
|
|
|
|
proto_item_append_text(ti, ": LAC 0x%04x", lac);
|
|
|
|
break;
|
|
|
|
case CBSP_CIDD_ALL_IN_BSC:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset - base_offs;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return the length of a single list element of the given discriminator/type */
|
|
|
|
static gint cell_id_len(guint8 discr)
|
|
|
|
{
|
|
|
|
switch (discr) {
|
|
|
|
case CBSP_CIDD_WHOLE_CGI:
|
|
|
|
return 7;
|
|
|
|
case CBSP_CIDD_LAC_CI:
|
|
|
|
return 4;
|
|
|
|
case CBSP_CIDD_CI:
|
|
|
|
return 2;
|
|
|
|
case CBSP_CIDD_LAI:
|
|
|
|
return 5;
|
|
|
|
case CBSP_CIDD_LAC:
|
|
|
|
return 2;
|
|
|
|
case CBSP_CIDD_ALL_IN_BSC:
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_cell_id_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree,
|
|
|
|
proto_item *parent_ti)
|
|
|
|
{
|
|
|
|
guint base_offs = offset;
|
|
|
|
guint32 discr;
|
|
|
|
guint count = 0;
|
|
|
|
|
|
|
|
/* list-global discriminator */
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
|
|
|
|
discr &= 0x0f;
|
|
|
|
offset++;
|
|
|
|
|
|
|
|
/* iterate over list items */
|
|
|
|
while (offset - base_offs < len) {
|
|
|
|
proto_tree *elem_tree;
|
|
|
|
proto_item *ti;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
guint remain_len = len - (offset - base_offs);
|
|
|
|
elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr),
|
|
|
|
ett_cbsp_cell_list, &ti,
|
|
|
|
"Cell List Item");
|
|
|
|
rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
|
|
|
|
if (rc <= 0)
|
|
|
|
break;
|
|
|
|
offset += rc;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
proto_item_append_text(parent_ti, " (%s): %u items",
|
|
|
|
val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_rr_load_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree,
|
|
|
|
proto_item *parent_ti)
|
|
|
|
{
|
|
|
|
guint base_offs = offset;
|
|
|
|
guint32 discr;
|
|
|
|
guint count = 0;
|
|
|
|
|
|
|
|
/* list-global discriminator */
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
|
|
|
|
discr &= 0x0f;
|
|
|
|
offset++;
|
|
|
|
|
|
|
|
/* iterate over list items */
|
|
|
|
while (offset - base_offs < len) {
|
|
|
|
proto_tree *elem_tree;
|
|
|
|
guint32 load1, load2;
|
|
|
|
proto_item *ti;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
guint remain_len = len - (offset - base_offs);
|
|
|
|
elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2,
|
|
|
|
ett_cbsp_load_list, &ti,
|
|
|
|
"RR Load List Item");
|
|
|
|
rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
|
|
|
|
if (rc <= 0)
|
|
|
|
break;
|
|
|
|
offset += rc;
|
|
|
|
|
|
|
|
proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load1, tvb, offset++, 1,
|
|
|
|
ENC_NA, &load1);
|
|
|
|
proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cell_load2, tvb, offset++, 1,
|
|
|
|
ENC_NA, &load2);
|
|
|
|
proto_item_append_text(ti, ": L1=%u%%, L2=%u%%", load1, load2);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
proto_item_append_text(parent_ti, " (%s): %u items",
|
|
|
|
val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_failure_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree,
|
|
|
|
proto_item *parent_ti)
|
|
|
|
{
|
|
|
|
guint base_offs = offset;
|
|
|
|
guint count = 0;
|
|
|
|
|
|
|
|
/* iterate over list items, each with its own discriminator */
|
|
|
|
while (offset - base_offs < len) {
|
|
|
|
proto_tree *elem_tree;
|
|
|
|
proto_item *ti;
|
|
|
|
guint remain_len, cause;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
guint8 discr = tvb_get_guint8(tvb, offset) & 0x0f;
|
|
|
|
elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+2,
|
|
|
|
ett_cbsp_fail_list, &ti,
|
|
|
|
"Failure List Item");
|
|
|
|
proto_tree_add_item(elem_tree, hf_cbsp_cell_id_disc, tvb, offset++, 1, ENC_NA);
|
|
|
|
remain_len = len - (offset - base_offs);
|
|
|
|
rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
|
|
|
|
if (rc <= 0)
|
|
|
|
break;
|
|
|
|
offset += rc;
|
|
|
|
|
|
|
|
proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_cause, tvb, offset++, 1, ENC_NA, &cause);
|
|
|
|
proto_item_append_text(ti, ": Cause %s",
|
|
|
|
val_to_str_const(cause, cbsp_cause_vals, "Undefined"));
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
proto_item_append_text(parent_ti, ": %u items", count);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_bc_compl_list_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree,
|
|
|
|
proto_item *parent_ti)
|
|
|
|
{
|
|
|
|
guint base_offs = offset;
|
|
|
|
guint32 discr;
|
|
|
|
guint count = 0;
|
|
|
|
|
|
|
|
/* list-global discriminator */
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_cbsp_cell_id_disc, tvb, offset, 1, ENC_NA, &discr);
|
|
|
|
discr &= 0x0f;
|
|
|
|
offset++;
|
|
|
|
|
|
|
|
/* iterate over list items */
|
|
|
|
while (offset - base_offs < len) {
|
|
|
|
proto_tree *elem_tree;
|
|
|
|
proto_item *ti;
|
|
|
|
guint32 num_bc, num_bi;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
guint remain_len = len - (offset - base_offs);
|
|
|
|
elem_tree = proto_tree_add_subtree(tree, tvb, offset, cell_id_len(discr)+3,
|
|
|
|
ett_cbsp_num_bcast_compl_list, &ti,
|
|
|
|
"Number of Broadcasts completed");
|
|
|
|
rc = dissect_cell_id_elem(discr, tvb, pinfo, offset, remain_len, elem_tree, ti);
|
|
|
|
if (rc <= 0)
|
|
|
|
break;
|
|
|
|
offset += rc;
|
|
|
|
|
|
|
|
proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_compl, tvb, offset, 2, ENC_NA,
|
|
|
|
&num_bc);
|
|
|
|
offset += 2;
|
|
|
|
proto_tree_add_item_ret_uint(elem_tree, hf_cbsp_num_bcast_info, tvb, offset++, 1, ENC_NA,
|
|
|
|
&num_bi);
|
|
|
|
proto_item_append_text(ti, ": NumBC=%u (%s)", num_bc,
|
|
|
|
val_to_str_const(num_bi, cbsp_num_bcast_shortinfo_vals, ""));
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
proto_item_append_text(parent_ti, " (%s): %u items",
|
|
|
|
val_to_str_const(discr, cbsp_cell_id_disc_vals, ""), count);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
dissect_cbsp_tlvs(tvbuff_t *tvb, int base_offs, int length, packet_info *pinfo, proto_tree *tree)
|
|
|
|
{
|
|
|
|
guint8 sms_encoding = SMS_ENCODING_7BIT;
|
|
|
|
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, *subtree;
|
|
|
|
guint32 tmp_u;
|
|
|
|
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, sms_encoding, ti);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_OLD_SERIAL_NR:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_old_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": 0x%04x", tmp_u);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_NEW_SERIAL_NR:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_new_serial_nr, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": 0x%04x", tmp_u);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_CATEGORY:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_category, tvb, offset, len, ENC_NA,&tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_category_names, ""));
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_REP_PERIOD:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_rep_period, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %u", tmp_u);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_NUM_BCAST_REQ:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_bcast_req, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %u", tmp_u);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_CAUSE:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_cause, tvb, offset, len, ENC_NA, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_cause_vals, ""));
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_DCS:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_dcs, tvb, offset, len, ENC_NA, &tmp_u);
|
|
|
|
subtree = proto_item_add_subtree(att_tree, ett_cbsp_cbs_data_coding);
|
|
|
|
sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, subtree, offset);
|
|
|
|
proto_item_append_text(ti, ": 0x%02x", tmp_u);
|
|
|
|
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_ret_uint(att_tree, hf_cbsp_msg_id, tvb, offset, len, ENC_BIG_ENDIAN, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": 0x%04x", tmp_u);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_EMERG_IND:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_emerg_ind, tvb, offset, len, ENC_NA, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_emerg_ind_vals, ""));
|
|
|
|
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_ret_uint(att_tree, hf_cbsp_channel_ind, tvb, offset, len, ENC_NA, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_chan_ind_vals, ""));
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_NUM_OF_PAGES:
|
|
|
|
proto_tree_add_item_ret_uint(att_tree, hf_cbsp_num_of_pages, tvb, offset, len, ENC_NA, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %u", tmp_u);
|
|
|
|
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_ret_uint(att_tree, hf_cbsp_bcast_msg_type, tvb, offset, len, ENC_NA, &tmp_u);
|
|
|
|
proto_item_append_text(ti, ": %s", val_to_str_const(tmp_u, cbsp_bcast_msg_type_vals, ""));
|
|
|
|
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);
|
|
|
|
proto_item_append_text(ti, ": %u (s)", 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);
|
|
|
|
proto_item_append_text(ti, ": %u (s)", secs);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_CELL_LIST:
|
|
|
|
dissect_cell_id_list_ie(tvb, pinfo, offset, len, att_tree, ti);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_NUM_BCAST_COMPL_LIST:
|
|
|
|
dissect_bc_compl_list_ie(tvb, pinfo, offset, len, att_tree, ti);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_FAILURE_LIST:
|
|
|
|
dissect_failure_list_ie(tvb, pinfo, offset, len, att_tree, ti);
|
|
|
|
break;
|
|
|
|
case CBSP_IEI_RR_LOADING_LIST:
|
|
|
|
dissect_rr_load_list_ie(tvb, pinfo, offset, len, att_tree, ti);
|
|
|
|
break;
|
|
|
|
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_cb_msg_page, { "CBS Message Information Page", "cbsp.cb_msg_page",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_cbs_page_content, { "CBS Page Content", "cbsp.cb_page_content",
|
|
|
|
FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_sched_period, { "Schedule Period", "cbsp.sched_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 } },
|
|
|
|
{ &hf_cbsp_user_info_length, { "User Information Length", "cbsp.user_info_len",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_cell_id_disc, { "Cell ID Discriminator", "cbsp.cell_id_disc",
|
|
|
|
FT_UINT8, BASE_DEC, VALS(cbsp_cell_id_disc_vals), 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_cell_load1, { "Radio Resource Load 1", "cbsp.rr_load1",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_cell_load2, { "Radio Resource Load 2", "cbsp.rr_load2",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_num_bcast_compl, { "Number of Broadcasts Completed", "cbsp.num_bcast_compl",
|
|
|
|
FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_num_bcast_info, { "Number of Broadcasts Info", "cbsp.num_bcast_info",
|
|
|
|
FT_UINT8, BASE_HEX, VALS(cbsp_num_bcast_info_vals), 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_lac, { "Location Area Code (LAC)", "cbsp.lac",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
|
|
|
|
{ &hf_cbsp_ci, { "Cell Identifier (CI)", "cbsp.ci",
|
|
|
|
FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
|
|
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_cbsp,
|
|
|
|
&ett_cbsp_ie,
|
|
|
|
&ett_cbsp_cbs_data_coding,
|
|
|
|
&ett_cbsp_cbs_page_content,
|
|
|
|
&ett_cbsp_cell_list,
|
|
|
|
&ett_cbsp_fail_list,
|
|
|
|
&ett_cbsp_load_list,
|
|
|
|
&ett_cbsp_num_bcast_compl_list,
|
|
|
|
};
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2018-09-08 08:13:56 +00:00
|
|
|
*
|
|
|
|
* 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:
|
|
|
|
*/
|