File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / in_netstat.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:19:56 2012 UTC (13 years, 4 months ago) by misho
Branches: bmon, MAIN
CVS tags: v2_1_0p0, v2_1_0, HEAD
bmon

    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>