2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
6 * This file implements the various access functions for the
7 * PROC file system. It is mainly used for debugging and
10 * Version: $Id: proc.c,v 1.45 2001/05/16 16:45:35 davem Exp $
12 * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
13 * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
14 * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
15 * Erik Schoenfelder, <schoenfr@ibr.cs.tu-bs.de>
18 * Alan Cox : UDP sockets show the rxqueue/txqueue
19 * using hint flag for the netinfo.
20 * Pauline Middelink : identd support
21 * Alan Cox : Make /proc safer.
22 * Erik Schoenfelder : /proc/net/snmp
23 * Alan Cox : Handle dead sockets properly.
24 * Gerhard Koerting : Show both timers
25 * Alan Cox : Allow inode to be NULL (kernel socket)
26 * Andi Kleen : Add support for open_requests and
27 * split functions for more readibility.
28 * Andi Kleen : Add support for /proc/net/netstat
29 * Arnaldo C. Melo : Convert to seq_file
31 * This program is free software; you can redistribute it and/or
32 * modify it under the terms of the GNU General Public License
33 * as published by the Free Software Foundation; either version
34 * 2 of the License, or (at your option) any later version.
36 #include <linux/types.h>
38 #include <net/protocol.h>
41 #include <linux/proc_fs.h>
42 #include <linux/seq_file.h>
46 static int fold_prot_inuse(struct proto *proto)
51 for (cpu = 0; cpu < NR_CPUS; cpu++)
52 res += proto->stats[cpu].inuse;
58 * Report socket allocation statistics [mea@utu.fi]
60 static int sockstat_seq_show(struct seq_file *seq, void *v)
62 /* From net/socket.c */
63 extern void socket_seq_show(struct seq_file *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));
77 static int sockstat_seq_open(struct inode *inode, struct file *file)
79 return single_open(file, sockstat_seq_show, NULL);
82 static struct file_operations sockstat_seq_fops = {
84 .open = sockstat_seq_open,
87 .release = single_release,
91 __fold_field(void *mib[], int offt)
93 unsigned long res = 0;
96 for (i = 0; i < NR_CPUS; i++) {
100 *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
103 *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) +
109 #define fold_field(_mib, _nr) __fold_field(_mib, (sizeof(unsigned long) * (_nr)))
112 static struct snmp_item snmp4_ipstats_list[] = {
113 #define __SNMP_GEN(x,y) SNMP_ITEM(struct ipstats_mib, x, y)
114 #define SNMP_GEN(x) __SNMP_GEN(x, #x)
115 SNMP_GEN(InReceives),
116 SNMP_GEN(InHdrErrors),
117 SNMP_GEN(InAddrErrors),
118 __SNMP_GEN(OutForwDatagrams,"ForwDatagrams"), /* for backward compatibility */
119 SNMP_GEN(InUnknownProtos),
120 SNMP_GEN(InDiscards),
121 SNMP_GEN(InDelivers),
122 SNMP_GEN(OutRequests),
123 SNMP_GEN(OutDiscards),
124 SNMP_GEN(OutNoRoutes),
125 SNMP_GEN(ReasmTimeout),
126 SNMP_GEN(ReasmReqds),
128 SNMP_GEN(ReasmFails),
131 SNMP_GEN(FragCreates),
137 * Called from the PROCfs module. This outputs /proc/net/snmp.
139 static int snmp_seq_show(struct seq_file *seq, void *v)
143 seq_printf(seq, "Ip: Forwarding DefaultTTL");
145 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
146 seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
148 seq_printf(seq, "\nIp: %d %d",
149 ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl);
151 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
152 seq_printf(seq, " %lu",
153 __fold_field((void **) ip_statistics,
154 snmp4_ipstats_list[i].offset));
156 seq_printf(seq, "\nIcmp: InMsgs InErrors InDestUnreachs InTimeExcds "
157 "InParmProbs InSrcQuenchs InRedirects InEchos "
158 "InEchoReps InTimestamps InTimestampReps InAddrMasks "
159 "InAddrMaskReps OutMsgs OutErrors OutDestUnreachs "
160 "OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects "
161 "OutEchos OutEchoReps OutTimestamps OutTimestampReps "
162 "OutAddrMasks OutAddrMaskReps\nIcmp:");
165 i < offsetof(struct icmp_mib, dummy) / sizeof(unsigned long); i++)
166 seq_printf(seq, " %lu",
167 fold_field((void **) icmp_statistics, i));
169 seq_printf(seq, "\nTcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens "
170 "PassiveOpens AttemptFails EstabResets CurrEstab "
171 "InSegs OutSegs RetransSegs InErrs OutRsts\nTcp:");
174 i < offsetof(struct tcp_mib, __pad) / sizeof(unsigned long); i++) {
175 if (i == (offsetof(struct tcp_mib, TcpMaxConn) / sizeof(unsigned long)))
176 /* MaxConn field is negative, RFC 2012 */
177 seq_printf(seq, " %ld",
178 fold_field((void **) tcp_statistics, i));
180 seq_printf(seq, " %lu",
181 fold_field((void **) tcp_statistics, i));
184 seq_printf(seq, "\nUdp: InDatagrams NoPorts InErrors OutDatagrams\n"
188 i < offsetof(struct udp_mib, __pad) / sizeof(unsigned long); i++)
189 seq_printf(seq, " %lu",
190 fold_field((void **) udp_statistics, i));
196 static int snmp_seq_open(struct inode *inode, struct file *file)
198 return single_open(file, snmp_seq_show, NULL);
201 static struct file_operations snmp_seq_fops = {
202 .owner = THIS_MODULE,
203 .open = snmp_seq_open,
206 .release = single_release,
210 * Output /proc/net/netstat
212 static int netstat_seq_show(struct seq_file *seq, void *v)
216 seq_puts(seq, "TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed"
217 " EmbryonicRsts PruneCalled RcvPruned OfoPruned"
218 " OutOfWindowIcmps LockDroppedIcmps ArpFilter"
219 " TW TWRecycled TWKilled"
220 " PAWSPassive PAWSActive PAWSEstab"
221 " DelayedACKs DelayedACKLocked DelayedACKLost"
222 " ListenOverflows ListenDrops"
223 " TCPPrequeued TCPDirectCopyFromBacklog"
224 " TCPDirectCopyFromPrequeue TCPPrequeueDropped"
225 " TCPHPHits TCPHPHitsToUser"
226 " TCPPureAcks TCPHPAcks"
227 " TCPRenoRecovery TCPSackRecovery"
229 " TCPFACKReorder TCPSACKReorder TCPRenoReorder"
231 " TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo"
232 " TCPLoss TCPLostRetransmit"
233 " TCPRenoFailures TCPSackFailures TCPLossFailures"
234 " TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans"
236 " TCPRenoRecoveryFail TCPSackRecoveryFail"
237 " TCPSchedulerFailed TCPRcvCollapsed"
238 " TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv"
240 " TCPAbortOnSyn TCPAbortOnData TCPAbortOnClose"
241 " TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger"
242 " TCPAbortFailed TCPMemoryPressures\n"
245 i < offsetof(struct linux_mib, __pad) / sizeof(unsigned long);
247 seq_printf(seq, " %lu",
248 fold_field((void **) net_statistics, i));
253 static int netstat_seq_open(struct inode *inode, struct file *file)
255 return single_open(file, netstat_seq_show, NULL);
258 static struct file_operations netstat_seq_fops = {
259 .owner = THIS_MODULE,
260 .open = netstat_seq_open,
263 .release = single_release,
266 int __init ip_misc_proc_init(void)
270 if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
273 if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
276 if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
281 proc_net_remove("snmp");
283 proc_net_remove("netstat");