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>