aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-06-27 18:10:53 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-07-22 17:11:57 +0200
commit2e2650f8f33201b1794f656cc8e64657eebee522 (patch)
treeb5b11218dd23b61e4b26e04823cf624c716c0409
parent35cc03f97d7d957bfecd540549a2d0cc809c8684 (diff)
gprs: Parse PTMSI and update TLLI accordingly
This commit adds code to parse the PTMSI in network originated messages - Attach Accept, - Routing Area Update Accept, and - P-TMSI Reallocation Command (see below) to keep track of the TLLI identifying the LLC connection. The P_TMSI Realloc Command specific code is not being tested yet, so a corresponding notice is logged when such a message will be received. NOTE: The gbproxy will lose the TLLI when the MS doesn't receive/use the message (normally the SGSN remembers the old TLLI for some time to avoid this kind of problem). If this happens the MS will probably restart the procedure and the network will have to answer again eventually using one of the above messages which will re-associate the IMSI with the TLLI before the MS can send a PDP Context Request message. Ticket: OW#1192 Sponsored-by: On-Waves ehf
-rw-r--r--openbsc/src/gprs/gb_proxy.c56
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.ok22
2 files changed, 66 insertions, 12 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 5fcd25a5b..b41bedb18 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -519,6 +519,23 @@ fail:
return -1;
}
+static int parse_mi_tmsi(uint8_t *value, size_t value_len, uint32_t *tmsi)
+{
+ uint32_t tmsi_be;
+
+ if (value_len != GSM48_TMSI_LEN)
+ return 0;
+
+ if ((value[0] & 0x0f) != GSM_MI_TYPE_TMSI)
+ return 0;
+
+ memcpy(&tmsi_be, value + 1, sizeof(tmsi_be));
+
+ *tmsi = ntohl(tmsi_be);
+
+ return 1;
+}
+
struct gbprox_parse_context {
/* Pointer to protocol specific parts */
struct gsm48_hdr *g48_hdr;
@@ -991,6 +1008,7 @@ static int gbprox_patch_gmm_attach_ack(struct msgb *msg,
struct gbprox_parse_context *parse_ctx)
{
uint8_t *value;
+ size_t value_len;
/* Skip Attach result */
/* Skip Force to standby */
@@ -1004,6 +1022,17 @@ static int gbprox_patch_gmm_attach_ack(struct msgb *msg,
gbprox_patch_raid(value, peer, parse_ctx->to_bss, "LLC/ATTACH_ACK");
+ /* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
+ tv_fixed_match(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
+
+ /* Skip Negotiated READY timer value (GPRS timer, opt, TV, length 2) */
+ tv_fixed_match(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL);
+
+ /* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
+ if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
+ &value, &value_len) > 0)
+ parse_mi_tmsi(value, value_len, &parse_ctx->new_ptmsi);
+
return 1;
}
@@ -1032,6 +1061,7 @@ static int gbprox_patch_gmm_ra_upd_ack(struct msgb *msg,
struct gbprox_parse_context *parse_ctx)
{
uint8_t *value;
+ size_t value_len;
/* Skip Force to standby */
/* Skip Update result */
@@ -1043,6 +1073,13 @@ static int gbprox_patch_gmm_ra_upd_ack(struct msgb *msg,
gbprox_patch_raid(value, peer, parse_ctx->to_bss, "LLC/RA_UPD_ACK");
+ /* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
+ tv_fixed_match(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
+
+ /* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
+ if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
+ &value, &value_len) > 0)
+ parse_mi_tmsi(value, value_len, &parse_ctx->new_ptmsi);
return 1;
}
@@ -1056,8 +1093,12 @@ static int gbprox_patch_gmm_ptmsi_reall_cmd(struct msgb *msg,
uint8_t *value;
size_t value_len;
- /* Skip Allocated P-TMSI */
- if (lv_shift(&data, &data_len, NULL, &value_len) <= 0 || value_len != 5)
+ LOGP(DLLC, LOGL_NOTICE,
+ "Got P-TMSI Reallocation Command which is not covered by unit tests yet.\n");
+
+ /* Allocated P-TMSI */
+ if (lv_shift(&data, &data_len, &value, &value_len) > 0 &&
+ parse_mi_tmsi(value, value_len, &parse_ctx->new_ptmsi) < 0)
/* invalid */
return 0;
@@ -1272,6 +1313,17 @@ static void gbprox_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
rc = gbprox_patch_dtap(msg, data, data_len, peer, &len_change, parse_ctx);
+ if (parse_ctx->new_ptmsi &&
+ (parse_ctx->new_ptmsi | 0xc000) != (tlli | 0xc000) &&
+ gbcfg.core_apn && parse_ctx->to_bss && parse_ctx->imsi) {
+ /* A new TLLI (PTMSI) has been signaled in the message */
+ LOGP(DGPRS, LOGL_INFO,
+ "Got new TLLI/PTMSI %08x (current is %08x)\n",
+ parse_ctx->new_ptmsi, tlli);
+ gbprox_register_tlli(peer, parse_ctx->new_ptmsi,
+ parse_ctx->imsi, parse_ctx->imsi_len);
+ }
+
if (rc > 0) {
llc_len += len_change;
ghp.crc_length += len_change;
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index f99087d9d..dc0414ca4 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -1657,11 +1657,11 @@ PROCESSING ACT PDP CTX REQ (REPLACE APN) from 0x01020304:1111
CALLBACK, event 0, msg length 76, 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 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
-NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 76 (gprs_ns_sendmsg)
-MESSAGE to SGSN at 0x05060708:32000, msg length 80
-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 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
+NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 81 (gprs_ns_sendmsg)
+MESSAGE to SGSN at 0x05060708:32000, msg length 85
+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 3a 01 c0 0d 0a 41 05 03 0c 00 00 1f 10 00 00 00 00 00 00 00 00 02 01 21 28 08 03 66 6f 6f 03 62 61 72 27 14 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 24 9d 75
-result (ACT PDP CTX REQ (REPLACE APN)) = 80
+result (ACT PDP CTX REQ (REPLACE APN)) = 85
PROCESSING GMM INFO from 0x05060708:32000
00 00 10 02 00 ef e2 b7 00 00 50 20 16 82 02 58 13 99 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 0a 82 08 02 0d 88 11 12 13 14 15 16 17 18 00 81 00 0e 88 41 c0 09 08 21 04 ba 3d
@@ -1703,7 +1703,7 @@ Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 7
RAID patched (SGSN): 2
- APN patched : 2
+ APN patched : 3
Attach Request count : 1
TLLI cache size : 1
TLLI-Cache: 1
@@ -1736,7 +1736,7 @@ Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 8
RAID patched (SGSN): 2
- APN patched : 2
+ APN patched : 3
Attach Request count : 1
TLLI-Cache: 0
--- RA update ---
@@ -1781,9 +1781,11 @@ Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 11
RAID patched (SGSN): 3
- APN patched : 2
+ APN patched : 3
Attach Request count : 1
- TLLI-Cache: 0
+ TLLI cache size : 1
+ TLLI-Cache: 1
+ TLLI efe28117, IMSI 12131415161718, AGE 0
PROCESSING DETACH REQ 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 01 18 05 f4 ef e2 b7 00 19 03 b9 97 cb 7e e1 41
@@ -1813,7 +1815,7 @@ Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 12
RAID patched (SGSN): 3
- APN patched : 2
+ APN patched : 3
Attach Request count : 1
TLLI-Cache: 0
--- Bad cases ---
@@ -1851,7 +1853,7 @@ Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 13
RAID patched (SGSN): 3
- APN patched : 2
+ APN patched : 3
Attach Request count : 1
TLLI-Cache: 0
===== GbProxy test END