summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-07-13 20:33:08 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-08-01 23:49:16 +0000
commit666e36aea9ddb9ffc6fd1c7620943449be345355 (patch)
tree6072ab06724fb6d474f889a58fcb85e654a0cdb1
parent5f8a0c5c7031c15beac4532fcde7450b9c0f84fe (diff)
nitb: Add a mode to not use TMSI for normal operation
In case foreign simcards are used we can not do authentication and ciphering. In case a TMSI is re-used too early and we do page using TMSI we can't know which of the two MS is responding to us. We could change the "secure channel" routine to ask for the IMSI and only then stop the paging. As we don't have ciphering there is not much use in using the TMSI. Add a mode "no assign-tmsi" that will not assign the TMSI during LU. Now CM Service Request and Paging Response will work using the IMSI. There can't be a clash with that. [ciaby fixed the vty write to use the right name]
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c94
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c22
3 files changed, 88 insertions, 31 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 6f7c8dd..90f3c80 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -281,6 +281,9 @@ struct gsm_network {
struct gsm_subscriber_group *subscr_group;
struct gsm_sms_queue *sms_queue;
+ /* nitb related control */
+ int avoid_tmsi;
+
/* control interface */
struct ctrl_handle *ctrl;
};
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index e380d94..02ffe58 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -67,7 +67,7 @@
void *tall_locop_ctx;
void *tall_authciphop_ctx;
-int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi);
+static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn);
static int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
uint8_t pdisc, uint8_t msg_type);
static void schedule_reject(struct gsm_subscriber_connection *conn);
@@ -294,6 +294,42 @@ static void allocate_loc_updating_req(struct gsm_subscriber_connection *conn)
struct gsm_loc_updating_operation);
}
+static int finish_lu(struct gsm_subscriber_connection *conn)
+{
+ int rc = 0;
+ int avoid_tmsi = conn->bts->network->avoid_tmsi;
+
+ /* We're all good */
+ if (avoid_tmsi) {
+ conn->subscr->tmsi = GSM_RESERVED_TMSI;
+ db_sync_subscriber(conn->subscr);
+ } else {
+ db_subscriber_alloc_tmsi(conn->subscr);
+ }
+
+ rc = gsm0408_loc_upd_acc(conn);
+ if (conn->bts->network->send_mm_info) {
+ /* send MM INFO with network name */
+ rc = gsm48_tx_mm_info(conn);
+ }
+
+ /* call subscr_update after putting the loc_upd_acc
+ * in the transmit queue, since S_SUBSCR_ATTACHED might
+ * trigger further action like SMS delivery */
+ subscr_update(conn->subscr, conn->bts,
+ GSM_SUBSCRIBER_UPDATE_ATTACHED);
+
+ /*
+ * The gsm0408_loc_upd_acc sends a MI with the TMSI. The
+ * MS needs to respond with a TMSI REALLOCATION COMPLETE
+ * (even if the TMSI is the same).
+ */
+ if (avoid_tmsi)
+ release_loc_updating_req(conn, 1);
+
+ return rc;
+}
+
static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event,
struct msgb *msg, void *data, void *param)
{
@@ -312,25 +348,7 @@ static int _gsm0408_authorize_sec_cb(unsigned int hooknum, unsigned int event,
case GSM_SECURITY_NOAVAIL:
case GSM_SECURITY_SUCCEEDED:
- /* We're all good */
- db_subscriber_alloc_tmsi(conn->subscr);
- rc = gsm0408_loc_upd_acc(conn, conn->subscr->tmsi);
- if (conn->bts->network->send_mm_info) {
- /* send MM INFO with network name */
- rc = gsm48_tx_mm_info(conn);
- }
-
- /* call subscr_update after putting the loc_upd_acc
- * in the transmit queue, since S_SUBSCR_ATTACHED might
- * trigger further action like SMS delivery */
- subscr_update(conn->subscr, conn->bts,
- GSM_SUBSCRIBER_UPDATE_ATTACHED);
-
- /*
- * The gsm0408_loc_upd_acc sends a MI with the TMSI. The
- * MS needs to respond with a TMSI REALLOCATION COMPLETE
- * (even if the TMSI is the same).
- */
+ rc = finish_lu(conn);
break;
default:
@@ -434,7 +452,7 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
}
/* Chapter 9.2.13 : Send LOCATION UPDATE ACCEPT */
-int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi)
+static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn)
{
struct gsm_bts *bts = conn->bts;
struct msgb *msg = gsm48_msgb_alloc();
@@ -452,8 +470,16 @@ int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn, uint32_t tmsi)
gsm48_generate_lai(lai, bts->network->country_code,
bts->network->network_code, bts->location_area_code);
- mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
- gsm48_generate_mid_from_tmsi(mid, tmsi);
+ if (conn->subscr->tmsi == GSM_RESERVED_TMSI) {
+ uint8_t mi[10];
+ int len;
+ len = gsm48_generate_mid_from_imsi(mi, conn->subscr->imsi);
+ mid = msgb_put(msg, len);
+ memcpy(mid, mi, len);
+ } else {
+ mid = msgb_put(msg, GSM48_MID_TMSI_LEN);
+ gsm48_generate_mid_from_tmsi(mid, conn->subscr->tmsi);
+ }
DEBUGP(DMM, "-> LOCATION UPDATE ACCEPT\n");
@@ -946,24 +972,30 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
GSM48_REJECT_INCORRECT_MESSAGE);
}
+ gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
mi_type = mi[0] & GSM_MI_TYPE_MASK;
- if (mi_type != GSM_MI_TYPE_TMSI) {
- DEBUGPC(DMM, "mi_type is not TMSI: %d\n", mi_type);
+
+ if (mi_type == GSM_MI_TYPE_IMSI) {
+ DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
+ req->cm_service_type, mi_type, mi_string);
+ subscr = subscr_get_by_imsi(bts->network->subscr_group,
+ mi_string);
+ } else if (mi_type == GSM_MI_TYPE_TMSI) {
+ DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
+ req->cm_service_type, mi_type, mi_string);
+ subscr = subscr_get_by_tmsi(bts->network->subscr_group,
+ tmsi_from_string(mi_string));
+ } else {
+ DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
return gsm48_tx_mm_serv_rej(conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
- gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
- DEBUGPC(DMM, "serv_type=0x%02x mi_type=0x%02x M(%s)\n",
- req->cm_service_type, mi_type, mi_string);
-
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
- tmsi_from_string(mi_string));
/* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
if (!subscr)
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index 6cf51a3..1515aea 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -1037,12 +1037,32 @@ DEFUN(cfg_nitb_no_subscr_create, cfg_nitb_no_subscr_create_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_nitb_assign_tmsi, cfg_nitb_assign_tmsi_cmd,
+ "assign-tmsi",
+ "Assign TMSI during Location Updating.\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ gsmnet->avoid_tmsi = 0;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_nitb_no_assign_tmsi, cfg_nitb_no_assign_tmsi_cmd,
+ "no assign-tmsi",
+ NO_STR "Assign TMSI during Location Updating.\n")
+{
+ struct gsm_network *gsmnet = gsmnet_from_vty(vty);
+ gsmnet->avoid_tmsi = 1;
+ return CMD_SUCCESS;
+}
+
static int config_write_nitb(struct vty *vty)
{
struct gsm_network *gsmnet = gsmnet_from_vty(vty);
vty_out(vty, "nitb%s", VTY_NEWLINE);
vty_out(vty, " %ssubscriber-create-on-demand%s",
gsmnet->create_subscriber ? "" : "no ", VTY_NEWLINE);
+ vty_out(vty, " %sassign-tmsi%s",
+ gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE);
return CMD_SUCCESS;
}
@@ -1096,6 +1116,8 @@ int bsc_vty_init_extra(void)
install_node(&nitb_node, config_write_nitb);
install_element(NITB_NODE, &cfg_nitb_subscr_create_cmd);
install_element(NITB_NODE, &cfg_nitb_no_subscr_create_cmd);
+ install_element(NITB_NODE, &cfg_nitb_assign_tmsi_cmd);
+ install_element(NITB_NODE, &cfg_nitb_no_assign_tmsi_cmd);
return 0;
}