X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fsnmp.c;h=995f39deff913ee77a9cf807f12d323635236a85;hb=d1d4d11a8d29f17dff15b039da6cacfd5db1a581;hp=d19493df9a53d5e4aefee9190cdc36cc6396afb3;hpb=10075e6fe3c384b73c2dd398a1435f8d10e56654;p=collectd.git diff --git a/src/snmp.c b/src/snmp.c index d19493df..995f39de 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -692,6 +692,7 @@ static void csnmp_host_open_session (host_definition_t *host) } } /* void csnmp_host_open_session */ +/* 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) { @@ -708,14 +709,18 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, || (vl->type == ASN_GAUGE)) { temp = (uint32_t) *vl->val.integer; - DEBUG ("snmp plugin: Parsed int32 value is %llu.", temp); + DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", temp); } else if (vl->type == ASN_COUNTER64) { temp = (uint32_t) vl->val.counter64->high; temp = temp << 32; temp += (uint32_t) vl->val.counter64->low; - DEBUG ("snmp plugin: Parsed int64 value is %llu.", temp); + DEBUG ("snmp plugin: Parsed int64 value is %"PRIu64".", temp); + } + else if (vl->type == ASN_OCTET_STR) + { + /* We'll handle this later.. */ } else { @@ -723,7 +728,51 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, defined = 0; } - if (type == DS_TYPE_COUNTER) + if (vl->type == ASN_OCTET_STR) + { + char *endptr; + + endptr = NULL; + if (vl->val.string != NULL) + { + char string[64]; + size_t string_length; + + string_length = sizeof (string) - 1; + if (vl->val_len < string_length) + string_length = vl->val_len; + + /* The strings we get from the Net-SNMP library may not be null + * terminated. That is why we're using `membpy' here and not `strcpy'. + * `string_length' is set to `vl->val_len' which holds the length of the + * string. -octo */ + memcpy (string, vl->val.string, string_length); + string[string_length] = 0; + + if (type == DS_TYPE_COUNTER) + { + ret.counter = (counter_t) strtoll (string, &endptr, /* base = */ 0); + DEBUG ("snmp plugin: csnmp_value_list_to_value: String to counter: %s -> %llu", + string, (unsigned long long) ret.counter); + } + else if (type == DS_TYPE_GAUGE) + { + ret.gauge = (gauge_t) strtod (string, &endptr); + DEBUG ("snmp plugin: csnmp_value_list_to_value: String to gauge: %s -> %g", + string, (double) ret.gauge); + } + } + + /* Check if an error occurred */ + if ((vl->val.string == NULL) || (endptr == (char *) vl->val.string)) + { + if (type == DS_TYPE_COUNTER) + ret.counter = 0; + else if (type == DS_TYPE_GAUGE) + ret.gauge = NAN; + } + } + else if (type == DS_TYPE_COUNTER) { ret.counter = temp; } @@ -830,6 +879,7 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head, char *ptr; size_t instance_len; + memset (il->instance, 0, sizeof (il->instance)); instance_len = sizeof (il->instance) - 1; if (instance_len > vb->val_len) instance_len = vb->val_len; @@ -837,7 +887,7 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head, sstrncpy (il->instance, (char *) ((vb->type == ASN_OCTET_STR) ? vb->val.string : vb->val.bitstring), - instance_len); + instance_len + 1); for (ptr = il->instance; *ptr != '\0'; ptr++) { @@ -1116,10 +1166,6 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) vb = res->variables; if (vb == NULL) { - if (res != NULL) - snmp_free_pdu (res); - res = NULL; - status = -1; break; } @@ -1128,10 +1174,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) * subtree */ if (csnmp_check_res_left_subtree (host, data, res) != 0) { - if (res != NULL) - snmp_free_pdu (res); - res = NULL; - + status = 0; break; } @@ -1153,11 +1196,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) (vb != NULL) && (vb->next_variable != NULL); vb = vb->next_variable) /* do nothing */; - if (vb == NULL) - { - status = -1; - break; - } + assert (vb != NULL); /* Copy OID to oid_list[data->values_len] */ memcpy (oid_list[data->values_len].oid, vb->name, @@ -1220,6 +1259,10 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) res = NULL; } /* while (status == 0) */ + if (res != NULL) + snmp_free_pdu (res); + res = NULL; + if (status == 0) csnmp_dispatch_table (host, data, instance_list, value_table); @@ -1395,8 +1438,8 @@ static int csnmp_read_host (host_definition_t *host) if ((time_end - time_start) > host->interval) { WARNING ("snmp plugin: Host `%s' should be queried every %i seconds, " - "but reading all values takes %lu seconds.", - host->name, host->interval, (unsigned long)(time_end - time_start)); + "but reading all values takes %u seconds.", + host->name, host->interval, (unsigned int) (time_end - time_start)); } return (0);