summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 b4f07e0b5..b890a6842 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 1d67c350c..3d0c30d2f 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 55b3958c0..81f70de75 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 101c57614..08b900b83 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 974dfa55f..65ff4f65a 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 2aff594fb..f8eee238d 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.