--- embedaddon/bmon/src/in_sysctl.c 2012/02/21 22:19:56 1.1.1.1 +++ embedaddon/bmon/src/in_sysctl.c 2014/07/30 07:55:27 1.1.1.2 @@ -1,7 +1,10 @@ /* * in_sysctl.c sysctl (BSD) * + * $Id: in_sysctl.c,v 1.1.1.2 2014/07/30 07:55:27 misho Exp $ + * * Copyright (c) 2001-2004 Thomas Graf + * Copyright (c) 2014 Žilvinas Valinskas * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -24,9 +27,9 @@ #include #include -#include #include -#include +#include +#include #include #if defined SYS_BSD @@ -37,10 +40,106 @@ #include #include -static int c_debug; +static int c_debug = 0; +static struct element_group *grp; -static void sysctl_read(void) +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; @@ -49,7 +148,7 @@ static void sysctl_read(void) quit("sysctl() failed"); if (c_debug) - fprintf(stderr, "sysctl 1-pass n=%d\n", (int) n); + fprintf(stderr, "sysctl 1-pass n=%zd\n", n); buf = xcalloc(1, n); @@ -57,21 +156,20 @@ static void sysctl_read(void) quit("sysctl() failed"); if (c_debug) - fprintf(stderr, "sysctl 2-pass n=%d\n", (int) n); + fprintf(stderr, "sysctl 2-pass n=%zd\n", n); - lim = buf + n; - next = buf; - - while (next < lim) { + lim = (buf + n); + for (next = buf; next < lim; ) { + struct element *e, *e_parent = NULL; struct if_msghdr *ifm, *nextifm; struct sockaddr_dl *sdl; - item_t *it; 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) @@ -81,82 +179,83 @@ static void sysctl_read(void) sdl = (struct sockaddr_dl *) (ifm + 1); - if (sdl->sdl_family != AF_LINK) + if (!cfg_show_all && !(ifm->ifm_flags & IFF_UP)) continue; - if (get_show_only_running() && !(ifm->ifm_flags & IFF_UP)) + if (sdl->sdl_family != AF_LINK) continue; if (c_debug) fprintf(stderr, "Processing %s\n", sdl->sdl_data); - it = lookup_item(get_local_node(), sdl->sdl_data, 0, 0); - if (it == NULL) + sdl->sdl_data[sdl->sdl_nlen] = '\0'; + e = element_lookup(grp, + sdl->sdl_data, sdl->sdl_index, + e_parent, ELEMENT_CREAT); + if (!e) continue; - it->i_major_attr = BYTES; - it->i_minor_attr = PACKETS; + if (e->e_flags & ELEMENT_FLAG_CREATED) { + if (e->e_parent) + e->e_level = e->e_parent->e_level + 1; - update_attr(it, PACKETS, - ifm->ifm_data.ifi_ipackets, - ifm->ifm_data.ifi_opackets, - RX_PROVIDED | TX_PROVIDED); + if (element_set_key_attr(e, "bytes", "packets") || + element_set_usage_attr(e, "bytes")) + BUG(); - update_attr(it, BYTES, - ifm->ifm_data.ifi_ibytes, - ifm->ifm_data.ifi_obytes, - RX_PROVIDED | TX_PROVIDED); + e->e_flags &= ~ELEMENT_FLAG_CREATED; + } - update_attr(it, ERRORS, - ifm->ifm_data.ifi_ierrors, - ifm->ifm_data.ifi_oerrors, - RX_PROVIDED | TX_PROVIDED); + 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; - update_attr(it, COLLISIONS, - 0, ifm->ifm_data.ifi_collisions, - TX_PROVIDED); + if (m->rxid) { + rx = sysctl_get_stats(ifm, m->rxid); + flags |= UPDATE_FLAG_RX; + } - update_attr(it, MULTICAST, - ifm->ifm_data.ifi_imcasts, - 0, - RX_PROVIDED); + if (m->txid) { + tx = sysctl_get_stats(ifm, m->txid); + flags |= UPDATE_FLAG_TX; + } - update_attr(it, DROP, - 0, - ifm->ifm_data.ifi_iqdrops, - TX_PROVIDED); + attr_update(e, m->attrid, rx, tx, flags); + } - notify_update(it, NULL); - increase_lifetime(it, 1); + element_notify_update(e, NULL); + element_lifesign(e, 1); } xfree(buf); } -static void print_help(void) +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 \n" \ - "\n"); + "sysctl - sysctl statistic collector for BSD and Darwin\n" \ + "\n" \ + " BSD and Darwin statistic collector using sysctl()\n" \ + " Author: Thomas Graf \n" \ + "\n"); } -static void sysctl_set_opts(tv_t *attrs) +static void +sysctl_set_opts(const char* type, const char* value) { - while (attrs) { - if (!strcasecmp(attrs->type, "debug")) - c_debug = 1; - else if (!strcasecmp(attrs->type, "help")) { - print_help(); - exit(0); - } - attrs = attrs->next; + if (!strcasecmp(type, "debug")) + c_debug = 1; + else if (!strcasecmp(type, "help")) { + print_help(); + exit(0); } } -static int sysctl_probe(void) +static int +sysctl_probe(void) { size_t n; int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; @@ -165,16 +264,30 @@ static int sysctl_probe(void) return 1; } -static struct input_module kstat_ops = { - .im_name = "sysctl", - .im_read = sysctl_read, - .im_set_opts = sysctl_set_opts, - .im_probe = sysctl_probe, +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) +static void __init +sysctl_init(void) { - register_input_module(&kstat_ops); + input_register(&kstat_ops); } #endif