diff options
author | Thomas Graf <tgraf@suug.ch> | 2014-06-02 15:03:43 +0200 |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2014-06-02 15:03:43 +0200 |
commit | ee347743aedda321f5e0c24664d67e198ed70af8 (patch) | |
tree | bdb06efde359947e3e24a0d3bcda3b5279b1a39d | |
parent | deb1cd2aba61791a6dcb11679e867f0abb477eb4 (diff) | |
parent | ee98b9ea304744766e22ccc10899dadf71a361b8 (diff) |
Merge branch 'macosx'
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | include/bmon/config.h | 6 | ||||
-rw-r--r-- | include/bmon/list.h | 8 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/in_netlink.c | 3 | ||||
-rw-r--r-- | src/in_sysctl.c | 293 | ||||
-rw-r--r-- | src/input.c | 7 | ||||
-rw-r--r-- | src/module.c | 1 | ||||
-rw-r--r-- | src/out_format.c | 4 |
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); |