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>