From f7c86c5b4d8f7d909595c0f01fcfaf5da4c4e7c4 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 30 Aug 2010 13:44:32 +0800 Subject: nat: Replace the MGCP Endpoint if that is required Add code to replace the Endpoint number for the mgcp. --- openbsc/include/openbsc/bsc_nat.h | 2 +- openbsc/src/nat/bsc_mgcp_utils.c | 37 ++++++++++++++++++++++++++++++++---- openbsc/tests/bsc-nat/bsc_data.c | 6 +++--- openbsc/tests/bsc-nat/bsc_nat_test.c | 2 +- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 11c24dc60..25b6429c4 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -264,7 +264,7 @@ void bsc_mgcp_free_endpoints(struct bsc_nat *nat); int bsc_mgcp_nat_init(struct bsc_nat *nat); struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number); -struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port); +struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip, int port); void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg); void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc); diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index d8ec29869..1728a41e7 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -196,6 +196,9 @@ void bsc_mgcp_dlcx(struct sccp_connections *con) { /* send a DLCX down the stream */ if (con->bsc_endp != -1) { + if (con->bsc->endpoint_status[con->bsc_endp] != 1) + LOGP(DNAT, LOGL_ERROR, "Endpoint 0x%x was not in use\n", con->bsc_endp); + con->bsc->endpoint_status[con->bsc_endp] = 0; bsc_mgcp_send_dlcx(con->bsc, con->bsc_endp); bsc_mgcp_free_endpoint(con->bsc->nat, con->msc_endp); } @@ -269,7 +272,7 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c } /* we need to generate a new and patched message */ - bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, + bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, sccp->bsc_endp, nat->mgcp_cfg->source_addr, mgcp_endp->bts_end.local_port); if (!bsc_msg) { LOGP(DMGCP, LOGL_ERROR, "Failed to patch the msg.\n"); @@ -401,7 +404,7 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg) * there should be nothing for us to rewrite so putting endp->rtp_port * with the value of 0 should be no problem. */ - output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), + output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), -1, bsc->nat->mgcp_cfg->source_addr, endp->net_end.local_port); if (!output) { @@ -438,9 +441,28 @@ uint32_t bsc_mgcp_extract_ci(const char *str) return ci; } +static void patch_mgcp(struct msgb *output, const char *op, const char *tok, + int endp, int len, int cr) +{ + int slen; + int ret; + char buf[40]; + + buf[0] = buf[39] = '\0'; + ret = sscanf(tok, "%*s %s", buf); + + slen = sprintf((char *) output->l3h, "%s %s %x@mgw MGCP 1.0%s", + op, buf, endp, cr ? "\r\n" : "\n"); + output->l3h = msgb_put(output, slen); +} + /* we need to replace some strings... */ -struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port) +struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char *ip, int port) { + static const char *crcx_str = "CRCX "; + static const char *dlcx_str = "DLCX "; + static const char *mdcx_str = "MDCX "; + static const char *ip_str = "c=IN IP4 "; static const char *aud_str = "m=audio "; @@ -461,11 +483,18 @@ struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port) running = input; output->l2h = output->data; + output->l3h = output->l2h; for (token = strsep(&running, "\n"); running; token = strsep(&running, "\n")) { int len = strlen(token); int cr = len > 0 && token[len - 1] == '\r'; - if (strncmp(ip_str, token, (sizeof ip_str) - 1) == 0) { + if (strncmp(crcx_str, token, (sizeof crcx_str) - 1) == 0) { + patch_mgcp(output, "CRCX", token, endpoint, len, cr); + } else if (strncmp(dlcx_str, token, (sizeof dlcx_str) - 1) == 0) { + patch_mgcp(output, "DLCX", token, endpoint, len, cr); + } else if (strncmp(mdcx_str, token, (sizeof mdcx_str) - 1) == 0) { + patch_mgcp(output, "MDCX", token, endpoint, len, cr); + } else if (strncmp(ip_str, token, (sizeof ip_str) - 1) == 0) { output->l3h = msgb_put(output, strlen(ip_str)); memcpy(output->l3h, ip_str, strlen(ip_str)); output->l3h = msgb_put(output, strlen(ip)); diff --git a/openbsc/tests/bsc-nat/bsc_data.c b/openbsc/tests/bsc-nat/bsc_data.c index 6700b0ca2..a3239799c 100644 --- a/openbsc/tests/bsc-nat/bsc_data.c +++ b/openbsc/tests/bsc-nat/bsc_data.c @@ -94,7 +94,7 @@ static const uint8_t ass_cmd[] = { /* nothing to patch */ static const char crcx[] = "CRCX 23265295 8@mgw MGCP 1.0\r\nC: 394b0439fb\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n"; -static const char crcx_patched[] = "CRCX 23265295 8@mgw MGCP 1.0\r\nC: 394b0439fb\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n"; +static const char crcx_patched[] = "CRCX 23265295 1e@mgw MGCP 1.0\r\nC: 394b0439fb\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n"; /* patch the ip and port */ @@ -102,8 +102,8 @@ static const char crcx_resp[] = "200 23265295\r\nI: 1\r\n\r\nv=0\r\nc=IN IP4 172 static const char crcx_resp_patched[] = "200 23265295\r\nI: 1\r\n\r\nv=0\r\nc=IN IP4 10.0.0.1\r\nm=audio 999 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\n"; /* patch the ip and port */ -static const char mdcx[] = " MDCX 23330829 8@mgw MGCP 1.0\r\nC: 394b0439fb\r\nI: 1\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 1049380491 0 IN IP4 172.16.18.2\r\ns=-\r\nc=IN IP4 172.16.18.2\r\nt=0 0\r\nm=audio 4410 RTP/AVP 126\r\na=rtpmap:126 AMR/8000/1\r\na=fmtp:126 mode-set=2;start-mode=0\r\na=ptime:20\r\na=recvonly\r\nm=image 4412 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"; -static const char mdcx_patched[] = " MDCX 23330829 8@mgw MGCP 1.0\r\nC: 394b0439fb\r\nI: 1\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 1049380491 0 IN IP4 172.16.18.2\r\ns=-\r\nc=IN IP4 10.0.0.23\r\nt=0 0\r\nm=audio 6666 RTP/AVP 126\r\na=rtpmap:126 AMR/8000/1\r\na=fmtp:126 mode-set=2;start-mode=0\r\na=ptime:20\r\na=recvonly\r\nm=image 4412 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"; +static const char mdcx[] = "MDCX 23330829 8@mgw MGCP 1.0\r\nC: 394b0439fb\r\nI: 1\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 1049380491 0 IN IP4 172.16.18.2\r\ns=-\r\nc=IN IP4 172.16.18.2\r\nt=0 0\r\nm=audio 4410 RTP/AVP 126\r\na=rtpmap:126 AMR/8000/1\r\na=fmtp:126 mode-set=2;start-mode=0\r\na=ptime:20\r\na=recvonly\r\nm=image 4412 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"; +static const char mdcx_patched[] = "MDCX 23330829 1e@mgw MGCP 1.0\r\nC: 394b0439fb\r\nI: 1\r\nL: p:20, a:AMR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 1049380491 0 IN IP4 172.16.18.2\r\ns=-\r\nc=IN IP4 10.0.0.23\r\nt=0 0\r\nm=audio 6666 RTP/AVP 126\r\na=rtpmap:126 AMR/8000/1\r\na=fmtp:126 mode-set=2;start-mode=0\r\na=ptime:20\r\na=recvonly\r\nm=image 4412 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"; static const char mdcx_resp[] = "200 23330829\r\n\r\nv=0\r\nc=IN IP4 172.16.18.2\r\nm=audio 4002 RTP/AVP 98\r\na=rtpmap:98 AMR/8000\r\n"; diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index acc5de343..8f4e2d152 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -521,7 +521,7 @@ static void test_mgcp_rewrite(void) char *input = strdup(orig); - output = bsc_mgcp_rewrite(input, strlen(input), ip, port); + output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port); if (msgb_l2len(output) != strlen(patc)) { fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig)); fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc); -- cgit v1.2.3