From 4ba777c9c31dac779e9e0f8b44a43d7f322b95bf Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 24 Jul 2018 18:38:16 +0100 Subject: [PATCH] Added nas log. Fixed gen_auth_info_anwser. Authentication is working again. --- srsepc/hdr/hss/hss.h | 6 ++-- srsepc/hdr/mme/mme.h | 12 ++----- srsepc/hdr/mme/mme_gtpc.h | 9 +++--- srsepc/hdr/mme/nas.h | 1 + srsepc/hdr/mme/s1ap.h | 3 +- srsepc/src/main.cc | 16 ++++++++-- srsepc/src/mme/mme.cc | 26 ++++++--------- srsepc/src/mme/mme_gtpc.cc | 47 +++++++++++++--------------- srsepc/src/mme/nas.cc | 13 +++++++- srsepc/src/mme/s1ap.cc | 3 +- srsepc/src/mme/s1ap_nas_transport.cc | 1 + 11 files changed, 74 insertions(+), 63 deletions(-) diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index aff99032e..922c7cd85 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -77,10 +77,10 @@ public: int init(hss_args_t *hss_args, srslte::log_filter* hss_log); void stop(void); - bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); - bool gen_update_loc_answer(uint64_t imsi, uint8_t* qci); + virtual bool gen_auth_info_answer(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres); + virtual bool gen_update_loc_answer(uint64_t imsi, uint8_t* qci); - bool resync_sqn(uint64_t imsi, uint8_t *auts); + virtual bool resync_sqn(uint64_t imsi, uint8_t *auts); private: diff --git a/srsepc/hdr/mme/mme.h b/srsepc/hdr/mme/mme.h index f7a080637..058009487 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -44,15 +44,6 @@ namespace srsepc{ -/* -typedef struct { - std::string s1ap_level; - std::string all_level; - int s1ap_hex_limit; - std::string filename; -}log_args_t; -*/ - typedef struct{ s1ap_args_t s1ap_args; //diameter_args_t diameter_args; @@ -66,7 +57,7 @@ class mme: public: static mme* get_instance(void); static void cleanup(void); - int init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log, hss_interface_nas * hss); + int init(mme_args_t* args, srslte::log_filter *nas_log, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log, hss_interface_nas * hss); void stop(); int get_s1_mme(); void run_thread(); @@ -83,6 +74,7 @@ private: srslte::byte_buffer_pool *m_pool; /*Logs*/ + srslte::log_filter *m_nas_log; srslte::log_filter *m_s1ap_log; srslte::log_filter *m_mme_gtpc_log; }; diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 9c502a576..08cd30e42 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -39,6 +39,7 @@ class spgw; class s1ap; class mme_gtpc + : public gtpc_interface_nas { public: @@ -52,12 +53,12 @@ public: bool init(srslte::log_filter *mme_gtpc_log); uint32_t get_new_ctrl_teid(); - void send_create_session_request(uint64_t imsi); - void handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); - void send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t *enb_fteid); + virtual bool send_create_session_request(uint64_t imsi); + bool handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu); + virtual bool send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t *enb_fteid); void handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu); void send_release_access_bearers_request(uint64_t imsi); - void send_delete_session_request(uint64_t imsi); + virtual bool send_delete_session_request(uint64_t imsi); private: diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index b4d999e39..50cab951a 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -135,6 +135,7 @@ class nas { public: nas(); + void init(s1ap_interface_nas *s1ap, gtpc_interface_nas *gtpc, hss_interface_nas *hss, srslte::log *nas_log); /*Initial UE messages*/ bool handle_nas_attach_request( uint32_t enb_ue_s1ap_id, diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index ec7ea2d51..a8a813831 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -63,7 +63,7 @@ public: static void cleanup(); int enb_listen(); - int init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_nas * hss_); + int init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, srslte::log_filter *nas_log, hss_interface_nas * hss_); void stop(); int get_s1_mme(); @@ -100,6 +100,7 @@ public: s1ap_args_t m_s1ap_args; srslte::log_filter *m_s1ap_log; + srslte::log_filter *m_nas_log; s1ap_mngmt_proc* m_s1ap_mngmt_proc; s1ap_nas_transport* m_s1ap_nas_transport; diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index e5c998ed7..e6e90c2b1 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -45,6 +45,8 @@ sig_int_handler(int signo){ } typedef struct { + std::string nas_level; + int nas_hex_limit; std::string s1ap_level; int s1ap_hex_limit; std::string gtpc_level; @@ -117,6 +119,8 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("pcap.enable", bpo::value(&args->mme_args.s1ap_args.pcap_enable)->default_value(false), "Enable S1AP PCAP") ("pcap.filename", bpo::value(&args->mme_args.s1ap_args.pcap_filename)->default_value("/tmp/epc.pcap"), "PCAP filename") + ("log.nas_level", bpo::value(&args->log_args.nas_level), "MME NAS log level") + ("log.nas_hex_limit", bpo::value(&args->log_args.nas_hex_limit), "MME NAS log hex dump limit") ("log.s1ap_level", bpo::value(&args->log_args.s1ap_level), "MME S1AP log level") ("log.s1ap_hex_limit", bpo::value(&args->log_args.s1ap_hex_limit), "MME S1AP log hex dump limit") ("log.gtpc_level", bpo::value(&args->log_args.gtpc_level), "MME GTPC log level") @@ -201,7 +205,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) { if(!srslte::string_to_mnc(mnc, &args->mme_args.s1ap_args.mnc)) { cout << "Error parsing mme.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; } - + // Convert MCC/MNC strings if(!srslte::string_to_mcc(mcc, &args->hss_args.mcc)) { cout << "Error parsing mme.mcc:" << mcc << " - must be a 3-digit string." << endl; @@ -221,6 +225,9 @@ parse_args(all_args_t *args, int argc, char* argv[]) { // Apply all_level to any unset layers if (vm.count("log.all_level")) { + if(!vm.count("log.nas_level")) { + args->log_args.nas_level = args->log_args.all_level; + } if(!vm.count("log.s1ap_level")) { args->log_args.s1ap_level = args->log_args.all_level; } @@ -303,6 +310,11 @@ main (int argc,char * argv[] ) logger = &logger_file; } + srslte::log_filter nas_log; + nas_log.init("NAS ",logger); + nas_log.set_level(level(args.log_args.nas_level)); + nas_log.set_hex_limit(args.log_args.nas_hex_limit); + srslte::log_filter s1ap_log; s1ap_log.init("S1AP",logger); s1ap_log.set_level(level(args.log_args.s1ap_level)); @@ -331,7 +343,7 @@ main (int argc,char * argv[] ) } mme *mme = mme::get_instance(); - if (mme->init(&args.mme_args, &s1ap_log, &mme_gtpc_log, hss)) { + if (mme->init(&args.mme_args, &nas_log, &s1ap_log, &mme_gtpc_log, hss)) { cout << "Error initializing MME" << endl; exit(1); } diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index d4ce540f1..9c3195093 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -71,23 +71,24 @@ mme::cleanup(void) } int -mme::init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log, hss_interface_nas * hss) +mme::init(mme_args_t* args, srslte::log_filter *nas_log, srslte::log_filter *s1ap_log, srslte::log_filter *mme_gtpc_log, hss_interface_nas * hss) { /*Init logger*/ + m_nas_log = nas_log; m_s1ap_log = s1ap_log; m_mme_gtpc_log = mme_gtpc_log; + /*Init S1AP*/ m_s1ap = s1ap::get_instance(); - if(m_s1ap->init(args->s1ap_args, s1ap_log, hss)){ + if (m_s1ap->init(args->s1ap_args, nas_log, s1ap_log, hss)) { m_s1ap_log->error("Error initializing MME S1APP\n"); exit(-1); } /*Init GTP-C*/ m_mme_gtpc = mme_gtpc::get_instance(); - if(!m_mme_gtpc->init(m_mme_gtpc_log)) - { + if (!m_mme_gtpc->init(m_mme_gtpc_log)) { m_s1ap_log->console("Error initializing GTP-C\n"); exit(-1); } @@ -101,8 +102,7 @@ mme::init(mme_args_t* args, srslte::log_filter *s1ap_log, srslte::log_filter *mm void mme::stop() { - if(m_running) - { + if (m_running) { m_s1ap->stop(); m_s1ap->cleanup(); m_running = false; @@ -140,22 +140,17 @@ mme::run_thread() } else if (rd_sz == -1 && errno == EAGAIN){ m_s1ap_log->debug("Socket timeout reached"); - } - else{ - if(msg_flags & MSG_NOTIFICATION) - { + } else { + if (msg_flags & MSG_NOTIFICATION) { //Received notification union sctp_notification *notification = (union sctp_notification*)pdu->msg; m_s1ap_log->debug("SCTP Notification %d\n", notification->sn_header.sn_type); - if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) - { + if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) { m_s1ap_log->info("SCTP Association Shutdown. Association: %d\n",sri.sinfo_assoc_id); m_s1ap_log->console("SCTP Association Shutdown. Association: %d\n",sri.sinfo_assoc_id); m_s1ap->delete_enb_ctx(sri.sinfo_assoc_id); } - } - else - { + } else { //Received data pdu->N_bytes = rd_sz; m_s1ap_log->info("Received S1AP msg. Size: %d\n", pdu->N_bytes); @@ -165,5 +160,4 @@ mme::run_thread() } return; } - } //namespace srsepc diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index 573093da3..570dbf2f8 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -91,7 +91,8 @@ mme_gtpc::get_new_ctrl_teid() { return m_next_ctrl_teid++; //FIXME Use a Id pool? } -void + +bool mme_gtpc::send_create_session_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending Create Session Request.\n"); @@ -133,17 +134,13 @@ mme_gtpc::send_create_session_request(uint64_t imsi) //Check whether this UE is already registed std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); - if(it != m_imsi_to_gtpc_ctx.end()) - { + if (it != m_imsi_to_gtpc_ctx.end()) { m_mme_gtpc_log->warning("Create Session Request being called for an UE with an active GTP-C connection.\n"); m_mme_gtpc_log->warning("Deleting previous GTP-C connection.\n"); std::map::iterator jt = m_mme_ctr_teid_to_imsi.find(it->second.mme_ctr_fteid.teid); - if(jt == m_mme_ctr_teid_to_imsi.end()) - { + if (jt == m_mme_ctr_teid_to_imsi.end()) { m_mme_gtpc_log->error("Could not find IMSI from MME Ctrl TEID. MME Ctr TEID: %d\n", it->second.mme_ctr_fteid.teid); - } - else - { + } else { m_mme_ctr_teid_to_imsi.erase(jt); } m_imsi_to_gtpc_ctx.erase(it); @@ -160,10 +157,10 @@ mme_gtpc::send_create_session_request(uint64_t imsi) gtpc_ctx.mme_ctr_fteid = cs_req->sender_f_teid; m_imsi_to_gtpc_ctx.insert(std::pair(imsi,gtpc_ctx)); m_spgw->handle_create_session_request(cs_req, &cs_resp_pdu); - + return true; } -void +bool mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) { struct srslte::gtpc_create_session_response *cs_resp = & cs_resp_pdu->choice.create_session_response; @@ -172,19 +169,19 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) if (cs_resp_pdu->header.type != srslte::GTPC_MSG_TYPE_CREATE_SESSION_RESPONSE) { m_mme_gtpc_log->warning("Could not create GTPC session. Not a create session response\n"); //TODO Handle error - return; + return false; } if (cs_resp->cause.cause_value != srslte::GTPC_CAUSE_VALUE_REQUEST_ACCEPTED) { m_mme_gtpc_log->warning("Could not create GTPC session. Create Session Request not accepted\n"); //TODO Handle error - return; + return false; } //Get IMSI from the control TEID std::map::iterator id_it = m_mme_ctr_teid_to_imsi.find(cs_resp_pdu->header.teid); if(id_it == m_mme_ctr_teid_to_imsi.end()) { m_mme_gtpc_log->warning("Could not find IMSI from Ctrl TEID.\n"); - return; + return false; } uint64_t imsi = id_it->second; @@ -198,7 +195,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) //Get S-GW S1-u F-TEID if (cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid_present == false){ m_mme_gtpc_log->error("Did not receive SGW S1-U F-TEID in create session response\n"); - return; + return false; } m_mme_gtpc_log->console("Create Session Response -- SPGW control TEID %d\n", sgw_ctr_fteid.teid); m_mme_gtpc_log->info("Create Session Response -- SPGW control TEID %d\n", sgw_ctr_fteid.teid); @@ -210,18 +207,18 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) //Check UE Ipv4 address was allocated if (cs_resp->paa_present != true) { m_mme_gtpc_log->error("PDN Adress Allocation not present\n"); - return; + return false; } if (cs_resp->paa.pdn_type != srslte::GTPC_PDN_TYPE_IPV4) { m_mme_gtpc_log->error("IPv6 not supported yet\n"); - return; + return false; } //Save create session response info to E-RAB context nas *nas_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); if(nas_ctx == NULL){ m_mme_gtpc_log->error("Could not find UE context. IMSI %015lu\n", imsi); - return; + return false; } emm_ctx_t *emm_ctx = &nas_ctx->m_emm_ctx; ecm_ctx_t *ecm_ctx = &nas_ctx->m_ecm_ctx; @@ -234,7 +231,7 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) if(it_g == m_imsi_to_gtpc_ctx.end()) { //Could not find GTP-C Context m_mme_gtpc_log->error("Could not find GTP-C context\n"); - return; + return false; } gtpc_ctx_t *gtpc_ctx = &it_g->second; gtpc_ctx->sgw_ctr_fteid = sgw_ctr_fteid; @@ -246,11 +243,11 @@ mme_gtpc::handle_create_session_response(srslte::gtpc_pdu *cs_resp_pdu) esm_ctx->pdn_addr_alloc= cs_resp->paa; esm_ctx->sgw_s1u_fteid = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid; m_s1ap->m_s1ap_ctx_mngmt_proc->send_initial_context_setup_request(nas_ctx, default_bearer); - return; + return true; } -void +bool mme_gtpc::send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srslte::gtp_fteid_t *enb_fteid) { m_mme_gtpc_log->info("Sending GTP-C Modify bearer request\n"); @@ -259,7 +256,7 @@ mme_gtpc::send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srs std::map::iterator it = m_imsi_to_gtpc_ctx.find(imsi); if (it == m_imsi_to_gtpc_ctx.end()) { m_mme_gtpc_log->error("Modify bearer request for UE without GTP-C connection\n"); - return; + return false; } srslte::gtp_fteid_t sgw_ctr_fteid = it->second.sgw_ctr_fteid; @@ -282,7 +279,7 @@ mme_gtpc::send_modify_bearer_request(uint64_t imsi, uint16_t erab_to_modify, srs srslte::gtpc_pdu mb_resp_pdu; m_spgw->handle_modify_bearer_request(&mb_req_pdu,&mb_resp_pdu); handle_modify_bearer_response(&mb_resp_pdu); - return; + return true; } void @@ -302,7 +299,7 @@ mme_gtpc::handle_modify_bearer_response(srslte::gtpc_pdu *mb_resp_pdu) return; } -void +bool mme_gtpc::send_delete_session_request(uint64_t imsi) { m_mme_gtpc_log->info("Sending GTP-C Delete Session Request request. IMSI %" PRIu64 "\n",imsi); @@ -314,7 +311,7 @@ mme_gtpc::send_delete_session_request(uint64_t imsi) std::map::iterator it_ctx = m_imsi_to_gtpc_ctx.find(imsi); if (it_ctx == m_imsi_to_gtpc_ctx.end()) { m_mme_gtpc_log->error("Could not find GTP-C context to remove\n"); - return; + return false; } sgw_ctr_fteid = it_ctx->second.sgw_ctr_fteid; @@ -341,7 +338,7 @@ mme_gtpc::send_delete_session_request(uint64_t imsi) m_mme_ctr_teid_to_imsi.erase(it_imsi); } m_imsi_to_gtpc_ctx.erase(it_ctx); - return; + return true; } void diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 853a1757c..0e49f488a 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -39,6 +39,17 @@ nas::nas() { m_pool = srslte::byte_buffer_pool::get_instance(); } +void +nas::init(s1ap_interface_nas *s1ap, + gtpc_interface_nas *gtpc, + hss_interface_nas *hss, + srslte::log *nas_log) +{ + m_s1ap = s1ap; + m_gtpc = gtpc; + m_hss = hss; + m_nas_log = nas_log; +} /******************************* * * Handle UE Initiating Messages @@ -261,7 +272,7 @@ nas::handle_identity_response(srslte::byte_buffer_t *nas_msg, srslte::byte_buffe m_emm_ctx.imsi=imsi; //Get Authentication Vectors from HSS - if (!m_hss->gen_auth_info_answer(imsi, m_sec_ctx.k_asme, autn, rand, m_sec_ctx.xres)) { + if (!m_hss->gen_auth_info_answer(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",imsi); m_nas_log->info("User not found. IMSI %015lu\n",imsi); return false; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 68d860a5e..f20ae3fa0 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -72,7 +72,7 @@ s1ap::cleanup(void) } int -s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_nas * hss) +s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *nas_log, srslte::log_filter *s1ap_log, hss_interface_nas * hss) { m_pool = srslte::byte_buffer_pool::get_instance(); @@ -80,6 +80,7 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log_filter *s1ap_log, hss_interface_na srslte::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &m_plmn); m_next_m_tmsi = rand(); //Init log + m_nas_log = nas_log; m_s1ap_log = s1ap_log; //Get pointer to the HSS diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 08549035f..d6a4b7b7e 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -496,6 +496,7 @@ s1ap_nas_transport::handle_nas_guti_attach_request( uint32_t enb_ue_s1ap_id, 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_mme_gtpc, m_hss, m_s1ap->m_nas_log); 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;