Improve Counter64 decoder to handle 16-byte values

Some SNMP implementations return 16-byte binaries for Counter64 values
instead of the standard 8 bytes. Updated decoder to:
- Handle 8-byte standard Counter64
- Handle 16-byte values by reading last 8 bytes
- Handle any size > 8 bytes by reading last 8 bytes
- Add debug/warning logging for non-standard sizes

This fixes DBConnection.EncodeError when polling interface statistics
from devices that return non-standard Counter64 encodings.
This commit is contained in:
Graham McIntire 2026-01-04 13:28:53 -06:00
parent 20f6a9171d
commit 38bd9828f7
No known key found for this signature in database

View file

@ -245,15 +245,32 @@ defmodule Towerops.Snmp.PollerWorker do
defp decode_snmp_value(value) when is_number(value), do: value
defp decode_snmp_value(value) when is_binary(value) do
# Try to decode as Counter64 (8 bytes, big-endian unsigned integer)
# Try to decode based on byte size
case byte_size(value) do
8 ->
# Standard Counter64 (8 bytes, big-endian unsigned integer)
<<counter::unsigned-big-integer-size(64)>> = value
counter
16 ->
# Some SNMP implementations return 16-byte values
# Try reading last 8 bytes as Counter64
<<_prefix::binary-size(8), counter::unsigned-big-integer-size(64)>> = value
counter
size when size > 8 ->
# Large binary, try reading last 8 bytes
offset = size - 8
<<_prefix::binary-size(offset), counter::unsigned-big-integer-size(64)>> = value
Logger.debug("Decoded #{size}-byte SNMP value as Counter64 from last 8 bytes: #{counter}")
counter
_ ->
# Unknown binary format, return nil
Logger.debug("Unknown SNMP binary value format, size: #{byte_size(value)}")
# Unknown binary format or too small
Logger.warning(
"Unknown SNMP binary value format, size: #{byte_size(value)}, bytes: #{inspect(value)}"
)
nil
end
end