diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2013-06-25 15:38:31 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-07-31 16:36:40 +0200 |
commit | 67e423c2561a5a08ac7331de2ab264a270b238c9 (patch) | |
tree | 20c5541ac8327dcf27a05717485d47216d2d46a2 /openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c | |
parent | 3615a30d3d201e656ef24eda28f83bfff3468e39 (diff) |
nat: Implement a post-routing for the NAT software
* The post-routing is applied after the first re-writing. To do this
the new number is copied back into the called data structure.
* Add a testcase that goes from 0172 to 0049 and then back to 0049
using the post rule with a table lookup.
Diffstat (limited to 'openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c')
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c index 5984d962d..3bc602e79 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c @@ -93,8 +93,9 @@ static char *match_and_rewrite_number(void *ctx, const char *number, return new_number; } -static char *rewrite_isdn_number(struct bsc_nat *nat, void *ctx, const char *imsi, - struct gsm_mncc_number *called) +static char *rewrite_isdn_number(struct bsc_nat *nat, struct llist_head *rewr_list, + void *ctx, const char *imsi, + struct gsm_mncc_number *called) { char int_number[sizeof(called->number) + 2]; char *number = called->number; @@ -114,9 +115,22 @@ static char *rewrite_isdn_number(struct bsc_nat *nat, void *ctx, const char *ims } return match_and_rewrite_number(ctx, number, - imsi, &nat->num_rewr, nat->num_rewr_trie); + imsi, rewr_list, nat->num_rewr_trie); } +static void update_called_number(struct gsm_mncc_number *called, + const char *chosen_number) +{ + if (strncmp(chosen_number, "00", 2) == 0) { + called->type = 1; + strncpy(called->number, chosen_number + 2, sizeof(called->number)); + } else { + /* rewrite international to unknown */ + if (called->type == 1) + called->type = 0; + strncpy(called->number, chosen_number, sizeof(called->number)); + } +} /** * Rewrite non global numbers... according to rules based on the IMSI @@ -129,7 +143,7 @@ static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg, unsigned int payload_len; struct gsm_mncc_number called; struct msgb *out; - char *new_number = NULL; + char *new_number_pre = NULL, *new_number_post = NULL, *chosen_number; uint8_t *outptr; const uint8_t *msgptr; int sec_len; @@ -147,16 +161,30 @@ static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg, TLVP_VAL(&tp, GSM48_IE_CALLED_BCD) - 1); /* check if it looks international and stop */ - new_number = rewrite_isdn_number(nat, msg, imsi, &called); + new_number_pre = rewrite_isdn_number(nat, &nat->num_rewr, msg, imsi, &called); - if (!new_number) { + if (!new_number_pre) { LOGP(DNAT, LOGL_DEBUG, "No IMSI match found, returning message.\n"); return NULL; } - if (strlen(new_number) > sizeof(called.number)) { + if (strlen(new_number_pre) > sizeof(called.number)) { LOGP(DNAT, LOGL_ERROR, "Number is too long for structure.\n"); - talloc_free(new_number); + talloc_free(new_number_pre); + return NULL; + } + update_called_number(&called, new_number_pre); + + /* another run through the re-write engine with other rules */ + new_number_post = rewrite_isdn_number(nat, &nat->num_rewr_post, msg, + imsi, &called); + chosen_number = new_number_post ? new_number_post : new_number_pre; + + + if (strlen(chosen_number) > sizeof(called.number)) { + LOGP(DNAT, LOGL_ERROR, "Number is too long for structure.\n"); + talloc_free(new_number_pre); + talloc_free(new_number_post); return NULL; } @@ -169,7 +197,8 @@ static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg, out = msgb_alloc_headroom(4096, 128, "changed-setup"); if (!out) { LOGP(DNAT, LOGL_ERROR, "Failed to allocate.\n"); - talloc_free(new_number); + talloc_free(new_number_pre); + talloc_free(new_number_post); return NULL; } @@ -183,15 +212,7 @@ static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg, memcpy(outptr, &hdr48->data[0], sec_len); /* create the new number */ - if (strncmp(new_number, "00", 2) == 0) { - called.type = 1; - strncpy(called.number, new_number + 2, sizeof(called.number)); - } else { - /* rewrite international to unknown */ - if (called.type == 1) - called.type = 0; - strncpy(called.number, new_number, sizeof(called.number)); - } + update_called_number(&called, chosen_number); gsm48_encode_called(out, &called); /* copy thre rest */ @@ -201,7 +222,8 @@ static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg, outptr = msgb_put(out, sec_len); memcpy(outptr, msgptr, sec_len); - talloc_free(new_number); + talloc_free(new_number_pre); + talloc_free(new_number_post); return out; } |