From 9e808ff9681be65ec8692dda9958d273861e6d35 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 24 Aug 2018 18:15:06 +0100 Subject: [PATCH 1/9] Starting to handle NAS initial UE messages as static methods of the nas class. --- srsepc/hdr/mme/nas.h | 91 +++++---- srsepc/src/mme/nas.cc | 278 ++++++++++++--------------- srsepc/src/mme/s1ap_nas_transport.cc | 45 +---- 3 files changed, 194 insertions(+), 220 deletions(-) diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 9eb7c5ad3..4c419cb06 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -131,55 +131,76 @@ typedef struct{ LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; } sec_ctx_t; +/* + * NAS Initialization Arguments + */ +typedef struct { + uint16_t mcc; + uint16_t mnc; + uint8_t mme_code; + uint16_t mme_group; + uint16_t tac; + std::string apn; + std::string dns; +} nas_init_t; + class nas { public: nas(); - void init(uint16_t mcc, - uint16_t mnc, - uint8_t mme_code, - uint16_t mme_group, - uint16_t tac, - std::string apn, - std::string dns, + void init(nas_init_t args, s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, hss_interface_nas *hss, srslte::log *nas_log); - /*Initial UE messages*/ - bool handle_attach_request( uint32_t enb_ue_s1ap_id, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri); + /*********************** + * Initial UE messages * + ***********************/ + //Attach request messages + static bool handle_attach_request( uint32_t enb_ue_s1ap_id, + struct sctp_sndrcvinfo *enb_sri, + srslte::byte_buffer_t *nas_msg, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); - bool handle_imsi_attach_request(uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - struct sctp_sndrcvinfo *enb_sri); + static bool 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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); - bool handle_guti_attach_request( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri); + bool handle_imsi_attach_request_known_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); + + + static bool 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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); bool handle_guti_attach_request_known_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, - srslte::byte_buffer_t *nas_rx, - struct sctp_sndrcvinfo *enb_sri); + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req); - bool handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri); + //Service request Messages + //Dettach request Messages + // /* Uplink NAS messages handling */ bool handle_authentication_response( srslte::byte_buffer_t *nas_rx); bool handle_security_mode_complete( srslte::byte_buffer_t *nas_rx); @@ -204,7 +225,7 @@ public: bool integrity_check (srslte::byte_buffer_t *pdu); bool short_integrity_check (srslte::byte_buffer_t *pdu); - /* UE Context*/ + /* UE Context */ emm_ctx_t m_emm_ctx; ecm_ctx_t m_ecm_ctx; esm_ctx_t m_esm_ctx[MAX_ERABS_PER_UE]; diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 63a3da39a..def9f3f6c 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -40,25 +40,19 @@ nas::nas() { } void -nas::init(uint16_t mcc, - uint16_t mnc, - uint8_t mme_code, - uint16_t mme_group, - uint16_t tac, - std::string apn, - std::string dns, +nas::init(nas_init_t args, s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, hss_interface_nas *hss, srslte::log *nas_log) { - m_mcc = mcc; - m_mnc = mnc; - m_mme_code = mme_code; - m_mme_group = mme_group; - m_tac = tac; - m_apn = apn; - m_dns = dns; + m_mcc = args.mcc; + m_mnc = args.mnc; + m_mme_code = args.mme_code; + m_mme_group = args.mme_group; + m_tac = args.tac; + m_apn = args.apn; + m_dns = args.dns; m_s1ap = s1ap; m_gtpc = gtpc; @@ -71,80 +65,136 @@ nas::init(uint16_t mcc, * Handle UE Initiating Messages * ********************************/ -//FIXME Move UE Initiating mesages from s1ap_nas_transport -bool +static bool nas::handle_attach_request( uint32_t enb_ue_s1ap_id, + struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) { - bool save = true; + uint32_t m_tmsi = 0; + uint64_t imsi = 0; LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; //Get NAS Attach Request and PDN connectivity request messages LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req); if(err != LIBLTE_SUCCESS){ - m_nas_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); - return save; + nas_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); + return false; } - /*Get PDN Connectivity Request*/ + //Get PDN Connectivity Request*/ err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req); if(err != LIBLTE_SUCCESS){ - m_nas_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); - return save; + nas_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); + return false; } - //Get attach type from attach request + //Get UE IMSI if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { - m_nas_log->console("Attach Request -- IMSI-style attach request\n"); - m_nas_log->info("Attach Request -- IMSI-style attach request\n"); - save = handle_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, enb_sri); + for(int i=0;i<=14;i++){ + imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + } + nas_log->console("Attach request -- IMSI Style Attach request\n"); + nas_log->info("Attach request -- IMSI Style Attach request\n"); + nas_log->console("Attach request -- IMSI: %015lu\n", imsi); + nas_log->info("Attach request -- IMSI: %015lu\n", imsi); } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { - m_nas_log->console("Attach Request -- GUTI-style attach request\n"); - m_nas_log->info("Attach Request -- GUTI-style attach request\n"); - save = handle_guti_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, nas_msg, reply_buffer, reply_flag, enb_sri); + m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; + imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); + nas_log->console("Attach request -- GUTI Style Attach request\n"); + nas_log->info("Attach request -- GUTI Style Attach request\n"); + nas_log->console("Attach request -- M-TMSI: 0x%x\n", m_tmsi); + nas_log->info("Attach request -- M-TMSI: 0x%x\n", m_tmsi); } else { - m_nas_log->error("Unhandled Mobile Id type in attach request\n"); - return save; + nas_log->error("Unhandled Mobile Id type in attach request\n"); + return false; + } + + //Log Attach Request Information + nas_log->console("Attach request -- eNB-UE S1AP Id: %d\n", enb_ue_s1ap_id); + nas_log->info("Attach request -- eNB-UE S1AP Id: %d\n", 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]); + 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"); + 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"); + + //Get NAS Context if UE is known + nas * nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); + 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_log->console("Attach Request -- IMSI-style attach request\n"); + nas_log->info("Attach Request -- IMSI-style attach request\n"); + 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_log->console("Attach Request -- GUTI-style attach request\n"); + nas_log->info("Attach Request -- GUTI-style attach request\n"); + 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 { + nas_log->error("Unhandled Mobile Id type in attach request\n"); + return false; + } + } else { + if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { + nas_log->console("Attach Request -- IMSI-style attach request\n"); + nas_log->info("Attach Request -- IMSI-style attach request\n"); + nas_ctx->handle_imsi_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req); + } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { + nas_log->console("Attach Request -- GUTI-style attach request\n"); + nas_log->info("Attach Request -- GUTI-style attach request\n"); + nas_ctx->handle_guti_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req); + } else { + nas_log->error("Unhandled Mobile Id type in attach request\n"); + return false; + } } //Log Attach Request information - m_nas_log->console("Attach request -- IMSI: %015lu\n", m_emm_ctx.imsi); - m_nas_log->info("Attach request -- IMSI: %015lu\n", m_emm_ctx.imsi); - m_nas_log->console("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id); - m_nas_log->info("Attach request -- eNB-UE S1AP Id: %d, MME-UE S1AP Id: %d\n", m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id); - m_nas_log->console("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); - m_nas_log->info("Attach request -- Attach type: %d\n", attach_req.eps_attach_type); - m_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]); - m_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]); - m_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]); - m_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]); - m_nas_log->console("Attach Request -- MS Network Capabilities Present: %s\n", attach_req.ms_network_cap_present ? "true" : "false"); - m_nas_log->info("Attach Request -- MS Network Capabilities Present: %s\n", attach_req.ms_network_cap_present ? "true" : "false"); - m_nas_log->console("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); - m_nas_log->info("PDN Connectivity Request -- EPS Bearer Identity requested: %d\n", pdn_con_req.eps_bearer_id); - m_nas_log->console("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); - m_nas_log->info("PDN Connectivity Request -- Procedure Transaction Id: %d\n", pdn_con_req.proc_transaction_id); - m_nas_log->console("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); - m_nas_log->info("PDN Connectivity Request -- ESM Information Transfer requested: %s\n", pdn_con_req.esm_info_transfer_flag_present ? "true" : "false"); - return save; + return true; } +static 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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) + +{ + return true; +} bool -nas::handle_imsi_attach_request( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - struct sctp_sndrcvinfo *enb_sri) +nas::handle_imsi_attach_request_known_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 ) { srslte::byte_buffer_t *nas_tx; @@ -218,86 +268,11 @@ nas::handle_imsi_attach_request( uint32_t enb_ue_s1ap_id, return true; } -bool -nas::handle_guti_attach_request( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - //Parse the message security header - uint8 pd = 0; - uint8 sec_hdr_type = 0; - liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); - - bool integrity_valid = false; - if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) { - m_nas_log->info("Attach request -- GUTI-stlye attach request is not integrity protected\n"); - m_nas_log->console("Attach request -- GUTI-stlye attach request is not integrity protected\n"); - } else { - m_nas_log->info("Attach request -- GUTI-stlye attach request is integrity protected\n"); - m_nas_log->console("Attach request -- GUTI-stlye attach request is integrity protected\n"); - } - - //GUTI style attach - uint32_t m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; - /*std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); - if (it == m_s1ap->m_tmsi_to_imsi.end()) { - //Could not find IMSI from M-TMSI, send Id request - m_s1ap_log->console("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi); - - //nas *nas_ctx = new nas; - //nas_ctx->init(m_s1ap->m_s1ap_args.mcc, - // m_s1ap->m_s1ap_args.mnc, - // m_s1ap->m_s1ap_args.mme_code, - // m_s1ap->m_s1ap_args.mme_group, - // m_s1ap->m_s1ap_args.tac, - // m_s1ap->m_s1ap_args.mme_apn, - // m_s1ap->m_s1ap_args.dns_addr, - // m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); - - bool err = nas_ctx->handle_guti_attach_request_unknown_ue( enb_ue_s1ap_id, - attach_req, - pdn_con_req, - nas_msg, - reply_buffer, - reply_flag, - enb_sri); - //if (err == false) { - // delete nas_ctx; - //} - return err; - } else { - //Found UE context from M-TMSI - m_nas_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); - m_nas_log->console("Attach Request -- IMSI: %015lu\n",it->second); - //Get UE EMM context - nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(it->second); - if (nas_ctx!=NULL) { - nas_ctx->handle_guti_attach_request_known_ue( enb_ue_s1ap_id, - attach_req, - pdn_con_req, - nas_msg, - reply_buffer, - reply_flag, - enb_sri); - } else { - m_s1ap_log->error("Found M-TMSI but could not find UE context\n"); - m_s1ap_log->console("Error: Found M-TMSI but could not find UE context\n"); - return false; - } - }*/ - return true; -} bool nas::handle_guti_attach_request_known_ue( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_rx, - struct sctp_sndrcvinfo *enb_sri) + 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) { m_nas_log->console("Found UE context. IMSI: %015lu, old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",m_emm_ctx.imsi, m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id); @@ -432,14 +407,17 @@ nas::handle_guti_attach_request_known_ue( uint32_t enb_ue_s1ap_id, } } -bool +static bool nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) + 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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) + { srslte::byte_buffer_t *nas_tx; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 09009d4a9..4bed610d4 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -96,47 +96,22 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); m_s1ap_log->info ("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); - //Make sure M-TMSI is present, if mandatory - if (msg_type != LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST && !init_ue->S_TMSI_present){ - m_s1ap_log->error("Initial UE Message 0x%x -- S-TMSI not present\n", msg_type); - m_s1ap_log->console("Initial UE message 0x%x -- S-TMSI not present\n", msg_type); - m_pool->deallocate(nas_msg); - return false; - } - - //Get NAS context if TMSI is present - nas *nas_ctx = NULL; - if (init_ue->S_TMSI_present) { - m_tmsi = ntohl(*((uint32_t*)&init_ue->S_TMSI.m_TMSI.buffer)); - imsi = m_s1ap->find_imsi_from_m_tmsi(m_tmsi); - if(imsi !=0){ - nas_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); - } - } - - //Create new NAS context if Attach request without known NAS context - //This will be release if the attach request returns an error - if (msg_type == LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST && nas_ctx == NULL) { - nas_ctx = new nas; - nas_ctx->init(m_s1ap->m_s1ap_args.mcc, - m_s1ap->m_s1ap_args.mnc, - m_s1ap->m_s1ap_args.mme_code, - m_s1ap->m_s1ap_args.mme_group, - m_s1ap->m_s1ap_args.tac, - m_s1ap->m_s1ap_args.mme_apn, - m_s1ap->m_s1ap_args.dns_addr, - m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); - } + nas_init_t nas_init; + nas_init.mcc = m_s1ap->m_s1ap_args.mcc; + nas_init.mnc = m_s1ap->m_s1ap_args.mnc; + nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code; + nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group; + nas_init.tac = m_s1ap->m_s1ap_args.tac; + nas_init.mme_apn = m_s1ap->m_s1ap_args.mme_apn; + nas_init.dns_addr = m_s1ap->m_s1ap_args.dns_addr; switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: m_s1ap_log->console("Received Initial UE message -- Attach Request\n"); m_s1ap_log->info("Received Initial UE message -- Attach Request\n"); - err = handle_nas_attach_request(enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); - if (err == false) { - delete nas_ctx; - } + err = nas::handle_nas_attach_request(enb_ue_s1ap_id, nas_init, enb_sri, nas_msg, + m_s1ap, m_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Service Request\n"); From 860e1b5491be07d577ab8d3572af07673596d539 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 27 Aug 2018 16:06:18 +0100 Subject: [PATCH 2/9] Changing Handling of initial UE NAS messages to use static methods. Handling of unknown GUTI attach request should be ok. --- .../srslte/interfaces/epc_interfaces.h | 2 + srsepc/hdr/mme/nas.h | 5 +- srsepc/hdr/mme/s1ap.h | 4 +- srsepc/hdr/mme/s1ap_nas_transport.h | 21 --- srsepc/src/mme/nas.cc | 71 ++++---- srsepc/src/mme/s1ap_nas_transport.cc | 171 +----------------- 6 files changed, 51 insertions(+), 223 deletions(-) diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h index 607675a00..4421b4f54 100644 --- a/lib/include/srslte/interfaces/epc_interfaces.h +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -53,6 +53,8 @@ public: virtual bool add_nas_ctx_to_mme_ue_s1ap_id_map(nas *nas_ctx) = 0; virtual bool add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id) = 0; virtual bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) = 0; + virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi) = 0; + virtual nas* find_nas_ctx_from_imsi(uint64_t imsi) = 0; virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup) = 0; virtual bool send_ue_context_release_command(uint32_t mme_ue_s1ap_id) = 0; virtual bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, struct sctp_sndrcvinfo enb_sri) = 0; diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 4c419cb06..9d3d3457c 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -160,7 +160,7 @@ public: //Attach request messages static bool handle_attach_request( uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo *enb_sri, - srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *nas_rx, nas_init_t args, s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, @@ -196,7 +196,8 @@ public: bool handle_guti_attach_request_known_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); + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_rx); //Service request Messages //Dettach request Messages diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 7219a362a..626a921c0 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -89,7 +89,7 @@ public: bool add_nas_ctx_to_mme_ue_s1ap_id_map(nas *nas_ctx); bool add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id); - nas* find_nas_ctx_from_imsi(uint64_t imsi); + virtual nas* find_nas_ctx_from_imsi(uint64_t imsi); nas* find_nas_ctx_from_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id); bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); @@ -97,7 +97,7 @@ public: bool delete_ue_ctx(uint64_t imsi); uint32_t allocate_m_tmsi(uint64_t imsi); - uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi); + virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi); s1ap_args_t m_s1ap_args; srslte::log_filter *m_s1ap_log; diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index 08c88deb6..890e80667 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -48,27 +48,6 @@ public: bool handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport, struct sctp_sndrcvinfo *enb_sri, srslte::byte_buffer_t *reply_buffer, bool *reply_flag); bool send_downlink_nas_transport(uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, struct sctp_sndrcvinfo enb_sri); - bool handle_nas_attach_request(uint32_t enb_ue_s1ap_id, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri); - - bool handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri); - - bool handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri); - bool handle_nas_detach_request( uint32_t m_tmsi, uint32_t enb_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index def9f3f6c..21c2bbdeb 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -65,10 +65,10 @@ nas::init(nas_init_t args, * Handle UE Initiating Messages * ********************************/ -static bool +bool nas::handle_attach_request( uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo *enb_sri, - srslte::byte_buffer_t *nas_msg, + srslte::byte_buffer_t *nas_rx, nas_init_t args, s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, @@ -81,7 +81,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id, LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; //Get NAS Attach Request and PDN connectivity request messages - LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req); + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_rx, &attach_req); if(err != LIBLTE_SUCCESS){ nas_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); return false; @@ -165,7 +165,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id, } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { nas_log->console("Attach Request -- GUTI-style attach request\n"); nas_log->info("Attach Request -- GUTI-style attach request\n"); - nas_ctx->handle_guti_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req); + nas_ctx->handle_guti_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx); } else { nas_log->error("Unhandled Mobile Id type in attach request\n"); return false; @@ -176,7 +176,7 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id, return true; } -static bool +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, @@ -190,6 +190,7 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, { return true; } + bool nas::handle_imsi_attach_request_known_ue( uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo *enb_sri, @@ -272,7 +273,8 @@ bool nas::handle_guti_attach_request_known_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) + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_rx) { m_nas_log->console("Found UE context. IMSI: %015lu, old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",m_emm_ctx.imsi, m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id); @@ -407,7 +409,7 @@ nas::handle_guti_attach_request_known_ue( uint32_t enb_ue_s1ap_id, } } -static bool +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, @@ -419,63 +421,70 @@ nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, srslte::log *nas_log) { + nas *nas_ctx; + srslte::byte_buffer_pool *pool = srslte::byte_buffer_pool::get_instance(); srslte::byte_buffer_t *nas_tx; + //Create new NAS context. + nas_ctx = new nas; + nas_ctx->init(args, s1ap, gtpc, hss, nas_log); + //Could not find IMSI from M-TMSI, send Id request //The IMSI will be set when the identity response is received //Set EMM ctx - m_emm_ctx.imsi = 0; - m_emm_ctx.state = EMM_STATE_DEREGISTERED; + nas_ctx->m_emm_ctx.imsi = 0; + nas_ctx->m_emm_ctx.state = EMM_STATE_DEREGISTERED; //Save UE network capabilities - memcpy(&m_sec_ctx.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - m_sec_ctx.ms_network_cap_present = attach_req.ms_network_cap_present; + 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(&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 - m_sec_ctx.ul_nas_count = 0; - m_sec_ctx.dl_nas_count = 0; - m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + nas_ctx->m_sec_ctx.ul_nas_count = 0; + nas_ctx->m_sec_ctx.dl_nas_count = 0; + nas_ctx->m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; //Set ECM context - m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - m_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); + nas_ctx->m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + nas_ctx->m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //Save attach request type - m_emm_ctx.attach_type = attach_req.eps_attach_type; + nas_ctx->m_emm_ctx.attach_type = attach_req.eps_attach_type; //Save whether ESM information transfer is necessary - m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + nas_ctx->m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; //Add eNB info to UE ctxt - memcpy(&m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + memcpy(&nas_ctx->m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Initialize E-RABs for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - m_esm_ctx[i].state = ERAB_DEACTIVATED; - m_esm_ctx[i].erab_id = i; + nas_ctx->m_esm_ctx[i].state = ERAB_DEACTIVATED; + nas_ctx->m_esm_ctx[i].erab_id = i; } //Store temporary ue context - m_s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(this); - m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,m_ecm_ctx.mme_ue_s1ap_id); + s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); + s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); //Send Identity Request - nas_tx = m_pool->allocate(); - pack_identity_request(nas_tx); - 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); + 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); + pool->deallocate(nas_tx); return true; } -/* +/*************************************** * - * Handle Uplink NAS Transport message + * Handle Uplink NAS Transport messages * - */ + ***************************************/ bool nas::handle_authentication_response(srslte::byte_buffer_t *nas_rx) { diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 4bed610d4..1ace0b17f 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -102,16 +102,16 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code; nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group; nas_init.tac = m_s1ap->m_s1ap_args.tac; - nas_init.mme_apn = m_s1ap->m_s1ap_args.mme_apn; - nas_init.dns_addr = m_s1ap->m_s1ap_args.dns_addr; + nas_init.apn = m_s1ap->m_s1ap_args.mme_apn; + nas_init.dns = m_s1ap->m_s1ap_args.dns_addr; switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: m_s1ap_log->console("Received Initial UE message -- Attach Request\n"); m_s1ap_log->info("Received Initial UE message -- Attach Request\n"); - err = nas::handle_nas_attach_request(enb_ue_s1ap_id, nas_init, enb_sri, nas_msg, - m_s1ap, m_gtpc, m_hss, m_s1ap->m_nas_log); + err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Service Request\n"); @@ -301,169 +301,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA return true; } -bool -s1ap_nas_transport::handle_nas_attach_request(uint32_t enb_ue_s1ap_id, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT attach_req; - LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; - - //Get NAS Attach Request and PDN connectivity request messages - LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_request_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_req); - if(err != LIBLTE_SUCCESS){ - m_s1ap_log->error("Error unpacking NAS attach request. Error: %s\n", liblte_error_text[err]); - m_pool->deallocate(nas_msg); - return false; - } - /*Get PDN Connectivity Request*/ - err = liblte_mme_unpack_pdn_connectivity_request_msg(&attach_req.esm_msg, &pdn_con_req); - if(err != LIBLTE_SUCCESS){ - m_s1ap_log->error("Error unpacking NAS PDN Connectivity Request. Error: %s\n", liblte_error_text[err]); - m_pool->deallocate(nas_msg); - return false; - } - - //Get attach type from attach request - if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { - m_s1ap_log->console("Attach Request -- IMSI-style attach request\n"); - m_s1ap_log->info("Attach Request -- IMSI-style attach request\n"); - handle_nas_imsi_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, reply_buffer, reply_flag, enb_sri); - } else if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_GUTI) { - m_s1ap_log->console("Attach Request -- GUTI-style attach request\n"); - m_s1ap_log->info("Attach Request -- GUTI-style attach request\n"); - handle_nas_guti_attach_request(enb_ue_s1ap_id, attach_req, pdn_con_req, nas_msg, reply_buffer, reply_flag, enb_sri); - } else { - m_s1ap_log->error("Unhandled Mobile Id type in attach request\n"); - return false; - } - - return true; -} - -bool -s1ap_nas_transport::handle_nas_imsi_attach_request(uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - //Get UE's IMSI - uint64_t imsi = 0; - for(int i=0;i<=14;i++){ - imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); - } - - //Check if UE is already attached - nas *old_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); - if (old_ctx!=NULL) { - m_s1ap_log->console("Attach Request -- UE is already attached."); - m_s1ap_log->info("Attach Request -- UE is already attached."); - //Detaching previoulsy attached UE. - m_mme_gtpc->send_delete_session_request(imsi); - if (old_ctx->m_ecm_ctx.mme_ue_s1ap_id!=0) { - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(old_ctx); - } - m_s1ap->delete_ue_ctx(imsi); - } - - //Set UE's EMM context - nas *nas_ctx = new nas; - nas_ctx->init(m_s1ap->m_s1ap_args.mcc, - m_s1ap->m_s1ap_args.mnc, - m_s1ap->m_s1ap_args.mme_code, - m_s1ap->m_s1ap_args.mme_group, - m_s1ap->m_s1ap_args.tac, - m_s1ap->m_s1ap_args.mme_apn, - m_s1ap->m_s1ap_args.dns_addr, - m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); - - bool err = nas_ctx->handle_imsi_attach_request( enb_ue_s1ap_id, - attach_req, - pdn_con_req, - enb_sri); - if (err == false){ - delete nas_ctx; - } - return err; -} - -bool -s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, - const LIBLTE_MME_ATTACH_REQUEST_MSG_STRUCT &attach_req, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - //Parse the message security header - uint8 pd = 0; - uint8 sec_hdr_type = 0; - liblte_mme_parse_msg_sec_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg, &pd, &sec_hdr_type); - - bool integrity_valid = false; - if(sec_hdr_type != LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) { - m_s1ap_log->info("Attach request -- GUTI-stlye attach request is not integrity protected\n"); - m_s1ap_log->console("Attach request -- GUTI-stlye attach request is not integrity protected\n"); - } else { - m_s1ap_log->info("Attach request -- GUTI-stlye attach request is integrity protected\n"); - m_s1ap_log->console("Attach request -- GUTI-stlye attach request is integrity protected\n"); - } - - //GUTI style attach - uint32_t m_tmsi = attach_req.eps_mobile_id.guti.m_tmsi; - std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); - if (it == m_s1ap->m_tmsi_to_imsi.end()) { - //Could not find IMSI from M-TMSI, send Id request - m_s1ap_log->console("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->info("Attach Request -- Could not find M-TMSI 0x%x\n", m_tmsi); - - nas *nas_ctx = new nas; - nas_ctx->init(m_s1ap->m_s1ap_args.mcc, - m_s1ap->m_s1ap_args.mnc, - m_s1ap->m_s1ap_args.mme_code, - m_s1ap->m_s1ap_args.mme_group, - m_s1ap->m_s1ap_args.tac, - m_s1ap->m_s1ap_args.mme_apn, - m_s1ap->m_s1ap_args.dns_addr, - m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); - - bool err = nas_ctx->handle_guti_attach_request_unknown_ue( enb_ue_s1ap_id, - attach_req, - pdn_con_req, - nas_msg, - reply_buffer, - reply_flag, - enb_sri); - if (err == false) { - delete nas_ctx; - } - return err; - } else { - //Found UE context from M-TMSI - m_s1ap_log->console("Attach Request -- Found M-TMSI: %d\n",m_tmsi); - m_s1ap_log->console("Attach Request -- IMSI: %015lu\n",it->second); - //Get UE EMM context - nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(it->second); - if (nas_ctx!=NULL) { - nas_ctx->handle_guti_attach_request_known_ue( enb_ue_s1ap_id, - attach_req, - pdn_con_req, - nas_msg, - enb_sri); - } else { - m_s1ap_log->error("Found M-TMSI but could not find UE context\n"); - m_s1ap_log->console("Error: Found M-TMSI but could not find UE context\n"); - return false; - } - } - return true; -} - bool s1ap_nas_transport::handle_nas_service_request( uint32_t m_tmsi, uint32_t enb_ue_s1ap_id, From 0ddb3d39dca27986ac827ee47b1afba2e6784858 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 27 Aug 2018 18:13:42 +0100 Subject: [PATCH 3/9] Moved handle_imsi_attach_request_from_unknown_ue to nas.cc in static method. Working. --- srsepc/src/mme/nas.cc | 77 +++++++++++++++++++++++++++- srsepc/src/mme/s1ap_nas_transport.cc | 4 +- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 21c2bbdeb..956d2ea20 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -34,7 +34,6 @@ namespace srsepc{ - nas::nas() { m_pool = srslte::byte_buffer_pool::get_instance(); } @@ -188,6 +187,82 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, srslte::log *nas_log) { + nas *nas_ctx; + srslte::byte_buffer_t *nas_tx; + srslte::byte_buffer_pool *pool = srslte::byte_buffer_pool::get_instance(); + + //Get IMSI + uint64_t imsi = 0; + for(int i=0;i<=14;i++){ + imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + } + + //Create UE context + nas_ctx = new nas; + nas_ctx->init(args,s1ap,gtpc,hss,nas_log); + + //Save IMSI, MME UE S1AP Id and make sure UE is EMM_DEREGISTERED + nas_ctx->m_emm_ctx.imsi = imsi; + nas_ctx->m_emm_ctx.state = EMM_STATE_DEREGISTERED; + 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)); + 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)); + } + + uint8_t eps_bearer_id = pdn_con_req.eps_bearer_id; //TODO: Unused + nas_ctx->m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; + + //Initialize NAS count + nas_ctx->m_sec_ctx.ul_nas_count = 0; + nas_ctx->m_sec_ctx.dl_nas_count = 0; + + //Set eNB information + nas_ctx->m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&nas_ctx->m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + nas_ctx->m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; + + //Initialize E-RABs + for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { + nas_ctx->m_esm_ctx[i].state = ERAB_DEACTIVATED; + nas_ctx->m_esm_ctx[i].erab_id = i; + } + + //Save attach request type + 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)) { + nas_log->console("User not found. IMSI %015lu\n",nas_ctx->m_emm_ctx.imsi); + nas_log->info("User not found. IMSI %015lu\n",nas_ctx->m_emm_ctx.imsi); + delete nas_ctx; + return false; + } + + //Allocate eKSI for this authentication vector + //Here we assume a new security context thus a new eKSI + nas_ctx->m_sec_ctx.eksi=0; + + //Save the UE context + s1ap->add_nas_ctx_to_imsi_map(nas_ctx); + s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); + s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); + + //Pack NAS Authentication Request in Downlink NAS Transport msg + nas_tx = pool->allocate(); + 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); + pool->deallocate(nas_tx); + + nas_log->info("Downlink NAS: Sending Authentication Request\n"); + nas_log->console("Downlink NAS: Sending Authentication Request\n"); return true; } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 1ace0b17f..e17d15e27 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -88,8 +88,8 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA memcpy(nas_msg->msg, &init_ue->NAS_PDU.buffer, init_ue->NAS_PDU.n_octets); nas_msg->N_bytes = init_ue->NAS_PDU.n_octets; - uint64_t imsi; - uint32_t m_tmsi; + uint64_t imsi = 0; + uint32_t m_tmsi = 0; uint32_t enb_ue_s1ap_id = init_ue->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID; liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &pd, &msg_type); From 0d80ae795b3f95eec60c8e92cf0d5f3b87df306c Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 27 Aug 2018 19:17:23 +0100 Subject: [PATCH 4/9] Added IMSI attach from unknown UE as a static function. --- .../srslte/interfaces/epc_interfaces.h | 1 + srsepc/hdr/mme/nas.h | 14 ++- srsepc/hdr/mme/s1ap.h | 2 +- srsepc/src/mme/nas.cc | 92 +++++-------------- 4 files changed, 34 insertions(+), 75 deletions(-) diff --git a/lib/include/srslte/interfaces/epc_interfaces.h b/lib/include/srslte/interfaces/epc_interfaces.h index 4421b4f54..6655c02a1 100644 --- a/lib/include/srslte/interfaces/epc_interfaces.h +++ b/lib/include/srslte/interfaces/epc_interfaces.h @@ -53,6 +53,7 @@ public: virtual bool add_nas_ctx_to_mme_ue_s1ap_id_map(nas *nas_ctx) = 0; virtual bool add_ue_to_enb_set(int32_t enb_assoc, uint32_t mme_ue_s1ap_id) = 0; virtual bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id) = 0; + virtual bool delete_ue_ctx(uint64_t imsi) = 0; virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi) = 0; virtual nas* find_nas_ctx_from_imsi(uint64_t imsi) = 0; virtual bool send_initial_context_setup_request(uint64_t imsi, uint16_t erab_to_setup) = 0; diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 9d3d3457c..197b736e8 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -177,10 +177,16 @@ public: hss_interface_nas *hss, srslte::log *nas_log); - bool handle_imsi_attach_request_known_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); + static bool 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, + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); static bool handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 626a921c0..3e7ba7b79 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -94,7 +94,7 @@ public: bool release_ue_ecm_ctx(uint32_t mme_ue_s1ap_id); void release_ues_ecm_ctx_in_enb(int32_t enb_assoc); - bool delete_ue_ctx(uint64_t imsi); + virtual bool delete_ue_ctx(uint64_t imsi); uint32_t allocate_m_tmsi(uint64_t imsi); virtual uint64_t find_imsi_from_m_tmsi(uint32_t m_tmsi); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 956d2ea20..bfed2d099 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -157,10 +157,12 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id, return false; } } else { + 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_log->console("Attach Request -- IMSI-style attach request\n"); nas_log->info("Attach Request -- IMSI-style attach request\n"); - nas_ctx->handle_imsi_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req); + nas::handle_imsi_attach_request_known_ue(nas_ctx, 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_log->console("Attach Request -- GUTI-style attach request\n"); nas_log->info("Attach Request -- GUTI-style attach request\n"); @@ -267,81 +269,31 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, } bool -nas::handle_imsi_attach_request_known_ue( uint32_t enb_ue_s1ap_id, +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, - const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req ) + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) { - srslte::byte_buffer_t *nas_tx; + bool err; + //Delete previous GTP-U session + gtpc->send_delete_session_request(nas_ctx->m_emm_ctx.imsi); - //Get IMSI - uint64_t imsi = 0; - for(int i=0;i<=14;i++){ - imsi += attach_req.eps_mobile_id.imsi[i]*std::pow(10,14-i); + //Release previous context in the eNB, if present + if(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id != 0){ + s1ap->send_ue_context_release_command(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); } + //Delete previous NAS context + s1ap->delete_ue_ctx(nas_ctx->m_emm_ctx.imsi); - //Save IMSI, MME UE S1AP Id and make sure UE is EMM_DEREGISTERED - m_emm_ctx.imsi = imsi; - m_emm_ctx.state = EMM_STATE_DEREGISTERED; - m_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - - //Save UE network capabilities - memcpy(&m_sec_ctx.ue_network_cap, &attach_req.ue_network_cap, sizeof(LIBLTE_MME_UE_NETWORK_CAPABILITY_STRUCT)); - m_sec_ctx.ms_network_cap_present = attach_req.ms_network_cap_present; - if (attach_req.ms_network_cap_present) { - memcpy(&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 - m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; - - //Initialize NAS count - m_sec_ctx.ul_nas_count = 0; - m_sec_ctx.dl_nas_count = 0; - - //Set eNB information - m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - - //Save whether secure ESM information transfer is necessary - m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; - - //Initialize E-RABs - for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - m_esm_ctx[i].state = ERAB_DEACTIVATED; - m_esm_ctx[i].erab_id = i; - } - - //Save attach request type - m_emm_ctx.attach_type = attach_req.eps_attach_type; - - //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)) { - m_nas_log->console("User not found. IMSI %015lu\n",m_emm_ctx.imsi); - m_nas_log->info("User not found. IMSI %015lu\n",m_emm_ctx.imsi); - return false; - } - - //Allocate eKSI for this authentication vector - //Here we assume a new security context thus a new eKSI - m_sec_ctx.eksi=0; - - //Save the UE context - m_s1ap->add_nas_ctx_to_imsi_map(this); - m_s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(this); - m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,m_ecm_ctx.mme_ue_s1ap_id); - - //Pack NAS Authentication Request in Downlink NAS Transport msg - nas_tx = m_pool->allocate(); - 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_pool->deallocate(nas_tx); - - m_nas_log->info("Downlink NAS: Sending Authentication Request\n"); - m_nas_log->console("Downlink NAS: Sending Authentication Request\n"); - return true; + //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); + return err; } bool From 3337f21ffa1756c631ea57f364589406771f5f41 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 28 Aug 2018 15:29:26 +0100 Subject: [PATCH 5/9] Added handle GUTI attach from known UE again. --- srsepc/hdr/mme/nas.h | 23 ++-- srsepc/src/mme/nas.cc | 297 ++++++++++++++++++++++-------------------- 2 files changed, 168 insertions(+), 152 deletions(-) diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 197b736e8..8e55113f3 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -182,6 +182,7 @@ public: 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, + srslte::byte_buffer_t *nas_rx, nas_init_t args, s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, @@ -199,14 +200,20 @@ public: hss_interface_nas *hss, srslte::log *nas_log); - bool handle_guti_attach_request_known_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, - srslte::byte_buffer_t *nas_rx); - - //Service request Messages - //Dettach request Messages + static bool 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, + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_rx, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); + //Service request messages + //Dettach request messages + //Tracking area update request messages // /* Uplink NAS messages handling */ bool handle_authentication_response( srslte::byte_buffer_t *nas_rx); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index bfed2d099..77d251239 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -162,18 +162,16 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id, if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { nas_log->console("Attach Request -- IMSI-style attach request\n"); nas_log->info("Attach Request -- IMSI-style attach request\n"); - nas::handle_imsi_attach_request_known_ue(nas_ctx, enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, 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_log->console("Attach Request -- GUTI-style attach request\n"); nas_log->info("Attach Request -- GUTI-style attach request\n"); - nas_ctx->handle_guti_attach_request_known_ue(enb_ue_s1ap_id, enb_sri, attach_req, pdn_con_req, nas_rx); + 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 { nas_log->error("Unhandled Mobile Id type in attach request\n"); return false; } } - - //Log Attach Request information return true; } @@ -274,6 +272,7 @@ nas::handle_imsi_attach_request_known_ue( nas *nas_ctx, 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, + srslte::byte_buffer_t *nas_rx, nas_init_t args, s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, @@ -296,146 +295,6 @@ nas::handle_imsi_attach_request_known_ue( nas *nas_ctx, return err; } -bool -nas::handle_guti_attach_request_known_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, - srslte::byte_buffer_t *nas_rx) -{ - m_nas_log->console("Found UE context. IMSI: %015lu, old eNB UE S1ap Id %d, old MME UE S1AP Id %d\n",m_emm_ctx.imsi, m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id); - - bool msg_valid = false; - srslte::byte_buffer_t *nas_tx; - - //Check NAS integrity - m_sec_ctx.ul_nas_count++; - msg_valid = integrity_check(nas_rx); - if (msg_valid == true && m_emm_ctx.state == EMM_STATE_DEREGISTERED) { - m_nas_log->console("GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d\n",m_sec_ctx.ul_nas_count, m_sec_ctx.dl_nas_count); - m_nas_log->info ("GUTI Attach -- NAS Integrity OK. UL count %d, DL count %d\n",m_sec_ctx.ul_nas_count, m_sec_ctx.dl_nas_count); - - //Create new MME UE S1AP Identity - m_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - - m_emm_ctx.procedure_transaction_id = pdn_con_req.proc_transaction_id; - - //Save Attach type - m_emm_ctx.attach_type = attach_req.eps_attach_type; - - //Set eNB information - m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - - //Save whether secure ESM information transfer is necessary - m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; - - //Initialize E-RABs - for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - m_esm_ctx[i].state = ERAB_DEACTIVATED; - m_esm_ctx[i].erab_id = i; - } - - //Store context based on MME UE S1AP id - m_s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(this); - m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, m_ecm_ctx.mme_ue_s1ap_id); - - //Re-generate K_eNB - srslte::security_generate_k_enb(m_sec_ctx.k_asme, m_sec_ctx.ul_nas_count, m_sec_ctx.k_enb); - m_nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", m_sec_ctx.ul_nas_count); - m_nas_log->console("Generating KeNB with UL NAS COUNT: %d\n", m_sec_ctx.ul_nas_count); - m_nas_log->info_hex(m_sec_ctx.k_enb, 32, "Key eNodeB (k_enb)\n"); - - //Send reply - nas_tx = m_pool->allocate(); - if (m_ecm_ctx.eit) { - m_nas_log->console("Secure ESM information transfer requested.\n"); - m_nas_log->info("Secure ESM information transfer requested.\n"); - pack_esm_information_request(nas_tx); - m_s1ap->send_downlink_nas_transport(m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id,nas_tx, *enb_sri); - } else { - //Get subscriber info from HSS - uint8_t default_bearer=5; - m_hss->gen_update_loc_answer(m_emm_ctx.imsi,&m_esm_ctx[default_bearer].qci); - m_nas_log->debug("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); - m_nas_log->console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci); - m_gtpc->send_create_session_request(m_emm_ctx.imsi); - } - m_pool->deallocate(nas_tx); - return true; - } else { - if (m_emm_ctx.state != EMM_STATE_DEREGISTERED) { - m_nas_log->error("Received GUTI-Attach Request from attached user.\n"); - m_nas_log->console("Received GUTI-Attach Request from attached user.\n"); - - //Delete previous Ctx, restart authentication - //Detaching previoulsy attached UE. - m_gtpc->send_delete_session_request(m_emm_ctx.imsi); - if (m_ecm_ctx.mme_ue_s1ap_id != 0) { - m_s1ap->send_ue_context_release_command(m_ecm_ctx.mme_ue_s1ap_id); - } - } - m_sec_ctx.ul_nas_count = 0; - m_sec_ctx.dl_nas_count = 0; - - //Create new MME UE S1AP Identity - uint32_t new_mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - - //Make sure context from previous NAS connections is not present - if (m_ecm_ctx.mme_ue_s1ap_id!=0) { - m_s1ap->release_ue_ecm_ctx(m_ecm_ctx.mme_ue_s1ap_id); - } - m_ecm_ctx.mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - - //Set EMM as de-registered - m_emm_ctx.state = EMM_STATE_DEREGISTERED; - //Save Attach type - m_emm_ctx.attach_type = attach_req.eps_attach_type; - - //Set UE ECM context - m_ecm_ctx.mme_ue_s1ap_id = m_ecm_ctx.mme_ue_s1ap_id; - - //Set eNB information - m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - //Save whether secure ESM information transfer is necessary - m_ecm_ctx.eit = pdn_con_req.esm_info_transfer_flag_present; - - //Initialize E-RABs - for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { - m_esm_ctx[i].state = ERAB_DEACTIVATED; - m_esm_ctx[i].erab_id = i; - } - //Store context based on MME UE S1AP id - m_s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(this); - m_s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,m_ecm_ctx.mme_ue_s1ap_id); - - //NAS integrity failed. Re-start authentication process. - m_nas_log->console("GUTI Attach request NAS integrity failed.\n"); - m_nas_log->console("RE-starting authentication procedure.\n"); - - //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)) { - m_nas_log->console("User not found. IMSI %015lu\n",m_emm_ctx.imsi); - m_nas_log->info("User not found. IMSI %015lu\n",m_emm_ctx.imsi); - return false; - } - - //Restarting security context. Reseting eKSI to 0. - m_sec_ctx.eksi=0; - nas_tx = m_pool->allocate(); - 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, *enb_sri); - m_pool->deallocate(nas_tx); - m_nas_log->info("Downlink NAS: Sent Authentication Request\n"); - m_nas_log->console("Downlink NAS: Sent Authentication Request\n"); - return true; - } -} - bool nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, struct sctp_sndrcvinfo *enb_sri, @@ -507,6 +366,156 @@ nas::handle_guti_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, return true; } +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, + const LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT &pdn_con_req, + srslte::byte_buffer_t *nas_rx, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) +{ + bool msg_valid = false; + srslte::byte_buffer_t *nas_tx; + srslte::byte_buffer_pool *pool = srslte::byte_buffer_pool::get_instance(); + + emm_ctx_t *emm_ctx = &nas_ctx->m_emm_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: %015lu, 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 + sec_ctx->ul_nas_count++; + 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); + + //Create new MME UE S1AP Identity + ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + + emm_ctx->procedure_transaction_id = pdn_con_req.proc_transaction_id; + + //Save Attach type + emm_ctx->attach_type = attach_req.eps_attach_type; + + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = pdn_con_req.esm_info_transfer_flag_present; + + //Initialize E-RABs + for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { + nas_ctx->m_esm_ctx[i].state = ERAB_DEACTIVATED; + nas_ctx->m_esm_ctx[i].erab_id = i; + } + + //Store context based on MME UE S1AP id + s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); + s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id, ecm_ctx->mme_ue_s1ap_id); + + //Re-generate K_eNB + srslte::security_generate_k_enb(sec_ctx->k_asme, sec_ctx->ul_nas_count, sec_ctx->k_enb); + nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); + nas_log->console("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); + nas_log->info_hex(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)\n"); + + //Send reply + nas_tx = pool->allocate(); + if (ecm_ctx->eit) { + nas_log->console("Secure ESM information transfer requested.\n"); + nas_log->info("Secure ESM information transfer requested.\n"); + nas_ctx->pack_esm_information_request(nas_tx); + s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, nas_tx, *enb_sri); + } else { + //Get subscriber info from HSS + uint8_t default_bearer=5; + hss->gen_update_loc_answer(emm_ctx->imsi,&nas_ctx->m_esm_ctx[default_bearer].qci); + nas_log->debug("Getting subscription information -- QCI %d\n", nas_ctx->m_esm_ctx[default_bearer].qci); + nas_log->console("Getting subscription information -- QCI %d\n", nas_ctx->m_esm_ctx[default_bearer].qci); + gtpc->send_create_session_request(emm_ctx->imsi); + } + pool->deallocate(nas_tx); + return true; + } else { + if (emm_ctx->state != EMM_STATE_DEREGISTERED) { + nas_log->error("Received GUTI-Attach Request from attached user.\n"); + nas_log->console("Received GUTI-Attach Request from attached user.\n"); + + //Delete previous Ctx, restart authentication + //Detaching previoulsy attached UE. + gtpc->send_delete_session_request(emm_ctx->imsi); + if (ecm_ctx->mme_ue_s1ap_id != 0) { + s1ap->send_ue_context_release_command(ecm_ctx->mme_ue_s1ap_id); + } + } + sec_ctx->ul_nas_count = 0; + sec_ctx->dl_nas_count = 0; + + //Create new MME UE S1AP Identity + uint32_t new_mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + + //Make sure context from previous NAS connections is not present + if (ecm_ctx->mme_ue_s1ap_id!=0) { + s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + } + ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + + //Set EMM as de-registered + emm_ctx->state = EMM_STATE_DEREGISTERED; + //Save Attach type + emm_ctx->attach_type = attach_req.eps_attach_type; + + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = pdn_con_req.esm_info_transfer_flag_present; + + //Initialize E-RABs + for (uint i = 0 ; i< MAX_ERABS_PER_UE; i++) { + nas_ctx->m_esm_ctx[i].state = ERAB_DEACTIVATED; + nas_ctx->m_esm_ctx[i].erab_id = i; + } + //Store context based on MME UE S1AP id + s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); + s1ap->add_ue_to_enb_set(enb_sri->sinfo_assoc_id,ecm_ctx->mme_ue_s1ap_id); + + //NAS integrity failed. Re-start authentication process. + nas_log->console("GUTI Attach request NAS integrity failed.\n"); + nas_log->console("RE-starting authentication procedure.\n"); + + //Get Authentication Vectors from HSS + if (!hss->gen_auth_info_answer(emm_ctx->imsi, sec_ctx->k_asme, sec_ctx->autn, sec_ctx->rand, sec_ctx->xres)) { + nas_log->console("User not found. IMSI %015lu\n", emm_ctx->imsi); + nas_log->info("User not found. IMSI %015lu\n", emm_ctx->imsi); + return false; + } + + //Restarting security context. Reseting eKSI to 0. + sec_ctx->eksi=0; + nas_tx = pool->allocate(); + nas_ctx->pack_authentication_request(nas_tx); + + //Send reply to eNB + s1ap->send_downlink_nas_transport(ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id,nas_tx, *enb_sri); + pool->deallocate(nas_tx); + nas_log->info("Downlink NAS: Sent Authentication Request\n"); + nas_log->console("Downlink NAS: Sent Authentication Request\n"); + return true; + } +} + +//Service Requests + /*************************************** * * Handle Uplink NAS Transport messages From 4313fb1e72cc58d043d72598297f4e65f9af1210 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 28 Aug 2018 17:28:31 +0100 Subject: [PATCH 6/9] Making sure M-TMSI is in host order in other small bug fixes. --- srsepc/src/hss/hss.cc | 2 +- srsepc/src/main.cc | 3 +++ srsepc/src/mme/nas.cc | 19 +++++-------------- srsepc/src/mme/s1ap.cc | 4 ++-- srsepc/src/mme/s1ap_nas_transport.cc | 4 ++++ 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 6bbf86097..844a3a92b 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -614,7 +614,7 @@ hss::increment_ue_sqn(uint64_t imsi) } increment_sqn(ue_ctx->sqn,ue_ctx->sqn); - m_hss_log->debug("Incremented SQN (IMSI: %" PRIu64 ")" PRIu64 "\n", imsi); + m_hss_log->debug("Incremented SQN -- IMSI: %" PRIu64 "\n", imsi); m_hss_log->debug_hex(ue_ctx->sqn, 6, "SQN: "); } diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 599564c6f..15a6b35f9 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -257,6 +257,9 @@ parse_args(all_args_t *args, int argc, char* argv[]) { if(!vm.count("log.hss_hex_limit")) { args->log_args.hss_hex_limit = args->log_args.all_hex_limit; } + if(!vm.count("log.nas_hex_limit")) { + args->log_args.nas_hex_limit = args->log_args.all_hex_limit; + } } // Check user database diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 77d251239..bd0d5be51 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -145,30 +145,20 @@ nas::handle_attach_request( uint32_t enb_ue_s1ap_id, { //Get attach type from attach request if (attach_req.eps_mobile_id.type_of_id == LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI) { - nas_log->console("Attach Request -- IMSI-style attach request\n"); - nas_log->info("Attach Request -- IMSI-style attach request\n"); 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_log->console("Attach Request -- GUTI-style attach request\n"); - nas_log->info("Attach Request -- GUTI-style attach request\n"); 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 { - nas_log->error("Unhandled Mobile Id type in attach request\n"); return false; } } else { 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_log->console("Attach Request -- IMSI-style attach request\n"); - nas_log->info("Attach Request -- IMSI-style attach request\n"); 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_log->console("Attach Request -- GUTI-style attach request\n"); - nas_log->info("Attach Request -- GUTI-style attach request\n"); 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 { - nas_log->error("Unhandled Mobile Id type in attach request\n"); return false; } } @@ -201,9 +191,10 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, nas_ctx = new nas; nas_ctx->init(args,s1ap,gtpc,hss,nas_log); - //Save IMSI, MME UE S1AP Id and make sure UE is EMM_DEREGISTERED + //Save IMSI, eNB UE S1AP Id, MME UE S1AP Id and make sure UE is EMM_DEREGISTERED nas_ctx->m_emm_ctx.imsi = imsi; nas_ctx->m_emm_ctx.state = EMM_STATE_DEREGISTERED; + nas_ctx->m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; nas_ctx->m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); //Save UE network capabilities @@ -221,7 +212,6 @@ nas::handle_imsi_attach_request_unknown_ue( uint32_t enb_ue_s1ap_id, nas_ctx->m_sec_ctx.dl_nas_count = 0; //Set eNB information - nas_ctx->m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; memcpy(&nas_ctx->m_ecm_ctx.enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); //Save whether secure ESM information transfer is necessary @@ -654,7 +644,7 @@ nas::handle_attach_complete(srslte::byte_buffer_t *nas_rx) 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->console("Sending EMM Information"); + m_nas_log->console("Sending EMM Information\n"); m_nas_log->info("Sending EMM Information\n"); } m_emm_ctx.state = EMM_STATE_REGISTERED; @@ -1100,8 +1090,9 @@ nas::pack_attach_accept(srslte::byte_buffer_t *nas_buffer) ); memcpy(&nas_buffer->msg[1],mac,4); - m_nas_log->info("Packed Attach Accept\n"); + //Log attach accept info + m_nas_log->info("Packed Attach Accept\n"); return true; } diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 51c76e17d..f51d1a48d 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -587,10 +587,10 @@ s1ap::find_imsi_from_m_tmsi(uint32_t m_tmsi) { std::map::iterator it = m_tmsi_to_imsi.find(m_tmsi); if (it != m_tmsi_to_imsi.end()) { - m_s1ap_log->debug("Found IMSI %015lu from M-TMSI 0x%x", it->second, m_tmsi); + m_s1ap_log->debug("Found IMSI %015lu from M-TMSI 0x%x\n", it->second, m_tmsi); return it->second; } else { - m_s1ap_log->debug("Could not find IMSI from M-TMSI 0x%x", m_tmsi); + m_s1ap_log->debug("Could not find IMSI from M-TMSI 0x%x\n", m_tmsi); return 0; } } diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index e17d15e27..09e884545 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -105,6 +105,10 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA nas_init.apn = m_s1ap->m_s1ap_args.mme_apn; nas_init.dns = m_s1ap->m_s1ap_args.dns_addr; + if(init_ue->S_TMSI_present){ + m_tmsi = ntohl(*((uint32_t*) &init_ue->S_TMSI.m_TMSI.buffer)); + } + switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_REQUEST: From a9e5b3b8e9432cc0d75f0645d22521dab9df4a33 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 29 Aug 2018 14:52:09 +0100 Subject: [PATCH 7/9] Changed service request to nas.cc --- srsepc/hdr/mme/nas.h | 27 ++++--- srsepc/src/mme/nas.cc | 109 +++++++++++++++++++++++++++ srsepc/src/mme/s1ap_nas_transport.cc | 7 -- 3 files changed, 127 insertions(+), 16 deletions(-) diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 8e55113f3..69821d558 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -212,18 +212,27 @@ public: hss_interface_nas *hss, srslte::log *nas_log); //Service request messages + static bool handle_service_request( uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, + struct sctp_sndrcvinfo *enb_sri, + srslte::byte_buffer_t *nas_rx, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); //Dettach request messages //Tracking area update request messages - // + /* Uplink NAS messages handling */ - bool handle_authentication_response( srslte::byte_buffer_t *nas_rx); - bool handle_security_mode_complete( srslte::byte_buffer_t *nas_rx); - bool handle_attach_complete( srslte::byte_buffer_t *nas_rx); - bool handle_esm_information_response( srslte::byte_buffer_t *nas_rx); - bool handle_identity_response( srslte::byte_buffer_t *nas_rx); - bool handle_tracking_area_update_request( srslte::byte_buffer_t *nas_rx); - bool handle_authentication_failure( srslte::byte_buffer_t *nas_rx); - bool handle_nas_detach_request( srslte::byte_buffer_t *nas_rx); + bool handle_authentication_response (srslte::byte_buffer_t *nas_rx); + bool handle_security_mode_complete (srslte::byte_buffer_t *nas_rx); + bool handle_attach_complete (srslte::byte_buffer_t *nas_rx); + bool handle_esm_information_response (srslte::byte_buffer_t *nas_rx); + bool handle_identity_response (srslte::byte_buffer_t *nas_rx); + bool handle_tracking_area_update_request (srslte::byte_buffer_t *nas_rx); + bool handle_authentication_failure (srslte::byte_buffer_t *nas_rx); + bool handle_nas_detach_request (srslte::byte_buffer_t *nas_rx); /* Downlink NAS messages packing */ bool pack_authentication_request (srslte::byte_buffer_t *nas_buffer); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index bd0d5be51..afa6e5067 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -505,6 +505,115 @@ nas::handle_guti_attach_request_known_ue( nas *nas_ctx, } //Service Requests + 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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) +{ + nas_log->info("Service request -- S-TMSI 0x%x\n", m_tmsi); + nas_log->console("Service request -- S-TMSI 0x%x\n", m_tmsi); + nas_log->info("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + nas_log->console("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + + bool mac_valid = false; + LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; + srslte::byte_buffer_pool *pool = srslte::byte_buffer_pool::get_instance(); + + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_rx, &service_req); + if (err !=LIBLTE_SUCCESS) { + nas_log->error("Could not unpack service request\n"); + return false; + } + + uint64_t imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); + if (imsi == 0) { + nas_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + nas_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + nas nas_tmp; + nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + srslte::byte_buffer_t *nas_tx = pool->allocate(); + nas_tmp.pack_service_reject(nas_tx); + s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); + pool->deallocate(nas_tx); + return true; + } + + nas *nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); + if (nas_ctx == NULL || nas_ctx->m_emm_ctx.state != EMM_STATE_REGISTERED) { + nas_log->console("UE is not EMM-Registered.\n"); + nas_log->error("UE is not EMM-Registered.\n"); + nas nas_tmp; + nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; + nas_tmp.m_ecm_ctx.mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + srslte::byte_buffer_t *nas_tx = pool->allocate(); + nas_tmp.pack_service_reject(nas_tx); + s1ap->send_downlink_nas_transport(enb_ue_s1ap_id, nas_tmp.m_ecm_ctx.mme_ue_s1ap_id, nas_tx, *enb_sri); + pool->deallocate(nas_tx); + return true; + } + emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; + ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; + sec_ctx_t *sec_ctx = &nas_ctx->m_sec_ctx; + + sec_ctx->ul_nas_count++; + mac_valid = nas_ctx->short_integrity_check(nas_rx); + if (mac_valid) { + nas_log->console("Service Request -- Short MAC valid\n"); + nas_log->info("Service Request -- Short MAC valid\n"); + if(ecm_ctx->state == ECM_STATE_CONNECTED) { + 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); + s1ap->send_ue_context_release_command(ecm_ctx->mme_ue_s1ap_id); + s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); + } + + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + + //UE not connect. Connect normally. + nas_log->console("Service Request -- User is ECM DISCONNECTED\n"); + nas_log->info("Service Request -- User is ECM DISCONNECTED\n"); + + //Create ECM context + ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + + //Set eNB information + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); + + //Save whether secure ESM information transfer is necessary + ecm_ctx->eit = false; + + //Get UE IP, and uplink F-TEID + if(emm_ctx->ue_ip.s_addr == 0 ){ + nas_log->error("UE has no valid IP assigned upon reception of service request"); + } + + nas_log->console("UE previously assigned IP: %s",inet_ntoa(emm_ctx->ue_ip)); + + //Re-generate K_eNB + srslte::security_generate_k_enb(sec_ctx->k_asme, sec_ctx->ul_nas_count, sec_ctx->k_enb); + nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); + nas_log->console("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); + nas_log->info_hex(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)\n"); + nas_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); + + //Save UE ctx to MME UE S1AP id + s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); + s1ap->send_initial_context_setup_request(imsi,5); + } else { + nas_log->console("Service Request -- Short MAC invalid. Ignoring service request\n"); + nas_log->console("Service Request -- Short MAC invalid. Ignoring service request\n"); + } + return true; +} /*************************************** * diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 09e884545..0c74494ce 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -294,13 +294,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA m_pool->deallocate(nas_msg); return false; } - - if (*reply_flag == true) { - m_s1ap_log->console("DL NAS: Sent Downlink NAS Message. DL NAS Count=%d, UL NAS count=%d\n", sec_ctx->dl_nas_count, sec_ctx->ul_nas_count); - m_s1ap_log->info("DL NAS: Sent Downlink NAS message. DL NAS Count=%d, UL NAS count=%d\n", sec_ctx->dl_nas_count, sec_ctx->ul_nas_count); - m_s1ap_log->info("DL NAS: MME UE S1AP id %d\n",ecm_ctx->mme_ue_s1ap_id); - m_s1ap_log->console("DL NAS: MME UE S1AP id %d\n",ecm_ctx->mme_ue_s1ap_id); - } m_pool->deallocate(nas_msg); return true; } From d2cb01ce87bcee9233668381765e51afb8ee8ed6 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 29 Aug 2018 14:56:55 +0100 Subject: [PATCH 8/9] Deleted old service request. --- srsepc/src/mme/s1ap_nas_transport.cc | 104 +-------------------------- 1 file changed, 3 insertions(+), 101 deletions(-) diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 0c74494ce..2874fe16d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -115,12 +115,13 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->console("Received Initial UE message -- Attach Request\n"); m_s1ap_log->info("Received Initial UE message -- Attach Request\n"); err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, - m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Service Request\n"); m_s1ap_log->info("Received Initial UE message -- Service Request\n"); - err = handle_nas_service_request(m_tmsi, enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); + err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: m_s1ap_log->console("Received Initial UE message -- Detach Request\n"); @@ -298,105 +299,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA return true; } -bool -s1ap_nas_transport::handle_nas_service_request( uint32_t m_tmsi, - uint32_t enb_ue_s1ap_id, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - m_s1ap_log->info("Service request -- S-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->console("Service request -- S-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->info("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - m_s1ap_log->console("Service request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - - bool mac_valid = false; - LIBLTE_MME_SERVICE_REQUEST_MSG_STRUCT service_req; - - LIBLTE_ERROR_ENUM err = liblte_mme_unpack_service_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &service_req); - if (err !=LIBLTE_SUCCESS) { - m_s1ap_log->error("Could not unpack service request\n"); - return false; - } - - std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); - if (it == m_s1ap->m_tmsi_to_imsi.end()) { - m_s1ap_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - nas nas_tmp; - nas_tmp.m_ecm_ctx.enb_ue_s1ap_id = enb_ue_s1ap_id; - nas_tmp.pack_service_reject(reply_buffer); - *reply_flag = true; - return true; - } - - nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(it->second); - if (nas_ctx == NULL || nas_ctx->m_emm_ctx.state != EMM_STATE_REGISTERED) { - m_s1ap_log->console("UE is not EMM-Registered.\n"); - m_s1ap_log->error("UE is not EMM-Registered.\n"); - nas_ctx->pack_service_reject(reply_buffer); - *reply_flag = true; - return true; - } - emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; - ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; - sec_ctx_t *sec_ctx = &nas_ctx->m_sec_ctx; - - sec_ctx->ul_nas_count++; - mac_valid = nas_ctx->short_integrity_check(nas_msg); - if (mac_valid) { - m_s1ap_log->console("Service Request -- Short MAC valid\n"); - m_s1ap_log->info("Service Request -- Short MAC valid\n"); - if(ecm_ctx->state == ECM_STATE_CONNECTED) { - m_s1ap_log->error("Service Request -- User is ECM CONNECTED\n"); - - //Release previous context - m_s1ap_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); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(nas_ctx); - m_s1ap->release_ue_ecm_ctx(ecm_ctx->mme_ue_s1ap_id); - } - - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - - //UE not connect. Connect normally. - m_s1ap_log->console("Service Request -- User is ECM DISCONNECTED\n"); - m_s1ap_log->info("Service Request -- User is ECM DISCONNECTED\n"); - - //Create ECM context - ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - - //Set eNB information - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - memcpy(&ecm_ctx->enb_sri, enb_sri, sizeof(struct sctp_sndrcvinfo)); - - //Save whether secure ESM information transfer is necessary - ecm_ctx->eit = false; - - //Get UE IP, and uplink F-TEID - if(emm_ctx->ue_ip.s_addr == 0 ){ - m_s1ap_log->error("UE has no valid IP assigned upon reception of service request"); - } - - m_s1ap_log->console("UE previously assigned IP: %s",inet_ntoa(emm_ctx->ue_ip)); - - //Re-generate K_eNB - srslte::security_generate_k_enb(sec_ctx->k_asme, sec_ctx->ul_nas_count, sec_ctx->k_enb); - m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); - m_s1ap_log->console("Generating KeNB with UL NAS COUNT: %d\n", sec_ctx->ul_nas_count); - m_s1ap_log->info_hex(sec_ctx->k_enb, 32, "Key eNodeB (k_enb)\n"); - m_s1ap_log->console("UE Ctr TEID %d\n", emm_ctx->sgw_ctrl_fteid.teid); - - //Save UE ctx to MME UE S1AP id - m_s1ap->add_nas_ctx_to_mme_ue_s1ap_id_map(nas_ctx); - m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(nas_ctx, 5); - } else { - m_s1ap_log->console("Service Request -- Short MAC invalid. Ignoring service request\n"); - m_s1ap_log->console("Service Request -- Short MAC invalid. Ignoring service request\n"); - } - return true; -} - bool s1ap_nas_transport::handle_nas_detach_request(uint32_t m_tmsi, uint32_t enb_ue_s1ap_id, From 9350e038103f3a26fdb705a6f80bd7f75c3dafb4 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 29 Aug 2018 17:47:34 +0100 Subject: [PATCH 9/9] Changed detach request and tracking area update request to nas.cc --- srsepc/hdr/mme/nas.h | 24 +++++- srsepc/src/mme/nas.cc | 111 ++++++++++++++++++++++++--- srsepc/src/mme/s1ap_nas_transport.cc | 98 +++-------------------- 3 files changed, 133 insertions(+), 100 deletions(-) diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index 69821d558..51a561355 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -221,9 +221,29 @@ public: gtpc_interface_nas *gtpc, hss_interface_nas *hss, srslte::log *nas_log); + //Dettach request messages + static bool handle_detach_request( uint32_t m_tmsi, + uint32_t enb_ue_s1ap_id, + struct sctp_sndrcvinfo *enb_sri, + srslte::byte_buffer_t *nas_rx, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); + //Tracking area update request messages - + static bool 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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log); + /* Uplink NAS messages handling */ bool handle_authentication_response (srslte::byte_buffer_t *nas_rx); bool handle_security_mode_complete (srslte::byte_buffer_t *nas_rx); @@ -232,7 +252,7 @@ public: bool handle_identity_response (srslte::byte_buffer_t *nas_rx); bool handle_tracking_area_update_request (srslte::byte_buffer_t *nas_rx); bool handle_authentication_failure (srslte::byte_buffer_t *nas_rx); - bool handle_nas_detach_request (srslte::byte_buffer_t *nas_rx); + bool handle_detach_request (srslte::byte_buffer_t *nas_rx); /* Downlink NAS messages packing */ bool pack_authentication_request (srslte::byte_buffer_t *nas_buffer); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index afa6e5067..02a72908d 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -505,15 +505,16 @@ nas::handle_guti_attach_request_known_ue( nas *nas_ctx, } //Service Requests - 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, - nas_init_t args, - s1ap_interface_nas *s1ap, - gtpc_interface_nas *gtpc, - hss_interface_nas *hss, - srslte::log *nas_log) +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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) { nas_log->info("Service request -- S-TMSI 0x%x\n", m_tmsi); nas_log->console("Service request -- S-TMSI 0x%x\n", m_tmsi); @@ -615,6 +616,96 @@ nas::handle_guti_attach_request_known_ue( nas *nas_ctx, return true; } +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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) +{ + nas_log->info("Detach Request -- S-TMSI 0x%x\n", m_tmsi); + nas_log->console("Detach Request -- S-TMSI 0x%x\n", m_tmsi); + nas_log->info("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + nas_log->console("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + + bool mac_valid = false; + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_req; + + LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_rx, &detach_req); + if (err !=LIBLTE_SUCCESS) { + nas_log->error("Could not unpack detach request\n"); + return false; + } + + uint64_t imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); + if (imsi == 0) { + nas_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + nas_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + return true; + } + + nas *nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); + if (nas_ctx == NULL) { + nas_log->console("Could not find UE context from IMSI\n"); + nas_log->error("Could not find UE context from IMSI\n"); + return true; + } + + emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; + ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; + sec_ctx_t *sec_ctx = &nas_ctx->m_sec_ctx; + + gtpc->send_delete_session_request(emm_ctx->imsi); + emm_ctx->state = EMM_STATE_DEREGISTERED; + sec_ctx->ul_nas_count++; + + nas_log->console("Received. M-TMSI 0x%x\n", m_tmsi); + //Received detach request as an initial UE message + //eNB created new ECM context to send the detach request; this needs to be cleared. + ecm_ctx->mme_ue_s1ap_id = s1ap->get_next_mme_ue_s1ap_id(); + ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; + s1ap->send_ue_context_release_command(ecm_ctx->mme_ue_s1ap_id); + return true; +} + +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, + nas_init_t args, + s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) +{ + nas_log->info("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); + nas_log->console("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); + nas_log->info("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + nas_log->console("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); + + nas_log->console("Warning: Tracking area update requests are not handled yet.\n"); + nas_log->warning("Tracking area update requests are not handled yet.\n"); + + uint64_t imsi = s1ap->find_imsi_from_m_tmsi(m_tmsi); + if (imsi == 0) { + nas_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + nas_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); + return true; + } + + nas *nas_ctx = s1ap->find_nas_ctx_from_imsi(imsi); + emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; + ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; + + sec_ctx_t *sec_ctx = &nas_ctx->m_sec_ctx; + + sec_ctx->ul_nas_count++; //Increment the NAS count, not to break the security ctx + return true; +} /*************************************** * * Handle Uplink NAS Transport messages @@ -916,7 +1007,7 @@ nas::handle_authentication_failure(srslte::byte_buffer_t *nas_rx) } bool -nas::handle_nas_detach_request(srslte::byte_buffer_t *nas_msg) +nas::handle_detach_request(srslte::byte_buffer_t *nas_msg) { m_nas_log->console("Detach request -- IMSI %015lu\n", m_emm_ctx.imsi); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 2874fe16d..e42fa3d29 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -115,23 +115,25 @@ s1ap_nas_transport::handle_initial_ue_message(LIBLTE_S1AP_MESSAGE_INITIALUEMESSA m_s1ap_log->console("Received Initial UE message -- Attach Request\n"); m_s1ap_log->info("Received Initial UE message -- Attach Request\n"); err = nas::handle_attach_request(enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, - m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_SECURITY_HDR_TYPE_SERVICE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Service Request\n"); m_s1ap_log->info("Received Initial UE message -- Service Request\n"); err = nas::handle_service_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, - m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: m_s1ap_log->console("Received Initial UE message -- Detach Request\n"); m_s1ap_log->info("Received Initial UE message -- Detach Request\n"); - err = handle_nas_detach_request(m_tmsi, enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); + err = nas::handle_detach_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REQUEST: m_s1ap_log->console("Received Initial UE message -- Tracking Area Update Request\n"); m_s1ap_log->info("Received Initial UE message -- Tracking Area Update Request\n"); - err = handle_nas_tracking_area_update_request(m_tmsi, enb_ue_s1ap_id, nas_msg, reply_buffer,reply_flag, enb_sri); + err = nas::handle_tracking_area_update_request(m_tmsi, enb_ue_s1ap_id, enb_sri, nas_msg, nas_init, + m_s1ap, m_mme_gtpc, m_hss, m_s1ap->m_nas_log); break; default: m_s1ap_log->info("Unhandled Initial UE Message 0x%x \n", msg_type); @@ -215,11 +217,11 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: m_s1ap_log->info("Plain Protected UL NAS: Detach Request\n"); m_s1ap_log->console("Plain Protected UL NAS: Detach Request\n"); - nas_ctx->handle_nas_detach_request(nas_msg); + nas_ctx->handle_detach_request(nas_msg); break; default: - m_s1ap_log->warning("Unhandled Plain NAS message 0x%x\n", msg_type ); - m_s1ap_log->console("Unhandled Plain NAS message 0x%x\n", msg_type ); + m_s1ap_log->warning("Unhandled Plain NAS message 0x%x\n", msg_type); + m_s1ap_log->console("Unhandled Plain NAS message 0x%x\n", msg_type); m_pool->deallocate(nas_msg); return false; } @@ -282,7 +284,7 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: m_s1ap_log->info("Integrity Protected UL NAS: Detach Request\n"); m_s1ap_log->console("Integrity Protected UL NAS: Detach Request\n"); - nas_ctx->handle_nas_detach_request(nas_msg); + nas_ctx->handle_detach_request(nas_msg); break; default: m_s1ap_log->warning("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type)); @@ -299,86 +301,6 @@ s1ap_nas_transport::handle_uplink_nas_transport(LIBLTE_S1AP_MESSAGE_UPLINKNASTRA return true; } -bool -s1ap_nas_transport::handle_nas_detach_request(uint32_t m_tmsi, - uint32_t enb_ue_s1ap_id, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - m_s1ap_log->info("Detach Request -- S-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->console("Detach Request -- S-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->info("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - m_s1ap_log->console("Detach Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - - bool mac_valid = false; - LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_req; - - LIBLTE_ERROR_ENUM err = liblte_mme_unpack_detach_request_msg((LIBLTE_BYTE_MSG_STRUCT*) nas_msg, &detach_req); - if (err !=LIBLTE_SUCCESS) { - m_s1ap_log->error("Could not unpack detach request\n"); - return false; - } - - std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); - if (it == m_s1ap->m_tmsi_to_imsi.end()) { - m_s1ap_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - return true; - } - - nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(it->second); - emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; - ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; - sec_ctx_t *sec_ctx = &nas_ctx->m_sec_ctx; - - m_mme_gtpc->send_delete_session_request(emm_ctx->imsi); - emm_ctx->state = EMM_STATE_DEREGISTERED; - sec_ctx->ul_nas_count++; - - m_s1ap_log->console("Received. M-TMSI 0x%x\n", m_tmsi); - //Received detach request as an initial UE message - //eNB created new ECM context to send the detach request; this needs to be cleared. - ecm_ctx->mme_ue_s1ap_id = m_s1ap->get_next_mme_ue_s1ap_id(); - ecm_ctx->enb_ue_s1ap_id = enb_ue_s1ap_id; - m_s1ap->m_s1ap_ctx_mngmt_proc->send_ue_context_release_command(nas_ctx); - return true; -} - -bool -s1ap_nas_transport::handle_nas_tracking_area_update_request(uint32_t m_tmsi, - uint32_t enb_ue_s1ap_id, - srslte::byte_buffer_t *nas_msg, - srslte::byte_buffer_t *reply_buffer, - bool* reply_flag, - struct sctp_sndrcvinfo *enb_sri) -{ - m_s1ap_log->info("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->console("Tracking Area Update Request -- S-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->info("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - m_s1ap_log->console("Tracking Area Update Request -- eNB UE S1AP Id %d\n", enb_ue_s1ap_id); - - m_s1ap_log->console("Warning: Tracking area update requests are not handled yet.\n"); - m_s1ap_log->warning("Tracking area update requests are not handled yet.\n"); - - std::map::iterator it = m_s1ap->m_tmsi_to_imsi.find(m_tmsi); - if (it == m_s1ap->m_tmsi_to_imsi.end()) { - m_s1ap_log->console("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - m_s1ap_log->error("Could not find IMSI from M-TMSI. M-TMSI 0x%x\n", m_tmsi); - return true; - } - - nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(it->second); - emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; - ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; - - sec_ctx_t *sec_ctx = &nas_ctx->m_sec_ctx; - - sec_ctx->ul_nas_count++; //Increment the NAS count, not to break the security ctx - return true; -} - bool s1ap_nas_transport::send_downlink_nas_transport(uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, srslte::byte_buffer_t *nas_msg, struct sctp_sndrcvinfo enb_sri) {