From 9ba273d365ac731a9c3ff285821062c346724390 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 23 Apr 2015 09:53:53 -0400 Subject: sgsn: Copy the msisdn to the sgsn_data and use it in PDP activation The MSISDN should be present for "security" reasons in the first activation of a PDP context. Take the encoded MSISDN, store it for future use and then put it into the PDP activation request. The MM Context contains a field for a decoded MSISDN already. As we need to forward the data to the GGSN I want to avoid having to store TON and NPI in another place. Simply store the data in the encoded form. --- openbsc/include/openbsc/gprs_sgsn.h | 3 +++ openbsc/src/gprs/gprs_subscriber.c | 14 ++++++++++++++ openbsc/src/gprs/sgsn_libgtp.c | 12 ++++++++++-- openbsc/tests/sgsn/sgsn_test.c | 9 +++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 2572ead52..baa2d781b 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -302,6 +302,9 @@ struct sgsn_subscriber_data { int auth_triplets_updated; struct llist_head pdp_list; int error_cause; + + uint8_t msisdn[9]; + size_t msisdn_len; }; #define SGSN_ERROR_CAUSE_NONE (-1) diff --git a/openbsc/src/gprs/gprs_subscriber.c b/openbsc/src/gprs/gprs_subscriber.c index 60f223a0b..52e7ba78d 100644 --- a/openbsc/src/gprs/gprs_subscriber.c +++ b/openbsc/src/gprs/gprs_subscriber.c @@ -1,6 +1,7 @@ /* MS subscriber data handling */ /* (C) 2014 by sysmocom s.f.m.c. GmbH + * (C) 2015 by Holger Hans Peter Freyther * * All Rights Reserved * @@ -259,9 +260,22 @@ static struct sgsn_subscriber_pdp_data *gprs_subscr_pdp_data_get_by_id( static void gprs_subscr_gsup_insert_data(struct gsm_subscriber *subscr, struct gprs_gsup_message *gsup_msg) { + struct sgsn_subscriber_data *sdata = subscr->sgsn_data; unsigned idx; int rc; + if (gsup_msg->msisdn_enc) { + if (gsup_msg->msisdn_enc_len > sizeof(sdata->msisdn)) { + LOGP(DGPRS, LOGL_ERROR, "MSISDN too long (%zu)\n", + gsup_msg->msisdn_enc_len); + sdata->msisdn_len = 0; + } else { + memcpy(sdata->msisdn, gsup_msg->msisdn_enc, + gsup_msg->msisdn_enc_len); + sdata->msisdn_len = gsup_msg->msisdn_enc_len; + } + } + if (gsup_msg->pdp_info_compl) { rc = gprs_subscr_pdp_data_clear(subscr); if (rc > 0) diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index 455e8af39..25b30d0fd 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -3,6 +3,7 @@ /* (C) 2010 by Harald Welte * (C) 2010 by On-Waves + * (C) 2015 by Holger Hans Peter Freyther * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -45,6 +46,7 @@ #include #include #include +#include #include #include @@ -153,8 +155,14 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn, /* IMSI, TEID/TEIC, FLLU/FLLC, TID, NSAPI set in pdp_newpdp */ - /* FIXME: MSISDN in BCD format from mmctx */ - //pdp->msisdn.l/.v + /* Put the MSISDN in case we have it */ + if (mmctx->subscr) { + pdp->msisdn.l = mmctx->subscr->sgsn_data->msisdn_len; + if (pdp->msisdn.l > sizeof(pdp->msisdn.v)) + pdp->msisdn.l = sizeof(pdp->msisdn.l); + memcpy(pdp->msisdn.v, mmctx->subscr->sgsn_data->msisdn, + pdp->msisdn.l); + } /* End User Address from GMM requested PDP address */ pdp->eua.l = TLVP_LEN(tp, OSMO_IE_GSM_REQ_PDP_ADDR); diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 197be9da4..d9b162dc2 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -414,9 +414,14 @@ static void test_subscriber_gsup(void) 0x02, 0x01, 0x07 /* GPRS not allowed */ }; +#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 + + static const uint8_t s1_msisdn[] = { MSISDN }; + static const uint8_t update_location_res[] = { 0x06, TEST_GSUP_IMSI1_IE, + 0x08, 0x09, MSISDN, 0x04, 0x00, /* PDP info complete */ 0x05, 0x12, 0x10, 0x01, 0x01, @@ -428,6 +433,8 @@ static void test_subscriber_gsup(void) 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n', }; +#undef MSISDN + static const uint8_t update_location_err[] = { 0x05, TEST_GSUP_IMSI1_IE, @@ -534,6 +541,8 @@ static void test_subscriber_gsup(void) OSMO_ASSERT(last_updated_subscr == s1); OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE); OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE); + OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn)); + OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0); OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list)); pdpd = llist_entry(s1->sgsn_data->pdp_list.next, struct sgsn_subscriber_pdp_data, list); -- cgit v1.2.3