2007-12-16 13:34:33 +00:00
/* packet-s1ap.c
2008-01-03 14:35:45 +00:00
* Routines for E - UTRAN S1 Application Protocol ( S1AP ) packet dissection
2010-04-12 19:35:51 +00:00
* Copyright 2007 - 2010 , Anders Broman < anders . broman @ ericsson . com >
2007-12-16 13:34:33 +00:00
*
2008-02-08 09:45:36 +00:00
* $ Id $
2007-12-16 13:34:33 +00:00
*
* 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 22:56:06 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
2007-12-16 13:34:33 +00:00
*
* Based on the RANAP dissector
*
2010-04-12 19:35:51 +00:00
* References : 3 GPP TS 36.413 V9 .2 .0 ( 2010 - 03 )
2007-12-16 13:34:33 +00:00
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include <glib.h>
# include <epan/packet.h>
2008-07-10 18:35:11 +00:00
# include <ctype.h>
2007-12-16 13:34:33 +00:00
# include <epan/strutil.h>
# include <epan/asn1.h>
2008-06-20 16:20:10 +00:00
# include <epan/prefs.h>
2009-03-03 18:25:25 +00:00
# include <epan/sctpppids.h>
2007-12-16 13:34:33 +00:00
# include "packet-ber.h"
# include "packet-per.h"
# include "packet-e212.h"
# include "packet-sccp.h"
2009-11-08 19:59:21 +00:00
# include "packet-lte-rrc.h"
2011-12-08 19:32:51 +00:00
# include "packet-ranap.h"
2011-12-08 21:17:03 +00:00
# include "packet-bssgp.h"
# include "packet-s1ap.h"
2007-12-16 13:34:33 +00:00
# ifdef _MSC_VER
/* disable: "warning C4146: unary minus operator applied to unsigned type, result still unsigned" */
# pragma warning(disable:4146)
# endif
2009-07-07 11:37:15 +00:00
# define PNAME "S1 Application Protocol"
2007-12-16 13:34:33 +00:00
# define PSNAME "S1AP"
# define PFNAME "s1ap"
2010-03-31 08:51:29 +00:00
/* Dissector will use SCTP PPID 18 or SCTP port. IANA assigned port = 36412 */
# define SCTP_PORT_S1AP 36412
2008-06-20 16:20:10 +00:00
2009-01-13 18:34:49 +00:00
static dissector_handle_t nas_eps_handle ;
2011-10-23 18:05:07 +00:00
static dissector_handle_t lppa_handle ;
2011-11-04 17:37:38 +00:00
static dissector_handle_t bssgp_handle ;
2008-11-16 12:35:42 +00:00
2007-12-16 13:34:33 +00:00
# include "packet-s1ap-val.h"
/* Initialize the protocol and registered fields */
static int proto_s1ap = - 1 ;
2009-03-23 17:31:50 +00:00
static int hf_s1ap_transportLayerAddressIPv4 = - 1 ;
static int hf_s1ap_transportLayerAddressIPv6 = - 1 ;
2007-12-16 13:34:33 +00:00
# include "packet-s1ap-hf.c"
/* Initialize the subtree pointers */
static int ett_s1ap = - 1 ;
2009-03-23 17:31:50 +00:00
static int ett_s1ap_TransportLayerAddress = - 1 ;
2009-11-08 19:59:21 +00:00
static int ett_s1ap_ToTargetTransparentContainer = - 1 ;
static int ett_s1ap_ToSourceTransparentContainer = - 1 ;
static int ett_s1ap_RRCContainer = - 1 ;
2010-06-23 04:50:52 +00:00
static int ett_s1ap_UERadioCapability = - 1 ;
2011-11-04 17:37:38 +00:00
static int ett_s1ap_RIMInformation = - 1 ;
2007-12-16 13:34:33 +00:00
# include "packet-s1ap-ett.c"
2009-11-08 19:59:21 +00:00
enum {
INITIATING_MESSAGE ,
SUCCESSFUL_OUTCOME ,
UNSUCCESSFUL_OUTCOME
} ;
2007-12-16 13:34:33 +00:00
/* Global variables */
static guint32 ProcedureCode ;
static guint32 ProtocolIE_ID ;
static guint32 ProtocolExtensionID ;
2008-06-20 16:20:10 +00:00
static guint gbl_s1apSctpPort = SCTP_PORT_S1AP ;
2009-11-05 20:34:56 +00:00
static guint32 handover_type_value ;
2009-11-08 19:59:21 +00:00
static guint32 message_type ;
2012-02-09 22:17:42 +00:00
static gboolean g_s1ap_dissect_container = TRUE ;
2007-12-16 13:34:33 +00:00
/* Dissector tables */
static dissector_table_t s1ap_ies_dissector_table ;
static dissector_table_t s1ap_ies_p1_dissector_table ;
static dissector_table_t s1ap_ies_p2_dissector_table ;
static dissector_table_t s1ap_extension_dissector_table ;
static dissector_table_t s1ap_proc_imsg_dissector_table ;
static dissector_table_t s1ap_proc_sout_dissector_table ;
static dissector_table_t s1ap_proc_uout_dissector_table ;
static int dissect_ProtocolIEFieldValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
2008-10-14 19:07:26 +00:00
/* Currently not used
2007-12-16 13:34:33 +00:00
static int dissect_ProtocolIEFieldPairFirstValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_ProtocolIEFieldPairSecondValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
2008-10-14 19:07:26 +00:00
*/
2007-12-16 13:34:33 +00:00
static int dissect_ProtocolExtensionFieldExtensionValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_InitiatingMessageValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_SuccessfulOutcomeValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_UnsuccessfulOutcomeValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
2009-11-08 19:59:21 +00:00
static int dissect_SourceeNB_ToTargeteNB_TransparentContainer_PDU ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_TargeteNB_ToSourceeNB_TransparentContainer_PDU ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
2011-12-09 03:00:56 +00:00
#if 0
2009-11-08 19:59:21 +00:00
static int dissect_SourceRNC_ToTargetRNC_TransparentContainer_PDU ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_TargetRNC_ToSourceRNC_TransparentContainer_PDU ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_SourceBSS_ToTargetBSS_TransparentContainer_PDU ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
static int dissect_TargetBSS_ToSourceBSS_TransparentContainer_PDU ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ) ;
2011-12-09 03:00:56 +00:00
# endif
2009-11-05 20:34:56 +00:00
2007-12-16 13:34:33 +00:00
# include "packet-s1ap-fn.c"
static int dissect_ProtocolIEFieldValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_ies_dissector_table , ProtocolIE_ID , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
2008-10-14 19:07:26 +00:00
/* Currently not used
2007-12-16 13:34:33 +00:00
static int dissect_ProtocolIEFieldPairFirstValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_ies_p1_dissector_table , ProtocolIE_ID , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
static int dissect_ProtocolIEFieldPairSecondValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_ies_p2_dissector_table , ProtocolIE_ID , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
2008-10-14 19:07:26 +00:00
*/
2007-12-16 13:34:33 +00:00
static int dissect_ProtocolExtensionFieldExtensionValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_extension_dissector_table , ProtocolExtensionID , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
static int dissect_InitiatingMessageValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_proc_imsg_dissector_table , ProcedureCode , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
static int dissect_SuccessfulOutcomeValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_proc_sout_dissector_table , ProcedureCode , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
static int dissect_UnsuccessfulOutcomeValue ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2010-12-20 05:35:29 +00:00
return ( dissector_try_uint ( s1ap_proc_uout_dissector_table , ProcedureCode , tvb , pinfo , tree ) ) ? tvb_length ( tvb ) : 0 ;
2007-12-16 13:34:33 +00:00
}
static void
dissect_s1ap ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
proto_item * s1ap_item = NULL ;
proto_tree * s1ap_tree = NULL ;
/* make entry in the Protocol column on summary display */
2009-08-09 06:26:46 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " S1AP " ) ;
2007-12-16 13:34:33 +00:00
/* create the s1ap protocol tree */
2011-10-21 02:10:19 +00:00
s1ap_item = proto_tree_add_item ( tree , proto_s1ap , tvb , 0 , - 1 , ENC_NA ) ;
2007-12-16 13:34:33 +00:00
s1ap_tree = proto_item_add_subtree ( s1ap_item , ett_s1ap ) ;
2011-10-21 02:10:19 +00:00
2007-12-16 13:34:33 +00:00
dissect_S1AP_PDU_PDU ( tvb , pinfo , s1ap_tree ) ;
}
2008-06-20 16:20:10 +00:00
/*--- proto_reg_handoff_s1ap ---------------------------------------*/
void
proto_reg_handoff_s1ap ( void )
{
2008-11-04 22:01:35 +00:00
static gboolean Initialized = FALSE ;
static dissector_handle_t s1ap_handle ;
static guint SctpPort ;
2008-06-20 16:20:10 +00:00
2010-03-31 08:51:29 +00:00
s1ap_handle = find_dissector ( " s1ap " ) ;
2008-06-20 16:20:10 +00:00
if ( ! Initialized ) {
2009-01-13 18:34:49 +00:00
nas_eps_handle = find_dissector ( " nas-eps " ) ;
2011-10-23 18:05:07 +00:00
lppa_handle = find_dissector ( " lppa " ) ;
2011-11-04 17:37:38 +00:00
bssgp_handle = find_dissector ( " bssgp " ) ;
2008-11-05 21:43:05 +00:00
dissector_add_handle ( " sctp.port " , s1ap_handle ) ; /* for "decode-as" */
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " sctp.ppi " , S1AP_PAYLOAD_PROTOCOL_ID , s1ap_handle ) ;
2008-06-20 16:20:10 +00:00
Initialized = TRUE ;
2008-11-04 22:01:35 +00:00
# include "packet-s1ap-dis-tab.c"
2008-06-20 16:20:10 +00:00
} else {
2008-11-05 21:43:05 +00:00
if ( SctpPort ! = 0 ) {
2010-12-20 05:35:29 +00:00
dissector_delete_uint ( " sctp.port " , SctpPort , s1ap_handle ) ;
2008-11-05 21:43:05 +00:00
}
2008-06-20 16:20:10 +00:00
}
SctpPort = gbl_s1apSctpPort ;
2008-11-05 21:43:05 +00:00
if ( SctpPort ! = 0 ) {
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " sctp.port " , SctpPort , s1ap_handle ) ;
2008-11-05 21:43:05 +00:00
}
2008-06-20 16:20:10 +00:00
}
2007-12-16 13:34:33 +00:00
/*--- proto_register_s1ap -------------------------------------------*/
void proto_register_s1ap ( void ) {
/* List of fields */
static hf_register_info hf [ ] = {
2009-03-23 17:31:50 +00:00
{ & hf_s1ap_transportLayerAddressIPv4 ,
{ " transportLayerAddress(IPv4) " , " s1ap.transportLayerAddressIPv4 " ,
2009-06-23 06:02:12 +00:00
FT_IPv4 , BASE_NONE , NULL , 0 ,
2009-03-23 17:31:50 +00:00
NULL , HFILL } } ,
{ & hf_s1ap_transportLayerAddressIPv6 ,
{ " transportLayerAddress(IPv6) " , " s1ap.transportLayerAddressIPv6 " ,
2011-10-06 19:07:26 +00:00
FT_IPv6 , BASE_NONE , NULL , 0 ,
2009-03-23 17:31:50 +00:00
NULL , HFILL } } ,
2007-12-16 13:34:33 +00:00
# include "packet-s1ap-hfarr.c"
} ;
/* List of subtrees */
static gint * ett [ ] = {
& ett_s1ap ,
2009-03-23 17:31:50 +00:00
& ett_s1ap_TransportLayerAddress ,
2009-11-08 19:59:21 +00:00
& ett_s1ap_ToTargetTransparentContainer ,
& ett_s1ap_ToSourceTransparentContainer ,
& ett_s1ap_RRCContainer ,
2010-06-23 04:50:52 +00:00
& ett_s1ap_UERadioCapability ,
2011-11-04 17:37:38 +00:00
& ett_s1ap_RIMInformation ,
2007-12-16 13:34:33 +00:00
# include "packet-s1ap-ettarr.c"
} ;
2008-06-20 16:20:10 +00:00
module_t * s1ap_module ;
2007-12-16 13:34:33 +00:00
/* Register protocol */
proto_s1ap = proto_register_protocol ( PNAME , PSNAME , PFNAME ) ;
/* Register fields and subtrees */
proto_register_field_array ( proto_s1ap , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2011-10-21 02:10:19 +00:00
2007-12-16 13:34:33 +00:00
/* Register dissector */
register_dissector ( " s1ap " , dissect_s1ap , proto_s1ap ) ;
/* Register dissector tables */
s1ap_ies_dissector_table = register_dissector_table ( " s1ap.ies " , " S1AP-PROTOCOL-IES " , FT_UINT32 , BASE_DEC ) ;
s1ap_ies_p1_dissector_table = register_dissector_table ( " s1ap.ies.pair.first " , " S1AP-PROTOCOL-IES-PAIR FirstValue " , FT_UINT32 , BASE_DEC ) ;
s1ap_ies_p2_dissector_table = register_dissector_table ( " s1ap.ies.pair.second " , " S1AP-PROTOCOL-IES-PAIR SecondValue " , FT_UINT32 , BASE_DEC ) ;
s1ap_extension_dissector_table = register_dissector_table ( " s1ap.extension " , " S1AP-PROTOCOL-EXTENSION " , FT_UINT32 , BASE_DEC ) ;
s1ap_proc_imsg_dissector_table = register_dissector_table ( " s1ap.proc.imsg " , " S1AP-ELEMENTARY-PROCEDURE InitiatingMessage " , FT_UINT32 , BASE_DEC ) ;
s1ap_proc_sout_dissector_table = register_dissector_table ( " s1ap.proc.sout " , " S1AP-ELEMENTARY-PROCEDURE SuccessfulOutcome " , FT_UINT32 , BASE_DEC ) ;
s1ap_proc_uout_dissector_table = register_dissector_table ( " s1ap.proc.uout " , " S1AP-ELEMENTARY-PROCEDURE UnsuccessfulOutcome " , FT_UINT32 , BASE_DEC ) ;
2011-10-21 02:10:19 +00:00
2008-11-04 22:01:35 +00:00
/* Register configuration options for ports */
s1ap_module = prefs_register_protocol ( proto_s1ap , proto_reg_handoff_s1ap ) ;
prefs_register_uint_preference ( s1ap_module , " sctp.port " ,
" S1AP SCTP Port " ,
" Set the SCTP port for S1AP messages " ,
10 ,
& gbl_s1apSctpPort ) ;
2012-02-09 22:17:42 +00:00
prefs_register_bool_preference ( s1ap_module , " dissect_container " , " Dissect TransparentContainer " , " Dissect TransparentContainers that are opaque to S1AP " , & g_s1ap_dissect_container ) ;
2007-12-16 13:34:33 +00:00
}