diff --git a/doc/counter_ex.h b/doc/counter_ex.h
new file mode 100644
index 0000000000000000000000000000000000000000..65fabf3756dddc1b41b3bb16d143b3158854c20f
--- /dev/null
+++ b/doc/counter_ex.h
@@ -0,0 +1,26 @@
+/*
+ * Example of a basic counter: an accumulator
+**/
+
+unsigned int init_acc(char *, void **);
+unsigned int get_acc(uint64_t *results, void *);
+void clean_acc(void *);
+void label_acc(char **labels, void *);
+
+Sensor rapl = {
+    .init = init_acc,
+    .get = get_acc,
+    .clean = clean_acc,
+    .label = label_acc,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "accumulator",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,		/* OPTPARSE_NONE / OPTPARSE_OPTIONAL / OPTPARSE_REQUIRED */
+        .usage_arg = NULL,
+        .usage_msg = "dumb accumulator",
+    },
+};
diff --git a/doc/network.md b/doc/network.md
new file mode 100644
index 0000000000000000000000000000000000000000..b5d1e68304a72a35da213a74dfab918321663247
--- /dev/null
+++ b/doc/network.md
@@ -0,0 +1,8 @@
+This sensor can autodetect interfaces in use by giving the special
+interface name "X".  But the total number of interfaces it can autodetect
+is currently under a hard-limit.  This hard-limit can be changed by
+modifying this line in `src/network.c`:
+
+```c
+#define NB_MAX_DEV 8
+```
diff --git a/src/network.c b/src/network.c
index 37d237376be4c893e2c29de8d160b61ba3190628..a668725dcd51825c2245c34b7ae387cd7125b294 100644
--- a/src/network.c
+++ b/src/network.c
@@ -17,28 +17,40 @@
     along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
 
  *******************************************************/
-#include <unistd.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <stdint.h>
+#include <unistd.h>
+
 #include "util.h"
 
+#define NB_MAX_DEV 8
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
+char *_labels_network[NB_SENSOR] = {
+    "%s:rxp",
+    "%s:rxb",
+    "%s:txp",
+    "%s:txb",
+};
 struct Network {
-    uint64_t values[NB_SENSOR];
-    uint64_t tmp_values[NB_SENSOR];
-    int sources[NB_SENSOR];
+    uint64_t values[NB_MAX_DEV][NB_SENSOR];
+    uint64_t tmp_values[NB_MAX_DEV][NB_SENSOR];
+    int sources[NB_MAX_DEV][NB_SENSOR];
+    char labels[NB_MAX_DEV][NB_SENSOR][128];
+    char devs[NB_MAX_DEV][128];
+    int ndev;
 };
 typedef struct Network Network;
 
-unsigned int _get_network(uint64_t *results, int *sources)
+static void _get_network(uint64_t *results, int *sources)
 {
     if (sources == NULL) {
-        return 0;
+        return;
     }
 
     char buffer[128];
@@ -51,18 +63,51 @@ unsigned int _get_network(uint64_t *results, int *sources)
 
         results[i] = strtoull(buffer, NULL, 10);
     }
-
-    return NB_SENSOR;
 }
 
