@ -24,26 +24,22 @@
*
*/
# include <iostream>
# include <cmath>
# include <inttypes.h> // for printing uint64_t
# include "srsepc/hdr/mme/s1ap.h"
# include "srsepc/hdr/mme/s1ap_nas_transport.h"
# include "srslte/common/security.h"
# include "srslte/common/liblte_security.h"
# include "srslte/common/security.h"
# include <cmath>
# include <inttypes.h> // for printing uint64_t
namespace srsepc {
nas : : nas ( ) {
nas : : nas ( )
{
m_pool = srslte : : byte_buffer_pool : : get_instance ( ) ;
}
void
nas : : init ( nas_init_t args ,
s1ap_interface_nas * s1ap ,
gtpc_interface_nas * gtpc ,
hss_interface_nas * hss ,
srslte : : log * nas_log )
void nas : : init (
nas_init_t args , s1ap_interface_nas * s1ap , gtpc_interface_nas * gtpc , hss_interface_nas * hss , srslte : : log * nas_log )
{
m_mcc = args . mcc ;
m_mnc = args . mnc ;
@ -68,8 +64,7 @@ nas::init(nas_init_t args,
* Handle UE Initiating Messages
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool
nas : : handle_attach_request ( uint32_t enb_ue_s1ap_id ,
bool nas : : handle_attach_request ( uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
srslte : : byte_buffer_t * nas_rx ,
nas_init_t args ,
@ -123,35 +118,44 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
nas_log - > console ( " Attach request -- Attach type: %d \n " , attach_req . eps_attach_type ) ;
nas_log - > info ( " Attach request -- Attach type: %d \n " , attach_req . eps_attach_type ) ;
nas_log - > console ( " Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d \n " ,
attach_req . ue_network_cap . eea [ 0 ] , attach_req . ue_network_cap . eea [ 1 ] , attach_req . ue_network_cap . eea [ 2 ] , attach_req . ue_network_cap . eea [ 3 ] ,
attach_req . ue_network_cap . eea [ 4 ] , attach_req . ue_network_cap . eea [ 5 ] , attach_req . ue_network_cap . eea [ 6 ] , attach_req . ue_network_cap . eea [ 7 ] ) ;
nas_log - > info ( " Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d \n " ,
attach_req . ue_network_cap . eea [ 0 ] , attach_req . ue_network_cap . eea [ 1 ] , attach_req . ue_network_cap . eea [ 2 ] , attach_req . ue_network_cap . eea [ 3 ] ,
attach_req . ue_network_cap . eea [ 4 ] , attach_req . ue_network_cap . eea [ 5 ] , attach_req . ue_network_cap . eea [ 6 ] , attach_req . ue_network_cap . eea [ 7 ] ) ;
attach_req . ue_network_cap . eea [ 0 ] , attach_req . ue_network_cap . eea [ 1 ] , attach_req . ue_network_cap . eea [ 2 ] ,
attach_req . ue_network_cap . eea [ 3 ] , attach_req . ue_network_cap . eea [ 4 ] , attach_req . ue_network_cap . eea [ 5 ] ,
attach_req . ue_network_cap . eea [ 6 ] , attach_req . ue_network_cap . eea [ 7 ] ) ;
nas_log - > info ( " Attach Request -- UE Network Capabilities EEA: %d%d%d%d%d%d%d%d \n " , attach_req . ue_network_cap . eea [ 0 ] ,
attach_req . ue_network_cap . eea [ 1 ] , attach_req . ue_network_cap . eea [ 2 ] , attach_req . ue_network_cap . eea [ 3 ] ,
attach_req . ue_network_cap . eea [ 4 ] , attach_req . ue_network_cap . eea [ 5 ] , attach_req . ue_network_cap . eea [ 6 ] ,
attach_req . ue_network_cap . eea [ 7 ] ) ;
nas_log - > console ( " Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d \n " ,
attach_req . ue_network_cap . eia [ 0 ] , attach_req . ue_network_cap . eia [ 1 ] , attach_req . ue_network_cap . eia [ 2 ] , attach_req . ue_network_cap . eia [ 3 ] ,
attach_req . ue_network_cap . eia [ 4 ] , attach_req . ue_network_cap . eia [ 5 ] , attach_req . ue_network_cap . eia [ 6 ] , attach_req . ue_network_cap . eia [ 7 ] ) ;
nas_log - > info ( " Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d \n " ,
attach_req . ue_network_cap . eia [ 0 ] , attach_req . ue_network_cap . eia [ 1 ] , attach_req . ue_network_cap . eia [ 2 ] , attach_req . ue_network_cap . eia [ 3 ] ,
attach_req . ue_network_cap . eia [ 4 ] , attach_req . ue_network_cap . eia [ 5 ] , attach_req . ue_network_cap . eia [ 6 ] , attach_req . ue_network_cap . eia [ 7 ] ) ;
nas_log - > console ( " Attach Request -- MS Network Capabilities Present: %s \n " , attach_req . ms_network_cap_present ? " true " : " false " ) ;
nas_log - > info ( " Attach Request -- MS Network Capabilities Present: %s \n " , attach_req . ms_network_cap_present ? " true " : " false " ) ;
attach_req . ue_network_cap . eia [ 0 ] , attach_req . ue_network_cap . eia [ 1 ] , attach_req . ue_network_cap . eia [ 2 ] ,
attach_req . ue_network_cap . eia [ 3 ] , attach_req . ue_network_cap . eia [ 4 ] , attach_req . ue_network_cap . eia [ 5 ] ,
attach_req . ue_network_cap . eia [ 6 ] , attach_req . ue_network_cap . eia [ 7 ] ) ;
nas_log - > info ( " Attach Request -- UE Network Capabilities EIA: %d%d%d%d%d%d%d%d \n " , attach_req . ue_network_cap . eia [ 0 ] ,
attach_req . ue_network_cap . eia [ 1 ] , attach_req . ue_network_cap . eia [ 2 ] , attach_req . ue_network_cap . eia [ 3 ] ,
attach_req . ue_network_cap . eia [ 4 ] , attach_req . ue_network_cap . eia [ 5 ] , attach_req . ue_network_cap . eia [ 6 ] ,
attach_req . ue_network_cap . eia [ 7 ] ) ;
nas_log - > console ( " Attach Request -- MS Network Capabilities Present: %s \n " ,
attach_req . ms_network_cap_present ? " true " : " false " ) ;
nas_log - > info ( " Attach Request -- MS Network Capabilities Present: %s \n " ,
attach_req . ms_network_cap_present ? " true " : " false " ) ;
nas_log - > console ( " PDN Connectivity Request -- EPS Bearer Identity requested: %d \n " , pdn_con_req . eps_bearer_id ) ;
nas_log - > info ( " PDN Connectivity Request -- EPS Bearer Identity requested: %d \n " , pdn_con_req . eps_bearer_id ) ;
nas_log - > console ( " PDN Connectivity Request -- Procedure Transaction Id: %d \n " , pdn_con_req . proc_transaction_id ) ;
nas_log - > info ( " PDN Connectivity Request -- Procedure Transaction Id: %d \n " , pdn_con_req . proc_transaction_id ) ;
nas_log - > console ( " PDN Connectivity Request -- ESM Information Transfer requested: %s \n " , pdn_con_req . esm_info_transfer_flag_present ? " true " : " false " ) ;
nas_log - > info ( " PDN Connectivity Request -- ESM Information Transfer requested: %s \n " , pdn_con_req . esm_info_transfer_flag_present ? " true " : " false " ) ;
nas_log - > console ( " PDN Connectivity Request -- ESM Information Transfer requested: %s \n " ,
pdn_con_req . esm_info_transfer_flag_present ? " true " : " false " ) ;
nas_log - > info ( " PDN Connectivity Request -- ESM Information Transfer requested: %s \n " ,
pdn_con_req . esm_info_transfer_flag_present ? " true " : " false " ) ;
// Get NAS Context if UE is known
nas * nas_ctx = s1ap - > find_nas_ctx_from_imsi ( imsi ) ;
if ( nas_ctx = = NULL )
{
if ( nas_ctx = = NULL ) {
// Get attach type from attach request
if ( attach_req . eps_mobile_id . type_of_id = = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI ) {
nas : : handle_imsi_attach_request_unknown_ue ( enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , args , s1ap , gtpc , hss , nas_log ) ;
nas : : handle_imsi_attach_request_unknown_ue ( enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , args , s1ap , gtpc ,
hss , nas_log ) ;
} else if ( attach_req . eps_mobile_id . type_of_id = = LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI ) {
nas : : handle_guti_attach_request_unknown_ue ( enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , args , s1ap , gtpc , hss , nas_log ) ;
nas : : handle_guti_attach_request_unknown_ue ( enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , args , s1ap , gtpc ,
hss , nas_log ) ;
} else {
return false ;
}
@ -159,9 +163,11 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
nas_log - > info ( " Attach Request -- Found previously attached UE. \n " ) ;
nas_log - > console ( " Attach Request -- Found previously attach UE. \n " ) ;
if ( attach_req . eps_mobile_id . type_of_id = = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI ) {
nas : : handle_imsi_attach_request_known_ue ( nas_ctx , enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , nas_rx , args , s1ap , gtpc , hss , nas_log ) ;
nas : : handle_imsi_attach_request_known_ue ( nas_ctx , enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , nas_rx , args ,
s1ap , gtpc , hss , nas_log ) ;
} else if ( attach_req . eps_mobile_id . type_of_id = = LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI ) {
nas : : handle_guti_attach_request_known_ue ( nas_ctx , enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , nas_rx , args , s1ap , gtpc , hss , nas_log ) ;
nas : : handle_guti_attach_request_known_ue ( nas_ctx , enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , nas_rx , args ,
s1ap , gtpc , hss , nas_log ) ;
} else {
return false ;
}
@ -169,8 +175,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id,
return true ;
}
bool
nas : : handle_imsi_attach_request_unknown_ue ( uint32_t enb_ue_s1ap_id ,
bool nas : : handle_imsi_attach_request_unknown_ue ( uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT & attach_req ,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT & pdn_con_req ,
@ -179,7 +184,6 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
gtpc_interface_nas * gtpc ,
hss_interface_nas * hss ,
srslte : : log * nas_log )
{
nas * nas_ctx ;
srslte : : byte_buffer_t * nas_tx ;
@ -202,10 +206,12 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id = s1ap - > get_next_mme_ue_s1ap_id ( ) ;
// Save UE network capabilities
memcpy ( & nas_ctx - > m_sec_ctx . ue_network_cap , & attach_req . ue_network_cap , sizeof ( LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ) ) ;
memcpy ( & nas_ctx - > m_sec_ctx . ue_network_cap , & attach_req . ue_network_cap ,
sizeof ( LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ) ) ;
nas_ctx - > m_sec_ctx . ms_network_cap_present = attach_req . ms_network_cap_present ;
if ( attach_req . ms_network_cap_present ) {
memcpy ( & nas_ctx - > m_sec_ctx . ms_network_cap , & attach_req . ms_network_cap , sizeof ( LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ) ) ;
memcpy ( & nas_ctx - > m_sec_ctx . ms_network_cap , & attach_req . ms_network_cap ,
sizeof ( LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ) ) ;
}
uint8_t eps_bearer_id = pdn_con_req . eps_bearer_id ; // TODO: Unused
@ -231,7 +237,8 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
nas_ctx - > m_emm_ctx . attach_type = attach_req . eps_attach_type ;
// Get Authentication Vectors from HSS
if ( ! hss - > gen_auth_info_answer ( nas_ctx - > m_emm_ctx . imsi , nas_ctx - > m_sec_ctx . k_asme , nas_ctx - > m_sec_ctx . autn , nas_ctx - > m_sec_ctx . rand , nas_ctx - > m_sec_ctx . xres ) ) {
if ( ! hss - > gen_auth_info_answer ( nas_ctx - > m_emm_ctx . imsi , nas_ctx - > m_sec_ctx . k_asme , nas_ctx - > m_sec_ctx . autn ,
nas_ctx - > m_sec_ctx . rand , nas_ctx - > m_sec_ctx . xres ) ) {
nas_log - > console ( " User not found. IMSI %015 " PRIu64 " \n " , nas_ctx - > m_emm_ctx . imsi ) ;
nas_log - > info ( " User not found. IMSI %015 " PRIu64 " \n " , nas_ctx - > m_emm_ctx . imsi ) ;
delete nas_ctx ;
@ -252,7 +259,8 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
nas_ctx - > pack_authentication_request ( nas_tx ) ;
// Send reply to eNB
s1ap - > send_downlink_nas_transport ( nas_ctx - > m_ecm_ctx . enb_ue_s1ap_id , nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id , nas_tx , nas_ctx - > m_ecm_ctx . enb_sri ) ;
s1ap - > send_downlink_nas_transport ( nas_ctx - > m_ecm_ctx . enb_ue_s1ap_id , nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id , nas_tx ,
nas_ctx - > m_ecm_ctx . enb_sri ) ;
pool - > deallocate ( nas_tx ) ;
nas_log - > info ( " Downlink NAS: Sending Authentication Request \n " ) ;
@ -260,8 +268,7 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
return true ;
}
bool
nas : : handle_imsi_attach_request_known_ue ( nas * nas_ctx ,
bool nas : : handle_imsi_attach_request_known_ue ( nas * nas_ctx ,
uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT & attach_req ,
@ -285,12 +292,12 @@ nas::handle_imsi_attach_request_known_ue( nas *nas_ctx,
s1ap - > delete_ue_ctx ( nas_ctx - > m_emm_ctx . imsi ) ;
// Handle new attach
err = nas : : handle_imsi_attach_request_unknown_ue ( enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , args , s1ap , gtpc , hss , nas_log ) ;
err = nas : : handle_imsi_attach_request_unknown_ue ( enb_ue_s1ap_id , enb_sri , attach_req , pdn_con_req , args , s1ap , gtpc ,
hss , nas_log ) ;
return err ;
}
bool
nas : : handle_guti_attach_request_unknown_ue ( uint32_t enb_ue_s1ap_id ,
bool nas : : handle_guti_attach_request_unknown_ue ( uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT & attach_req ,
const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT & pdn_con_req ,
@ -316,10 +323,12 @@ nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
nas_ctx - > m_emm_ctx . state = EMM_STATE_DEREGISTERED ;
// Save UE network capabilities
memcpy ( & nas_ctx - > m_sec_ctx . ue_network_cap , & attach_req . ue_network_cap , sizeof ( LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ) ) ;
memcpy ( & nas_ctx - > m_sec_ctx . ue_network_cap , & attach_req . ue_network_cap ,
sizeof ( LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT ) ) ;
nas_ctx - > m_sec_ctx . ms_network_cap_present = attach_req . ms_network_cap_present ;
if ( attach_req . ms_network_cap_present ) {
memcpy ( & nas_ctx - > m_sec_ctx . ms_network_cap , & attach_req . ms_network_cap , sizeof ( LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ) ) ;
memcpy ( & nas_ctx - > m_sec_ctx . ms_network_cap , & attach_req . ms_network_cap ,
sizeof ( LIBLTE_MME_MS_NETWORK_CAPABILITY_STRUCT ) ) ;
}
// Initialize NAS count
nas_ctx - > m_sec_ctx . ul_nas_count = 0 ;
@ -354,14 +363,14 @@ nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id,
// Send Identity Request
nas_tx = pool - > allocate ( ) ;
nas_ctx - > pack_identity_request ( nas_tx ) ;
s1ap - > send_downlink_nas_transport ( nas_ctx - > m_ecm_ctx . enb_ue_s1ap_id , nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id , nas_tx , nas_ctx - > m_ecm_ctx . enb_sri ) ;
s1ap - > send_downlink_nas_transport ( nas_ctx - > m_ecm_ctx . enb_ue_s1ap_id , nas_ctx - > m_ecm_ctx . mme_ue_s1ap_id , nas_tx ,
nas_ctx - > m_ecm_ctx . enb_sri ) ;
pool - > deallocate ( nas_tx ) ;
return true ;
}
bool
nas : : handle_guti_attach_request_known_ue ( nas * nas_ctx ,
bool nas : : handle_guti_attach_request_known_ue ( nas * nas_ctx ,
uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT & attach_req ,
@ -381,13 +390,16 @@ nas::handle_guti_attach_request_known_ue( nas *nas_ctx,
ecm_ctx_t * ecm_ctx = & nas_ctx - > m_ecm_ctx ;
sec_ctx_t * sec_ctx = & nas_ctx - > m_sec_ctx ;
nas_log - > console ( " Found UE context. IMSI: %015 " PRIu64 " , old eNB UE S1ap Id %d, old MME UE S1AP Id %d \n " , emm_ctx - > imsi , ecm_ctx - > enb_ue_s1ap_id , ecm_ctx - > mme_ue_s1ap_id ) ;
nas_log - > console ( " Found UE context. IMSI: %015 " PRIu64 " , old eNB UE S1ap Id %d, old MME UE S1AP Id %d \n " ,
emm_ctx - > imsi , ecm_ctx - > enb_ue_s1ap_id , ecm_ctx - > mme_ue_s1ap_id ) ;
// Check NAS integrity
msg_valid = nas_ctx - > integrity_check ( nas_rx ) ;
if ( msg_valid = = true & & emm_ctx - > state = = EMM_STATE_DEREGISTERED ) {
nas_log - > console ( " GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d \n " , sec_ctx - > ul_nas_count , sec_ctx - > dl_nas_count ) ;
nas_log - > info ( " GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d \n " , sec_ctx - > ul_nas_count , sec_ctx - > dl_nas_count ) ;
nas_log - > console ( " GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d \n " , sec_ctx - > ul_nas_count ,
sec_ctx - > dl_nas_count ) ;
nas_log - > info ( " GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d \n " , sec_ctx - > ul_nas_count ,
sec_ctx - > dl_nas_count ) ;
// Create new MME UE S1AP Identity
ecm_ctx - > mme_ue_s1ap_id = s1ap - > get_next_mme_ue_s1ap_id ( ) ;
@ -509,8 +521,7 @@ nas::handle_guti_attach_request_known_ue( nas *nas_ctx,
}
// Service Requests
bool
nas : : handle_service_request ( uint32_t m_tmsi ,
bool nas : : handle_service_request ( uint32_t m_tmsi ,
uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
srslte : : byte_buffer_t * nas_rx ,
@ -574,7 +585,8 @@ nas::handle_service_request( uint32_t m_tmsi,
nas_log - > error ( " Service Request -- User is ECM CONNECTED \n " ) ;
// Release previous context
nas_log - > info ( " Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d \n " , ecm_ctx - > enb_ue_s1ap_id , ecm_ctx - > mme_ue_s1ap_id ) ;
nas_log - > info ( " Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d \n " ,
ecm_ctx - > enb_ue_s1ap_id , ecm_ctx - > mme_ue_s1ap_id ) ;
s1ap - > send_ue_context_release_command ( ecm_ctx - > mme_ue_s1ap_id ) ;
s1ap - > release_ue_ecm_ctx ( ecm_ctx - > mme_ue_s1ap_id ) ;
}
@ -620,8 +632,7 @@ nas::handle_service_request( uint32_t m_tmsi,
return true ;
}
bool
nas : : handle_detach_request ( uint32_t m_tmsi ,
bool nas : : handle_detach_request ( uint32_t m_tmsi ,
uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
srslte : : byte_buffer_t * nas_rx ,
@ -676,8 +687,7 @@ nas::handle_detach_request( uint32_t m_tmsi,
return true ;
}
bool
nas : : handle_tracking_area_update_request ( uint32_t m_tmsi ,
bool nas : : handle_tracking_area_update_request ( uint32_t m_tmsi ,
uint32_t enb_ue_s1ap_id ,
struct sctp_sndrcvinfo * enb_sri ,
srslte : : byte_buffer_t * nas_rx ,
@ -717,8 +727,7 @@ nas::handle_tracking_area_update_request( uint32_t m_tmsi,
* Handle Uplink NAS Transport messages
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool
nas : : handle_authentication_response ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_authentication_response ( srslte : : byte_buffer_t * nas_rx )
{
srslte : : byte_buffer_t * nas_tx ;
LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp ;
@ -770,8 +779,7 @@ nas::handle_authentication_response(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_security_mode_complete ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_security_mode_complete ( srslte : : byte_buffer_t * nas_rx )
{
srslte : : byte_buffer_t * nas_tx ;
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp ;
@ -810,9 +818,7 @@ nas::handle_security_mode_complete(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_attach_complete ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_attach_complete ( srslte : : byte_buffer_t * nas_rx )
{
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp ;
uint8_t pd , msg_type ;
@ -826,7 +832,8 @@ nas::handle_attach_complete(srslte::byte_buffer_t *nas_rx)
return false ;
}
err = liblte_mme_unpack_activate_default_eps_bearer_context_accept_msg ( ( LIBLTE_BYTE_MSG_STRUCT * ) & attach_comp . esm_msg , & act_bearer ) ;
err = liblte_mme_unpack_activate_default_eps_bearer_context_accept_msg ( ( LIBLTE_BYTE_MSG_STRUCT * ) & attach_comp . esm_msg ,
& act_bearer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
m_nas_log - > error ( " Error unpacking Activate EPS Bearer Context Accept Msg. Error: %s \n " , liblte_error_text [ err ] ) ;
return false ;
@ -841,7 +848,8 @@ nas::handle_attach_complete(srslte::byte_buffer_t *nas_rx)
}
if ( m_emm_ctx . state = = EMM_STATE_DEREGISTERED ) {
// Attach requested from attach request
m_gtpc - > send_modify_bearer_request ( m_emm_ctx . imsi , act_bearer . eps_bearer_id , & m_esm_ctx [ act_bearer . eps_bearer_id ] . enb_fteid ) ;
m_gtpc - > send_modify_bearer_request ( m_emm_ctx . imsi , act_bearer . eps_bearer_id ,
& m_esm_ctx [ act_bearer . eps_bearer_id ] . enb_fteid ) ;
// Send reply to EMM Info to UE
nas_tx = m_pool - > allocate ( ) ;
@ -857,13 +865,13 @@ nas::handle_attach_complete(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_esm_information_response ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_esm_information_response ( srslte : : byte_buffer_t * nas_rx )
{
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT esm_info_resp ;
// Get NAS authentication response
LIBLTE_ERROR_ENUM err = srslte_mme_unpack_esm_information_response_msg ( ( LIBLTE_BYTE_MSG_STRUCT * ) nas_rx , & esm_info_resp ) ;
LIBLTE_ERROR_ENUM err =
srslte_mme_unpack_esm_information_response_msg ( ( LIBLTE_BYTE_MSG_STRUCT * ) nas_rx , & esm_info_resp ) ;
if ( err ! = LIBLTE_SUCCESS ) {
m_nas_log - > error ( " Error unpacking NAS authentication response. Error: %s \n " , liblte_error_text [ err ] ) ;
return false ;
@ -891,8 +899,7 @@ nas::handle_esm_information_response(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_identity_response ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_identity_response ( srslte : : byte_buffer_t * nas_rx )
{
srslte : : byte_buffer_t * nas_tx ;
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp ;
@ -939,9 +946,7 @@ nas::handle_identity_response(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_tracking_area_update_request ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_tracking_area_update_request ( srslte : : byte_buffer_t * nas_rx )
{
m_nas_log - > console ( " Warning: Tracking Area Update Request messages not handled yet. \n " ) ;
m_nas_log - > warning ( " Warning: Tracking Area Update Request messages not handled yet. \n " ) ;
@ -949,9 +954,7 @@ nas::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_authentication_failure ( srslte : : byte_buffer_t * nas_rx )
bool nas : : handle_authentication_failure ( srslte : : byte_buffer_t * nas_rx )
{
m_nas_log - > info ( " Received Authentication Failure \n " ) ;
@ -987,7 +990,8 @@ nas::handle_authentication_failure(srslte::byte_buffer_t *nas_rx)
return false ;
}
// Get Authentication Vectors from HSS
if ( ! m_hss - > gen_auth_info_answer ( m_emm_ctx . imsi , m_sec_ctx . k_asme , m_sec_ctx . autn , m_sec_ctx . rand , m_sec_ctx . xres ) ) {
if ( ! m_hss - > gen_auth_info_answer ( m_emm_ctx . imsi , m_sec_ctx . k_asme , m_sec_ctx . autn , m_sec_ctx . rand ,
m_sec_ctx . xres ) ) {
m_nas_log - > console ( " User not found. IMSI %015 " PRIu64 " \n " , m_emm_ctx . imsi ) ;
m_nas_log - > info ( " User not found. IMSI %015 " PRIu64 " \n " , m_emm_ctx . imsi ) ;
return false ;
@ -1001,7 +1005,8 @@ nas::handle_authentication_failure(srslte::byte_buffer_t *nas_rx)
pack_authentication_request ( nas_tx ) ;
// Send reply to eNB
m_s1ap - > send_downlink_nas_transport ( m_ecm_ctx . enb_ue_s1ap_id , m_ecm_ctx . mme_ue_s1ap_id , nas_tx , m_ecm_ctx . enb_sri ) ;
m_s1ap - > send_downlink_nas_transport ( m_ecm_ctx . enb_ue_s1ap_id , m_ecm_ctx . mme_ue_s1ap_id , nas_tx ,
m_ecm_ctx . enb_sri ) ;
m_pool - > deallocate ( nas_tx ) ;
m_nas_log - > info ( " Downlink NAS: Sent Authentication Request \n " ) ;
@ -1012,8 +1017,7 @@ nas::handle_authentication_failure(srslte::byte_buffer_t *nas_rx)
return true ;
}
bool
nas : : handle_detach_request ( srslte : : byte_buffer_t * nas_msg )
bool nas : : handle_detach_request ( srslte : : byte_buffer_t * nas_msg )
{
m_nas_log - > console ( " Detach request -- IMSI %015 " PRIu64 " \n " , m_emm_ctx . imsi ) ;
@ -1035,8 +1039,7 @@ nas::handle_detach_request(srslte::byte_buffer_t *nas_msg)
}
/*Packing/Unpacking helper functions*/
bool
nas : : pack_authentication_request ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_authentication_request ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing Authentication Request \n " ) ;
@ -1056,8 +1059,7 @@ nas::pack_authentication_request(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_authentication_reject ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_authentication_reject ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing Authentication Reject \n " ) ;
@ -1071,8 +1073,7 @@ nas::pack_authentication_reject(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_security_mode_command ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_security_mode_command ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing Security Mode Command \n " ) ;
@ -1103,19 +1104,16 @@ nas::pack_security_mode_command(srslte::byte_buffer_t *nas_buffer)
sm_cmd . nonce_mme_present = false ;
uint8_t sec_hdr_type = 3 ;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg ( & sm_cmd , sec_hdr_type , m_sec_ctx . dl_nas_count , ( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg ( & sm_cmd , sec_hdr_type , m_sec_ctx . dl_nas_count ,
( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
m_nas_log - > console ( " Error packing Authentication Request \n " ) ;
return false ;
}
// Generate EPS security context
srslte : : security_generate_k_nas ( m_sec_ctx . k_asme ,
m_sec_ctx . cipher_algo ,
m_sec_ctx . integ_algo ,
m_sec_ctx . k_nas_enc ,
m_sec_ctx . k_nas_int
) ;
srslte : : security_generate_k_nas ( m_sec_ctx . k_asme , m_sec_ctx . cipher_algo , m_sec_ctx . integ_algo , m_sec_ctx . k_nas_enc ,
m_sec_ctx . k_nas_int ) ;
m_nas_log - > info_hex ( m_sec_ctx . k_nas_enc , 32 , " Key NAS Encryption (k_nas_enc) \n " ) ;
m_nas_log - > info_hex ( m_sec_ctx . k_nas_int , 32 , " Key NAS Integrity (k_nas_int) \n " ) ;
@ -1133,8 +1131,7 @@ nas::pack_security_mode_command(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_esm_information_request ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_esm_information_request ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing ESM Information request \n " ) ;
@ -1145,7 +1142,8 @@ nas::pack_esm_information_request(srslte::byte_buffer_t *nas_buffer)
uint8_t sec_hdr_type = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED ;
m_sec_ctx . dl_nas_count + + ;
LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg ( & esm_info_req , sec_hdr_type , m_sec_ctx . dl_nas_count , ( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg (
& esm_info_req , sec_hdr_type , m_sec_ctx . dl_nas_count , ( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
m_nas_log - > error ( " Error packing ESM information request \n " ) ;
m_nas_log - > console ( " Error packing ESM information request \n " ) ;
@ -1160,8 +1158,7 @@ nas::pack_esm_information_request(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_attach_accept ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_attach_accept ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing Attach Accept \n " ) ;
@ -1209,11 +1206,8 @@ nas::pack_attach_accept(srslte::byte_buffer_t *nas_buffer)
attach_accept . guti . guti . mme_code = m_mme_code ;
attach_accept . guti . guti . m_tmsi = m_s1ap - > allocate_m_tmsi ( m_emm_ctx . imsi ) ;
m_nas_log - > debug ( " Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x \n " ,
attach_accept . guti . guti . mcc ,
attach_accept . guti . guti . mnc ,
attach_accept . guti . guti . mme_group_id ,
attach_accept . guti . guti . mme_code ,
attach_accept . guti . guti . m_tmsi ) ;
attach_accept . guti . guti . mcc , attach_accept . guti . guti . mnc , attach_accept . guti . guti . mme_group_id ,
attach_accept . guti . guti . mme_code , attach_accept . guti . guti . m_tmsi ) ;
// Set up LAI for combined EPS/IMSI attach
attach_accept . lai_present = true ;
@ -1272,8 +1266,10 @@ nas::pack_attach_accept(srslte::byte_buffer_t *nas_buffer)
uint8_t sec_hdr_type = 2 ;
m_sec_ctx . dl_nas_count + + ;
liblte_mme_pack_activate_default_eps_bearer_context_request_msg ( & act_def_eps_bearer_context_req , & attach_accept . esm_msg ) ;
liblte_mme_pack_attach_accept_msg ( & attach_accept , sec_hdr_type , m_sec_ctx . dl_nas_count , ( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
liblte_mme_pack_activate_default_eps_bearer_context_request_msg ( & act_def_eps_bearer_context_req ,
& attach_accept . esm_msg ) ;
liblte_mme_pack_attach_accept_msg ( & attach_accept , sec_hdr_type , m_sec_ctx . dl_nas_count ,
( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
// Encrypt NAS message
cipher_encrypt ( nas_buffer ) ;
@ -1288,8 +1284,7 @@ nas::pack_attach_accept(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_identity_request ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_identity_request ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing Identity Request \n " ) ;
@ -1304,8 +1299,7 @@ nas::pack_identity_request(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_emm_information ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_emm_information ( srslte : : byte_buffer_t * nas_buffer )
{
m_nas_log - > info ( " Packing EMM Information \n " ) ;
@ -1323,7 +1317,8 @@ nas::pack_emm_information(srslte::byte_buffer_t *nas_buffer)
uint8_t sec_hdr_type = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED ;
m_sec_ctx . dl_nas_count + + ;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg ( & emm_info , sec_hdr_type , m_sec_ctx . dl_nas_count , ( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg ( & emm_info , sec_hdr_type , m_sec_ctx . dl_nas_count ,
( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
m_nas_log - > error ( " Error packing EMM Information \n " ) ;
m_nas_log - > console ( " Error packing EMM Information \n " ) ;
@ -1342,8 +1337,7 @@ nas::pack_emm_information(srslte::byte_buffer_t *nas_buffer)
return true ;
}
bool
nas : : pack_service_reject ( srslte : : byte_buffer_t * nas_buffer )
bool nas : : pack_service_reject ( srslte : : byte_buffer_t * nas_buffer )
{
uint8_t emm_cause = LIBLTE_MME_EMM_CAUSE_IMPLICITLY_DETACHED ;
@ -1355,7 +1349,8 @@ nas::pack_service_reject(srslte::byte_buffer_t *nas_buffer)
service_rej . t3446 = 0 ;
service_rej . emm_cause = emm_cause ;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_service_reject_msg ( & service_rej , LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS , 0 , ( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
LIBLTE_ERROR_ENUM err = liblte_mme_pack_service_reject_msg ( & service_rej , LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS , 0 ,
( LIBLTE_BYTE_MSG_STRUCT * ) nas_buffer ) ;
if ( err ! = LIBLTE_SUCCESS ) {
m_nas_log - > error ( " Error packing Service Reject \n " ) ;
m_nas_log - > console ( " Error packing Service Reject \n " ) ;
@ -1380,27 +1375,16 @@ bool nas::short_integrity_check(srslte::byte_buffer_t* pdu)
return false ;
}
switch ( m_sec_ctx . integ_algo )
{
switch ( m_sec_ctx . integ_algo ) {
case srslte : : INTEGRITY_ALGORITHM_ID_EIA0 :
break ;
case srslte : : INTEGRITY_ALGORITHM_ID_128_EIA1 :
srslte : : security_128_eia1 ( & m_sec_ctx . k_nas_int [ 16 ] ,
m_sec_ctx . ul_nas_count ,
0 ,
SECURITY_DIRECTION_UPLINK ,
& pdu - > msg [ 0 ] ,
2 ,
& exp_mac [ 0 ] ) ;
srslte : : security_128_eia1 ( & m_sec_ctx . k_nas_int [ 16 ] , m_sec_ctx . ul_nas_count , 0 , SECURITY_DIRECTION_UPLINK ,
& pdu - > msg [ 0 ] , 2 , & exp_mac [ 0 ] ) ;
break ;
case srslte : : INTEGRITY_ALGORITHM_ID_128_EIA2 :
srslte : : security_128_eia2 ( & m_sec_ctx . k_nas_int [ 16 ] ,
m_sec_ctx . ul_nas_count ,
0 ,
SECURITY_DIRECTION_UPLINK ,
& pdu - > msg [ 0 ] ,
2 ,
& exp_mac [ 0 ] ) ;
srslte : : security_128_eia2 ( & m_sec_ctx . k_nas_int [ 16 ] , m_sec_ctx . ul_nas_count , 0 , SECURITY_DIRECTION_UPLINK ,
& pdu - > msg [ 0 ] , 2 , & exp_mac [ 0 ] ) ;
break ;
default :
break ;
@ -1426,8 +1410,7 @@ bool nas::integrity_check(srslte::byte_buffer_t *pdu)
uint8_t * mac = & pdu - > msg [ 1 ] ;
int i ;
switch ( m_sec_ctx . integ_algo )
{
switch ( m_sec_ctx . integ_algo ) {
case srslte : : INTEGRITY_ALGORITHM_ID_EIA0 :
break ;
case srslte : : INTEGRITY_ALGORITHM_ID_128_EIA1 :
@ -1462,8 +1445,7 @@ bool nas::integrity_check(srslte::byte_buffer_t *pdu)
return false ;
}
}
m_nas_log - > info ( " Integrity check ok. Local: count=%d, Received: count=%d \n " ,
m_sec_ctx . ul_nas_count , pdu - > msg [ 5 ] ) ;
m_nas_log - > info ( " Integrity check ok. Local: count=%d, Received: count=%d \n " , m_sec_ctx . ul_nas_count , pdu - > msg [ 5 ] ) ;
return true ;
}
@ -1498,8 +1480,7 @@ void nas::integrity_generate(srslte::byte_buffer_t* pdu, uint8_t* mac)
void nas : : cipher_decrypt ( srslte : : byte_buffer_t * pdu )
{
srslte : : byte_buffer_t tmp_pdu ;
switch ( m_sec_ctx . cipher_algo )
{
switch ( m_sec_ctx . cipher_algo ) {
case srslte : : CIPHERING_ALGORITHM_ID_EEA0 :
break ;
case srslte : : CIPHERING_ALGORITHM_ID_128_EEA1 :
@ -1533,8 +1514,7 @@ void nas::cipher_decrypt(srslte::byte_buffer_t *pdu)
void nas : : cipher_encrypt ( srslte : : byte_buffer_t * pdu )
{
srslte : : byte_buffer_t pdu_tmp ;
switch ( m_sec_ctx . cipher_algo )
{
switch ( m_sec_ctx . cipher_algo ) {
case srslte : : CIPHERING_ALGORITHM_ID_EEA0 :
break ;
case srslte : : CIPHERING_ALGORITHM_ID_128_EEA1 :
@ -1564,5 +1544,4 @@ void nas::cipher_encrypt(srslte::byte_buffer_t *pdu)
break ;
}
}
} // namespace srsepc