root/fs/proc/net.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. proc_lookupnet
  2. proc_readnetdir
  3. proc_readnet

   1 /*
   2  *  linux/fs/proc/net.c
   3  *
   4  *  Copyright (C) 1991, 1992 Linus Torvalds
   5  *
   6  *  gjh 3/'93 heim@peanuts.informatik.uni-tuebingen.de (Gerald J. Heim)
   7  *            most of this file is stolen from base.c
   8  *            it works, but you shouldn't use it as a guideline
   9  *            for new proc-fs entries. once i'll make it better.
  10  * fvk 3/'93  waltje@uwalt.nl.mugnet.org (Fred N. van Kempen)
  11  *            cleaned up the whole thing, moved "net" specific code to
  12  *            the NET kernel layer (where it belonged in the first place).
  13  * Michael K. Johnson (johnsonm@stolaf.edu) 3/93
  14  *            Added support from my previous inet.c.  Cleaned things up
  15  *            quite a bit, modularized the code.
  16  * fvk 4/'93  waltje@uwalt.nl.mugnet.org (Fred N. van Kempen)
  17  *            Renamed "route_get_info()" to "rt_get_info()" for consistency.
  18  *
  19  *  proc net directory handling functions
  20  */
  21 #include <linux/autoconf.h>
  22 
  23 #include <asm/segment.h>
  24 
  25 #include <linux/errno.h>
  26 #include <linux/sched.h>
  27 #include <linux/proc_fs.h>
  28 #include <linux/stat.h>
  29 
  30 /* forward references */
  31 static int proc_readnet(struct inode * inode, struct file * file,
  32                          char * buf, int count);
  33 static int proc_readnetdir(struct inode *, struct file *,
  34                            struct dirent *, int);
  35 static int proc_lookupnet(struct inode *,const char *,int,struct inode **);
  36 
  37 /* the get_*_info() functions are in the net code, and are configured
  38    in via the standard mechanism... */
  39 #ifdef CONFIG_INET
  40 extern int unix_get_info(char *);
  41 extern int tcp_get_info(char *);
  42 extern int udp_get_info(char *);
  43 extern int raw_get_info(char *);
  44 extern int arp_get_info(char *);
  45 extern int dev_get_info(char *);
  46 extern int rt_get_info(char *);
  47 #endif /* CONFIG_INET */
  48 
  49 
  50 static struct file_operations proc_net_operations = {
  51         NULL,                   /* lseek - default */
  52         proc_readnet,           /* read - bad */
  53         NULL,                   /* write - bad */
  54         proc_readnetdir,        /* readdir */
  55         NULL,                   /* select - default */
  56         NULL,                   /* ioctl - default */
  57         NULL,                   /* mmap */
  58         NULL,                   /* no special open code */
  59         NULL,                   /* no special release code */
  60         NULL                    /* can't fsync */
  61 };
  62 
  63 /*
  64  * proc directories can do almost nothing..
  65  */
  66 struct inode_operations proc_net_inode_operations = {
  67         &proc_net_operations,   /* default net directory file-ops */
  68         NULL,                   /* create */
  69         proc_lookupnet,         /* lookup */
  70         NULL,                   /* link */
  71         NULL,                   /* unlink */
  72         NULL,                   /* symlink */
  73         NULL,                   /* mkdir */
  74         NULL,                   /* rmdir */
  75         NULL,                   /* mknod */
  76         NULL,                   /* rename */
  77         NULL,                   /* readlink */
  78         NULL,                   /* follow_link */
  79         NULL,                   /* bmap */
  80         NULL,                   /* truncate */
  81         NULL                    /* permission */
  82 };
  83 
  84 static struct proc_dir_entry net_dir[] = {
  85         { 1,2,".." },
  86         { 8,1,"." }
  87 #ifdef CONFIG_INET
  88         ,{ 128,4,"unix" },
  89         { 129,3,"arp" },
  90         { 130,5,"route" },
  91         { 131,3,"dev" },
  92         { 132,3,"raw" },
  93         { 133,3,"tcp" },
  94         { 134,3,"udp" }
  95 #endif  /* CONFIG_INET */
  96 };
  97 
  98 #define NR_NET_DIRENTRY ((sizeof (net_dir))/(sizeof (net_dir[0])))
  99 
 100 
 101 static int proc_lookupnet(struct inode * dir,const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 102         struct inode ** result)
 103 {
 104         unsigned int ino;
 105         int i;
 106 
 107         *result = NULL;
 108         if (!dir)
 109                 return -ENOENT;
 110         if (!S_ISDIR(dir->i_mode)) {
 111                 iput(dir);
 112                 return -ENOENT;
 113         }
 114         i = NR_NET_DIRENTRY;
 115         while (i-- > 0 && !proc_match(len,name,net_dir+i))
 116                 /* nothing */;
 117         if (i < 0) {
 118                 iput(dir);
 119                 return -ENOENT;
 120         }
 121         ino = net_dir[i].low_ino;
 122         if (!(*result = iget(dir->i_sb,ino))) {
 123                 iput(dir);
 124                 return -ENOENT;
 125         }
 126         iput(dir);
 127         return 0;
 128 }
 129 
 130 static int proc_readnetdir(struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 131         struct dirent * dirent, int count)
 132 {
 133         struct proc_dir_entry * de;
 134         unsigned int ino;
 135         int i,j;
 136 
 137         if (!inode || !S_ISDIR(inode->i_mode))
 138                 return -EBADF;
 139         ino = inode->i_ino;
 140         if (((unsigned) filp->f_pos) < NR_NET_DIRENTRY) {
 141                 de = net_dir + filp->f_pos;
 142                 filp->f_pos++;
 143                 i = de->namelen;
 144                 ino = de->low_ino;
 145                 put_fs_long(ino, &dirent->d_ino);
 146                 put_fs_word(i,&dirent->d_reclen);
 147                 put_fs_byte(0,i+dirent->d_name);
 148                 j = i;
 149                 while (i--)
 150                         put_fs_byte(de->name[i], i+dirent->d_name);
 151                 return j;
 152         }
 153         return 0;
 154 }
 155 
 156 
 157 static int proc_readnet(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 158                         char * buf, int count)
 159 {
 160         char * page;
 161         int length;
 162         int end;
 163         unsigned int ino;
 164 
 165         if (count < 0)
 166                 return -EINVAL;
 167         if (!(page = (char*) __get_free_page(GFP_KERNEL)))
 168                 return -ENOMEM;
 169         ino = inode->i_ino;
 170         switch (ino) {
 171 #ifdef CONFIG_INET
 172                 case 128:
 173                         length = unix_get_info(page);
 174                         break;
 175                 case 129:
 176                         length = arp_get_info(page);
 177                         break;
 178                 case 130:
 179                         length = rt_get_info(page);
 180                         break;
 181                 case 131:
 182                         length = dev_get_info(page);
 183                         break;
 184                 case 132:
 185                         length = raw_get_info(page);
 186                         break;
 187                 case 133:
 188                         length = tcp_get_info(page);
 189                         break;
 190                 case 134:
 191                         length = udp_get_info(page);
 192                         break;
 193 #endif /* CONFIG_INET */
 194                 default:
 195                         free_page((unsigned long) page);
 196                         return -EBADF;
 197         }
 198         if (file->f_pos >= length) {
 199                 free_page((unsigned long) page);
 200                 return 0;
 201         }
 202         if (count + file->f_pos > length)
 203                 count = length - file->f_pos;
 204         end = count + file->f_pos;
 205         memcpy_tofs(buf, page + file->f_pos, count);
 206         free_page((unsigned long) page);
 207         file->f_pos = end;
 208         return count;
 209 
 210 }

/* [previous][next][first][last][top][bottom][index][help] */