aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-01-10 22:39:07 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-01-10 22:45:24 +0100
commit68368dd99a2c98a4e8761f222f6174855d38bdd8 (patch)
treef3b7a92dea0f8649b7916344b44fd02bef9b8c50
parent50be1a9d7fb1042dc9946d4b7ce5d4b906adb6a3 (diff)
nat: Implement clearing of TP-SRR flags from TPDUs
Match IMSI and destination address against a set of entries, if it is matching the header will be modified and no sender report will be requested. Change the test case to request the sender report and then verify that this bit is reset to 0.
-rw-r--r--openbsc/include/openbsc/bsc_nat.h2
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_utils.c43
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_vty.c28
-rw-r--r--openbsc/tests/bsc-nat/bsc_data.c12
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c55
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.ok3
6 files changed, 136 insertions, 7 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index b4f07e0b..b890a684 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -295,6 +295,8 @@ struct bsc_nat {
struct llist_head smsc_rewr;
char *tpdest_match_name;
struct llist_head tpdest_match;
+ char *sms_clear_tp_srr_name;
+ struct llist_head sms_clear_tp_srr;
/* USSD messages we want to match */
char *ussd_lst_name;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
index 1d67c350..3d0c30d2 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
@@ -98,6 +98,7 @@ struct bsc_nat *bsc_nat_alloc(void)
INIT_LLIST_HEAD(&nat->num_rewr);
INIT_LLIST_HEAD(&nat->smsc_rewr);
INIT_LLIST_HEAD(&nat->tpdest_match);
+ INIT_LLIST_HEAD(&nat->sms_clear_tp_srr);
nat->stats.sccp.conn = osmo_counter_alloc("nat.sccp.conn");
nat->stats.sccp.calls = osmo_counter_alloc("nat.sccp.calls");
@@ -954,11 +955,35 @@ static char *find_new_smsc(struct bsc_nat *nat, void *ctx, const char *imsi,
return new_number;
}
+/**
+ * Clear the TP-SRR from the TPDU header
+ */
+static uint8_t sms_new_tpdu_hdr(struct bsc_nat *nat, const char *imsi,
+ const char *dest_nr, uint8_t hdr)
+{
+ struct bsc_nat_num_rewr_entry *entry;
+
+ /* We will find a new number now */
+ llist_for_each_entry(entry, &nat->sms_clear_tp_srr, list) {
+ /* check the IMSI match */
+ if (regexec(&entry->msisdn_reg, imsi, 0, NULL, 0) != 0)
+ continue;
+ if (regexec(&entry->num_reg, dest_nr, 0, NULL, 0) != 0)
+ continue;
+
+ /* matched phone number and imsi */
+ return hdr & ~0x20;
+ }
+
+ return hdr;
+}
+
static struct msgb *sms_create_new(uint8_t type, uint8_t ref,
struct gsm48_hdr *old_hdr48,
const uint8_t *orig_addr_ptr,
int orig_addr_len, const char *new_number,
- const uint8_t *data_ptr, int data_len)
+ const uint8_t *data_ptr, int data_len,
+ uint8_t tpdu_first_byte)
{
uint8_t new_addr_len;
struct gsm48_hdr *new_hdr48;
@@ -991,8 +1016,11 @@ static struct msgb *sms_create_new(uint8_t type, uint8_t ref,
new_addr[1] = 0x91;
msgb_lv_put(out, new_addr_len - 1, new_addr + 1);
- msgb_lv_put(out, data_len, data_ptr);
+ /* patch in the new TPDU header value */
+ msgb_v_put(out, data_len);
+ msgb_tv_fixed_put(out, tpdu_first_byte, data_len - 1, &data_ptr[1]);
+ /* prepend GSM 04.08 header */
new_hdr48 = (struct gsm48_hdr *) msgb_push(out, sizeof(*new_hdr48) + 1);
memcpy(new_hdr48, old_hdr48, sizeof(*old_hdr48));
new_hdr48->data[0] = msgb_l3len(out);
@@ -1022,6 +1050,7 @@ static struct msgb *rewrite_sms(struct bsc_nat *nat, struct msgb *msg,
char *dest_nr;
char *new_number = NULL;
+ uint8_t tpdu_hdr;
struct msgb *out;
payload_len = len - sizeof(*hdr48);
@@ -1107,13 +1136,19 @@ static struct msgb *rewrite_sms(struct bsc_nat *nat, struct msgb *msg,
dest_nr = &_dest_nr[2];
}
+ /**
+ * Call functions to rewrite the data
+ */
+ tpdu_hdr = sms_new_tpdu_hdr(nat, imsi, dest_nr, data_ptr[0]);
new_number = find_new_smsc(nat, msg, imsi, smsc_addr, dest_nr);
- if (!new_number)
+
+ if (tpdu_hdr == data_ptr[0] && !new_number)
return NULL;
out = sms_create_new(GSM411_MT_RP_DATA_MO, ref, hdr48,
orig_addr_ptr, orig_addr_len,
- new_number, data_ptr, data_len);
+ new_number ? new_number : smsc_addr,
+ data_ptr, data_len, tpdu_hdr);
talloc_free(new_number);
return out;
}
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
index 55b3958c..81f70de7 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -127,6 +127,9 @@ static int config_write_nat(struct vty *vty)
if (_nat->tpdest_match_name)
vty_out(vty, " rewrite-smsc tp-dest-match %s%s",
_nat->tpdest_match_name, VTY_NEWLINE);
+ if (_nat->sms_clear_tp_srr_name)
+ vty_out(vty, " sms-clear-tp-srr %s%s",
+ _nat->sms_clear_tp_srr_name, VTY_NEWLINE);
llist_for_each_entry(lst, &_nat->access_lists, list)
write_acc_lst(vty, lst);
@@ -512,6 +515,29 @@ DEFUN(cfg_nat_smsc_tpdest,
&_nat->tpdest_match, argv[0]);
}
+DEFUN(cfg_nat_sms_clear_tpsrr,
+ cfg_nat_sms_clear_tpsrr_cmd,
+ "sms-clear-tp-srr FILENAME",
+ "SMS TPDU Sender Report Request clearing\n"
+ "Files with rules for matching MSISDN\n")
+{
+ return replace_rules(_nat, &_nat->sms_clear_tp_srr_name,
+ &_nat->sms_clear_tp_srr, argv[0]);
+}
+
+DEFUN(cfg_nat_no_sms_clear_tpsrr,
+ cfg_nat_no_sms_clear_tpsrr_cmd,
+ "sms-clear-tp-srr",
+ NO_STR
+ "SMS TPDU Sender Report Request clearing\n")
+{
+ talloc_free(_nat->sms_clear_tp_srr_name);
+ _nat->sms_clear_tp_srr_name = NULL;
+
+ bsc_nat_num_rewr_entry_adapt(NULL, &_nat->sms_clear_tp_srr, NULL);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_nat_ussd_lst_name,
cfg_nat_ussd_lst_name_cmd,
"ussd-list-name NAME",
@@ -958,6 +984,8 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_element(NAT_NODE, &cfg_nat_number_rewrite_cmd);
install_element(NAT_NODE, &cfg_nat_smsc_addr_cmd);
install_element(NAT_NODE, &cfg_nat_smsc_tpdest_cmd);
+ install_element(NAT_NODE, &cfg_nat_sms_clear_tpsrr_cmd);
+ install_element(NAT_NODE, &cfg_nat_no_sms_clear_tpsrr_cmd);
install_element(NAT_NODE, &cfg_nat_pgroup_cmd);
install_element(NAT_NODE, &cfg_nat_no_pgroup_cmd);
diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c
index 101c5761..08b900b8 100644
--- a/openbsc/tests/bsc-nat/bsc_data.c
+++ b/openbsc/tests/bsc-nat/bsc_data.c
@@ -101,7 +101,7 @@ static const uint8_t smsc_rewrite[] = {
0x00, 0x30, 0xfd, 0x06, 0x01, 0x13, 0x1e, 0x00,
0x01, 0x29, 0x01, 0x03, 0x26, 0x09, 0x01, 0x23,
0x00, 0x0c, 0x00, 0x07, 0x91, 0x36, 0x19, 0x08,
-0x00, 0x10, 0x50, 0x17, 0x01, 0x0c, 0x0f, 0x81,
+0x00, 0x10, 0x50, 0x17, 0x21, 0x0c, 0x0f, 0x81,
0x00, 0x94, 0x51, 0x87, 0x86, 0x78, 0x46, 0xf5,
0x00, 0x00, 0x09, 0xcc, 0xb7, 0xbd, 0x0c, 0xca,
0xbf, 0xeb, 0x20
@@ -117,6 +117,16 @@ static const uint8_t smsc_rewrite_patched[] = {
0xca, 0xbf, 0xeb, 0x20
};
+static const uint8_t smsc_rewrite_patched_hdr[] = {
+0x00, 0x30, 0xfd, 0x06, 0x01, 0x13, 0x1e, 0x00,
+0x01, 0x29, 0x01, 0x03, 0x26, 0x09, 0x01, 0x23,
+0x00, 0x0c, 0x00, 0x07, 0x91, 0x36, 0x19, 0x08,
+0x00, 0x10, 0x50, 0x17, 0x01, 0x0c, 0x0f, 0x81,
+0x00, 0x94, 0x51, 0x87, 0x86, 0x78, 0x46, 0xf5,
+0x00, 0x00, 0x09, 0xcc, 0xb7, 0xbd, 0x0c, 0xca,
+0xbf, 0xeb, 0x20
+};
+
/*
* MGCP messages
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 974dfa55..65ff4f65 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -986,11 +986,12 @@ static void test_smsc_rewrite()
struct bsc_nat *nat = bsc_nat_alloc();
/* a fake list */
- struct osmo_config_list smsc_entries, dest_entries;
- struct osmo_config_entry smsc_entry, dest_entry;
+ struct osmo_config_list smsc_entries, dest_entries, clear_entries;
+ struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
INIT_LLIST_HEAD(&smsc_entries.entry);
INIT_LLIST_HEAD(&dest_entries.entry);
+ INIT_LLIST_HEAD(&clear_entries.entry);
smsc_entry.mcc = "^515039";
smsc_entry.option = "639180000105()";
smsc_entry.text = "6666666666667";
@@ -1000,10 +1001,20 @@ static void test_smsc_rewrite()
dest_entry.option = "^0049";
dest_entry.text = "";
llist_add_tail(&dest_entry.list, &dest_entries.entry);
+ clear_entry.mcc = "^515039";
+ clear_entry.option = "^0049";
+ clear_entry.text = "";
+ llist_add_tail(&clear_entry.list, &clear_entries.entry);
bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
+ bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
+ printf("Testing SMSC rewriting.\n");
+
+ /*
+ * Check if the SMSC address is changed
+ */
copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
parsed = bsc_nat_parse(msg);
if (!parsed) {
@@ -1019,6 +1030,46 @@ static void test_smsc_rewrite()
verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
msgb_free(out);
+
+ /* clear out the filter for SMSC */
+ printf("Attempting to only rewrite the HDR\n");
+ bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
+ msg = msgb_alloc(4096, "SMSC rewrite");
+ copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
+ parsed = bsc_nat_parse(msg);
+ if (!parsed) {
+ printf("FAIL: Could not parse SMS\n");
+ abort();
+ }
+
+ out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ if (out == msg) {
+ printf("FAIL: This should have changed.\n");
+ abort();
+ }
+
+ verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
+ msgb_free(out);
+
+ /* clear out the next filter */
+ printf("Attempting to change nothing.\n");
+ bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
+ msg = msgb_alloc(4096, "SMSC rewrite");
+ copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
+ parsed = bsc_nat_parse(msg);
+ if (!parsed) {
+ printf("FAIL: Could not parse SMS\n");
+ abort();
+ }
+
+ out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
+ if (out != msg) {
+ printf("FAIL: This should not have changed.\n");
+ abort();
+ }
+
+ verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
+ msgb_free(out);
}
int main(int argc, char **argv)
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.ok b/openbsc/tests/bsc-nat/bsc_nat_test.ok
index 2aff594f..f8eee238 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.ok
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.ok
@@ -18,4 +18,7 @@ Testing MGCP.
Testing finding of a BSC Connection
Testing rewriting MGCP messages.
Testing MGCP response parsing.
+Testing SMSC rewriting.
+Attempting to only rewrite the HDR
+Attempting to change nothing.
Testing execution completed.