Add VTY command
line vty
bind A.B.C.D
The command merely stores the configured IP-address, which can then be used by
the calling main program to set the telnet port of the VTY line. (Commits in
openbsc and osmo-iuh will follow up on this.)
Add function vty_get_bind_addr() to publish the address in the vty.h API.
Add static vty_bind_addr to store.
For allocation/freeing reasons, a NULL address defaults to 127.0.0.1.
BTW, I decided against allowing keywords 'any' and 'localhost' in place of an
actual IP address to make sure a written config is always identical to the
parsed config.
---
include/osmocom/vty/vty.h | 3 +++
src/vty/vty.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/include/osmocom/vty/vty.h b/include/osmocom/vty/vty.h
index 3684397..43cb0cf 100644
--- a/include/osmocom/vty/vty.h
+++ b/include/osmocom/vty/vty.h
@@ -186,6 +186,9 @@ void *vty_current_index(struct vty *);
int vty_current_node(struct vty *vty);
int vty_go_parent(struct vty *vty);
+/* Return IP address passed to the 'line vty'/'bind' command, or "127.0.0.1" */
+const char *vty_get_bind_addr(void);
+
extern void *tall_vty_ctx;
extern struct cmd_element cfg_description_cmd;
diff --git a/src/vty/vty.c b/src/vty/vty.c
index 5bcbe4a..7e27d7e 100644
--- a/src/vty/vty.c
+++ b/src/vty/vty.c
@@ -75,6 +75,10 @@ vector Vvty_serv_thread;
char *vty_cwd = NULL;
+/* IP address passed to the 'line vty'/'bind' command */
+static const char *vty_bind_addr = NULL;
+#define VTY_BIND_ADDR_DEFAULT "127.0.0.1"
+
/* Configure lock. */
static int vty_config;
@@ -1585,6 +1589,29 @@ DEFUN(no_vty_login,
return CMD_SUCCESS;
}
+/* vty bind */
+DEFUN(vty_bind, vty_bind_cmd, "bind A.B.C.D",
+ "Accept VTY telnet connections on local interface\n"
+ "Local interface IP address (default: " VTY_BIND_ADDR_DEFAULT ")\n")
+{
+ /* Avoid (small) mem leak: initially, vty_bind_addr is NULL. Whenever
+ * this gets called, it is set to a strdup. So whenever it is non-NULL,
+ * free it first. See also vty_get_bind_addr() for the NULL default. */
+ if (vty_bind_addr) {
+ talloc_free((void*)vty_bind_addr);
+ vty_bind_addr = NULL;
+ }
+ vty_bind_addr = talloc_strdup(tall_vty_ctx, argv[0]);
+ return CMD_SUCCESS;
+}
+
+const char *vty_get_bind_addr(void)
+{
+ if (!vty_bind_addr)
+ return VTY_BIND_ADDR_DEFAULT;
+ return vty_bind_addr;
+}
+
DEFUN(service_advanced_vty,
service_advanced_vty_cmd,
"service advanced-vty",
@@ -1654,6 +1681,10 @@ static int vty_config_write(struct vty *vty)
if (!password_check)
vty_out(vty, " no login%s", VTY_NEWLINE);
+ /* bind */
+ if (vty_bind_addr)
+ vty_out(vty, " bind %s%s", vty_bind_addr, VTY_NEWLINE);
+
vty_out(vty, "!%s", VTY_NEWLINE);
return CMD_SUCCESS;
@@ -1757,6 +1788,7 @@ void vty_init(struct vty_app_info *app_info)
vty_install_default(VTY_NODE);
install_element(VTY_NODE, &vty_login_cmd);
install_element(VTY_NODE, &no_vty_login_cmd);
+ install_element(VTY_NODE, &vty_bind_cmd);
}
/*! \brief Read the configuration file using the VTY code
--
2.1.4
Abort upon unknown options and missing option arguments. This came to my
attention while rewiring the -m and -M options: passing -M without argument
would launch nitb with wrong configuration. So, rather exit immediately.
If there are legacy options that should be ignored, they deserve an own 'case:'
in the option switch. There are none that I'm aware of though.
---
openbsc/src/osmo-nitb/bsc_hack.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/openbsc/src/osmo-nitb/bsc_hack.c b/openbsc/src/osmo-nitb/bsc_hack.c
index a89300a..6f8da98 100644
--- a/openbsc/src/osmo-nitb/bsc_hack.c
+++ b/openbsc/src/osmo-nitb/bsc_hack.c
@@ -187,7 +187,9 @@ static void handle_options(int argc, char **argv)
rf_ctrl_path = optarg;
break;
default:
- /* ignore */
+ /* catch unknown options *as well as* missing arguments. */
+ fprintf(stderr, "Error in command line options. Abort.\n");
+ exit(-1);
break;
}
}
--
2.1.4
Following the 'line vty'/'bind A.B.C.D' command added in libosmocore, use the
configured address to set the telnet bind for the VTY line. It is now possible
to publish the VTY on a specific local interface (including 0.0.0.0 aka "any").
Implement in all of:
osmo-gbproxy
osmo-gtphub
osmo-sgsn
osmo-bsc
osmo-bsc_nat
osmo-bsc_mgcp
osmo-nitb
In some of these main programs, move the telnet initialization below the
configuration parsing.
Historically, this was not a good idea for programs using bsc_init.c (aka
bsc_bootstrap_network()), since they expected a gsm_network struct pointer in
((struct telnet_connection*)vty->priv)->priv, so that telnet had to be either
initialized or replaced by a dummy struct. In the meantime, the gsm_network
struct is not actually looked up in a priv pointer but in the static bsc_vty.c
scope (bsc_gsmnet), so this limitation is mere legacy (even though said legacy
is still there in an "#if 0" chunk).
In the other binaries I have briefly looked at the init sequence dependencies
and found no reason to initialize telnet above the config file parsing. In any
case, I have tested every single one of abovementioned binaries to verify that
they still parse the example config successfully and launch, allowing VTY
connections on the configured address(es). I hope this suffices.
In all of the above, log VTY address and port. LOGL_INFO is disabled by default
in some of the logging scopes, and since it is a single log message right at
program launch, I decided for the slightly more aggressive LOGL_NOTICE.
---
openbsc/src/gprs/gb_proxy_main.c | 12 ++++++++----
openbsc/src/gprs/gtphub_main.c | 11 ++++++++---
openbsc/src/gprs/sgsn_main.c | 11 ++++++++---
openbsc/src/libbsc/bsc_init.c | 6 +++++-
openbsc/src/osmo-bsc_mgcp/mgcp_main.c | 6 +++++-
openbsc/src/osmo-bsc_nat/bsc_nat.c | 7 ++++++-
6 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c
index f82fb5b..0c3cfbe 100644
--- a/openbsc/src/gprs/gb_proxy_main.c
+++ b/openbsc/src/gprs/gb_proxy_main.c
@@ -252,10 +252,6 @@ int main(int argc, char **argv)
rate_ctr_init(tall_bsc_ctx);
osmo_stats_init(tall_bsc_ctx);
- rc = telnet_init(tall_bsc_ctx, &dummy_network, OSMO_VTY_PORT_GBPROXY);
- if (rc < 0)
- exit(1);
-
bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_bsc_ctx);
if (!bssgp_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
@@ -274,6 +270,14 @@ int main(int argc, char **argv)
exit(2);
}
+ /* start telnet after reading config for vty_get_bind_addr() */
+ LOGP(DGPRS, LOGL_NOTICE, "VTY at %s %d\n",
+ vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
+ rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network,
+ vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
+ if (rc < 0)
+ exit(1);
+
if (!gprs_nsvc_by_nsei(gbcfg.nsi, gbcfg.nsip_sgsn_nsei)) {
LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u "
"without creating that NSEI before\n",
diff --git a/openbsc/src/gprs/gtphub_main.c b/openbsc/src/gprs/gtphub_main.c
index f18710d..89582b1 100644
--- a/openbsc/src/gprs/gtphub_main.c
+++ b/openbsc/src/gprs/gtphub_main.c
@@ -314,9 +314,6 @@ int main(int argc, char **argv)
gtphub_vty_init(hub, cfg);
rate_ctr_init(osmo_gtphub_ctx);
- rc = telnet_init(osmo_gtphub_ctx, 0, OSMO_VTY_PORT_GTPHUB);
- if (rc < 0)
- exit(1);
handle_options(ccfg, argc, argv);
@@ -327,6 +324,14 @@ int main(int argc, char **argv)
exit(2);
}
+ /* start telnet after reading config for vty_get_bind_addr() */
+ LOGP(DGTPHUB, LOGL_NOTICE, "VTY at %s %d\n",
+ vty_get_bind_addr(), OSMO_VTY_PORT_GTPHUB);
+ rc = telnet_init_dynif(osmo_gtphub_ctx, 0, vty_get_bind_addr(),
+ OSMO_VTY_PORT_GTPHUB);
+ if (rc < 0)
+ exit(1);
+
if (gtphub_start(hub, cfg,
next_restart_count(ccfg->restart_counter_file))
!= 0)
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 2d3a0e4..b10b0b3 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -315,9 +315,6 @@ int main(int argc, char **argv)
handle_options(argc, argv);
rate_ctr_init(tall_bsc_ctx);
- rc = telnet_init(tall_bsc_ctx, &dummy_network, OSMO_VTY_PORT_SGSN);
- if (rc < 0)
- exit(1);
ctrl = sgsn_controlif_setup(NULL, OSMO_CTRL_PORT_SGSN);
if (!ctrl) {
@@ -357,6 +354,14 @@ int main(int argc, char **argv)
exit(2);
}
+ /* start telnet after reading config for vty_get_bind_addr() */
+ LOGP(DGPRS, LOGL_NOTICE, "VTY at %s %d\n",
+ vty_get_bind_addr(), OSMO_VTY_PORT_SGSN);
+ rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network,
+ vty_get_bind_addr(), OSMO_VTY_PORT_SGSN);
+ if (rc < 0)
+ exit(1);
+
rc = sgsn_gtp_init(&sgsn_inst);
if (rc) {
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on GTP socket\n");
diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c
index 743f4c1..859d999 100644
--- a/openbsc/src/libbsc/bsc_init.c
+++ b/openbsc/src/libbsc/bsc_init.c
@@ -495,7 +495,11 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *),
return rc;
}
- rc = telnet_init(tall_bsc_ctx, bsc_gsmnet, OSMO_VTY_PORT_NITB_BSC);
+ /* start telnet after reading config for vty_get_bind_addr() */
+ LOGP(DNM, LOGL_NOTICE, "VTY at %s %d\n",
+ vty_get_bind_addr(), OSMO_VTY_PORT_NITB_BSC);
+ rc = telnet_init_dynif(tall_bsc_ctx, bsc_gsmnet, vty_get_bind_addr(),
+ OSMO_VTY_PORT_NITB_BSC);
if (rc < 0)
return rc;
diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c
index d755c90..e226b02 100644
--- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c
+++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c
@@ -232,7 +232,11 @@ int main(int argc, char **argv)
if (rc < 0)
return rc;
- rc = telnet_init(tall_bsc_ctx, &dummy_network, OSMO_VTY_PORT_BSC_MGCP);
+ /* start telnet after reading config for vty_get_bind_addr() */
+ LOGP(DMGCP, LOGL_NOTICE, "VTY at %s %d\n",
+ vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP);
+ rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network,
+ vty_get_bind_addr(), OSMO_VTY_PORT_BSC_MGCP);
if (rc < 0)
return rc;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index 41291d9..e3dc10e 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -1628,12 +1628,17 @@ int main(int argc, char **argv)
osmo_stats_init(tall_bsc_ctx);
/* init vty and parse */
- telnet_init(tall_bsc_ctx, NULL, OSMO_VTY_PORT_BSC_NAT);
if (mgcp_parse_config(config_file, nat->mgcp_cfg, MGCP_BSC_NAT) < 0) {
fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
return -3;
}
+ /* start telnet after reading config for vty_get_bind_addr() */
+ LOGP(DNAT, LOGL_NOTICE, "VTY at %s %d\n",
+ vty_get_bind_addr(), OSMO_VTY_PORT_BSC_NAT);
+ telnet_init_dynif(tall_bsc_ctx, NULL, vty_get_bind_addr(),
+ OSMO_VTY_PORT_BSC_NAT);
+
/* over rule the VTY config */
if (msc_ip)
bsc_nat_set_msc_ip(nat, msc_ip);
--
2.1.4