Annotation of embedaddon/bmon/src/in_sysctl.c, revision 1.1.1.2
1.1 misho 1: /*
2: * in_sysctl.c sysctl (BSD)
3: *
1.1.1.2 ! misho 4: * $Id: in_sysctl.c 20 2004-10-30 22:46:16Z tgr $
! 5: *
1.1 misho 6: * Copyright (c) 2001-2004 Thomas Graf <tgraf@suug.ch>
1.1.1.2 ! misho 7: * Copyright (c) 2014 Žilvinas Valinskas <zilvinas.valinskas@gmail.com>
1.1 misho 8: *
9: * Permission is hereby granted, free of charge, to any person obtaining a
10: * copy of this software and associated documentation files (the "Software"),
11: * to deal in the Software without restriction, including without limitation
12: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13: * and/or sell copies of the Software, and to permit persons to whom the
14: * Software is furnished to do so, subject to the following conditions:
15: *
16: * The above copyright notice and this permission notice shall be included
17: * in all copies or substantial portions of the Software.
18: *
19: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25: * DEALINGS IN THE SOFTWARE.
26: */
27:
28: #include <bmon/bmon.h>
29: #include <bmon/input.h>
30: #include <bmon/conf.h>
1.1.1.2 ! misho 31: #include <bmon/group.h>
! 32: #include <bmon/element.h>
1.1 misho 33: #include <bmon/utils.h>
34:
35: #if defined SYS_BSD
36: #include <sys/socket.h>
37: #include <net/if.h>
38: #include <sys/param.h>
39: #include <sys/sysctl.h>
40: #include <net/if_dl.h>
41: #include <net/route.h>
42:
1.1.1.2 ! misho 43: static int c_debug = 0;
! 44: static struct element_group *grp;
! 45:
! 46: enum {
! 47: SYSCTL_RX_BYTES = 0x100,
! 48: SYSCTL_TX_BYTES,
! 49: SYSCTL_RX_PACKETS,
! 50: SYSCTL_TX_PACKETS,
! 51: SYSCTL_RX_ERRORS,
! 52: SYSCTL_TX_ERRORS,
! 53: SYSCTL_RX_DROPS,
! 54: SYSCTL_RX_MCAST,
! 55: SYSCTL_TX_MCAST,
! 56: SYSCTL_TX_COLLS,
! 57: };
! 58: static struct attr_map link_attrs[] = {
! 59: {
! 60: .name = "bytes",
! 61: .type = ATTR_TYPE_COUNTER,
! 62: .unit = UNIT_BYTE,
! 63: .rxid = SYSCTL_RX_BYTES,
! 64: .txid = SYSCTL_TX_BYTES,
! 65: .description = "Bytes",
! 66: },
! 67: {
! 68: .name = "packets",
! 69: .type = ATTR_TYPE_COUNTER,
! 70: .unit = UNIT_NUMBER,
! 71: .rxid = SYSCTL_RX_PACKETS,
! 72: .txid = SYSCTL_TX_PACKETS,
! 73: .description = "Packets",
! 74: },
! 75: {
! 76: .name = "errors",
! 77: .type = ATTR_TYPE_COUNTER,
! 78: .unit = UNIT_NUMBER,
! 79: .rxid = SYSCTL_RX_ERRORS,
! 80: .txid = SYSCTL_TX_ERRORS,
! 81: .description = "Errors",
! 82: },
! 83: {
! 84: .name = "drop",
! 85: .type = ATTR_TYPE_COUNTER,
! 86: .unit = UNIT_NUMBER,
! 87: .rxid = SYSCTL_RX_DROPS,
! 88: .description = "Dropped",
! 89: },
! 90: {
! 91: .name = "coll",
! 92: .type = ATTR_TYPE_COUNTER,
! 93: .unit = UNIT_NUMBER,
! 94: .txid = SYSCTL_TX_COLLS,
! 95: .description = "Collisions",
! 96: },
! 97: {
! 98: .name = "mcast",
! 99: .type = ATTR_TYPE_COUNTER,
! 100: .unit = UNIT_NUMBER,
! 101: .rxid = SYSCTL_RX_MCAST,
! 102: .txid = SYSCTL_TX_MCAST,
! 103: .description = "Multicast",
! 104: }
! 105: };
! 106:
! 107: uint64_t sysctl_get_stats(const struct if_msghdr *ifm, int what)
! 108: {
! 109: switch(what) {
! 110: case SYSCTL_RX_BYTES:
! 111: return ifm->ifm_data.ifi_ibytes;
! 112: case SYSCTL_TX_BYTES:
! 113: return ifm->ifm_data.ifi_obytes;
! 114:
! 115: case SYSCTL_RX_PACKETS:
! 116: return ifm->ifm_data.ifi_ipackets;
! 117: case SYSCTL_TX_PACKETS:
! 118: return ifm->ifm_data.ifi_opackets;
! 119:
! 120: case SYSCTL_RX_ERRORS:
! 121: return ifm->ifm_data.ifi_ierrors;
! 122: case SYSCTL_TX_ERRORS:
! 123: return ifm->ifm_data.ifi_oerrors;
! 124:
! 125: case SYSCTL_RX_DROPS:
! 126: return ifm->ifm_data.ifi_iqdrops;
! 127:
! 128: case SYSCTL_RX_MCAST:
! 129: return ifm->ifm_data.ifi_imcasts;
! 130: case SYSCTL_TX_MCAST:
! 131: return ifm->ifm_data.ifi_omcasts;
! 132: case SYSCTL_TX_COLLS:
! 133: return ifm->ifm_data.ifi_collisions;
! 134:
! 135: default:
! 136: return 0;
! 137: };
! 138: }
1.1 misho 139:
1.1.1.2 ! misho 140: static void
! 141: sysctl_read(void)
1.1 misho 142: {
143: int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
144: size_t n;
145: char *buf, *next, *lim;
146:
147: if (sysctl(mib, 6, NULL, &n, NULL, 0) < 0)
148: quit("sysctl() failed");
149:
150: if (c_debug)
1.1.1.2 ! misho 151: fprintf(stderr, "sysctl 1-pass n=%zd\n", n);
1.1 misho 152:
153: buf = xcalloc(1, n);
154:
155: if (sysctl(mib, 6, buf, &n, NULL, 0) < 0)
156: quit("sysctl() failed");
157:
158: if (c_debug)
1.1.1.2 ! misho 159: fprintf(stderr, "sysctl 2-pass n=%zd\n", n);
1.1 misho 160:
1.1.1.2 ! misho 161: lim = (buf + n);
! 162: for (next = buf; next < lim; ) {
! 163: struct element *e, *e_parent = NULL;
1.1 misho 164: struct if_msghdr *ifm, *nextifm;
165: struct sockaddr_dl *sdl;
166:
167: ifm = (struct if_msghdr *) next;
168: if (ifm->ifm_type != RTM_IFINFO)
169: break;
170:
171: next += ifm->ifm_msglen;
1.1.1.2 ! misho 172:
1.1 misho 173: while (next < lim) {
174: nextifm = (struct if_msghdr *) next;
175: if (nextifm->ifm_type != RTM_NEWADDR)
176: break;
177: next += nextifm->ifm_msglen;
178: }
179:
180: sdl = (struct sockaddr_dl *) (ifm + 1);
181:
1.1.1.2 ! misho 182: if (!cfg_show_all && !(ifm->ifm_flags & IFF_UP))
1.1 misho 183: continue;
184:
1.1.1.2 ! misho 185: if (sdl->sdl_family != AF_LINK)
1.1 misho 186: continue;
187:
188: if (c_debug)
189: fprintf(stderr, "Processing %s\n", sdl->sdl_data);
190:
1.1.1.2 ! misho 191: sdl->sdl_data[sdl->sdl_nlen] = '\0';
! 192: e = element_lookup(grp,
! 193: sdl->sdl_data, sdl->sdl_index,
! 194: e_parent, ELEMENT_CREAT);
! 195: if (!e)
1.1 misho 196: continue;
197:
1.1.1.2 ! misho 198: if (e->e_flags & ELEMENT_FLAG_CREATED) {
! 199: if (e->e_parent)
! 200: e->e_level = e->e_parent->e_level + 1;
! 201:
! 202: if (element_set_key_attr(e, "bytes", "packets") ||
! 203: element_set_usage_attr(e, "bytes"))
! 204: BUG();
1.1 misho 205:
1.1.1.2 ! misho 206: e->e_flags &= ~ELEMENT_FLAG_CREATED;
! 207: }
! 208:
! 209: int i;
! 210: for (i = 0; i < ARRAY_SIZE(link_attrs); i++) {
! 211: struct attr_map *m = &link_attrs[i];
! 212: uint64_t rx = 0, tx = 0;
! 213: int flags = 0;
! 214:
! 215: if (m->rxid) {
! 216: rx = sysctl_get_stats(ifm, m->rxid);
! 217: flags |= UPDATE_FLAG_RX;
! 218: }
! 219:
! 220: if (m->txid) {
! 221: tx = sysctl_get_stats(ifm, m->txid);
! 222: flags |= UPDATE_FLAG_TX;
! 223: }
! 224:
! 225: attr_update(e, m->attrid, rx, tx, flags);
! 226: }
1.1 misho 227:
1.1.1.2 ! misho 228: element_notify_update(e, NULL);
! 229: element_lifesign(e, 1);
1.1 misho 230: }
231:
232: xfree(buf);
233: }
234:
1.1.1.2 ! misho 235: static void
! 236: print_help(void)
1.1 misho 237: {
238: printf(
1.1.1.2 ! misho 239: "sysctl - sysctl statistic collector for BSD and Darwin\n" \
! 240: "\n" \
! 241: " BSD and Darwin statistic collector using sysctl()\n" \
! 242: " Author: Thomas Graf <tgraf@suug.ch>\n" \
! 243: "\n");
1.1 misho 244: }
245:
1.1.1.2 ! misho 246: static void
! 247: sysctl_set_opts(const char* type, const char* value)
! 248: {
! 249: if (!strcasecmp(type, "debug"))
! 250: c_debug = 1;
! 251: else if (!strcasecmp(type, "help")) {
! 252: print_help();
! 253: exit(0);
1.1 misho 254: }
255: }
256:
1.1.1.2 ! misho 257: static int
! 258: sysctl_probe(void)
1.1 misho 259: {
260: size_t n;
261: int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0};
262: if (sysctl(mib, 6, NULL, &n, NULL, 0) < 0)
263: return 0;
264: return 1;
265: }
266:
1.1.1.2 ! misho 267: static int sysctl_do_init(void)
! 268: {
! 269: if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)))
! 270: BUG();
! 271:
! 272: grp = group_lookup(DEFAULT_GROUP, GROUP_CREATE);
! 273: if (!grp)
! 274: BUG();
! 275:
! 276: return 0;
! 277: }
! 278:
! 279: static struct bmon_module kstat_ops = {
! 280: .m_name = "sysctl",
! 281: .m_do = sysctl_read,
! 282: .m_parse_opt = sysctl_set_opts,
! 283: .m_probe = sysctl_probe,
! 284: .m_init = sysctl_do_init,
1.1 misho 285: };
286:
1.1.1.2 ! misho 287: static void __init
! 288: sysctl_init(void)
1.1 misho 289: {
1.1.1.2 ! misho 290: input_register(&kstat_ops);
1.1 misho 291: }
292:
293: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>