patch-2.1.25 linux/net/wanrouter/wanproc.c
Next file: linux/net/x25/af_x25.c
Previous file: linux/net/wanrouter/wanmain.c
Back to the patch index
Back to the overall index
- Lines: 461
- Date:
Sun Feb 2 16:44:21 1997
- Orig file:
v2.1.24/linux/net/wanrouter/wanproc.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v2.1.24/linux/net/wanrouter/wanproc.c linux/net/wanrouter/wanproc.c
@@ -0,0 +1,460 @@
+/*****************************************************************************
+* wanproc.c WAN Multiprotocol Router Module. proc filesystem interface.
+*
+* This module is completely hardware-independent and provides
+* access to the router using Linux /proc filesystem.
+*
+* Author: Gene Kozin <genek@compuserve.com>
+*
+* Copyright: (c) 1995-1996 Sangoma Technologies Inc.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version
+* 2 of the License, or (at your option) any later version.
+* ============================================================================
+* Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
+* Jan 30, 1997 Alan Cox Hacked around for 2.1
+*****************************************************************************/
+
+#include <linux/stddef.h> /* offsetof(), etc. */
+#include <linux/errno.h> /* return codes */
+#include <linux/kernel.h>
+#include <linux/malloc.h> /* kmalloc(), kfree() */
+#include <linux/mm.h> /* verify_area(), etc. */
+#include <linux/string.h> /* inline mem*, str* functions */
+#include <asm/segment.h> /* kernel <-> user copy */
+#include <asm/byteorder.h> /* htons(), etc. */
+#include <asm/uaccess.h> /* copy_to_user */
+#include <linux/wanrouter.h> /* WAN router API definitions */
+
+
+/****** Defines and Macros **************************************************/
+
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
+#define ROUTER_PAGE_SZ 4000 /* buffer size for printing proc info */
+
+/****** Data Types **********************************************************/
+
+typedef struct wan_stat_entry
+{
+ struct wan_stat_entry * next;
+ char *description; /* description string */
+ void *data; /* -> data */
+ unsigned data_type; /* data type */
+} wan_stat_entry_t;
+
+/****** Function Prototypes *************************************************/
+
+/* Proc filesystem interface */
+static int router_proc_perms (struct inode*, int);
+static long router_proc_read(struct inode* inode, struct file* file, char* buf,
+ unsigned long count);
+
+/* Methods for preparing data for reading proc entries */
+
+static int about_get_info(char* buf, char** start, off_t offs, int len, int dummy);
+static int config_get_info(char* buf, char** start, off_t offs, int len, int dummy);
+static int status_get_info(char* buf, char** start, off_t offs, int len, int dummy);
+static int wandev_get_info(char* buf, char** start, off_t offs, int len, int dummy);
+
+/* Miscellaneous */
+
+/*
+ * Global Data
+ */
+
+/*
+ * Names of the proc directory entries
+ */
+
+static char name_root[] = ROUTER_NAME;
+static char name_info[] = "about";
+static char name_conf[] = "config";
+static char name_stat[] = "status";
+
+/*
+ * Structures for interfacing with the /proc filesystem.
+ * Router creates its own directory /proc/net/router with the folowing
+ * entries:
+ * About general information (version, copyright, etc.)
+ * Conf device configuration
+ * Stat global device statistics
+ * <device> entry for each WAN device
+ */
+
+/*
+ * Generic /proc/net/router/<file> file and inode operations
+ */
+
+static struct file_operations router_fops =
+{
+ NULL, /* lseek */
+ router_proc_read, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* select */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ NULL, /* no special open code */
+ NULL, /* no special release code */
+ NULL /* can't fsync */
+};
+
+static struct inode_operations router_inode =
+{
+ &router_fops,
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
+ NULL, /* bmap */
+ NULL, /* truncate */
+ router_proc_perms
+};
+
+/*
+ * /proc/net/router/<device> file and inode operations
+ */
+
+static struct file_operations wandev_fops =
+{
+ NULL, /* lseek */
+ router_proc_read, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* select */
+ wanrouter_ioctl, /* ioctl */
+ NULL, /* mmap */
+ NULL, /* no special open code */
+ NULL, /* no special release code */
+ NULL /* can't fsync */
+};
+
+static struct inode_operations wandev_inode =
+{
+ &wandev_fops,
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
+ NULL, /* bmap */
+ NULL, /* truncate */
+ router_proc_perms
+};
+
+/*
+ * Proc filesystem derectory entries.
+ */
+
+/*
+ * /proc/net/router
+ */
+
+static struct proc_dir_entry proc_router =
+{
+ 0, /* .low_ino */
+ sizeof(name_root) - 1, /* .namelen */
+ name_root, /* .name */
+ 0555 | S_IFDIR, /* .mode */
+ 2, /* .nlink */
+ 0, /* .uid */
+ 0, /* .gid */
+ 0, /* .size */
+ &proc_dir_inode_operations, /* .ops */
+ NULL, /* .get_info */
+ NULL, /* .fill_node */
+ NULL, /* .next */
+ NULL, /* .parent */
+ NULL, /* .subdir */
+ NULL, /* .data */
+};
+
+/*
+ * /proc/net/router/about
+ */
+
+static struct proc_dir_entry proc_router_info =
+{
+ 0, /* .low_ino */
+ sizeof(name_info) - 1, /* .namelen */
+ name_info, /* .name */
+ 0444 | S_IFREG, /* .mode */
+ 1, /* .nlink */
+ 0, /* .uid */
+ 0, /* .gid */
+ 0, /* .size */
+ &router_inode, /* .ops */
+ &about_get_info, /* .get_info */
+ NULL, /* .fill_node */
+ NULL, /* .next */
+ NULL, /* .parent */
+ NULL, /* .subdir */
+ NULL, /* .data */
+};
+
+/*
+ * /proc/net/router/config
+ */
+
+static struct proc_dir_entry proc_router_conf =
+{
+ 0, /* .low_ino */
+ sizeof(name_conf) - 1, /* .namelen */
+ name_conf, /* .name */
+ 0444 | S_IFREG, /* .mode */
+ 1, /* .nlink */
+ 0, /* .uid */
+ 0, /* .gid */
+ 0, /* .size */
+ &router_inode, /* .ops */
+ &config_get_info, /* .get_info */
+ NULL, /* .fill_node */
+ NULL, /* .next */
+ NULL, /* .parent */
+ NULL, /* .subdir */
+ NULL, /* .data */
+};
+
+/*
+ * /proc/net/router/status
+ */
+
+static struct proc_dir_entry proc_router_stat =
+{
+ 0, /* .low_ino */
+ sizeof(name_stat) - 1, /* .namelen */
+ name_stat, /* .name */
+ 0444 | S_IFREG, /* .mode */
+ 1, /* .nlink */
+ 0, /* .uid */
+ 0, /* .gid */
+ 0, /* .size */
+ &router_inode, /* .ops */
+ status_get_info, /* .get_info */
+ NULL, /* .fill_node */
+ NULL, /* .next */
+ NULL, /* .parent */
+ NULL, /* .subdir */
+ NULL, /* .data */
+};
+
+/*
+ * Interface functions
+ */
+
+/*
+ * Initialize router proc interface.
+ */
+
+int wanrouter_proc_init (void)
+{
+ int err = proc_register_dynamic(&proc_net, &proc_router);
+
+ if (!err)
+ {
+ proc_register_dynamic(&proc_router, &proc_router_info);
+ proc_register_dynamic(&proc_router, &proc_router_conf);
+ proc_register_dynamic(&proc_router, &proc_router_stat);
+ }
+ return err;
+}
+
+/*
+ * Clean up router proc interface.
+ */
+
+void wanrouter_proc_cleanup (void)
+{
+ proc_unregister(&proc_router, proc_router_info.low_ino);
+ proc_unregister(&proc_router, proc_router_conf.low_ino);
+ proc_unregister(&proc_router, proc_router_stat.low_ino);
+ proc_unregister(&proc_net, proc_router.low_ino);
+}
+
+/*
+ * Add directory entry for WAN device.
+ */
+
+int wanrouter_proc_add (wan_device_t* wandev)
+{
+ if (wandev->magic != ROUTER_MAGIC)
+ return -EINVAL;
+
+ memset(&wandev->dent, 0, sizeof(wandev->dent));
+ wandev->dent.namelen = strlen(wandev->name);
+ wandev->dent.name = wandev->name;
+ wandev->dent.mode = 0444 | S_IFREG;
+ wandev->dent.nlink = 1;
+ wandev->dent.ops = &wandev_inode;
+ wandev->dent.get_info = &wandev_get_info;
+ wandev->dent.data = wandev;
+ return proc_register_dynamic(&proc_router, &wandev->dent);
+}
+
+/*
+ * Delete directory entry for WAN device.
+ */
+
+int wanrouter_proc_delete(wan_device_t* wandev)
+{
+ if (wandev->magic != ROUTER_MAGIC)
+ return -EINVAL;
+ proc_unregister(&proc_router, wandev->dent.low_ino);
+ return 0;
+}
+
+/****** Proc filesystem entry points ****************************************/
+
+/*
+ * Verify access rights.
+ */
+
+static int router_proc_perms (struct inode* inode, int op)
+{
+ return 0;
+}
+
+/*
+ * Read router proc directory entry.
+ * This is universal routine for reading all entries in /proc/net/router
+ * directory. Each directory entry contains a pointer to the 'method' for
+ * preparing data for that entry.
+ * o verify arguments
+ * o allocate kernel buffer
+ * o call get_info() to prepare data
+ * o copy data to user space
+ * o release kernel buffer
+ *
+ * Return: number of bytes copied to user space (0, if no data)
+ * <0 error
+ */
+
+static long router_proc_read(struct inode* inode, struct file* file,
+ char* buf, unsigned long count)
+{
+ struct proc_dir_entry* dent;
+ char* page;
+ int pos, offs, len;
+
+ if (count <= 0)
+ return 0;
+
+ dent = inode->u.generic_ip;
+ if ((dent == NULL) || (dent->get_info == NULL))
+ return 0;
+
+ page = kmalloc(ROUTER_PAGE_SZ, GFP_KERNEL);
+ if (page == NULL)
+ return -ENOBUFS;
+
+ pos = dent->get_info(page, dent->data, 0, 0, 0);
+ offs = file->f_pos;
+ if (offs < pos)
+ {
+ len = min(pos - offs, count);
+ if(copy_to_user(buf, (page + offs), len))
+ return -EFAULT;
+ file->f_pos += len;
+ }
+ else
+ len = 0;
+ kfree(page);
+ return len;
+}
+
+/*
+ * Prepare data for reading 'About' entry.
+ * Return length of data.
+ */
+
+static int about_get_info(char* buf, char** start, off_t offs, int len,
+ int dummy)
+{
+ int cnt = 0;
+
+ cnt += sprintf(&buf[cnt], "%12s : %u.%u\n",
+ "version", ROUTER_VERSION, ROUTER_RELEASE);
+ return cnt;
+}
+
+/*
+ * Prepare data for reading 'Config' entry.
+ * Return length of data.
+ * NOT YET IMPLEMENTED
+ */
+
+static int config_get_info(char* buf, char** start, off_t offs, int len,
+ int dummy)
+{
+ int cnt = 0;
+
+ cnt += sprintf(&buf[cnt], "%12s : %u.%u\n",
+ "version", ROUTER_VERSION, ROUTER_RELEASE);
+ return cnt;
+}
+
+/*
+ * Prepare data for reading 'Status' entry.
+ * Return length of data.
+ * NOT YET IMPLEMENTED
+ */
+
+static int status_get_info(char* buf, char** start, off_t offs, int len,
+ int dummy)
+{
+ int cnt = 0;
+
+ cnt += sprintf(&buf[cnt], "%12s : %u.%u\n",
+ "version", ROUTER_VERSION, ROUTER_RELEASE);
+ return cnt;
+}
+
+/*
+ * Prepare data for reading <device> entry.
+ * Return length of data.
+ *
+ * On entry, the 'start' argument will contain a pointer to WAN device
+ * data space.
+ */
+
+static int wandev_get_info(char* buf, char** start, off_t offs, int len,
+ int dummy)
+{
+ wan_device_t* wandev = (void*)start;
+ int cnt = 0;
+
+ if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
+ return 0;
+ cnt += sprintf(&buf[cnt], "%12s : %s\n", "name", wandev->name);
+ return cnt;
+}
+
+/*
+ * End
+ */
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov