Added the ability to the HSS to be configured through a .csv.

This commit is contained in:
Pedro Alvarez 2017-12-13 19:50:19 +00:00
parent 0a4e256fec
commit aef328d68b
6 changed files with 152 additions and 15 deletions

View File

@ -21,6 +21,23 @@ mcc = 001
mnc = 01
mme_bind_addr = 127.0.0.0/24
#####################################################################
# HSS configuration
#
# db_file: Location of .csv file that stores UEs information.
#
#####################################################################
[hss]
db_file = user_db.csv
#####################################################################
# SP-GW configuration
#
# gtpu_bind_addr: Location of .csv file that stores UEs information.
#
#####################################################################
[spgw]
gtpu_bind_addr=127.0.0.2
sgi_if_addr=172.0.0.1

View File

@ -38,14 +38,22 @@
#include "srslte/common/logger_file.h"
#include "srslte/common/log_filter.h"
#include "srslte/common/buffer_pool.h"
#include <fstream>
namespace srsepc{
typedef struct{
std::string ue_file;
std::string db_file;
}hss_args_t;
typedef struct{
std::string name;
uint64_t imsi;
uint8_t key[16];
uint8_t op[16];
uint8_t amf[2];
}hss_ue_ctx_t;
class hss
@ -54,12 +62,16 @@ public:
static hss* get_instance(void);
static void cleanup(void);
int init(hss_args_t *hss_args, srslte::log_filter* hss_log);
bool read_db_file(std::string db_file);
void get_sqn(uint8_t sqn[6]);
void gen_rand(uint8_t rand_[16]);
bool get_k_amf_op(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op);
bool gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres);
std::vector<std::string> split_string(const std::string &str, char delimiter);
void get_uint_vec_from_hex_str(const std::string &key_str, uint8_t *key, uint len);
private:
hss();
@ -68,6 +80,9 @@ private:
uint64_t m_sqn; //48 bits
srslte::byte_buffer_pool *m_pool;
std::ifstream m_db_file;
std::map<uint64_t,hss_ue_ctx_t*> m_imsi_to_ue_ctx;
/*Logs*/
srslte::log_filter *m_hss_log;

View File

@ -41,12 +41,16 @@ boost::mutex hss_instance_mutex;
hss::hss()
:m_sqn(0x112233445566)
{
m_pool = srslte::byte_buffer_pool::get_instance();
m_pool = srslte::byte_buffer_pool::get_instance();
return;
}
hss::~hss()
{
if(m_db_file.is_open())
{
m_db_file.close();
}
return;
}
@ -73,15 +77,57 @@ hss::cleanup(void)
int
hss::init(hss_args_t *hss_args, srslte::log_filter *hss_log)
{
/*Init loggers*/
srand(time(NULL));
/*Init loggers*/
m_hss_log = hss_log;
m_hss_log->info("HSS Initialized\n");
m_hss_log->console("HSS Initialized\n");
/*Read user information from DB*/
read_db_file(hss_args->db_file);
return 0;
}
bool
hss::read_db_file(std::string db_filename)
{
m_db_file.open(db_filename.c_str());
if(!m_db_file.is_open())
{
return false;
}
m_hss_log->info("Opended DB file: %s\n", db_filename.c_str() );
std::string line;
while (std::getline(m_db_file, line))
{
if(line[0] != '#')
{
std::vector<std::string> split = split_string(line,',');
if(split.size()!=5)
{
m_hss_log->error("Error parsing .csv file %d\n");
return false;
}
hss_ue_ctx_t *ue_ctx = new hss_ue_ctx_t;
ue_ctx->name = split[0];
ue_ctx->imsi = atoll(split[1].c_str());
get_uint_vec_from_hex_str(split[2],ue_ctx->key,16);
get_uint_vec_from_hex_str(split[3],ue_ctx->op,16);
get_uint_vec_from_hex_str(split[4],ue_ctx->amf,2);
m_hss_log->debug("Added user from DB, IMSI: %015lu\n", ue_ctx->imsi);
m_hss_log->debug_hex(ue_ctx->key, 16, "User Key : ");
m_hss_log->debug_hex(ue_ctx->op, 16, "User OP : ");
m_hss_log->debug_hex(ue_ctx->amf, 2, "AMF : ");
m_imsi_to_ue_ctx.insert(std::pair<uint64_t,hss_ue_ctx_t*>(ue_ctx->imsi,ue_ctx));
}
}
return true;
}
bool
hss::gen_auth_info_answer_milenage(uint64_t imsi, uint8_t *k_asme, uint8_t *autn, uint8_t *rand, uint8_t *xres)
{
@ -154,22 +200,24 @@ bool
hss::get_k_amf_op(uint64_t imsi, uint8_t *k, uint8_t *amf, uint8_t *op )
{
/*
uint8_t k_tmp[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
uint8_t amf_tmp[2]={0x80,0x00};
uint8_t op_tmp[16]={0x63,0xbf,0xA5,0x0E,0xE6,0x52,0x33,0x65,0xFF,0x14,0xC1,0xF4,0x5F,0x88,0x73,0x7D};
if(imsi != 1010123456789)
*/
std::map<uint64_t,hss_ue_ctx_t*>::iterator ue_ctx_it = m_imsi_to_ue_ctx.find(imsi);
if(ue_ctx_it == m_imsi_to_ue_ctx.end())
{
m_hss_log->info("User not found. IMSI: %015lu\n",imsi);
m_hss_log->console("User not found. IMSI: %015lu\n",imsi);
return false;
}
hss_ue_ctx_t *ue_ctx = ue_ctx_it->second;
m_hss_log->info("Found User %015lu\n",imsi);
m_hss_log->console("Found User %015lu\n",imsi);
memcpy(k,k_tmp,16);
memcpy(amf,amf_tmp,2);
memcpy(op,op_tmp,16);
memcpy(k,ue_ctx->key,16);
memcpy(amf,ue_ctx->amf,2);
memcpy(op,ue_ctx->op,16);
return true;
}
@ -195,4 +243,43 @@ hss::gen_rand(uint8_t rand_[16])
return;
}
/* Helper functions*/
std::vector<std::string>
hss::split_string(const std::string &str, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
void
hss::get_uint_vec_from_hex_str(const std::string &key_str, uint8_t *key, uint len)
{
const char *pos = key_str.c_str();
for (uint count = 0; count < len; count++) {
sscanf(pos, "%2hhx", &key[count]);
pos += 2;
}
return;
}
/*
uint64_t
string_to_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);
}
return imsi;
}
*/
} //namespace srsepc

