From 20102b0c8204c8340aae628ef5a36bbf9e4dedc8 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 18 May 2011 18:41:14 +0200 Subject: [PATCH] nat: Refactor the number patching code into a new method Separate the code to patch the code and the code to find a new number based on the old number. This will allow to add multiple targets for number changing. --- openbsc/src/osmo-bsc_nat/bsc_nat_utils.c | 101 +++++++++++++---------- 1 file changed, 56 insertions(+), 45 deletions(-) diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c index dd32c752a..4696bb03a 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c @@ -798,6 +798,61 @@ int bsc_write_cb(struct osmo_fd *bfd, struct msgb *msg) return rc; } +static char *rewrite_non_international(struct bsc_nat *nat, void *ctx, const char *imsi, + struct gsm_mncc_number *called) +{ + struct osmo_config_entry *entry; + char *new_number = NULL; + + if (!nat->num_rewr) + return NULL; + + if (called->plan != 1) + return NULL; + if (called->type == 1) + return NULL; + if (strncmp(called->number, "00", 2) == 0) + return NULL; + + /* need to find a replacement and then fix it */ + llist_for_each_entry(entry, &nat->num_rewr->entry, list) { + regex_t reg; + regmatch_t matches[2]; + + if (entry->mcc[0] != '*' && strncmp(entry->mcc, imsi, 3) != 0) + continue; + if (entry->mnc[0] != '*' && strncmp(entry->mnc, imsi + 3, 2) != 0) + continue; + + if (entry->text[0] == '+') { + LOGP(DNAT, LOGL_ERROR, + "Plus is not allowed in the number"); + continue; + } + + /* We have an entry for the IMSI. Need to match now */ + if (regcomp(®, entry->option, REG_EXTENDED) != 0) { + LOGP(DNAT, LOGL_ERROR, + "Regexp '%s' is not valid.\n", entry->option); + continue; + } + + /* this regexp matches... */ + if (regexec(®, called->number, 2, matches, 0) == 0 && + matches[1].rm_eo != -1) + new_number = talloc_asprintf(ctx, "%s%s", + entry->text, + &called->number[matches[1].rm_so]); + regfree(®); + + if (new_number) + break; + } + + return new_number; +} + + /** * Rewrite non global numbers... according to rules based on the IMSI */ @@ -809,7 +864,6 @@ struct msgb *bsc_nat_rewrite_setup(struct bsc_nat *nat, struct msgb *msg, struct uint8_t msg_type, proto; unsigned int payload_len; struct gsm_mncc_number called; - struct osmo_config_entry *entry; char *new_number = NULL; struct msgb *out, *sccp; uint8_t *outptr; @@ -819,9 +873,6 @@ struct msgb *bsc_nat_rewrite_setup(struct bsc_nat *nat, struct msgb *msg, struct if (!imsi || strlen(imsi) < 5) return msg; - if (!nat->num_rewr) - return msg; - /* only care about DTAP messages */ if (parsed->bssap != BSSAP_MSG_DTAP) return msg; @@ -851,47 +902,7 @@ struct msgb *bsc_nat_rewrite_setup(struct bsc_nat *nat, struct msgb *msg, struct TLVP_VAL(&tp, GSM48_IE_CALLED_BCD) - 1); /* check if it looks international and stop */ - if (called.plan != 1) - return msg; - if (called.type == 1) - return msg; - if (strncmp(called.number, "00", 2) == 0) - return msg; - - /* need to find a replacement and then fix it */ - llist_for_each_entry(entry, &nat->num_rewr->entry, list) { - regex_t reg; - regmatch_t matches[2]; - - if (entry->mcc[0] != '*' && strncmp(entry->mcc, imsi, 3) != 0) - continue; - if (entry->mnc[0] != '*' && strncmp(entry->mnc, imsi + 3, 2) != 0) - continue; - - if (entry->text[0] == '+') { - LOGP(DNAT, LOGL_ERROR, - "Plus is not allowed in the number"); - continue; - } - - /* We have an entry for the IMSI. Need to match now */ - if (regcomp(®, entry->option, REG_EXTENDED) != 0) { - LOGP(DNAT, LOGL_ERROR, - "Regexp '%s' is not valid.\n", entry->option); - continue; - } - - /* this regexp matches... */ - if (regexec(®, called.number, 2, matches, 0) == 0 && - matches[1].rm_eo != -1) - new_number = talloc_asprintf(msg, "%s%s", - entry->text, - &called.number[matches[1].rm_so]); - regfree(®); - - if (new_number) - break; - } + new_number = rewrite_non_international(nat, msg, imsi, &called); if (!new_number) { LOGP(DNAT, LOGL_DEBUG, "No IMSI match found, returning message.\n");