gbproxy: Refactor gbprox_patch_raid(), use different RAI types properly
Currently gbprox_patch_raid() updates the local MCC/MNC with every BSS originated message, even if the RAI is an 'old' one. This patch separates state updating and patching into 2 functions gbprox_update_current_raid and gbprox_patch_raid. In addition, a field named old_raid_enc is added to gbproxy_parse_context, which is used for 'old RAI' IEs in Attach Requests and RA Update Requests. Only the bssg_raid_enc in BSS originated message is used to update the BSS side 'local' MCC/MNC. Sponsored-by: On-Waves ehf
This commit is contained in:
parent
311592fc39
commit
12496dd7db
|
@ -409,6 +409,7 @@ struct gbproxy_parse_context {
|
|||
uint8_t *ptmsi_enc;
|
||||
uint8_t *new_ptmsi_enc;
|
||||
uint8_t *raid_enc;
|
||||
uint8_t *old_raid_enc;
|
||||
uint8_t *bssgp_raid_enc;
|
||||
uint8_t *bssgp_ptimsi;
|
||||
|
||||
|
@ -418,6 +419,7 @@ struct gbproxy_parse_context {
|
|||
int need_decryption;
|
||||
uint32_t tlli;
|
||||
int pdu_type;
|
||||
int old_raid_matches;
|
||||
};
|
||||
|
||||
struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
|
||||
|
@ -821,13 +823,51 @@ static int patching_is_required(struct gbproxy_peer *peer,
|
|||
return need_at_least <= peer->cfg->patch_mode;
|
||||
}
|
||||
|
||||
/* patch RA identifier in place, update peer accordingly */
|
||||
static void gbprox_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer,
|
||||
int to_bss, const char *log_text)
|
||||
/* update peer according to the BSS message */
|
||||
static void gbprox_update_current_raid(uint8_t *raid_enc,
|
||||
struct gbproxy_peer *peer,
|
||||
const char *log_text)
|
||||
{
|
||||
struct gbproxy_patch_state *state = &peer->patch_state;
|
||||
const int old_local_mcc = state->local_mcc;
|
||||
const int old_local_mnc = state->local_mnc;
|
||||
struct gprs_ra_id raid;
|
||||
|
||||
if (!raid_enc)
|
||||
return;
|
||||
|
||||
gsm48_parse_ra(&raid, raid_enc);
|
||||
|
||||
/* save source side MCC/MNC */
|
||||
if (!peer->cfg->core_mcc || raid.mcc == peer->cfg->core_mcc) {
|
||||
state->local_mcc = 0;
|
||||
} else {
|
||||
state->local_mcc = raid.mcc;
|
||||
}
|
||||
|
||||
if (!peer->cfg->core_mnc || raid.mnc == peer->cfg->core_mnc) {
|
||||
state->local_mnc = 0;
|
||||
} else {
|
||||
state->local_mnc = raid.mnc;
|
||||
}
|
||||
|
||||
if (old_local_mcc != state->local_mcc ||
|
||||
old_local_mnc != state->local_mnc)
|
||||
LOGP(DGPRS, LOGL_NOTICE,
|
||||
"Patching RAID %sactivated, msg: %s, "
|
||||
"local: %d-%d, core: %d-%d\n",
|
||||
state->local_mcc || state->local_mnc ?
|
||||
"" : "de",
|
||||
log_text,
|
||||
state->local_mcc, state->local_mnc,
|
||||
peer->cfg->core_mcc, peer->cfg->core_mnc);
|
||||
}
|
||||
|
||||
/* patch RA identifier in place */
|
||||
static void gbprox_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer,
|
||||
int to_bss, const char *log_text)
|
||||
{
|
||||
struct gbproxy_patch_state *state = &peer->patch_state;
|
||||
int old_mcc;
|
||||
int old_mnc;
|
||||
struct gprs_ra_id raid;
|
||||
|
@ -839,20 +879,11 @@ static void gbprox_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer,
|
|||
|
||||
if (!to_bss) {
|
||||
/* BSS -> SGSN */
|
||||
/* save BSS side MCC/MNC */
|
||||
if (!peer->cfg->core_mcc || raid.mcc == peer->cfg->core_mcc) {
|
||||
state->local_mcc = 0;
|
||||
} else {
|
||||
state->local_mcc = raid.mcc;
|
||||
if (state->local_mcc)
|
||||
raid.mcc = peer->cfg->core_mcc;
|
||||
}
|
||||
|
||||
if (!peer->cfg->core_mnc || raid.mnc == peer->cfg->core_mnc) {
|
||||
state->local_mnc = 0;
|
||||
} else {
|
||||
state->local_mnc = raid.mnc;
|
||||
if (state->local_mnc)
|
||||
raid.mnc = peer->cfg->core_mnc;
|
||||
}
|
||||
} else {
|
||||
/* SGSN -> BSS */
|
||||
if (state->local_mcc)
|
||||
|
@ -862,18 +893,6 @@ static void gbprox_patch_raid(uint8_t *raid_enc, struct gbproxy_peer *peer,
|
|||
raid.mnc = state->local_mnc;
|
||||
}
|
||||
|
||||
if (old_local_mcc != state->local_mcc ||
|
||||
old_local_mnc != state->local_mnc)
|
||||
LOGP(DGPRS, LOGL_NOTICE,
|
||||
"Patching RAID %sactivated, msg: %s, "
|
||||
"local: %d-%d, core: %d-%d, to %s\n",
|
||||
state->local_mcc || state->local_mnc ?
|
||||
"" : "de",
|
||||
log_text,
|
||||
state->local_mcc, state->local_mnc,
|
||||
peer->cfg->core_mcc, peer->cfg->core_mnc,
|
||||
to_bss ? "BSS" : "SGSN");
|
||||
|
||||
if (state->local_mcc || state->local_mnc) {
|
||||
enum gbprox_peer_ctr counter =
|
||||
to_bss ?
|
||||
|
@ -979,7 +998,7 @@ static int gbprox_parse_gmm_attach_req(uint8_t *data, size_t data_len,
|
|||
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->raid_enc = value;
|
||||
parse_ctx->old_raid_enc = value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1069,7 +1088,7 @@ static int gbprox_parse_gmm_ra_upd_req(uint8_t *data, size_t data_len,
|
|||
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->raid_enc = value;
|
||||
parse_ctx->old_raid_enc = value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1339,14 +1358,18 @@ static int gbprox_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
|
|||
return have_patched;
|
||||
|
||||
if (parse_ctx->raid_enc) {
|
||||
/* TODO: BSS->SGSN: Only patch if matches original BSSGP,
|
||||
* don't update internal mapping, patch to invalid if P-TMSI
|
||||
* unknown. */
|
||||
gbprox_patch_raid(parse_ctx->raid_enc, peer, parse_ctx->to_bss,
|
||||
parse_ctx->llc_msg_name);
|
||||
have_patched = 1;
|
||||
}
|
||||
|
||||
if (parse_ctx->old_raid_enc && parse_ctx->old_raid_matches) {
|
||||
/* TODO: Patch to invalid if P-TMSI unknown. */
|
||||
gbprox_patch_raid(parse_ctx->old_raid_enc, peer, parse_ctx->to_bss,
|
||||
parse_ctx->llc_msg_name);
|
||||
have_patched = 1;
|
||||
}
|
||||
|
||||
if (parse_ctx->apn_ie &&
|
||||
peer->cfg->core_apn &&
|
||||
!parse_ctx->to_bss &&
|
||||
|
@ -1399,6 +1422,30 @@ static void gbprox_log_parse_context(struct gbproxy_parse_context *parse_ctx,
|
|||
sep = ",";
|
||||
}
|
||||
|
||||
if (parse_ctx->bssgp_raid_enc) {
|
||||
struct gprs_ra_id raid;
|
||||
gsm48_parse_ra(&raid, parse_ctx->bssgp_raid_enc);
|
||||
LOGP(DGPRS, LOGL_DEBUG, "%s BSSGP RAID %u-%u-%u-%u", sep,
|
||||
raid.mcc, raid.mnc, raid.lac, raid.rac);
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
if (parse_ctx->raid_enc) {
|
||||
struct gprs_ra_id raid;
|
||||
gsm48_parse_ra(&raid, parse_ctx->raid_enc);
|
||||
LOGP(DGPRS, LOGL_DEBUG, "%s RAID %u-%u-%u-%u", sep,
|
||||
raid.mcc, raid.mnc, raid.lac, raid.rac);
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
if (parse_ctx->old_raid_enc) {
|
||||
struct gprs_ra_id raid;
|
||||
gsm48_parse_ra(&raid, parse_ctx->old_raid_enc);
|
||||
LOGP(DGPRS, LOGL_DEBUG, "%s old RAID %u-%u-%u-%u", sep,
|
||||
raid.mcc, raid.mnc, raid.lac, raid.rac);
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
if (parse_ctx->ptmsi_enc) {
|
||||
uint32_t ptmsi = GSM_RESERVED_TMSI;
|
||||
int ok;
|
||||
|
@ -1840,6 +1887,13 @@ static void gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
|
|||
|
||||
now = time(NULL);
|
||||
|
||||
if (parse_ctx.bssgp_raid_enc && parse_ctx.old_raid_enc &&
|
||||
memcmp(parse_ctx.bssgp_raid_enc, parse_ctx.old_raid_enc, 6) == 0)
|
||||
parse_ctx.old_raid_matches = 1;
|
||||
|
||||
gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer,
|
||||
parse_ctx.llc_msg_name);
|
||||
|
||||
tlli_info = gbprox_update_state_ul(peer, now, &parse_ctx);
|
||||
|
||||
gbprox_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),
|
||||
|
|
Loading…
Reference in New Issue