1 /* Copyright '97 by Andi Kleen. Subject to the GPL. */
10 enum State { number = 0, i_forward, i_inp_icmp, i_outp_icmp, i_rto_alg };
19 static enum State state;
20 static int indent[] = { 4, 4, 8, 8, 4 }; /* for each state */
22 #define I_STATIC (1<<16) /* static configuration option. */
23 #define I_TITLE (1<<17)
25 char *titles[] = { /* for each state */
27 "ICMP input histogram:",
28 "ICMP output histogram:",
32 /* XXX check against the snmp mib rfc.
34 struct entry Iptab[] = {
35 { "Forwarding", "Forwarding is %s", i_forward|I_STATIC },
36 { "DefaultTTL", "Default TTL is %d", number|I_STATIC },
37 { "InReceives", "%d total packets received", number },
38 { "InHdrErrors", "%d with invalid headers", number },
39 { "InAddrErrors", "%d with invalid addresses", number },
40 { "ForwDatagrams", "%d forwarded", number },
41 { "InUnknownProtos", "%d with unknown protocol", number },
42 { "InDiscards", "%d incoming packets discarded", number },
43 { "InDelivers", "%d incoming packets delivered", number },
44 { "OutRequests", "%d requests sent out", number }, /*?*/
45 { "OutDiscards", "%d outgoing packets dropped", number },
46 { "OutNoRoutes", "%d dropped because of missing route", number },
47 { "ReasmTimeout", "%d fragments dropped after timeout", number },
48 { "ReasmReqds", "%d reassemblies required", number }, /* ? */
49 { "ReasmOKs", "%d packets reassembled ok", number },
50 { "ReasmFails", "%d packet reassembles failed", number },
51 { "FragOKs", "%d fragments received ok", number },
52 { "FragFails", "%d fragments failed", number },
53 { "FragCreates", "%d fragments created", number }
56 struct entry Icmptab[] = {
57 { "InMsgs", "%d ICMP messages received", number },
58 { "InErrors", "%d input ICMP message failed.", number },
59 { "InDestUnreachs", "destination unreachable: %d", i_inp_icmp|I_TITLE },
60 { "InTimeExcds", "timeout in transit: %d", i_inp_icmp|I_TITLE },
61 { "InParmProbs", "wrong parameters: %d", i_inp_icmp|I_TITLE }, /*?*/
62 { "InSrcQuenchs", "source quenchs: %d", i_inp_icmp|I_TITLE },
63 { "InRedirects", "redirects: %d", i_inp_icmp|I_TITLE },
64 { "InEchos", "echo requests: %d", i_inp_icmp|I_TITLE },
65 { "InEchoReps", "echo replies: %d", i_inp_icmp|I_TITLE },
66 { "InTimestamps", "timestamp request: %d", i_inp_icmp|I_TITLE },
67 { "InTimestampReps", "timestamp reply: %d", i_inp_icmp|I_TITLE },
68 { "InAddrMasks", "address mask request: %d", i_inp_icmp|I_TITLE }, /*?*/
69 { "InAddrMaskReps", "address mask replies", i_inp_icmp|I_TITLE }, /*?*/
70 { "OutMsgs", "%d ICMP messages sent", number },
71 { "OutErrors", "%d ICMP messages failed", number },
72 { "OutDestUnreachs", "destination unreachable: %d", i_outp_icmp|I_TITLE },
73 { "OutTimeExcds", "time exceeded: %d", i_outp_icmp|I_TITLE },
74 { "OutParmProbs", "wrong parameters: %d", i_outp_icmp|I_TITLE }, /*?*/
75 { "OutSrcQuenchs", "source quench: %d", i_outp_icmp|I_TITLE },
76 { "OutRedirects", "redirect: %d", i_outp_icmp|I_TITLE },
77 { "OutEchos", "echo request: %d", i_outp_icmp|I_TITLE },
78 { "OutEchoReps", "echo replies: %d", i_outp_icmp|I_TITLE },
79 { "OutTimestamps", "timestamp requests: %d", i_outp_icmp|I_TITLE },
80 { "OutTimestampReps", "timestamp replies: %d", i_outp_icmp|I_TITLE },
81 { "OutAddrMasks", "address mask requests: %d", i_outp_icmp|I_TITLE },
82 { "OutAddrMaskReps", "address mask replies: %d", i_outp_icmp|I_TITLE },
85 struct entry Tcptab[] = {
86 { "RtoAlgorithm", "RTO algorithm is %s", i_rto_alg|I_STATIC },
87 { "RtoMin", "", number },
88 { "RtoMax", "", number },
89 { "MaxConn", "", number },
90 { "ActiveOpens", "%d active opens", number },
91 { "PassiveOpens", "%d passive opens", number },
92 { "AttemptFails", "%d failed connection attempts", number },
93 { "EstabResets", "%d connection resets received", number },
94 { "CurrEstab", "%d connections established", number },
95 { "InSegs", "%d segments received", number },
96 { "OutSegs", "%d segments send out", number },
97 { "RetransSegs", "%d segments retransmited", number },
100 struct entry Udptab[] = {
101 { "InDatagrams", "%d packets received", number },
102 { "NoPorts", "%d packets to unknown port received.", number },
103 { "InErrors", "%d packet receive errors", number },
104 { "OutDatagrams", "%d packets send", number },
113 struct tabtab snmptabs[] = {
114 { "Ip", Iptab, sizeof(Iptab) },
115 { "Icmp", Icmptab, sizeof(Icmptab) },
116 { "Tcp", Tcptab, sizeof(Tcptab) },
117 { "Udp", Udptab, sizeof(Udptab) },
121 static char *skiptok(char *s)
123 while (!isspace(*s) && *s != '\0')
131 int cmpentries(const void *a, const void *b)
133 return strcmp( ((struct entry*)a)->title, ((struct entry*)b)->title);
136 void printval(struct tabtab *tab, char *title, int val)
138 struct entry *ent, key;
143 ent = bsearch(&key, tab->tab, tab->size/sizeof(struct entry),
144 sizeof(struct entry), cmpentries);
145 if (!ent) /* XXX warning */
148 if (type & I_STATIC) {
153 if (*ent->out == '\0')
156 if (type & I_TITLE) {
159 printf("%*s%s\n", indent[state], "", titles[type]);
165 sprintf(buf, ent->out, val);
169 sprintf(buf, ent->out, val == 2 ? "enabled" : "disabled");
174 sprintf(buf,ent->out, val);
177 case i_rto_alg: /* XXXX */
183 printf("%*s%s\n",indent[type],"", buf);
188 struct tabtab *newtable(struct tabtab *tabs, char *title)
192 for (t = tabs; t->title; t++)
193 if (!strcmp(title, t->title)) {
194 printf("%s:\n", title);
204 char buf1[512], buf2[512];
207 f = fopen("/proc/net/snmp", "r");
209 perror("cannot open /proc/net/snmp");
212 while (fgets(buf1,sizeof buf1,f)) {
216 if (!fgets(buf2,sizeof buf2,f)) break;
217 sp = strchr(buf1, ':');
218 np = strchr(buf2, ':');
222 tab = newtable(snmptabs, buf1);
223 if (tab == NULL) /* XXX print warning */
229 while(isspace(*sp)) sp++;
230 while(isspace(*np)) np++;
231 /*if (*np == '\0') goto formaterr;*/
234 if (*p == '\0') endflag=1;
236 printval(tab, sp, strtoul(np,&np,10));
241 perror("/proc/net/snmp");
246 perror("error parsing /proc/net/snmp");
254 /* we sort at runtime because I'm lazy ;) */
255 for (t = snmptabs; t->title; t++)
256 qsort(t->tab, t->size/sizeof(struct entry),
257 sizeof(struct entry), cmpentries);