summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMartin Baulig <martin@src.gnome.org>1999-04-05 12:49:04 +0000
committerMartin Baulig <martin@src.gnome.org>1999-04-05 12:49:04 +0000
commit3130d7db337dab18727445f8b291f19dd417f6b7 (patch)
treee40f9ecdda7384b5792a430d6332c4bc5b2b567a /kernel
parent30af079f994622a591e9d432dbe524257f26cf37 (diff)
downloadlibgtop-3130d7db337dab18727445f8b291f19dd417f6b7.tar.gz
Added LIBGTOP_NETLOAD: Network statistics.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sysctl/libgtop.c119
-rw-r--r--kernel/sysctl/libgtop.h38
2 files changed, 156 insertions, 1 deletions
diff --git a/kernel/sysctl/libgtop.c b/kernel/sysctl/libgtop.c
index aa99139e..ec3ed143 100644
--- a/kernel/sysctl/libgtop.c
+++ b/kernel/sysctl/libgtop.c
@@ -52,6 +52,17 @@ static int proc_maps_ctl_handler (ctl_table *table, int *name, int nlen,
void *newval, size_t newlen,
void **context);
+#if CONFIG_NET
+
+#include <linux/netdevice.h>
+
+static int proc_net_ctl_handler (ctl_table *table, int *name, int nlen,
+ void *oldval, size_t *oldlenp,
+ void *newval, size_t newlen,
+ void **context);
+
+#endif /* CONFIG_NET */
+
static int libgtop_sysctl_version = 1;
static int libgtop_update_expensive = 5000;
@@ -106,6 +117,12 @@ ctl_table libgtop_table[] = {
&proc_args_ctl_handler},
{LIBGTOP_PROC_MAPS, NULL, NULL, 0, 0444, NULL, NULL,
&proc_maps_ctl_handler},
+#if CONFIG_NET
+ /* You cannot actually "write" this value; we just use this to
+ * pass the device name as parameter. */
+ {LIBGTOP_NETLOAD, NULL, NULL, 0, 0666, NULL, NULL,
+ &proc_net_ctl_handler},
+#endif
{0}
};
@@ -1147,3 +1164,105 @@ proc_maps_ctl_handler (ctl_table *table, int *name, int nlen,
kfree (proc_maps);
return retval;
}
+
+#if CONFIG_NET
+
+static int
+proc_net_ctl_handler (ctl_table *table, int *name, int nlen,
+ void *oldval, size_t *oldlenp, void *newval,
+ size_t newlen, void **context)
+{
+ int len, len_name, retval = -ENOSYS;
+ struct net_device_stats *stats;
+ libgtop_netload_t netload;
+ struct device *dev;
+ char *dev_name;
+
+ if (!oldlenp || get_user (len, oldlenp))
+ return -EFAULT;
+
+ if (len != sizeof (libgtop_netload_t))
+ return -EFAULT;
+
+ if (!name || !nlen || get_user (len_name, name))
+ return -EFAULT;
+
+ if (nlen != 1)
+ return -EFAULT;
+
+ /* Allocate memory for device name. */
+ if (newlen > PAGE_SIZE)
+ return -ENOMEM;
+
+ if (!(dev_name = kmalloc (newlen+1, GFP_KERNEL)))
+ return -ENOMEM;
+
+ /* Copy device name from user space. */
+ if (copy_from_user (dev_name, newval, newlen)) {
+ retval = -EFAULT;
+ goto free_name_out;
+ }
+ dev_name [newlen] = '\0';
+
+ dev = dev_get (dev_name);
+ if (!dev) {
+ retval = -ENODEV;
+ goto free_name_out;
+ }
+
+ if (!dev->get_stats) {
+ retval = -ENODEV;
+ goto free_name_out;
+ }
+
+ stats = dev->get_stats (dev);
+
+ if (!stats) {
+ retval = -ENODEV;
+ goto free_name_out;
+ }
+
+ netload.rx_packets = stats->rx_packets;
+ netload.tx_packets = stats->tx_packets;
+
+ netload.rx_bytes = stats->rx_bytes;
+ netload.tx_bytes = stats->tx_bytes;
+
+ netload.rx_errors = stats->rx_errors;
+ netload.tx_errors = stats->tx_errors;
+
+ netload.rx_dropped = stats->rx_dropped;
+ netload.tx_dropped = stats->tx_dropped;
+
+ netload.multicast = stats->multicast;
+ netload.collisions = stats->collisions;
+
+ netload.rx_length_errors = stats->rx_length_errors;
+ netload.rx_over_errors = stats->rx_over_errors;
+ netload.rx_crc_errors = stats->rx_crc_errors;
+ netload.rx_frame_errors = stats->rx_frame_errors;
+ netload.rx_fifo_errors = stats->rx_fifo_errors;
+ netload.rx_missed_errors = stats->rx_missed_errors;
+
+ netload.tx_aborted_errors = stats->tx_aborted_errors;
+ netload.tx_carrier_errors = stats->tx_carrier_errors;
+ netload.tx_fifo_errors = stats->tx_fifo_errors;
+ netload.tx_heartbeat_errors = stats->tx_heartbeat_errors;
+ netload.tx_window_errors = stats->tx_window_errors;
+
+ netload.rx_compressed = stats->rx_compressed;
+ netload.tx_compressed = stats->tx_compressed;
+
+ if (copy_to_user (oldval, (void *) &netload, len)) {
+ retval = -EFAULT;
+ goto free_name_out;
+ }
+
+ retval = 1;
+
+ free_name_out:
+ kfree (dev_name);
+ return retval;
+}
+
+#endif /* CONFIG_NET */
diff --git a/kernel/sysctl/libgtop.h b/kernel/sysctl/libgtop.h
index 7ebd2165..3152ccc2 100644
--- a/kernel/sysctl/libgtop.h
+++ b/kernel/sysctl/libgtop.h
@@ -17,7 +17,8 @@ enum {
LIBGTOP_PROC_MEM,
LIBGTOP_PROC_SIGNAL,
LIBGTOP_PROC_ARGS,
- LIBGTOP_PROC_MAPS
+ LIBGTOP_PROC_MAPS,
+ LIBGTOP_NETLOAD
};
enum {
@@ -87,6 +88,8 @@ typedef struct libgtop_proc_signal libgtop_proc_signal_t;
typedef struct libgtop_proc_maps_header libgtop_proc_maps_header_t;
typedef struct libgtop_proc_maps libgtop_proc_maps_t;
+typedef struct libgtop_netload libgtop_netload_t;
+
struct libgtop_cpu
{
unsigned long total; /* Total CPU Time */
@@ -204,4 +207,37 @@ struct libgtop_proc_maps
char filename [LIBGTOP_MAP_PATH_LEN];
};
+struct libgtop_netload
+{
+ unsigned long rx_packets; /* total packets received */
+ unsigned long tx_packets; /* total packets transmitted */
+ unsigned long rx_bytes; /* total bytes received */
+ unsigned long tx_bytes; /* total bytes transmitted */
+ unsigned long rx_errors; /* bad packets received */
+ unsigned long tx_errors; /* packet transmit problems */
+ unsigned long rx_dropped; /* no space in linux buffers */
+ unsigned long tx_dropped; /* no space available in linux */
+ unsigned long multicast; /* multicast packets received */
+ unsigned long collisions;
+
+ /* detailed rx_errors: */
+ unsigned long rx_length_errors;
+ unsigned long rx_over_errors; /* receiver ring buff overflow */
+ unsigned long rx_crc_errors; /* recved pkt with crc error */
+ unsigned long rx_frame_errors; /* recv'd frame alignment error */
+ unsigned long rx_fifo_errors; /* recv'r fifo overrun */
+ unsigned long rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ unsigned long tx_aborted_errors;
+ unsigned long tx_carrier_errors;
+ unsigned long tx_fifo_errors;
+ unsigned long tx_heartbeat_errors;
+ unsigned long tx_window_errors;
+
+ /* for cslip etc */
+ unsigned long rx_compressed;
+ unsigned long tx_compressed;
+};
+
#endif