Merge branch 'collectd-4.10' into collectd-5.0
[collectd.git] / src / snmp.c
index e78ade9..6ef3b94 100644 (file)
@@ -301,7 +301,7 @@ static int csnmp_config_add_data_shift (data_definition_t *dd, oconfig_item_t *c
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
   {
-    WARNING ("snmp plugin: The `Scale' config option needs exactly one number argument.");
+    WARNING ("snmp plugin: The `Shift' config option needs exactly one number argument.");
     return (-1);
   }
 
@@ -708,7 +708,9 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
   value_t ret;
   uint64_t tmp_unsigned = 0;
   int64_t tmp_signed = 0;
-  int defined = 1;
+  _Bool defined = 1;
+  /* Set to true when the original SNMP type appears to have been signed. */
+  _Bool prefer_signed = 0;
 
   if ((vl->type == ASN_INTEGER)
       || (vl->type == ASN_UINTEGER)
@@ -720,7 +722,12 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
   {
     tmp_unsigned = (uint32_t) *vl->val.integer;
     tmp_signed = (int32_t) *vl->val.integer;
-    DEBUG ("snmp plugin: Parsed int32 value is %"PRIi64".", tmp_signed);
+
+    if ((vl->type == ASN_INTEGER)
+        || (vl->type == ASN_GAUGE))
+      prefer_signed = 1;
+
+    DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
   }
   else if (vl->type == ASN_COUNTER64)
   {
@@ -809,14 +816,24 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
   }
   else if (type == DS_TYPE_GAUGE)
   {
-    ret.gauge = NAN;
-    if (defined != 0)
+    if (!defined)
+      ret.gauge = NAN;
+    else if (prefer_signed)
       ret.gauge = (scale * tmp_signed) + shift;
+    else
+      ret.gauge = (scale * tmp_unsigned) + shift;
   }
   else if (type == DS_TYPE_DERIVE)
-    ret.derive = (derive_t) tmp_signed;
+  {
+    if (prefer_signed)
+      ret.derive = (derive_t) tmp_signed;
+    else
+      ret.derive = (derive_t) tmp_unsigned;
+  }
   else if (type == DS_TYPE_ABSOLUTE)
+  {
     ret.absolute = (absolute_t) tmp_unsigned;
+  }
   else
   {
     ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source "
@@ -850,10 +867,12 @@ static int csnmp_check_res_left_subtree (const host_definition_t *host,
       vb = vb->next_variable, i++)
   {
     num_checked++;
-    if (snmp_oid_ncompare (data->values[i].oid,
-         data->values[i].oid_len,
-         vb->name, vb->name_length,
-         data->values[i].oid_len) != 0)
+
+    if ((vb->type == SNMP_ENDOFMIBVIEW)
+       || (snmp_oid_ncompare (data->values[i].oid,
+           data->values[i].oid_len,
+           vb->name, vb->name_length,
+           data->values[i].oid_len) != 0))
       num_left_subtree++;
   }
 
@@ -1057,7 +1076,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
   sstrncpy (vl.host, host->name, sizeof (vl.host));
   sstrncpy (vl.plugin, "snmp", sizeof (vl.plugin));
 
-  vl.interval = (int) CDTIME_T_TO_TIME_T (host->interval);
+  vl.interval = host->interval;
 
   subid = 0;
   have_more = 1;
@@ -1445,7 +1464,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
   sstrncpy (vl.type, data->type, sizeof (vl.type));
   sstrncpy (vl.type_instance, data->instance.string, sizeof (vl.type_instance));
 
-  vl.interval = (int) CDTIME_T_TO_TIME_T (host->interval);
+  vl.interval = host->interval;
 
   req = snmp_pdu_create (SNMP_MSG_GET);
   if (req == NULL)
@@ -1518,9 +1537,8 @@ static int csnmp_read_host (user_data_t *ud)
 
   host = ud->data;
 
-  /* FIXME: Convert "interval_g" to cdtime_t, too. */
   if (host->interval == 0)
-    host->interval = TIME_T_TO_CDTIME_T (interval_g);
+    host->interval = interval_g;
 
   time_start = cdtime ();