statistics.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /*
  2. * Copyright 1997,1999,2000 Andi Kleen. Subject to the GPL.
  3. * $Id: statistics.c,v 1.23 2010-10-29 19:24:36 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
  7. */
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "config.h"
  13. #include "intl.h"
  14. #include "proc.h"
  15. /* #define WARN 1 */
  16. #ifdef WARN
  17. #define UFWARN(x) x
  18. #else
  19. #define UFWARN(x)
  20. #endif
  21. int print_static,f_raw,f_tcp,f_udp,f_unknown = 1;
  22. enum State {
  23. number = 0, opt_number, i_forward, i_inp_icmp, i_outp_icmp, i_rto_alg,
  24. MaxState
  25. };
  26. #define normal number
  27. struct entry {
  28. char *title;
  29. char *out;
  30. enum State type;
  31. };
  32. struct statedesc {
  33. int indent;
  34. char *title;
  35. };
  36. struct statedesc states[] = {
  37. [number] = { 4, NULL },
  38. [opt_number] = { 4, NULL },
  39. [i_forward] = { 4, NULL },
  40. [i_inp_icmp] = { 8, N_("ICMP input histogram:") },
  41. [i_outp_icmp] = { 8, N_("ICMP output histogram:") },
  42. [MaxState] = {0},
  43. };
  44. static enum State state;
  45. #define I_STATIC (1<<16) /* static configuration option. */
  46. #define I_TITLE (1<<17)
  47. /*
  48. * XXX check against the snmp mib rfc.
  49. *
  50. * Don't mark the first field as translatable! It's a snmp MIB standard.
  51. * - acme
  52. */
  53. struct entry Iptab[] =
  54. {
  55. {"Forwarding", N_("Forwarding is %s"), i_forward | I_STATIC},
  56. {"DefaultTTL", N_("Default TTL is %llu"), number | I_STATIC},
  57. {"InReceives", N_("%llu total packets received"), number},
  58. {"InHdrErrors", N_("%llu with invalid headers"), opt_number},
  59. {"InAddrErrors", N_("%llu with invalid addresses"), opt_number},
  60. {"ForwDatagrams", N_("%llu forwarded"), number},
  61. {"InUnknownProtos", N_("%llu with unknown protocol"), opt_number},
  62. {"InDiscards", N_("%llu incoming packets discarded"), number},
  63. {"InDelivers", N_("%llu incoming packets delivered"), number},
  64. {"OutRequests", N_("%llu requests sent out"), number}, /*? */
  65. {"OutDiscards", N_("%llu outgoing packets dropped"), opt_number},
  66. {"OutNoRoutes", N_("%llu dropped because of missing route"), opt_number},
  67. {"ReasmTimeout", N_("%llu fragments dropped after timeout"), opt_number},
  68. {"ReasmReqds", N_("%llu reassemblies required"), opt_number}, /* ? */
  69. {"ReasmOKs", N_("%llu packets reassembled ok"), opt_number},
  70. {"ReasmFails", N_("%llu packet reassembles failed"), opt_number},
  71. {"FragOKs", N_("%llu fragments received ok"), opt_number},
  72. {"FragFails", N_("%llu fragments failed"), opt_number},
  73. {"FragCreates", N_("%llu fragments created"), opt_number}
  74. };
  75. struct entry Ip6tab[] =
  76. {
  77. {"Ip6InReceives", N_("%llu total packets received"), number},
  78. {"Ip6InHdrErrors", N_("%llu with invalid headers"), opt_number},
  79. {"Ip6InTooBigErrors", N_("%llu with packets too big"), opt_number},
  80. {"Ip6InNoRoutes", N_("%llu incoming packets with no route"), opt_number},
  81. {"Ip6InAddrErrors", N_("%llu with invalid addresses"), opt_number},
  82. {"Ip6InUnknownProtos", N_("%llu with unknown protocol"), opt_number},
  83. {"Ip6InTruncatedPkts", N_("%llu with truncated packets"), opt_number},
  84. {"Ip6InDiscards", N_("%llu incoming packets discarded"), number},
  85. {"Ip6InDelivers", N_("%llu incoming packets delivered"), number},
  86. {"Ip6OutForwDatagrams", N_("%llu forwarded"), number},
  87. {"Ip6OutRequests", N_("%llu requests sent out"), number}, /*? */
  88. {"Ip6OutDiscards", N_("%llu outgoing packets dropped"), opt_number},
  89. {"Ip6OutNoRoutes", N_("%llu dropped because of missing route"), opt_number},
  90. {"Ip6ReasmTimeout", N_("%llu fragments dropped after timeout"), opt_number},
  91. {"Ip6ReasmReqds", N_("%llu reassemblies required"), opt_number}, /* ? */
  92. {"Ip6ReasmOKs", N_("%llu packets reassembled ok"), opt_number},
  93. {"Ip6ReasmFails", N_("%llu packet reassembles failed"), opt_number},
  94. {"Ip6FragOKs", N_("%llu fragments received ok"), opt_number},
  95. {"Ip6FragFails", N_("%llu fragments failed"), opt_number},
  96. {"Ip6FragCreates", N_("%llu fragments created"), opt_number},
  97. {"Ip6InMcastPkts", N_("%llu incoming multicast packets"), opt_number},
  98. {"Ip6OutMcastPkts", N_("%llu outgoing multicast packets"), opt_number}
  99. };
  100. struct entry Icmptab[] =
  101. {
  102. {"InMsgs", N_("%llu ICMP messages received"), number},
  103. {"InErrors", N_("%llu input ICMP message failed."), number},
  104. {"InDestUnreachs", N_("destination unreachable: %llu"), i_inp_icmp | I_TITLE},
  105. {"InTimeExcds", N_("timeout in transit: %llu"), i_inp_icmp | I_TITLE},
  106. {"InParmProbs", N_("wrong parameters: %llu"), i_inp_icmp | I_TITLE}, /*? */
  107. {"InSrcQuenchs", N_("source quenches: %llu"), i_inp_icmp | I_TITLE},
  108. {"InRedirects", N_("redirects: %llu"), i_inp_icmp | I_TITLE},
  109. {"InEchos", N_("echo requests: %llu"), i_inp_icmp | I_TITLE},
  110. {"InEchoReps", N_("echo replies: %llu"), i_inp_icmp | I_TITLE},
  111. {"InTimestamps", N_("timestamp request: %llu"), i_inp_icmp | I_TITLE},
  112. {"InTimestampReps", N_("timestamp reply: %llu"), i_inp_icmp | I_TITLE},
  113. {"InAddrMasks", N_("address mask request: %llu"), i_inp_icmp | I_TITLE}, /*? */
  114. {"InAddrMaskReps", N_("address mask replies: %llu"), i_inp_icmp | I_TITLE}, /*? */
  115. {"OutMsgs", N_("%llu ICMP messages sent"), number},
  116. {"OutErrors", N_("%llu ICMP messages failed"), number},
  117. {"OutDestUnreachs", N_("destination unreachable: %llu"), i_outp_icmp | I_TITLE},
  118. {"OutTimeExcds", N_("time exceeded: %llu"), i_outp_icmp | I_TITLE},
  119. {"OutParmProbs", N_("wrong parameters: %llu"), i_outp_icmp | I_TITLE}, /*? */
  120. {"OutSrcQuenchs", N_("source quench: %llu"), i_outp_icmp | I_TITLE},
  121. {"OutRedirects", N_("redirect: %llu"), i_outp_icmp | I_TITLE},
  122. {"OutEchos", N_("echo request: %llu"), i_outp_icmp | I_TITLE},
  123. {"OutEchoReps", N_("echo replies: %llu"), i_outp_icmp | I_TITLE},
  124. {"OutTimestamps", N_("timestamp requests: %llu"), i_outp_icmp | I_TITLE},
  125. {"OutTimestampReps", N_("timestamp replies: %llu"), i_outp_icmp | I_TITLE},
  126. {"OutAddrMasks", N_("address mask requests: %llu"), i_outp_icmp | I_TITLE},
  127. {"OutAddrMaskReps", N_("address mask replies: %llu"), i_outp_icmp | I_TITLE},
  128. };
  129. struct entry Icmp6tab[] =
  130. {
  131. {"Icmp6InMsgs", N_("%llu ICMP messages received"), number},
  132. {"Icmp6InErrors", N_("%llu input ICMP message failed."), number},
  133. {"Icmp6InDestUnreachs", N_("destination unreachable: %llu"), i_inp_icmp | I_TITLE},
  134. {"Icmp6InPktTooBigs", N_("packets too big: %llu"), i_inp_icmp | I_TITLE},
  135. {"Icmp6InTimeExcds", N_("received ICMPv6 time exceeded: %llu"), i_inp_icmp | I_TITLE},
  136. {"Icmp6InParmProblems", N_("parameter problem: %llu"), i_inp_icmp | I_TITLE},
  137. {"Icmp6InEchos", N_("echo requests: %llu"), i_inp_icmp | I_TITLE},
  138. {"Icmp6InEchoReplies", N_("echo replies: %llu"), i_inp_icmp | I_TITLE},
  139. {"Icmp6InGroupMembQueries", N_("group member queries: %llu"), i_inp_icmp | I_TITLE},
  140. {"Icmp6InGroupMembResponses", N_("group member responses: %llu"), i_inp_icmp | I_TITLE},
  141. {"Icmp6InGroupMembReductions", N_("group member reductions: %llu"), i_inp_icmp | I_TITLE},
  142. {"Icmp6InRouterSolicits", N_("router solicits: %llu"), i_inp_icmp | I_TITLE},
  143. {"Icmp6InRouterAdvertisements", N_("router advertisement: %llu"), i_inp_icmp | I_TITLE},
  144. {"Icmp6InNeighborSolicits", N_("neighbour solicits: %llu"), i_inp_icmp | I_TITLE},
  145. {"Icmp6InNeighborAdvertisements", N_("neighbour advertisement: %llu"), i_inp_icmp | I_TITLE},
  146. {"Icmp6InRedirects", N_("redirects: %llu"), i_inp_icmp | I_TITLE},
  147. {"Icmp6OutMsgs", N_("%llu ICMP messages sent"), number},
  148. {"Icmp6OutDestUnreachs", N_("destination unreachable: %llu"), i_outp_icmp | I_TITLE},
  149. {"Icmp6OutPktTooBigs", N_("packets too big: %llu"), i_outp_icmp | I_TITLE},
  150. {"Icmp6OutTimeExcds", N_("sent ICMPv6 time exceeded: %llu"), i_outp_icmp | I_TITLE},
  151. {"Icmp6OutParmProblems", N_("parameter problem: %llu"), i_outp_icmp | I_TITLE},
  152. {"Icmp6OutEchos", N_("echo requests: %llu"), i_outp_icmp | I_TITLE},
  153. {"Icmp6OutEchoReplies", N_("echo replies: %llu"), i_outp_icmp | I_TITLE},
  154. {"Icmp6OutGroupMembQueries", N_("group member queries: %llu"), i_outp_icmp | I_TITLE},
  155. {"Icmp6OutGroupMembResponses", N_("group member responses: %llu"), i_outp_icmp | I_TITLE},
  156. {"Icmp6OutGroupMembReductions", N_("group member reductions: %llu"), i_outp_icmp | I_TITLE},
  157. {"Icmp6OutRouterSolicits", N_("router solicits: %llu"), i_outp_icmp | I_TITLE},
  158. {"Icmp6OutRouterAdvertisements ", N_("router advertisement: %llu"), i_outp_icmp | I_TITLE},
  159. {"Icmp6OutNeighborSolicits", N_("neighbor solicits: %llu"), i_outp_icmp | I_TITLE},
  160. {"Icmp6OutNeighborAdvertisements", N_("neighbor advertisements: %llu"), i_outp_icmp | I_TITLE},
  161. {"Icmp6OutRedirects", N_("redirects: %llu"), i_outp_icmp | I_TITLE},
  162. };
  163. struct entry Tcptab[] =
  164. {
  165. {"RtoAlgorithm", N_("RTO algorithm is %s"), i_rto_alg | I_STATIC},
  166. {"RtoMin", "", number},
  167. {"RtoMax", "", number},
  168. {"MaxConn", "", number},
  169. {"ActiveOpens", N_("%llu active connections openings"), number},
  170. {"PassiveOpens", N_("%llu passive connection openings"), number},
  171. {"AttemptFails", N_("%llu failed connection attempts"), number},
  172. {"EstabResets", N_("%llu connection resets received"), number},
  173. {"CurrEstab", N_("%llu connections established"), number},
  174. {"InSegs", N_("%llu segments received"), number},
  175. {"OutSegs", N_("%llu segments send out"), number},
  176. {"RetransSegs", N_("%llu segments retransmited"), number},
  177. {"InErrs", N_("%llu bad segments received."), number},
  178. {"OutRsts", N_("%llu resets sent"), number},
  179. };
  180. struct entry Udptab[] =
  181. {
  182. {"InDatagrams", N_("%llu packets received"), number},
  183. {"NoPorts", N_("%llu packets to unknown port received."), number},
  184. {"InErrors", N_("%llu packet receive errors"), number},
  185. {"OutDatagrams", N_("%llu packets sent"), number},
  186. {"RcvbufErrors", N_("%llu receive buffer errors"), number},
  187. {"SndbufErrors", N_("%llu send buffer errors"), number},
  188. };
  189. struct entry Udp6tab[] =
  190. {
  191. {"Udp6InDatagrams", N_("%llu packets received"), number},
  192. {"Udp6NoPorts", N_("%llu packets to unknown port received."), number},
  193. {"Udp6InErrors", N_("%llu packet receive errors"), number},
  194. {"Udp6OutDatagrams", N_("%llu packets sent"), number},
  195. };
  196. struct entry Tcpexttab[] =
  197. {
  198. {"SyncookiesSent", N_("%llu SYN cookies sent"), opt_number},
  199. {"SyncookiesRecv", N_("%llu SYN cookies received"), opt_number},
  200. {"SyncookiesFailed", N_("%llu invalid SYN cookies received"), opt_number},
  201. { "EmbryonicRsts", N_("%llu resets received for embryonic SYN_RECV sockets"),
  202. opt_number },
  203. { "PruneCalled", N_("%llu packets pruned from receive queue because of socket"
  204. " buffer overrun"), opt_number },
  205. /* obsolete: 2.2.0 doesn't do that anymore */
  206. { "RcvPruned", N_("%llu packets pruned from receive queue"), opt_number },
  207. { "OfoPruned", N_("%llu packets dropped from out-of-order queue because of"
  208. " socket buffer overrun"), opt_number },
  209. { "OutOfWindowIcmps", N_("%llu ICMP packets dropped because they were "
  210. "out-of-window"), opt_number },
  211. { "LockDroppedIcmps", N_("%llu ICMP packets dropped because"
  212. " socket was locked"), opt_number },
  213. { "TW", N_("%llu TCP sockets finished time wait in fast timer"), opt_number },
  214. { "TWRecycled", N_("%llu time wait sockets recycled by time stamp"), opt_number },
  215. { "TWKilled", N_("%llu TCP sockets finished time wait in slow timer"), opt_number },
  216. { "PAWSPassive", N_("%llu passive connections rejected because of"
  217. " time stamp"), opt_number },
  218. { "PAWSActive", N_("%llu active connections rejected because of "
  219. "time stamp"), opt_number },
  220. { "PAWSEstab", N_("%llu packets rejects in established connections because of"
  221. " timestamp"), opt_number },
  222. { "DelayedACKs", N_("%llu delayed acks sent"), opt_number },
  223. { "DelayedACKLocked", N_("%llu delayed acks further delayed because of"
  224. " locked socket"), opt_number },
  225. { "DelayedACKLost", N_("Quick ack mode was activated %llu times"), opt_number },
  226. { "ListenOverflows", N_("%llu times the listen queue of a socket overflowed"),
  227. opt_number },
  228. { "ListenDrops", N_("%llu SYNs to LISTEN sockets dropped"), opt_number },
  229. { "TCPPrequeued", N_("%llu packets directly queued to recvmsg prequeue."),
  230. opt_number },
  231. { "TCPDirectCopyFromBacklog", N_("%llu bytes directly in process context from backlog"), opt_number },
  232. { "TCPDirectCopyFromPrequeue", N_("%llu bytes directly received in process context from prequeue"),
  233. opt_number },
  234. { "TCPPrequeueDropped", N_("%llu packets dropped from prequeue"), opt_number },
  235. { "TCPHPHits", N_("%llu packet headers predicted"), number },
  236. { "TCPHPHitsToUser", N_("%llu packets header predicted and "
  237. "directly queued to user"), opt_number },
  238. { "SockMallocOOM", N_("Ran %llu times out of system memory during "
  239. "packet sending"), opt_number },
  240. { "TCPPureAcks", N_("%llu acknowledgments not containing data payload received"), opt_number },
  241. { "TCPHPAcks", N_("%llu predicted acknowledgments"), opt_number },
  242. { "TCPRenoRecovery", N_("%llu times recovered from packet loss due to fast retransmit"), opt_number },
  243. { "TCPSackRecovery", N_("%llu times recovered from packet loss by selective acknowledgements"), opt_number },
  244. { "TCPSACKReneging", N_("%llu bad SACK blocks received"), opt_number },
  245. { "TCPFACKReorder", N_("Detected reordering %llu times using FACK"), opt_number },
  246. { "TCPSACKReorder", N_("Detected reordering %llu times using SACK"), opt_number },
  247. { "TCPTSReorder", N_("Detected reordering %llu times using time stamp"), opt_number },
  248. { "TCPRenoReorder", N_("Detected reordering %llu times using reno fast retransmit"), opt_number },
  249. { "TCPFullUndo", N_("%llu congestion windows fully recovered without slow start"), opt_number },
  250. { "TCPPartialUndo", N_("%llu congestion windows partially recovered using Hoe heuristic"), opt_number },
  251. { "TCPDSackUndo", N_("%llu congestion window recovered without slow start using DSACK"), opt_number },
  252. { "TCPLossUndo", N_("%llu congestion windows recovered without slow start after partial ack"), opt_number },
  253. { "TCPLostRetransmits", N_("%llu retransmits lost"), opt_number },
  254. { "TCPRenoFailures", N_("%llu timeouts after reno fast retransmit"), opt_number },
  255. { "TCPSackFailures", N_("%llu timeouts after SACK recovery"), opt_number },
  256. { "TCPLossFailures", N_("%llu timeouts in loss state"), opt_number },
  257. { "TCPFastRetrans", N_("%llu fast retransmits"), opt_number },
  258. { "TCPForwardRetrans", N_("%llu forward retransmits"), opt_number },
  259. { "TCPSlowStartRetrans", N_("%llu retransmits in slow start"), opt_number },
  260. { "TCPTimeouts", N_("%llu other TCP timeouts"), opt_number },
  261. { "TCPRenoRecoveryFailed", N_("%llu reno fast retransmits failed"), opt_number },
  262. { "TCPSackRecoveryFail", N_("%llu SACK retransmits failed"), opt_number },
  263. { "TCPSchedulerFailed", N_("%llu times receiver scheduled too late for direct processing"), opt_number },
  264. { "TCPRcvCollapsed", N_("%llu packets collapsed in receive queue due to low socket buffer"), opt_number },
  265. { "TCPDSACKOldSent", N_("%llu DSACKs sent for old packets"), opt_number },
  266. { "TCPDSACKOfoSent", N_("%llu DSACKs sent for out of order packets"), opt_number },
  267. { "TCPDSACKRecv", N_("%llu DSACKs received"), opt_number },
  268. { "TCPDSACKOfoRecv", N_("%llu DSACKs for out of order packets received"), opt_number },
  269. { "TCPAbortOnSyn", N_("%llu connections reset due to unexpected SYN"), opt_number },
  270. { "TCPAbortOnData", N_("%llu connections reset due to unexpected data"), opt_number },
  271. { "TCPAbortOnClose", N_("%llu connections reset due to early user close"), opt_number },
  272. { "TCPAbortOnMemory", N_("%llu connections aborted due to memory pressure"), opt_number },
  273. { "TCPAbortOnTimeout", N_("%llu connections aborted due to timeout"), opt_number },
  274. { "TCPAbortOnLinger", N_("%llu connections aborted after user close in linger timeout"), opt_number },
  275. { "TCPAbortFailed", N_("%llu times unable to send RST due to no memory"), opt_number },
  276. { "TCPMemoryPressures", N_("TCP ran low on memory %llu times"), opt_number },
  277. { "TCPLoss", N_("%llu TCP data loss events"), opt_number },
  278. { "TCPDSACKUndo", N_("%llu congestion windows recovered without slow start by DSACK"),
  279. opt_number },
  280. { "TCPRenoRecoveryFail", N_("%llu classic Reno fast retransmits failed"), opt_number },
  281. };
  282. struct tabtab {
  283. char *title;
  284. struct entry *tab;
  285. size_t size;
  286. int *flag;
  287. };
  288. struct tabtab snmptabs[] =
  289. {
  290. {"Ip", Iptab, sizeof(Iptab), &f_raw},
  291. {"Icmp", Icmptab, sizeof(Icmptab), &f_raw},
  292. {"Tcp", Tcptab, sizeof(Tcptab), &f_tcp},
  293. {"Udp", Udptab, sizeof(Udptab), &f_udp},
  294. {"TcpExt", Tcpexttab, sizeof(Tcpexttab), &f_tcp},
  295. {NULL}
  296. };
  297. struct tabtab snmp6tabs[] =
  298. {
  299. {"Ip6", Ip6tab, sizeof(Ip6tab), &f_raw},
  300. {"Icmp6", Icmp6tab, sizeof(Icmp6tab), &f_raw},
  301. {"Udp6", Udp6tab, sizeof(Udp6tab), &f_udp},
  302. {"Tcp6", Tcptab, sizeof(Tcptab), &f_tcp},
  303. {NULL}
  304. };
  305. /* XXX IGMP */
  306. int cmpentries(const void *a, const void *b)
  307. {
  308. return strcmp(((struct entry *) a)->title, ((struct entry *) b)->title);
  309. }
  310. void printval(struct tabtab *tab, char *title, unsigned long long val)
  311. {
  312. struct entry *ent = NULL, key;
  313. int type;
  314. char buf[512];
  315. key.title = title;
  316. if (tab->tab)
  317. ent = bsearch(&key, tab->tab, tab->size / sizeof(struct entry),
  318. sizeof(struct entry), cmpentries);
  319. if (!ent) { /* try our best */
  320. if (val)
  321. printf("%*s%s: %llu\n", states[state].indent, "", title, val);
  322. return;
  323. }
  324. type = ent->type;
  325. if (type & I_STATIC) {
  326. type &= ~I_STATIC;
  327. if (!print_static)
  328. return;
  329. }
  330. if (*ent->out == '\0')
  331. return;
  332. if (type & I_TITLE) {
  333. type &= ~I_TITLE;
  334. if (state != type)
  335. printf("%*s%s\n", states[state].indent, "", _(states[type].title));
  336. }
  337. buf[0] = '\0';
  338. switch (type) {
  339. case opt_number:
  340. if (val == 0)
  341. break;
  342. /*FALL THOUGH*/
  343. case number:
  344. snprintf(buf, sizeof(buf), _(ent->out), val);
  345. break;
  346. case i_forward:
  347. type = normal;
  348. snprintf(buf, sizeof(buf), _(ent->out), val == 2 ? _("enabled") : _("disabled"));
  349. break;
  350. case i_outp_icmp:
  351. case i_inp_icmp:
  352. if (val > 0)
  353. snprintf(buf, sizeof(buf), _(ent->out), val);
  354. break;
  355. case i_rto_alg: /* XXXX */
  356. break;
  357. default:
  358. abort();
  359. }
  360. if (buf[0])
  361. printf("%*s%s\n", states[type].indent, "", buf);
  362. state = type;
  363. }
  364. struct tabtab *newtable(struct tabtab *tabs, char *title)
  365. {
  366. struct tabtab *t;
  367. static struct tabtab dummytab;
  368. for (t = tabs; t->title; t++) {
  369. if (!strcmp(title, t->title)) {
  370. if (*(t->flag))
  371. printf("%s:\n", _(title));
  372. state = normal;
  373. return t;
  374. }
  375. }
  376. if (!f_unknown)
  377. return NULL;
  378. printf("%s:\n", _(title));
  379. dummytab.title = title;
  380. dummytab.flag = &f_unknown;
  381. return &dummytab;
  382. }
  383. int process_fd(FILE *f, int all, char *filter)
  384. {
  385. char buf1[2048], buf2[2048];
  386. char *sp, *np, *p;
  387. while (fgets(buf1, sizeof buf1, f)) {
  388. int endflag;
  389. struct tabtab *tab;
  390. if (buf1[0] == '\n') // skip empty first line in 2.6 kernels
  391. continue;
  392. if (!fgets(buf2, sizeof buf2, f))
  393. break;
  394. sp = strchr(buf1, ':');
  395. np = strchr(buf2, ':');
  396. if (!np || !sp)
  397. goto formaterr;
  398. *sp = '\0';
  399. if (!all)
  400. if (strncmp(buf1, filter, strlen(filter)))
  401. continue;
  402. tab = newtable(snmptabs, buf1);
  403. if (tab == NULL) {
  404. printf("unknown %s\n", buf1);
  405. continue;
  406. }
  407. np++;
  408. sp++;
  409. endflag = 0;
  410. while (!endflag) {
  411. sp += strspn(sp, " \t\n");
  412. np += strspn(np, " \t\n");
  413. /*if (*np == '\0') goto formaterr; */
  414. p = sp+strcspn(sp, " \t\n");
  415. if (*p == '\0')
  416. endflag = 1;
  417. *p = '\0';
  418. if (*sp != '\0' && *(tab->flag))
  419. printval(tab, sp, strtoull(np, &np, 10));
  420. sp = p + 1;
  421. }
  422. }
  423. return 0;
  424. formaterr:
  425. return -1;
  426. }
  427. void cpytitle(char *original, char *new)
  428. {
  429. char *ptr = original;
  430. while(*ptr != '6' && *ptr != '\0') {
  431. *new = *ptr;
  432. new++;
  433. ptr++;
  434. }
  435. *new = *ptr;
  436. new++;
  437. *new = '\0';
  438. }
  439. void process6_fd(FILE *f)
  440. {
  441. char buf1[1024],buf2[50],buf3[1024];
  442. unsigned long long val;
  443. struct tabtab *tab = NULL;
  444. int cpflg = 0;
  445. while (fgets(buf1, sizeof buf1, f)) {
  446. sscanf(buf1, "%s %llu", buf2, &val);
  447. if(!cpflg) {
  448. cpytitle(buf2, buf3);
  449. tab = newtable(snmp6tabs, buf3);
  450. cpflg = 1;
  451. }
  452. if(!strstr(buf2, buf3)) {
  453. cpytitle(buf2, buf3);
  454. tab = newtable(snmp6tabs, buf3);
  455. }
  456. if (*(tab->flag))
  457. printval(tab, buf2, val);
  458. }
  459. }
  460. void parsesnmp(int flag_raw, int flag_tcp, int flag_udp)
  461. {
  462. FILE *f;
  463. f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp;
  464. f = proc_fopen("/proc/net/snmp");
  465. if (!f) {
  466. perror(_("cannot open /proc/net/snmp"));
  467. return;
  468. }
  469. if (process_fd(f, 1, NULL) < 0)
  470. fprintf(stderr, _("Problem while parsing /proc/net/snmp\n"));
  471. if (ferror(f))
  472. perror("/proc/net/snmp");
  473. fclose(f);
  474. f = proc_fopen("/proc/net/netstat");
  475. if (f) {
  476. if (process_fd(f, 1, NULL) <0)
  477. fprintf(stderr, _("Problem while parsing /proc/net/netstat\n"));
  478. if (ferror(f))
  479. perror("/proc/net/netstat");
  480. fclose(f);
  481. }
  482. return;
  483. }
  484. void parsesnmp6(int flag_raw, int flag_tcp, int flag_udp)
  485. {
  486. FILE *f;
  487. f_raw = flag_raw; f_tcp = flag_tcp; f_udp = flag_udp;
  488. f = fopen("/proc/net/snmp6", "r");
  489. if (!f) {
  490. perror(_("cannot open /proc/net/snmp6"));
  491. return;
  492. }
  493. process6_fd(f);
  494. if (ferror(f))
  495. perror("/proc/net/snmp6");
  496. fclose(f);
  497. f = fopen("/proc/net/snmp", "r");
  498. if (!f) {
  499. perror(_("cannot open /proc/net/snmp"));
  500. return;
  501. }
  502. process_fd(f, 0, "Tcp");
  503. if (ferror(f))
  504. perror("/proc/net/snmp");
  505. fclose(f);
  506. }
  507. void inittab(void)
  508. {
  509. struct tabtab *t;
  510. /* we sort at runtime because I'm lazy ;) */
  511. for (t = snmptabs; t->title; t++)
  512. qsort(t->tab, t->size / sizeof(struct entry),
  513. sizeof(struct entry), cmpentries);
  514. }
  515. void inittab6(void)
  516. {
  517. struct tabtab *t;
  518. for (t = snmp6tabs; t->title; t++)
  519. qsort(t->tab, t->size / sizeof(struct entry),
  520. sizeof(struct entry), cmpentries);
  521. }