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-07-14 09:34:33 +0200
commit32ee7f9840c373bd51761cc5af6a39b261f2e1e1 (patch)
tree91d37e95b75a6a294d37e78c422d3a0be97082a1
parent0c0b30022534e330029a21f8d3b8ed42e7d1c953 (diff)
nitb: Add a mode to not use TMSI for normal operationzecke/features/no-tmsi
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.
-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 6f7c8dd2a..90f3c800d 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 e380d948b..02ffe580b 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 6cf51a33f..3c33ffcd7 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, " %suse-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;
}