View File

@ -73,6 +73,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
string mme_bind_addr;
string spgw_bind_addr;
string sgi_if_addr;
string hss_db_file;
// Command line only options
bpo::options_description general("General options");
@ -92,6 +93,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
("mme.mcc", bpo::value<string>(&mcc)->default_value("001"), "Mobile Country Code")
("mme.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
("mme.mme_bind_addr", bpo::value<string>(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection")
("hss.db_file", bpo::value<string>(&hss_db_file)->default_value("ue_db.csv"),".csv file that stores UE's keys")
("spgw.gtpu_bind_addr", bpo::value<string>(&spgw_bind_addr)->default_value("127.0.0.1"),"IP address of SP-GW for the S1-U connection")
("spgw.sgi_if_addr", bpo::value<string>(&sgi_if_addr)->default_value("176.16.0.1"),"IP address of TUN interface for the SGi connection")
;
@ -168,6 +170,7 @@ parse_args(all_args_t *args, int argc, char* argv[]) {
args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr;
args->spgw_args.gtpu_bind_addr = spgw_bind_addr;
args->spgw_args.sgi_if_addr = sgi_if_addr;
args->hss_args.db_file = hss_db_file;
return;
}

View File

@ -627,6 +627,7 @@ s1ap::send_initial_context_setup_request(uint32_t mme_ue_s1ap_id, struct srslte:
}
erab_ctxt->transportLayerAddress.n_bits = 32; //IPv4
uint32_t sgw_s1u_ip = htonl(cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4);
//uint32_t sgw_s1u_ip = cs_resp->eps_bearer_context_created.s1_u_sgw_f_teid.ipv4;
uint8_t *tmp_ptr = erab_ctxt->transportLayerAddress.buffer;
liblte_value_2_bits(sgw_s1u_ip, &tmp_ptr, 32);//FIXME consider ipv6
@ -833,9 +834,10 @@ s1ap::activate_eps_bearer(uint32_t mme_s1ap_id, uint8_t ebi)
return;
}
ue_ctx_t * ue_ctx = ue_ctx_it->second;
if (ue_ctx->erabs_ctx[ebi].state != ERAB_CTX_REQUESTED)
if (ue_ctx->erabs_ctx[ebi].state != ERAB_CTX_SETUP)
{
m_s1ap_log->error("EPS Bearer could not be activated. EPS Bearer id %d\n",ebi);
m_s1ap_log->error("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d, state %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state);
m_s1ap_log->console("EPS Bearer could not be activated. MME S1AP Id %d, EPS Bearer id %d\n",mme_s1ap_id,ebi,ue_ctx->erabs_ctx[ebi].state);
return;
}

13
srsepc/user_db.csv Normal file
View File

@ -0,0 +1,13 @@
#
# .csv to store UE's information in HSS
# Kept in the following format: "Name,IMSI,Key,OP,AMF"
#
# Name: Human readable name to help distinguish UE's. Largely ignored by the HSS
# IMSI: UE's IMSI value
# Key: UE's key, where other keys are derived from. Stored in hexadecimal
# OP: Operator's code, sotred in hexadecimal
# AMF: Authentication management feild, stored in hexadecimal
#
# Note: Lines starting by '#' are ignored
ue1,001010123456789,00112233445566778899aabbccddeeff,63BFA50EE6523365FF14C1F45F88737D,8000
ue2,001010123456780,00112233445566778899aabbccddeeaa,63BFA50EE6523365FF14C1F45F88737D,2000
Can't render this file because it contains an unexpected character in line 3 and column 33.