1 /* Copyright '97 by Andi Kleen. Subject to the GPL. */
18 enum State { number = 0, i_forward, i_inp_icmp, i_outp_icmp, i_rto_alg };
27 static enum State state;
28 static int indent[] = { 4, 4, 8, 8, 4 }; /* for each state */
30 #define I_STATIC (1<<16) /* static configuration option. */
31 #define I_TITLE (1<<17)
33 char *titles[] = { /* for each state */
35 "ICMP input histogram:",
36 "ICMP output histogram:",
40 /* XXX check against the snmp mib rfc.
42 struct entry Iptab[] = {
43 { "Forwarding", "Forwarding is %s", i_forward|I_STATIC },
44 { "DefaultTTL", "Default TTL is %d", number|I_STATIC },
45 { "InReceives", "%d total packets received", number },
46 { "InHdrErrors", "%d with invalid headers", number },
47 { "InAddrErrors", "%d with invalid addresses", number },
48 { "ForwDatagrams", "%d forwarded", number },
49 { "InUnknownProtos", "%d with unknown protocol", number },
50 { "InDiscards", "%d incoming packets discarded", number },
51 { "InDelivers", "%d incoming packets delivered", number },
52 { "OutRequests", "%d requests sent out", number }, /*?*/
53 { "OutDiscards", "%d outgoing packets dropped", number },
54 { "OutNoRoutes", "%d dropped because of missing route", number },
55 { "ReasmTimeout", "%d fragments dropped after timeout", number },
56 { "ReasmReqds", "%d reassemblies required", number }, /* ? */
57 { "ReasmOKs", "%d packets reassembled ok", number },
58 { "ReasmFails", "%d packet reassembles failed", number },
59 { "FragOKs", "%d fragments received ok", number },
60 { "FragFails", "%d fragments failed", number },
61 { "FragCreates", "%d fragments created", number }
64 struct entry Icmptab[] = {
65 { "InMsgs", "%d ICMP messages received", number },
66 { "InErrors", "%d input ICMP message failed.", number },
67 { "InDestUnreachs", "destination unreachable: %d", i_inp_icmp|I_TITLE },
68 { "InTimeExcds", "timeout in transit: %d", i_inp_icmp|I_TITLE },
69 { "InParmProbs", "wrong parameters: %d", i_inp_icmp|I_TITLE }, /*?*/
70 { "InSrcQuenchs", "source quenchs: %d", i_inp_icmp|I_TITLE },
71 { "InRedirects", "redirects: %d", i_inp_icmp|I_TITLE },
72 { "InEchos", "echo requests: %d", i_inp_icmp|I_TITLE },
73 { "InEchoReps", "echo replies: %d", i_inp_icmp|I_TITLE },
74 { "InTimestamps", "timestamp request: %d", i_inp_icmp|I_TITLE },
75 { "InTimestampReps", "timestamp reply: %d", i_inp_icmp|I_TITLE },
76 { "InAddrMasks", "address mask request: %d", i_inp_icmp|I_TITLE }, /*?*/
77 { "InAddrMaskReps", "address mask replies", i_inp_icmp|I_TITLE }, /*?*/
78 { "OutMsgs", "%d ICMP messages sent", number },
79 { "OutErrors", "%d ICMP messages failed", number },
80 { "OutDestUnreachs", "destination unreachable: %d", i_outp_icmp|I_TITLE },
81 { "OutTimeExcds", "time exceeded: %d", i_outp_icmp|I_TITLE },
82 { "OutParmProbs", "wrong parameters: %d", i_outp_icmp|I_TITLE }, /*?*/
83 { "OutSrcQuenchs", "source quench: %d", i_outp_icmp|I_TITLE },
84 { "OutRedirects", "redirect: %d", i_outp_icmp|I_TITLE },
85 { "OutEchos", "echo request: %d", i_outp_icmp|I_TITLE },
86 { "OutEchoReps", "echo replies: %d", i_outp_icmp|I_TITLE },
87 { "OutTimestamps", "timestamp requests: %d", i_outp_icmp|I_TITLE },
88 { "OutTimestampReps", "timestamp replies: %d", i_outp_icmp|I_TITLE },
89 { "OutAddrMasks", "address mask requests: %d", i_outp_icmp|I_TITLE },
90 { "OutAddrMaskReps", "address mask replies: %d", i_outp_icmp|I_TITLE },
93 struct entry Tcptab[] = {
94 { "RtoAlgorithm", "RTO algorithm is %s", i_rto_alg|I_STATIC },
95 { "RtoMin", "", number },
96 { "RtoMax", "", number },
97 { "MaxConn", "", number },
98 { "ActiveOpens", "%d active opens", number },
99 { "PassiveOpens", "%d passive opens", number },
100 { "AttemptFails", "%d failed connection attempts", number },
101 { "EstabResets", "%d connection resets received", number },
102 { "CurrEstab", "%d connections established", number },
103 { "InSegs", "%d segments received", number },
104 { "OutSegs", "%d segments send out", number },
105 { "RetransSegs", "%d segments retransmited", number },
106 { "InErrs", "%d bad segments received.", number },
107 { "OutRsts", "%d resets sent", number },
110 struct entry Udptab[] = {
111 { "InDatagrams", "%d packets received", number },
112 { "NoPorts", "%d packets to unknown port received.", number },
113 { "InErrors", "%d packet receive errors", number },
114 { "OutDatagrams", "%d packets send", number },
123 struct tabtab snmptabs[] = {
124 { "Ip", Iptab, sizeof(Iptab) },
125 { "Icmp", Icmptab, sizeof(Icmptab) },
126 { "Tcp", Tcptab, sizeof(Tcptab) },
127 { "Udp", Udptab, sizeof(Udptab) },
131 static char *skiptok(char *s)
133 while (!isspace(*s) && *s != '\0')
141 int cmpentries(const void *a, const void *b)
143 return strcmp( ((struct entry*)a)->title, ((struct entry*)b)->title);
146 void printval(struct tabtab *tab, char *title, int val)
148 struct entry *ent, key;
153 ent = bsearch(&key, tab->tab, tab->size/sizeof(struct entry),
154 sizeof(struct entry), cmpentries);
155 if (!ent) { /* try our best */
156 printf("%*s%s: %d\n", indent[state], "", title, val);
160 if (type & I_STATIC) {
165 if (*ent->out == '\0')
168 if (type & I_TITLE) {
171 printf("%*s%s\n", indent[state], "", titles[type]);
177 sprintf(buf, ent->out, val);
181 sprintf(buf, ent->out, val == 2 ? "enabled" : "disabled");
186 sprintf(buf,ent->out, val);
189 case i_rto_alg: /* XXXX */
195 printf("%*s%s\n",indent[type],"", buf);
200 struct tabtab *newtable(struct tabtab *tabs, char *title)
204 for (t = tabs; t->title; t++)
205 if (!strcmp(title, t->title)) {
206 printf("%s:\n", title);
216 char buf1[512], buf2[512];
219 f = fopen("/proc/net/snmp", "r");
221 perror("cannot open /proc/net/snmp");
224 while (fgets(buf1,sizeof buf1,f)) {
228 if (!fgets(buf2,sizeof buf2,f)) break;
229 sp = strchr(buf1, ':');
230 np = strchr(buf2, ':');
234 tab = newtable(snmptabs, buf1);
236 UFWARN((printf("unknown title %s\n", buf1)));
243 while(isspace(*sp)) sp++;
244 while(isspace(*np)) np++;
245 /*if (*np == '\0') goto formaterr;*/
248 if (*p == '\0') endflag=1;
251 if (*sp != '\0') /* XXX */
252 printval(tab, sp, strtoul(np,&np,10));
257 perror("/proc/net/snmp");
262 perror("error parsing /proc/net/snmp");
270 /* we sort at runtime because I'm lazy ;) */
271 for (t = snmptabs; t->title; t++)
272 qsort(t->tab, t->size/sizeof(struct entry),
273 sizeof(struct entry), cmpentries);