aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-06 15:16:45 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2014-08-13 09:55:27 +0200
commit690768a1717cda1fbc027ed75c818e886da50f7c (patch)
tree79065f9a592ada4b93815c2bc5ca4b6d84efae69 /openbsc
parent2db2512f4de4bc88c934293eb260e4888c240b3e (diff)
gbproxy: Parse additional IMSI/PTMSI/TLLI fields
This adds parsing support for the following messages: - Attach Request: IMSI/PTMSI - Identity Response: IMSI/PTMSI - BSSGP: Optional TLLI IE - BSSGP/PAGING_PS: PTMSI A new new_ptmsi_enc field is added for newly assigned PTMSI in SGSN->BSS messages (instead of ptmsi_enc). The ptmsi_enc field is now used for informational PTMSI IE in messages. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/src/gprs/gb_proxy.c79
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.c22
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.ok34
3 files changed, 121 insertions, 14 deletions
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 003534903..7945c42df 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -359,6 +359,17 @@ static int is_mi_tmsi(uint8_t *value, size_t value_len)
return 1;
}
+static int is_mi_imsi(uint8_t *value, size_t value_len)
+{
+ if (value_len == 0)
+ return 0;
+
+ if (!value || (value[0] & 0x0f) != GSM_MI_TYPE_IMSI)
+ return 0;
+
+ return 1;
+}
+
static int parse_mi_tmsi(uint8_t *value, size_t value_len, uint32_t *tmsi)
{
uint32_t tmsi_be;
@@ -392,6 +403,7 @@ struct gbproxy_parse_context {
uint8_t *apn_ie;
size_t apn_ie_len;
uint8_t *ptmsi_enc;
+ uint8_t *new_ptmsi_enc;
uint8_t *raid_enc;
uint8_t *bssgp_raid_enc;
uint8_t *bssgp_ptimsi;
@@ -847,11 +859,18 @@ static int gbprox_parse_gmm_attach_req(uint8_t *data, size_t data_len,
/* Skip DRX parameter */
v_fixed_shift(&data, &data_len, 3, NULL);
- /* Skip Mobile identity */
- if (lv_shift(&data, &data_len, NULL, &value_len) <= 0 ||
+ /* Get Mobile identity */
+ if (lv_shift(&data, &data_len, &value, &value_len) <= 0 ||
value_len < 5 || value_len > 8)
/* invalid */
- return 0;;
+ return 0;
+
+ if (is_mi_tmsi(value, value_len)) {
+ parse_ctx->ptmsi_enc = value;
+ } else if (is_mi_imsi(value, value_len)) {
+ parse_ctx->imsi = value;
+ parse_ctx->imsi_len = value_len;
+ }
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
@@ -891,7 +910,7 @@ static int gbprox_parse_gmm_attach_ack(uint8_t *data, size_t data_len,
if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
&value, &value_len) > 0 &&
is_mi_tmsi(value, value_len))
- parse_ctx->ptmsi_enc = value;
+ parse_ctx->new_ptmsi_enc = value;
return 1;
}
@@ -939,7 +958,7 @@ static int gbprox_parse_gmm_ra_upd_ack(uint8_t *data, size_t data_len,
if (tlv_match(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
&value, &value_len) > 0 &&
is_mi_tmsi(value, value_len))
- parse_ctx->ptmsi_enc = value;
+ parse_ctx->new_ptmsi_enc = value;
return 1;
}
@@ -958,7 +977,7 @@ static int gbprox_parse_gmm_ptmsi_reall_cmd(uint8_t *data, size_t data_len,
/* Allocated P-TMSI */
if (lv_shift(&data, &data_len, &value, &value_len) > 0 &&
is_mi_tmsi(value, value_len))
- parse_ctx->ptmsi_enc = value;
+ parse_ctx->new_ptmsi_enc = value;
if (v_fixed_shift(&data, &data_len, 6, &value) <= 0)
return 0;
@@ -968,6 +987,30 @@ static int gbprox_parse_gmm_ptmsi_reall_cmd(uint8_t *data, size_t data_len,
return 1;
}
+static int gbprox_parse_gmm_id_resp(uint8_t *data, size_t data_len,
+ struct gbproxy_parse_context *parse_ctx)
+{
+ uint8_t *value;
+ size_t value_len;
+
+ parse_ctx->llc_msg_name = "ID_RESP";
+
+ /* Mobile identity, Mobile identity 10.5.1.4, M LV 2-10 */
+ if (lv_shift(&data, &data_len, &value, &value_len) <= 0 ||
+ value_len < 1 || value_len > 9)
+ /* invalid */
+ return 0;
+
+ if (is_mi_tmsi(value, value_len)) {
+ parse_ctx->ptmsi_enc = value;
+ } else if (is_mi_imsi(value, value_len)) {
+ parse_ctx->imsi = value;
+ parse_ctx->imsi_len = value_len;
+ }
+
+ return 1;
+}
+
static int gbprox_parse_gsm_act_pdp_req(uint8_t *data, size_t data_len,
struct gbproxy_parse_context *parse_ctx)
{
@@ -1067,6 +1110,10 @@ static int gbprox_parse_dtap(uint8_t *data, size_t data_len,
case GSM48_MT_GSM_ACT_PDP_REQ:
return gbprox_parse_gsm_act_pdp_req(data, data_len, parse_ctx);
+ case GSM48_MT_GMM_ID_RESP:
+ return gbprox_parse_gmm_id_resp(data, data_len, parse_ctx);
+ break;
+
case GSM48_MT_GMM_DETACH_REQ:
/* TODO: Check power off if !to_bss, if yes invalidate */
parse_ctx->llc_msg_name = "DETACH_REQ";
@@ -1216,9 +1263,17 @@ static void gbprox_update_state(struct gbproxy_peer *peer,
}
if (parse_ctx->ptmsi_enc) {
+ uint32_t ptmsi = GSM_RESERVED_TMSI;
+ int ok;
+ ok = parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN, &ptmsi);
+ LOGP(DGPRS, LOGL_DEBUG, "%s: Got PTMSI %08x%s\n",
+ msg_name, ptmsi, ok ? "" : " (parse error)");
+ }
+
+ if (parse_ctx->new_ptmsi_enc) {
uint32_t new_ptmsi = GSM_RESERVED_TMSI;
int ok;
- ok = parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN,
+ ok = parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
&new_ptmsi);
LOGP(DGPRS, LOGL_DEBUG, "%s: Got new PTMSI %08x%s\n",
msg_name, new_ptmsi, ok ? "" : " (parse error)");
@@ -1233,10 +1288,10 @@ static void gbprox_update_state(struct gbproxy_peer *peer,
msg_name, mi_buf);
}
- if (parse_ctx->ptmsi_enc && parse_ctx->to_bss && parse_ctx->imsi) {
+ if (parse_ctx->new_ptmsi_enc && parse_ctx->to_bss && parse_ctx->imsi) {
/* A new TLLI (PTMSI) has been signaled in the message */
uint32_t new_ptmsi;
- if (!parse_mi_tmsi(parse_ctx->ptmsi_enc, GSM48_TMSI_LEN,
+ if (!parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
&new_ptmsi)) {
LOGP(DGPRS, LOGL_ERROR,
"Failed to parse new TLLI/PTMSI (current is %08x)\n",
@@ -1316,6 +1371,12 @@ static int gbprox_parse_bssgp_message(uint8_t *bssgp, size_t bssgp_len,
parse_ctx->imsi_len = TLVP_LEN(tp, BSSGP_IE_IMSI);
}
+ if (TLVP_PRESENT(tp, BSSGP_IE_TLLI))
+ parse_ctx->tlli_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TLLI);
+
+ if (TLVP_PRESENT(tp, BSSGP_IE_TMSI) && pdu_type == BSSGP_PDUT_PAGING_PS)
+ parse_ctx->ptmsi_enc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_TMSI);
+
if (TLVP_PRESENT(tp, BSSGP_IE_LLC_PDU)) {
uint8_t *llc = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LLC_PDU);
size_t llc_len = TLVP_LEN(tp, BSSGP_IE_LLC_PDU);
diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c
index a3768ae17..769dc675d 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.c
+++ b/openbsc/tests/gbproxy/gbproxy_test.c
@@ -146,6 +146,22 @@ static const unsigned char bssgp_attach_req[75] = {
0x16, 0x6d, 0x01
};
+/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Identity Request */
+static const unsigned char bssgp_identity_req[] = {
+ 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
+ 0x16, 0x82, 0x02, 0x58, 0x0e, 0x89, 0x41, 0xc0,
+ 0x01, 0x08, 0x15, 0x01, 0xff, 0x6c, 0xba
+};
+
+/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Identity Response */
+static const unsigned char bssgp_identity_resp[] = {
+ 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
+ 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
+ 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x11, 0x01,
+ 0xc0, 0x0d, 0x08, 0x16, 0x08, 0x11, 0x12, 0x13,
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0xb7, 0x1b, 0x9a
+};
+
/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Accept */
static const unsigned char bssgp_attach_acc[88] = {
0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
@@ -984,6 +1000,12 @@ static void test_gbproxy_ra_patching()
send_ns_unitdata(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
bssgp_attach_req, sizeof(bssgp_attach_req));
+ send_ns_unitdata(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
+ bssgp_identity_req, sizeof(bssgp_identity_req));
+
+ send_ns_unitdata(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
+ bssgp_identity_resp, sizeof(bssgp_identity_resp));
+
send_ns_unitdata(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
bssgp_attach_acc, sizeof(bssgp_attach_acc));
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index 036c4a3e4..ee67c33ef 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -1639,6 +1639,30 @@ MESSAGE to SGSN at 0x05060708:32000, msg length 79
result (ATTACH REQUEST) = 79
+PROCESSING IDENT REQUEST from 0x05060708:32000
+00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
+
+CALLBACK, event 0, msg length 23, bvci 0x1002
+00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
+
+NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 23 (gprs_ns_sendmsg)
+MESSAGE to BSS at 0x01020304:1111, msg length 27
+00 00 10 02 00 bb c5 46 79 00 50 20 16 82 02 58 0e 89 41 c0 01 08 15 01 ff 6c ba
+
+result (IDENT REQUEST) = 27
+
+PROCESSING IDENT RESPONSE from 0x01020304:1111
+00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a
+
+CALLBACK, event 0, msg length 40, bvci 0x1002
+00 00 10 02 01 bb c5 46 79 00 00 04 08 88 11 22 33 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a
+
+NS UNITDATA MESSAGE to SGSN, BVCI 0x1002, msg length 40 (gprs_ns_sendmsg)
+MESSAGE to SGSN at 0x05060708:32000, msg length 44
+00 00 10 02 01 bb c5 46 79 00 00 04 08 88 21 63 54 40 50 60 75 30 00 80 0e 00 11 01 c0 0d 08 16 08 11 12 13 14 15 16 17 18 b7 1b 9a
+
+result (IDENT RESPONSE) = 44
+
PROCESSING ATTACH ACCEPT from 0x05060708:32000
00 00 10 02 00 bb c5 46 79 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 9e 41 c0 05 08 02 01 49 04 21 63 54 40 50 60 19 cd d7 08 17 16 18 05 f4 ef e2 b7 00 42 67 9a
@@ -1701,7 +1725,7 @@ result (ACT PDP CTX REQ (REMOVE APN)) = 75
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
- RAID patched (BSS ): 7
+ RAID patched (BSS ): 8
RAID patched (SGSN): 2
APN patched : 3
Attach Request count : 1
@@ -1734,7 +1758,7 @@ result (DETACH ACC) = 71
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
@@ -1779,7 +1803,7 @@ result (ACT PDP CTX REQ (REMOVE APN)) = 80
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
- RAID patched (BSS ): 11
+ RAID patched (BSS ): 12
RAID patched (SGSN): 3
APN patched : 3
Attach Request count : 1
@@ -1813,7 +1837,7 @@ result (DETACH ACC) = 71
Gbproxy global:
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 : 3
Attach Request count : 1
@@ -1851,7 +1875,7 @@ Gbproxy global:
Patch error: no peer : 1
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 : 3
Attach Request count : 1