aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/nat/bsc_mgcp_utils.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-04-01 06:48:52 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-04-01 07:41:23 +0200
commitc57575bea80c901823f22983cb49ba03da5b21e5 (patch)
tree15581904c0607596d73612b4aa3c399c16d40a03 /openbsc/src/nat/bsc_mgcp_utils.c
parent8cdfe9fc37819051187ad02dca20d8b75c701b0b (diff)
nat: Test rewriting of MGCP messages to patch ip and port
Add code to change the ip and port for audio data inside MGCP messages. This is needed because the BSS might be behind the NAT and can not reach the network directly and might be behind a nat so the announced sourceport is not the one as we see it.
Diffstat (limited to 'openbsc/src/nat/bsc_mgcp_utils.c')
-rw-r--r--openbsc/src/nat/bsc_mgcp_utils.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c
index 0f45a91a5..3639a7b00 100644
--- a/openbsc/src/nat/bsc_mgcp_utils.c
+++ b/openbsc/src/nat/bsc_mgcp_utils.c
@@ -95,6 +95,67 @@ struct bsc_connection *bsc_mgcp_find_con(struct bsc_nat *nat, int endpoint)
return NULL;
}
+/* we need to replace some strings... */
+struct msgb *bsc_mgcp_rewrite(struct msgb *input, const char *ip, int port)
+{
+ static const char *ip_str = "c=IN IP4 ";
+ static const char *aud_str = "m=audio ";
+
+ char buf[128];
+ char *running, *token;
+ struct msgb *output;
+
+ if (msgb_l2len(input) > 4096 - 128) {
+ LOGP(DMGCP, LOGL_ERROR, "Input is too long.\n");
+ return NULL;
+ }
+
+ output = msgb_alloc_headroom(4096, 128, "MGCP rewritten");
+ if (!output) {
+ LOGP(DMGCP, LOGL_ERROR, "Failed to allocate new MGCP msg.\n");
+ return NULL;
+ }
+
+ running = (char *) input->l2h;
+ output->l2h = output->data;
+ for (token = strsep(&running, "\n"); token; token = strsep(&running, "\n")) {
+ int len = strlen(token);
+
+ /* ignore completely empty lines for now */
+ if (len == 0)
+ continue;
+
+ 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));
+ memcpy(output->l3h, ip, strlen(ip));
+ output->l3h = msgb_put(output, 2);
+ output->l3h[0] = '\r';
+ output->l3h[1] = '\n';
+ } else if (strncmp(aud_str, token, (sizeof aud_str) - 1) == 0) {
+ int payload;
+ if (sscanf(token, "m=audio %*d RTP/AVP %d", &payload) != 1) {
+ LOGP(DMGCP, LOGL_ERROR, "Could not parsed audio line.\n");
+ msgb_free(output);
+ return NULL;
+ }
+
+ snprintf(buf, sizeof(buf)-1, "m=audio %d RTP/AVP %d\r\n", port, payload);
+ buf[sizeof(buf)-1] = '\0';
+
+ output->l3h = msgb_put(output, strlen(buf));
+ memcpy(output->l3h, buf, strlen(buf));
+ } else {
+ output->l3h = msgb_put(output, len + 1);
+ memcpy(output->l3h, token, len);
+ output->l3h[len] = '\n';
+ }
+ }
+
+ return output;
+}
+
static int mgcp_do_read(struct bsc_fd *fd)
{
struct bsc_nat *nat;