#include // perror, printf, fprintf, snprintf #include // exit, free #include // memset, strncpy #include #include "conf2uedata.h" #include "memory.h" #include "utils.h" #include "display.h" #include "fs.h" #include "conf_emm.h" #include "conf_user_data.h" #include "conf_usim.h" int plmn_nb = 0; plmn_conf_param_t* user_plmn_list=NULL; network_record_t* user_network_record_list = NULL; int main(int argc, char**argv) { int option; const char* conf_file = NULL; const char* output_dir = NULL; const char options[]="c:o:h"; while ((option = getopt(argc, argv, options)) != -1) { switch (option) { case 'c': conf_file = optarg; break; case 'o': output_dir = optarg; break; case 'h': _display_usage(); return EXIT_SUCCESS; break; default: break; } } if (output_dir == NULL ) { printf("No output option found\n"); _display_usage(); return EXIT_FAILURE; } if ( conf_file == NULL ) { printf("No Configuration file is given\n"); _display_usage(); return EXIT_FAILURE; } if ( parse_config_file(output_dir, conf_file) == EXIT_FAILURE ) { exit(EXIT_FAILURE); } display_data_from_directory(output_dir); exit(EXIT_SUCCESS); } int parse_config_file(const char *output_dir, const char *conf_filename) { int rc = EXIT_SUCCESS; int ret; int ue_nb = 0; config_setting_t *root_setting = NULL; config_setting_t *ue_setting = NULL; config_setting_t *all_plmn_setting = NULL; char user[10]; config_t cfg; ret = get_config_from_file(conf_filename, &cfg); if (ret == EXIT_FAILURE) { exit(1); } root_setting = config_root_setting(&cfg); ue_nb = config_setting_length(root_setting) - 1; all_plmn_setting = config_setting_get_member(root_setting, PLMN); if (all_plmn_setting == NULL) { printf("NO PLMN SECTION...EXITING...\n"); return (EXIT_FAILURE); } rc = parse_plmns(all_plmn_setting); if (rc == EXIT_FAILURE) { return rc; } fill_network_record_list(); for (int i = 0; i < ue_nb; i++) { emm_nvdata_t emm_data; user_nvdata_t user_data; user_data_conf_t user_data_conf; usim_data_t usim_data; usim_data_conf_t usim_data_conf; user_plmns_t user_plmns; sprintf(user, "%s%d", UE, i); ue_setting = config_setting_get_member(root_setting, user); if (ue_setting == NULL) { printf("Check UE%d settings\n", i); return EXIT_FAILURE; } rc = parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn); if (rc != EXIT_SUCCESS) { return EXIT_FAILURE; } rc = parse_ue_user_data(ue_setting, i, &user_data_conf); if (rc != EXIT_SUCCESS) { printf("Problem in USER section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } gen_user_data(&user_data_conf, &user_data); write_user_data(output_dir, i, &user_data); rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); if (rc != EXIT_SUCCESS) { printf("Problem in SIM section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } gen_usim_data(&usim_data_conf, &usim_data, &user_plmns); write_usim_data(output_dir, i, &usim_data); gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, user_plmns.equivalents_home.size); write_emm_data(output_dir, i, &emm_data); } config_destroy(&cfg); return(EXIT_SUCCESS); } int get_config_from_file(const char *filename, config_t *config) { config_init(config); if (filename == NULL) { // XXX write error message ? exit(EXIT_FAILURE); } /* Read the file. If there is an error, report it and exit. */ if (!config_read_file(config, filename)) { fprintf(stderr, "Cant read config file '%s': %s\n", filename, config_error_text(config)); if ( config_error_type(config) == CONFIG_ERR_PARSE ) { fprintf(stderr, "This is line %d\n", config_error_line(config)); } config_destroy(config); return (EXIT_FAILURE); } return EXIT_SUCCESS; } int parse_plmn_param(config_setting_t *plmn_setting, int index) { int rc = 0; rc = config_setting_lookup_string(plmn_setting, FULLNAME, &user_plmn_list[index].fullname); if (rc != 1) { printf("Check PLMN%d FULLNAME. Exiting\n", index); return EXIT_FAILURE; } rc = config_setting_lookup_string(plmn_setting, SHORTNAME, &user_plmn_list[index].shortname); if (rc != 1) { printf("Check PLMN%d SHORTNAME. Exiting\n", index); return EXIT_FAILURE; } rc = config_setting_lookup_string(plmn_setting, MNC, &user_plmn_list[index].mnc); if (rc != 1 || strlen(user_plmn_list[index].mnc) > 3 || strlen(user_plmn_list[index].mnc) < 2) { printf("Check PLMN%d MNC. Exiting\n", index); return EXIT_FAILURE; } rc = config_setting_lookup_string(plmn_setting, MCC, &user_plmn_list[index].mcc); if (rc != 1 || strlen(user_plmn_list[index].mcc) != 3) { printf("Check PLMN%d MCC. Exiting\n", index); return EXIT_FAILURE; } return EXIT_SUCCESS; } int parse_plmns(config_setting_t *all_plmn_setting) { config_setting_t *plmn_setting = NULL; char plmn[10]; int rc = EXIT_SUCCESS; plmn_nb = config_setting_length(all_plmn_setting); user_plmn_list = malloc(sizeof(plmn_conf_param_t) * plmn_nb); user_network_record_list = malloc(sizeof(network_record_t) * plmn_nb); for (int i = 0; i < plmn_nb; i++) { memset(&user_network_record_list[i], 0xff, sizeof(network_record_t)); memset(&user_plmn_list[i], 0xff, sizeof(plmn_conf_param_t)); } for (int i = 0; i < plmn_nb; i++) { sprintf(plmn, "%s%d", PLMN, i); plmn_setting = config_setting_get_member(all_plmn_setting, plmn); if (plmn_setting != NULL) { rc = parse_plmn_param(plmn_setting, i); if (rc == EXIT_FAILURE) { return rc; } } else { printf("Problem in PLMN%d. Exiting...\n", i); return EXIT_FAILURE; } } return rc; } int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, user_plmns_t *user_plmns, const char **h) { int nb_errors = 0; const char *hplmn; if ( config_setting_lookup_string(ue_setting, HPLMN, h) != 1 ) { printf("Check HPLMN section for UE%d. Exiting\n", user_id); return EXIT_FAILURE; } hplmn = *h; if (get_plmn_index(hplmn) == -1) { printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", user_id); return EXIT_FAILURE; } if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled) == EXIT_FAILURE ) nb_errors++; if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators) == EXIT_FAILURE ) nb_errors++; if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled) == EXIT_FAILURE ) nb_errors++; if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens) == EXIT_FAILURE ) nb_errors++; if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home) == EXIT_FAILURE ) nb_errors++; if ( nb_errors > 0 ) return EXIT_FAILURE; return EXIT_SUCCESS; } int parse_Xplmn(config_setting_t *ue_setting, const char *section, int user_id, plmns_list *plmns) { int rc; int item_count; config_setting_t *setting; setting = config_setting_get_member(ue_setting, section); if (setting == NULL) { printf("Check %s section for UE%d. Exiting\n", section, user_id); return EXIT_FAILURE; } item_count = config_setting_length(setting); int *datas = malloc(item_count * sizeof(int)); for (int i = 0; i < item_count; i++) { const char *mccmnc = config_setting_get_string_elem(setting, i); if (mccmnc == NULL) { printf("Check %s section for UE%d. Exiting\n", section, user_id); return EXIT_FAILURE; } rc = get_plmn_index(mccmnc); if (rc == -1) { printf("The PLMN %s is not defined in PLMN section. Exiting...\n", mccmnc); return EXIT_FAILURE; } datas[i] = rc; } plmns->size = item_count; plmns->items = datas; return EXIT_SUCCESS; } int get_plmn_index(const char * mccmnc) { char mcc[4]; char mnc[strlen(mccmnc) - 2]; strncpy(mcc, mccmnc, 3); mcc[3] = '\0'; strncpy(mnc, mccmnc + 3, 3); mnc[strlen(mccmnc) - 3] = '\0'; for (int i = 0; i < plmn_nb; i++) { if (strcmp(user_plmn_list[i].mcc, mcc) == 0) { if (strcmp(user_plmn_list[i].mnc, mnc) == 0) { return i; } } } return -1; } plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { plmn_t plmn; char num[6]; memset(&plmn, 0xff, sizeof(plmn)); snprintf(num, 6, "%s%s", plmn_conf->mcc, plmn_conf->mnc); plmn.MCCdigit2 = plmn_conf->mcc[1]; plmn.MCCdigit1 = plmn_conf->mcc[0]; plmn.MCCdigit3 = plmn_conf->mcc[2]; plmn.MNCdigit2 = plmn_conf->mnc[1]; plmn.MNCdigit1 = plmn_conf->mnc[0]; if (strlen(plmn_conf->mnc) > 2) { plmn.MNCdigit3 = plmn_conf->mnc[2]; } return plmn; } void fill_network_record_list() { for (int i = 0; i < plmn_nb; i++) { strcpy(user_network_record_list[i].fullname, user_plmn_list[i].fullname); strcpy(user_network_record_list[i].shortname, user_plmn_list[i].shortname); char num[6]; sprintf(num, "%s%s", user_plmn_list[i].mcc, user_plmn_list[i].mnc); user_network_record_list[i].num = atoi(num); user_network_record_list[i].plmn = make_plmn_from_conf(&user_plmn_list[i]); user_network_record_list[i].tac_end = 0xfffd; user_network_record_list[i].tac_start = 0x0001; } } /* * Displays command line usage */ void _display_usage(void) { fprintf(stderr, "usage: conf2uedata [OPTION] [directory] ...\n"); fprintf(stderr, "\t[-c]\tConfig file to use\n"); fprintf(stderr, "\t[-o]\toutput file directory\n"); fprintf(stderr, "\t[-h]\tDisplay this usage\n"); }