diff options
-rw-r--r-- | openbsc/include/openbsc/gprs_gb_parse.h | 2 | ||||
-rw-r--r-- | openbsc/src/gprs/gb_proxy_patch.c | 13 | ||||
-rw-r--r-- | openbsc/src/gprs/gb_proxy_tlli.c | 28 | ||||
-rw-r--r-- | openbsc/src/gprs/gprs_gb_parse.c | 10 | ||||
-rw-r--r-- | openbsc/tests/gbproxy/gbproxy_test.c | 57 | ||||
-rw-r--r-- | openbsc/tests/gbproxy/gbproxy_test.ok | 32 |
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 |