1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/types.h>
37#include <net/icmp.h>
38#include <net/protocol.h>
39#include <net/tcp.h>
40#include <net/udp.h>
41#include <linux/proc_fs.h>
42#include <linux/seq_file.h>
43#include <net/sock.h>
44#include <net/raw.h>
45
46static int fold_prot_inuse(struct proto *proto)
47{
48 int res = 0;
49 int cpu;
50
51 for (cpu = 0; cpu < NR_CPUS; cpu++)
52 res += proto->stats[cpu].inuse;
53
54 return res;
55}
56
57
58
59
60static int sockstat_seq_show(struct seq_file *seq, void *v)
61{
62
63 extern void socket_seq_show(struct seq_file *seq);
64
65 socket_seq_show(seq);
66 seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
67 fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
68 tcp_tw_count, atomic_read(&tcp_sockets_allocated),
69 atomic_read(&tcp_memory_allocated));
70 seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
71 seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
72 seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
73 atomic_read(&ip_frag_mem));
74 return 0;
75}
76
77static int sockstat_seq_open(struct inode *inode, struct file *file)
78{
79 return single_open(file, sockstat_seq_show, NULL);
80}
81
82static struct file_operations sockstat_seq_fops = {
83 .owner = THIS_MODULE,
84 .open = sockstat_seq_open,
85 .read = seq_read,
86 .llseek = seq_lseek,
87 .release = single_release,
88};
89
90static unsigned long
91fold_field(void *mib[], int nr)
92{
93 unsigned long res = 0;
94 int i;
95
96 for (i = 0; i < NR_CPUS; i++) {
97 if (!cpu_possible(i))
98 continue;
99 res +=
100 *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
101 sizeof (unsigned long) * nr));
102 res +=
103 *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) +
104 sizeof (unsigned long) * nr));
105 }
106 return res;
107}
108
109
110
111
112static int snmp_seq_show(struct seq_file *seq, void *v)
113{
114 int i;
115
116 seq_printf(seq, "Ip: Forwarding DefaultTTL InReceives InHdrErrors "
117 "InAddrErrors ForwDatagrams InUnknownProtos "
118 "InDiscards InDelivers OutRequests OutDiscards "
119 "OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs "
120 "ReasmFails FragOKs FragFails FragCreates\nIp: %d %d",
121 ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl);
122
123 for (i = 0;
124 i < offsetof(struct ip_mib, __pad) / sizeof(unsigned long); i++)
125 seq_printf(seq, " %lu",
126 fold_field((void **) ip_statistics, i));
127
128 seq_printf(seq, "\nIcmp: InMsgs InErrors InDestUnreachs InTimeExcds "
129 "InParmProbs InSrcQuenchs InRedirects InEchos "
130 "InEchoReps InTimestamps InTimestampReps InAddrMasks "
131 "InAddrMaskReps OutMsgs OutErrors OutDestUnreachs "
132 "OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects "
133 "OutEchos OutEchoReps OutTimestamps OutTimestampReps "
134 "OutAddrMasks OutAddrMaskReps\nIcmp:");
135
136 for (i = 0;
137 i < offsetof(struct icmp_mib, dummy) / sizeof(unsigned long); i++)
138 seq_printf(seq, " %lu",
139 fold_field((void **) icmp_statistics, i));
140
141 seq_printf(seq, "\nTcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens "
142 "PassiveOpens AttemptFails EstabResets CurrEstab "
143 "InSegs OutSegs RetransSegs InErrs OutRsts\nTcp:");
144
145 for (i = 0;
146 i < offsetof(struct tcp_mib, __pad) / sizeof(unsigned long); i++) {
147 if (i == (offsetof(struct tcp_mib, TcpMaxConn) / sizeof(unsigned long)))
148
149 seq_printf(seq, " %ld",
150 fold_field((void **) tcp_statistics, i));
151 else
152 seq_printf(seq, " %lu",
153 fold_field((void **) tcp_statistics, i));
154 }
155
156 seq_printf(seq, "\nUdp: InDatagrams NoPorts InErrors OutDatagrams\n"
157 "Udp:");
158
159 for (i = 0;
160 i < offsetof(struct udp_mib, __pad) / sizeof(unsigned long); i++)
161 seq_printf(seq, " %lu",
162 fold_field((void **) udp_statistics, i));
163
164 seq_putc(seq, '\n');
165 return 0;
166}
167
168static int snmp_seq_open(struct inode *inode, struct file *file)
169{
170 return single_open(file, snmp_seq_show, NULL);
171}
172
173static struct file_operations snmp_seq_fops = {
174 .owner = THIS_MODULE,
175 .open = snmp_seq_open,
176 .read = seq_read,
177 .llseek = seq_lseek,
178 .release = single_release,
179};
180
181
182
183
184static int netstat_seq_show(struct seq_file *seq, void *v)
185{
186 int i;
187
188 seq_puts(seq, "TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed"
189 " EmbryonicRsts PruneCalled RcvPruned OfoPruned"
190 " OutOfWindowIcmps LockDroppedIcmps ArpFilter"
191 " TW TWRecycled TWKilled"
192 " PAWSPassive PAWSActive PAWSEstab"
193 " DelayedACKs DelayedACKLocked DelayedACKLost"
194 " ListenOverflows ListenDrops"
195 " TCPPrequeued TCPDirectCopyFromBacklog"
196 " TCPDirectCopyFromPrequeue TCPPrequeueDropped"
197 " TCPHPHits TCPHPHitsToUser"
198 " TCPPureAcks TCPHPAcks"
199 " TCPRenoRecovery TCPSackRecovery"
200 " TCPSACKReneging"
201 " TCPFACKReorder TCPSACKReorder TCPRenoReorder"
202 " TCPTSReorder"
203 " TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo"
204 " TCPLoss TCPLostRetransmit"
205 " TCPRenoFailures TCPSackFailures TCPLossFailures"
206 " TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans"
207 " TCPTimeouts"
208 " TCPRenoRecoveryFail TCPSackRecoveryFail"
209 " TCPSchedulerFailed TCPRcvCollapsed"
210 " TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv"
211 " TCPDSACKOfoRecv"
212 " TCPAbortOnSyn TCPAbortOnData TCPAbortOnClose"
213 " TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger"
214 " TCPAbortFailed TCPMemoryPressures\n"
215 "TcpExt:");
216 for (i = 0;
217 i < offsetof(struct linux_mib, __pad) / sizeof(unsigned long);
218 i++)
219 seq_printf(seq, " %lu",
220 fold_field((void **) net_statistics, i));
221 seq_putc(seq, '\n');
222 return 0;
223}
224
225static int netstat_seq_open(struct inode *inode, struct file *file)
226{
227 return single_open(file, netstat_seq_show, NULL);
228}
229
230static struct file_operations netstat_seq_fops = {
231 .owner = THIS_MODULE,
232 .open = netstat_seq_open,
233 .read = seq_read,
234 .llseek = seq_lseek,
235 .release = single_release,
236};
237
238int __init ip_misc_proc_init(void)
239{
240 int rc = 0;
241
242 if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
243 goto out_netstat;
244
245 if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
246 goto out_snmp;
247
248 if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
249 goto out_sockstat;
250out:
251 return rc;
252out_sockstat:
253 proc_net_remove("snmp");
254out_snmp:
255 proc_net_remove("netstat");
256out_netstat:
257 rc = -ENOMEM;
258 goto out;
259}
260
261