1 /* Copyright 1997,1999 by Andi Kleen. Subject to the GPL. */
2 /* $Id: statistics.c,v 1.11 1999/01/06 12:05:49 freitag Exp $ */
3 /* 19980630 - i18n - Arnaldo Carvalho de Melo <acme@conectiva.com.br> */
4 /* 19981113 - i18n fixes - Arnaldo Carvalho de Melo <acme@conectiva.com.br> */
5 /* 19990101 - added net/netstat, -t, -u, -w supprt - Bernd Eckenfels */
21 int print_static
,f_raw
,f_tcp
,f_udp
;
24 number
= 0, opt_number
, i_forward
, i_inp_icmp
, i_outp_icmp
, i_rto_alg
,
41 struct statedesc states
[] = {
42 [number
] = { 4, NULL
},
43 [opt_number
] = { 4, NULL
},
44 [i_forward
] = { 4, NULL
},
45 [i_inp_icmp
] = { 8, N_("ICMP input histogram:") },
46 [i_outp_icmp
] = { 8, N_("ICMP output histogram:") },
50 static enum State state
;
52 #define I_STATIC (1<<16) /* static configuration option. */
53 #define I_TITLE (1<<17)
56 * XXX check against the snmp mib rfc.
58 * Don't mark the first field as translatable! It's a snmp MIB standard.
61 struct entry Iptab
[] =
63 {"Forwarding", N_("Forwarding is %s"), i_forward
| I_STATIC
},
64 {"DefaultTTL", N_("Default TTL is %d"), number
| I_STATIC
},
65 {"InReceives", N_("%d total packets received"), number
},
66 {"InHdrErrors", N_("%d with invalid headers"), opt_number
},
67 {"InAddrErrors", N_("%d with invalid addresses"), opt_number
},
68 {"ForwDatagrams", N_("%d forwarded"), number
},
69 {"InUnknownProtos", N_("%d with unknown protocol"), opt_number
},
70 {"InDiscards", N_("%d incoming packets discarded"), number
},
71 {"InDelivers", N_("%d incoming packets delivered"), number
},
72 {"OutRequests", N_("%d requests sent out"), number
}, /*? */
73 {"OutDiscards", N_("%d outgoing packets dropped"), opt_number
},
74 {"OutNoRoutes", N_("%d dropped because of missing route"), opt_number
},
75 {"ReasmTimeout", N_("%d fragments dropped after timeout"), opt_number
},
76 {"ReasmReqds", N_("%d reassemblies required"), opt_number
}, /* ? */
77 {"ReasmOKs", N_("%d packets reassembled ok"), opt_number
},
78 {"ReasmFails", N_("%d packet reassembles failed"), opt_number
},
79 {"FragOKs", N_("%d fragments received ok"), opt_number
},
80 {"FragFails", N_("%d fragments failed"), opt_number
},
81 {"FragCreates", N_("%d fragments created"), opt_number
}
84 struct entry Icmptab
[] =
86 {"InMsgs", N_("%d ICMP messages received"), number
},
87 {"InErrors", N_("%d input ICMP message failed."), number
},
88 {"InDestUnreachs", N_("destination unreachable: %d"), i_inp_icmp
| I_TITLE
},
89 {"InTimeExcds", N_("timeout in transit: %d"), i_inp_icmp
| I_TITLE
},
90 {"InParmProbs", N_("wrong parameters: %d"), i_inp_icmp
| I_TITLE
}, /*? */
91 {"InSrcQuenchs", N_("source quenchs: %d"), i_inp_icmp
| I_TITLE
},
92 {"InRedirects", N_("redirects: %d"), i_inp_icmp
| I_TITLE
},
93 {"InEchos", N_("echo requests: %d"), i_inp_icmp
| I_TITLE
},
94 {"InEchoReps", N_("echo replies: %d"), i_inp_icmp
| I_TITLE
},
95 {"InTimestamps", N_("timestamp request: %d"), i_inp_icmp
| I_TITLE
},
96 {"InTimestampReps", N_("timestamp reply: %d"), i_inp_icmp
| I_TITLE
},
97 {"InAddrMasks", N_("address mask request: %d"), i_inp_icmp
| I_TITLE
}, /*? */
98 {"InAddrMaskReps", N_("address mask replies"), i_inp_icmp
| I_TITLE
}, /*? */
99 {"OutMsgs", N_("%d ICMP messages sent"), number
},
100 {"OutErrors", N_("%d ICMP messages failed"), number
},
101 {"OutDestUnreachs", N_("destination unreachable: %d"), i_outp_icmp
| I_TITLE
},
102 {"OutTimeExcds", N_("time exceeded: %d"), i_outp_icmp
| I_TITLE
},
103 {"OutParmProbs", N_("wrong parameters: %d"), i_outp_icmp
| I_TITLE
}, /*? */
104 {"OutSrcQuenchs", N_("source quench: %d"), i_outp_icmp
| I_TITLE
},
105 {"OutRedirects", N_("redirect: %d"), i_outp_icmp
| I_TITLE
},
106 {"OutEchos", N_("echo request: %d"), i_outp_icmp
| I_TITLE
},
107 {"OutEchoReps", N_("echo replies: %d"), i_outp_icmp
| I_TITLE
},
108 {"OutTimestamps", N_("timestamp requests: %d"), i_outp_icmp
| I_TITLE
},
109 {"OutTimestampReps", N_("timestamp replies: %d"), i_outp_icmp
| I_TITLE
},
110 {"OutAddrMasks", N_("address mask requests: %d"), i_outp_icmp
| I_TITLE
},
111 {"OutAddrMaskReps", N_("address mask replies: %d"), i_outp_icmp
| I_TITLE
},
114 struct entry Tcptab
[] =
116 {"RtoAlgorithm", N_("RTO algorithm is %s"), i_rto_alg
| I_STATIC
},
117 {"RtoMin", "", number
},
118 {"RtoMax", "", number
},
119 {"MaxConn", "", number
},
120 {"ActiveOpens", N_("%d active connections openings"), number
},
121 {"PassiveOpens", N_("%d passive connection openings"), number
},
122 {"AttemptFails", N_("%d failed connection attempts"), number
},
123 {"EstabResets", N_("%d connection resets received"), number
},
124 {"CurrEstab", N_("%d connections established"), number
},
125 {"InSegs", N_("%d segments received"), number
},
126 {"OutSegs", N_("%d segments send out"), number
},
127 {"RetransSegs", N_("%d segments retransmited"), number
},
128 {"InErrs", N_("%d bad segments received."), number
},
129 {"OutRsts", N_("%d resets sent"), number
},
132 struct entry Udptab
[] =
134 {"InDatagrams", N_("%d packets received"), number
},
135 {"NoPorts", N_("%d packets to unknown port received."), number
},
136 {"InErrors", N_("%d packet receive errors"), number
},
137 {"OutDatagrams", N_("%d packets sent"), number
},
140 struct entry Tcpexttab
[] =
142 {"SyncookiesSent", N_("%d SYN cookies sent"), opt_number
},
143 {"SyncookiesRecv", N_("%d SYN cookies received"), opt_number
},
144 {"SyncookiesFailed", N_("%d invalid SYN cookies received"), opt_number
},
146 { "EmbryonicRsts", N_("%d resets received for embryonic SYN_RECV sockets"),
148 { "PruneCalled", N_("%d packets pruned from receive queue because of socket"
149 " buffer overrun"), opt_number
},
150 /* obsolete: 2.2.0 doesn't do that anymore */
151 { "RcvPruned", N_("%d packets pruned from out-of-order queue"), opt_number
},
152 { "OfoPruned", N_("%d packets dropped from out-of-order queue because of"
153 " socket buffer overrun"), opt_number
},
154 { "OutOfWindowIcmps", N_("%d ICMP packets dropped because they were "
155 "out-of-window"), opt_number
},
156 { "LockDroppedIcmps", N_("%d ICMP packets dropped because socket was locked"),
167 struct tabtab snmptabs
[] =
169 {"Ip", Iptab
, sizeof(Iptab
), &f_raw
},
170 {"Icmp", Icmptab
, sizeof(Icmptab
), &f_raw
},
171 {"Tcp", Tcptab
, sizeof(Tcptab
), &f_tcp
},
172 {"Udp", Udptab
, sizeof(Udptab
), &f_udp
},
173 {"TcpExt", Tcpexttab
, sizeof(Tcpexttab
), &f_tcp
},
179 int cmpentries(const void *a
, const void *b
)
181 return strcmp(((struct entry
*) a
)->title
, ((struct entry
*) b
)->title
);
184 void printval(struct tabtab
*tab
, char *title
, int val
)
186 struct entry
*ent
, key
;
191 ent
= bsearch(&key
, tab
->tab
, tab
->size
/ sizeof(struct entry
),
192 sizeof(struct entry
), cmpentries
);
193 if (!ent
) { /* try our best */
194 printf("%*s%s: %d\n", states
[state
].indent
, "", title
, val
);
198 if (type
& I_STATIC
) {
203 if (*ent
->out
== '\0')
206 if (type
& I_TITLE
) {
209 printf("%*s%s\n", states
[state
].indent
, "", _(states
[type
].title
));
218 snprintf(buf
, sizeof(buf
), _(ent
->out
), val
);
222 snprintf(buf
, sizeof(buf
), _(ent
->out
), val
== 2 ? _("enabled") : _("disabled"));
227 snprintf(buf
, sizeof(buf
), _(ent
->out
), val
);
229 case i_rto_alg
: /* XXXX */
235 printf("%*s%s\n", states
[type
].indent
, "", buf
);
240 struct tabtab
*newtable(struct tabtab
*tabs
, char *title
)
244 for (t
= tabs
; t
->title
; t
++)
245 if (!strcmp(title
, t
->title
)) {
247 printf("%s:\n", _(title
));
255 void process_fd(FILE *f
)
257 char buf1
[512], buf2
[512];
259 while (fgets(buf1
, sizeof buf1
, f
)) {
263 if (!fgets(buf2
, sizeof buf2
, f
))
265 sp
= strchr(buf1
, ':');
266 np
= strchr(buf2
, ':');
270 tab
= newtable(snmptabs
, buf1
);
272 UFWARN((printf(_("unknown title %s\n"), buf1
)));
280 sp
+= strspn(sp
, " \t\n");
281 np
+= strspn(np
, " \t\n");
282 /*if (*np == '\0') goto formaterr; */
284 p
= sp
+strcspn(sp
, " \t\n");
289 if (*sp
!= '\0' && *(tab
->flag
))
290 printval(tab
, sp
, strtoul(np
, &np
, 10));
298 perror(_("error parsing /proc/net/snmp"));
303 void parsesnmp(int flag_raw
, int flag_tcp
, int flag_udp
)
307 f_raw
= flag_raw
; f_tcp
= flag_tcp
; f_udp
= flag_udp
;
309 f
= fopen("/proc/net/snmp", "r");
311 perror(_("cannot open /proc/net/snmp"));
317 perror("/proc/net/snmp");
321 f
= fopen("/proc/net/netstat", "r");
327 perror("/proc/net/netstat");
339 /* we sort at runtime because I'm lazy ;) */
340 for (t
= snmptabs
; t
->title
; t
++)
341 qsort(t
->tab
, t
->size
/ sizeof(struct entry
),
342 sizeof(struct entry
), cmpentries
);