gbproxy: Handle old and new P-TMSI/TLLI
Don't replace the current TLLI immediately, store it in an additional 'assigned_tlli' field and discard the old TLLI when both sides have used the new one (see GSM 04.08, 4.7.1.5). Add an Attach Complete message to test and check, whether the related field of the corresponding tlli_info struct are set as expected during the local TLLI validation cycle. Sponsored-by: On-Waves ehf
This commit is contained in:
parent
3c5b40fb75
commit
59748e653b
|
@ -85,6 +85,9 @@ struct gbproxy_tlli_info {
|
|||
struct llist_head list;
|
||||
|
||||
uint32_t tlli;
|
||||
uint32_t assigned_tlli;
|
||||
int bss_validated;
|
||||
int net_validated;
|
||||
time_t timestamp;
|
||||
uint8_t *mi_data;
|
||||
size_t mi_data_len;
|
||||
|
@ -124,6 +127,8 @@ int gbprox_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvc
|
|||
|
||||
struct gbproxy_peer *gbprox_peer_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);
|
||||
|
||||
struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
|
||||
uint32_t tlli);
|
||||
struct gbproxy_tlli_info *gbprox_find_tlli_by_mi(struct gbproxy_peer *peer,
|
||||
const uint8_t *mi_data,
|
||||
size_t mi_data_len);
|
||||
|
|
|
@ -420,14 +420,14 @@ struct gbproxy_parse_context {
|
|||
int pdu_type;
|
||||
};
|
||||
|
||||
static struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *gbprox_find_tlli(struct gbproxy_peer *peer,
|
||||
uint32_t tlli)
|
||||
{
|
||||
struct gbproxy_tlli_info *tlli_info;
|
||||
struct gbproxy_patch_state *state = &peer->patch_state;
|
||||
|
||||
llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
|
||||
if (tlli_info->tlli == tlli)
|
||||
if (tlli_info->tlli == tlli || tlli_info->assigned_tlli == tlli)
|
||||
return tlli_info;
|
||||
|
||||
return NULL;
|
||||
|
@ -659,8 +659,41 @@ void gbprox_reassign_tlli(struct gbproxy_tlli_info *tlli_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;
|
||||
/* Remember assigned TLLI */
|
||||
tlli_info->assigned_tlli = new_tlli;
|
||||
tlli_info->bss_validated = 0;
|
||||
tlli_info->net_validated = 0;
|
||||
}
|
||||
|
||||
static void gbprox_validate_tlli(struct gbproxy_tlli_info *tlli_info,
|
||||
uint32_t tlli, int to_bss)
|
||||
{
|
||||
LOGP(DGPRS, LOGL_DEBUG,
|
||||
"%s({tlli = %08x, assigned_tlli = %08x, net_vld = %d, bss_vld = %d}, %08x)\n",
|
||||
__func__, tlli_info->tlli, tlli_info->assigned_tlli,
|
||||
tlli_info->net_validated, tlli_info->bss_validated, tlli);
|
||||
|
||||
if (!tlli_info->assigned_tlli || tlli_info->assigned_tlli != tlli)
|
||||
return;
|
||||
|
||||
if (gprs_tlli_type(tlli) != TLLI_LOCAL)
|
||||
return;
|
||||
|
||||
/* See GSM 04.08, 4.7.1.5 */
|
||||
if (to_bss)
|
||||
tlli_info->net_validated = 1;
|
||||
else
|
||||
tlli_info->bss_validated = 1;
|
||||
|
||||
if (!tlli_info->bss_validated || !tlli_info->net_validated)
|
||||
return;
|
||||
|
||||
LOGP(DGPRS, LOGL_INFO,
|
||||
"The TLLI %08x has been validated (was %08x)\n",
|
||||
tlli_info->assigned_tlli, tlli_info->tlli);
|
||||
|
||||
tlli_info->tlli = tlli;
|
||||
tlli_info->assigned_tlli = 0;
|
||||
}
|
||||
|
||||
void gbprox_touch_tlli(struct gbproxy_peer *peer,
|
||||
|
@ -1429,10 +1462,16 @@ static struct gbproxy_tlli_info *gbprox_update_state(
|
|||
parse_ctx->imsi_len, now);
|
||||
}
|
||||
} else if (parse_ctx->tlli_enc && parse_ctx->llc) {
|
||||
if (!tlli_info) {
|
||||
tlli_info =
|
||||
gbprox_register_tlli(peer, parse_ctx->tlli,
|
||||
parse_ctx->imsi,
|
||||
parse_ctx->imsi_len, now);
|
||||
} else {
|
||||
gbprox_validate_tlli(tlli_info, parse_ctx->tlli,
|
||||
parse_ctx->to_bss);
|
||||
gbprox_touch_tlli(peer, tlli_info, now);
|
||||
}
|
||||
} else if (tlli_info) {
|
||||
gbprox_touch_tlli(peer, tlli_info, now);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <osmocom/core/signal.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gprs/gprs_msgb.h>
|
||||
#include <osmocom/gprs/gprs_ns.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
|
@ -124,10 +125,12 @@ static int dump_peers(FILE *stream, int indent, time_t now,
|
|||
} else {
|
||||
snprintf(mi_buf, sizeof(mi_buf), "(none)");
|
||||
}
|
||||
rc = fprintf(stream,
|
||||
"%*s TLLI %08x, IMSI %s, AGE %d\n",
|
||||
indent, "",
|
||||
tlli_info->tlli, mi_buf, (int)age);
|
||||
fprintf(stream, "%*s TLLI %08x",
|
||||
indent, "", tlli_info->tlli);
|
||||
if (tlli_info->assigned_tlli)
|
||||
fprintf(stream, "/%08x", tlli_info->assigned_tlli);
|
||||
rc = fprintf(stream, ", IMSI %s, AGE %d\n",
|
||||
mi_buf, (int)age);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
@ -181,6 +184,14 @@ static const unsigned char bssgp_attach_acc[88] = {
|
|||
0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x42, 0x67, 0x9a
|
||||
};
|
||||
|
||||
/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Complete */
|
||||
static const unsigned char bssgp_attach_complete[] = {
|
||||
0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
|
||||
0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
|
||||
0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x08, 0x01,
|
||||
0xc0, 0x11, 0x08, 0x03, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - GMM Information */
|
||||
static const unsigned char bssgp_gmm_information[66] = {
|
||||
0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
|
||||
|
@ -970,6 +981,12 @@ static void test_gbproxy_ra_patching()
|
|||
struct gprs_ra_id rai_unknown =
|
||||
{.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
|
||||
const char *err_msg = NULL;
|
||||
const uint32_t ptmsi = 0xefe2b700;
|
||||
const uint32_t local_tlli = 0xefe2b700;
|
||||
struct gbproxy_tlli_info *tlli_info;
|
||||
struct gbproxy_peer *peer;
|
||||
|
||||
OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
|
||||
|
||||
bssgp_nsi = nsi;
|
||||
gbcfg.nsi = bssgp_nsi;
|
||||
|
@ -1003,6 +1020,9 @@ static void test_gbproxy_ra_patching()
|
|||
gprs_dump_nsi(nsi);
|
||||
dump_peers(stdout, 0, 0, &gbcfg);
|
||||
|
||||
peer = gbprox_peer_by_nsei(&gbcfg, 0x1000);
|
||||
OSMO_ASSERT(peer != NULL);
|
||||
|
||||
send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
|
||||
|
||||
send_bssgp_suspend(nsi, &bss_peer[0], &rai_bss);
|
||||
|
@ -1025,14 +1045,43 @@ static void test_gbproxy_ra_patching()
|
|||
send_ns_unitdata(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
|
||||
bssgp_attach_acc, sizeof(bssgp_attach_acc));
|
||||
|
||||
tlli_info = gbprox_find_tlli(peer, local_tlli);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->assigned_tlli == local_tlli);
|
||||
OSMO_ASSERT(tlli_info->tlli != local_tlli);
|
||||
OSMO_ASSERT(!tlli_info->bss_validated);
|
||||
OSMO_ASSERT(!tlli_info->net_validated);
|
||||
|
||||
send_ns_unitdata(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
|
||||
bssgp_attach_complete, sizeof(bssgp_attach_complete));
|
||||
|
||||
tlli_info = gbprox_find_tlli(peer, local_tlli);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->assigned_tlli == local_tlli);
|
||||
OSMO_ASSERT(tlli_info->tlli != local_tlli);
|
||||
OSMO_ASSERT(tlli_info->bss_validated);
|
||||
OSMO_ASSERT(!tlli_info->net_validated);
|
||||
|
||||
/* Replace APN (1) */
|
||||
send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
|
||||
&bss_peer[0], 0x1002,
|
||||
bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
|
||||
|
||||
tlli_info = gbprox_find_tlli(peer, local_tlli);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->assigned_tlli == local_tlli);
|
||||
OSMO_ASSERT(tlli_info->tlli != local_tlli);
|
||||
OSMO_ASSERT(tlli_info->bss_validated);
|
||||
OSMO_ASSERT(!tlli_info->net_validated);
|
||||
|
||||
send_ns_unitdata(nsi, "GMM INFO", &sgsn_peer, 0x1002,
|
||||
bssgp_gmm_information, sizeof(bssgp_gmm_information));
|
||||
|
||||
tlli_info = gbprox_find_tlli(peer, local_tlli);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->assigned_tlli == 0);
|
||||
OSMO_ASSERT(tlli_info->tlli == local_tlli);
|
||||
|
||||
/* Replace APN (2) */
|
||||
send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
|
||||
&bss_peer[0], 0x1002,
|
||||
|
|
|
@ -1677,6 +1677,18 @@ MESSAGE to BSS at 0x01020304:1111, msg length 92
|
|||
|
||||
result (ATTACH ACCEPT) = 92
|
||||
|
||||
PROCESSING ATTACH COMPLETE from 0x01020304:1111
|
||||
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ff ff ff
|
||||
|
||||
CALLBACK, event 0, msg length 31, bvci 0x1002
|
||||
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ff ff ff
|
||||
|
||||
NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 31 (gprs_ns_sendmsg)
|
||||
MESSAGE to SGSN at 0x05060708:32000, msg length 35
|
||||
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 08 01 c0 11 08 03 ff ff ff
|
||||
|
||||
result (ATTACH COMPLETE) = 35
|
||||
|
||||
PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111
|
||||
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 35 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 03 02 61 62 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 5a ff 02
|
||||
|
||||
|
@ -1727,7 +1739,7 @@ result (ACT PDP CTX REQ (REMOVE APN)) = 75
|
|||
|
||||
Peers:
|
||||
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
|
||||
RAID patched (BSS ): 8
|
||||
RAID patched (BSS ): 9
|
||||
RAID patched (SGSN): 2
|
||||
APN patched : 3
|
||||
Attach Request count : 1
|
||||
|
@ -1760,7 +1772,7 @@ result (DETACH ACC) = 71
|
|||
|
||||
Peers:
|
||||
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
|
||||
RAID patched (BSS ): 9
|
||||
RAID patched (BSS ): 10
|
||||
RAID patched (SGSN): 2
|
||||
APN patched : 3
|
||||
Attach Request count : 1
|
||||
|
@ -1805,13 +1817,13 @@ result (ACT PDP CTX REQ (REMOVE APN)) = 75
|
|||
|
||||
Peers:
|
||||
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
|
||||
RAID patched (BSS ): 12
|
||||
RAID patched (BSS ): 13
|
||||
RAID patched (SGSN): 3
|
||||
APN patched : 4
|
||||
Attach Request count : 1
|
||||
TLLI cache size : 1
|
||||
TLLI-Cache: 1
|
||||
TLLI efe2b700, IMSI 12131415161718, AGE 0
|
||||
TLLI bbc54679/efe2b700, IMSI 12131415161718, AGE 0
|
||||
PROCESSING DETACH REQ (PWR OFF) from 0x01020304:1111
|
||||
00 00 10 02 01 ef e2 b7 00 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 15 01 c0 19 08 05 09 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 84 0c eb
|
||||
|
||||
|
@ -1827,7 +1839,7 @@ result (DETACH REQ (PWR OFF)) = 48
|
|||
Gbproxy global:
|
||||
Peers:
|
||||
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
|
||||
RAID patched (BSS ): 13
|
||||
RAID patched (BSS ): 14
|
||||
RAID patched (SGSN): 3
|
||||
APN patched : 4
|
||||
Attach Request count : 1
|
||||
|
@ -1865,7 +1877,7 @@ Gbproxy global:
|
|||
Patch error: no peer : 1
|
||||
Peers:
|
||||
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
|
||||
RAID patched (BSS ): 14
|
||||
RAID patched (BSS ): 15
|
||||
RAID patched (SGSN): 3
|
||||
APN patched : 4
|
||||
Attach Request count : 1
|
||||
|
|
Loading…
Reference in New Issue