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  * Alan Cox (gw4pts@gw4pts.ampr.org) 4/94
  19  *            Dusted off the code and added IPX. Fixed the 4K limit.
  20  * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
  21  *            /proc/net/snmp.
  22  *
  23  *  proc net directory handling functions
  24  */
  25 #include <linux/autoconf.h>
  26 
  27 #include <asm/segment.h>
  28 
  29 #include <linux/errno.h>
  30 #include <linux/sched.h>
  31 #include <linux/proc_fs.h>
  32 #include <linux/stat.h>
  33 
  34 /* forward references */
  35 static int proc_readnet(struct inode * inode, struct file * file,
  36                          char * buf, int count);
  37 static int proc_readnetdir(struct inode *, struct file *,
  38                            struct dirent *, int);
  39 static int proc_lookupnet(struct inode *,const char *,int,struct inode **);
  40 
  41 /* the get_*_info() functions are in the net code, and are configured
  42    in via the standard mechanism... */
  43 extern int unix_get_info(char *, char **, off_t, int);
  44 #ifdef CONFIG_INET
  45 extern int tcp_get_info(char *, char **, off_t, int);
  46 extern int udp_get_info(char *, char **, off_t, int);
  47 extern int raw_get_info(char *, char **, off_t, int);
  48 extern int arp_get_info(char *, char **, off_t, int);
  49 extern int rarp_get_info(char *, char **, off_t, int);
  50 extern int dev_get_info(char *, char **, off_t, int);
  51 extern int rt_get_info(char *, char **, off_t, int);
  52 extern int snmp_get_info(char *, char **, off_t, int);
  53 #endif /* CONFIG_INET */
  54 #ifdef CONFIG_IPX
  55 extern int ipx_get_info(char *, char **, off_t, int);
  56 extern int ipx_rt_get_info(char *, char **, off_t, int);
  57 #endif /* CONFIG_IPX */
  58 #ifdef CONFIG_AX25
  59 extern int ax25_get_info(char *, char **, off_t, int);
  60 extern int ax25_rt_get_info(char *, char **, off_t, int);
  61 #ifdef CONFIG_NETROM
  62 extern int nr_get_info(char *, char **, off_t, int);
  63 extern int nr_nodes_get_info(char *, char **, off_t, int);
  64 extern int nr_neigh_get_info(char *, char **, off_t, int);
  65 #endif /* CONFIG_NETROM */
  66 #endif /* CONFIG_AX25 */
  67 
  68 
  69 static struct file_operations proc_net_operations = {
  70         NULL,                   /* lseek - default */
  71         proc_readnet,           /* read - bad */
  72         NULL,                   /* write - bad */
  73         proc_readnetdir,        /* readdir */
  74         NULL,                   /* select - default */
  75         NULL,                   /* ioctl - default */
  76         NULL,                   /* mmap */
  77         NULL,                   /* no special open code */
  78         NULL,                   /* no special release code */
  79         NULL                    /* can't fsync */
  80 };
  81 
  82 /*
  83  * proc directories can do almost nothing..
  84  */
  85 struct inode_operations proc_net_inode_operations = {
  86         &proc_net_operations,   /* default net directory file-ops */
  87         NULL,                   /* create */
  88         proc_lookupnet,         /* lookup */
  89         NULL,                   /* link */
  90         NULL,                   /* unlink */
  91         NULL,                   /* symlink */
  92         NULL,                   /* mkdir */
  93         NULL,                   /* rmdir */
  94         NULL,                   /* mknod */
  95         NULL,                   /* rename */
  96         NULL,                   /* readlink */
  97         NULL,                   /* follow_link */
  98         NULL,                   /* bmap */
  99         NULL,                   /* truncate */
 100         NULL                    /* permission */
 101 };
 102 
 103 static struct proc_dir_entry net_dir[] = {
 104         { 1,2,".." },
 105         { 8,1,"." },
 106         { 128,4,"unix" }
 107 #ifdef CONFIG_INET
 108         ,{ 129,3,"arp" },
 109         { 130,5,"route" },
 110         { 131,3,"dev" },
 111         { 132,3,"raw" },
 112         { 133,3,"tcp" },
 113         { 134,3,"udp" },
 114         { 135,4,"snmp" }
 115 #ifdef CONFIG_INET_RARP
 116         ,{ 136,4,"rarp"}
 117 #endif
 118 #endif  /* CONFIG_INET */
 119 #ifdef CONFIG_IPX
 120         ,{ 137,9,"ipx_route" },
 121         { 138,3,"ipx" }
 122 #endif /* CONFIG_IPX */
 123 #ifdef CONFIG_AX25
 124         ,{ 139,10,"ax25_route" },
 125         { 140,4,"ax25" }
 126 #ifdef CONFIG_NETROM
 127         ,{ 141,8,"nr_nodes" },
 128         { 142,8,"nr_neigh" },
 129         { 143,2,"nr" }
 130 #endif /* CONFIG_NETROM */
 131 #endif /* CONFIG_AX25 */
 132 };
 133 
 134 #define NR_NET_DIRENTRY ((sizeof (net_dir))/(sizeof (net_dir[0])))
 135 
 136 
 137 static int proc_lookupnet(struct inode * dir,const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 138         struct inode ** result)
 139 {
 140         unsigned int ino;
 141         int i;
 142 
 143         *result = NULL;
 144         if (!dir)
 145                 return -ENOENT;
 146         if (!S_ISDIR(dir->i_mode)) {
 147                 iput(dir);
 148                 return -ENOENT;
 149         }
 150         i = NR_NET_DIRENTRY;
 151         while (i-- > 0 && !proc_match(len,name,net_dir+i))
 152                 /* nothing */;
 153         if (i < 0) {
 154                 iput(dir);
 155                 return -ENOENT;
 156         }
 157         ino = net_dir[i].low_ino;
 158         if (!(*result = iget(dir->i_sb,ino))) {
 159                 iput(dir);
 160                 return -ENOENT;
 161         }
 162         iput(dir);
 163         return 0;
 164 }
 165 
 166 static int proc_readnetdir(struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 167         struct dirent * dirent, int count)
 168 {
 169         struct proc_dir_entry * de;
 170         unsigned int ino;
 171         int i,j;
 172 
 173         if (!inode || !S_ISDIR(inode->i_mode))
 174                 return -EBADF;
 175         ino = inode->i_ino;
 176         if (((unsigned) filp->f_pos) < NR_NET_DIRENTRY) {
 177                 de = net_dir + filp->f_pos;
 178                 filp->f_pos++;
 179                 i = de->namelen;
 180                 ino = de->low_ino;
 181                 put_fs_long(ino, &dirent->d_ino);
 182                 put_fs_word(i,&dirent->d_reclen);
 183                 put_fs_byte(0,i+dirent->d_name);
 184                 j = i;
 185                 while (i--)
 186                         put_fs_byte(de->name[i], i+dirent->d_name);
 187                 return j;
 188         }
 189         return 0;
 190 }
 191 
 192 
 193 #define PROC_BLOCK_SIZE (3*1024)                /* 4K page size but our output routines use some slack for overruns */
 194 
 195 static int proc_readnet(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 196                         char * buf, int count)
 197 {
 198         char * page;
 199         int length;
 200         unsigned int ino;
 201         int bytes=count;
 202         int thistime;
 203         int copied=0;
 204         char *start;
 205 
 206         if (count < 0)
 207                 return -EINVAL;
 208         if (!(page = (char*) __get_free_page(GFP_KERNEL)))
 209                 return -ENOMEM;
 210         ino = inode->i_ino;
 211 
 212         while(bytes>0)
 213         {
 214                 thistime=bytes;
 215                 if(bytes>PROC_BLOCK_SIZE)
 216                         thistime=PROC_BLOCK_SIZE;
 217 
 218                 switch (ino) 
 219                 {
 220                         case 128:
 221                                 length = unix_get_info(page,&start,file->f_pos,thistime);
 222                                 break;
 223 #ifdef CONFIG_INET
 224                         case 129:
 225                                 length = arp_get_info(page,&start,file->f_pos,thistime);
 226                                 break;
 227                         case 130:
 228                                 length = rt_get_info(page,&start,file->f_pos,thistime);
 229                                 break;
 230                         case 131:
 231                                 length = dev_get_info(page,&start,file->f_pos,thistime);
 232                                 break;
 233                         case 132:
 234                                 length = raw_get_info(page,&start,file->f_pos,thistime);
 235                                 break;
 236                         case 133:
 237                                 length = tcp_get_info(page,&start,file->f_pos,thistime);
 238                                 break;
 239                         case 134:
 240                                 length = udp_get_info(page,&start,file->f_pos,thistime);
 241                                 break;
 242                         case 135:
 243                                 length = snmp_get_info(page, &start, file->f_pos,thistime);
 244                                 break;
 245 #ifdef CONFIG_INET_RARP                         
 246                         case 136:
 247                                 length = rarp_get_info(page,&start,file->f_pos,thistime);
 248                                 break;
 249 #endif /* CONFIG_INET_RARP */                           
 250 #endif /* CONFIG_INET */
 251 #ifdef CONFIG_IPX
 252                         case 137:
 253                                 length = ipx_rt_get_info(page,&start,file->f_pos,thistime);
 254                                 break;
 255                         case 138:
 256                                 length = ipx_get_info(page,&start,file->f_pos,thistime);
 257                                 break;
 258 #endif /* CONFIG_IPX */
 259 #ifdef CONFIG_AX25
 260                         case 139:
 261                                 length = ax25_rt_get_info(page,&start,file->f_pos,thistime);
 262                                 break;
 263                         case 140:
 264                                 length = ax25_get_info(page,&start,file->f_pos,thistime);
 265                                 break;
 266 #ifdef CONFIG_NETROM
 267                         case 141:
 268                                 length = nr_nodes_get_info(page,&start,file->f_pos,thistime);
 269                                 break;
 270                         case 142:
 271                                 length = nr_neigh_get_info(page,&start,file->f_pos,thistime);
 272                                 break;
 273                         case 143:
 274                                 length = nr_get_info(page,&start,file->f_pos,thistime);
 275                                 break;
 276 #endif /* CONFIG_NETROM */
 277 #endif /* CONFIG_AX25 */
 278 
 279                         default:
 280                                 free_page((unsigned long) page);
 281                                 return -EBADF;
 282                 }
 283                 
 284                 /*
 285                  *      We have been given a non page aligned block of
 286                  *      the data we asked for + a bit. We have been given
 287                  *      the start pointer and we know the length.. 
 288                  */
 289 
 290                 if (length <= 0)
 291                         break;
 292                 /*
 293                  *      Copy the bytes
 294                  */
 295                 memcpy_tofs(buf+copied, start, length);
 296                 file->f_pos+=length;    /* Move down the file */
 297                 bytes-=length;
 298                 copied+=length;
 299                 if(length<thistime)
 300                         break;  /* End of file */
 301         }
 302         free_page((unsigned long) page);
 303         return copied;
 304 
 305 }

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