aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gprs_gb_parse.h2
-rw-r--r--openbsc/src/gprs/gb_proxy_patch.c13
-rw-r--r--openbsc/src/gprs/gb_proxy_tlli.c28
-rw-r--r--openbsc/src/gprs/gprs_gb_parse.c10
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.c57
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.ok32
6 files changed, 133 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/gprs_gb_parse.h b/openbsc/include/openbsc/gprs_gb_parse.h
index 4dc5f6ff1..246839286 100644
--- a/openbsc/include/openbsc/gprs_gb_parse.h
+++ b/openbsc/include/openbsc/gprs_gb_parse.h
@@ -29,7 +29,7 @@ struct gprs_gb_parse_context {
uint8_t *raid_enc;
uint8_t *old_raid_enc;
uint8_t *bssgp_raid_enc;
- uint8_t *bssgp_ptimsi;
+ uint8_t *bssgp_ptmsi_enc;
/* General info */
const char *llc_msg_name;
diff --git a/openbsc/src/gprs/gb_proxy_patch.c b/openbsc/src/gprs/gb_proxy_patch.c
index b14809495..c1d2497db 100644
--- a/openbsc/src/gprs/gb_proxy_patch.c
+++ b/openbsc/src/gprs/gb_proxy_patch.c
@@ -327,6 +327,19 @@ void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
}
}
+ if (parse_ctx->bssgp_ptmsi_enc && peer->cfg->patch_ptmsi) {
+ uint32_t ptmsi;
+ if (parse_ctx->to_bss)
+ ptmsi = link_info->tlli.ptmsi;
+ else
+ ptmsi = link_info->sgsn_tlli.ptmsi;
+
+ if (ptmsi != GSM_RESERVED_TMSI)
+ gbproxy_patch_ptmsi(
+ parse_ctx->bssgp_ptmsi_enc, peer,
+ ptmsi, parse_ctx->to_bss, "BSSGP P-TMSI");
+ }
+
if (parse_ctx->llc) {
uint8_t *llc = parse_ctx->llc;
size_t llc_len = parse_ctx->llc_len;
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c
index 467006e87..54e41e9e0 100644
--- a/openbsc/src/gprs/gb_proxy_tlli.c
+++ b/openbsc/src/gprs/gb_proxy_tlli.c
@@ -542,6 +542,30 @@ struct gbproxy_link_info *gbproxy_update_link_state_ul(
return link_info;
}
+static struct gbproxy_link_info *gbproxy_get_link_info_dl(
+ struct gbproxy_peer *peer,
+ struct gprs_gb_parse_context *parse_ctx)
+{
+ struct gbproxy_link_info *link_info = NULL;
+
+ /* Which key to use depends on its availability only, if that fails, do
+ * not retry it with another key (e.g. IMSI). */
+ if (parse_ctx->tlli_enc)
+ link_info = gbproxy_link_info_by_sgsn_tlli(peer, parse_ctx->tlli,
+ parse_ctx->peer_nsei);
+
+ /* TODO: Get link_info by (SGSN) P-TMSI if that is available (see
+ * GSM 08.18, 7.2) instead of using the IMSI as key. */
+ else if (parse_ctx->imsi)
+ link_info = gbproxy_link_info_by_imsi(
+ peer, parse_ctx->imsi, parse_ctx->imsi_len);
+
+ if (link_info)
+ link_info->is_deregistered = 0;
+
+ return link_info;
+}
+
struct gbproxy_link_info *gbproxy_update_link_state_dl(
struct gbproxy_peer *peer,
time_t now,
@@ -549,9 +573,7 @@ struct gbproxy_link_info *gbproxy_update_link_state_dl(
{
struct gbproxy_link_info *link_info = NULL;
- if (parse_ctx->tlli_enc)
- link_info = gbproxy_link_info_by_sgsn_tlli(
- peer, parse_ctx->tlli, parse_ctx->peer_nsei);
+ link_info = gbproxy_get_link_info_dl(peer, parse_ctx);
if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && link_info) {
/* A new P-TMSI has been signalled in the message,
diff --git a/openbsc/src/gprs/gprs_gb_parse.c b/openbsc/src/gprs/gprs_gb_parse.c
index 8e72cc819..6c6371ca0 100644
--- a/openbsc/src/gprs/gprs_gb_parse.c
+++ b/openbsc/src/gprs/gprs_gb_parse.c
@@ -596,7 +596,7 @@ int gprs_gb_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
}
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);
+ parse_ctx->bssgp_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);
@@ -633,6 +633,7 @@ void gprs_gb_log_parse_context(int log_level,
if (!parse_ctx->tlli_enc &&
!parse_ctx->ptmsi_enc &&
!parse_ctx->new_ptmsi_enc &&
+ !parse_ctx->bssgp_ptmsi_enc &&
!parse_ctx->imsi)
return;
@@ -681,6 +682,13 @@ void gprs_gb_log_parse_context(int log_level,
sep = ",";
}
+ if (parse_ctx->bssgp_ptmsi_enc) {
+ uint32_t ptmsi = GSM_RESERVED_TMSI;
+ gprs_parse_tmsi(parse_ctx->bssgp_ptmsi_enc, &ptmsi);
+ LOGPC(DGPRS, log_level, "%s BSSGP PTMSI %08x", sep, ptmsi);
+ sep = ",";
+ }
+
if (parse_ctx->ptmsi_enc) {
uint32_t ptmsi = GSM_RESERVED_TMSI;
gprs_parse_tmsi(parse_ctx->ptmsi_enc, &ptmsi);
diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c
index 103b4bd62..3986325a7 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.c
+++ b/openbsc/tests/gbproxy/gbproxy_test.c
@@ -721,6 +721,53 @@ static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
}
+static void send_bssgp_paging(struct gprs_ns_inst *nsi,
+ struct sockaddr_in *src_addr,
+ const uint8_t *imsi, size_t imsi_size,
+ struct gprs_ra_id *raid, uint32_t ptmsi)
+{
+ /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
+ unsigned char msg[100] = {
+ 0x06,
+ };
+
+ const unsigned char drx_ie[] = {0x0a, 0x82, 0x07, 0x04};
+ const unsigned char qos_ie[] = {0x18, 0x83, 0x00, 0x00, 0x00};
+
+ size_t bssgp_msg_size = 1;
+
+ if (imsi) {
+ OSMO_ASSERT(imsi_size <= 127);
+ msg[bssgp_msg_size] = BSSGP_IE_IMSI;
+ msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
+ memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
+ bssgp_msg_size += 2 + imsi_size;
+ }
+
+ memcpy(msg + bssgp_msg_size, drx_ie, sizeof(drx_ie));
+ bssgp_msg_size += sizeof(drx_ie);
+
+ if (raid) {
+ msg[bssgp_msg_size] = BSSGP_IE_ROUTEING_AREA;
+ msg[bssgp_msg_size+1] = 0x86;
+ gsm48_construct_ra(msg + bssgp_msg_size + 2, raid);
+ bssgp_msg_size += 8;
+ }
+
+ memcpy(msg + bssgp_msg_size, qos_ie, sizeof(qos_ie));
+ bssgp_msg_size += sizeof(qos_ie);
+
+ if (ptmsi != GSM_RESERVED_TMSI) {
+ const uint32_t ptmsi_be = htonl(ptmsi);
+ msg[bssgp_msg_size] = BSSGP_IE_TMSI;
+ msg[bssgp_msg_size+1] = 0x84;
+ memcpy(msg + bssgp_msg_size + 2, &ptmsi_be, 4);
+ bssgp_msg_size += 6;
+ }
+
+ send_ns_unitdata(nsi, "PAGING_PS", src_addr, 0, msg, bssgp_msg_size);
+}
+
static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
struct sockaddr_in *src_addr,
uint16_t bvci, uint8_t tag)
@@ -2127,6 +2174,7 @@ static void test_gbproxy_ptmsi_patching()
struct gbproxy_peer *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
+ int old_ctr;
OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
@@ -2366,6 +2414,15 @@ static void test_gbproxy_ptmsi_patching()
dump_peers(stdout, 0, 0, &gbcfg);
+ old_ctr = peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current;
+
+ send_bssgp_paging(nsi, &sgsn_peer, imsi, sizeof(imsi), &rai_bss, sgsn_ptmsi3);
+
+ dump_peers(stdout, 0, 0, &gbcfg);
+
+ OSMO_ASSERT(old_ctr + 1 ==
+ peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current);
+
/* Bad case: Invalid BVCI */
send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
local_bss_tlli3, 1, 12);
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index 9dbcb4588..c5bf0c853 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -2756,6 +2756,30 @@ Peers:
TLLI cache size : 1
TLLI-Cache: 1
TLLI ead4775a -> e0543210, IMSI 12131415161718, AGE 0
+PROCESSING PAGING_PS from 0x05060708:32000
+00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 e0 54 32 10
+
+CALLBACK, event 0, msg length 34, bvci 0x0000
+00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 e0 54 32 10
+
+NS UNITDATA MESSAGE to BSS, BVCI 0x0000, msg length 34 (gprs_ns_sendmsg)
+MESSAGE to BSS at 0x01020304:1111, msg length 38
+00 00 00 00 06 0d 88 11 12 13 14 15 16 17 18 0a 82 07 04 1b 86 11 22 33 40 50 60 18 83 00 00 00 20 84 ea d4 77 5a
+
+result (PAGING_PS) = 38
+
+Peers:
+ NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
+ RAID patched (BSS ): 13
+ RAID patched (SGSN): 5
+ APN patched : 1
+ TLLI patched (BSS ): 11
+ TLLI patched (SGSN): 9
+ P-TMSI patched (SGSN): 4
+ Attach Request count : 1
+ TLLI cache size : 1
+ TLLI-Cache: 1
+ TLLI ead4775a -> e0543210, IMSI 12131415161718, AGE 0
PROCESSING LLC_DISCARDED from 0x01020304:1111
00 00 00 00 2c 1f 84 ea d4 77 5a 0f 81 01 04 82 ee e1 25 83 00 00 0c
@@ -2838,12 +2862,12 @@ result (DETACH REQ) = 48
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 14
- RAID patched (SGSN): 5
+ RAID patched (SGSN): 6
APN patched : 1
TLLI patched (BSS ): 13
TLLI patched (SGSN): 10
P-TMSI patched (BSS ): 1
- P-TMSI patched (SGSN): 3
+ P-TMSI patched (SGSN): 4
Attach Request count : 1
TLLI from SGSN unknown : 2
TLLI cache size : 1
@@ -2864,12 +2888,12 @@ result (DETACH ACC) = 71
Peers:
NSEI 4096, BVCI 4098, not blocked, RAI 112-332-16464-96
RAID patched (BSS ): 14
- RAID patched (SGSN): 5
+ RAID patched (SGSN): 6
APN patched : 1
TLLI patched (BSS ): 13
TLLI patched (SGSN): 11
P-TMSI patched (BSS ): 1
- P-TMSI patched (SGSN): 3
+ P-TMSI patched (SGSN): 4
Attach Request count : 1
TLLI from SGSN unknown : 2
TLLI-Cache: 0