From 2223025e218263af6e1157ef1eeca1686cefe4b9 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 19 Aug 2009 12:53:57 +0200 Subject: [PATCH] [tmsi] Make the tmsi a 4 octet number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tmsi is four octets long, there is no need to make it a string and then jump through hoops to convert it to a number. Keep the database using it as a string to benefit from the NULL handling of the db. Introduce the reserved tmsi which has all bits set to 1 according to GSM 03.03 §2.4 and start checking for it and make sure the db code will never allocate such a tmsi. --- openbsc/include/openbsc/gsm_subscriber.h | 9 ++++++--- openbsc/src/db.c | 24 ++++++++++++++++-------- openbsc/src/gsm_04_08.c | 17 +++++++++-------- openbsc/src/gsm_subscriber.c | 8 +++++--- openbsc/src/gsm_subscriber_base.c | 1 + openbsc/src/paging.c | 4 +--- openbsc/src/vty_interface.c | 4 ++-- openbsc/tests/db/db_test.c | 4 ++-- 8 files changed, 42 insertions(+), 29 deletions(-) diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index aaf261eda..ea70c3aa2 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -7,14 +7,17 @@ #define GSM_IMEI_LENGTH 17 #define GSM_IMSI_LENGTH 17 -#define GSM_TMSI_LENGTH 17 #define GSM_NAME_LENGTH 128 #define GSM_EXTENSION_LENGTH 128 +/* reserved according to GSM 03.03 § 2.4 */ +#define GSM_RESERVED_TMSI 0xFFFFFFFF + #define GSM_MIN_EXTEN 20000 #define GSM_MAX_EXTEN 49999 #define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001 +#define tmsi_from_string(str) strtoul(str, NULL, 10) struct gsm_equipment { long long unsigned int id; @@ -32,7 +35,7 @@ struct gsm_subscriber { struct gsm_network *net; long long unsigned int id; char imsi[GSM_IMSI_LENGTH]; - char tmsi[GSM_TMSI_LENGTH]; + u_int32_t tmsi; u_int16_t lac; char name[GSM_NAME_LENGTH]; char extension[GSM_EXTENSION_LENGTH]; @@ -70,7 +73,7 @@ enum gsm_subscriber_update_reason { struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr); struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr); struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net, - const char *tmsi); + u_int32_t tmsi); struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net, const char *imsi); struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net, diff --git a/openbsc/src/db.c b/openbsc/src/db.c index 45c55aff9..270d4d90b 100644 --- a/openbsc/src/db.c +++ b/openbsc/src/db.c @@ -376,7 +376,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, string = dbi_result_get_string(result, "tmsi"); if (string) - strncpy(subscr->tmsi, string, GSM_TMSI_LENGTH); + subscr->tmsi = tmsi_from_string(string); string = dbi_result_get_string(result, "name"); if (string) @@ -388,7 +388,7 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, subscr->lac = dbi_result_get_uint(result, "lac"); subscr->authorized = dbi_result_get_uint(result, "authorized"); - printf("DB: Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %s, EXTEN '%s', LAC %hu, AUTH %u\n", + printf("DB: Found Subscriber: ID %llu, IMSI %s, NAME '%s', TMSI %u, EXTEN '%s', LAC %hu, AUTH %u\n", subscr->id, subscr->imsi, subscr->name, subscr->tmsi, subscr->extension, subscr->lac, subscr->authorized); dbi_result_free(result); @@ -400,12 +400,15 @@ struct gsm_subscriber *db_get_subscriber(struct gsm_network *net, int db_sync_subscriber(struct gsm_subscriber* subscriber) { dbi_result result; + char tmsi[14]; char *q_tmsi; - if (subscriber->tmsi[0]) + + if (subscriber->tmsi != GSM_RESERVED_TMSI) { + sprintf(tmsi, "%u", subscriber->tmsi); dbi_conn_quote_string_copy(conn, - subscriber->tmsi, + tmsi, &q_tmsi); - else + } else q_tmsi = strdup("NULL"); result = dbi_conn_queryf(conn, "UPDATE Subscriber " @@ -475,10 +478,15 @@ int db_sync_equipment(struct gsm_equipment *equip) int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber) { dbi_result result=NULL; + char tmsi[14]; char* tmsi_quoted; for (;;) { - sprintf(subscriber->tmsi, "%i", rand()); - dbi_conn_quote_string_copy(conn, subscriber->tmsi, &tmsi_quoted); + subscriber->tmsi = rand(); + if (subscriber->tmsi == GSM_RESERVED_TMSI) + continue; + + sprintf(tmsi, "%u", subscriber->tmsi); + dbi_conn_quote_string_copy(conn, tmsi, &tmsi_quoted); result = dbi_conn_queryf(conn, "SELECT * FROM Subscriber " "WHERE tmsi = %s ", @@ -495,7 +503,7 @@ int db_subscriber_alloc_tmsi(struct gsm_subscriber* subscriber) { } if (!dbi_result_next_row(result)) { dbi_result_free(result); - printf("DB: Allocated TMSI %s for IMSI %s.\n", subscriber->tmsi, subscriber->imsi); + printf("DB: Allocated TMSI %u for IMSI %s.\n", subscriber->tmsi, subscriber->imsi); return db_sync_subscriber(subscriber); } dbi_result_free(result); diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index d6fe09fa2..196fdca11 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -291,15 +291,12 @@ static void allocate_loc_updating_req(struct gsm_lchan *lchan) static int gsm0408_authorize(struct gsm_lchan *lchan, struct msgb *msg) { - u_int32_t tmsi; - if (authorize_subscriber(lchan->loc_operation, lchan->subscr)) { int rc; db_subscriber_alloc_tmsi(lchan->subscr); - tmsi = strtoul(lchan->subscr->tmsi, NULL, 10); release_loc_updating_req(lchan); - rc = gsm0408_loc_upd_acc(msg->lchan, tmsi); + rc = gsm0408_loc_upd_acc(msg->lchan, lchan->subscr->tmsi); /* call subscr_update after putting the loc_upd_acc * in the transmit queue, since S_SUBSCR_ATTACHED might * trigger further action like SMS delivery */ @@ -1054,7 +1051,8 @@ static int mm_rx_loc_upd_req(struct msgb *msg) lchan->loc_operation->waiting_for_imei = 1; /* look up the subscriber based on TMSI, request IMSI if it fails */ - subscr = subscr_get_by_tmsi(bts->network, mi_string); + subscr = subscr_get_by_tmsi(bts->network, + tmsi_from_string(mi_string)); if (!subscr) { /* send IDENTITY REQUEST message to get IMSI */ rc = mm_tx_identity_req(lchan, GSM_MI_TYPE_IMSI); @@ -1352,7 +1350,8 @@ static int gsm48_rx_mm_serv_req(struct msgb *msg) if (is_siemens_bts(bts)) send_siemens_mrpci(msg->lchan, classmark2-1); - subscr = subscr_get_by_tmsi(bts->network, mi_string); + subscr = subscr_get_by_tmsi(bts->network, + tmsi_from_string(mi_string)); /* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */ if (!subscr) @@ -1389,7 +1388,8 @@ static int gsm48_rx_mm_imsi_detach_ind(struct msgb *msg) switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(bts->network, mi_string); + subscr = subscr_get_by_tmsi(bts->network, + tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: subscr = subscr_get_by_imsi(bts->network, mi_string); @@ -1495,7 +1495,8 @@ static int gsm48_rr_rx_pag_resp(struct msgb *msg) switch (mi_type) { case GSM_MI_TYPE_TMSI: - subscr = subscr_get_by_tmsi(bts->network, mi_string); + subscr = subscr_get_by_tmsi(bts->network, + tmsi_from_string(mi_string)); break; case GSM_MI_TYPE_IMSI: subscr = subscr_get_by_imsi(bts->network, mi_string); diff --git a/openbsc/src/gsm_subscriber.c b/openbsc/src/gsm_subscriber.c index 84e14a0ea..a4e35c7b1 100644 --- a/openbsc/src/gsm_subscriber.c +++ b/openbsc/src/gsm_subscriber.c @@ -35,17 +35,19 @@ extern struct llist_head *subscr_bsc_active_subscriber(void); struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_network *net, - const char *tmsi) + u_int32_t tmsi) { + char tmsi_string[14]; struct gsm_subscriber *subscr; /* we might have a record in memory already */ llist_for_each_entry(subscr, subscr_bsc_active_subscriber(), entry) { - if (strcmp(subscr->tmsi, tmsi) == 0) + if (tmsi == subscr->tmsi) return subscr_get(subscr); } - return db_get_subscriber(net, GSM_SUBSCRIBER_TMSI, tmsi); + sprintf(tmsi_string, "%u", tmsi); + return db_get_subscriber(net, GSM_SUBSCRIBER_TMSI, tmsi_string); } struct gsm_subscriber *subscr_get_by_imsi(struct gsm_network *net, diff --git a/openbsc/src/gsm_subscriber_base.c b/openbsc/src/gsm_subscriber_base.c index d6a179b5c..345544d49 100644 --- a/openbsc/src/gsm_subscriber_base.c +++ b/openbsc/src/gsm_subscriber_base.c @@ -112,6 +112,7 @@ struct gsm_subscriber *subscr_alloc(void) memset(s, 0, sizeof(*s)); llist_add_tail(&s->entry, &active_subscribers); s->use_count = 1; + s->tmsi = GSM_RESERVED_TMSI; INIT_LLIST_HEAD(&s->requests); diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c index fd0611a14..b8552133e 100644 --- a/openbsc/src/paging.c +++ b/openbsc/src/paging.c @@ -90,7 +90,6 @@ static void paging_remove_request(struct gsm_bts_paging_state *paging_bts, static void page_ms(struct gsm_paging_request *request) { u_int8_t mi[128]; - unsigned long int tmsi; unsigned int mi_len; unsigned int page_group; @@ -98,8 +97,7 @@ static void page_ms(struct gsm_paging_request *request) request->subscr->imsi); page_group = calculate_group(request->bts, request->subscr); - tmsi = strtoul(request->subscr->tmsi, NULL, 10); - mi_len = gsm48_generate_mid_from_tmsi(mi, tmsi); + mi_len = gsm48_generate_mid_from_tmsi(mi, request->subscr->tmsi); rsl_paging_cmd(request->bts, page_group, mi_len, mi, request->chan_type); } diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index f75cfaf8a..00decd2b5 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -427,8 +427,8 @@ void subscr_dump_vty(struct vty *vty, struct gsm_subscriber *subscr) VTY_NEWLINE); if (subscr->imsi) vty_out(vty, " IMSI: %s%s", subscr->imsi, VTY_NEWLINE); - if (subscr->tmsi) - vty_out(vty, " TMSI: %08X%s", atoi(subscr->tmsi), + if (subscr->tmsi != GSM_RESERVED_TMSI) + vty_out(vty, " TMSI: %08X%s", subscr->tmsi, VTY_NEWLINE); vty_out(vty, " Use count: %u%s", subscr->use_count, VTY_NEWLINE); } diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c index a248e6025..f168acb64 100644 --- a/openbsc/tests/db/db_test.c +++ b/openbsc/tests/db/db_test.c @@ -38,8 +38,8 @@ if (strcmp(original->imsi, copy->imsi) != 0) \ fprintf(stderr, "IMSIs do not match in %s:%d '%s' '%s'\n", \ __FUNCTION__, __LINE__, original->imsi, copy->imsi); \ - if (strcmp(original->tmsi, copy->tmsi) != 0) \ - fprintf(stderr, "TMSIs do not match in %s:%d '%s' '%s'\n", \ + if (original->tmsi != copy->tmsi) \ + fprintf(stderr, "TMSIs do not match in %s:%d '%u' '%u'\n", \ __FUNCTION__, __LINE__, original->tmsi, copy->tmsi); \ if (strcmp(original->name, copy->name) != 0) \ fprintf(stderr, "names do not match in %s:%d '%s' '%s'\n", \