2005-04-17 02:20:36 +04:00
/*
* INET An implementation of the TCP / IP protocol suite for the LINUX
* operating system . INET is implemented using the BSD Socket
* interface as the means of communication with the user level .
*
* This file implements the various access functions for the
* PROC file system . It is mainly used for debugging and
* statistics .
*
* Authors : Fred N . van Kempen , < waltje @ uWalt . NL . Mugnet . ORG >
* Gerald J . Heim , < heim @ peanuts . informatik . uni - tuebingen . de >
* Fred Baumgarten , < dc6iq @ insu1 . etec . uni - karlsruhe . de >
* Erik Schoenfelder , < schoenfr @ ibr . cs . tu - bs . de >
*
* Fixes :
* Alan Cox : UDP sockets show the rxqueue / txqueue
* using hint flag for the netinfo .
* Pauline Middelink : identd support
* Alan Cox : Make / proc safer .
* Erik Schoenfelder : / proc / net / snmp
* Alan Cox : Handle dead sockets properly .
* Gerhard Koerting : Show both timers
* Alan Cox : Allow inode to be NULL ( kernel socket )
* Andi Kleen : Add support for open_requests and
* split functions for more readibility .
* Andi Kleen : Add support for / proc / net / netstat
* Arnaldo C . Melo : Convert to seq_file
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# include <linux/types.h>
2007-09-12 14:01:34 +04:00
# include <net/net_namespace.h>
2005-04-17 02:20:36 +04:00
# include <net/icmp.h>
# include <net/protocol.h>
# include <net/tcp.h>
# include <net/udp.h>
2006-11-27 22:10:57 +03:00
# include <net/udplite.h>
2008-12-30 10:04:08 +03:00
# include <linux/bottom_half.h>
2005-12-27 07:43:12 +03:00
# include <linux/inetdevice.h>
2005-04-17 02:20:36 +04:00
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
# include <net/sock.h>
# include <net/raw.h>
/*
* Report socket allocation statistics [ mea @ utu . fi ]
*/
static int sockstat_seq_show ( struct seq_file * seq , void * v )
{
2008-04-01 06:43:18 +04:00
struct net * net = seq - > private ;
2008-12-30 10:04:08 +03:00
int orphans , sockets ;
local_bh_disable ( ) ;
2009-02-16 11:08:56 +03:00
orphans = percpu_counter_sum_positive ( & tcp_orphan_count ) ;
sockets = percpu_counter_sum_positive ( & tcp_sockets_allocated ) ;
2008-12-30 10:04:08 +03:00
local_bh_enable ( ) ;
2008-04-01 06:43:18 +04:00
2005-04-17 02:20:36 +04:00
socket_seq_show ( seq ) ;
seq_printf ( seq , " TCP: inuse %d orphan %d tw %d alloc %d mem %d \n " ,
2008-12-30 10:04:08 +03:00
sock_prot_inuse_get ( net , & tcp_prot ) , orphans ,
tcp_death_row . tw_count , sockets ,
2005-04-17 02:20:36 +04:00
atomic_read ( & tcp_memory_allocated ) ) ;
2008-04-01 06:41:46 +04:00
seq_printf ( seq , " UDP: inuse %d mem %d \n " ,
2008-04-01 06:43:18 +04:00
sock_prot_inuse_get ( net , & udp_prot ) ,
2007-12-31 11:29:24 +03:00
atomic_read ( & udp_memory_allocated ) ) ;
2008-04-01 06:41:46 +04:00
seq_printf ( seq , " UDPLITE: inuse %d \n " ,
2008-04-01 06:43:18 +04:00
sock_prot_inuse_get ( net , & udplite_prot ) ) ;
2008-04-01 06:41:46 +04:00
seq_printf ( seq , " RAW: inuse %d \n " ,
2008-04-01 06:43:18 +04:00
sock_prot_inuse_get ( net , & raw_prot ) ) ;
2007-10-15 13:31:52 +04:00
seq_printf ( seq , " FRAG: inuse %d memory %d \n " ,
2008-04-01 06:43:18 +04:00
ip_frag_nqueues ( net ) , ip_frag_mem ( net ) ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
static int sockstat_seq_open ( struct inode * inode , struct file * file )
{
2008-07-18 15:07:21 +04:00
return single_open_net ( inode , file , sockstat_seq_show ) ;
2008-04-01 06:43:18 +04:00
}
2007-02-12 11:55:35 +03:00
static const struct file_operations sockstat_seq_fops = {
2005-04-17 02:20:36 +04:00
. owner = THIS_MODULE ,
. open = sockstat_seq_open ,
. read = seq_read ,
. llseek = seq_lseek ,
2008-07-18 15:07:44 +04:00
. release = single_release_net ,
2005-04-17 02:20:36 +04:00
} ;
/* snmp items */
2005-11-30 03:21:38 +03:00
static const struct snmp_mib snmp4_ipstats_list [ ] = {
2009-04-27 13:45:02 +04:00
SNMP_MIB_ITEM ( " InReceives " , IPSTATS_MIB_INPKTS ) ,
2005-04-17 02:20:36 +04:00
SNMP_MIB_ITEM ( " InHdrErrors " , IPSTATS_MIB_INHDRERRORS ) ,
SNMP_MIB_ITEM ( " InAddrErrors " , IPSTATS_MIB_INADDRERRORS ) ,
SNMP_MIB_ITEM ( " ForwDatagrams " , IPSTATS_MIB_OUTFORWDATAGRAMS ) ,
SNMP_MIB_ITEM ( " InUnknownProtos " , IPSTATS_MIB_INUNKNOWNPROTOS ) ,
SNMP_MIB_ITEM ( " InDiscards " , IPSTATS_MIB_INDISCARDS ) ,
SNMP_MIB_ITEM ( " InDelivers " , IPSTATS_MIB_INDELIVERS ) ,
2009-04-27 13:45:02 +04:00
SNMP_MIB_ITEM ( " OutRequests " , IPSTATS_MIB_OUTPKTS ) ,
2005-04-17 02:20:36 +04:00
SNMP_MIB_ITEM ( " OutDiscards " , IPSTATS_MIB_OUTDISCARDS ) ,
SNMP_MIB_ITEM ( " OutNoRoutes " , IPSTATS_MIB_OUTNOROUTES ) ,
SNMP_MIB_ITEM ( " ReasmTimeout " , IPSTATS_MIB_REASMTIMEOUT ) ,
SNMP_MIB_ITEM ( " ReasmReqds " , IPSTATS_MIB_REASMREQDS ) ,
SNMP_MIB_ITEM ( " ReasmOKs " , IPSTATS_MIB_REASMOKS ) ,
SNMP_MIB_ITEM ( " ReasmFails " , IPSTATS_MIB_REASMFAILS ) ,
SNMP_MIB_ITEM ( " FragOKs " , IPSTATS_MIB_FRAGOKS ) ,
SNMP_MIB_ITEM ( " FragFails " , IPSTATS_MIB_FRAGFAILS ) ,
SNMP_MIB_ITEM ( " FragCreates " , IPSTATS_MIB_FRAGCREATES ) ,
SNMP_MIB_SENTINEL
} ;
2007-05-14 14:07:30 +04:00
/* Following RFC4293 items are displayed in /proc/net/netstat */
static const struct snmp_mib snmp4_ipextstats_list [ ] = {
SNMP_MIB_ITEM ( " InNoRoutes " , IPSTATS_MIB_INNOROUTES ) ,
SNMP_MIB_ITEM ( " InTruncatedPkts " , IPSTATS_MIB_INTRUNCATEDPKTS ) ,
SNMP_MIB_ITEM ( " InMcastPkts " , IPSTATS_MIB_INMCASTPKTS ) ,
SNMP_MIB_ITEM ( " OutMcastPkts " , IPSTATS_MIB_OUTMCASTPKTS ) ,
SNMP_MIB_ITEM ( " InBcastPkts " , IPSTATS_MIB_INBCASTPKTS ) ,
SNMP_MIB_ITEM ( " OutBcastPkts " , IPSTATS_MIB_OUTBCASTPKTS ) ,
2009-04-27 13:45:02 +04:00
SNMP_MIB_ITEM ( " InOctets " , IPSTATS_MIB_INOCTETS ) ,
SNMP_MIB_ITEM ( " OutOctets " , IPSTATS_MIB_OUTOCTETS ) ,
SNMP_MIB_ITEM ( " InMcastOctets " , IPSTATS_MIB_INMCASTOCTETS ) ,
SNMP_MIB_ITEM ( " OutMcastOctets " , IPSTATS_MIB_OUTMCASTOCTETS ) ,
SNMP_MIB_ITEM ( " InBcastOctets " , IPSTATS_MIB_INBCASTOCTETS ) ,
SNMP_MIB_ITEM ( " OutBcastOctets " , IPSTATS_MIB_OUTBCASTOCTETS ) ,
2007-05-14 14:07:30 +04:00
SNMP_MIB_SENTINEL
} ;
2010-01-22 13:17:26 +03:00
static const struct {
const char * name ;
2007-09-17 20:57:33 +04:00
int index ;
} icmpmibmap [ ] = {
{ " DestUnreachs " , ICMP_DEST_UNREACH } ,
{ " TimeExcds " , ICMP_TIME_EXCEEDED } ,
{ " ParmProbs " , ICMP_PARAMETERPROB } ,
{ " SrcQuenchs " , ICMP_SOURCE_QUENCH } ,
{ " Redirects " , ICMP_REDIRECT } ,
{ " Echos " , ICMP_ECHO } ,
{ " EchoReps " , ICMP_ECHOREPLY } ,
{ " Timestamps " , ICMP_TIMESTAMP } ,
{ " TimestampReps " , ICMP_TIMESTAMPREPLY } ,
{ " AddrMasks " , ICMP_ADDRESS } ,
{ " AddrMaskReps " , ICMP_ADDRESSREPLY } ,
2007-10-09 12:59:42 +04:00
{ NULL , 0 }
2007-09-17 20:57:33 +04:00
} ;
2005-11-30 03:21:38 +03:00
static const struct snmp_mib snmp4_tcp_list [ ] = {
2005-04-17 02:20:36 +04:00
SNMP_MIB_ITEM ( " RtoAlgorithm " , TCP_MIB_RTOALGORITHM ) ,
SNMP_MIB_ITEM ( " RtoMin " , TCP_MIB_RTOMIN ) ,
SNMP_MIB_ITEM ( " RtoMax " , TCP_MIB_RTOMAX ) ,
SNMP_MIB_ITEM ( " MaxConn " , TCP_MIB_MAXCONN ) ,
SNMP_MIB_ITEM ( " ActiveOpens " , TCP_MIB_ACTIVEOPENS ) ,
SNMP_MIB_ITEM ( " PassiveOpens " , TCP_MIB_PASSIVEOPENS ) ,
SNMP_MIB_ITEM ( " AttemptFails " , TCP_MIB_ATTEMPTFAILS ) ,
SNMP_MIB_ITEM ( " EstabResets " , TCP_MIB_ESTABRESETS ) ,
SNMP_MIB_ITEM ( " CurrEstab " , TCP_MIB_CURRESTAB ) ,
SNMP_MIB_ITEM ( " InSegs " , TCP_MIB_INSEGS ) ,
SNMP_MIB_ITEM ( " OutSegs " , TCP_MIB_OUTSEGS ) ,
SNMP_MIB_ITEM ( " RetransSegs " , TCP_MIB_RETRANSSEGS ) ,
SNMP_MIB_ITEM ( " InErrs " , TCP_MIB_INERRS ) ,
SNMP_MIB_ITEM ( " OutRsts " , TCP_MIB_OUTRSTS ) ,
SNMP_MIB_SENTINEL
} ;
2005-11-30 03:21:38 +03:00
static const struct snmp_mib snmp4_udp_list [ ] = {
2005-04-17 02:20:36 +04:00
SNMP_MIB_ITEM ( " InDatagrams " , UDP_MIB_INDATAGRAMS ) ,
SNMP_MIB_ITEM ( " NoPorts " , UDP_MIB_NOPORTS ) ,
SNMP_MIB_ITEM ( " InErrors " , UDP_MIB_INERRORS ) ,
SNMP_MIB_ITEM ( " OutDatagrams " , UDP_MIB_OUTDATAGRAMS ) ,
2006-08-15 10:57:10 +04:00
SNMP_MIB_ITEM ( " RcvbufErrors " , UDP_MIB_RCVBUFERRORS ) ,
SNMP_MIB_ITEM ( " SndbufErrors " , UDP_MIB_SNDBUFERRORS ) ,
2005-04-17 02:20:36 +04:00
SNMP_MIB_SENTINEL
} ;
2005-11-30 03:21:38 +03:00
static const struct snmp_mib snmp4_net_list [ ] = {
2005-04-17 02:20:36 +04:00
SNMP_MIB_ITEM ( " SyncookiesSent " , LINUX_MIB_SYNCOOKIESSENT ) ,
SNMP_MIB_ITEM ( " SyncookiesRecv " , LINUX_MIB_SYNCOOKIESRECV ) ,
SNMP_MIB_ITEM ( " SyncookiesFailed " , LINUX_MIB_SYNCOOKIESFAILED ) ,
SNMP_MIB_ITEM ( " EmbryonicRsts " , LINUX_MIB_EMBRYONICRSTS ) ,
SNMP_MIB_ITEM ( " PruneCalled " , LINUX_MIB_PRUNECALLED ) ,
SNMP_MIB_ITEM ( " RcvPruned " , LINUX_MIB_RCVPRUNED ) ,
SNMP_MIB_ITEM ( " OfoPruned " , LINUX_MIB_OFOPRUNED ) ,
SNMP_MIB_ITEM ( " OutOfWindowIcmps " , LINUX_MIB_OUTOFWINDOWICMPS ) ,
SNMP_MIB_ITEM ( " LockDroppedIcmps " , LINUX_MIB_LOCKDROPPEDICMPS ) ,
SNMP_MIB_ITEM ( " ArpFilter " , LINUX_MIB_ARPFILTER ) ,
SNMP_MIB_ITEM ( " TW " , LINUX_MIB_TIMEWAITED ) ,
SNMP_MIB_ITEM ( " TWRecycled " , LINUX_MIB_TIMEWAITRECYCLED ) ,
SNMP_MIB_ITEM ( " TWKilled " , LINUX_MIB_TIMEWAITKILLED ) ,
SNMP_MIB_ITEM ( " PAWSPassive " , LINUX_MIB_PAWSPASSIVEREJECTED ) ,
SNMP_MIB_ITEM ( " PAWSActive " , LINUX_MIB_PAWSACTIVEREJECTED ) ,
SNMP_MIB_ITEM ( " PAWSEstab " , LINUX_MIB_PAWSESTABREJECTED ) ,
SNMP_MIB_ITEM ( " DelayedACKs " , LINUX_MIB_DELAYEDACKS ) ,
SNMP_MIB_ITEM ( " DelayedACKLocked " , LINUX_MIB_DELAYEDACKLOCKED ) ,
SNMP_MIB_ITEM ( " DelayedACKLost " , LINUX_MIB_DELAYEDACKLOST ) ,
SNMP_MIB_ITEM ( " ListenOverflows " , LINUX_MIB_LISTENOVERFLOWS ) ,
SNMP_MIB_ITEM ( " ListenDrops " , LINUX_MIB_LISTENDROPS ) ,
SNMP_MIB_ITEM ( " TCPPrequeued " , LINUX_MIB_TCPPREQUEUED ) ,
SNMP_MIB_ITEM ( " TCPDirectCopyFromBacklog " , LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG ) ,
SNMP_MIB_ITEM ( " TCPDirectCopyFromPrequeue " , LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE ) ,
SNMP_MIB_ITEM ( " TCPPrequeueDropped " , LINUX_MIB_TCPPREQUEUEDROPPED ) ,
SNMP_MIB_ITEM ( " TCPHPHits " , LINUX_MIB_TCPHPHITS ) ,
SNMP_MIB_ITEM ( " TCPHPHitsToUser " , LINUX_MIB_TCPHPHITSTOUSER ) ,
SNMP_MIB_ITEM ( " TCPPureAcks " , LINUX_MIB_TCPPUREACKS ) ,
SNMP_MIB_ITEM ( " TCPHPAcks " , LINUX_MIB_TCPHPACKS ) ,
SNMP_MIB_ITEM ( " TCPRenoRecovery " , LINUX_MIB_TCPRENORECOVERY ) ,
SNMP_MIB_ITEM ( " TCPSackRecovery " , LINUX_MIB_TCPSACKRECOVERY ) ,
SNMP_MIB_ITEM ( " TCPSACKReneging " , LINUX_MIB_TCPSACKRENEGING ) ,
SNMP_MIB_ITEM ( " TCPFACKReorder " , LINUX_MIB_TCPFACKREORDER ) ,
SNMP_MIB_ITEM ( " TCPSACKReorder " , LINUX_MIB_TCPSACKREORDER ) ,
SNMP_MIB_ITEM ( " TCPRenoReorder " , LINUX_MIB_TCPRENOREORDER ) ,
SNMP_MIB_ITEM ( " TCPTSReorder " , LINUX_MIB_TCPTSREORDER ) ,
SNMP_MIB_ITEM ( " TCPFullUndo " , LINUX_MIB_TCPFULLUNDO ) ,
SNMP_MIB_ITEM ( " TCPPartialUndo " , LINUX_MIB_TCPPARTIALUNDO ) ,
SNMP_MIB_ITEM ( " TCPDSACKUndo " , LINUX_MIB_TCPDSACKUNDO ) ,
SNMP_MIB_ITEM ( " TCPLossUndo " , LINUX_MIB_TCPLOSSUNDO ) ,
SNMP_MIB_ITEM ( " TCPLoss " , LINUX_MIB_TCPLOSS ) ,
SNMP_MIB_ITEM ( " TCPLostRetransmit " , LINUX_MIB_TCPLOSTRETRANSMIT ) ,
SNMP_MIB_ITEM ( " TCPRenoFailures " , LINUX_MIB_TCPRENOFAILURES ) ,
SNMP_MIB_ITEM ( " TCPSackFailures " , LINUX_MIB_TCPSACKFAILURES ) ,
SNMP_MIB_ITEM ( " TCPLossFailures " , LINUX_MIB_TCPLOSSFAILURES ) ,
SNMP_MIB_ITEM ( " TCPFastRetrans " , LINUX_MIB_TCPFASTRETRANS ) ,
SNMP_MIB_ITEM ( " TCPForwardRetrans " , LINUX_MIB_TCPFORWARDRETRANS ) ,
SNMP_MIB_ITEM ( " TCPSlowStartRetrans " , LINUX_MIB_TCPSLOWSTARTRETRANS ) ,
SNMP_MIB_ITEM ( " TCPTimeouts " , LINUX_MIB_TCPTIMEOUTS ) ,
SNMP_MIB_ITEM ( " TCPRenoRecoveryFail " , LINUX_MIB_TCPRENORECOVERYFAIL ) ,
SNMP_MIB_ITEM ( " TCPSackRecoveryFail " , LINUX_MIB_TCPSACKRECOVERYFAIL ) ,
SNMP_MIB_ITEM ( " TCPSchedulerFailed " , LINUX_MIB_TCPSCHEDULERFAILED ) ,
SNMP_MIB_ITEM ( " TCPRcvCollapsed " , LINUX_MIB_TCPRCVCOLLAPSED ) ,
SNMP_MIB_ITEM ( " TCPDSACKOldSent " , LINUX_MIB_TCPDSACKOLDSENT ) ,
SNMP_MIB_ITEM ( " TCPDSACKOfoSent " , LINUX_MIB_TCPDSACKOFOSENT ) ,
SNMP_MIB_ITEM ( " TCPDSACKRecv " , LINUX_MIB_TCPDSACKRECV ) ,
SNMP_MIB_ITEM ( " TCPDSACKOfoRecv " , LINUX_MIB_TCPDSACKOFORECV ) ,
SNMP_MIB_ITEM ( " TCPAbortOnSyn " , LINUX_MIB_TCPABORTONSYN ) ,
SNMP_MIB_ITEM ( " TCPAbortOnData " , LINUX_MIB_TCPABORTONDATA ) ,
SNMP_MIB_ITEM ( " TCPAbortOnClose " , LINUX_MIB_TCPABORTONCLOSE ) ,
SNMP_MIB_ITEM ( " TCPAbortOnMemory " , LINUX_MIB_TCPABORTONMEMORY ) ,
SNMP_MIB_ITEM ( " TCPAbortOnTimeout " , LINUX_MIB_TCPABORTONTIMEOUT ) ,
SNMP_MIB_ITEM ( " TCPAbortOnLinger " , LINUX_MIB_TCPABORTONLINGER ) ,
SNMP_MIB_ITEM ( " TCPAbortFailed " , LINUX_MIB_TCPABORTFAILED ) ,
SNMP_MIB_ITEM ( " TCPMemoryPressures " , LINUX_MIB_TCPMEMORYPRESSURES ) ,
2007-08-25 09:55:52 +04:00
SNMP_MIB_ITEM ( " TCPSACKDiscard " , LINUX_MIB_TCPSACKDISCARD ) ,
SNMP_MIB_ITEM ( " TCPDSACKIgnoredOld " , LINUX_MIB_TCPDSACKIGNOREDOLD ) ,
SNMP_MIB_ITEM ( " TCPDSACKIgnoredNoUndo " , LINUX_MIB_TCPDSACKIGNOREDNOUNDO ) ,
2007-09-26 09:47:31 +04:00
SNMP_MIB_ITEM ( " TCPSpuriousRTOs " , LINUX_MIB_TCPSPURIOUSRTOS ) ,
2008-07-30 14:03:15 +04:00
SNMP_MIB_ITEM ( " TCPMD5NotFound " , LINUX_MIB_TCPMD5NOTFOUND ) ,
SNMP_MIB_ITEM ( " TCPMD5Unexpected " , LINUX_MIB_TCPMD5UNEXPECTED ) ,
2008-11-25 08:27:22 +03:00
SNMP_MIB_ITEM ( " TCPSackShifted " , LINUX_MIB_SACKSHIFTED ) ,
SNMP_MIB_ITEM ( " TCPSackMerged " , LINUX_MIB_SACKMERGED ) ,
SNMP_MIB_ITEM ( " TCPSackShiftFallback " , LINUX_MIB_SACKSHIFTFALLBACK ) ,
2005-04-17 02:20:36 +04:00
SNMP_MIB_SENTINEL
} ;
2008-11-11 08:43:08 +03:00
static void icmpmsg_put_line ( struct seq_file * seq , unsigned long * vals ,
unsigned short * type , int count )
{
int j ;
if ( count ) {
seq_printf ( seq , " \n IcmpMsg: " ) ;
for ( j = 0 ; j < count ; + + j )
seq_printf ( seq , " %sType%u " ,
type [ j ] & 0x100 ? " Out " : " In " ,
type [ j ] & 0xff ) ;
seq_printf ( seq , " \n IcmpMsg: " ) ;
for ( j = 0 ; j < count ; + + j )
seq_printf ( seq , " %lu " , vals [ j ] ) ;
}
}
2007-09-17 20:57:33 +04:00
static void icmpmsg_put ( struct seq_file * seq )
{
# define PERLINE 16
2008-11-11 08:43:08 +03:00
int i , count ;
unsigned short type [ PERLINE ] ;
unsigned long vals [ PERLINE ] , val ;
2008-07-18 15:06:04 +04:00
struct net * net = seq - > private ;
2007-09-17 20:57:33 +04:00
count = 0 ;
for ( i = 0 ; i < ICMPMSG_MIB_MAX ; i + + ) {
2010-02-16 18:20:26 +03:00
val = snmp_fold_field ( ( void __percpu * * ) net - > mib . icmpmsg_statistics , i ) ;
2008-11-11 08:43:08 +03:00
if ( val ) {
type [ count ] = i ;
vals [ count + + ] = val ;
}
if ( count = = PERLINE ) {
icmpmsg_put_line ( seq , vals , type , count ) ;
count = 0 ;
}
2007-09-17 20:57:33 +04:00
}
2008-11-11 08:43:08 +03:00
icmpmsg_put_line ( seq , vals , type , count ) ;
2007-09-17 20:57:33 +04:00
# undef PERLINE
}
static void icmp_put ( struct seq_file * seq )
{
int i ;
2008-07-18 15:06:04 +04:00
struct net * net = seq - > private ;
2007-09-17 20:57:33 +04:00
seq_puts ( seq , " \n Icmp: InMsgs InErrors " ) ;
for ( i = 0 ; icmpmibmap [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " In%s " , icmpmibmap [ i ] . name ) ;
seq_printf ( seq , " OutMsgs OutErrors " ) ;
for ( i = 0 ; icmpmibmap [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " Out%s " , icmpmibmap [ i ] . name ) ;
seq_printf ( seq , " \n Icmp: %lu %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . icmp_statistics , ICMP_MIB_INMSGS ) ,
snmp_fold_field ( ( void __percpu * * ) net - > mib . icmp_statistics , ICMP_MIB_INERRORS ) ) ;
2007-09-17 20:57:33 +04:00
for ( i = 0 ; icmpmibmap [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . icmpmsg_statistics ,
2007-09-17 20:57:33 +04:00
icmpmibmap [ i ] . index ) ) ;
seq_printf ( seq , " %lu %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . icmp_statistics , ICMP_MIB_OUTMSGS ) ,
snmp_fold_field ( ( void __percpu * * ) net - > mib . icmp_statistics , ICMP_MIB_OUTERRORS ) ) ;
2007-09-17 20:57:33 +04:00
for ( i = 0 ; icmpmibmap [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . icmpmsg_statistics ,
2007-10-30 08:02:57 +03:00
icmpmibmap [ i ] . index | 0x100 ) ) ;
2007-09-17 20:57:33 +04:00
}
2005-04-17 02:20:36 +04:00
/*
* Called from the PROCfs module . This outputs / proc / net / snmp .
*/
static int snmp_seq_show ( struct seq_file * seq , void * v )
{
int i ;
2008-07-18 15:06:04 +04:00
struct net * net = seq - > private ;
2005-04-17 02:20:36 +04:00
seq_puts ( seq , " Ip: Forwarding DefaultTTL " ) ;
for ( i = 0 ; snmp4_ipstats_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %s " , snmp4_ipstats_list [ i ] . name ) ;
seq_printf ( seq , " \n Ip: %d %d " ,
2008-07-18 15:06:26 +04:00
IPV4_DEVCONF_ALL ( net , FORWARDING ) ? 1 : 2 ,
2007-12-17 00:32:48 +03:00
sysctl_ip_default_ttl ) ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; snmp4_ipstats_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . ip_statistics ,
2007-04-25 08:53:35 +04:00
snmp4_ipstats_list [ i ] . entry ) ) ;
2005-04-17 02:20:36 +04:00
2007-09-17 20:57:33 +04:00
icmp_put ( seq ) ; /* RFC 2011 compatibility */
icmpmsg_put ( seq ) ;
2005-04-17 02:20:36 +04:00
seq_puts ( seq , " \n Tcp: " ) ;
for ( i = 0 ; snmp4_tcp_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %s " , snmp4_tcp_list [ i ] . name ) ;
seq_puts ( seq , " \n Tcp: " ) ;
for ( i = 0 ; snmp4_tcp_list [ i ] . name ! = NULL ; i + + ) {
/* MaxConn field is signed, RFC 2012 */
if ( snmp4_tcp_list [ i ] . entry = = TCP_MIB_MAXCONN )
seq_printf ( seq , " %ld " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . tcp_statistics ,
2007-04-25 08:53:35 +04:00
snmp4_tcp_list [ i ] . entry ) ) ;
2005-04-17 02:20:36 +04:00
else
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . tcp_statistics ,
2007-04-25 08:53:35 +04:00
snmp4_tcp_list [ i ] . entry ) ) ;
2005-04-17 02:20:36 +04:00
}
seq_puts ( seq , " \n Udp: " ) ;
for ( i = 0 ; snmp4_udp_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %s " , snmp4_udp_list [ i ] . name ) ;
seq_puts ( seq , " \n Udp: " ) ;
for ( i = 0 ; snmp4_udp_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . udp_statistics ,
2007-04-25 08:53:35 +04:00
snmp4_udp_list [ i ] . entry ) ) ;
2005-04-17 02:20:36 +04:00
2006-11-27 22:10:57 +03:00
/* the UDP and UDP-Lite MIBs are the same */
seq_puts ( seq , " \n UdpLite: " ) ;
for ( i = 0 ; snmp4_udp_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %s " , snmp4_udp_list [ i ] . name ) ;
seq_puts ( seq , " \n UdpLite: " ) ;
for ( i = 0 ; snmp4_udp_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . udplite_statistics ,
2007-04-25 08:53:35 +04:00
snmp4_udp_list [ i ] . entry ) ) ;
2008-03-07 03:22:02 +03:00
2005-04-17 02:20:36 +04:00
seq_putc ( seq , ' \n ' ) ;
return 0 ;
}
static int snmp_seq_open ( struct inode * inode , struct file * file )
{
2008-07-18 15:07:21 +04:00
return single_open_net ( inode , file , snmp_seq_show ) ;
2008-07-18 15:06:04 +04:00
}
2007-02-12 11:55:35 +03:00
static const struct file_operations snmp_seq_fops = {
2005-04-17 02:20:36 +04:00
. owner = THIS_MODULE ,
. open = snmp_seq_open ,
. read = seq_read ,
. llseek = seq_lseek ,
2008-07-18 15:07:44 +04:00
. release = single_release_net ,
2005-04-17 02:20:36 +04:00
} ;
2007-09-17 20:57:33 +04:00
2005-04-17 02:20:36 +04:00
/*
* Output / proc / net / netstat
*/
static int netstat_seq_show ( struct seq_file * seq , void * v )
{
int i ;
2008-07-18 15:05:17 +04:00
struct net * net = seq - > private ;
2005-04-17 02:20:36 +04:00
seq_puts ( seq , " TcpExt: " ) ;
for ( i = 0 ; snmp4_net_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %s " , snmp4_net_list [ i ] . name ) ;
seq_puts ( seq , " \n TcpExt: " ) ;
for ( i = 0 ; snmp4_net_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . net_statistics ,
2007-04-25 08:53:35 +04:00
snmp4_net_list [ i ] . entry ) ) ;
2005-04-17 02:20:36 +04:00
2007-05-14 14:07:30 +04:00
seq_puts ( seq , " \n IpExt: " ) ;
for ( i = 0 ; snmp4_ipextstats_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %s " , snmp4_ipextstats_list [ i ] . name ) ;
seq_puts ( seq , " \n IpExt: " ) ;
for ( i = 0 ; snmp4_ipextstats_list [ i ] . name ! = NULL ; i + + )
seq_printf ( seq , " %lu " ,
2010-02-16 18:20:26 +03:00
snmp_fold_field ( ( void __percpu * * ) net - > mib . ip_statistics ,
2007-05-14 14:07:30 +04:00
snmp4_ipextstats_list [ i ] . entry ) ) ;
2005-04-17 02:20:36 +04:00
seq_putc ( seq , ' \n ' ) ;
return 0 ;
}
static int netstat_seq_open ( struct inode * inode , struct file * file )
{
2008-07-18 15:07:21 +04:00
return single_open_net ( inode , file , netstat_seq_show ) ;
2008-07-18 15:05:17 +04:00
}
2007-02-12 11:55:35 +03:00
static const struct file_operations netstat_seq_fops = {
2005-04-17 02:20:36 +04:00
. owner = THIS_MODULE ,
. open = netstat_seq_open ,
. read = seq_read ,
. llseek = seq_lseek ,
2008-07-18 15:07:44 +04:00
. release = single_release_net ,
2005-04-17 02:20:36 +04:00
} ;
2008-04-01 06:42:37 +04:00
static __net_init int ip_proc_init_net ( struct net * net )
{
if ( ! proc_net_fops_create ( net , " sockstat " , S_IRUGO , & sockstat_seq_fops ) )
2008-07-18 15:06:50 +04:00
goto out_sockstat ;
2008-07-18 15:05:17 +04:00
if ( ! proc_net_fops_create ( net , " netstat " , S_IRUGO , & netstat_seq_fops ) )
goto out_netstat ;
2008-07-18 15:06:04 +04:00
if ( ! proc_net_fops_create ( net , " snmp " , S_IRUGO , & snmp_seq_fops ) )
goto out_snmp ;
2008-07-18 15:05:17 +04:00
2008-04-01 06:42:37 +04:00
return 0 ;
2008-07-18 15:05:17 +04:00
2008-07-18 15:06:04 +04:00
out_snmp :
proc_net_remove ( net , " netstat " ) ;
2008-07-18 15:05:17 +04:00
out_netstat :
proc_net_remove ( net , " sockstat " ) ;
2008-07-18 15:06:50 +04:00
out_sockstat :
2008-07-18 15:05:17 +04:00
return - ENOMEM ;
2008-04-01 06:42:37 +04:00
}
static __net_exit void ip_proc_exit_net ( struct net * net )
{
2008-07-18 15:06:04 +04:00
proc_net_remove ( net , " snmp " ) ;
2008-07-18 15:05:17 +04:00
proc_net_remove ( net , " netstat " ) ;
2008-04-01 06:42:37 +04:00
proc_net_remove ( net , " sockstat " ) ;
}
static __net_initdata struct pernet_operations ip_proc_ops = {
. init = ip_proc_init_net ,
. exit = ip_proc_exit_net ,
} ;
2005-04-17 02:20:36 +04:00
int __init ip_misc_proc_init ( void )
{
2008-07-18 15:06:50 +04:00
return register_pernet_subsys ( & ip_proc_ops ) ;
2005-04-17 02:20:36 +04:00
}
2007-04-21 02:57:15 +04:00