diff options
-rw-r--r-- | asn1/gsm_map/gsm_map.cnf | 4 | ||||
-rw-r--r-- | asn1/gsm_map/packet-gsm_map-template.c | 30 | ||||
-rw-r--r-- | asn1/gsm_map/packet-gsm_map-template.h | 2 | ||||
-rw-r--r-- | asn1/sabp/packet-sabp-template.c | 5 | ||||
-rw-r--r-- | asn1/sabp/sabp.cnf | 36 | ||||
-rw-r--r-- | epan/CMakeLists.txt | 4 | ||||
-rw-r--r-- | epan/dissectors/Makefile.common | 3 | ||||
-rw-r--r-- | epan/dissectors/packet-bmc.c | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-cell_broadcast.c | 570 | ||||
-rw-r--r-- | epan/dissectors/packet-cell_broadcast.h | 59 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_cbch.c | 585 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.c | 32 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_map.h | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-rsl.c | 12 | ||||
-rw-r--r-- | epan/dissectors/packet-sabp.c | 68 |
15 files changed, 1371 insertions, 57 deletions
diff --git a/asn1/gsm_map/gsm_map.cnf b/asn1/gsm_map/gsm_map.cnf index c8e3629cdb..dbff6fe572 100644 --- a/asn1/gsm_map/gsm_map.cnf +++ b/asn1/gsm_map/gsm_map.cnf @@ -1,5 +1,5 @@ -#.OPT +#.OPT -b #-d satcom #-s packet-gsm_map-tmp @@ -436,7 +436,7 @@ actx->pinfo->p2p_dir = P2P_DIR_RECV; if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_gsm_map_cbs_data_coding); - dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree); + dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree, 0); #.FN_BODY USSD-String VAL_PTR = ¶meter_tvb diff --git a/asn1/gsm_map/packet-gsm_map-template.c b/asn1/gsm_map/packet-gsm_map-template.c index 2ae8f3b45d..a04a17987b 100644 --- a/asn1/gsm_map/packet-gsm_map-template.c +++ b/asn1/gsm_map/packet-gsm_map-template.c @@ -604,24 +604,24 @@ static const value_string gsm_map_cbs_coding_grp15_class_vals[] = { /* 3GPP TS 23.038 version 7.0.0 Release 7 */ guint8 -dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) +dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint16 offset) { guint8 octet; guint8 coding_grp; guint8 character_set; - octet = tvb_get_guint8(tvb,0); + octet = tvb_get_guint8(tvb,offset); coding_grp = octet >>4; - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_NOT_SET; switch (coding_grp){ case 0: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp0_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp0_lang, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_7BIT; break; case 1: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp1_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp1_lang, tvb, offset, 1, ENC_BIG_ENDIAN); if ((octet & 0x0f)== 0){ sms_encoding = SMS_ENCODING_7BIT_LANG; }else{ @@ -629,11 +629,11 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree } break; case 2: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp2_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp2_lang, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_7BIT; break; case 3: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp3_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp3_lang, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_7BIT; break; /* Coding_grp 01xx */ @@ -645,11 +645,11 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree /* FALLTHRU */ case 7: /* FALLTHRU */ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_comp, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class_ind, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_comp, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class_ind, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, offset, 1, ENC_BIG_ENDIAN); if ((octet & 0x10)== 0x10){ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, offset, 1, ENC_BIG_ENDIAN); } /* Bits 3 and 2 indicate the character set being used, */ character_set = (octet&0x0c)>>2; @@ -679,8 +679,8 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree break; case 9: /* Message with User Data Header (UDH) structure:*/ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, offset, 1, ENC_BIG_ENDIAN); character_set = (octet&0x0c)>>2; switch (character_set){ case 0: @@ -720,8 +720,8 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree break; case 15: /* Data coding / message handling */ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_mess_code, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_class, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_mess_code, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_class, tvb, offset, 1, ENC_BIG_ENDIAN); character_set = (octet&0x04)>>2; if (character_set == 0){ sms_encoding = SMS_ENCODING_7BIT; diff --git a/asn1/gsm_map/packet-gsm_map-template.h b/asn1/gsm_map/packet-gsm_map-template.h index 6f167adeb8..a57ce8f3f9 100644 --- a/asn1/gsm_map/packet-gsm_map-template.h +++ b/asn1/gsm_map/packet-gsm_map-template.h @@ -51,7 +51,7 @@ extern const value_string gsm_map_PDP_Type_Organisation_vals[]; extern const value_string gsm_map_ietf_defined_pdp_vals[]; extern const value_string gsm_map_etsi_defined_pdp_vals[]; -guint8 dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree); +guint8 dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint16 offset); void dissect_gsm_map_msisdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree); #include "packet-gsm_map-exp.h" diff --git a/asn1/sabp/packet-sabp-template.c b/asn1/sabp/packet-sabp-template.c index 7c735114fa..b8fb84e762 100644 --- a/asn1/sabp/packet-sabp-template.c +++ b/asn1/sabp/packet-sabp-template.c @@ -40,6 +40,7 @@ #include "packet-gsm_map.h" #include "packet-gsm_sms.h" #include <epan/sctpppids.h> +#include "packet-cell_broadcast.h" #define PNAME "UTRAN IuBC interface SABP signaling" #define PSNAME "SABP" @@ -58,6 +59,8 @@ static int ett_sabp = -1; static int ett_sabp_e212 = -1; static int ett_sabp_cbs_data_coding = -1; static int ett_sabp_bcast_msg = -1; +static int ett_sabp_cbs_serial_number = -1; +static int ett_sabp_cbs_new_serial_number = -1; #include "packet-sabp-ett.c" @@ -182,6 +185,8 @@ void proto_register_sabp(void) { &ett_sabp_e212, &ett_sabp_cbs_data_coding, &ett_sabp_bcast_msg, + &ett_sabp_cbs_serial_number, + &ett_sabp_cbs_new_serial_number, #include "packet-sabp-ettarr.c" }; diff --git a/asn1/sabp/sabp.cnf b/asn1/sabp/sabp.cnf index cb6a2d64db..c3f3738cc7 100644 --- a/asn1/sabp/sabp.cnf +++ b/asn1/sabp/sabp.cnf @@ -178,6 +178,40 @@ Error-Indication N sabp.proc.imsg id-Error-Indication if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_sabp_cbs_data_coding); - sms_encoding = dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree); + sms_encoding = dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree, 0); +#.FN_BODY Message-Identifier VAL_PTR = ¶meter_tvb + tvbuff_t *parameter_tvb=NULL; + +%(DEFAULT_BODY)s + if (!parameter_tvb) + return offset; + dissect_cbs_message_identifier(parameter_tvb, tree, 0); + +#.FN_BODY Serial-Number VAL_PTR = ¶meter_tvb + tvbuff_t *parameter_tvb=NULL; + proto_tree *subtree; + +%(DEFAULT_BODY)s + if (!parameter_tvb) + return offset; + subtree = proto_item_add_subtree(actx->created_item, ett_sabp_cbs_serial_number); + dissect_cbs_serial_number(parameter_tvb, subtree, 0); +#.FN_BODY New-Serial-Number VAL_PTR = ¶meter_tvb + tvbuff_t *parameter_tvb=NULL; + proto_tree *subtree; + +%(DEFAULT_BODY)s + if (!parameter_tvb) + return offset; + subtree = proto_item_add_subtree(actx->created_item, ett_sabp_cbs_new_serial_number); + dissect_cbs_serial_number(parameter_tvb, subtree, 0); + +#.FN_BODY Broadcast-Message-Content VAL_PTR = ¶meter_tvb + tvbuff_t *parameter_tvb=NULL; + +%(DEFAULT_BODY)s + if (!parameter_tvb) + return offset; + dissect_umts_cell_broadcast_message(parameter_tvb, actx->pinfo, proto_tree_get_root(tree)); diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index cae7cb84fb..364abc2895 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -397,6 +397,7 @@ set(DISSECTOR_SRC dissectors/packet-catapult-dct2000.c dissectors/packet-ccsds.c dissectors/packet-cdp.c + dissectors/packet-cell_broadcast.c dissectors/packet-cfm.c dissectors/packet-cgmp.c dissectors/packet-chdlc.c @@ -608,8 +609,9 @@ set(DISSECTOR_SRC dissectors/packet-gsm_a_rr.c dissectors/packet-gsm_bsslap.c dissectors/packet-gsm_bssmap_le.c - dissectors/packet-gsm_rlcmac.c + dissectors/packet-gsm_cbch.c dissectors/packet-gsm_ipa.c + dissectors/packet-gsm_rlcmac.c dissectors/packet-gsm_sms.c dissectors/packet-gsm_sms_ud.c dissectors/packet-gsm_um.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index f4f4d0249e..1924075981 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -315,6 +315,7 @@ DISSECTOR_SRC = \ packet-catapult-dct2000.c \ packet-ccsds.c \ packet-cdp.c \ + packet-cell_broadcast.c \ packet-cfm.c \ packet-cgmp.c \ packet-chdlc.c \ @@ -526,6 +527,7 @@ DISSECTOR_SRC = \ packet-gsm_a_rr.c \ packet-gsm_bsslap.c \ packet-gsm_bssmap_le.c \ + packet-gsm_cbch.c \ packet-gsm_ipa.c \ packet-gsm_rlcmac.c \ packet-gsm_sms.c \ @@ -1116,6 +1118,7 @@ DISSECTOR_INCLUDES = \ packet-c1222.h \ packet-camel.h \ packet-cdt.h \ + packet-cell_broadcast.h \ packet-charging_ase.h \ packet-chdlc.h \ packet-cimd.h \ diff --git a/epan/dissectors/packet-bmc.c b/epan/dissectors/packet-bmc.c index bcc704abe3..af18efb19c 100644 --- a/epan/dissectors/packet-bmc.c +++ b/epan/dissectors/packet-bmc.c @@ -32,6 +32,10 @@ #include <epan/bitswap.h> #include <epan/packet.h> +#include <epan/asn1.h> /* needed for packet-gsm_map.h */ + +#include "packet-cell_broadcast.h" +#include "packet-gsm_map.h" static int dissect_bmc_cbs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); static int dissect_bmc_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); @@ -138,19 +142,21 @@ dissect_bmc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) static int dissect_bmc_cbs_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) { + tvbuff_t *cell_broadcast_tvb; gint offset=1; - proto_tree_add_item(tree, hf_bmc_message_id, tvb, offset, 2, ENC_BIG_ENDIAN); + dissect_cbs_message_identifier(tvb, tree, offset); offset += 2; - proto_tree_add_item(tree, hf_bmc_serial_number, tvb, offset, 2, ENC_BIG_ENDIAN); + dissect_cbs_serial_number(tvb, tree, offset); offset += 2; - proto_tree_add_item(tree, hf_bmc_data_coding_scheme, tvb, offset, 1, ENC_BIG_ENDIAN); + dissect_cbs_data_coding_scheme(tvb, pinfo, tree, offset); offset += 1; - proto_tree_add_item(tree, hf_bmc_cb_data, tvb, offset, tvb_length_remaining(tvb,offset), ENC_NA); - offset = tvb_length(tvb); + cell_broadcast_tvb = tvb_new_subset(tvb, offset, -1, -1); + dissect_umts_cell_broadcast_message(cell_broadcast_tvb, pinfo, tree); + offset = tvb_length(cell_broadcast_tvb); return offset; } diff --git a/epan/dissectors/packet-cell_broadcast.c b/epan/dissectors/packet-cell_broadcast.c new file mode 100644 index 0000000000..1ef524cffe --- /dev/null +++ b/epan/dissectors/packet-cell_broadcast.c @@ -0,0 +1,570 @@ +/* packet-gsm_cell_broadcast.c + * Routines for GSM Cell Broadcast Service dissection - A.K.A. 3GPP 23.041 (GSM 03.41) section 9.4 + * + * Copyright 2011, Mike Morrin <mike.morrin [AT] ipaccess.com> + * + * $Id$ + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <epan/packet.h> + +#include <epan/emem.h> +#include <epan/strutil.h> +#include <epan/asn1.h> + +#include <epan/packet.h> +#include <epan/reassemble.h> + +#include "packet-gsm_map.h" +#include "packet-gsm_sms.h" + +#define GSM_CBS_PAGE_SIZE 88 + +const value_string message_id_values[] = { + { 0, "Index"}, + { 10, "Flashes"}, + { 20, "Hospitals"}, + { 22, "Doctors"}, + { 24, "Pharmacy"}, + { 30, "Long Distance Road Reports"}, + { 32, "Local Road Reports"}, + { 34, "Taxis"}, + { 40, "Weather"}, + { 50, "Regional Services (local phone prefixes) / District (Base Station Identity)"}, + { 52, "Network Information"}, + { 54, "Operator Service"}, + { 56, "Directory Enquiries (national)"}, + { 57, "Directory Enquiries (international)"}, + { 58, "Customer Care (national)"}, + { 59, "Customer Care (international)"}, + { 60, "Local Date/Time Group incl. Time Zone"}, + { 100, "Regional Services (local phone prefixes)"}, + { 101, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 102, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 103, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 104, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 105, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 106, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 107, "planned for news, events, whether, traffic, TV station and News of the day"}, + { 123, "Mobile Auction"}, + { 140, "Handelsblatt (latest info from stock exchange)"}, + { 666, "PASSO Traffic Alert (brief teaser information for IVR)"}, + { 1000, "LCS CBS Message Identifier for E-OTD Assistance Data message"}, + { 1001, "LCS CBS Message Identifier for DGPS Correction Data message"}, + { 1002, "LCS CBS Message Identifier for GPS Ephemeris and Clock Correction Data message"}, + { 1003, "LCS CBS Message Identifier for GPS Almanac and Other Data message"}, + { 4352, "ETWS CBS Message Identifier for earthquake warning message"}, + { 4353, "ETWS CBS Message Identifier for tsunami warning message"}, + { 4354, "ETWS CBS Message Identifier for earthquake and tsunami combined warning message"}, + { 4355, "ETWS CBS Message Identifier for test message"}, + { 4356, "ETWS CBS Message Identifier for messages related to other emergency types"}, + { 4370, "CMAS CBS Message Identifier for CMAS Presidential Level Alerts"}, + { 4371, "CMAS CBS Message Identifier for CMAS Extreme Alerts with Severity of Extreme, Urgency of Immediate, and Certainty of Observed"}, + { 4372, "CMAS CBS Message Identifier for CMAS Extreme Alerts with Severity of Extreme, Urgency of Immediate, and Certainty of Likely"}, + { 4373, "CMAS CBS Message Identifier for CMAS Severe Alerts with Severity of Extreme, Urgency of Expected, and Certainty of Observed"}, + { 4374, "CMAS CBS Message Identifier for CMAS Severe Alerts with Severity of Extreme, Urgency of Expected, and Certainty of Likely"}, + { 4375, "CMAS CBS Message Identifier for CMAS Severe Alerts with Severity of Severe, Urgency of Immediate, and Certainty of Observed"}, + { 4376, "CMAS CBS Message Identifier for CMAS Severe Alerts with Severity of Severe, Urgency of Immediate, and Certainty of Likely"}, + { 4377, "CMAS CBS Message Identifier for CMAS Severe Alerts with Severity of Severe, Urgency of Expected, and Certainty of Observed"}, + { 4378, "CMAS CBS Message Identifier for CMAS Severe Alerts with Severity of Severe, Urgency of Expected, and Certainty of Likely"}, + { 4379, "CMAS CBS Message Identifier for Child Abduction Emergency (or Amber Alert)"}, + { 4380, "CMAS CBS Message Identifier for the Required Monthly Test"}, + { 4381, "CMAS CBS Message Identifier for CMAS Exercise"}, + { 4382, "CMAS CBS Message Identifier for operator defined use"}, + { 65535, "Message Identifier Reserved, and should not be used for new services"}, + { 0, NULL } +}; + +const value_string geographic_scope_values[] = { + { 0x00, "Cell-wide (immediate display)" }, + { 0x01, "PLMN-wide" }, + { 0x02, "Location Area-wide (GSM) or Service Area-wide (UMTS)" }, + { 0x03, "Cell-wide (normal display)" }, + { 0, NULL } +}; + +/* Initialize the protocol and registered fields */ +static int proto_cell_broadcast = -1; + +static int hf_gsm_cbs_serial_number = -1; +static int hf_gsm_cbs_geographic_scope = -1; +static int hf_gsm_cbs_message_code = -1; +static int hf_gsm_cbs_update_number = -1; +static int hf_gsm_cbs_message_identifier = -1; +static int hf_gsm_cbs_total_pages = -1; +static int hf_gsm_cbs_current_page = -1; + +/* These fields are used when reassembling multi-page gsm cbs messages */ +static int hf_gsm_cbs_pages = -1; +static int hf_gsm_cbs_page_num = -1; +static int hf_gsm_cbs_page_overlap = -1; +static int hf_gsm_cbs_page_overlap_conflict = -1; +static int hf_gsm_cbs_page_multiple_tails = -1; +static int hf_gsm_cbs_page_too_long_fragment = -1; +static int hf_gsm_cbs_page_error = -1; +static int hf_gsm_cbs_page_count = -1; +static int hf_gsm_cbs_message_reassembled_in = -1; +static int hf_gsm_cbs_message_reassembled_length = -1; +static int hf_gsm_cbs_page_content = -1; +static int hf_gsm_cbs_message_content = -1; + +/* Initialize the subtree pointers */ +static gint ett_cbs_msg = -1; +static gint ett_cbs_serial_no = -1; +static gint ett_cbs_coding = -1; +static gint ett_gsm_cbs_page = -1; +static gint ett_gsm_cbs_page_content = -1; +static gint ett_gsm_cbs_pages = -1; + +/* reassembly of GSM multi-page messages */ +static GHashTable *gsm_cbs_page_table = NULL; +static GHashTable *gsm_cbs_message_table = NULL; + +/* Structure needed for the fragmentation routines in reassemble.c */ +static const fragment_items gsm_page_items = { + &ett_gsm_cbs_page, + &ett_gsm_cbs_pages, + &hf_gsm_cbs_pages, + &hf_gsm_cbs_page_num, + &hf_gsm_cbs_page_overlap, + &hf_gsm_cbs_page_overlap_conflict, + &hf_gsm_cbs_page_multiple_tails, + &hf_gsm_cbs_page_too_long_fragment, + &hf_gsm_cbs_page_error, + &hf_gsm_cbs_page_count, + &hf_gsm_cbs_message_reassembled_in, + &hf_gsm_cbs_message_reassembled_length, + "pages" +}; + + +static void gsm_cbs_message_reassembly_init(void) +{ + fragment_table_init(&gsm_cbs_page_table); + reassembled_table_init(&gsm_cbs_message_table); +} + +guint16 dissect_cbs_serial_number(tvbuff_t *tvb, proto_tree *tree, guint16 offset) +{ + guint16 serial_number = tvb_get_ntohs(tvb, offset) ; + proto_item *item; + proto_tree *subtree; + + item = proto_tree_add_item(tree, hf_gsm_cbs_serial_number, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_item_append_text(item, ", Message Code: %d, Update Number: %d", (serial_number & 0x3FF) >> 4, serial_number & 0x0F); + subtree = proto_item_add_subtree(item, ett_cbs_serial_no); + proto_tree_add_item(subtree, hf_gsm_cbs_geographic_scope, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(subtree, hf_gsm_cbs_message_code, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(subtree, hf_gsm_cbs_update_number, tvb, offset, 2, ENC_BIG_ENDIAN); + offset +=2; + return offset; +} + +guint16 dissect_cbs_message_identifier(tvbuff_t *tvb, proto_tree *tree, guint16 offset) +{ + guint16 msg_id; + const char *msg_id_string = NULL; + + msg_id = tvb_get_ntohs(tvb, offset); + msg_id_string = match_strval(msg_id, message_id_values); + if (msg_id_string == NULL) + { + if (msg_id < 1000) + { + msg_id_string = "Message ID to be allocated by GSMA"; + } + else if (msg_id < 4096) + { + msg_id_string = "Message ID intended for standardization in future versions of 3GPP TS 23.041"; + } + else if (msg_id < 4224) + { + msg_id_string = "Message ID reserved for Cell Broadcast Data Download (unsecured) to the SIM "; + } + else if (msg_id < 4352) + { + msg_id_string = "Message ID reserved for Cell Broadcast Data Download (secured) to the SIM "; + } + else if (msg_id < 4360) + { + msg_id_string = "ETWS CBS Message Identifier for future extension"; + } + else if (msg_id < 4400) + { + msg_id_string = "CMAS CBS Message Identifier for future extension"; + } + else if (msg_id < 6400) + { + msg_id_string = "CBS Message Identifier for future PWS use"; + } + else if (msg_id < 40960) + { + msg_id_string = "Intended for standardization in future versions of 3GPP TS 23.041"; + } + else if (msg_id < 43500) + { + msg_id_string = "Message ID in PLMN operator specific range"; + } + else if (msg_id < 43530) + { + msg_id_string = "Traffic Information Traffic Master UK"; + } + else if (msg_id < 43585) + { + msg_id_string = "Traffic information Mannesmann Telecommerce"; + } + else if (msg_id < 45056) + { + msg_id_string = "Message ID in PLMN operator specific range"; + } + else + { + msg_id_string = "Message ID intended as PLMN operator specific range in future versions of 3GPP TS 23.041"; + } + } + proto_tree_add_uint_format_value(tree, hf_gsm_cbs_message_identifier, tvb, offset, 2, msg_id, "%s (%d)", msg_id_string, msg_id); + return 2; +} + +static tvbuff_t * dissect_cbs_data(guint8 sms_encoding, tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint16 offset ) +{ + tvbuff_t * tvb_out = NULL; + guint8 out_len; + int length = tvb_length(tvb) - offset; + gchar *utf8_text = NULL; + static unsigned char msgbuf[1024]; + guint8 * input_string = tvb_get_ephemeral_string(tvb, offset, length); + GIConv cd; + GError *l_conv_error = NULL; + + switch(sms_encoding){ + case SMS_ENCODING_7BIT: + case SMS_ENCODING_7BIT_LANG: + out_len = gsm_sms_char_7bit_unpack(0, length, sizeof(msgbuf), + input_string, + msgbuf); + msgbuf[out_len] = '\0'; + utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len); + tvb_out = tvb_new_child_real_data(tvb, utf8_text, out_len, out_len); + add_new_data_source(pinfo, tvb_out, "unpacked 7 bit data"); + break; + + case SMS_ENCODING_8BIT: + tvb_out = tvb_new_subset(tvb, offset, length, length); + break; + + case SMS_ENCODING_UCS2: + case SMS_ENCODING_UCS2_LANG: + if ((cd = g_iconv_open("UTF-8","UCS-2BE")) != (GIConv) -1) + { + utf8_text = g_convert_with_iconv(input_string, length, cd, NULL, NULL, &l_conv_error); + if(!l_conv_error) + { + tvb_out = tvb_new_subset(tvb, offset, length, length); + } + else + proto_tree_add_text(tree, tvb, offset, length, "CBS String: g_convert_with_iconv FAILED"); + + g_free(utf8_text); + g_iconv_close(cd); + } + else + { + proto_tree_add_text(tree, tvb, offset, length, "CBS String: g_iconv_open FAILED contact wireshark"); + } + break; + + default: + proto_tree_add_text(tree, tvb, offset, length, "Unhandled encoding %d of CBS String", sms_encoding); + break; + } + return tvb_out; +} + +static void +dissect_gsm_cell_broadcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 sms_encoding, total_pages, current_page; + guint32 offset = 0; + guint32 len, msg_key; + proto_item *cbs_page_item = NULL, *cbs_page_item2 = NULL; + proto_tree *cbs_page_tree = NULL, *cbs_page_subtree = NULL; + guint16 serial_number, message_id; + tvbuff_t *cbs_page_tvb = NULL; + tvbuff_t *cbs_msg_tvb = NULL; + fragment_data * frag_data = NULL; + + len = tvb_length(tvb); + + col_append_str(pinfo->cinfo, COL_PROTOCOL, " Cell Broadcast"); + col_append_str(pinfo->cinfo, COL_INFO, " (CBS Page)"); + + cbs_page_item = proto_tree_add_protocol_format(proto_tree_get_root(tree), proto_cell_broadcast, tvb, 0, len, "GSM Cell Broadcast"); + cbs_page_tree = proto_item_add_subtree(cbs_page_item, ett_gsm_cbs_page); + + serial_number = tvb_get_ntohs(tvb, offset); + offset += dissect_cbs_serial_number(tvb, cbs_page_tree, offset); + message_id = tvb_get_ntohs(tvb, offset); + offset += dissect_cbs_message_identifier(tvb, cbs_page_tree, offset); + sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, cbs_page_tree, offset++); + total_pages = tvb_get_guint8(tvb, offset); + current_page = (total_pages & 0xF0) >> 4; + total_pages &= 0x0F; + proto_tree_add_item(cbs_page_tree, hf_gsm_cbs_current_page, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(cbs_page_tree, hf_gsm_cbs_total_pages, tvb, offset++, 1, ENC_BIG_ENDIAN); + cbs_page_tvb = dissect_cbs_data(sms_encoding, tvb, cbs_page_tree, pinfo, offset ); + + if (cbs_page_tvb != NULL) + { + if (tree != NULL) + { + proto_item *item = proto_tree_add_text(cbs_page_tree, tvb, offset, -1, "Cell Broadcast Page Contents"); + proto_tree *cbs_page_subtree = proto_item_add_subtree(item, ett_gsm_cbs_page_content); + gint len = tvb_length(cbs_page_tvb); + proto_tree_add_string(cbs_page_subtree, hf_gsm_cbs_page_content, cbs_page_tvb, 0, len, tvb_get_ephemeral_string(cbs_page_tvb, 0, len)); + } + if (total_pages == 1) + { + /* no need for reassembly */ + cbs_msg_tvb = cbs_page_tvb; + } + else + { + /* now we have a complete page, try to concatenate the full message */ + /* we can use the serial number and message ID as keys, as they are the same for all pages of a message */ + msg_key = (serial_number << 16) + message_id; + frag_data = fragment_add_check(cbs_page_tvb, 0, pinfo, msg_key, + gsm_cbs_page_table, gsm_cbs_message_table, + ((current_page -1) * GSM_CBS_PAGE_SIZE), + GSM_CBS_PAGE_SIZE, (current_page!=total_pages)); + cbs_msg_tvb = process_reassembled_data(cbs_page_tvb, 0, pinfo, "Reassembled Cell Broadcast message", + frag_data, &gsm_page_items, NULL, cbs_page_tree); + } + } + if ((tree != NULL) && (cbs_msg_tvb != NULL)) + { + guint16 len; + proto_item *cbs_msg_item = NULL; + proto_tree *cbs_msg_tree = NULL; + + len = tvb_length(cbs_msg_tvb); + col_append_str(pinfo->cinfo, COL_INFO, " (CBS Message)"); + + cbs_msg_item = proto_tree_add_protocol_format(proto_tree_get_root(tree), proto_cell_broadcast, cbs_msg_tvb, 0, len, "GSM Cell Broadcast Message"); + cbs_msg_tree = proto_item_add_subtree(cbs_msg_item, ett_cbs_msg); + + proto_tree_add_string(cbs_msg_tree, hf_gsm_cbs_message_content, cbs_msg_tvb, 0, len, tvb_get_ephemeral_string(cbs_msg_tvb, 0, len)); + } +} + +void dissect_umts_cell_broadcast_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 sms_encoding; + guint32 offset = 0; + guint32 len; + proto_item *cbs_item = NULL, *cbs_item2 = NULL; + proto_tree *cbs_tree = NULL, *cbs_subtree = NULL; + guint16 msg_len; + tvbuff_t * cbs_msg_tvb = NULL; + + len = tvb_length(tvb); + + col_append_str(pinfo->cinfo, COL_PROTOCOL, " Cell Broadcast"); + col_append_str(pinfo->cinfo, COL_INFO, " (CBS Message)"); + + cbs_item = proto_tree_add_protocol_format(proto_tree_get_root(tree), proto_cell_broadcast, tvb, 0, len, "Cell Broadcast"); + cbs_tree = proto_item_add_subtree(cbs_item, ett_cbs_msg); + + sms_encoding = dissect_cbs_data_coding_scheme(tvb, pinfo, cbs_tree, 0); + offset++; + cbs_msg_tvb = dissect_cbs_data(sms_encoding, tvb, cbs_tree, pinfo, offset ); + + msg_len = tvb_length(cbs_msg_tvb); + cbs_item2 = proto_tree_add_text(cbs_tree, tvb, offset, -1, "Cell Broadcast Message Contents (length: %d)", msg_len); + cbs_subtree = proto_item_add_subtree(cbs_item2, ett_cbs_msg); + proto_tree_add_text(cbs_subtree, cbs_msg_tvb , 0, tvb_length(cbs_msg_tvb), tvb_get_ephemeral_string(cbs_msg_tvb, 0, msg_len)); +} + +/* Register the protocol with Wireshark */ +void +proto_register_cbs(void) +{ + /* Setup list of header fields */ + static hf_register_info hf_cbs[] = + { + { &hf_gsm_cbs_serial_number, + { "GSM CBS Serial Number", "gsm_cbs.serial_number", + FT_UINT16, BASE_HEX_DEC, NULL, 0x00, + NULL, HFILL } + }, + { &hf_gsm_cbs_message_code, + { "GSM CBS Message Code", "gsm_cbs.message_code", + FT_UINT16, BASE_DEC_HEX, NULL, 0x3FF0, + NULL, HFILL } + }, + { &hf_gsm_cbs_geographic_scope, + { "GSM CBS Geographic Scope", "gsm_cbs.geographic_scope", + FT_UINT16, BASE_DEC, VALS(geographic_scope_values), 0xC000, + NULL, HFILL } + }, + { &hf_gsm_cbs_update_number, + { "GSM CBS Update Number", "gsm_cbs.update_number", + FT_UINT16, BASE_DEC, NULL, 0x000F, + NULL, HFILL } + }, + { &hf_gsm_cbs_message_identifier, + { "GSM CBS Message Identifier", "gsm_cbs.message-identifier", + FT_UINT16, BASE_DEC_HEX, NULL, 0x00, + NULL, HFILL } + }, + { &hf_gsm_cbs_total_pages, + { "GSM CBS Total Pages", "gsm_cbs.total_pages", + FT_UINT8, BASE_DEC, NULL, 0x0F, + NULL, HFILL } + }, + { &hf_gsm_cbs_current_page, + { "GSM CBS Current Page", "gsm_cbs.current_page", + FT_UINT8, BASE_DEC, NULL, 0xF0, + NULL, HFILL } + }, + /* Fragment fields + */ + { &hf_gsm_cbs_page_overlap, + { "page overlap", + "gsm_cbs.page.overlap", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "GSM CBS page overlaps with other fragments", HFILL + } + }, + { &hf_gsm_cbs_page_overlap_conflict, + { "Conflicting data in page overlap", + "gsm_cbs.page.overlap.conflict", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Overlapping pages contained conflicting data", HFILL + } + }, + { &hf_gsm_cbs_page_multiple_tails, + { "Multiple final pages found", + "gsm_cbs.page.multipletails", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Several copies of the final page were found when reassembling the message", HFILL + } + }, + { &hf_gsm_cbs_page_too_long_fragment, + { "Page too long", + "gsm_cbs.page.toolongfragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Page contained data past end of packet", HFILL + } + }, + { &hf_gsm_cbs_page_error, + { "Reassembly error", + "gsm_cbs.fragment.error", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "Reassembly error due to illegal fragments", HFILL + } + }, + { &hf_gsm_cbs_page_count, + { "Fragment count", + "gsm_cbs.fragment.count", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Count of Page Fragment", HFILL + } + }, + { &hf_gsm_cbs_message_reassembled_in, + { "Reassembled in", + "gsm_cbs.reassembled.in", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "CBS pages are reassembled in the given packet", HFILL + } + }, + { &hf_gsm_cbs_message_reassembled_length, + { "Reassembled message length", + "gsm_cbs.reassembled.length", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The total length of the reassembled message", HFILL + } + }, + { &hf_gsm_cbs_page_num, + { "CBS Page Number", + "gsm_cbs.page_number", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_gsm_cbs_pages, + { "CBS Pages", + "gsm_cbs.pages", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_gsm_cbs_page_content, + { "CBS Page Content", + "gsm_cbs.page_content", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_gsm_cbs_message_content, + { "CBS Message Content", + "gsm_cbs.message_content", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_cbs_msg, + &ett_cbs_serial_no, + &ett_cbs_coding, + &ett_gsm_cbs_page, + &ett_gsm_cbs_page_content, + &ett_gsm_cbs_pages, + }; + + /* Register the protocol name and description */ + proto_cell_broadcast = proto_register_protocol("GSM Cell Broadcast Service", "GSM Cell Broadcast Service", "gsm_cell_broadcast"); + + proto_register_field_array(proto_cell_broadcast, hf_cbs, array_length(hf_cbs)); + register_init_routine(gsm_cbs_message_reassembly_init); + + /* subdissector code */ + register_dissector("gsm_cell_broadcast", dissect_gsm_cell_broadcast, proto_cell_broadcast); + register_dissector("umts_cell_broadcast", dissect_umts_cell_broadcast_message, proto_cell_broadcast); + + /* subtree array */ + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_gsm_cbs(void) +{ +} diff --git a/epan/dissectors/packet-cell_broadcast.h b/epan/dissectors/packet-cell_broadcast.h new file mode 100644 index 0000000000..68923603c0 --- /dev/null +++ b/epan/dissectors/packet-cell_broadcast.h @@ -0,0 +1,59 @@ +/* packet-cell_broadcast.h + * + * $Id$ + * + * Copyright 2011, Mike Morrin <mike.morrin [AT] ipaccess.com>, + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PACKET_CELL_BROADCAST_H +#define PACKET_CELL_BROADCAST_H + + +/** + * Dissects the GSM/UMTS/SABP Message Identifier + * + * @param tvb + * @param tree + * @param offset + */ +void dissect_cbs_message_identifier(tvbuff_t *tvb, proto_tree *tree, guint16 offset); + + +/** + * Decodes the GSM/UMTS/SABP message Serial Number + * + * @param tvb + * @param tree + * @param offset + */ +void dissect_cbs_serial_number(tvbuff_t *tvb, proto_tree *tree, guint16 offset); + + +/** + * Dissects UMTS/SABP Cell Broadcast Message + * + * @param tvb + * @param pinfo + * @param tree + */ +guint16 dissect_umts_cell_broadcast_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +#endif /* PACKET_CELL_BROADCAST_H */ diff --git a/epan/dissectors/packet-gsm_cbch.c b/epan/dissectors/packet-gsm_cbch.c new file mode 100644 index 0000000000..26c47df9d4 --- /dev/null +++ b/epan/dissectors/packet-gsm_cbch.c @@ -0,0 +1,585 @@ +/* packet-gsm_cbch.c + * Routines for GSM CBCH dissection - A.K.A. 3GPP 44.012 (GSM 04.12) + * + * Copyright 2011, Mike Morrin <mike.morrin [AT] ipaccess.com> + * + * $Id$ + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include <stdlib.h> + +#include <string.h> + +#include <epan/packet.h> +#include <epan/reassemble.h> +#include "packet-cell_broadcast.h" + +#define CBCH_FRAGMENT_SIZE 22 + +const value_string block_type_lpd_strings[] = { + { 0x00, "NOT Cell Broadcast"}, + { 0x01, "Cell Broadcast"}, + { 0x02, "NOT Cell Broadcast"}, + { 0x03, "NOT Cell Broadcast"}, + { 0, NULL} +}; + +const value_string block_type_seq_num_values[] = { + { 0x00, "First Block"}, + { 0x01, "Second Block"}, + { 0x02, "Third Block"}, + { 0x03, "Fourth Block"}, + { 0x08, "First Schedule Block"}, + { 0xFF, "Null message"}, + { 0, NULL} +}; + +const value_string sched_type_values[] = { + { 0x00, "messages formatted as specified in subclause 3.5 of 3GPP 44.012"}, + { 0xFF, "Unknown schedule message format"}, + { 0, NULL} +}; + +/* Initialize the protocol and registered fields */ +static int proto_cbch = -1; + +static int hf_gsm_cbch_spare_bit = -1; +static int hf_gsm_cbch_lpd = -1; +static int hf_gsm_cbch_lb = -1; +static int hf_gsm_cbch_seq_num = -1; +static int hf_gsm_cbch_sched_type = -1; +static int hf_gsm_cbch_sched_begin_slot = -1; +static int hf_gsm_cbch_sched_spare = -1; +static int hf_gsm_cbch_sched_end_slot = -1; +static int hf_gsm_cbch_sched_msg_id = -1; + +/* These fields are used when reassembling cbch fragments +*/ +static int hf_cbch_fragments = -1; +static int hf_cbch_fragment = -1; +static int hf_cbch_fragment_overlap = -1; +static int hf_cbch_fragment_overlap_conflict = -1; +static int hf_cbch_fragment_multiple_tails = -1; +static int hf_cbch_fragment_too_long_fragment = -1; +static int hf_cbch_fragment_error = -1; +static int hf_cbch_fragment_count = -1; +static int hf_cbch_reassembled_in = -1; +static int hf_cbch_reassembled_length = -1; + +/* Initialize the subtree pointers */ +static gint ett_cbch_msg = -1; +static gint ett_schedule_msg = -1; +static gint ett_schedule_new_msg = -1; +static gint ett_cbch_fragment = -1; +static gint ett_cbch_fragments = -1; + +static dissector_handle_t data_handle; +static dissector_handle_t cbs_handle; + +/* reassembly of CHCH blocks */ +static GHashTable *fragment_block_table = NULL; +static GHashTable *reassembled_message_table = NULL; + +/* Structure needed for the fragmentation routines in reassemble.c +*/ +static const fragment_items cbch_frag_items = { + &ett_cbch_fragment, + &ett_cbch_fragments, + &hf_cbch_fragments, + &hf_cbch_fragment, + &hf_cbch_fragment_overlap, + &hf_cbch_fragment_overlap_conflict, + &hf_cbch_fragment_multiple_tails, + &hf_cbch_fragment_too_long_fragment, + &hf_cbch_fragment_error, + &hf_cbch_fragment_count, + &hf_cbch_reassembled_in, + &hf_cbch_reassembled_length, + "blocks" +}; + +static void cbch_defragment_init(void) +{ + fragment_table_init(&fragment_block_table); + reassembled_table_init(&reassembled_message_table); +} + +static void dissect_schedule_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree) +{ + guint8 octet1, i, j, k=0, len, sched_begin, sched_end, new_slots[48] , offset = 0; + gboolean valid_message = TRUE; + guint16 other_slots[48]; + proto_item *item = NULL, *schedule_item = NULL; + proto_tree *sched_tree = NULL, *sched_subtree = NULL; + + len = tvb_length(tvb); + + col_append_str(pinfo->cinfo, COL_INFO, " CBCH Schedule Message "); + + schedule_item = proto_tree_add_protocol_format(top_tree, proto_cbch, tvb, 0, len, + "GSM CBCH Schedule Message"); + + sched_tree = proto_item_add_subtree(schedule_item, ett_schedule_msg); + + proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_type, tvb, offset, 1, ENC_BIG_ENDIAN); + octet1 = tvb_get_guint8(tvb, offset); + if (0 == (octet1 & 0xC0)) + { + sched_begin = octet1 & 0x3F; + proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_begin_slot, tvb, offset++, 1, ENC_BIG_ENDIAN); + if (1 == sched_begin) + { + proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "(apparently) Scheduled Scheduling Message"); + } + else if ((2 <= sched_begin) && (48 >= sched_begin)) + { + proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "(apparently) Unscheduled Scheduling Message"); + } + else + { + proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "Begin Slot Number out of range: ignoring message"); + valid_message = FALSE; + } + proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_spare, tvb, offset, 1, ENC_BIG_ENDIAN); + sched_end = tvb_get_guint8(tvb, offset); + proto_tree_add_item(sched_tree, hf_gsm_cbch_sched_end_slot, tvb, offset++, 1, ENC_BIG_ENDIAN); + if (sched_end < sched_begin) + { + proto_tree_add_text(sched_tree, tvb, offset - 1, 1, "End Slot Number less than Begin Slot Number: ignoring message"); + valid_message = FALSE; + } + + if (valid_message) + { + /* build an array of new messages */ + memset(&new_slots, 0xFF, sizeof(new_slots)); + memset(&other_slots, 0xFF, sizeof(other_slots)); + + /* iterate over the octets */ + for (i=0; i<6; i++) + { + octet1 = tvb_get_guint8(tvb, offset++); + + /* iterate over the bits */ + for (j=0; j<8; j++) + { + if (octet1 & (0x80>>j)) + { + new_slots[k++] = (i<<3) + j + 1; + } + } + } + /* print the array of new messages */ + item = proto_tree_add_text(sched_tree, tvb, offset-6, 6, "This schedule contains %d slots with new messages", k); + sched_subtree = proto_item_add_subtree(item, ett_schedule_new_msg); + for (i=0; i<k; i++) + { + DISSECTOR_ASSERT(new_slots[i] < 48); + octet1 = tvb_get_guint8(tvb, offset); + if ((octet1 & 0x80) == 0x80) + { + /* MDT 1 */ + guint8 octet2; + guint16 msg_id; + + octet2 = tvb_get_guint8(tvb, offset + 1); + msg_id = ((octet1 &0x7F) << 8) + octet2; + proto_tree_add_text(sched_subtree, tvb, offset, 2, + "Slot: %d, Message ID: %d, First transmission of an SMSCB within the Schedule Period", + new_slots[i], msg_id); + offset +=2; + other_slots[new_slots[i] - 1] = msg_id; + } + else if ((octet1 & 0xC0) == 0) + { + /* MDT 00 */ + if (octet1 < new_slots[i]) + { + proto_tree_add_text(sched_subtree, tvb, offset++, 1, + "Slot: %d, Message ID: %d, Repeat of Slot %d", + new_slots[i], other_slots[octet1 - 1], octet1); + other_slots[new_slots[i] - 1] = other_slots[octet1 - 1]; + } + else + { + proto_tree_add_text(sched_subtree, tvb, offset++, 1, + "Slot: %d, Apparent forward reference to slot %d", + new_slots[i], octet1); + } + } + else if ((octet1 == 0x40)) + { + /* MDT 010000000 */ + proto_tree_add_text(sched_subtree, tvb, offset++, 1, "Slot: %d Free Message Slot, optional reading", new_slots[k]); + other_slots[new_slots[i] - 1] = 0xFFFE; + } + else if ((octet1 == 0x41)) + { + /* MDT 010000001 */ + proto_tree_add_text(sched_subtree, tvb, offset++, 1, "Slot: %d Free Message Slot, reading advised", new_slots[k]); + other_slots[new_slots[i] - 1] = 0xFFFE; + } + else + { + /* reserved MDT */ + proto_tree_add_text(sched_subtree, tvb, offset, 1, "Slot: %d reseved MDT: %x", new_slots[k], octet1); + other_slots[new_slots[i] - 1] = 0xFFFE; + } + } + proto_item_set_end(item, tvb, offset); + + /* print schedule of other messages */ + item = proto_tree_add_text(sched_tree, tvb, offset, 0, "Other message slots in this schedule"); + sched_subtree = proto_item_add_subtree(item, ett_schedule_new_msg); + for (k=0; offset<len; j++) + { + while ((other_slots[k]!=0xFFFF) && (k<sched_end)) + { + k++; + } + if (k >= sched_end) + break; + + octet1 = tvb_get_guint8(tvb, offset); + if ((octet1 & 0x80) == 0x80) + { + if ((offset+1)<len) + { + /* MDT 1 */ + guint8 octet2; + guint16 msg_id; + + octet2 = tvb_get_guint8(tvb, offset + 1); + msg_id = ((octet1 &0x7F) << 8) + octet2; + other_slots[k] = msg_id; + proto_tree_add_text(sched_subtree, tvb, offset, 2, + "Slot: %d, Message: %d, First transmission of an SMSCB within the Schedule Period", + ++k, msg_id); + offset +=2; + } + } + else if ((octet1 & 0xC0) == 0) + { + /* MDT 00 */ + if (octet1 < k) + { + other_slots[k] = other_slots[octet1 - 1]; + proto_tree_add_text(sched_subtree, tvb, offset++, 1, + "Slot: %d, Message ID: %d, Repeat of Slot %d", + ++k, other_slots[octet1 - 1], octet1); + } + else + { + proto_tree_add_text(sched_subtree, tvb, offset++, 1, + "Slot: %d, Apparent forward reference to slot %d", + ++k, octet1); + } + } + else if ((octet1 == 0x40)) + { + /* MDT 010000000 */ + proto_tree_add_text(sched_subtree, tvb, offset++, 1, "Slot: %d Free Message Slot, optional reading", ++k); + } + else if ((octet1 == 0x41)) + { + /* MDT 010000001 */ + proto_tree_add_text(sched_subtree, tvb, offset++, 1, "Slot: %d Free Message Slot, reading advised", ++k); + } + else + { + /* reserved MDT */ + proto_tree_add_text(sched_subtree, tvb, offset, 1, "Slot: %d reserved MDT: %x", ++k, octet1); + } + } + proto_item_set_end(item, tvb, offset); + proto_tree_add_text(sched_tree, tvb, offset, -1, "Padding"); + } + } +} + +static void +dissect_cbch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + fragment_data * frag_data = NULL; + guint8 octet, lb, lpd, seq_num; + guint32 offset; + guint32 len; + proto_item *cbch_item = NULL; + proto_tree *cbch_tree = NULL; + tvbuff_t *reass_tvb = NULL, *msg_tvb = NULL; + + len = tvb_length(tvb); + offset = 0; + octet = tvb_get_guint8(tvb, offset); + + /* + * create the protocol tree + */ + cbch_item = proto_tree_add_protocol_format(tree, proto_cbch, tvb, 0, len, + "GSM CBCH - Block (0x%02x)", octet&3); + + col_append_str(pinfo->cinfo, COL_PROTOCOL, " CBCH"); + + cbch_tree = proto_item_add_subtree(cbch_item, ett_cbch_msg); + + proto_tree_add_text(cbch_tree, tvb, offset, 1, + "CBCH Block"); + + proto_tree_add_uint(cbch_tree, hf_gsm_cbch_spare_bit, tvb, offset, 1, octet); + proto_tree_add_uint(cbch_tree, hf_gsm_cbch_lpd, tvb, offset, 1, octet); + proto_tree_add_uint(cbch_tree, hf_gsm_cbch_lb, tvb, offset, 1, octet); + proto_tree_add_uint(cbch_tree, hf_gsm_cbch_seq_num, tvb, offset, 1, octet); + seq_num = octet & 0x0F; + lpd = (octet & 0x60) >> 5; + lb = (octet & 0x10) >> 4; + + if (lpd == 1) + { + switch (seq_num) + { + case 0x00: + case 0x08: + pinfo->fragmented = TRUE; + /* we should have a unique ID for the reassembled page, but we don't really have anything from the protocol... + The GSM frame number div 4 might be used for this, but it has not been passed to this layer and does not + exist at all if the message is being passed over the RSL interface. + So we just use 0... */ + + /* after reassembly we will need to know if this is a scheduling message, + this information is carried in the initial sequence number, not the payload, + so we prepend the reassembly with the octet containing the initial sequence number + to allow later dissection of the payload */ + frag_data = fragment_add_seq_check(tvb, offset, pinfo, 0, + fragment_block_table, reassembled_message_table, + seq_num & 0x03, CBCH_FRAGMENT_SIZE + 1, !lb); + reass_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CBCH message", + frag_data, &cbch_frag_items, NULL, cbch_tree); + break; + + case 0x01: + case 0x02: + case 0x03: + pinfo->fragmented = TRUE; + offset++; /* step to beginning of payload */ + frag_data = fragment_add_seq_check(tvb, offset, pinfo, 0, + fragment_block_table, reassembled_message_table, seq_num, + CBCH_FRAGMENT_SIZE, !lb); + reass_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CBCH message", + frag_data, &cbch_frag_items, NULL, cbch_tree); + break; + + case 0x0F: + proto_tree_add_text(cbch_tree, tvb, offset, 1, "NULL message"); + call_dissector(data_handle, tvb, pinfo, cbch_tree); + break; + + default: + proto_tree_add_text(cbch_tree, tvb, offset, 1, "reserved Sequence Number"); + call_dissector(data_handle, tvb, pinfo, cbch_tree); + break; + } + if (reass_tvb) + { + /* Reassembled */ + + /* the tvb contains the reassmbled message prepended with the sequence number octet from the first block + We use this to determine whether this is a normal message or a scheduling message */ + offset = 0; + + octet = tvb_get_guint8(reass_tvb, offset++); + msg_tvb = tvb_new_subset_remaining(reass_tvb, offset); + + if (octet & 0x08) + { + dissect_schedule_message(msg_tvb, pinfo, tree); + } + else + { + call_dissector(cbs_handle, msg_tvb, pinfo, tree); + } + } + } + else + { + proto_tree_add_text(cbch_tree, tvb, offset, 1, "invalid Link Protocol Discriminator"); + call_dissector(data_handle, tvb, pinfo, cbch_tree); + } +} + +/* Register the protocol with Wireshark */ +void +proto_register_gsm_cbch(void) +{ + /* Setup list of header fields */ + static hf_register_info hf_smscb[] = + { + { &hf_gsm_cbch_spare_bit, + { "GSM CBCH spare bit", "gsm_cbch_block_type.spare", + FT_UINT8, BASE_HEX, NULL, 0x80, + NULL, HFILL} + }, + { &hf_gsm_cbch_lpd, + { "GSM CBCH Link Protocol Discriminator", "gsm_cbch_block_type.lpd", + FT_UINT8, BASE_DEC, VALS(block_type_lpd_strings), 0x60, + NULL, HFILL} + }, + { &hf_gsm_cbch_lb, + { "GSM CBCH Last Block", "gsm_cbch_block_type.lb", + FT_UINT8, BASE_DEC, NULL, 0x10, + "Last Block", HFILL} + }, + { &hf_gsm_cbch_seq_num, + { "GSM CBCH Sequence Number", "gsm_cbch_block_type.seq_num", + FT_UINT8, BASE_DEC, VALS(block_type_seq_num_values), 0x0F, + NULL, HFILL} + }, + { &hf_gsm_cbch_sched_type, + { "GSM CBCH Schedule Type", "gsm_cbch.sched_type", + FT_UINT8, BASE_DEC, VALS(sched_type_values), 0xC0, + NULL, HFILL} + }, + { &hf_gsm_cbch_sched_begin_slot, + { "GSM CBCH Schedule Begin slot", "gsm_cbch.schedule_begin", + FT_UINT8, BASE_DEC, NULL, 0x3F, + NULL, HFILL} + }, + { &hf_gsm_cbch_sched_spare, + { "GSM CBCH Schedule Spare Bits", "gsm_cbch.sched_spare", + FT_UINT8, BASE_DEC, NULL, 0xC0, + NULL, HFILL} + }, + { &hf_gsm_cbch_sched_end_slot, + { "GSM CBCH Schedule End Slot", "gsm_cbch.sched_end", + FT_UINT8, BASE_DEC, NULL, 0x3F, + NULL, HFILL} + }, + { &hf_gsm_cbch_sched_msg_id, + { "GSM CBCH Schedule Message ID", "gsm_cbch.sched_msg_id", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL} + }, + /* Fragment fields + */ + { &hf_cbch_fragment_overlap, + { "Fragment overlap", + "gsm_cbch.fragment.overlap", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Fragment overlaps with other fragments", HFILL + } + }, + { &hf_cbch_fragment_overlap_conflict, + { "Conflicting data in fragment overlap", + "gsm_cbch.fragment.overlap.conflict", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Overlapping fragments contained conflicting data", HFILL + } + }, + { &hf_cbch_fragment_multiple_tails, + { "Multiple tail fragments found", + "gsm_cbch.fragment.multipletails", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Several tails were found when defragmenting the packet", HFILL + } + }, + { &hf_cbch_fragment_too_long_fragment, + { "Fragment too long", + "gsm_cbch.fragment.toolongfragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Fragment contained data past end of packet", HFILL + } + }, + { &hf_cbch_fragment_error, + { "Defragmentation error", + "gsm_cbch.fragment.error", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "Defragmentation error due to illegal fragments", HFILL + } + }, + { &hf_cbch_fragment_count, + { "Fragmentation count", + "gsm_cbch.fragment.count", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Count of CBCH Fragments", HFILL + } + }, + { &hf_cbch_reassembled_in, + { "Reassembled in", + "gsm_cbch.reassembled.in", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "CBCH fragments are reassembled in the given packet", HFILL + } + }, + { &hf_cbch_reassembled_length, + { "Reassembled message length is one less than indicated here", + "gsm_cbch.reassembled.length", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The total length of the reassembled message", HFILL + } + }, + { &hf_cbch_fragment, + { "CBCH Fragment", + "gsm_cbch.fragment", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_cbch_fragments, + { "CBCH Fragments", + "gsm_cbch.fragments", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + } + }; + +/* Setup protocol subtree array */ + static gint *ett[] = { + &ett_cbch_msg, + &ett_schedule_msg, + &ett_schedule_new_msg, + &ett_cbch_fragment, + &ett_cbch_fragments, + }; + + /* Register the protocol name and description */ + proto_cbch = + proto_register_protocol("GSM Cell Broadcast Channel", "GSM CBCH", "gsm_cbch"); + + proto_register_field_array(proto_cbch, hf_smscb, array_length(hf_smscb)); + + /* subdissector code */ + register_dissector("gsm_cbch", dissect_cbch, proto_cbch); + register_init_routine(cbch_defragment_init); + + /* subtree array */ + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_gsm_cbch(void) +{ + data_handle = find_dissector("data"); + cbs_handle = find_dissector("gsm_cell_broadcast"); +} diff --git a/epan/dissectors/packet-gsm_map.c b/epan/dissectors/packet-gsm_map.c index e013a57bfd..56f619aebe 100644 --- a/epan/dissectors/packet-gsm_map.c +++ b/epan/dissectors/packet-gsm_map.c @@ -2716,24 +2716,24 @@ static const value_string gsm_map_cbs_coding_grp15_class_vals[] = { /* 3GPP TS 23.038 version 7.0.0 Release 7 */ guint8 -dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) +dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint16 offset) { guint8 octet; guint8 coding_grp; guint8 character_set; - octet = tvb_get_guint8(tvb,0); + octet = tvb_get_guint8(tvb,offset); coding_grp = octet >>4; - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_NOT_SET; switch (coding_grp){ case 0: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp0_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp0_lang, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_7BIT; break; case 1: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp1_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp1_lang, tvb, offset, 1, ENC_BIG_ENDIAN); if ((octet & 0x0f)== 0){ sms_encoding = SMS_ENCODING_7BIT_LANG; }else{ @@ -2741,11 +2741,11 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree } break; case 2: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp2_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp2_lang, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_7BIT; break; case 3: - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp3_lang, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp3_lang, tvb, offset, 1, ENC_BIG_ENDIAN); sms_encoding = SMS_ENCODING_7BIT; break; /* Coding_grp 01xx */ @@ -2757,11 +2757,11 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree /* FALLTHRU */ case 7: /* FALLTHRU */ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_comp, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class_ind, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_comp, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class_ind, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, offset, 1, ENC_BIG_ENDIAN); if ((octet & 0x10)== 0x10){ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, offset, 1, ENC_BIG_ENDIAN); } /* Bits 3 and 2 indicate the character set being used, */ character_set = (octet&0x0c)>>2; @@ -2791,8 +2791,8 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree break; case 9: /* Message with User Data Header (UDH) structure:*/ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_char_set, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp4_7_class, tvb, offset, 1, ENC_BIG_ENDIAN); character_set = (octet&0x0c)>>2; switch (character_set){ case 0: @@ -2832,8 +2832,8 @@ dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree break; case 15: /* Data coding / message handling */ - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_mess_code, tvb, 0, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_class, tvb, 0, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_mess_code, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_gsm_map_cbs_coding_grp15_class, tvb, offset, 1, ENC_BIG_ENDIAN); character_set = (octet&0x04)>>2; if (character_set == 0){ sms_encoding = SMS_ENCODING_7BIT; @@ -4501,7 +4501,7 @@ dissect_gsm_map_ss_USSD_DataCodingScheme(gboolean implicit_tag _U_, tvbuff_t *tv if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_gsm_map_cbs_data_coding); - dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree); + dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree, 0); diff --git a/epan/dissectors/packet-gsm_map.h b/epan/dissectors/packet-gsm_map.h index 179c59c976..bd80867762 100644 --- a/epan/dissectors/packet-gsm_map.h +++ b/epan/dissectors/packet-gsm_map.h @@ -59,7 +59,7 @@ extern const value_string gsm_map_PDP_Type_Organisation_vals[]; extern const value_string gsm_map_ietf_defined_pdp_vals[]; extern const value_string gsm_map_etsi_defined_pdp_vals[]; -guint8 dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree); +guint8 dissect_cbs_data_coding_scheme(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint16 offset); void dissect_gsm_map_msisdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree); diff --git a/epan/dissectors/packet-rsl.c b/epan/dissectors/packet-rsl.c index 945734ffdc..55fd77b80d 100644 --- a/epan/dissectors/packet-rsl.c +++ b/epan/dissectors/packet-rsl.c @@ -171,6 +171,8 @@ static int ett_ie_message_id = -1; static int ett_ie_sys_info_type = -1; static proto_tree *top_tree; +static dissector_handle_t gsm_cbch_handle; +static dissector_handle_t gsm_cbs_handle; static dissector_handle_t gsm_a_ccch_handle; static dissector_handle_t gsm_a_dtap_handle; static dissector_handle_t gsm_a_sacch_handle; @@ -1977,6 +1979,7 @@ dissect_rsl_ie_smscb_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree { proto_item *ti; proto_tree *ie_tree; + tvbuff_t *next_tvb; guint length; guint8 ie_id; @@ -2002,7 +2005,8 @@ dissect_rsl_ie_smscb_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree /* * SMSCB frame */ - proto_tree_add_text(ie_tree, tvb,offset,length,"SMSCB frame"); + next_tvb = tvb_new_subset(tvb, offset, length, length); + call_dissector(gsm_cbch_handle, next_tvb, pinfo, top_tree); offset = offset + length; @@ -2202,6 +2206,7 @@ dissect_rsl_ie_smscb_mess(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre { proto_item *ti; proto_tree *ie_tree; + tvbuff_t *next_tvb; guint length; guint8 ie_id; int ie_offset; @@ -2228,7 +2233,8 @@ dissect_rsl_ie_smscb_mess(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * SMSCB Message */ - proto_tree_add_text(ie_tree, tvb,offset,length ,"SMSCB Message"); + next_tvb = tvb_new_subset(tvb, offset, length, length); + call_dissector(gsm_cbs_handle, next_tvb, pinfo, top_tree); offset = ie_offset + length; @@ -3985,6 +3991,8 @@ proto_reg_handoff_rsl(void) rsl_handle = create_dissector_handle(dissect_rsl, proto_rsl); dissector_add_uint("lapd.gsm.sapi", LAPD_GSM_SAPI_RA_SIG_PROC, rsl_handle); + gsm_cbch_handle = find_dissector("gsm_cbch"); + gsm_cbs_handle = find_dissector("gsm_cell_broadcast"); gsm_a_ccch_handle = find_dissector("gsm_a_ccch"); gsm_a_dtap_handle = find_dissector("gsm_a_dtap"); gsm_a_sacch_handle = find_dissector("gsm_a_sacch"); diff --git a/epan/dissectors/packet-sabp.c b/epan/dissectors/packet-sabp.c index c8aaa4bf39..8d1b17812d 100644 --- a/epan/dissectors/packet-sabp.c +++ b/epan/dissectors/packet-sabp.c @@ -48,6 +48,7 @@ #include "packet-gsm_map.h" #include "packet-gsm_sms.h" #include <epan/sctpppids.h> +#include "packet-cell_broadcast.h" #define PNAME "UTRAN IuBC interface SABP signaling" #define PSNAME "SABP" @@ -99,7 +100,7 @@ typedef enum _ProtocolIE_ID_enum { } ProtocolIE_ID_enum; /*--- End of included file: packet-sabp-val.h ---*/ -#line 49 "../../asn1/sabp/packet-sabp-template.c" +#line 50 "../../asn1/sabp/packet-sabp-template.c" /* Initialize the protocol and registered fields */ static int proto_sabp = -1; @@ -189,13 +190,15 @@ static int hf_sabp_successfulOutcome_value = -1; /* SuccessfulOutcome_value */ static int hf_sabp_unsuccessfulOutcome_value = -1; /* UnsuccessfulOutcome_value */ /*--- End of included file: packet-sabp-hf.c ---*/ -#line 55 "../../asn1/sabp/packet-sabp-template.c" +#line 56 "../../asn1/sabp/packet-sabp-template.c" /* Initialize the subtree pointers */ static int ett_sabp = -1; static int ett_sabp_e212 = -1; static int ett_sabp_cbs_data_coding = -1; static int ett_sabp_bcast_msg = -1; +static int ett_sabp_cbs_serial_number = -1; +static int ett_sabp_cbs_new_serial_number = -1; /*--- Included file: packet-sabp-ett.c ---*/ @@ -241,7 +244,7 @@ static gint ett_sabp_SuccessfulOutcome = -1; static gint ett_sabp_UnsuccessfulOutcome = -1; /*--- End of included file: packet-sabp-ett.c ---*/ -#line 63 "../../asn1/sabp/packet-sabp-template.c" +#line 66 "../../asn1/sabp/packet-sabp-template.c" /* Global variables */ static guint32 ProcedureCode; @@ -477,8 +480,16 @@ dissect_sabp_Available_Bandwidth(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t * static int dissect_sabp_Broadcast_Message_Content(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 211 "../../asn1/sabp/sabp.cnf" + tvbuff_t *parameter_tvb=NULL; + offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, - 1, 9968, FALSE, NULL); + 1, 9968, FALSE, ¶meter_tvb); + + if (!parameter_tvb) + return offset; + dissect_umts_cell_broadcast_message(parameter_tvb, actx->pinfo, proto_tree_get_root(tree)); + return offset; } @@ -660,12 +671,10 @@ dissect_sabp_Data_Coding_Scheme(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *a offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, 8, 8, FALSE, ¶meter_tvb); - if (!parameter_tvb) return offset; subtree = proto_item_add_subtree(actx->created_item, ett_sabp_cbs_data_coding); - sms_encoding = dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree); - + sms_encoding = dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree, 0); @@ -753,8 +762,17 @@ dissect_sabp_Failure_List(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U static int dissect_sabp_Message_Identifier(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 183 "../../asn1/sabp/sabp.cnf" + tvbuff_t *parameter_tvb=NULL; + offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, - 16, 16, FALSE, NULL); + 16, 16, FALSE, ¶meter_tvb); + + if (!parameter_tvb) + return offset; + dissect_cbs_message_identifier(parameter_tvb, tree, 0); + + return offset; } @@ -763,8 +781,19 @@ dissect_sabp_Message_Identifier(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *a static int dissect_sabp_Serial_Number(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 191 "../../asn1/sabp/sabp.cnf" + tvbuff_t *parameter_tvb=NULL; + proto_tree *subtree; + offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, - 16, 16, FALSE, NULL); + 16, 16, FALSE, ¶meter_tvb); + + if (!parameter_tvb) + return offset; + subtree = proto_item_add_subtree(actx->created_item, ett_sabp_cbs_serial_number); + dissect_cbs_serial_number(parameter_tvb, subtree, 0); + + return offset; } @@ -773,8 +802,19 @@ dissect_sabp_Serial_Number(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _ static int dissect_sabp_New_Serial_Number(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 201 "../../asn1/sabp/sabp.cnf" + tvbuff_t *parameter_tvb=NULL; + proto_tree *subtree; + offset = dissect_sabp_Serial_Number(tvb, offset, actx, tree, hf_index); + if (!parameter_tvb) + return offset; + subtree = proto_item_add_subtree(actx->created_item, ett_sabp_cbs_new_serial_number); + dissect_cbs_serial_number(parameter_tvb, subtree, 0); + + + return offset; } @@ -1682,7 +1722,7 @@ static int dissect_SABP_PDU_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto /*--- End of included file: packet-sabp-fn.c ---*/ -#line 87 "../../asn1/sabp/packet-sabp-template.c" +#line 90 "../../asn1/sabp/packet-sabp-template.c" static int dissect_ProtocolIEFieldValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { @@ -2093,7 +2133,7 @@ void proto_register_sabp(void) { "UnsuccessfulOutcome_value", HFILL }}, /*--- End of included file: packet-sabp-hfarr.c ---*/ -#line 177 "../../asn1/sabp/packet-sabp-template.c" +#line 180 "../../asn1/sabp/packet-sabp-template.c" }; /* List of subtrees */ @@ -2102,6 +2142,8 @@ void proto_register_sabp(void) { &ett_sabp_e212, &ett_sabp_cbs_data_coding, &ett_sabp_bcast_msg, + &ett_sabp_cbs_serial_number, + &ett_sabp_cbs_new_serial_number, /*--- Included file: packet-sabp-ettarr.c ---*/ #line 1 "../../asn1/sabp/packet-sabp-ettarr.c" @@ -2146,7 +2188,7 @@ void proto_register_sabp(void) { &ett_sabp_UnsuccessfulOutcome, /*--- End of included file: packet-sabp-ettarr.c ---*/ -#line 186 "../../asn1/sabp/packet-sabp-template.c" +#line 191 "../../asn1/sabp/packet-sabp-template.c" }; @@ -2229,7 +2271,7 @@ proto_reg_handoff_sabp(void) /*--- End of included file: packet-sabp-dis-tab.c ---*/ -#line 223 "../../asn1/sabp/packet-sabp-template.c" +#line 228 "../../asn1/sabp/packet-sabp-template.c" } |