X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fsnmp.c;h=b68baf378f088d38ea69eecdde50a83a0bdd1854;hb=fda68e239798cea197a225ed5325f5bb3c2e70de;hp=54bcf67242170ea93c6cdc070a5a81a8196ed067;hpb=50c6b81549e3239034f71f00ff7dde4c6a8767e5;p=collectd.git diff --git a/src/snmp.c b/src/snmp.c index 54bcf672..b68baf37 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -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); } @@ -703,12 +703,15 @@ static void csnmp_host_open_session (host_definition_t *host) /* TODO: Check if negative values wrap around. Problem: negative temperatures. */ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, - double scale, double shift) + double scale, double shift, + const char *host_name, const char *data_name) { 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 +723,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) { @@ -748,8 +756,11 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, oid_buffer); else #endif - WARNING ("snmp plugin: I don't know the ASN type \"%i\" (OID: %s)", - (int) vl->type, oid_buffer); + WARNING ("snmp plugin: I don't know the ASN type #%i " + "(OID: \"%s\", data block \"%s\", host block \"%s\")", + (int) vl->type, oid_buffer, + (data_name != NULL) ? data_name : "UNKNOWN", + (host_name != NULL) ? host_name : "UNKNOWN"); defined = 0; } @@ -809,14 +820,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 +871,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++; } @@ -958,7 +981,8 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */ static int csnmp_instance_list_add (csnmp_list_instances_t **head, csnmp_list_instances_t **tail, - const struct snmp_pdu *res) + const struct snmp_pdu *res, + const host_definition_t *hd, const data_definition_t *dd) { csnmp_list_instances_t *il; struct variable_list *vb; @@ -998,7 +1022,8 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head, } else { - value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, 1.0, 0.0); + value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, + /* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name); ssnprintf (il->instance, sizeof (il->instance), "%llu", val.counter); } @@ -1286,7 +1311,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) /* Allocate a new `csnmp_list_instances_t', insert the instance name and * add it to the list */ if (csnmp_instance_list_add (&instance_list, &instance_list_ptr, - res) != 0) + res, host, data) != 0) { ERROR ("snmp plugin: csnmp_instance_list_add failed."); status = -1; @@ -1342,7 +1367,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) vt->subid = vb->name[vb->name_length - 1]; vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type, - data->scale, data->shift); + data->scale, data->shift, host->name, data->name); vt->next = NULL; if (value_table_ptr[i] == NULL) @@ -1492,8 +1517,8 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data) for (i = 0; i < data->values_len; i++) if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len, vb->name, vb->name_length) == 0) - vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type, - data->scale, data->shift); + vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type, + data->scale, data->shift, host->name, data->name); } /* for (res->variables) */ if (res != NULL)