|
version 1.1.1.1, 2012/02/21 22:19:56
|
version 1.1.1.3, 2019/10/21 14:58:35
|
|
Line 1
|
Line 1
|
| /* |
/* |
| * in_sysctl.c sysctl (BSD) |
* in_sysctl.c sysctl (BSD) |
| * |
* |
| |
* $Id$ |
| |
* |
| * Copyright (c) 2001-2004 Thomas Graf <tgraf@suug.ch> |
* 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 |
* Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
* copy of this software and associated documentation files (the "Software"), |
|
Line 24
|
Line 27
|
| |
|
| #include <bmon/bmon.h> |
#include <bmon/bmon.h> |
| #include <bmon/input.h> |
#include <bmon/input.h> |
| #include <bmon/item.h> |
|
| #include <bmon/conf.h> |
#include <bmon/conf.h> |
| #include <bmon/node.h> | #include <bmon/group.h> |
| | #include <bmon/element.h> |
| #include <bmon/utils.h> |
#include <bmon/utils.h> |
| |
|
| #if defined SYS_BSD |
#if defined SYS_BSD |
|
Line 37
|
Line 40
|
| #include <net/if_dl.h> |
#include <net/if_dl.h> |
| #include <net/route.h> |
#include <net/route.h> |
| |
|
| 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}; |
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; |
| size_t n; |
size_t n; |
| char *buf, *next, *lim; |
char *buf, *next, *lim; |
|
Line 49 static void sysctl_read(void)
|
Line 148 static void sysctl_read(void)
|
| quit("sysctl() failed"); |
quit("sysctl() failed"); |
| |
|
| if (c_debug) |
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); |
buf = xcalloc(1, n); |
| |
|
|
Line 57 static void sysctl_read(void)
|
Line 156 static void sysctl_read(void)
|
| quit("sysctl() failed"); |
quit("sysctl() failed"); |
| |
|
| if (c_debug) |
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; | lim = (buf + n); |
| next = buf; | for (next = buf; next < lim; ) { |
| struct element *e, *e_parent = NULL; |
| while (next < lim) { | |
| struct if_msghdr *ifm, *nextifm; |
struct if_msghdr *ifm, *nextifm; |
| struct sockaddr_dl *sdl; |
struct sockaddr_dl *sdl; |
| item_t *it; | char info_buf[64]; |
| |
|
| ifm = (struct if_msghdr *) next; |
ifm = (struct if_msghdr *) next; |
| if (ifm->ifm_type != RTM_IFINFO) |
if (ifm->ifm_type != RTM_IFINFO) |
| break; |
break; |
| |
|
| next += ifm->ifm_msglen; |
next += ifm->ifm_msglen; |
| |
|
| while (next < lim) { |
while (next < lim) { |
| nextifm = (struct if_msghdr *) next; |
nextifm = (struct if_msghdr *) next; |
| if (nextifm->ifm_type != RTM_NEWADDR) |
if (nextifm->ifm_type != RTM_NEWADDR) |
|
Line 81 static void sysctl_read(void)
|
Line 180 static void sysctl_read(void)
|
| |
|
| sdl = (struct sockaddr_dl *) (ifm + 1); |
sdl = (struct sockaddr_dl *) (ifm + 1); |
| |
|
| if (sdl->sdl_family != AF_LINK) | if (!cfg_show_all && !(ifm->ifm_flags & IFF_UP)) |
| continue; |
continue; |
| |
|
| if (get_show_only_running() && !(ifm->ifm_flags & IFF_UP)) | if (sdl->sdl_family != AF_LINK) |
| continue; |
continue; |
| |
|
| if (c_debug) |
if (c_debug) |
| fprintf(stderr, "Processing %s\n", sdl->sdl_data); |
fprintf(stderr, "Processing %s\n", sdl->sdl_data); |
| |
|
| it = lookup_item(get_local_node(), sdl->sdl_data, 0, 0); | sdl->sdl_data[sdl->sdl_nlen] = '\0'; |
| if (it == NULL) | e = element_lookup(grp, |
| | sdl->sdl_data, sdl->sdl_index, |
| | e_parent, ELEMENT_CREAT); |
| | if (!e) |
| continue; |
continue; |
| |
|
| it->i_major_attr = BYTES; | if (e->e_flags & ELEMENT_FLAG_CREATED) { |
| it->i_minor_attr = PACKETS; | if (e->e_parent) |
| | e->e_level = e->e_parent->e_level + 1; |
| |
|
| update_attr(it, PACKETS, | if (element_set_key_attr(e, "bytes", "packets") || |
| ifm->ifm_data.ifi_ipackets, | element_set_usage_attr(e, "bytes")) |
| ifm->ifm_data.ifi_opackets, | BUG(); |
| RX_PROVIDED | TX_PROVIDED); | |
| |
|
| update_attr(it, BYTES, | e->e_flags &= ~ELEMENT_FLAG_CREATED; |
| ifm->ifm_data.ifi_ibytes, | } |
| ifm->ifm_data.ifi_obytes, | |
| RX_PROVIDED | TX_PROVIDED); | |
| |
|
| update_attr(it, ERRORS, | int i; |
| ifm->ifm_data.ifi_ierrors, | for (i = 0; i < ARRAY_SIZE(link_attrs); i++) { |
| ifm->ifm_data.ifi_oerrors, | struct attr_map *m = &link_attrs[i]; |
| RX_PROVIDED | TX_PROVIDED); | uint64_t rx = 0, tx = 0; |
| | int flags = 0; |
| |
|
| update_attr(it, COLLISIONS, | if (m->rxid) { |
| 0, ifm->ifm_data.ifi_collisions, | rx = sysctl_get_stats(ifm, m->rxid); |
| TX_PROVIDED); | flags |= UPDATE_FLAG_RX; |
| | } |
| |
|
| update_attr(it, MULTICAST, | if (m->txid) { |
| ifm->ifm_data.ifi_imcasts, | tx = sysctl_get_stats(ifm, m->txid); |
| 0, | flags |= UPDATE_FLAG_TX; |
| RX_PROVIDED); | } |
| |
|
| update_attr(it, DROP, | attr_update(e, m->attrid, rx, tx, flags); |
| 0, | } |
| ifm->ifm_data.ifi_iqdrops, | |
| TX_PROVIDED); | |
| |
|
| notify_update(it, NULL); | snprintf(info_buf, sizeof(info_buf), "%ju", (uintmax_t)ifm->ifm_data.ifi_mtu); |
| increase_lifetime(it, 1); | element_update_info(e, "MTU", info_buf); |
| | |
| | snprintf(info_buf, sizeof(info_buf), "%ju", (uintmax_t)ifm->ifm_data.ifi_metric); |
| | element_update_info(e, "Metric", info_buf); |
| | |
| | #if !(defined(__NetBSD__) || defined(__FreeBSD__)) |
| | snprintf(info_buf, sizeof(info_buf), "%u", ifm->ifm_data.ifi_recvquota); |
| | element_update_info(e, "RX-Quota", info_buf); |
| | |
| | snprintf(info_buf, sizeof(info_buf), "%u", ifm->ifm_data.ifi_xmitquota); |
| | element_update_info(e, "TX-Quota", info_buf); |
| | #endif |
| | |
| | element_notify_update(e, NULL); |
| | element_lifesign(e, 1); |
| } |
} |
| |
|
| xfree(buf); |
xfree(buf); |
| } |
} |
| |
|
| static void print_help(void) | static void |
| | print_help(void) |
| { |
{ |
| printf( |
printf( |
| "sysctl - sysctl statistic collector for BSD and Darwin\n" \ | "sysctl - sysctl statistic collector for BSD and Darwin\n" \ |
| "\n" \ | "\n" \ |
| " BSD and Darwin statistic collector using sysctl()\n" \ | " BSD and Darwin statistic collector using sysctl()\n" \ |
| " Author: Thomas Graf <tgraf@suug.ch>\n" \ | " Author: Thomas Graf <tgraf@suug.ch>\n" \ |
| "\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(type, "debug")) |
| if (!strcasecmp(attrs->type, "debug")) | c_debug = 1; |
| c_debug = 1; | else if (!strcasecmp(type, "help")) { |
| else if (!strcasecmp(attrs->type, "help")) { | print_help(); |
| print_help(); | exit(0); |
| exit(0); | |
| } | |
| attrs = attrs->next; | |
| } |
} |
| } |
} |
| |
|
| static int sysctl_probe(void) | static int |
| | sysctl_probe(void) |
| { |
{ |
| size_t n; |
size_t n; |
| int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; |
int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; |
|
Line 165 static int sysctl_probe(void)
|
Line 279 static int sysctl_probe(void)
|
| return 1; |
return 1; |
| } |
} |
| |
|
| static struct input_module kstat_ops = { | static int sysctl_do_init(void) |
| .im_name = "sysctl", | { |
| .im_read = sysctl_read, | if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs))) |
| .im_set_opts = sysctl_set_opts, | BUG(); |
| .im_probe = sysctl_probe, | |
| | 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 |
#endif |