summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2014-06-02 15:03:43 +0200
committerThomas Graf <tgraf@suug.ch>2014-06-02 15:03:43 +0200
commitee347743aedda321f5e0c24664d67e198ed70af8 (patch)
treebdb06efde359947e3e24a0d3bcda3b5279b1a39d
parentdeb1cd2aba61791a6dcb11679e867f0abb477eb4 (diff)
parentee98b9ea304744766e22ccc10899dadf71a361b8 (diff)
Merge branch 'macosx'
-rw-r--r--configure.ac8
-rw-r--r--include/bmon/config.h6
-rw-r--r--include/bmon/list.h8
-rw-r--r--src/Makefile.am1
-rw-r--r--src/in_netlink.c3
-rw-r--r--src/in_sysctl.c293
-rw-r--r--src/input.c7
-rw-r--r--src/module.c1
-rw-r--r--src/out_format.c4
9 files changed, 326 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac
index 6e7cc8c..bd1724f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,8 +69,12 @@ fi
PKG_CHECK_MODULES([CONFUSE], [libconfuse], [], AC_MSG_ERROR([requires libconfuse]))
-PKG_CHECK_MODULES([LIBNL], [libnl-3.0], [], AC_MSG_ERROR([requires libnl3-dev]))
-PKG_CHECK_MODULES([LIBNL_ROUTE], [libnl-route-3.0], [], AC_MSG_ERROR([requires libnl3-route]))
+case ${target_os} in
+ linux*)
+ PKG_CHECK_MODULES([LIBNL], [libnl-3.0], [], AC_MSG_ERROR([requires libnl3-dev]))
+ PKG_CHECK_MODULES([LIBNL_ROUTE], [libnl-route-3.0], [], AC_MSG_ERROR([requires libnl3-route]))
+ ;;
+esac
AC_CHECK_LIB(m, pow, [], AC_MSG_ERROR([requires libm]))
diff --git a/include/bmon/config.h b/include/bmon/config.h
index e717245..ad6a367 100644
--- a/include/bmon/config.h
+++ b/include/bmon/config.h
@@ -46,7 +46,11 @@
#include <syslog.h>
#include <sys/wait.h>
#include <dirent.h>
-#include <values.h>
+#ifdef SYS_BSD
+# include <float.h>
+#else
+# include <values.h>
+#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
diff --git a/include/bmon/list.h b/include/bmon/list.h
index c7569d7..fff9409 100644
--- a/include/bmon/list.h
+++ b/include/bmon/list.h
@@ -8,6 +8,14 @@
#ifndef BMON_LIST_H_
#define BMON_LIST_H_
+#ifdef __APPLE__
+/* Apple systems define these macros in system headers, so we undef
+ * them prior to inclusion of this file */
+#undef LIST_HEAD
+#undef LIST_HEAD_INIT
+#undef INIT_LIST_HEAD
+#endif
+
struct list_head
{
struct list_head * next;
diff --git a/src/Makefile.am b/src/Makefile.am
index dcc7bfd..c773410 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,7 @@ bmon_SOURCES = \
in_null.c \
in_dummy.c \
in_proc.c \
+ in_sysctl.c \
out_null.c \
out_format.c \
out_ascii.c \
diff --git a/src/in_netlink.c b/src/in_netlink.c
index 67f4a83..64021f5 100644
--- a/src/in_netlink.c
+++ b/src/in_netlink.c
@@ -31,6 +31,8 @@
#include <bmon/input.h>
#include <bmon/utils.h>
+#ifndef SYS_BSD
+
static int c_notc = 0;
static struct element_group *grp;
static struct bmon_module netlink_ops;
@@ -866,3 +868,4 @@ static void __init netlink_init(void)
{
input_register(&netlink_ops);
}
+#endif
diff --git a/src/in_sysctl.c b/src/in_sysctl.c
new file mode 100644
index 0000000..6583574
--- /dev/null
+++ b/src/in_sysctl.c
@@ -0,0 +1,293 @@
+/*
+ * in_sysctl.c sysctl (BSD)
+ *
+ * $Id: in_sysctl.c 20 2004-10-30 22:46:16Z tgr $
+ *
+ * Copyright (c) 2001-2004 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2014 Žilvinas Valinskas <zilvinas.valinskas@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <bmon/bmon.h>
+#include <bmon/input.h>
+#include <bmon/conf.h>
+#include <bmon/group.h>
+#include <bmon/element.h>
+#include <bmon/utils.h>
+
+#if defined SYS_BSD
+#include <sys/socket.h>
+#include <net/if.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+
+static int c_debug = 0;
+static struct element_group *grp;
+
+enum {
+ SYSCTL_RX_BYTES = 0x100,
+ SYSCTL_TX_BYTES,
+ SYSCTL_RX_PACKETS,
+ SYSCTL_TX_PACKETS,
+ SYSCTL_RX_ERRORS,
+ SYSCTL_TX_ERRORS,
+ SYSCTL_RX_DROPS,
+ SYSCTL_RX_MCAST,
+ SYSCTL_TX_MCAST,
+ SYSCTL_TX_COLLS,
+};
+static struct attr_map link_attrs[] = {
+{
+ .name = "bytes",
+ .type = ATTR_TYPE_COUNTER,
+ .unit = UNIT_BYTE,
+ .rxid = SYSCTL_RX_BYTES,
+ .txid = SYSCTL_TX_BYTES,
+ .description = "Bytes",
+},
+{
+ .name = "packets",
+ .type = ATTR_TYPE_COUNTER,
+ .unit = UNIT_NUMBER,
+ .rxid = SYSCTL_RX_PACKETS,
+ .txid = SYSCTL_TX_PACKETS,
+ .description = "Packets",
+},
+{
+ .name = "errors",
+ .type = ATTR_TYPE_COUNTER,
+ .unit = UNIT_NUMBER,
+ .rxid = SYSCTL_RX_ERRORS,
+ .txid = SYSCTL_TX_ERRORS,
+ .description = "Errors",
+},
+{
+ .name = "drop",
+ .type = ATTR_TYPE_COUNTER,
+ .unit = UNIT_NUMBER,
+ .rxid = SYSCTL_RX_DROPS,
+ .description = "Dropped",
+},
+{
+ .name = "coll",
+ .type = ATTR_TYPE_COUNTER,
+ .unit = UNIT_NUMBER,
+ .txid = SYSCTL_TX_COLLS,
+ .description = "Collisions",
+},
+{
+ .name = "mcast",
+ .type = ATTR_TYPE_COUNTER,
+ .unit = UNIT_NUMBER,
+ .rxid = SYSCTL_RX_MCAST,
+ .txid = SYSCTL_TX_MCAST,
+ .description = "Multicast",
+}
+};
+
+uint64_t sysctl_get_stats(const struct if_msghdr *ifm, int what)
+{
+ switch(what) {
+ case SYSCTL_RX_BYTES:
+ return ifm->ifm_data.ifi_ibytes;
+ case SYSCTL_TX_BYTES:
+ return ifm->ifm_data.ifi_obytes;
+
+ case SYSCTL_RX_PACKETS:
+ return ifm->ifm_data.ifi_ipackets;
+ case SYSCTL_TX_PACKETS:
+ return ifm->ifm_data.ifi_opackets;
+
+ case SYSCTL_RX_ERRORS:
+ return ifm->ifm_data.ifi_ierrors;
+ case SYSCTL_TX_ERRORS:
+ return ifm->ifm_data.ifi_oerrors;
+
+ case SYSCTL_RX_DROPS:
+ return ifm->ifm_data.ifi_iqdrops;
+
+ case SYSCTL_RX_MCAST:
+ return ifm->ifm_data.ifi_imcasts;
+ case SYSCTL_TX_MCAST:
+ return ifm->ifm_data.ifi_omcasts;
+ case SYSCTL_TX_COLLS:
+ return ifm->ifm_data.ifi_collisions;
+
+ default:
+ return 0;
+ };
+}
+
+static void
+sysctl_read(void)
+{
+ int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
+ size_t n;
+ char *buf, *next, *lim;
+
+ if (sysctl(mib, 6, NULL, &n, NULL, 0) < 0)
+ quit("sysctl() failed");
+
+ if (c_debug)
+ fprintf(stderr, "sysctl 1-pass n=%zd\n", n);
+
+ buf = xcalloc(1, n);
+
+ if (sysctl(mib, 6, buf, &n, NULL, 0) < 0)
+ quit("sysctl() failed");
+
+ if (c_debug)
+ fprintf(stderr, "sysctl 2-pass n=%zd\n", n);
+
+ lim = (buf + n);
+ for (next = buf; next < lim; ) {
+ struct element *e, *e_parent = NULL;
+ struct if_msghdr *ifm, *nextifm;
+ struct sockaddr_dl *sdl;
+
+ ifm = (struct if_msghdr *) next;
+ if (ifm->ifm_type != RTM_IFINFO)
+ break;
+
+ next += ifm->ifm_msglen;
+
+ while (next < lim) {
+ nextifm = (struct if_msghdr *) next;
+ if (nextifm->ifm_type != RTM_NEWADDR)
+ break;
+ next += nextifm->ifm_msglen;
+ }
+
+ sdl = (struct sockaddr_dl *) (ifm + 1);
+
+ if (!cfg_show_all && !(ifm->ifm_flags & IFF_UP))
+ continue;
+
+ if (sdl->sdl_family != AF_LINK)
+ continue;
+
+ if (c_debug)
+ fprintf(stderr, "Processing %s\n", sdl->sdl_data);
+
+ sdl->sdl_data[sdl->sdl_nlen] = '\0';
+ e = element_lookup(grp,
+ sdl->sdl_data, sdl->sdl_index,
+ e_parent, ELEMENT_CREAT);
+ if (!e)
+ continue;
+
+ if (e->e_flags & ELEMENT_FLAG_CREATED) {
+ if (e->e_parent)
+ e->e_level = e->e_parent->e_level + 1;
+
+ if (element_set_key_attr(e, "bytes", "packets") ||
+ element_set_usage_attr(e, "bytes"))
+ BUG();
+
+ e->e_flags &= ~ELEMENT_FLAG_CREATED;
+ }
+
+ int i;
+ for (i = 0; i < ARRAY_SIZE(link_attrs); i++) {
+ struct attr_map *m = &link_attrs[i];
+ uint64_t rx = 0, tx = 0;
+ int flags = 0;
+
+ if (m->rxid) {
+ rx = sysctl_get_stats(ifm, m->rxid);
+ flags |= UPDATE_FLAG_RX;
+ }
+
+ if (m->txid) {
+ tx = sysctl_get_stats(ifm, m->txid);
+ flags |= UPDATE_FLAG_TX;
+ }
+
+ attr_update(e, m->attrid, rx, tx, flags);
+ }
+
+ element_notify_update(e, NULL);
+ element_lifesign(e, 1);
+ }
+
+ xfree(buf);
+}
+
+static void
+print_help(void)
+{
+ printf(
+ "sysctl - sysctl statistic collector for BSD and Darwin\n" \
+ "\n" \
+ " BSD and Darwin statistic collector using sysctl()\n" \
+ " Author: Thomas Graf <tgraf@suug.ch>\n" \
+ "\n");
+}
+
+static void
+sysctl_set_opts(const char* type, const char* value)
+{
+ if (!strcasecmp(type, "debug"))
+ c_debug = 1;
+ else if (!strcasecmp(type, "help")) {
+ print_help();
+ exit(0);
+ }
+}
+
+static int
+sysctl_probe(void)
+{
+ size_t n;
+ int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
+ if (sysctl(mib, 6, NULL, &n, NULL, 0) < 0)
+ return 0;
+ return 1;
+}
+
+static int sysctl_do_init(void)
+{
+ if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)))
+ BUG();
+
+ grp = group_lookup(DEFAULT_GROUP, GROUP_CREATE);
+ if (!grp)
+ BUG();
+
+ return 0;
+}
+
+static struct bmon_module kstat_ops = {
+ .m_name = "sysctl",
+ .m_do = sysctl_read,
+ .m_parse_opt = sysctl_set_opts,
+ .m_probe = sysctl_probe,
+ .m_init = sysctl_do_init,
+};
+
+static void __init
+sysctl_init(void)
+{
+ input_register(&kstat_ops);
+}
+
+#endif
diff --git a/src/input.c b/src/input.c
index f4afac7..4a7d4ca 100644
--- a/src/input.c
+++ b/src/input.c
@@ -44,11 +44,18 @@ static void activate_default(void)
if (!input_subsys.s_nmod) {
struct bmon_module *m;
+#ifdef SYS_LINUX
if (!input_set("netlink"))
return;
if (!input_set("proc"))
return;
+#endif
+
+#ifdef SYS_BSD
+ if (!input_set("sysctl"))
+ return;
+#endif
/* Fall back to anything that could act as default */
list_for_each_entry(m, &input_subsys.s_mod_list, m_list) {
diff --git a/src/module.c b/src/module.c
index 5727e58..b245f72 100644
--- a/src/module.c
+++ b/src/module.c
@@ -115,6 +115,7 @@ int module_register(struct bmon_subsys *ss, struct bmon_module *m)
list_add_tail(&m->m_list, &ss->s_mod_list);
m->m_subsys = ss;
+ return 0;
}
static void __auto_load(struct bmon_module *m)
diff --git a/src/out_format.c b/src/out_format.c
index bfe29a5..19c588f 100644
--- a/src/out_format.c
+++ b/src/out_format.c
@@ -126,10 +126,10 @@ static char *get_token(struct element_group *g, struct element *e,
}
if (!strncasecmp(type, "rx:", 3)) {
- snprintf(buf, len, "%lu", a->a_rx_rate.r_total);
+ snprintf(buf, len, "%llu", a->a_rx_rate.r_total);
return buf;
} else if (!strncasecmp(type, "tx:", 3)) {
- snprintf(buf, len, "%lu", a->a_tx_rate.r_total);
+ snprintf(buf, len, "%llu", a->a_tx_rate.r_total);
return buf;
} else if (!strncasecmp(type, "rxrate:", 7)) {
snprintf(buf, len, "%.2f", a->a_rx_rate.r_rate);