mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -2,8 +2,8 @@
 | 
			
		||||
 * Message rewriting functionality
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
 * (C) 2010-2011 by On-Waves
 | 
			
		||||
 * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
 * (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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
/*
 | 
			
		||||
 * BSC NAT Message filtering
 | 
			
		||||
 *
 | 
			
		||||
 * (C) 2010-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
 * (C) 2010-2012 by On-Waves
 | 
			
		||||
 * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
 * (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()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user