Add config option "Size" to ping plugin
authorWitold Baryluk <witold.baryluk@gmail.com>
Wed, 2 Dec 2015 00:43:00 +0000 (01:43 +0100)
committerWitold Baryluk <witold.baryluk@gmail.com>
Wed, 2 Dec 2015 00:43:00 +0000 (01:43 +0100)
src/collectd.conf.pod
src/ping.c

index d7d1501..46dbca4 100644 (file)
@@ -4957,6 +4957,13 @@ Default: B<0.9>
 
 Sets the Time-To-Live of generated ICMP packets.
 
+=item B<Size> I<size>
+
+Sets the size of the data payload in ICMP packet to specified I<size> (it
+will be filled with regular ASCII pattern). If not set, default 56 byte
+long string is used so that the packet size of an ICMPv4 packet is exactly
+64 bytes, similar to the behaviour of normal ping(1) command.
+
 =item B<SourceAddress> I<host>
 
 Sets the source address to use. I<host> may either be a numerical network
index df2f6da..7eb2293 100644 (file)
@@ -73,6 +73,7 @@ static char  *ping_source = NULL;
 #ifdef HAVE_OPING_1_3
 static char  *ping_device = NULL;
 #endif
+static char  *ping_data = NULL;
 static int    ping_ttl = PING_DEF_TTL;
 static double ping_interval = 1.0;
 static double ping_timeout = 0.9;
@@ -91,6 +92,7 @@ static const char *config_keys[] =
 #ifdef HAVE_OPING_1_3
   "Device",
 #endif
+  "Size",
   "TTL",
   "Interval",
   "Timeout",
@@ -280,6 +282,9 @@ static void *ping_thread (void *arg) /* {{{ */
   ping_setopt (pingobj, PING_OPT_TIMEOUT, (void *) &ping_timeout);
   ping_setopt (pingobj, PING_OPT_TTL, (void *) &ping_ttl);
 
+  if (ping_data != NULL)
+    ping_setopt (pingobj, PING_OPT_DATA, (void *) ping_data);
+
   /* Add all the hosts to the ping object. */
   count = 0;
   for (hl = hostlist_head; hl != NULL; hl = hl->next)
@@ -537,6 +542,44 @@ static int ping_config (const char *key, const char *value) /* {{{ */
       WARNING ("ping plugin: Ignoring invalid interval %g (%s)",
           tmp, value);
   }
+  else if (strcasecmp (key, "Size") == 0) {
+    int size;
+
+    if (ping_data != NULL)
+    {
+      free(ping_data);
+      ping_data = NULL;
+    }
+
+    size = atoi (value);
+    if ((size >= 1) && (size <= 65536))
+    {
+      int i;
+      ping_data = (char*) malloc(size + 1);
+      if (ping_data == NULL)
+      {
+        char errbuf[1024];
+        ERROR ("ping plugin: malloc failed: %s",
+            sstrerror (errno, errbuf, sizeof (errbuf)));
+        return (1);
+      }
+      /* Note: By default oping is using constant string
+       * "liboping -- ICMP ping library <http://octo.it/liboping/>"
+       * which is exactly 56 bytes.
+       *
+       * Optimally we would follow the ping(1) behaviour, but we
+       * cannot use byte 00 or start data payload at exactly same
+       * location, due to oping library limitations. */
+      for (i = 0; i < size; i++) /* {{{ */
+      {
+        /* This restricts data pattern to be only composed of easily
+         * printable characters, and not NUL character. */
+        ping_data[i] = ('0' + i % 64);
+      }  /* }}} for (i = 0; i < size; i++) */
+      ping_data[size] = '\0';
+    } else
+      WARNING ("ping plugin: Ignoring invalid Size %i.", size);
+  }
   else if (strcasecmp (key, "Timeout") == 0)
   {
     double tmp;
@@ -688,6 +731,11 @@ static int ping_shutdown (void) /* {{{ */
     hl = hl_next;
   }
 
+  if (ping_data != NULL) {
+    free (ping_data);
+    ping_data = NULL;
+  }
+
   return (0);
 } /* }}} int ping_shutdown */