linux-bk/net/sctp/proc.c
<<
>>
Prefs
   1/* SCTP kernel reference Implementation
   2 * Copyright (c) 2003 International Business Machines, Corp.
   3 *
   4 * This file is part of the SCTP kernel reference Implementation
   5 *
   6 * The SCTP reference implementation is free software;
   7 * you can redistribute it and/or modify it under the terms of
   8 * the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2, or (at your option)
  10 * any later version.
  11 *
  12 * The SCTP reference implementation is distributed in the hope that it
  13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  14 *                 ************************
  15 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16 * See the GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with GNU CC; see the file COPYING.  If not, write to
  20 * the Free Software Foundation, 59 Temple Place - Suite 330,
  21 * Boston, MA 02111-1307, USA.
  22 *
  23 * Please send any bug reports or fixes you make to the
  24 * email address(es):
  25 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
  26 *
  27 * Or submit a bug report through the following website:
  28 *    http://www.sf.net/projects/lksctp
  29 *
  30 * Written or modified by:
  31 *    Sridhar Samudrala <sri@us.ibm.com>
  32 *
  33 * Any bugs reported given to us we will try to fix... any fixes shared will
  34 * be incorporated into the next SCTP release.
  35 */
  36
  37#include <linux/types.h>
  38#include <linux/seq_file.h>
  39#include <linux/init.h>
  40#include <net/sctp/sctp.h>
  41
  42struct snmp_mib sctp_snmp_list[] = {
  43        SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB),
  44        SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS),
  45        SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS),
  46        SNMP_MIB_ITEM("SctpAborteds", SCTP_MIB_ABORTEDS),
  47        SNMP_MIB_ITEM("SctpShutdowns", SCTP_MIB_SHUTDOWNS),
  48        SNMP_MIB_ITEM("SctpOutOfBlues", SCTP_MIB_OUTOFBLUES),
  49        SNMP_MIB_ITEM("SctpChecksumErrors", SCTP_MIB_CHECKSUMERRORS),
  50        SNMP_MIB_ITEM("SctpOutCtrlChunks", SCTP_MIB_OUTCTRLCHUNKS),
  51        SNMP_MIB_ITEM("SctpOutOrderChunks", SCTP_MIB_OUTORDERCHUNKS),
  52        SNMP_MIB_ITEM("SctpOutUnorderChunks", SCTP_MIB_OUTUNORDERCHUNKS),
  53        SNMP_MIB_ITEM("SctpInCtrlChunks", SCTP_MIB_INCTRLCHUNKS),
  54        SNMP_MIB_ITEM("SctpInOrderChunks", SCTP_MIB_INORDERCHUNKS),
  55        SNMP_MIB_ITEM("SctpInUnorderChunks", SCTP_MIB_INUNORDERCHUNKS),
  56        SNMP_MIB_ITEM("SctpFragUsrMsgs", SCTP_MIB_FRAGUSRMSGS),
  57        SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS),
  58        SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS),
  59        SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS),
  60};
  61
  62/* Return the current value of a particular entry in the mib by adding its
  63 * per cpu counters.
  64 */ 
  65static unsigned long
  66fold_field(void *mib[], int nr)
  67{
  68        unsigned long res = 0;
  69        int i;
  70
  71        for (i = 0; i < NR_CPUS; i++) {
  72                if (!cpu_possible(i))
  73                        continue;
  74                res +=
  75                    *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
  76                                         sizeof (unsigned long) * nr));
  77                res +=
  78                    *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) +
  79                                         sizeof (unsigned long) * nr));
  80        }
  81        return res;
  82}
  83
  84/* Display sctp snmp mib statistics(/proc/net/sctp/snmp). */
  85static int sctp_snmp_seq_show(struct seq_file *seq, void *v)
  86{
  87        int i;
  88
  89        for (i = 0; sctp_snmp_list[i].name != NULL; i++)
  90                seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i].name,
  91                           fold_field((void **)sctp_statistics, 
  92                                      sctp_snmp_list[i].entry));
  93
  94        return 0;
  95}
  96
  97/* Initialize the seq file operations for 'snmp' object. */
  98static int sctp_snmp_seq_open(struct inode *inode, struct file *file)
  99{
 100        return single_open(file, sctp_snmp_seq_show, NULL);
 101}
 102
 103static struct file_operations sctp_snmp_seq_fops = {
 104        .owner   = THIS_MODULE,
 105        .open    = sctp_snmp_seq_open,
 106        .read    = seq_read,
 107        .llseek  = seq_lseek,
 108        .release = single_release,
 109};
 110
 111/* Set up the proc fs entry for 'snmp' object. */
 112int __init sctp_snmp_proc_init(void)
 113{
 114        struct proc_dir_entry *p;
 115
 116        p = create_proc_entry("snmp", S_IRUGO, proc_net_sctp);
 117        if (!p)
 118                return -ENOMEM;
 119
 120        p->proc_fops = &sctp_snmp_seq_fops;
 121
 122        return 0;
 123}
 124
 125/* Cleanup the proc fs entry for 'snmp' object. */
 126void sctp_snmp_proc_exit(void)
 127{
 128        remove_proc_entry("snmp", proc_net_sctp);
 129}
 130
 131/* Dump local addresses of an association/endpoint. */
 132static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
 133{
 134        struct list_head *pos;
 135        struct sctp_sockaddr_entry *laddr;
 136        union sctp_addr *addr;
 137        struct sctp_af *af;
 138
 139        list_for_each(pos, &epb->bind_addr.address_list) {
 140                laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
 141                addr = (union sctp_addr *)&laddr->a;
 142                af = sctp_get_af_specific(addr->sa.sa_family);
 143                af->seq_dump_addr(seq, addr);
 144        }
 145}
 146
 147/* Dump remote addresses of an association. */
 148static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_association *assoc)
 149{
 150        struct list_head *pos;
 151        struct sctp_transport *transport;
 152        union sctp_addr *addr;
 153        struct sctp_af *af;
 154
 155        list_for_each(pos, &assoc->peer.transport_addr_list) {
 156                transport = list_entry(pos, struct sctp_transport, transports);
 157                addr = (union sctp_addr *)&transport->ipaddr;
 158                af = sctp_get_af_specific(addr->sa.sa_family);
 159                af->seq_dump_addr(seq, addr);
 160        }
 161}
 162
 163/* Display sctp endpoints (/proc/net/sctp/eps). */
 164static int sctp_eps_seq_show(struct seq_file *seq, void *v)
 165{
 166        struct sctp_hashbucket *head;
 167        struct sctp_ep_common *epb;
 168        struct sctp_endpoint *ep;
 169        struct sock *sk;
 170        int hash;
 171
 172        seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT LADDRS\n");
 173        for (hash = 0; hash < sctp_ep_hashsize; hash++) {
 174                head = &sctp_ep_hashtable[hash];
 175                read_lock(&head->lock);
 176                for (epb = head->chain; epb; epb = epb->next) {
 177                        ep = sctp_ep(epb);
 178                        sk = epb->sk;
 179                        seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk,
 180                                   sctp_sk(sk)->type, sk->sk_state, hash,
 181                                   epb->bind_addr.port);
 182                        sctp_seq_dump_local_addrs(seq, epb);
 183                        seq_printf(seq, "\n");
 184                }
 185                read_unlock(&head->lock);
 186        }
 187
 188        return 0;
 189}
 190
 191/* Initialize the seq file operations for 'eps' object. */
 192static int sctp_eps_seq_open(struct inode *inode, struct file *file)
 193{
 194        return single_open(file, sctp_eps_seq_show, NULL);
 195}
 196
 197static struct file_operations sctp_eps_seq_fops = {
 198        .open    = sctp_eps_seq_open,
 199        .read    = seq_read,
 200        .llseek  = seq_lseek,
 201        .release = single_release,
 202};
 203
 204/* Set up the proc fs entry for 'eps' object. */
 205int __init sctp_eps_proc_init(void)
 206{
 207        struct proc_dir_entry *p;
 208
 209        p = create_proc_entry("eps", S_IRUGO, proc_net_sctp);
 210        if (!p)
 211                return -ENOMEM;
 212
 213        p->proc_fops = &sctp_eps_seq_fops;
 214
 215        return 0;
 216}
 217
 218/* Cleanup the proc fs entry for 'eps' object. */
 219void sctp_eps_proc_exit(void)
 220{
 221        remove_proc_entry("eps", proc_net_sctp);
 222}
 223
 224/* Display sctp associations (/proc/net/sctp/assocs). */
 225static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
 226{
 227        struct sctp_hashbucket *head;
 228        struct sctp_ep_common *epb;
 229        struct sctp_association *assoc;
 230        struct sock *sk;
 231        int hash;
 232
 233        seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT LPORT RPORT "
 234                        "LADDRS <-> RADDRS\n");
 235        for (hash = 0; hash < sctp_assoc_hashsize; hash++) {
 236                head = &sctp_assoc_hashtable[hash];
 237                read_lock(&head->lock);
 238                for (epb = head->chain; epb; epb = epb->next) {
 239                        assoc = sctp_assoc(epb);
 240                        sk = epb->sk;
 241                        seq_printf(seq,
 242                                   "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ",
 243                                   assoc, sk, sctp_sk(sk)->type, sk->sk_state,
 244                                   assoc->state, hash, epb->bind_addr.port,
 245                                   assoc->peer.port);
 246                        sctp_seq_dump_local_addrs(seq, epb);
 247                        seq_printf(seq, "<-> ");
 248                        sctp_seq_dump_remote_addrs(seq, assoc);
 249                        seq_printf(seq, "\n");
 250                }
 251                read_unlock(&head->lock);
 252        }
 253
 254        return 0;
 255}
 256
 257/* Initialize the seq file operations for 'assocs' object. */
 258static int sctp_assocs_seq_open(struct inode *inode, struct file *file)
 259{
 260        return single_open(file, sctp_assocs_seq_show, NULL);
 261}
 262
 263static struct file_operations sctp_assocs_seq_fops = {
 264        .open    = sctp_assocs_seq_open,
 265        .read    = seq_read,
 266        .llseek  = seq_lseek,
 267        .release = single_release,
 268};
 269
 270/* Set up the proc fs entry for 'assocs' object. */
 271int __init sctp_assocs_proc_init(void)
 272{
 273        struct proc_dir_entry *p;
 274
 275        p = create_proc_entry("assocs", S_IRUGO, proc_net_sctp);
 276        if (!p)
 277                return -ENOMEM;
 278
 279        p->proc_fops = &sctp_assocs_seq_fops;
 280
 281        return 0;
 282}
 283
 284/* Cleanup the proc fs entry for 'assocs' object. */
 285void sctp_assocs_proc_exit(void)
 286{
 287        remove_proc_entry("assocs", proc_net_sctp);
 288}
 289
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.