home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / proc / net.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-16  |  4.9 KB  |  211 lines

  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. extern int unix_get_info(char *);
  40. #ifdef CONFIG_INET
  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.     { 128,4,"unix" }
  88. #ifdef CONFIG_INET
  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,
  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,
  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,
  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. }
  211.