From dbd9449a1659f46ef8be68c6c643045e841835a6 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 2 Apr 2013 12:34:11 +0200 Subject: nat: Allow to re-write international numbers in the CC Setup messages Prepend the international number with a '+' and then do the normal re-writing on it. There are a couple of ways to handle this: \+([0-9]), \+[0-9][0-9]([0-9]), \+49([0-9]) Add a test case for the international re-write based on an already internationalized number. --- openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c | 26 +++++++++---- openbsc/tests/bsc-nat/bsc_data.c | 17 +++++++++ openbsc/tests/bsc-nat/bsc_nat_test.c | 60 +++++++++++++++++++++++++++++- 3 files changed, 94 insertions(+), 9 deletions(-) diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c index 1eed149a5..c9b6f4a91 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_rewrite.c @@ -2,8 +2,8 @@ * Message rewriting functionality */ /* - * (C) 2010-2011 by Holger Hans Peter Freyther - * (C) 2010-2011 by On-Waves + * (C) 2010-2013 by Holger Hans Peter Freyther + * (C) 2010-2013 by On-Waves * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -65,18 +65,27 @@ static char *match_and_rewrite_number(void *ctx, const char *number, return new_number; } -static char *rewrite_non_international(struct bsc_nat *nat, void *ctx, const char *imsi, +static char *rewrite_isdn_number(struct bsc_nat *nat, void *ctx, const char *imsi, struct gsm_mncc_number *called) { + char *number = called->number; + if (llist_empty(&nat->num_rewr)) return NULL; + /* only ISDN plan */ if (called->plan != 1) return NULL; - if (called->type == 1) - return NULL; - return match_and_rewrite_number(ctx, called->number, + /* international, prepend */ + if (called->type == 1) { + char int_number[sizeof(called->number) + 2]; + int_number[0] = '+'; + memcpy(&int_number[1], number, strlen(number) + 1); + number = int_number; + } + + return match_and_rewrite_number(ctx, number, imsi, &nat->num_rewr); } @@ -110,7 +119,7 @@ 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_non_international(nat, msg, imsi, &called); + new_number = rewrite_isdn_number(nat, msg, imsi, &called); if (!new_number) { LOGP(DNAT, LOGL_DEBUG, "No IMSI match found, returning message.\n"); @@ -150,6 +159,9 @@ static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg, 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)); } gsm48_encode_called(out, &called); diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c index fe0051a59..5a76689e9 100644 --- a/openbsc/tests/bsc-nat/bsc_data.c +++ b/openbsc/tests/bsc-nat/bsc_data.c @@ -229,6 +229,15 @@ static const uint8_t cc_setup_national_patched[] = { 0x66, 0xf6, 0x15, 0x02, 0x11, 0x01 }; +/* patch the phone number of cc_setup_national_patched */ +static const uint8_t cc_setup_national_patched_patched[] = { + 0x00, 0x21, 0xfd, 0x06, 0x01, 0x12, + 0x6d, 0x00, 0x01, 0x1a, 0x01, 0x00, 0x17, 0x03, + 0x05, 0x04, 0x06, 0x60, 0x04, 0x02, 0x00, 0x05, + 0x81, 0x5e, 0x07, 0x91, 0x63, 0x71, 0x32, 0x33, + 0x66, 0xf6, 0x15, 0x02, 0x11, 0x01 +}; + static const uint8_t cc_setup_international[] = { 0x00, 0x22, 0xfd, 0x06, 0x01, 0x13, 0xe7, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x18, 0x03, @@ -236,3 +245,11 @@ static const uint8_t cc_setup_international[] = { 0x81, 0x5e, 0x08, 0x81, 0x00, 0x94, 0x71, 0x33, 0x63, 0x66, 0x03, 0x15, 0x02, 0x11, 0x01 }; + +static const uint8_t cc_setup_national_again[] = { + 0x00, 0x22, 0xfd, 0x06, 0x01, 0x12, 0x6d, 0x00, + 0x01, 0x1b, 0x01, 0x00, 0x18, 0x03, 0x05, 0x04, + 0x06, 0x60, 0x04, 0x02, 0x00, 0x05, 0x81, 0x5e, + 0x08, 0x81, 0x63, 0x94, 0x71, 0x32, 0x33, 0x66, + 0xf6, 0x15, 0x02, 0x11, 0x01 +}; diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index c2931f98b..6148a375d 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -1,8 +1,8 @@ /* * BSC NAT Message filtering * - * (C) 2010-2012 by Holger Hans Peter Freyther - * (C) 2010-2012 by On-Waves + * (C) 2010-2013 by Holger Hans Peter Freyther + * (C) 2010-2013 by On-Waves * * All Rights Reserved * @@ -985,6 +985,62 @@ static void test_setup_rewrite() verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national)); msgb_free(out); + + /* Now see what happens to an international number */ + entry.mnc = "*"; + entry.option = "^\\+[0-9][0-9]([1-9])"; + entry.text = "0036"; + bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries); + msg = msgb_alloc(4096, "test_dt_filter"); + copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched)); + parsed = bsc_nat_parse(msg); + if (!parsed) { + printf("FAIL: Could not parse ID resp %d\n", __LINE__); + abort(); + } + + out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + if (!out) { + printf("FAIL: A new message should be created %d.\n", __LINE__); + abort(); + } + + if (msg == out) { + printf("FAIL: The message should have changed %d\n", __LINE__); + abort(); + } + + verify_msg(out, cc_setup_national_patched_patched, + ARRAY_SIZE(cc_setup_national_patched_patched)); + msgb_free(out); + + /* go from international back to national */ + entry.mnc = "*"; + entry.option = "^\\+([0-9])"; + entry.text = "36"; + bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries); + msg = msgb_alloc(4096, "test_dt_filter"); + copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched)); + parsed = bsc_nat_parse(msg); + if (!parsed) { + printf("FAIL: Could not parse ID resp %d\n", __LINE__); + abort(); + } + + out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi); + if (!out) { + printf("FAIL: A new message should be created %d.\n", __LINE__); + abort(); + } + + if (msg == out) { + printf("FAIL: The message should have changed %d\n", __LINE__); + abort(); + } + + verify_msg(out, cc_setup_national_again, + ARRAY_SIZE(cc_setup_national_again)); + msgb_free(out); } static void test_sms_smsc_rewrite() -- cgit v1.2.3