Annotation of embedaddon/bmon/src/in_netstat.c, revision 1.1.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>