From: Holger Hans Peter Freyther <[email protected]>

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.
---
 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 2572ead..baa2d78 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 60f223a..52e7ba7 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 455e8af..25b30d0 100644
--- a/openbsc/src/gprs/sgsn_libgtp.c
+++ b/openbsc/src/gprs/sgsn_libgtp.c
@@ -3,6 +3,7 @@

 /* (C) 2010 by Harald Welte <[email protected]>
  * (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 <openbsc/gprs_llc.h>
 #include <openbsc/gprs_sgsn.h>
 #include <openbsc/gprs_gmm.h>
+#include <openbsc/gsm_subscriber.h>

 #include <gtp.h>
 #include <pdp.h>
@@ -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 197be9d..f6f8cd6 100644
--- a/openbsc/tests/sgsn/sgsn_test.c
+++ b/openbsc/tests/sgsn/sgsn_test.c
@@ -414,6 +414,10 @@ 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,
@@ -426,8 +430,11 @@ static void test_subscriber_gsup(void)
                        0x10, 0x01, 0x02,
                        0x11, 0x02, 0xf1, 0x21, /* IPv4 */
                        0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
+               0x13, 0x09, MSISDN,
        };

+#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);
-- 
2.3.5

Reply via email to