2012-01-26 19:51:48 +00:00
/* packet-gsm_cbch.c
* Routines for GSM CBCH dissection - A . K . A . 3 GPP 44.012 ( GSM 04.12 )
*
* 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
2012-06-28 23:18:38 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
2012-01-26 19:51:48 +00:00
*/
2012-03-16 15:33:12 +00:00
# include "config.h"
2012-01-26 19:51:48 +00:00
# include <epan/packet.h>
# include <epan/reassemble.h>
2015-08-12 13:01:45 +00:00
# include <epan/expert.h>
2012-01-26 19:51:48 +00:00
2013-12-15 23:44:12 +00:00
void proto_register_gsm_cbch ( void ) ;
void proto_reg_handoff_gsm_cbch ( void ) ;
2012-01-26 19:51:48 +00:00
# define CBCH_FRAGMENT_SIZE 22
const value_string block_type_lpd_strings [ ] = {
2012-03-16 15:33:12 +00:00
{ 0x00 , " NOT Cell Broadcast " } ,
{ 0x01 , " Cell Broadcast " } ,
{ 0x02 , " NOT Cell Broadcast " } ,
{ 0x03 , " NOT Cell Broadcast " } ,
{ 0 , NULL }
2012-01-26 19:51:48 +00:00
} ;
const value_string block_type_seq_num_values [ ] = {
2012-03-16 15:33:12 +00:00
{ 0x00 , " First Block " } ,
{ 0x01 , " Second Block " } ,
{ 0x02 , " Third Block " } ,
{ 0x03 , " Fourth Block " } ,
{ 0x08 , " First Schedule Block " } ,
{ 0xFF , " Null message " } ,
{ 0 , NULL }
2012-01-26 19:51:48 +00:00
} ;
const value_string sched_type_values [ ] = {
2012-03-16 15:33:12 +00:00
{ 0x00 , " messages formatted as specified in subclause 3.5 of 3GPP 44.012 " } ,
{ 0xFF , " Unknown schedule message format " } ,
{ 0 , NULL }
2012-01-26 19:51:48 +00:00
} ;
/* 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 ;
2012-03-16 15:33:12 +00:00
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 ;
2013-12-19 22:18:30 +00:00
static int hf_gsm_cbch_slot = - 1 ;
2013-01-31 17:55:31 +00:00
/* static int hf_gsm_cbch_sched_msg_id = -1; */
2015-08-12 13:01:45 +00:00
static int hf_gsm_cbch_padding = - 1 ;
static int hf_gsm_cbch_block = - 1 ;
2012-01-26 19:51:48 +00:00
/* These fields are used when reassembling cbch fragments
2012-03-16 15:33:12 +00:00
*/
static int hf_cbch_fragments = - 1 ;
static int hf_cbch_fragment = - 1 ;
static int hf_cbch_fragment_overlap = - 1 ;
2012-01-26 19:51:48 +00:00
static int hf_cbch_fragment_overlap_conflict = - 1 ;
2012-03-16 15:33:12 +00:00
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 ;
2012-01-26 19:51:48 +00:00
/* Initialize the subtree pointers */
static gint ett_cbch_msg = - 1 ;
static gint ett_schedule_msg = - 1 ;
static gint ett_schedule_new_msg = - 1 ;
2012-03-16 15:33:12 +00:00
static gint ett_cbch_fragment = - 1 ;
static gint ett_cbch_fragments = - 1 ;
2012-01-26 19:51:48 +00:00
2015-08-12 13:01:45 +00:00
static expert_field ei_gsm_cbch_sched_end_slot = EI_INIT ;
static expert_field ei_gsm_cbch_seq_num_null = EI_INIT ;
static expert_field ei_gsm_cbch_seq_num_reserved = EI_INIT ;
static expert_field ei_gsm_cbch_lpd = EI_INIT ;
2012-01-26 19:51:48 +00:00
static dissector_handle_t cbs_handle ;
/* reassembly of CHCH blocks */
2013-03-22 23:59:54 +00:00
static reassembly_table cbch_block_reassembly_table ;
2012-01-26 19:51:48 +00:00
/* Structure needed for the fragmentation routines in reassemble.c
2012-03-16 15:33:12 +00:00
*/
2012-01-26 19:51:48 +00:00
static const fragment_items cbch_frag_items = {
2012-03-16 15:33:12 +00:00
& 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 ,
2012-09-07 02:09:59 +00:00
/* Reassembled data field */
NULL ,
2012-03-16 15:33:12 +00:00
" blocks "
2012-01-26 19:51:48 +00:00
} ;
2015-08-12 13:01:45 +00:00
static const range_string gsm_cbch_sched_begin_slot_rvals [ ] = {
{ 0 , 0 , " Out of range (ignoring message) " } ,
{ 1 , 1 , " (apparently) Scheduled Scheduling Message " } ,
{ 2 , 48 , " (apparently) Unscheduled Scheduling Message " } ,
{ 49 , 0xFF , " Out of range (ignoring message) " } ,
{ 0x00 , 0x00 , NULL } ,
} ;
2012-03-16 15:33:12 +00:00
static void
dissect_schedule_message ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * top_tree )
2012-01-26 19:51:48 +00:00
{
2014-08-21 22:44:07 +00:00
guint len , offset = 0 ;
guint8 octet1 , i , k = 0 ;
2013-06-01 23:56:32 +00:00
guint8 sched_begin , sched_end , new_slots [ 48 ] ;
2012-03-16 15:33:12 +00:00
gboolean valid_message = TRUE ;
guint16 other_slots [ 48 ] ;
proto_item * item = NULL , * schedule_item = NULL ;
proto_tree * sched_tree = NULL , * sched_subtree = NULL ;
2014-08-21 22:44:07 +00:00
len = tvb_reported_length ( tvb ) ;
2012-03-16 15:33:12 +00:00
col_append_str ( pinfo - > cinfo , COL_INFO , " CBCH Schedule Message " ) ;
2014-08-21 22:44:07 +00:00
schedule_item = proto_tree_add_protocol_format ( top_tree , proto_cbch , tvb , 0 , - 1 ,
2012-03-16 15:33:12 +00:00
" 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 ) )
{
2015-08-12 13:01:45 +00:00
proto_item * slot_item ;
2012-03-16 15:33:12 +00:00
sched_begin = octet1 & 0x3F ;
proto_tree_add_item ( sched_tree , hf_gsm_cbch_sched_begin_slot , tvb , offset + + , 1 , ENC_BIG_ENDIAN ) ;
2015-08-12 13:01:45 +00:00
if ( ( sched_begin < 1 ) | | ( sched_begin > 48 ) )
2012-03-16 15:33:12 +00:00
{
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 ) ;
2015-08-12 13:01:45 +00:00
slot_item = proto_tree_add_item ( sched_tree , hf_gsm_cbch_sched_end_slot , tvb , offset + + , 1 , ENC_BIG_ENDIAN ) ;
2012-03-16 15:33:12 +00:00
if ( sched_end < sched_begin )
{
2015-08-12 13:01:45 +00:00
expert_add_info ( pinfo , slot_item , & ei_gsm_cbch_sched_end_slot ) ;
2012-03-16 15:33:12 +00:00
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 + + )
2012-01-26 19:51:48 +00:00
{
2014-08-21 22:44:07 +00:00
guint8 j ;
2012-03-16 15:33:12 +00:00
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 ;
}
}
2012-01-26 19:51:48 +00:00
}
2012-03-16 15:33:12 +00:00
/* print the array of new messages */
2014-06-27 00:33:02 +00:00
sched_subtree = proto_tree_add_subtree_format ( sched_tree , tvb , offset - 6 , 6 , ett_schedule_new_msg , & item ,
" This schedule contains %d slots with new messages " , k ) ;
2012-03-16 15:33:12 +00:00
for ( i = 0 ; i < k ; i + + )
2012-01-26 19:51:48 +00:00
{
2013-11-20 22:34:36 +00:00
DISSECTOR_ASSERT ( new_slots [ i ] < = 48 ) ;
2012-03-16 15:33:12 +00:00
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 ;
2013-12-19 22:18:30 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset , 2 , new_slots [ i ] ,
" %d, Message ID: %d, First transmission of an SMSCB within the Schedule Period " ,
2012-03-16 15:33:12 +00:00
new_slots [ i ] , msg_id ) ;
offset + = 2 ;
other_slots [ new_slots [ i ] - 1 ] = msg_id ;
}
else if ( ( octet1 & 0xC0 ) = = 0 )
{
/* MDT 00 */
2013-10-08 01:09:51 +00:00
if ( octet1 = = 0 )
{
2013-12-19 22:18:30 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , new_slots [ i ] ,
" %d, Repeat of non-existant slot %d " ,
2013-10-08 01:09:51 +00:00
new_slots [ i ] , octet1 ) ;
}
else if ( octet1 < new_slots [ i ] )
2012-03-16 15:33:12 +00:00
{
2013-12-19 22:18:30 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , new_slots [ i ] ,
" %d, Message ID: %d, Repeat of Slot %d " ,
2012-03-16 15:33:12 +00:00
new_slots [ i ] , other_slots [ octet1 - 1 ] , octet1 ) ;
other_slots [ new_slots [ i ] - 1 ] = other_slots [ octet1 - 1 ] ;
}
else
{
2013-12-19 22:18:30 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , new_slots [ i ] ,
" %d, Apparent forward reference to slot %d " ,
2012-03-16 15:33:12 +00:00
new_slots [ i ] , octet1 ) ;
}
}
else if ( octet1 = = 0x40 )
{
/* MDT 010000000 */
2016-03-28 14:30:55 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , new_slots [ i ] ,
" %d Free Message Slot, optional reading " , new_slots [ i ] ) ;
2012-03-16 15:33:12 +00:00
other_slots [ new_slots [ i ] - 1 ] = 0xFFFE ;
}
else if ( octet1 = = 0x41 )
{
/* MDT 010000001 */
2016-03-28 14:30:55 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , new_slots [ i ] ,
" %d Free Message Slot, reading advised " , new_slots [ i ] ) ;
2012-03-16 15:33:12 +00:00
other_slots [ new_slots [ i ] - 1 ] = 0xFFFE ;
}
else
{
/* reserved MDT */
2016-03-28 14:30:55 +00:00
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset , 1 , new_slots [ i ] ,
" %d reserved MDT: %x " , new_slots [ i ] , octet1 ) ;
2012-03-16 15:33:12 +00:00
other_slots [ new_slots [ i ] - 1 ] = 0xFFFE ;
}
2012-01-26 19:51:48 +00:00
}
2012-03-16 15:33:12 +00:00
proto_item_set_end ( item , tvb , offset ) ;
2012-01-26 19:51:48 +00:00
2012-03-16 15:33:12 +00:00
/* print schedule of other messages */
2014-06-27 00:33:02 +00:00
sched_subtree = proto_tree_add_subtree ( sched_tree , tvb , offset , 0 ,
ett_schedule_new_msg , & item , " Other message slots in this schedule " ) ;
2014-08-21 22:44:07 +00:00
for ( k = 0 ; offset < len ; )
2012-01-26 19:51:48 +00:00
{
2013-10-15 13:05:31 +00:00
/* XXX I don't know if a message can validly contain more than
* 48 slots , but that ' s the size of the array we create so cap
* it there to avoid uninitialized memory errors ( see bug
* https : //bugs.wireshark.org/bugzilla/show_bug.cgi?id=9270) */
if ( sched_end > 48 )
sched_end = 48 ;
while ( ( k < sched_end ) & & ( other_slots [ k ] ! = 0xFFFF ) )
2012-03-16 15:33:12 +00:00
{
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 ;
2013-12-19 22:18:30 +00:00
k + + ;
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset , 2 , k ,
" %d, Message: %d, First transmission of an SMSCB within the Schedule Period " ,
k , msg_id ) ;
2012-03-16 15:33:12 +00:00
offset + = 2 ;
}
2013-06-01 23:56:32 +00:00
else
{
/* I'm not sure what's supposed to be dissected in this
* case . Perhaps just an expert info is appropriate ?
* Regardless , we need to increment k to prevent an
* infinite loop , see
* https : //bugs.wireshark.org/bugzilla/show_bug.cgi?id=8730
*/
+ + k ;
}
2012-03-16 15:33:12 +00:00
}
2013-12-11 12:54:10 +00:00
else if ( octet1 & & ( ( octet1 & 0xC0 ) = = 0 ) )
2012-03-16 15:33:12 +00:00
{
/* MDT 00 */
if ( octet1 < k )
{
other_slots [ k ] = other_slots [ octet1 - 1 ] ;
2013-12-19 22:18:30 +00:00
k + + ;
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , k ,
" %d, Message ID: %d, Repeat of Slot %d " ,
k , other_slots [ octet1 - 1 ] , octet1 ) ;
2012-03-16 15:33:12 +00:00
}
else
{
2013-12-19 22:18:30 +00:00
k + + ;
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , k ,
" %d, Apparent forward reference to slot %d " ,
k , octet1 ) ;
2012-03-16 15:33:12 +00:00
}
}
else if ( octet1 = = 0x40 )
{
/* MDT 010000000 */
2013-12-19 22:18:30 +00:00
k + + ;
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , k ,
" %d Free Message Slot, optional reading " , k ) ;
2012-03-16 15:33:12 +00:00
}
else if ( octet1 = = 0x41 )
{
/* MDT 010000001 */
2013-12-19 22:18:30 +00:00
k + + ;
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset + + , 1 , k ,
" %d Free Message Slot, reading advised " , k ) ;
2012-03-16 15:33:12 +00:00
}
else
{
/* reserved MDT */
2013-12-19 22:18:30 +00:00
k + + ;
proto_tree_add_uint_format_value ( sched_subtree , hf_gsm_cbch_slot , tvb , offset , 1 , k ,
" %d reserved MDT: %x " , k , octet1 ) ;
2012-03-16 15:33:12 +00:00
}
2012-01-26 19:51:48 +00:00
}
2012-03-16 15:33:12 +00:00
proto_item_set_end ( item , tvb , offset ) ;
2015-08-12 13:01:45 +00:00
proto_tree_add_item ( sched_tree , hf_gsm_cbch_padding , tvb , offset , - 1 , ENC_NA ) ;
2012-03-16 15:33:12 +00:00
}
}
2012-01-26 19:51:48 +00:00
}
2015-11-14 01:18:34 +00:00
static int
dissect_cbch ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2012-01-26 19:51:48 +00:00
{
2013-07-17 21:12:24 +00:00
fragment_head * frag_data = NULL ;
2012-03-16 15:33:12 +00:00
guint8 octet , lb , lpd , seq_num ;
guint32 offset ;
2015-08-12 13:01:45 +00:00
proto_item * cbch_item , * lpd_item , * seq_item ;
2014-08-21 22:44:07 +00:00
proto_tree * cbch_tree ;
2012-03-16 15:33:12 +00:00
tvbuff_t * reass_tvb = NULL , * msg_tvb = NULL ;
offset = 0 ;
octet = tvb_get_guint8 ( tvb , offset ) ;
/*
* create the protocol tree
*/
2014-08-21 22:44:07 +00:00
cbch_item = proto_tree_add_protocol_format ( tree , proto_cbch , tvb , 0 , - 1 ,
2012-03-16 15:33:12 +00:00
" 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 ) ;
2015-08-12 13:01:45 +00:00
proto_tree_add_uint ( cbch_tree , hf_gsm_cbch_block , tvb , offset , 1 , octet ) ;
2012-03-16 15:33:12 +00:00
proto_tree_add_uint ( cbch_tree , hf_gsm_cbch_spare_bit , tvb , offset , 1 , octet ) ;
2015-08-12 13:01:45 +00:00
lpd_item = proto_tree_add_uint ( cbch_tree , hf_gsm_cbch_lpd , tvb , offset , 1 , octet ) ;
2012-03-16 15:33:12 +00:00
proto_tree_add_uint ( cbch_tree , hf_gsm_cbch_lb , tvb , offset , 1 , octet ) ;
2015-08-12 13:01:45 +00:00
seq_item = proto_tree_add_uint ( cbch_tree , hf_gsm_cbch_seq_num , tvb , offset , 1 , octet ) ;
2012-03-16 15:33:12 +00:00
seq_num = octet & 0x0F ;
lpd = ( octet & 0x60 ) > > 5 ;
lb = ( octet & 0x10 ) > > 4 ;
if ( lpd = = 1 )
{
switch ( seq_num )
{
case 0x00 :
case 0x08 :
2012-01-26 19:51:48 +00:00
pinfo - > fragmented = TRUE ;
/* we should have a unique ID for the reassembled page, but we don't really have anything from the protocol...
2012-03-16 15:33:12 +00:00
The GSM frame number div 4 might be used for this , but it has not been passed to this layer and does not
2012-01-26 19:51:48 +00:00
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 */
2013-03-22 23:59:54 +00:00
frag_data = fragment_add_seq_check ( & cbch_block_reassembly_table ,
tvb , offset , pinfo , 0 , NULL ,
2012-01-26 19:51:48 +00:00
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 ;
2012-03-16 15:33:12 +00:00
case 0x01 :
case 0x02 :
case 0x03 :
2012-01-26 19:51:48 +00:00
pinfo - > fragmented = TRUE ;
offset + + ; /* step to beginning of payload */
2013-03-22 23:59:54 +00:00
frag_data = fragment_add_seq_check ( & cbch_block_reassembly_table ,
tvb , offset , pinfo , 0 , NULL ,
seq_num , CBCH_FRAGMENT_SIZE , ! lb ) ;
2012-01-26 19:51:48 +00:00
reass_tvb = process_reassembled_data ( tvb , offset , pinfo , " Reassembled CBCH message " ,
frag_data , & cbch_frag_items , NULL , cbch_tree ) ;
break ;
2012-03-16 15:33:12 +00:00
case 0x0F :
2015-08-12 13:01:45 +00:00
expert_add_info ( pinfo , seq_item , & ei_gsm_cbch_seq_num_null ) ;
2016-03-20 00:33:14 +00:00
call_data_dissector ( tvb , pinfo , cbch_tree ) ;
2012-01-26 19:51:48 +00:00
break ;
2012-03-16 15:33:12 +00:00
default :
2015-08-12 13:01:45 +00:00
expert_add_info ( pinfo , seq_item , & ei_gsm_cbch_seq_num_reserved ) ;
2016-03-20 00:33:14 +00:00
call_data_dissector ( tvb , pinfo , cbch_tree ) ;
2012-01-26 19:51:48 +00:00
break ;
2012-03-16 15:33:12 +00:00
}
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
{
2015-08-12 13:01:45 +00:00
expert_add_info ( pinfo , lpd_item , & ei_gsm_cbch_lpd ) ;
2016-03-20 00:33:14 +00:00
call_data_dissector ( tvb , pinfo , cbch_tree ) ;
2012-03-16 15:33:12 +00:00
}
2015-11-14 01:18:34 +00:00
return tvb_captured_length ( tvb ) ;
2012-01-26 19:51:48 +00:00
}
/* Register the protocol with Wireshark */
void
proto_register_gsm_cbch ( void )
{
2012-03-16 15:33:12 +00:00
/* Setup list of header fields */
static hf_register_info hf_smscb [ ] =
{
{ & hf_gsm_cbch_spare_bit ,
2012-07-31 18:54:11 +00:00
{ " GSM CBCH spare bit " , " gsm_cbch.block_type.spare " ,
2012-03-16 15:33:12 +00:00
FT_UINT8 , BASE_HEX , NULL , 0x80 ,
NULL , HFILL }
} ,
{ & hf_gsm_cbch_lpd ,
2012-07-31 18:54:11 +00:00
{ " GSM CBCH Link Protocol Discriminator " , " gsm_cbch.block_type.lpd " ,
2012-03-16 15:33:12 +00:00
FT_UINT8 , BASE_DEC , VALS ( block_type_lpd_strings ) , 0x60 ,
NULL , HFILL }
} ,
{ & hf_gsm_cbch_lb ,
2012-07-31 18:54:11 +00:00
{ " GSM CBCH Last Block " , " gsm_cbch.block_type.lb " ,
2012-03-16 15:33:12 +00:00
FT_UINT8 , BASE_DEC , NULL , 0x10 ,
NULL , HFILL }
} ,
{ & hf_gsm_cbch_seq_num ,
2012-07-31 18:54:11 +00:00
{ " GSM CBCH Sequence Number " , " gsm_cbch.block_type.seq_num " ,
2012-03-16 15:33:12 +00:00
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 " ,
2015-08-12 13:01:45 +00:00
FT_UINT8 , BASE_DEC | BASE_RANGE_STRING , RVALS ( gsm_cbch_sched_begin_slot_rvals ) , 0x3F ,
2012-03-16 15:33:12 +00:00
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 }
} ,
2013-12-19 22:18:30 +00:00
{ & hf_gsm_cbch_slot ,
{ " Slot " , " gsm_cbch.slot " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
NULL , HFILL }
} ,
2015-08-12 13:01:45 +00:00
{ & hf_gsm_cbch_padding ,
{ " Padding " , " gsm_cbch.padding " ,
FT_BYTES , BASE_NONE , NULL , 0x0 ,
NULL , HFILL }
} ,
{ & hf_gsm_cbch_block ,
{ " CBCH Block " , " gsm_cbch.block " ,
FT_UINT8 , BASE_HEX , NULL , 0x0 ,
NULL , HFILL }
} ,
2013-01-31 17:55:31 +00:00
#if 0
2012-03-16 15:33:12 +00:00
{ & hf_gsm_cbch_sched_msg_id ,
{ " GSM CBCH Schedule Message ID " , " gsm_cbch.sched_msg_id " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
NULL , HFILL }
} ,
2013-01-31 17:55:31 +00:00
# endif
2012-03-16 15:33:12 +00:00
/* 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
}
}
} ;
2012-01-26 19:51:48 +00:00
/* Setup protocol subtree array */
2012-03-16 15:33:12 +00:00
static gint * ett [ ] = {
& ett_cbch_msg ,
& ett_schedule_msg ,
& ett_schedule_new_msg ,
& ett_cbch_fragment ,
& ett_cbch_fragments ,
} ;
2015-08-12 13:01:45 +00:00
expert_module_t * expert_cbch ;
static ei_register_info ei [ ] = {
{ & ei_gsm_cbch_sched_end_slot , { " gsm_cbch.sched_end.bad_range " , PI_PROTOCOL , PI_WARN , " End Slot Number less than Begin Slot Number: ignoring message " , EXPFILL } } ,
{ & ei_gsm_cbch_seq_num_null , { " gsm_cbch.block_type.seq_num.null " , PI_PROTOCOL , PI_NOTE , " NULL message " , EXPFILL } } ,
{ & ei_gsm_cbch_seq_num_reserved , { " gsm_cbch.block_type.seq_num.reserved " , PI_PROTOCOL , PI_NOTE , " Reserved Sequence Number " , EXPFILL } } ,
{ & ei_gsm_cbch_lpd , { " gsm_cbch.block_type.lpd.invalid " , PI_PROTOCOL , PI_WARN , " Invalid Link Protocol Discriminator " , EXPFILL } } ,
} ;
2012-03-16 15:33:12 +00:00
/* 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 ) ) ;
2015-08-12 13:01:45 +00:00
expert_cbch = expert_register_protocol ( proto_cbch ) ;
expert_register_field_array ( expert_cbch , ei , array_length ( ei ) ) ;
2012-03-16 15:33:12 +00:00
/* subdissector code */
2015-12-09 04:04:01 +00:00
register_dissector ( " gsm_cbch " , dissect_cbch , proto_cbch ) ;
2017-01-29 00:53:36 +00:00
reassembly_table_register ( & cbch_block_reassembly_table ,
& addresses_reassembly_table_functions ) ;
2012-03-16 15:33:12 +00:00
/* subtree array */
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2012-01-26 19:51:48 +00:00
}
void
proto_reg_handoff_gsm_cbch ( void )
{
2016-03-16 13:02:52 +00:00
cbs_handle = find_dissector_add_dependency ( " gsm_cbs " , proto_cbch ) ;
2012-01-26 19:51:48 +00:00
}
2014-08-21 22:44:07 +00:00
/*
* Editor modelines - http : //www.wireshark.org/tools/modelines.html
*
* Local variables :
* c - basic - offset : 4
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* vi : set shiftwidth = 4 tabstop = 8 expandtab :
* : indentSize = 4 : tabSize = 8 : noTabs = true :
*/