2 * Copyright 1997,1999,2000 Andi Kleen. Subject to the GPL.
3 * $Id: statistics.c,v 1.22 2008/10/03 01:07:47 ecki Exp $
4 * 19980630 - i18n - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * 19981113 - i18n fixes - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 * 19990101 - added net/netstat, -t, -u, -w supprt - Bernd Eckenfels
24 int print_static,f_raw,f_tcp,f_udp,f_unknown = 1;
27 number = 0, opt_number, i_forward, i_inp_icmp, i_outp_icmp, i_rto_alg,
44 struct statedesc states[] = {
45 [number] = { 4, NULL },
46 [opt_number] = { 4, NULL },
47 [i_forward] = { 4, NULL },
48 [i_inp_icmp] = { 8, N_("ICMP input histogram:") },
49 [i_outp_icmp] = { 8, N_("ICMP output histogram:") },
53 static enum State state;
55 #define I_STATIC (1<<16) /* static configuration option. */
56 #define I_TITLE (1<<17)
59 * XXX check against the snmp mib rfc.
61 * Don't mark the first field as translatable! It's a snmp MIB standard.
64 struct entry Iptab[] =
66 {"Forwarding", N_("Forwarding is %s"), i_forward | I_STATIC},
67 {"DefaultTTL", N_("Default TTL is %u"), number | I_STATIC},
68 {"InReceives", N_("%u total packets received"), number},
69 {"InHdrErrors", N_("%u with invalid headers"), opt_number},
70 {"InAddrErrors", N_("%u with invalid addresses"), opt_number},
71 {"ForwDatagrams", N_("%u forwarded"), number},
72 {"InUnknownProtos", N_("%u with unknown protocol"), opt_number},
73 {"InDiscards", N_("%u incoming packets discarded"), number},
74 {"InDelivers", N_("%u incoming packets delivered"), number},
75 {"OutRequests", N_("%u requests sent out"), number}, /*? */
76 {"OutDiscards", N_("%u outgoing packets dropped"), opt_number},
77 {"OutNoRoutes", N_("%u dropped because of missing route"), opt_number},
78 {"ReasmTimeout", N_("%u fragments dropped after timeout"), opt_number},
79 {"ReasmReqds", N_("%u reassemblies required"), opt_number}, /* ? */
80 {"ReasmOKs", N_("%u packets reassembled ok"), opt_number},
81 {"ReasmFails", N_("%u packet reassembles failed"), opt_number},
82 {"FragOKs", N_("%u fragments received ok"), opt_number},
83 {"FragFails", N_("%u fragments failed"), opt_number},
84 {"FragCreates", N_("%u fragments created"), opt_number}
87 struct entry Ip6tab[] =
89 {"Ip6InReceives", N_("%u total packets received"), number},
90 {"Ip6InHdrErrors", N_("%u with invalid headers"), opt_number},
91 {"Ip6InTooBigErrors", N_("%u with packets too big"), opt_number},
92 {"Ip6InNoRoutes", N_("%u incoming packets with no route"), opt_number},
93 {"Ip6InAddrErrors", N_("%u with invalid addresses"), opt_number},
94 {"Ip6InUnknownProtos", N_("%u with unknown protocol"), opt_number},
95 {"Ip6InTruncatedPkts", N_("%u with truncated packets"), opt_number},
96 {"Ip6InDiscards", N_("%u incoming packets discarded"), number},
97 {"Ip6InDelivers", N_("%u incoming packets delivered"), number},
98 {"Ip6OutForwDatagrams", N_("%u forwarded"), number},
99 {"Ip6OutRequests", N_("%u requests sent out"), number}, /*? */
100 {"Ip6OutDiscards", N_("%u outgoing packets dropped"), opt_number},
101 {"Ip6OutNoRoutes", N_("%u dropped because of missing route"), opt_number},
102 {"Ip6ReasmTimeout", N_("%u fragments dropped after timeout"), opt_number},
103 {"Ip6ReasmReqds", N_("%u reassemblies required"), opt_number}, /* ? */
104 {"Ip6ReasmOKs", N_("%u packets reassembled ok"), opt_number},
105 {"Ip6ReasmFails", N_("%u packet reassembles failed"), opt_number},
106 {"Ip6FragOKs", N_("%u fragments received ok"), opt_number},
107 {"Ip6FragFails", N_("%u fragments failed"), opt_number},
108 {"Ip6FragCreates", N_("%u fragments created"), opt_number},
109 {"Ip6InMcastPkts", N_("%u incoming multicast packets"), opt_number},
110 {"Ip6OutMcastPkts", N_("%u outgoing multicast packets"), opt_number}
113 struct entry Icmptab[] =
115 {"InMsgs", N_("%u ICMP messages received"), number},
116 {"InErrors", N_("%u input ICMP message failed."), number},
117 {"InDestUnreachs", N_("destination unreachable: %u"), i_inp_icmp | I_TITLE},
118 {"InTimeExcds", N_("timeout in transit: %u"), i_inp_icmp | I_TITLE},
119 {"InParmProbs", N_("wrong parameters: %u"), i_inp_icmp | I_TITLE}, /*? */
120 {"InSrcQuenchs", N_("source quenches: %u"), i_inp_icmp | I_TITLE},
121 {"InRedirects", N_("redirects: %u"), i_inp_icmp | I_TITLE},
122 {"InEchos", N_("echo requests: %u"), i_inp_icmp | I_TITLE},
123 {"InEchoReps", N_("echo replies: %u"), i_inp_icmp | I_TITLE},
124 {"InTimestamps", N_("timestamp request: %u"), i_inp_icmp | I_TITLE},
125 {"InTimestampReps", N_("timestamp reply: %u"), i_inp_icmp | I_TITLE},
126 {"InAddrMasks", N_("address mask request: %u"), i_inp_icmp | I_TITLE}, /*? */
127 {"InAddrMaskReps", N_("address mask replies: %u"), i_inp_icmp | I_TITLE}, /*? */
128 {"OutMsgs", N_("%u ICMP messages sent"), number},
129 {"OutErrors", N_("%u ICMP messages failed"), number},
130 {"OutDestUnreachs", N_("destination unreachable: %u"), i_outp_icmp | I_TITLE},
131 {"OutTimeExcds", N_("time exceeded: %u"), i_outp_icmp | I_TITLE},
132 {"OutParmProbs", N_("wrong parameters: %u"), i_outp_icmp | I_TITLE}, /*? */
133 {"OutSrcQuenchs", N_("source quench: %u"), i_outp_icmp | I_TITLE},
134 {"OutRedirects", N_("redirect: %u"), i_outp_icmp | I_TITLE},
135 {"OutEchos", N_("echo request: %u"), i_outp_icmp | I_TITLE},
136 {"OutEchoReps", N_("echo replies: %u"), i_outp_icmp | I_TITLE},
137 {"OutTimestamps", N_("timestamp requests: %u"), i_outp_icmp | I_TITLE},
138 {"OutTimestampReps", N_("timestamp replies: %u"), i_outp_icmp | I_TITLE},
139 {"OutAddrMasks", N_("address mask requests: %u"), i_outp_icmp | I_TITLE},
140 {"OutAddrMaskReps", N_("address mask replies: %u"), i_outp_icmp | I_TITLE},
143 struct entry Icmp6tab[] =
145 {"Icmp6InMsgs", N_("%u ICMP messages received"), number},
146 {"Icmp6InErrors", N_("%u input ICMP message failed."), number},
147 {"Icmp6InDestUnreachs", N_("destination unreachable: %u"), i_inp_icmp | I_TITLE},
148 {"Icmp6InPktTooBigs", N_("packets too big: %u"), i_inp_icmp | I_TITLE},
149 {"Icmp6InTimeExcds", N_("received ICMPv6 time exceeded: %u"), i_inp_icmp | I_TITLE},
150 {"Icmp6InParmProblems", N_("parameter problem: %u"), i_inp_icmp | I_TITLE},
151 {"Icmp6InEchos", N_("echo requests: %u"), i_inp_icmp | I_TITLE},
152 {"Icmp6InEchoReplies", N_("echo replies: %u"), i_inp_icmp | I_TITLE},
153 {"Icmp6InGroupMembQueries", N_("group member queries: %u"), i_inp_icmp | I_TITLE},
154 {"Icmp6InGroupMembResponses", N_("group member responses: %u"), i_inp_icmp | I_TITLE},
155 {"Icmp6InGroupMembReductions", N_("group member reductions: %u"), i_inp_icmp | I_TITLE},
156 {"Icmp6InRouterSolicits", N_("router solicits: %u"), i_inp_icmp | I_TITLE},
157 {"Icmp6InRouterAdvertisements", N_("router advertisement: %u"), i_inp_icmp | I_TITLE},
158 {"Icmp6InNeighborSolicits", N_("neighbour solicits: %u"), i_inp_icmp | I_TITLE},
159 {"Icmp6InNeighborAdvertisements", N_("neighbour advertisement: %u"), i_inp_icmp | I_TITLE},
160 {"Icmp6InRedirects", N_("redirects: %u"), i_inp_icmp | I_TITLE},
161 {"Icmp6OutMsgs", N_("%u ICMP messages sent"), number},
162 {"Icmp6OutDestUnreachs", N_("destination unreachable: %u"), i_outp_icmp | I_TITLE},
163 {"Icmp6OutPktTooBigs", N_("packets too big: %u"), i_outp_icmp | I_TITLE},
164 {"Icmp6OutTimeExcds", N_("sent ICMPv6 time exceeded: %u"), i_outp_icmp | I_TITLE},
165 {"Icmp6OutParmProblems", N_("parameter problem: %u"), i_outp_icmp | I_TITLE},
166 {"Icmp6OutEchos", N_("echo requests: %u"), i_outp_icmp | I_TITLE},
167 {"Icmp6OutEchoReplies", N_("echo replies: %u"), i_outp_icmp | I_TITLE},
168 {"Icmp6OutGroupMembQueries", N_("group member queries: %u"), i_outp_icmp | I_TITLE},
169 {"Icmp6OutGroupMembResponses", N_("group member responses: %u"), i_outp_icmp | I_TITLE},
170 {"Icmp6OutGroupMembReductions", N_("group member reductions: %u"), i_outp_icmp | I_TITLE},
171 {"Icmp6OutRouterSolicits", N_("router solicits: %u"), i_outp_icmp | I_TITLE},
172 {"Icmp6OutRouterAdvertisements ", N_("router advertisement: %u"), i_outp_icmp | I_TITLE},
173 {"Icmp6OutNeighborSolicits", N_("neighbor solicits: %u"), i_outp_icmp | I_TITLE},
174 {"Icmp6OutNeighborAdvertisements", N_("neighbor advertisements: %u"), i_outp_icmp | I_TITLE},
175 {"Icmp6OutRedirects", N_("redirects: %u"), i_outp_icmp | I_TITLE},
178 struct entry Tcptab[] =
180 {"RtoAlgorithm", N_("RTO algorithm is %s"), i_rto_alg | I_STATIC},
181 {"RtoMin", "", number},
182 {"RtoMax", "", number},
183 {"MaxConn", "", number},
184 {"ActiveOpens", N_("%u active connections openings"), number},
185 {"PassiveOpens", N_("%u passive connection openings"), number},
186 {"AttemptFails", N_("%u failed connection attempts"), number},
187 {"EstabResets", N_("%u connection resets received"), number},
188 {"CurrEstab", N_("%u connections established"), number},
189 {"InSegs", N_("%u segments received"), number},
190 {"OutSegs", N_("%u segments send out"), number},
191 {"RetransSegs", N_("%u segments retransmited"), number},
192 {"InErrs", N_("%u bad segments received."), number},
193 {"OutRsts", N_("%u resets sent"), number},
196 struct entry Udptab[] =
198 {"InDatagrams", N_("%u packets received"), number},
199 {"NoPorts", N_("%u packets to unknown port received."), number},
200 {"InErrors", N_("%u packet receive errors"), number},
201 {"OutDatagrams", N_("%u packets sent"), number},
204 struct entry Udp6tab[] =
206 {"Udp6InDatagrams", N_("%u packets received"), number},
207 {"Udp6NoPorts", N_("%u packets to unknown port received."), number},
208 {"Udp6InErrors", N_("%u packet receive errors"), number},
209 {"Udp6OutDatagrams", N_("%u packets sent"), number},
212 struct entry Tcpexttab[] =
214 {"SyncookiesSent", N_("%u SYN cookies sent"), opt_number},
215 {"SyncookiesRecv", N_("%u SYN cookies received"), opt_number},
216 {"SyncookiesFailed", N_("%u invalid SYN cookies received"), opt_number},
218 { "EmbryonicRsts", N_("%u resets received for embryonic SYN_RECV sockets"),
220 { "PruneCalled", N_("%u packets pruned from receive queue because of socket"
221 " buffer overrun"), opt_number },
222 /* obsolete: 2.2.0 doesn't do that anymore */
223 { "RcvPruned", N_("%u packets pruned from receive queue"), opt_number },
224 { "OfoPruned", N_("%u packets dropped from out-of-order queue because of"
225 " socket buffer overrun"), opt_number },
226 { "OutOfWindowIcmps", N_("%u ICMP packets dropped because they were "
227 "out-of-window"), opt_number },
228 { "LockDroppedIcmps", N_("%u ICMP packets dropped because"
229 " socket was locked"), opt_number },
230 { "TW", N_("%u TCP sockets finished time wait in fast timer"), opt_number },
231 { "TWRecycled", N_("%u time wait sockets recycled by time stamp"), opt_number },
232 { "TWKilled", N_("%u TCP sockets finished time wait in slow timer"), opt_number },
233 { "PAWSPassive", N_("%u passive connections rejected because of"
234 " time stamp"), opt_number },
235 { "PAWSActive", N_("%u active connections rejected because of "
236 "time stamp"), opt_number },
237 { "PAWSEstab", N_("%u packets rejects in established connections because of"
238 " timestamp"), opt_number },
239 { "DelayedACKs", N_("%u delayed acks sent"), opt_number },
240 { "DelayedACKLocked", N_("%u delayed acks further delayed because of"
241 " locked socket"), opt_number },
242 { "DelayedACKLost", N_("Quick ack mode was activated %u times"), opt_number },
243 { "ListenOverflows", N_("%u times the listen queue of a socket overflowed"),
245 { "ListenDrops", N_("%u SYNs to LISTEN sockets dropped"), opt_number },
246 { "TCPPrequeued", N_("%u packets directly queued to recvmsg prequeue."),
248 { "TCPDirectCopyFromBacklog", N_("%u bytes directly in process context from backlog"), opt_number },
249 { "TCPDirectCopyFromPrequeue", N_("%u bytes directly received in process context from prequeue"),
251 { "TCPPrequeueDropped", N_("%u packets dropped from prequeue"), opt_number },
252 { "TCPHPHits", N_("%u packet headers predicted"), number },
253 { "TCPHPHitsToUser", N_("%u packets header predicted and "
254 "directly queued to user"), opt_number },
255 { "SockMallocOOM", N_("Ran %u times out of system memory during "
256 "packet sending"), opt_number },
257 { "TCPPureAcks", N_("%u acknowledgments not containing data payload received"), opt_number },
258 { "TCPHPAcks", N_("%u predicted acknowledgments"), opt_number },
259 { "TCPRenoRecovery", N_("%u times recovered from packet loss due to fast retransmit"), opt_number },
260 { "TCPSackRecovery", N_("%u times recovered from packet loss by selective acknowledgements"), opt_number },
261 { "TCPSACKReneging", N_("%u bad SACK blocks received"), opt_number },
262 { "TCPFACKReorder", N_("Detected reordering %u times using FACK"), opt_number },
263 { "TCPSACKReorder", N_("Detected reordering %u times using SACK"), opt_number },
264 { "TCPTSReorder", N_("Detected reordering %u times using time stamp"), opt_number },
265 { "TCPRenoReorder", N_("Detected reordering %u times using reno fast retransmit"), opt_number },
266 { "TCPFullUndo", N_("%u congestion windows fully recovered without slow start"), opt_number },
267 { "TCPPartialUndo", N_("%u congestion windows partially recovered using Hoe heuristic"), opt_number },
268 { "TCPDSackUndo", N_("%u congestion window recovered without slow start using DSACK"), opt_number },
269 { "TCPLossUndo", N_("%u congestion windows recovered without slow start after partial ack"), opt_number },
270 { "TCPLostRetransmits", N_("%u retransmits lost"), opt_number },
271 { "TCPRenoFailures", N_("%u timeouts after reno fast retransmit"), opt_number },
272 { "TCPSackFailures", N_("%u timeouts after SACK recovery"), opt_number },
273 { "TCPLossFailures", N_("%u timeouts in loss state"), opt_number },
274 { "TCPFastRetrans", N_("%u fast retransmits"), opt_number },
275 { "TCPForwardRetrans", N_("%u forward retransmits"), opt_number },
276 { "TCPSlowStartRetrans", N_("%u retransmits in slow start"), opt_number },
277 { "TCPTimeouts", N_("%u other TCP timeouts"), opt_number },
278 { "TCPRenoRecoveryFailed", N_("%u reno fast retransmits failed"), opt_number },
279 { "TCPSackRecoveryFail", N_("%u SACK retransmits failed"), opt_number },
280 { "TCPSchedulerFailed", N_("%u times receiver scheduled too late for direct processing"), opt_number },
281 { "TCPRcvCollapsed", N_("%u packets collapsed in receive queue due to low socket buffer"), opt_number },
282 { "TCPDSACKOldSent", N_("%u DSACKs sent for old packets"), opt_number },
283 { "TCPDSACKOfoSent", N_("%u DSACKs sent for out of order packets"), opt_number },
284 { "TCPDSACKRecv", N_("%u DSACKs received"), opt_number },
285 { "TCPDSACKOfoRecv", N_("%u DSACKs for out of order packets received"), opt_number },
286 { "TCPAbortOnSyn", N_("%u connections reset due to unexpected SYN"), opt_number },
287 { "TCPAbortOnData", N_("%u connections reset due to unexpected data"), opt_number },
288 { "TCPAbortOnClose", N_("%u connections reset due to early user close"), opt_number },
289 { "TCPAbortOnMemory", N_("%u connections aborted due to memory pressure"), opt_number },
290 { "TCPAbortOnTimeout", N_("%u connections aborted due to timeout"), opt_number },
291 { "TCPAbortOnLinger", N_("%u connections aborted after user close in linger timeout"), opt_number },
292 { "TCPAbortFailed", N_("%u times unabled to send RST due to no memory"), opt_number },
293 { "TCPMemoryPressures", N_("TCP ran low on memory %u times"), opt_number },
294 { "TCPLoss", N_("%u TCP data loss events"), opt_number },
295 { "TCPDSACKUndo", N_("%u congestion windows recovered without slow start by DSACK"),
297 { "TCPRenoRecoveryFail", N_("%u classic Reno fast retransmits failed"), opt_number },
307 struct tabtab snmptabs[] =
309 {"Ip", Iptab, sizeof(Iptab), &f_raw},
310 {"Icmp", Icmptab, sizeof(Icmptab), &f_raw},
311 {"Tcp", Tcptab, sizeof(Tcptab), &f_tcp},
312 {"Udp", Udptab, sizeof(Udptab), &f_udp},
313 {"TcpExt", Tcpexttab, sizeof(Tcpexttab), &f_tcp},
317 struct tabtab snmp6tabs[] =
319 {"Ip6", Ip6tab, sizeof(Ip6tab), &f_raw},
320 {"Icmp6", Icmp6tab, sizeof(Icmp6tab), &f_raw},
321 {"Udp6", Udp6tab, sizeof(Udp6tab), &f_udp},
322 {"Tcp6", Tcptab, sizeof(Tcptab), &f_tcp},
328 int cmpentries(const void *a, const void *b)
330 return strcmp(((struct entry *) a)->title, ((struct entry *) b)->title);
333 void printval(struct tabtab *tab, char *title, int val)
335 struct entry *ent = NULL, key;
341 ent = bsearch(&key, tab->tab, tab->size / sizeof(struct entry),
342 sizeof(struct entry), cmpentries);
343 if (!ent) { /* try our best */
345 printf("%*s%s: %d\n", states[state].indent, "", title, val);
349 if (type & I_STATIC) {
354 if (*ent->out == '\0')
357 if (type & I_TITLE) {
360 printf("%*s%s\n", states[state].indent, "", _(states[type].title));
369 snprintf(buf, sizeof(buf), _(ent->out), val);
373 snprintf(buf, sizeof(buf), _(ent->out), val == 2 ? _("enabled") : _("disabled"));
378 snprintf(buf, sizeof(buf), _(ent->out), val);
380 case i_rto_alg: /* XXXX */
386 printf("%*s%s\n", states[type].indent, "", buf);
391 struct tabtab *newtable(struct tabtab *tabs, char *title)
394 static struct tabtab dummytab;
396 for (t = tabs; t->title; t++) {
397 if (!strcmp(title, t->title)) {
399 printf("%s:\n", _(title));
406 printf("%s:\n", _(title));
407 dummytab.title = title;
408 dummytab.flag = &f_unknown;
412 int process_fd(FILE *f, int all, char *filter)
414 char buf1[2048], buf2[2048];
416 while (fgets(buf1, sizeof buf1, f)) {
420 if (buf1[0] == '\n') // skip empty first line in 2.6 kernels
423 if (!fgets(buf2, sizeof buf2, f))
425 sp = strchr(buf1, ':');
426 np = strchr(buf2, ':');
432 if (strncmp(buf1, filter, strlen(filter)))
435 tab = newtable(snmptabs, buf1);
437 printf("unknown %s\n", buf1);
445 sp += strspn(sp, " \t\n");
446 np += strspn(np, " \t\n");
447 /*if (*np == '\0') goto formaterr; */
449 p = sp+strcspn(sp, " \t\n");
454 if (*sp != '\0' && *(tab->flag))
455 printval(tab, sp, strtoul(np, &np, 10));
466 void cpytitle(char *original, char *new)
468 char *ptr = original;
469 while(*ptr != '6' && *ptr != '\0') {
479 void process6_fd(FILE *f)
481 char buf1[1024],buf2[50],buf3[1024];
483 struct tabtab *tab = NULL;
486 while (fgets(buf1, sizeof buf1, f)) {
487 sscanf(buf1, "%s %lu", buf2, &val);
489 cpytitle(buf2, buf3);
490 tab = newtable(snmp6tabs, buf3);
493 if(!strstr(buf2, buf3)) {
494 cpytitle(buf2, buf3);
495 tab = newtable(snmp6tabs, buf3);
498 printval(tab, buf2, val);
503 void parsesnmp(int flag_raw, int flag_tcp, int flag_udp)
507 f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp;
509 f = proc_fopen("/proc/net/snmp");
511 perror(_("cannot open /proc/net/snmp"));
515 if (process_fd(f, 1, NULL) < 0)
516 fprintf(stderr, _("Problem while parsing /proc/net/snmp\n"));
519 perror("/proc/net/snmp");
523 f = proc_fopen("/proc/net/netstat");
526 if (process_fd(f, 1, NULL) <0)
527 fprintf(stderr, _("Problem while parsing /proc/net/netstat\n"));
530 perror("/proc/net/netstat");
537 void parsesnmp6(int flag_raw, int flag_tcp, int flag_udp)
541 f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp;
543 f = fopen("/proc/net/snmp6", "r");
545 perror(_("cannot open /proc/net/snmp6"));
550 perror("/proc/net/snmp6");
553 f = fopen("/proc/net/snmp", "r");
555 perror(_("cannot open /proc/net/snmp"));
558 process_fd(f, 0, "Tcp");
560 perror("/proc/net/snmp");
569 /* we sort at runtime because I'm lazy ;) */
570 for (t = snmptabs; t->title; t++)
571 qsort(t->tab, t->size / sizeof(struct entry),
572 sizeof(struct entry), cmpentries);
579 for (t = snmp6tabs; t->title; t++)
580 qsort(t->tab, t->size / sizeof(struct entry),
581 sizeof(struct entry), cmpentries);