Commit f9332f2d authored by Adam Wujek's avatar Adam Wujek 💬

userspace/snmpd: fix handling of 64bit objects

snmp_set_var_typed_value function does not epxect counter64 values as a
uint64_t, but as a struct counter64. Their binary representation differs by
order of 32bit words. By this it was wrongly seen as a endianess problem.
Since some status objects use 64bit values for calculations it is more
convenient to use uint64_t in our structures, then convert to struct counter64
just before passing data to the SNMP engine.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent 5ff8e63d
...@@ -56,13 +56,7 @@ time_t wrsCurrentTime_data_fill(void) ...@@ -56,13 +56,7 @@ time_t wrsCurrentTime_data_fill(void)
} while ((tmp1 != utch) || (tmp2 != utcl)); } while ((tmp1 != utch) || (tmp2 != utcl));
wrs_d_current_64 = (uint64_t)(utch) << 32 | utcl; wrs_d_current_64 = (uint64_t)(utch) << 32 | utcl;
/* wrsCurrentTime_s.wrsDateTAI = wrs_d_current_64;
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrsCurrentTime_s.wrsDateTAI =
(wrs_d_current_64 << 32) | (wrs_d_current_64 >> 32);
t = wrs_d_current_64; t = wrs_d_current_64;
localtime_r(&t, &tm); localtime_r(&t, &tm);
......
...@@ -8,6 +8,7 @@ static int group_handler(netsnmp_mib_handler *handler, ...@@ -8,6 +8,7 @@ static int group_handler(netsnmp_mib_handler *handler,
struct pickinfo *pi; struct pickinfo *pi;
void *ptr; void *ptr;
int len; int len;
struct counter64 tmp_counter64;
/* /*
* Retrieve information from ppsi itself. But this function * Retrieve information from ppsi itself. But this function
...@@ -31,6 +32,15 @@ static int group_handler(netsnmp_mib_handler *handler, ...@@ -31,6 +32,15 @@ static int group_handler(netsnmp_mib_handler *handler,
} }
pi = GT_PICKINFO + obj; pi = GT_PICKINFO + obj;
ptr = (void *)&GT_DATA_STRUCT + pi->offset; ptr = (void *)&GT_DATA_STRUCT + pi->offset;
/* snmp_set_var_typed_value function does not support counter64
* as a uint64_t, but as a struct counter64. Their binary
* representation differs by order of 32bit words. We fill
* struct counter64 according to its fields. */
if (pi->type == ASN_COUNTER64) {
tmp_counter64.high = (*(uint64_t *)ptr) >> 32;
tmp_counter64.low = *(uint64_t *)ptr;
ptr = &tmp_counter64;
}
len = pi->len; len = pi->len;
if (len > 8) /* special case for strings */ if (len > 8) /* special case for strings */
len = strnlen(ptr, len); len = strnlen(ptr, len);
......
...@@ -120,12 +120,7 @@ wrsPstatsHCTable_data_fill(unsigned int *n_rows) ...@@ -120,12 +120,7 @@ wrsPstatsHCTable_data_fill(unsigned int *n_rows)
for (i = 0; i < n_counters_in_fpga; i++) { for (i = 0; i < n_counters_in_fpga; i++) {
if (fscanf(f, "%" SCNu32, &tmp1) == 1 && if (fscanf(f, "%" SCNu32, &tmp1) == 1 &&
fscanf(f, "%" SCNu32, &tmp2) == 1) { fscanf(f, "%" SCNu32, &tmp2) == 1) {
/* counters[i] = (((uint64_t) tmp2) << 32) | tmp1;
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
counters[i] = (((uint64_t) tmp1) << 32) | tmp2;
} else { } else {
counters[i] = 0xffffffffffffffffLL; counters[i] = 0xffffffffffffffffLL;
} }
......
...@@ -88,16 +88,9 @@ time_t wrsPtpDataTable_data_fill(unsigned int *n_rows) ...@@ -88,16 +88,9 @@ time_t wrsPtpDataTable_data_fill(unsigned int *n_rows)
/* Keep value 0 for Not available */ /* Keep value 0 for Not available */
wrsPtpDataTable_array[0].wrsPtpPhaseTracking = wrsPtpDataTable_array[0].wrsPtpPhaseTracking =
1 + ppsi_servo->tracking_enabled; 1 + ppsi_servo->tracking_enabled;
/* wrsPtpDataTable_array[0].wrsPtpRTT = ppsi_servo->picos_mu;
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrsPtpDataTable_array[0].wrsPtpRTT = (ppsi_servo->picos_mu << 32)
| (ppsi_servo->picos_mu >> 32);
wrsPtpDataTable_array[0].wrsPtpClockOffsetPs = wrsPtpDataTable_array[0].wrsPtpClockOffsetPs =
(ppsi_servo->offset << 32) ppsi_servo->offset;
| (ppsi_servo->offset >> 32);
wrsPtpDataTable_array[0].wrsPtpClockOffsetPsHR = wrsPtpDataTable_array[0].wrsPtpClockOffsetPsHR =
int_saturate(ppsi_servo->offset); int_saturate(ppsi_servo->offset);
wrsPtpDataTable_array[0].wrsPtpSkew = wrsPtpDataTable_array[0].wrsPtpSkew =
......
...@@ -51,6 +51,7 @@ table_handler(netsnmp_mib_handler *handler, ...@@ -51,6 +51,7 @@ table_handler(netsnmp_mib_handler *handler,
int row, subid; int row, subid;
int len; int len;
void *ptr; void *ptr;
struct counter64 tmp_counter64;
switch (reqinfo->mode) { switch (reqinfo->mode) {
case MODE_GET: case MODE_GET:
...@@ -91,6 +92,15 @@ table_handler(netsnmp_mib_handler *handler, ...@@ -91,6 +92,15 @@ table_handler(netsnmp_mib_handler *handler,
pi = TT_PICKINFO + subid; pi = TT_PICKINFO + subid;
ptr = (void *)(TT_DATA_ARRAY + row) + pi->offset; ptr = (void *)(TT_DATA_ARRAY + row) + pi->offset;
/* snmp_set_var_typed_value function does not support counter64
* as a uint64_t, but as a struct counter64. Their binary
* representation differs by order of 32bit words. We fill
* struct counter64 according to its fields. */
if (pi->type == ASN_COUNTER64) {
tmp_counter64.high = (*(uint64_t *)ptr) >> 32;
tmp_counter64.low = *(uint64_t *)ptr;
ptr = &tmp_counter64;
}
len = pi->len; len = pi->len;
if (len > 8) /* special case for strings */ if (len > 8) /* special case for strings */
len = strnlen(ptr, len); len = strnlen(ptr, len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment