Change in osmo-sysmon[master]: Add ping probe support

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Mon Jan 28 14:28:11 UTC 2019


Max has uploaded this change for review. ( https://gerrit.osmocom.org/12710


Change subject: Add ping probe support
......................................................................

Add ping probe support

If liboping is available during ./configure than 'ping XXX' entries will
be supported in .cfg file, where XXX can be either IP address or FQDN.

Sample output:
...
  ping
    ya.ru
      IP: 2a02:6b8::2:242
      dropped: 3/3
    8.8.8.8
      IP: 8.8.8.8
      dropped: 0/3
      latency: 20.4 ms
      TTL: 120
...

N. B: to gather actual ping statistic we have to be able to send ICMP
requests (have enough privileges to work with RAW sockets).

Related: SYS#2655

Change-Id: Ife32540b532fb54368f63c78fb7837b84d4e8c76
---
M configure.ac
M src/Makefile.am
M src/osysmon.h
M src/osysmon_main.c
A src/osysmon_ping.c
5 files changed, 278 insertions(+), 1 deletion(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sysmon refs/changes/10/12710/1

diff --git a/configure.ac b/configure.ac
index 734ac99..be60a8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -111,6 +111,9 @@
    AC_SUBST([COVERAGE_LDFLAGS])
 fi
 
+PKG_CHECK_MODULES(LIBOPING, liboping, found_oping=yes, [AC_DEFINE([NO_OPING], [1], [Don't use liboping])])
+AM_CONDITIONAL(HAVE_OPING, test "$found_oping" = yes)
+
 AC_ARG_ENABLE(profile,
 		[AS_HELP_STRING([--enable-profile], [Compile with profiling support enabled], )],
 		[profile=$enableval], [profile="no"])
diff --git a/src/Makefile.am b/src/Makefile.am
index 412337b..2e5f260 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,6 +37,12 @@
 	osysmon_main.c \
 	$(NULL)
 
+if HAVE_OPING
+osmo_sysmon_SOURCES += osysmon_ping.c
+osmo_sysmon_LDADD += $(LIBOPING_LIBS)
+osmo_sysmon_CFLAGS = $(AM_CFLAGS) $(LIBOPING_CFLAGS)
+endif
+
 osmo_ctrl_client_SOURCES = \
 	simple_ctrl.c \
 	osmo-ctrl-client.c \
diff --git a/src/osysmon.h b/src/osysmon.h
index 735b11e..8b17972 100644
--- a/src/osysmon.h
+++ b/src/osysmon.h
@@ -6,9 +6,11 @@
 
 #include <stdbool.h>
 
+#include "config.h"
 #include "value_node.h"
 
 struct rtnl_client_state;
+struct ping_state;
 
 struct osysmon_state {
 	struct rtnl_client_state *rcs;
@@ -18,6 +20,7 @@
 	struct llist_head netdevs;
 	/* list of 'struct osysmon_file' */
 	struct llist_head files;
+	struct ping_state *pings;
 };
 
 extern struct osysmon_state *g_oss;
@@ -28,6 +31,7 @@
 	CTRL_CLIENT_NODE = _LAST_OSMOVTY_NODE + 1,
 	CTRL_CLIENT_GETVAR_NODE,
 	NETDEV_NODE,
+	PING_NODE,
 };
 
 
@@ -42,5 +46,8 @@
 int osysmon_sysinfo_init();
 int osysmon_sysinfo_poll(struct value_node *parent);
 
+int osysmon_ping_init();
+int osysmon_ping_poll(struct value_node *parent);
+
 int osysmon_file_init();
 int osysmon_file_poll(struct value_node *parent);
diff --git a/src/osysmon_main.c b/src/osysmon_main.c
index 82df61f..96dfa69 100644
--- a/src/osysmon_main.c
+++ b/src/osysmon_main.c
@@ -193,7 +193,7 @@
 
 int main(int argc, char **argv)
 {
-	int rc;
+	int rc, ping_init;
 
 	osmo_init_logging2(NULL, &log_info);
 
@@ -207,6 +207,9 @@
 	osysmon_sysinfo_init();
 	osysmon_ctrl_init();
 	osysmon_rtnl_init();
+#ifndef NO_OPING
+	ping_init = osysmon_ping_init();
+#endif
 	osysmon_file_init();
 
 	rc = vty_read_config_file(cmdline_opts.config_file, NULL);
@@ -233,6 +236,10 @@
 		osysmon_sysinfo_poll(root);
 		osysmon_ctrl_poll(root);
 		osysmon_rtnl_poll(root);
+#ifndef NO_OPING
+		if (ping_init == 0)
+			osysmon_ping_poll(root);
+#endif
 		osysmon_file_poll(root);
 
 		display_update(root);
diff --git a/src/osysmon_ping.c b/src/osysmon_ping.c
new file mode 100644
index 0000000..eaa3d1b
--- /dev/null
+++ b/src/osysmon_ping.c
@@ -0,0 +1,254 @@
+/* Simple Osmocom System Monitor (osysmon): Support for ping probe */
+
+/* (C) 2018 by sysmocom - s.f.m.c. GmbH.
+ * Author: Max Suraev
+ * All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301, USA.
+ */
+
+#include <stdbool.h>
+#include <errno.h>
+
+#include <oping.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/command.h>
+
+#include "osysmon.h"
+#include "value_node.h"
+
+/***********************************************************************
+ * Data model
+ ***********************************************************************/
+
+#define BUFLEN 128
+
+struct ping_state {
+       pingobj_t *ping_handle;
+};
+
+/* Workaround for liboping issue https://github.com/octo/liboping/issues/43 */
+static int add_host(pingobj_t *pinger, const char *host)
+{
+	int num_host = ping_iterator_count(pinger),
+		  rc = ping_host_add(pinger, host);
+
+	if (rc < 0) {
+		if (num_host != ping_iterator_count(pinger))
+			ping_host_remove(pinger, host);
+	}
+
+	return rc;
+}
+
+
+static bool add_drop(pingobj_iter_t *iter, struct value_node *vn_host)
+{
+	char *s = NULL;
+	uint32_t drop, seq;
+	size_t len = sizeof(drop);
+	int rc = ping_iterator_get_info(iter, PING_INFO_DROPPED, &drop, &len);
+	if (rc)
+		return false;
+
+	len = sizeof(seq);
+	rc = ping_iterator_get_info(iter, PING_INFO_SEQUENCE, &seq, &len);
+	if (rc)
+		return false;
+
+	osmo_talloc_asprintf(vn_host, s, "%u/%u", drop, seq);
+	value_node_add(vn_host, "dropped", s);
+
+	return true;
+}
+
+static bool add_ttl(pingobj_iter_t *iter, struct value_node *vn_host)
+{
+	int ttl, rc;
+	size_t len = sizeof(ttl);
+
+	rc = ping_iterator_get_info(iter, PING_INFO_RECV_TTL, &ttl, &len);
+	if (rc)
+		return false;
+
+	if (ttl > -1) {
+		char *s = NULL;
+		osmo_talloc_asprintf(vn_host, s, "%d", ttl);
+		value_node_add(vn_host, "TTL", s);
+	}
+
+	return true;
+}
+
+static bool add_latency(pingobj_iter_t *iter, struct value_node *vn_host)
+{
+	double latency;
+	size_t len = sizeof(latency);
+	int rc = ping_iterator_get_info(iter, PING_INFO_LATENCY, &latency, &len);
+	if (rc)
+		return false;
+
+	if (latency > -1) {
+		char *s = NULL;
+		osmo_talloc_asprintf(vn_host, s, "%.1lf ms", latency);
+		value_node_add(vn_host, "latency", s);
+	}
+
+	return true;
+}
+
+
+/***********************************************************************
+ * VTY
+ ***********************************************************************/
+
+static struct cmd_node ping_node = {
+	PING_NODE,
+	"%s(config-ping)# ",
+	1,
+};
+
+int osysmon_ping_go_parent(struct vty *vty)
+{
+	switch (vty->node) {
+	case PING_NODE:
+		vty->node = CONFIG_NODE;
+		vty->index = NULL;
+		break;
+	default:
+		break;
+	}
+	return vty->node;
+}
+
+#define PING_STR "Configure a host to be monitored/pinged\n"
+
+DEFUN(cfg_ping, cfg_ping_cmd,
+      "ping HOST",
+      PING_STR "Name of the host to ping\n")
+{
+	int rc = add_host(g_oss->pings->ping_handle, argv[0]);
+	if (rc < 0) {
+		vty_out(vty, "[%d] Couldn't add pinger for %s: %s%s",
+			ping_iterator_count(g_oss->pings->ping_handle), argv[0],
+			ping_get_error(g_oss->pings->ping_handle), VTY_NEWLINE);
+
+		return CMD_WARNING;
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_ping, cfg_no_ping_cmd,
+      "no ping HOST",
+      NO_STR PING_STR "Name of the host to ping\n")
+{
+	int rc = ping_host_remove(g_oss->pings->ping_handle, argv[0]);
+	if (rc < 0) {
+		vty_out(vty, "[%d] Couldn't remove %s pinger: %s%s",
+			ping_iterator_count(g_oss->pings->ping_handle), argv[0],
+			ping_get_error(g_oss->pings->ping_handle), VTY_NEWLINE);
+
+		return CMD_WARNING;
+	}
+
+	return CMD_SUCCESS;
+}
+
+static int config_write_ping(struct vty *vty)
+{
+	char buf[BUFLEN];
+	pingobj_iter_t *iter;
+	for (iter = ping_iterator_get(g_oss->pings->ping_handle); iter; iter = ping_iterator_next(iter)) {
+		size_t len = BUFLEN;
+		/* hostname as it was supplied via vty 'ping' entry */
+		if (ping_iterator_get_info(iter, PING_INFO_USERNAME, buf, &len))
+			return CMD_WARNING;
+
+		vty_out(vty, "ping %s%s", buf, VTY_NEWLINE);
+	}
+
+	return CMD_SUCCESS;
+}
+
+
+/***********************************************************************
+ * Runtime Code
+ ***********************************************************************/
+
+/* called once on startup before config file parsing */
+int osysmon_ping_init()
+{
+	install_element(CONFIG_NODE, &cfg_ping_cmd);
+	install_element(CONFIG_NODE, &cfg_no_ping_cmd);
+	install_node(&ping_node, config_write_ping);
+
+	g_oss->pings = talloc_zero(NULL, struct ping_state);
+	if (!g_oss->pings)
+		return -ENOMEM;
+
+	g_oss->pings->ping_handle = ping_construct();
+
+	if (g_oss->pings->ping_handle)
+		return 0;
+
+	return -EINVAL;
+}
+
+/* called periodically */
+int osysmon_ping_poll(struct value_node *parent)
+{
+	char buf[BUFLEN];
+	struct value_node *vn_host;
+	int num_host = ping_iterator_count(g_oss->pings->ping_handle);
+	pingobj_iter_t *iter;
+	struct value_node *vn_ping = value_node_add(parent, "ping", NULL);
+	if (!vn_ping)
+		return -ENOMEM;
+
+	for (iter = ping_iterator_get(g_oss->pings->ping_handle); iter; iter = ping_iterator_next(iter)) {
+		size_t len = BUFLEN;
+		int rc = ping_iterator_get_info(iter, PING_INFO_USERNAME, buf, &len);
+		if (rc)
+			return -EINVAL;
+
+		vn_host = value_node_find_or_add(vn_ping, talloc_strdup(vn_ping, buf));
+		if (!vn_host)
+			return -ENOMEM;
+
+		len = BUFLEN; /* IP address is looked up on-call, even 40 bytes should be enough */
+		rc = ping_iterator_get_info(iter, PING_INFO_ADDRESS, buf, &len);
+		if (rc)
+			return -EINVAL;
+
+		value_node_add(vn_host, "IP", buf);
+
+		add_drop(iter, vn_host);
+
+		/* Parameters below might be absent from output depending on the host reachability: */
+		add_latency(iter, vn_host);
+		add_ttl(iter, vn_host);
+	}
+
+	if (num_host)
+		return ping_send(g_oss->pings->ping_handle);
+
+	return 0;
+}

-- 
To view, visit https://gerrit.osmocom.org/12710
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sysmon
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ife32540b532fb54368f63c78fb7837b84d4e8c76
Gerrit-Change-Number: 12710
Gerrit-PatchSet: 1
Gerrit-Owner: Max <msuraev at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190128/f638b580/attachment.htm>


More information about the gerrit-log mailing list