diff options
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat_utils.c | 43 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat_vty.c | 28 |
2 files changed, 67 insertions, 4 deletions
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); |