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 extern int ip_acct_procinfo(char *, char **, off_t, int);
  54 extern int ip_fw_blk_procinfo(char *, char **, off_t, int);
  55 extern int ip_fw_fwd_procinfo(char *, char **, off_t, int);
  56 extern int ip_mc_procinfo(char *, char **, off_t, int);
  57 #endif /* CONFIG_INET */
  58 #ifdef CONFIG_IPX
  59 extern int ipx_get_info(char *, char **, off_t, int);
  60 extern int ipx_rt_get_info(char *, char **, off_t, int);
  61 #endif /* CONFIG_IPX */
  62 #ifdef CONFIG_AX25
  63 extern int ax25_get_info(char *, char **, off_t, int);
  64 extern int ax25_rt_get_info(char *, char **, off_t, int);
  65 #ifdef CONFIG_NETROM
  66 extern int nr_get_info(char *, char **, off_t, int);
  67 extern int nr_nodes_get_info(char *, char **, off_t, int);
  68 extern int nr_neigh_get_info(char *, char **, off_t, int);
  69 #endif /* CONFIG_NETROM */
  70 #endif /* CONFIG_AX25 */
  71 
  72 
  73 static struct file_operations proc_net_operations = {
  74         NULL,                   /* lseek - default */
  75         proc_readnet,           /* read - bad */
  76         NULL,                   /* write - bad */
  77         proc_readnetdir,        /* readdir */
  78         NULL,                   /* select - default */
  79         NULL,                   /* ioctl - default */
  80         NULL,                   /* mmap */
  81         NULL,                   /* no special open code */
  82         NULL,                   /* no special release code */
  83         NULL                    /* can't fsync */
  84 };
  85 
  86 /*
  87  * proc directories can do almost nothing..
  88  */
  89 struct inode_operations proc_net_inode_operations = {
  90         &proc_net_operations,   /* default net directory file-ops */
  91         NULL,                   /* create */
  92         proc_lookupnet,         /* lookup */
  93         NULL,                   /* link */
  94         NULL,                   /* unlink */
  95         NULL,                   /* symlink */
  96         NULL,                   /* mkdir */
  97         NULL,                   /* rmdir */
  98         NULL,                   /* mknod */
  99         NULL,                   /* rename */
 100         NULL,                   /* readlink */
 101         NULL,                   /* follow_link */
 102         NULL,                   /* bmap */
 103         NULL,                   /* truncate */
 104         NULL                    /* permission */
 105 };
 106 
 107 static struct proc_dir_entry net_dir[] = {
 108         { PROC_NET,             1, "." },
 109         { PROC_ROOT_INO,        2, ".." },
 110         { PROC_NET_UNIX,        4, "unix" },
 111 #ifdef CONFIG_INET
 112         { PROC_NET_ARP,         3, "arp" },
 113         { PROC_NET_ROUTE,       5, "route" },
 114         { PROC_NET_DEV,         3, "dev" },
 115         { PROC_NET_RAW,         3, "raw" },
 116         { PROC_NET_TCP,         3, "tcp" },
 117         { PROC_NET_UDP,         3, "udp" },
 118         { PROC_NET_SNMP,        4, "snmp" },
 119 #ifdef CONFIG_INET_RARP
 120         { PROC_NET_RARP,        4, "rarp"},
 121 #endif
 122 #ifdef CONFIG_IP_MULTICAST
 123         { PROC_NET_IGMP,        4, "igmp"},
 124 #endif
 125 #ifdef CONFIG_IP_FIREWALL
 126         { PROC_NET_IPFWFWD,     10, "ip_forward"},
 127         { PROC_NET_IPBLFWD,     8,  "ip_block"},
 128 #endif
 129 #ifdef CONFIG_IP_ACCT
 130         { PROC_NET_IPACCT,      7,  "ip_acct"},
 131 #endif
 132 #endif  /* CONFIG_INET */
 133 #ifdef CONFIG_IPX
 134         { PROC_NET_IPX_ROUTE,   9, "ipx_route" },
 135         { PROC_NET_IPX,         3, "ipx" },
 136 #endif /* CONFIG_IPX */
 137 #ifdef CONFIG_AX25
 138         { PROC_NET_AX25_ROUTE,  10, "ax25_route" },
 139         { PROC_NET_AX25,        4, "ax25" },
 140 #ifdef CONFIG_NETROM
 141         { PROC_NET_NR_NODES,    8, "nr_nodes" },
 142         { PROC_NET_NR_NEIGH,    8, "nr_neigh" },
 143         { PROC_NET_NR,          2, "nr" },
 144 #endif /* CONFIG_NETROM */
 145 #endif /* CONFIG_AX25 */
 146         { 0, 0, NULL }
 147 };
 148 
 149 #define NR_NET_DIRENTRY ((sizeof (net_dir))/(sizeof (net_dir[0])) - 1)
 150 
 151 static int proc_lookupnet(struct inode * dir,const char * name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 152         struct inode ** result)
 153 {
 154         struct proc_dir_entry *de;
 155 
 156         *result = NULL;
 157         if (!dir)
 158                 return -ENOENT;
 159         if (!S_ISDIR(dir->i_mode)) {
 160                 iput(dir);
 161                 return -ENOENT;
 162         }
 163         for (de = net_dir ; de->name ; de++) {
 164                 if (!proc_match(len, name, de))
 165                         continue;
 166                 *result = iget(dir->i_sb, de->low_ino);
 167                 iput(dir);
 168                 if (!*result)
 169                         return -ENOENT;
 170                 return 0;
 171         }
 172         return -ENOENT;
 173 }
 174 
 175 static int proc_readnetdir(struct inode * inode, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
 176         struct dirent * dirent, int count)
 177 {
 178         struct proc_dir_entry * de;
 179         unsigned int ino;
 180         int i,j;
 181 
 182         if (!inode || !S_ISDIR(inode->i_mode))
 183                 return -EBADF;
 184         ino = inode->i_ino;
 185         if (((unsigned) filp->f_pos) < NR_NET_DIRENTRY) {
 186                 de = net_dir + filp->f_pos;
 187                 filp->f_pos++;
 188                 i = de->namelen;
 189                 ino = de->low_ino;
 190                 put_fs_long(ino, &dirent->d_ino);
 191                 put_fs_word(i,&dirent->d_reclen);
 192                 put_fs_byte(0,i+dirent->d_name);
 193                 j = i;
 194                 while (i--)
 195                         put_fs_byte(de->name[i], i+dirent->d_name);
 196                 return j;
 197         }
 198         return 0;
 199 }
 200 
 201 
 202 #define PROC_BLOCK_SIZE (3*1024)                /* 4K page size but our output routines use some slack for overruns */
 203 
 204 static int proc_readnet(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
 205                         char * buf, int count)
 206 {
 207         char * page;
 208         int length;
 209         unsigned int ino;
 210         int bytes=count;
 211         int thistime;
 212         int copied=0;
 213         char *start;
 214 
 215         if (count < 0)
 216                 return -EINVAL;
 217         if (!(page = (char*) __get_free_page(GFP_KERNEL)))
 218                 return -ENOMEM;
 219         ino = inode->i_ino;
 220 
 221         while(bytes>0)
 222         {
 223                 thistime=bytes;
 224                 if(bytes>PROC_BLOCK_SIZE)
 225                         thistime=PROC_BLOCK_SIZE;
 226 
 227                 switch (ino) 
 228                 {
 229                         case PROC_NET_UNIX:
 230                                 length = unix_get_info(page,&start,file->f_pos,thistime);
 231                                 break;
 232 #ifdef CONFIG_INET
 233                         case PROC_NET_ARP:
 234                                 length = arp_get_info(page,&start,file->f_pos,thistime);
 235                                 break;
 236                         case PROC_NET_ROUTE:
 237                                 length = rt_get_info(page,&start,file->f_pos,thistime);
 238                                 break;
 239                         case PROC_NET_DEV:
 240                                 length = dev_get_info(page,&start,file->f_pos,thistime);
 241                                 break;
 242                         case PROC_NET_RAW:
 243                                 length = raw_get_info(page,&start,file->f_pos,thistime);
 244                                 break;
 245                         case PROC_NET_TCP:
 246                                 length = tcp_get_info(page,&start,file->f_pos,thistime);
 247                                 break;
 248                         case PROC_NET_UDP:
 249                                 length = udp_get_info(page,&start,file->f_pos,thistime);
 250                                 break;
 251                         case PROC_NET_SNMP:
 252                                 length = snmp_get_info(page, &start, file->f_pos,thistime);
 253                                 break;
 254 #ifdef CONFIG_IP_MULTICAST
 255                         case PROC_NET_IGMP:
 256                                 length = ip_mc_procinfo(page, &start, file->f_pos,thistime);
 257                                 break;
 258 #endif
 259 #ifdef CONFIG_IP_FIREWALL
 260                         case PROC_NET_IPFWFWD:
 261                                 length = ip_fw_fwd_procinfo(page, &start, file->f_pos,thistime);
 262                                 break;
 263                         case PROC_NET_IPBLFWD:
 264                                 length = ip_fw_blk_procinfo(page, &start, file->f_pos,thistime);
 265                                 break;
 266 #endif
 267 #ifdef CONFIG_IP_ACCT
 268                         case PROC_NET_IPACCT:
 269                                 length = ip_acct_procinfo(page, &start, file->f_pos,thistime);
 270                                 break;
 271 #endif
 272 #ifdef CONFIG_INET_RARP                         
 273                         case PROC_NET_RARP:
 274                                 length = rarp_get_info(page,&start,file->f_pos,thistime);
 275                                 break;
 276 #endif /* CONFIG_INET_RARP */                           
 277 #endif /* CONFIG_INET */
 278 #ifdef CONFIG_IPX
 279                         case PROC_NET_IPX_ROUTE:
 280                                 length = ipx_rt_get_info(page,&start,file->f_pos,thistime);
 281                                 break;
 282                         case PROC_NET_IPX:
 283                                 length = ipx_get_info(page,&start,file->f_pos,thistime);
 284                                 break;
 285 #endif /* CONFIG_IPX */
 286 #ifdef CONFIG_AX25
 287                         case PROC_NET_AX25_ROUTE:
 288                                 length = ax25_rt_get_info(page,&start,file->f_pos,thistime);
 289                                 break;
 290                         case PROC_NET_AX25:
 291                                 length = ax25_get_info(page,&start,file->f_pos,thistime);
 292                                 break;
 293 #ifdef CONFIG_NETROM
 294                         case PROC_NET_NR_NODES:
 295                                 length = nr_nodes_get_info(page,&start,file->f_pos,thistime);
 296                                 break;
 297                         case PROC_NET_NR_NEIGH:
 298                                 length = nr_neigh_get_info(page,&start,file->f_pos,thistime);
 299                                 break;
 300                         case PROC_NET_NR:
 301                                 length = nr_get_info(page,&start,file->f_pos,thistime);
 302                                 break;
 303 #endif /* CONFIG_NETROM */
 304 #endif /* CONFIG_AX25 */
 305 
 306                         default:
 307                                 free_page((unsigned long) page);
 308                                 return -EBADF;
 309                 }
 310                 
 311                 /*
 312                  *      We have been given a non page aligned block of
 313                  *      the data we asked for + a bit. We have been given
 314                  *      the start pointer and we know the length.. 
 315                  */
 316 
 317                 if (length <= 0)
 318                         break;
 319                 /*
 320                  *      Copy the bytes
 321                  */
 322                 memcpy_tofs(buf+copied, start, length);
 323                 file->f_pos+=length;    /* Move down the file */
 324                 bytes-=length;
 325                 copied+=length;
 326                 if(length<thistime)
 327                         break;  /* End of file */
 328         }
 329         free_page((unsigned long) page);
 330         return copied;
 331 
 332 }

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