AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
AC_PLUGIN([email], [yes], [EMail statistics])
AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
+AC_PLUGIN([ethstat], [yes], [Stats from NIC driver])
AC_PLUGIN([exec], [yes], [Execution of external programs])
AC_PLUGIN([filecount], [yes], [Count files in directories])
AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
dns . . . . . . . . . $enable_dns
email . . . . . . . . $enable_email
entropy . . . . . . . $enable_entropy
+ ethstat . . . . . . . $enable_ethstat
exec . . . . . . . . $enable_exec
filecount . . . . . . $enable_filecount
fscache . . . . . . . $enable_fscache
--- /dev/null
+/**
+ * collectd - src/ethstat.c
+ * Copyright (C) 2011 Cyril Feraudet
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Cyril Feraudet <cyril at feraudet.com>
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+#include <sys/types.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include "ethstat.h"
+
+# if KERNEL_LINUX
+
+
+static int ethstat_config (const char *key, const char *value)
+{
+ if (strcasecmp (key, "Iface") == 0) {
+ ifacelist[ifacenumber] = malloc(strlen(value) + 1);
+ strcpy(ifacelist[ifacenumber++], value);
+ INFO("ethstat: Registred iface %s", value);
+ }
+ return (0);
+}
+
+
+static void ethstat_submit_value (char *devname, char *counter, unsigned long long value)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].counter = value;
+
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "ethstat", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, devname, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "derive", sizeof (vl.type));
+ sstrncpy (vl.type_instance, counter, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+}
+
+
+static int getstats(char *devname, struct ifreq *ifr) {
+ int fd;
+ struct ethtool_drvinfo drvinfo;
+ struct ethtool_gstrings *strings;
+ struct ethtool_stats *stats;
+ unsigned int n_stats, sz_str, sz_stats, i;
+ int err;
+
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ ERROR("ethstat - %s : Cannot get control socket", devname);
+ return 1;
+ }
+
+ drvinfo.cmd = ETHTOOL_GDRVINFO;
+ ifr->ifr_data = (caddr_t)&drvinfo;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err < 0) {
+ ERROR("ethstat - %s : Cannot get driver information", devname);
+ return 1;
+ }
+
+
+ n_stats = drvinfo.n_stats;
+ if (n_stats < 1) {
+ ERROR("ethstat - %s : No stats available", devname);
+ return 1;
+ }
+
+ sz_str = n_stats * ETH_GSTRING_LEN;
+ sz_stats = n_stats * sizeof(u64);
+
+ strings = calloc(1, sz_str + sizeof(struct ethtool_gstrings));
+ stats = calloc(1, sz_stats + sizeof(struct ethtool_stats));
+ if (!strings || !stats) {
+ ERROR("ethstat - %s No memory available", devname);
+ return 1;
+ }
+
+ strings->cmd = ETHTOOL_GSTRINGS;
+ strings->string_set = ETH_SS_STATS;
+ strings->len = n_stats;
+ ifr->ifr_data = (caddr_t) strings;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err < 0) {
+ ERROR("ethstat - %s : Cannot get stats strings information", devname);
+ free(strings);
+ free(stats);
+ return 96;
+ }
+
+ stats->cmd = ETHTOOL_GSTATS;
+ stats->n_stats = n_stats;
+ ifr->ifr_data = (caddr_t) stats;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err < 0) {
+ ERROR("ethstat - %s : Cannot get stats information", devname);
+ free(strings);
+ free(stats);
+ return 97;
+ }
+
+ for (i = 0; i < n_stats; i++) {
+ DEBUG("ethstat - %s : %s: %llu",
+ devname,
+ &strings->data[i * ETH_GSTRING_LEN],
+ stats->data[i]);
+ ethstat_submit_value (
+ devname,
+ (char*)&strings->data[i * ETH_GSTRING_LEN],
+ stats->data[i]);
+ }
+ free(strings);
+ free(stats);
+
+
+ return 0;
+}
+
+
+static int ethstat_read(void)
+{
+ struct ifreq ifr;
+ int i;
+
+ for (i = 0 ; i < ifacenumber ; i++) {
+ DEBUG("ethstat - Processing : %s\n", ifacelist[i]);
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, ifacelist[i]);
+ getstats(ifacelist[i], &ifr);
+ }
+ return 0;
+}
+
+void module_register (void)
+{
+ ifacelist = malloc(sizeof(char*));
+ plugin_register_config ("ethstat", ethstat_config,
+ config_keys, config_keys_num);
+ plugin_register_read ("ethstat", ethstat_read);
+}
+
+#endif
--- /dev/null
+/**
+ * collectd - src/ethstat.h
+ * Copyright (C) 2011 Cyril Feraudet
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Cyril Feraudet <cyril at feraudet.com>
+ **/
+
+#define ETHTOOL_BUSINFO_LEN 32
+#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
+#define ETH_GSTRING_LEN 32
+#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
+#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
+
+enum ethtool_stringset {
+ ETH_SS_TEST = 0,
+ ETH_SS_STATS,
+};
+
+typedef unsigned long long u64;
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+typedef unsigned long long __u64;
+
+
+static const char *config_keys[] =
+{
+ "Iface"
+};
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+static char **ifacelist;
+static int ifacenumber = 0;
+struct ethtool_drvinfo {
+ __u32 cmd;
+ char driver[32]; /* driver short name, "tulip", "eepro100" */
+ char version[32]; /* driver version string */
+ char fw_version[32]; /* firmware version string, if applicable */
+ char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
+ /* For PCI devices, use pci_name(pci_dev). */
+ char reserved1[32];
+ char reserved2[16];
+ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
+ __u32 testinfo_len;
+ __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
+ __u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
+};
+
+struct ethtool_gstrings {
+ __u32 cmd; /* ETHTOOL_GSTRINGS */
+ __u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
+ __u32 len; /* number of strings in the string set */
+ __u8 data[0];
+};
+
+struct ethtool_stats {
+ __u32 cmd; /* ETHTOOL_GSTATS */
+ __u32 n_stats; /* number of u64's being returned */
+ __u64 data[0];
+};
+
+
+