diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-03-23 16:19:37 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2015-03-24 18:52:45 +0100 |
commit | d2f21e079613a7c0ed4f245fb14a6b3d20eefdfc (patch) | |
tree | 0179c3ebeb238f70a6ea789a03dabd72c31af7e0 | |
parent | 679a8d0b75fe2db44cacdcd56b11aec3803ca521 (diff) |
m3ua: Begin to create a m3ua client connection
Implement a basic M3UA state machine on a SCTP connection.
-rw-r--r-- | include/mtp_data.h | 1 | ||||
-rw-r--r-- | include/sctp_m3ua.h | 22 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/sctp_m3ua_client.c | 75 | ||||
-rw-r--r-- | src/vty_interface.c | 158 |
5 files changed, 255 insertions, 3 deletions
diff --git a/include/mtp_data.h b/include/mtp_data.h index 9d53f24..74e0864 100644 --- a/include/mtp_data.h +++ b/include/mtp_data.h @@ -41,6 +41,7 @@ enum ss7_link_type { SS7_LTYPE_NONE, SS7_LTYPE_UDP, SS7_LTYPE_M2UA, + SS7_LTYPE_M3UA_CLIENT, }; /** diff --git a/include/sctp_m3ua.h b/include/sctp_m3ua.h new file mode 100644 index 0000000..c7918be --- /dev/null +++ b/include/sctp_m3ua.h @@ -0,0 +1,22 @@ +/* + * Represet M3UA client (and later server) links + */ +#pragma once + +#include "mtp_data.h" + +#include <netinet/in.h> + +struct mtp_m3ua_client_link { + struct mtp_link *base; + + char *source; + struct sockaddr_in local; + + char *dest; + struct sockaddr_in remote; + int link_index; + int routing_context; +}; + +struct mtp_m3ua_client_link *mtp_m3ua_client_link_init(struct mtp_link *link); diff --git a/src/Makefile.am b/src/Makefile.am index b7044a4..b4fe733 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ osmo_stp_SOURCES = main_stp.c mtp_layer3.c thread.c pcap.c link_udp.c snmp_mtp.c bss_patch.c bssap_sccp.c bsc_sccp.c bsc_ussd.c input/ipaccess.c \ mtp_link.c counter.c bsc.c ss7_application.c \ vty_interface.c vty_interface_cmds.c mgcp_patch.c \ - mgcp_callagent.c isup_filter.c + mgcp_callagent.c isup_filter.c sctp_m3ua_client.c osmo_stp_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \ $(LIBOSMOSCCP_LIBS) $(NEXUSWARE_C7_LIBS) \ -lpthread -lnetsnmp -lcrypto -lxua -lsctp diff --git a/src/sctp_m3ua_client.c b/src/sctp_m3ua_client.c new file mode 100644 index 0000000..0c87f2f --- /dev/null +++ b/src/sctp_m3ua_client.c @@ -0,0 +1,75 @@ +/* Run M3UA over SCTP here */ +/* (C) 2015 by Holger Hans Peter Freyther + * + * 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 <sctp_m3ua.h> +#include <cellmgr_debug.h> + +#include <osmocom/core/talloc.h> + +#define SCTP_PPID_M3UA 3 + +#define notImplemented \ + LOGP(DINP, LOGL_NOTICE, "%s:%s not implemented.\n", \ + __FILE__, __func__); + +static int m3ua_write(struct mtp_link *mtp_link, struct msgb *msg) +{ + msgb_free(msg); + return 0; +} + +static int m3ua_shutdown(struct mtp_link *mtp_link) +{ + return 0; +} + +static int m3ua_reset(struct mtp_link *mtp_link) +{ + /* let the framework call start again */ + return m3ua_shutdown(mtp_link); +} + +static int m3ua_clear_queue(struct mtp_link *mtp_link) +{ + /* nothing */ + return 0; +} + +struct mtp_m3ua_client_link *mtp_m3ua_client_link_init(struct mtp_link *blnk) +{ + struct mtp_m3ua_client_link *lnk; + + lnk = talloc_zero(blnk, struct mtp_m3ua_client_link); + if (!lnk) { + LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n"); + return NULL; + } + + /* make sure we can resolve it both ways */ + lnk->base = blnk; + blnk->data = lnk; + blnk->type = SS7_LTYPE_M3UA_CLIENT; + + /* do some checks for lower layer handling */ + blnk->skip_link_test = 1; + + lnk->base->write = m3ua_write; + lnk->base->shutdown = m3ua_shutdown; + lnk->base->reset = m3ua_reset; + lnk->base->clear_queue = m3ua_clear_queue; + return lnk; +} diff --git a/src/vty_interface.c b/src/vty_interface.c index 93ebc6a..dd4412b 100644 --- a/src/vty_interface.c +++ b/src/vty_interface.c @@ -23,6 +23,7 @@ #include <mtp_pcap.h> #include <msc_connection.h> #include <sctp_m2ua.h> +#include <sctp_m3ua.h> #include <ss7_application.h> #include <ss7_vty.h> #include <cellmgr_debug.h> @@ -157,6 +158,7 @@ static void write_link(struct vty *vty, struct mtp_link *link) const char *name = link->name ? link->name : ""; struct mtp_udp_link *ulnk; struct mtp_m2ua_link *m2ua; + struct mtp_m3ua_client_link *m3ua_client; vty_out(vty, " link %d%s", link->nr, VTY_NEWLINE); vty_out(vty, " description %s%s", name, VTY_NEWLINE); @@ -179,11 +181,27 @@ static void write_link(struct vty *vty, struct mtp_link *link) vty_out(vty, " ss7-transport m2ua%s", VTY_NEWLINE); if (m2ua->as) - vty_out(vty, " m2ua application-server %s%s", + vty_out(vty, " m2ua application-server-index %s%s", m2ua->as, VTY_NEWLINE); vty_out(vty, " m2ua link-index %d%s", m2ua->link_index, VTY_NEWLINE); break; + case SS7_LTYPE_M3UA_CLIENT: + m3ua_client = (struct mtp_m3ua_client_link *) link->data; + vty_out(vty, " ss7-transport m3ua-client%s", VTY_NEWLINE); + vty_out(vty, " m3ua-client source ip %s%s", + inet_ntoa(m3ua_client->local.sin_addr), VTY_NEWLINE); + vty_out(vty, " m3ua-client source port %d%s", + ntohs(m3ua_client->local.sin_port), VTY_NEWLINE); + vty_out(vty, " m3ua-client dest ip %s%s", + inet_ntoa(m3ua_client->remote.sin_addr), VTY_NEWLINE); + vty_out(vty, " m3ua-client dest port %d%s", + ntohs(m3ua_client->remote.sin_port), VTY_NEWLINE); + vty_out(vty, " m3ua-client link-index %d%s", + m3ua_client->link_index, VTY_NEWLINE); + vty_out(vty, " m3ua-client routing-context %d%s", + m3ua_client->routing_context, VTY_NEWLINE); + break; case SS7_LTYPE_NONE: break; } @@ -573,7 +591,7 @@ DEFUN(cfg_linkset_link, cfg_linkset_link_cmd, } DEFUN(cfg_link_ss7_transport, cfg_link_ss7_transport_cmd, - "ss7-transport (none|udp|m2ua)", + "ss7-transport (none|udp|m2ua|m3ua-client)", "SS7 transport for the link\n" "No transport\n" "MTP over UDP\n" "SCTP M2UA\n") { @@ -586,6 +604,8 @@ DEFUN(cfg_link_ss7_transport, cfg_link_ss7_transport_cmd, wanted = SS7_LTYPE_UDP; else if (strcmp("m2ua", argv[0]) == 0) wanted = SS7_LTYPE_M2UA; + else if (strcmp("m3ua-client", argv[0]) == 0) + wanted = SS7_LTYPE_M3UA_CLIENT; if (link->type != wanted && link->type != SS7_LTYPE_NONE) { vty_out(vty, "%%Can not change the type of a link.\n"); @@ -599,6 +619,9 @@ DEFUN(cfg_link_ss7_transport, cfg_link_ss7_transport_cmd, case SS7_LTYPE_M2UA: link->data = mtp_m2ua_link_init(link); break; + case SS7_LTYPE_M3UA_CLIENT: + link->data = mtp_m3ua_client_link_init(link); + break; case SS7_LTYPE_NONE: /* nothing */ break; @@ -735,6 +758,131 @@ DEFUN(cfg_link_m2ua_link_index, cfg_link_m2ua_link_index_cmd, return CMD_SUCCESS; } + +DEFUN(cfg_link_m3ua_client_source_ip, cfg_link_m3ua_client_source_ip_cmd, + "m3ua-client source ip HOST_NAME", + "M3UA Client\n" "Source Address\n" "IP\n" "Hostname or IPv4 address\n") +{ + struct hostent *hosts; + + struct mtp_link *link = vty->index; + struct mtp_m3ua_client_link *m3ua_link; + + if (link->type != SS7_LTYPE_M3UA_CLIENT) { + vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + m3ua_link = link->data; + + talloc_free(m3ua_link->source); + m3ua_link->source = talloc_strdup(m3ua_link, argv[0]); + + hosts = gethostbyname(m3ua_link->source); + if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) { + vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + m3ua_link->local.sin_addr = * (struct in_addr *) hosts->h_addr_list[0]; + return CMD_SUCCESS; +} + +DEFUN(cfg_link_m3ua_client_source_port, cfg_link_m3ua_client_source_port_cmd, + "m3ua-client source port <1-65535>", + "M3UA Client\n" "Source Address\n" "Port\n" "Number\n") +{ + struct mtp_link *link = vty->index; + struct mtp_m3ua_client_link *m3ua_link; + + if (link->type != SS7_LTYPE_M3UA_CLIENT) { + vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + m3ua_link = link->data; + m3ua_link->local.sin_port = htons(atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(cfg_link_m3ua_client_dest_ip, cfg_link_m3ua_client_dest_ip_cmd, + "m3ua-client dest ip HOST_NAME", + "M3UA Client\n" "Destination Address\n" "IP\n" "Hostname or IPv4 address\n") +{ + struct hostent *hosts; + + struct mtp_link *link = vty->index; + struct mtp_m3ua_client_link *m3ua_link; + + if (link->type != SS7_LTYPE_M3UA_CLIENT) { + vty_out(vty, "%%This only applies to M3UA client links.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + m3ua_link = link->data; + + talloc_free(m3ua_link->dest); + m3ua_link->dest = talloc_strdup(m3ua_link, argv[0]); + + hosts = gethostbyname(m3ua_link->dest); + if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) { + vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + m3ua_link->remote.sin_addr = * (struct in_addr *) hosts->h_addr_list[0]; + return CMD_SUCCESS; +} + +DEFUN(cfg_link_m3ua_client_dest_port, cfg_link_m3ua_client_dest_port_cmd, + "m3ua-client dest port <1-65535>", + "M3UA Client\n" "Destination Address\n" "Port\n" "Number\n") +{ + struct mtp_link *link = vty->index; + struct mtp_m3ua_client_link *m3ua_link; + + if (link->type != SS7_LTYPE_M3UA_CLIENT) { + vty_out(vty, "%%This only applies to M3UA client links.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + m3ua_link = link->data; + m3ua_link->remote.sin_port = htons(atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(cfg_link_m3ua_client_link_index, cfg_link_m3ua_client_link_index_cmd, + "m3ua-client link-index <0-65535>", + "M3UA Client\n" "Link index\n" "Index\n") +{ + struct mtp_link *link = vty->index; + struct mtp_m3ua_client_link *m3ua_link; + + if (link->type != SS7_LTYPE_M3UA_CLIENT) { + vty_out(vty, "%%This only applies to M3UA client links.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + m3ua_link = link->data; + m3ua_link->link_index = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_link_m3ua_client_routing_ctx, cfg_link_m3ua_client_routing_ctx_cmd, + "m3ua-client routing-context <0-65535>", + "M3UA Client\n" "Routing Context\n" "Nunber\n") +{ + struct mtp_link *link = vty->index; + struct mtp_m3ua_client_link *m3ua_link; + + if (link->type != SS7_LTYPE_M3UA_CLIENT) { + vty_out(vty, "%%This only applies to M3UA client links.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + m3ua_link = link->data; + m3ua_link->routing_context = atoi(argv[0]); + return CMD_SUCCESS; +} + DEFUN(cfg_ss7_msc, cfg_ss7_msc_cmd, "msc <0-100>", "MSC Connection\n" "MSC Number\n") @@ -1151,6 +1299,12 @@ void cell_vty_init(void) install_element(LINK_NODE, &cfg_link_udp_link_index_cmd); install_element(LINK_NODE, &cfg_link_m2ua_as_cmd); install_element(LINK_NODE, &cfg_link_m2ua_link_index_cmd); + install_element(LINK_NODE, &cfg_link_m3ua_client_source_ip_cmd); + install_element(LINK_NODE, &cfg_link_m3ua_client_source_port_cmd); + install_element(LINK_NODE, &cfg_link_m3ua_client_dest_ip_cmd); + install_element(LINK_NODE, &cfg_link_m3ua_client_dest_port_cmd); + install_element(LINK_NODE, &cfg_link_m3ua_client_link_index_cmd); + install_element(LINK_NODE, &cfg_link_m3ua_client_routing_ctx_cmd); install_element(SS7_NODE, &cfg_ss7_msc_cmd); install_node(&msc_node, config_write_msc); |