linux/net/x25/x25_proc.c
<<
>>
Prefs
   1/*
   2 *      X.25 Packet Layer release 002
   3 *
   4 *      This is ALPHA test software. This code may break your machine,
   5 *      randomly fail to work with new releases, misbehave and/or generally
   6 *      screw up. It might even work.
   7 *
   8 *      This code REQUIRES 2.4 with seq_file support
   9 *
  10 *      This module:
  11 *              This module is free software; you can redistribute it and/or
  12 *              modify it under the terms of the GNU General Public License
  13 *              as published by the Free Software Foundation; either version
  14 *              2 of the License, or (at your option) any later version.
  15 *
  16 *      History
  17 *      2002/10/06      Arnaldo Carvalho de Melo  seq_file support
  18 */
  19
  20#include <linux/init.h>
  21#include <linux/proc_fs.h>
  22#include <linux/seq_file.h>
  23#include <linux/export.h>
  24#include <net/net_namespace.h>
  25#include <net/sock.h>
  26#include <net/x25.h>
  27
  28#ifdef CONFIG_PROC_FS
  29
  30static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
  31        __acquires(x25_route_list_lock)
  32{
  33        read_lock_bh(&x25_route_list_lock);
  34        return seq_list_start_head(&x25_route_list, *pos);
  35}
  36
  37static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
  38{
  39        return seq_list_next(v, &x25_route_list, pos);
  40}
  41
  42static void x25_seq_route_stop(struct seq_file *seq, void *v)
  43        __releases(x25_route_list_lock)
  44{
  45        read_unlock_bh(&x25_route_list_lock);
  46}
  47
  48static int x25_seq_route_show(struct seq_file *seq, void *v)
  49{
  50        struct x25_route *rt = list_entry(v, struct x25_route, node);
  51
  52        if (v == &x25_route_list) {
  53                seq_puts(seq, "Address          Digits  Device\n");
  54                goto out;
  55        }
  56
  57        rt = v;
  58        seq_printf(seq, "%-15s  %-6d  %-5s\n",
  59                   rt->address.x25_addr, rt->sigdigits,
  60                   rt->dev ? rt->dev->name : "???");
  61out:
  62        return 0;
  63}
  64
  65static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
  66        __acquires(x25_list_lock)
  67{
  68        read_lock_bh(&x25_list_lock);
  69        return seq_hlist_start_head(&x25_list, *pos);
  70}
  71
  72static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
  73{
  74        return seq_hlist_next(v, &x25_list, pos);
  75}
  76
  77static void x25_seq_socket_stop(struct seq_file *seq, void *v)
  78        __releases(x25_list_lock)
  79{
  80        read_unlock_bh(&x25_list_lock);
  81}
  82
  83static int x25_seq_socket_show(struct seq_file *seq, void *v)
  84{
  85        struct sock *s;
  86        struct x25_sock *x25;
  87        struct net_device *dev;
  88        const char *devname;
  89
  90        if (v == SEQ_START_TOKEN) {
  91                seq_printf(seq, "dest_addr  src_addr   dev   lci st vs vr "
  92                                "va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
  93                goto out;
  94        }
  95
  96        s = sk_entry(v);
  97        x25 = x25_sk(s);
  98
  99        if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
 100                devname = "???";
 101        else
 102                devname = x25->neighbour->dev->name;
 103
 104        seq_printf(seq, "%-10s %-10s %-5s %3.3X  %d  %d  %d  %d %3lu %3lu "
 105                        "%3lu %3lu %3lu %5d %5d %ld\n",
 106                   !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
 107                   !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
 108                   devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
 109                   x25->va, x25_display_timer(s) / HZ, x25->t2  / HZ,
 110                   x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
 111                   sk_wmem_alloc_get(s),
 112                   sk_rmem_alloc_get(s),
 113                   s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
 114out:
 115        return 0;
 116}
 117
 118static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos)
 119        __acquires(x25_forward_list_lock)
 120{
 121        read_lock_bh(&x25_forward_list_lock);
 122        return seq_list_start_head(&x25_forward_list, *pos);
 123}
 124
 125static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos)
 126{
 127        return seq_list_next(v, &x25_forward_list, pos);
 128}
 129
 130static void x25_seq_forward_stop(struct seq_file *seq, void *v)
 131        __releases(x25_forward_list_lock)
 132{
 133        read_unlock_bh(&x25_forward_list_lock);
 134}
 135
 136static int x25_seq_forward_show(struct seq_file *seq, void *v)
 137{
 138        struct x25_forward *f = list_entry(v, struct x25_forward, node);
 139
 140        if (v == &x25_forward_list) {
 141                seq_printf(seq, "lci dev1       dev2\n");
 142                goto out;
 143        }
 144
 145        f = v;
 146
 147        seq_printf(seq, "%d %-10s %-10s\n",
 148                        f->lci, f->dev1->name, f->dev2->name);
 149out:
 150        return 0;
 151}
 152
 153static const struct seq_operations x25_seq_route_ops = {
 154        .start  = x25_seq_route_start,
 155        .next   = x25_seq_route_next,
 156        .stop   = x25_seq_route_stop,
 157        .show   = x25_seq_route_show,
 158};
 159
 160static const struct seq_operations x25_seq_socket_ops = {
 161        .start  = x25_seq_socket_start,
 162        .next   = x25_seq_socket_next,
 163        .stop   = x25_seq_socket_stop,
 164        .show   = x25_seq_socket_show,
 165};
 166
 167static const struct seq_operations x25_seq_forward_ops = {
 168        .start  = x25_seq_forward_start,
 169        .next   = x25_seq_forward_next,
 170        .stop   = x25_seq_forward_stop,
 171        .show   = x25_seq_forward_show,
 172};
 173
 174static int x25_seq_socket_open(struct inode *inode, struct file *file)
 175{
 176        return seq_open(file, &x25_seq_socket_ops);
 177}
 178
 179static int x25_seq_route_open(struct inode *inode, struct file *file)
 180{
 181        return seq_open(file, &x25_seq_route_ops);
 182}
 183
 184static int x25_seq_forward_open(struct inode *inode, struct file *file)
 185{
 186        return seq_open(file, &x25_seq_forward_ops);
 187}
 188
 189static const struct file_operations x25_seq_socket_fops = {
 190        .open           = x25_seq_socket_open,
 191        .read           = seq_read,
 192        .llseek         = seq_lseek,
 193        .release        = seq_release,
 194};
 195
 196static const struct file_operations x25_seq_route_fops = {
 197        .open           = x25_seq_route_open,
 198        .read           = seq_read,
 199        .llseek         = seq_lseek,
 200        .release        = seq_release,
 201};
 202
 203static const struct file_operations x25_seq_forward_fops = {
 204        .open           = x25_seq_forward_open,
 205        .read           = seq_read,
 206        .llseek         = seq_lseek,
 207        .release        = seq_release,
 208};
 209
 210int __init x25_proc_init(void)
 211{
 212        if (!proc_mkdir("x25", init_net.proc_net))
 213                return -ENOMEM;
 214
 215        if (!proc_create("x25/route", S_IRUGO, init_net.proc_net,
 216                        &x25_seq_route_fops))
 217                goto out;
 218
 219        if (!proc_create("x25/socket", S_IRUGO, init_net.proc_net,
 220                        &x25_seq_socket_fops))
 221                goto out;
 222
 223        if (!proc_create("x25/forward", S_IRUGO, init_net.proc_net,
 224                        &x25_seq_forward_fops))
 225                goto out;
 226        return 0;
 227
 228out:
 229        remove_proc_subtree("x25", init_net.proc_net);
 230        return -ENOMEM;
 231}
 232
 233void __exit x25_proc_exit(void)
 234{
 235        remove_proc_subtree("x25", init_net.proc_net);
 236}
 237
 238#else /* CONFIG_PROC_FS */
 239
 240int __init x25_proc_init(void)
 241{
 242        return 0;
 243}
 244
 245void __exit x25_proc_exit(void)
 246{
 247}
 248#endif /* CONFIG_PROC_FS */
 249