Annotation of embedaddon/bmon/src/in_netstat.c, revision 1.1
1.1 ! misho 1: /*
! 2: * in_netstat.c netstat -i -a
! 3: *
! 4: * ... or probably-the-most-silly-attempt-to-gather-network-statistics
! 5: *
! 6: * Copyright (c) 2001-2004 Thomas Graf <tgraf@suug.ch>
! 7: *
! 8: * Permission is hereby granted, free of charge, to any person obtaining a
! 9: * copy of this software and associated documentation files (the "Software"),
! 10: * to deal in the Software without restriction, including without limitation
! 11: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
! 12: * and/or sell copies of the Software, and to permit persons to whom the
! 13: * Software is furnished to do so, subject to the following conditions:
! 14: *
! 15: * The above copyright notice and this permission notice shall be included
! 16: * in all copies or substantial portions of the Software.
! 17: *
! 18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
! 19: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
! 21: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
! 23: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
! 24: * DEALINGS IN THE SOFTWARE.
! 25: */
! 26:
! 27: #include <bmon/bmon.h>
! 28: #include <bmon/input.h>
! 29: #include <bmon/item.h>
! 30: #include <bmon/node.h>
! 31: #include <bmon/conf.h>
! 32: #include <bmon/utils.h>
! 33: #include <inttypes.h>
! 34:
! 35: static char *c_cmd = "netstat -i -a";
! 36:
! 37: static void netstat_read(void)
! 38: {
! 39: FILE * fd;
! 40: char buf[512];
! 41:
! 42: if (!(fd = popen(c_cmd, "r")))
! 43: quit("popen(c_cmd) failed: %s\n", strerror(errno));
! 44:
! 45: for (; fgets(buf, sizeof(buf), fd);) {
! 46: char *p, *s;
! 47: item_t *intf;
! 48:
! 49: if (buf[0] == '\n' || buf[0] == '\r')
! 50: continue;
! 51:
! 52: if (!strncmp(buf, "Name", 4) ||
! 53: !strncmp(buf, "Kernel", 6) ||
! 54: !strncmp(buf, "Iface", 5))
! 55: continue;
! 56:
! 57:
! 58: if (!(p = strchr(buf, ' ')))
! 59: continue;
! 60:
! 61: *p = '\0';
! 62: s = p+1;
! 63:
! 64: for (p = &buf[0]; *p == ' ' || *p == '\t'; p++);
! 65:
! 66:
! 67: #if defined SYS_LINUX
! 68: {
! 69: int i;
! 70: char flags[32];
! 71: b_cnt_t rx_p, tx_p, rx_errors, tx_errors, rx_drop, tx_drop;
! 72:
! 73: i = sscanf(s, "%*s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %*d "
! 74: "%" SCNu64 " %" SCNu64 " %" SCNu64 " %s",
! 75: &rx_p, &rx_errors, &rx_drop, &tx_p, &tx_errors, &tx_drop, flags);
! 76:
! 77: if (i != 7)
! 78: continue;
! 79:
! 80: if (get_show_only_running() && !strchr(flags, 'R'))
! 81: continue;
! 82:
! 83: intf = lookup_item(get_local_node(), p, 0, 0);
! 84:
! 85: if (NULL == intf)
! 86: continue;
! 87:
! 88: intf->i_major_attr = BYTES;
! 89: intf->i_minor_attr = PACKETS;
! 90:
! 91: update_attr(intf, PACKETS, rx_p, tx_p, RX_PROVIDED | TX_PROVIDED);
! 92: update_attr(intf, ERRORS, rx_errors, tx_errors,
! 93: RX_PROVIDED | TX_PROVIDED);
! 94: update_attr(intf, DROP, rx_drop, tx_drop,
! 95: RX_PROVIDED | TX_PROVIDED);
! 96: }
! 97: #else
! 98: {
! 99: int i;
! 100: b_cnt_t rx_p, tx_p, rx_errors, tx_errors, tx_frame;
! 101:
! 102: i = sscanf(s, "%*s %*s %*s %llu %llu %llu %llu %llu",
! 103: &rx_p, &rx_errors, &tx_p, &tx_errors, &tx_frame);
! 104:
! 105: if (i != 5)
! 106: continue;
! 107:
! 108: /*
! 109: * XXX: get_show_only_running()
! 110: */
! 111:
! 112: intf = lookup_item(get_local_node(), p, 0, 0);
! 113:
! 114: if (NULL == intf)
! 115: continue;
! 116:
! 117: intf->i_major_attr = BYTES;
! 118: intf->i_minor_attr = PACKETS;
! 119:
! 120: update_attr(intf, PACKETS, rx_p, tx_p, RX_PROVIDED | TX_PROVIDED);
! 121: update_attr(intf, ERRORS, rx_errors, tx_errors,
! 122: RX_PROVIDED | TX_PROVIDED);
! 123: update_attr(intf, FRAME, 0, tx_frame, TX_PROVIDED);
! 124: }
! 125: #endif
! 126:
! 127: notify_update(intf, NULL);
! 128: increase_lifetime(intf, 1);
! 129: }
! 130:
! 131: pclose(fd);
! 132: }
! 133:
! 134: static int netstat_probe(void)
! 135: {
! 136: FILE *fd = popen(c_cmd, "r");
! 137:
! 138: if (fd) {
! 139: pclose(fd);
! 140: return 1;
! 141: }
! 142:
! 143: return 0;
! 144: }
! 145:
! 146: static void print_help(void)
! 147: {
! 148: printf(
! 149: "netstat - statistic collector using netstat -i\n" \
! 150: "\n" \
! 151: " Very lame attempt to collect statistics by parsing the output\n" \
! 152: " of netstat -i -a. Only the packet counters and a few error counters\n" \
! 153: " are provided depending on the architecture. If all fails this could\n" \
! 154: " theoretically be used to see at least some of the statistics.\n" \
! 155: "\n" \
! 156: " WARNING: The default behaviour is to start netstat -i -a without an absolute\n" \
! 157: " path which means that an attacker could create an executable `netstat'\n" \
! 158: " which would then be run under the privileges you started bmon. For that\n" \
! 159: " reason this input method is never used by default\n" \
! 160: " Author: Thomas Graf <tgraf@suug.ch>\n" \
! 161: "\n" \
! 162: " Options:\n" \
! 163: " cmd=STR Netstat command to use (default: netstat -i -a)\n" \
! 164: "\n");
! 165: }
! 166:
! 167: static void netstat_set_opts(tv_t *attrs)
! 168: {
! 169: while (attrs) {
! 170: if (!strcasecmp(attrs->type, "cmd") && attrs->value)
! 171: c_cmd = attrs->value;
! 172: else if (!strcasecmp(attrs->type, "help")) {
! 173: print_help();
! 174: exit(0);
! 175: }
! 176: attrs = attrs->next;
! 177: }
! 178: }
! 179:
! 180: static struct input_module netstat_ops = {
! 181: .im_name = "netstat",
! 182: .im_read = netstat_read,
! 183: .im_set_opts = netstat_set_opts,
! 184: .im_probe = netstat_probe,
! 185: .im_no_default = 1,
! 186: };
! 187:
! 188: static void __init netstat_init(void)
! 189: {
! 190: register_input_module(&netstat_ops);
! 191: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>