diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-09-15 19:30:20 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-09-15 19:30:20 +0200 |
commit | b1dfc462dfa308d62b939847dbee2218c3a25fc1 (patch) | |
tree | 45e37d40b8cb870873a66586217e04ca7d0e84fa /src/mgcp_patch.c | |
parent | 588754c7d391482de6b903e3a80a0df103d314d8 (diff) |
cellmgr: Patch the MGCP messages and replace the domain name
Replace the domain name with a new name domain that can be configured
via the VTY interface.
Diffstat (limited to 'src/mgcp_patch.c')
-rw-r--r-- | src/mgcp_patch.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/mgcp_patch.c b/src/mgcp_patch.c new file mode 100644 index 0000000..f4a8579 --- /dev/null +++ b/src/mgcp_patch.c @@ -0,0 +1,111 @@ +/* MGCP message patching */ +/* + * (C) 2011 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2011 by On-Waves + * All Rights Reserved + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <mgcp_patch.h> +#include <cellmgr_debug.h> +#include <ss7_application.h> +#include <string.h> + +#include <osmocom/gsm/tlv.h> + + +struct msgb *mgcp_patch(struct ss7_application *app, struct msgb *msg) +{ + char *token, *remaining; + struct msgb *out; + int len, out_len, state, i; + + if (!app->mgcp_domain_name) + return msg; + + if (msgb_tailroom(msg) <= strlen(app->mgcp_domain_name)) { + LOGP(DMGCP, LOGL_ERROR, "Not enough space to add a zero line.\n"); + return msg; + } + + msg->l2h[msgb_l2len(msg)] = '\0'; + + /** + * We now need to rewrite the message, but actually only the first + * line and the rest can be copied. + */ + out = msgb_alloc_headroom(4096, 128, "MGCP Patch Copy"); + if (!out) { + LOGP(DMGCP, LOGL_ERROR, "Failed to create the MSGB copy.\n"); + return NULL; + } + + + remaining = (char *) msg->l2h; + token = strsep(&remaining, "\n"); + if (!token) { + LOGP(DMGCP, LOGL_ERROR, "Failed to split the MGCP.\n"); + msgb_free(out); + return msg; + } + + len = strlen(token); + out->l2h = msgb_put(out, 0); + + /* + * State machine for copying and modifying the MGCP line, first find + * half of the endpoint, put ours, copy the rest of the line + */ + state = 0; + for (i = 0; i < len; ++i) { + switch (state) { + case 2: + if (token[i] == '@') + state += 1; + msgb_v_put(out, token[i]); + break; + case 3: + /* copy the new name */ + out->l3h = msgb_put(out, strlen(app->mgcp_domain_name)); + memcpy(out->l3h, app->mgcp_domain_name, msgb_l3len(out)); + + /* skip everything to the next whitespace */ + for (; i < len; ++i) { + if (token[i] == ' ') { + break; + } + } + + for (; i < len; ++i) + msgb_v_put(out, token[i]); + msgb_v_put(out, '\n'); + break; + default: + if (token[i] == ' ') + state += 1; + msgb_v_put(out, token[i]); + break; + } + } + + /* append the rest */ + out_len = msgb_l2len(msg) - len - 1; + out->l3h = msgb_put(out, out_len); + memcpy(out->l3h, &msg->l2h[len + 1], out_len); + + msgb_free(msg); + return out; +} + |