+/*
+ * read from fd len chars and store them into buf
+ * make *s points to the first occurence of c into buf
+*/
+static int strchr_refill(int fd, char *buf, int len, char **s, char c)
+{
+    *s = strchr(*s, c);
+
+    if (*s == NULL) {
+        int nbytes = read(fd, buf, len - 1);
+        if (nbytes < 0) {
+            perror("read");
+            return -1;
+        }
+        buf[len - 1] = '\0';
+
+        /* whole file read */
+        if (nbytes == 0) {
+            return 0;
+        }
 
+        *s = strchr(buf, c);
+    }
+
+    return 1;
+}
 
 unsigned int init_network(char *dev, void **ptr)
 {
     if (dev == NULL) {
-        return 0;
+        exit(1);
     }
 
+    char *filenames[] = {
+        "/sys/class/net/%s/statistics/rx_packets",
+        "/sys/class/net/%s/statistics/rx_bytes",
+        "/sys/class/net/%s/statistics/tx_packets",
+        "/sys/class/net/%s/statistics/tx_bytes",
+    };
+
+    struct Network *state = malloc(sizeof(struct Network));
+    memset(state, '\0', sizeof(*state));
+
     if (strcmp(dev, "X") == 0) {
         int fd = open(route, O_RDONLY);
 
@@ -74,50 +119,110 @@ unsigned int init_network(char *dev, void **ptr)
 
         char buffer[1000];
 
-        if (read(fd, buffer, 999) < 0 ) {
-            perror("read");
+        /* skip first line */
+        char *s = buffer;
+        int ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
+        if (ret != 1) {
             close(fd);
+            free(state);
             exit(1);
         }
+        s++;
 
-        char *start_of_dev = index(buffer, '\n') + 1;
-        char *end_of_dev = index(start_of_dev, '\t');
-        *end_of_dev = '\0';
-        dev = start_of_dev;
-        close(fd);
-    }
+        char *start_of_dev = s;
+        /* jump to the end of the device name */
+        ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
+        if (ret != 1) {
+            close(fd);
+            free(state);
+            exit(1);
+        }
 
-    char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
-                         "/sys/class/net/%s/statistics/rx_bytes",
-                         "/sys/class/net/%s/statistics/tx_packets",
-                         "/sys/class/net/%s/statistics/tx_bytes"
-                        };
+        state->ndev++;	// ndev should be equal to 1 at this point
+        memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
+               MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
+
+        for (;;) {
+            /* jump to the next line */
+            ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
+            if (ret != 1) {
+                break;
+            }
+            s++;
+
+            start_of_dev = s;
+            ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
+            if (ret != 1) {
+                break;
+            }
+
+            /* compare dev name to the previously saved one */
+            int newdev = 1;
+            for (int i = 0; i < state->ndev && newdev; i++) {
+	            if (strncmp(start_of_dev, state->devs[i], s - start_of_dev) == 0) {
+	            	newdev = 0;
+	            }
+            }
+            if (newdev) {
+                if (state->ndev >= NB_MAX_DEV) {
+                    fprintf(stderr, "Maximum amount of network devices exceeded (%d).\n", NB_MAX_DEV);
+                    break;
+                }
+                state->ndev++;
+                memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
+                       MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
+            }
+        }
 
-    Network *state = malloc(sizeof(Network));
+        close(fd);
+    } else {
+        state->ndev = 1;
+        memcpy(&(state->devs[0]), dev, strlen(dev) + 1);
+    }
 
     char buffer2[256];
-    for (int i = 0; i < NB_SENSOR; i++) {
-        snprintf(buffer2, 256, filenames[i], dev);
-        state->sources[i] = open(buffer2, O_RDONLY);
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            snprintf(buffer2, sizeof(buffer2), filenames[j], state->devs[i]);
+            errno = 0;
+            int fd = open(buffer2, O_RDONLY);
+            if (fd < 0) {
+                fprintf(stderr, "init_network: open: %s: %.*s\n", strerror(errno),
+                        (int)sizeof(buffer2), buffer2);
+                free(state);
+                exit(1);
+            }
+            state->sources[i][j] = fd;
+            snprintf(state->labels[i][j], sizeof(state->labels[i][j]), _labels_network[j],
+                     state->devs[i]);
+        }
     }
 
     *ptr = (void *) state;
-    _get_network(state->values, state->sources);
 
-    return NB_SENSOR;
+    for (int i = 0; i < state->ndev; i++) {
+        _get_network(state->values[i], state->sources[i]);
+    }
+
+    return state->ndev * NB_SENSOR;
 }
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
-    Network *state = (Network *) ptr;
-    _get_network(state->tmp_values, state->sources);
+    struct Network *state = (struct Network *) ptr;
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
+    for (int i = 0; i < state->ndev; i++) {
+        _get_network(state->tmp_values[i], state->sources[i]);
+
+        for (int j = 0; j < NB_SENSOR; j++) {
+            results[i*NB_SENSOR + j] = modulo_substraction(state->tmp_values[i][j], state->values[i][j]);
+        }
+
+        memcpy(&(state->values[i]), &(state->tmp_values[i]),
+               NB_SENSOR * sizeof(state->values[i][0]));
     }
 
-    memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
-    return NB_SENSOR;
+    return state->ndev * NB_SENSOR;
 }
 
 void clean_network(void *ptr)
@@ -128,19 +233,22 @@ void clean_network(void *ptr)
         return;
     }
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        close(state->sources[i]);
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            close(state->sources[i][j]);
+        }
     }
 
     free(state);
 }
 
-char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
-void label_network(char **labels, void *none)
+void label_network(char **labels, void *ptr)
 {
-    UNUSED(none);
+    struct Network *state = (struct Network *) ptr;
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        labels[i] = _labels_network[i];
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            labels[i*NB_SENSOR + j] = state->labels[i][j];
+        }
     }
 }
diff --git a/src/util.h b/src/util.h
index e422d070693cd28af9613e77a5efdb917ce6b2f6..0015a9867452800633582cdbd9736ab5c11c145e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -38,6 +38,8 @@
         exit(code);                          \
     } while (0)
 
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
 
 /**
  * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs,