aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gb_proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gprs/gb_proxy.c')
-rw-r--r--openbsc/src/gprs/gb_proxy.c94
1 files changed, 58 insertions, 36 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 98b10b972..103ecb59e 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -439,6 +439,9 @@ struct gbproxy_tlli_info *gbprox_find_tlli_by_mi(
struct gbproxy_tlli_info *tlli_info;
struct gbproxy_patch_state *state = &peer->patch_state;
+ if (!is_mi_imsi(mi_data, mi_data_len))
+ return NULL;
+
llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
if (tlli_info->mi_data_len != mi_data_len)
continue;
@@ -600,6 +603,9 @@ static struct gbproxy_tlli_info *gbprox_get_detached_tlli_info(
static void gbprox_update_tlli_info(struct gbproxy_tlli_info *tlli_info,
const uint8_t *imsi, size_t imsi_len)
{
+ if (!is_mi_imsi(imsi, imsi_len))
+ return;
+
tlli_info->mi_data_len = imsi_len;
tlli_info->mi_data =
talloc_realloc_size(tlli_info, tlli_info->mi_data, imsi_len);
@@ -607,26 +613,35 @@ static void gbprox_update_tlli_info(struct gbproxy_tlli_info *tlli_info,
memcpy(tlli_info->mi_data, imsi, imsi_len);
}
+void gbprox_reassign_tlli(struct gbproxy_tlli_info *tlli_info,
+ struct gbproxy_peer *peer, uint32_t new_tlli)
+{
+ if (new_tlli == tlli_info->tlli)
+ return;
+
+ LOGP(DGPRS, LOGL_INFO,
+ "The TLLI has been reassigned from %08x to %08x\n",
+ tlli_info->tlli, new_tlli);
+
+ /* TODO: Save old TLLI */
+ tlli_info->tlli = new_tlli;
+}
+
void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli,
const uint8_t *imsi, size_t imsi_len)
{
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_tlli_info *tlli_info;
- int enable_patching;
+ int enable_patching = -1;
time_t now = 0;
int tlli_already_known;
- if (!imsi || (imsi[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMSI)
- return;
-
- if (!peer->cfg->check_imsi)
- return;
-
/* Check, whether the IMSI matches */
- enable_patching = gbprox_check_imsi(peer, imsi, imsi_len);
-
- if (enable_patching < 0)
- return;
+ if (is_mi_imsi(imsi, imsi_len)) {
+ enable_patching = gbprox_check_imsi(peer, imsi, imsi_len);
+ if (enable_patching < 0)
+ return;
+ }
tlli_info = gbprox_find_tlli(peer, tlli);
@@ -644,32 +659,23 @@ void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli,
tlli_already_known = tlli_info != NULL;
- if (!tlli_already_known && !enable_patching)
- return;
-
tlli_info = gbprox_get_detached_tlli_info(peer, tlli_info, tlli);
OSMO_ASSERT(tlli_info != NULL);
- if (enable_patching) {
- if (!tlli_already_known)
- LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
+ if (!tlli_already_known)
+ LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
- now = time(NULL);
+ now = time(NULL);
- gbprox_attach_tlli_info(peer, now, tlli_info);
- gbprox_update_tlli_info(tlli_info, imsi, imsi_len);
+ gbprox_attach_tlli_info(peer, now, tlli_info);
+ gbprox_update_tlli_info(tlli_info, imsi, imsi_len);
+ if (enable_patching >= 0)
+ tlli_info->enable_patching = enable_patching;
- gbprox_remove_stale_tllis(peer, now);
- /* Be on the safe side, currently the new tlli_info won't be
- * removed, but this not enforced explicitely */
- tlli_info = NULL;
- } else {
- LOGP(DGPRS, LOGL_INFO,
- "Removing TLLI %08x from list (patching no longer enabled)\n",
- tlli);
- talloc_free(tlli_info);
- tlli_info = NULL;
- }
+ gbprox_remove_stale_tllis(peer, now);
+ /* Be on the safe side, currently the new tlli_info won't be
+ * removed, but this not enforced explicitely */
+ tlli_info = NULL;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->enabled_tllis_count;
@@ -694,11 +700,17 @@ static void gbprox_unregister_tlli(struct gbproxy_peer *peer, uint32_t tlli)
static int gbprox_check_tlli(struct gbproxy_peer *peer, uint32_t tlli)
{
+ struct gbproxy_tlli_info *tlli_info;
+
LOGP(DGPRS, LOGL_INFO, "Checking TLLI %08x, class: %d\n",
tlli, gprs_tlli_type(tlli));
- return !peer->cfg->check_imsi ||
- gbprox_find_tlli(peer, tlli) != NULL;
+ if (!peer->cfg->check_imsi)
+ return 1;
+
+ tlli_info = gbprox_find_tlli(peer, tlli);
+
+ return tlli_info != NULL && tlli_info->enable_patching;
}
/* check whether patching is enabled at this level */
@@ -1240,6 +1252,13 @@ static void gbprox_update_state(struct gbproxy_peer *peer,
struct gbproxy_parse_context *parse_ctx)
{
const char *msg_name = "BSSGP";
+ struct gbproxy_tlli_info *tlli_info = NULL;
+
+ if (!peer->cfg->check_imsi)
+ return;
+
+ if (parse_ctx->tlli_enc)
+ tlli_info = gbprox_find_tlli(peer, parse_ctx->tlli);
if (parse_ctx->llc_msg_name)
msg_name = parse_ctx->llc_msg_name;
@@ -1290,7 +1309,8 @@ static void gbprox_update_state(struct gbproxy_peer *peer,
msg_name, mi_buf);
}
- if (parse_ctx->new_ptmsi_enc && parse_ctx->to_bss && parse_ctx->imsi) {
+ if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc &&
+ parse_ctx->to_bss) {
/* A new PTMSI has been signaled in the message,
* register new TLLI */
uint32_t new_ptmsi;
@@ -1306,9 +1326,11 @@ static void gbprox_update_state(struct gbproxy_peer *peer,
LOGP(DGPRS, LOGL_INFO,
"Got new TLLI/PTMSI %08x/%08x (current is %08x)\n",
new_tlli, new_ptmsi, parse_ctx->tlli);
- gbprox_register_tlli(peer, new_ptmsi,
+ if (tlli_info)
+ gbprox_reassign_tlli(tlli_info, peer, new_tlli);
+ gbprox_register_tlli(peer, new_tlli,
parse_ctx->imsi, parse_ctx->imsi_len);
- } else if (parse_ctx->tlli && parse_ctx->imsi) {
+ } else if (parse_ctx->tlli_enc && parse_ctx->llc) {
gbprox_register_tlli(peer, parse_ctx->tlli,
parse_ctx->imsi, parse_ctx->imsi_len);
}