gbproxy: Refactor IMSI matching

The current implementation makes it difficult to add further match
expressions.

This patch adds a new struct gbproxy_match that contains the fields
needed for each match expression. The matches (config) and the
results (link_info) are stored in arrays. All related functions are
updated to use them. The old fields in the config structure are
removed.

Sponsored-by: On-Waves ehf
This commit is contained in:
Jacob Erlbeck 2014-09-25 11:17:31 +02:00 committed by Holger Hans Peter Freyther
parent 55ec2bf97f
commit 9a83d7af55
6 changed files with 131 additions and 95 deletions

View File

@ -59,6 +59,17 @@ enum gbproxy_keep_mode {
GBPROX_KEEP_ALWAYS,
};
enum gbproxy_match_id {
GBPROX_MATCH_PATCHING,
GBPROX_MATCH_LAST
};
struct gbproxy_match {
int enable;
char *re_str;
regex_t re_comp;
};
struct gbproxy_config {
/* parsed from config file */
uint16_t nsip_sgsn_nsei;
@ -77,7 +88,6 @@ struct gbproxy_config {
int core_mcc;
uint8_t* core_apn;
size_t core_apn_size;
char * match_re;
int tlli_max_age;
int tlli_max_len;
@ -89,8 +99,7 @@ struct gbproxy_config {
enum gbproxy_keep_mode keep_link_infos;
/* IMSI checking/matching */
int check_imsi;
regex_t imsi_re_comp;
struct gbproxy_match matches[GBPROX_MATCH_LAST];
/* Used to generate identifiers */
unsigned bss_ptmsi_state;
@ -154,8 +163,7 @@ struct gbproxy_link_info {
int is_deregistered;
int imsi_matches;
int is_matching[GBPROX_MATCH_LAST];
};
@ -217,7 +225,8 @@ struct gbproxy_link_info *gbproxy_link_info_by_ptmsi(
uint32_t ptmsi);
int gbproxy_imsi_matches(
struct gbproxy_peer *peer,
struct gbproxy_config *cfg,
enum gbproxy_match_id match_id,
struct gbproxy_link_info *link_info);
uint32_t gbproxy_map_tlli(
uint32_t other_tlli, struct gbproxy_link_info *link_info, int to_bss);
@ -229,7 +238,7 @@ uint32_t gbproxy_make_sgsn_tlli(
uint32_t bss_tlli);
void gbproxy_reset_link(struct gbproxy_link_info *link_info);
int gbproxy_check_imsi(
struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len);
struct gbproxy_match *match, const uint8_t *imsi, size_t imsi_len);
/* Message patching */
void gbproxy_patch_bssgp(
@ -243,10 +252,8 @@ int gbproxy_patch_llc(
int *len_change, struct gprs_gb_parse_context *parse_ctx);
int gbproxy_set_patch_filter(
struct gbproxy_config *cfg, const char *filter, const char **err_msg);
void gbproxy_clear_patch_filter(struct gbproxy_config *cfg);
int gbproxy_check_imsi(
struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len);
struct gbproxy_match *match, const char *filter, const char **err_msg);
void gbproxy_clear_patch_filter(struct gbproxy_match *match);
/* Peer handling */
struct gbproxy_peer *gbproxy_peer_by_bvci(

View File

@ -584,7 +584,8 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
if (link_info && cfg->route_to_sgsn2) {
if (cfg->acquire_imsi && link_info->imsi_len == 0)
sgsn_nsei = 0xffff;
else if (gbproxy_imsi_matches(peer, link_info))
else if (gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING,
link_info))
sgsn_nsei = cfg->nsip_sgsn2_nsei;
}
@ -1346,10 +1347,12 @@ void gbprox_reset(struct gbproxy_config *cfg)
int gbproxy_init_config(struct gbproxy_config *cfg)
{
struct timespec tp;
INIT_LLIST_HEAD(&cfg->bts_peers);
cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0);
clock_gettime(CLOCK_REALTIME, &tp);
cfg->bss_ptmsi_state = tp.tv_sec + tp.tv_nsec;
cfg->sgsn_tlli_state = tp.tv_sec - tp.tv_nsec;
return 0;
}

View File

@ -24,6 +24,7 @@
#include <openbsc/gprs_gb_parse.h>
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
@ -198,6 +199,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;
int have_patched = 0;
int fcs;
struct gbproxy_config *cfg = peer->cfg;
if (parse_ctx->ptmsi_enc && link_info &&
!parse_ctx->old_raid_is_foreign && peer->cfg->patch_ptmsi) {
@ -216,7 +218,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
}
}
if (parse_ctx->new_ptmsi_enc && link_info && peer->cfg->patch_ptmsi) {
if (parse_ctx->new_ptmsi_enc && link_info && cfg->patch_ptmsi) {
uint32_t ptmsi;
if (parse_ctx->to_bss)
ptmsi = link_info->tlli.ptmsi;
@ -243,9 +245,10 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
}
if (parse_ctx->apn_ie &&
peer->cfg->core_apn &&
cfg->core_apn &&
!parse_ctx->to_bss &&
gbproxy_imsi_matches(peer, link_info) && peer->cfg->core_apn) {
gbproxy_imsi_matches(cfg, GBPROX_MATCH_PATCHING, link_info) &&
cfg->core_apn) {
size_t new_len;
gbproxy_patch_apn_ie(msg,
parse_ctx->apn_ie, parse_ctx->apn_ie_len,
@ -371,35 +374,38 @@ patch_error:
err_info);
}
void gbproxy_clear_patch_filter(struct gbproxy_config *cfg)
void gbproxy_clear_patch_filter(struct gbproxy_match *match)
{
if (cfg->check_imsi) {
regfree(&cfg->imsi_re_comp);
cfg->check_imsi = 0;
if (match->enable) {
regfree(&match->re_comp);
match->enable = 0;
}
talloc_free(match->re_str);
match->re_str = NULL;
}
int gbproxy_set_patch_filter(struct gbproxy_config *cfg, const char *filter,
int gbproxy_set_patch_filter(struct gbproxy_match *match, const char *filter,
const char **err_msg)
{
static char err_buf[300];
int rc;
gbproxy_clear_patch_filter(cfg);
gbproxy_clear_patch_filter(match);
if (!filter)
return 0;
rc = regcomp(&cfg->imsi_re_comp, filter,
rc = regcomp(&match->re_comp, filter,
REG_EXTENDED | REG_NOSUB | REG_ICASE);
if (rc == 0) {
cfg->check_imsi = 1;
match->enable = 1;
match->re_str = talloc_strdup(tall_bsc_ctx, filter);
return 0;
}
if (err_msg) {
regerror(rc, &cfg->imsi_re_comp,
regerror(rc, &match->re_comp,
err_buf, sizeof(err_buf));
*err_msg = err_buf;
}
@ -407,13 +413,13 @@ int gbproxy_set_patch_filter(struct gbproxy_config *cfg, const char *filter,
return -1;
}
int gbproxy_check_imsi(struct gbproxy_peer *peer,
int gbproxy_check_imsi(struct gbproxy_match *match,
const uint8_t *imsi, size_t imsi_len)
{
char mi_buf[200];
int rc;
if (!peer->cfg->check_imsi)
if (!match->enable)
return 1;
rc = gprs_is_mi_imsi(imsi, imsi_len);
@ -427,11 +433,11 @@ int gbproxy_check_imsi(struct gbproxy_peer *peer,
LOGP(DGPRS, LOGL_DEBUG, "Checking IMSI '%s' (%d)\n", mi_buf, rc);
rc = regexec(&peer->cfg->imsi_re_comp, mi_buf, 0, NULL, 0);
rc = regexec(&match->re_comp, mi_buf, 0, NULL, 0);
if (rc == REG_NOMATCH) {
LOGP(DGPRS, LOGL_INFO,
"IMSI '%s' doesn't match pattern '%s'\n",
mi_buf, peer->cfg->match_re);
mi_buf, match->re_str);
return 0;
}

View File

@ -374,13 +374,18 @@ static void gbproxy_unregister_link_info(struct gbproxy_peer *peer,
return;
}
int gbproxy_imsi_matches(struct gbproxy_peer *peer,
struct gbproxy_link_info *link_info)
int gbproxy_imsi_matches(struct gbproxy_config *cfg,
enum gbproxy_match_id match_id,
struct gbproxy_link_info *link_info)
{
if (!peer->cfg->check_imsi)
struct gbproxy_match *match;
OSMO_ASSERT(match_id >= 0 && match_id < ARRAY_SIZE(cfg->matches));
match = &cfg->matches[match_id];
if (!match->enable)
return 1;
return link_info != NULL && link_info->imsi_matches;
return link_info != NULL && link_info->is_matching[match_id];
}
void gbproxy_assign_imsi(struct gbproxy_peer *peer,
@ -389,6 +394,7 @@ void gbproxy_assign_imsi(struct gbproxy_peer *peer,
{
int imsi_matches;
struct gbproxy_link_info *other_link_info;
enum gbproxy_match_id match_id;
/* Make sure that there is a second entry with the same IMSI */
other_link_info = gbproxy_link_info_by_imsi(
@ -410,10 +416,16 @@ void gbproxy_assign_imsi(struct gbproxy_peer *peer,
parse_ctx->imsi, parse_ctx->imsi_len);
/* Check, whether the IMSI matches */
imsi_matches = gbproxy_check_imsi(peer, parse_ctx->imsi,
parse_ctx->imsi_len);
if (imsi_matches >= 0)
link_info->imsi_matches = imsi_matches;
OSMO_ASSERT(ARRAY_SIZE(link_info->is_matching) ==
ARRAY_SIZE(peer->cfg->matches));
for (match_id = 0; match_id < ARRAY_SIZE(link_info->is_matching);
++match_id) {
imsi_matches = gbproxy_check_imsi(
&peer->cfg->matches[match_id],
parse_ctx->imsi, parse_ctx->imsi_len);
if (imsi_matches >= 0)
link_info->is_matching[match_id] = imsi_matches;
}
}
static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a,

View File

@ -75,6 +75,8 @@ static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
static int config_write_gbproxy(struct vty *vty)
{
enum gbproxy_match_id match_id;
vty_out(vty, "gbproxy%s", VTY_NEWLINE);
vty_out(vty, " sgsn nsei %u%s", g_cfg->nsip_sgsn_nsei,
@ -87,9 +89,12 @@ static int config_write_gbproxy(struct vty *vty)
vty_out(vty, " core-mobile-network-code %d%s",
g_cfg->core_mnc, VTY_NEWLINE);
if (g_cfg->match_re)
vty_out(vty, " match-imsi %s%s",
g_cfg->match_re, VTY_NEWLINE);
for (match_id = 0; match_id < ARRAY_SIZE(g_cfg->matches); ++match_id) {
struct gbproxy_match *match = &g_cfg->matches[match_id];
if (match->re_str)
vty_out(vty, " match-imsi %s%s",
match->re_str, VTY_NEWLINE);
}
if (g_cfg->core_apn != NULL) {
if (g_cfg->core_apn_size > 0) {
@ -194,15 +199,13 @@ DEFUN(cfg_gbproxy_match_imsi,
{
const char *filter = argv[0];
const char *err_msg = NULL;
struct gbproxy_match *match = &g_cfg->matches[GBPROX_MATCH_PATCHING];
if (gbproxy_set_patch_filter(g_cfg, filter, &err_msg) != 0) {
if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {
vty_out(vty, "Match expression invalid: %s%s",
err_msg, VTY_NEWLINE);
return CMD_WARNING;
}
talloc_free(g_cfg->match_re);
/* TODO: replace NULL */
g_cfg->match_re = talloc_strdup(NULL, filter);
g_cfg->acquire_imsi = 1;
@ -214,10 +217,9 @@ DEFUN(cfg_gbproxy_no_match_imsi,
"no match-imsi",
NO_STR GBPROXY_MATCH_IMSI_STR)
{
gbproxy_clear_patch_filter(g_cfg);
struct gbproxy_match *match = &g_cfg->matches[GBPROX_MATCH_PATCHING];
talloc_free(g_cfg->match_re);
g_cfg->match_re = NULL;
gbproxy_clear_patch_filter(match);
g_cfg->acquire_imsi = 0;

View File

@ -129,6 +129,7 @@ static int dump_peers(FILE *stream, int indent, time_t now,
time_t age = now ? now - link_info->timestamp : 0;
int stored_msgs = 0;
struct llist_head *iter;
enum gbproxy_match_id match_id;
llist_for_each(iter, &link_info->stored_msgs)
stored_msgs++;
@ -157,8 +158,14 @@ static int dump_peers(FILE *stream, int indent, time_t now,
if (stored_msgs)
fprintf(stream, ", STORED %d", stored_msgs);
if (cfg->check_imsi && link_info->imsi_matches)
fprintf(stream, ", IMSI matches");
for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches);
++match_id) {
if (cfg->matches[match_id].enable &&
link_info->is_matching[match_id]) {
fprintf(stream, ", IMSI matches");
break;
}
}
if (link_info->imsi_acq_pending)
fprintf(stream, ", IMSI acquisition in progress");
@ -1546,6 +1553,7 @@ static void test_gbproxy_ra_patching()
const uint32_t foreign_tlli = 0xbbc54679;
const uint32_t foreign_tlli2 = 0xbb00beef;
const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
const char *patch_re = "^9898|^121314";
struct gbproxy_link_info *link_info;
struct gbproxy_peer *peer;
LLIST_HEAD(rcv_list);
@ -1565,10 +1573,10 @@ static void test_gbproxy_ra_patching()
configure_sgsn_peer(&sgsn_peer);
configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
patch_re, &err_msg) != 0) {
fprintf(stderr, "Failed to compile RE '%s': %s\n",
gbcfg.match_re, err_msg);
patch_re, err_msg);
exit(1);
}
@ -2777,7 +2785,8 @@ static void test_gbproxy_secondary_sgsn()
gbcfg.route_to_sgsn2 = 1;
gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
filter_re, &err_msg) != 0) {
fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
err_msg);
OSMO_ASSERT(err_msg == NULL);
@ -3946,10 +3955,12 @@ struct gbproxy_link_info *register_tlli(
struct gbproxy_link_info *link_info;
int imsi_matches = -1;
int tlli_already_known = 0;
struct gbproxy_config *cfg = peer->cfg;
/* Check, whether the IMSI matches */
if (gprs_is_mi_imsi(imsi, imsi_len)) {
imsi_matches = gbproxy_check_imsi(peer, imsi, imsi_len);
imsi_matches = gbproxy_check_imsi(
&cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
if (imsi_matches < 0)
return NULL;
}
@ -3985,7 +3996,7 @@ struct gbproxy_link_info *register_tlli(
gbproxy_update_link_info(link_info, imsi, imsi_len);
if (imsi_matches >= 0)
link_info->imsi_matches = imsi_matches;
link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
return link_info;
}
@ -4008,7 +4019,8 @@ static void test_gbproxy_tlli_expire(void)
gbproxy_init_config(&cfg);
if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
filter_re, &err_msg) != 0) {
fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
err_msg);
OSMO_ASSERT(err_msg == NULL);
@ -4219,8 +4231,6 @@ static void test_gbproxy_tlli_expire(void)
static void test_gbproxy_imsi_matching(void)
{
struct gbproxy_config cfg = {0};
struct gbproxy_peer *peer;
const char *err_msg = NULL;
const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
@ -4233,65 +4243,61 @@ static void test_gbproxy_imsi_matching(void)
const char *filter_re2 = "^1234";
const char *filter_re3 = "^4321";
const char *filter_re4_bad = "^12[";
struct gbproxy_match match = {0,};
printf("=== Test IMSI/TMSI matching ===\n\n");
gbproxy_init_config(&cfg);
OSMO_ASSERT(cfg.check_imsi == 0);
OSMO_ASSERT(match.enable == 0);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
OSMO_ASSERT(match.enable == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
OSMO_ASSERT(match.enable == 1);
err_msg = NULL;
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
OSMO_ASSERT(err_msg != NULL);
OSMO_ASSERT(cfg.check_imsi == 0);
OSMO_ASSERT(match.enable == 0);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
OSMO_ASSERT(match.enable == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 0);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
OSMO_ASSERT(match.enable == 0);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
OSMO_ASSERT(match.enable == 1);
gbproxy_clear_patch_filter(&cfg);
OSMO_ASSERT(cfg.check_imsi == 0);
gbproxy_clear_patch_filter(&match);
OSMO_ASSERT(match.enable == 0);
peer = gbproxy_peer_alloc(&cfg, 20);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
OSMO_ASSERT(match.enable == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
/* imsi3_bad contains 0xE and 0xF digits, but the conversion function
* doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
* case. */
OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
OSMO_ASSERT(cfg.check_imsi == 1);
OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
OSMO_ASSERT(match.enable == 1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
/* TODO: Check correct length but wrong type with is_mi_tmsi */
gbproxy_peer_free(peer);
}
static struct log_info_cat gprs_categories[] = {