SnmpKit.Agent.Table (snmpkit v2.0.1)

Serves a conceptual table from rows produced by a function.

Register it at the table's entry OID (ifEntry, not ifTable):

SnmpKit.Agent.register(agent, "ifEntry", SnmpKit.Agent.Table,
  columns: [{1, :integer}, {2, :octet_string}, {5, :gauge32}, {8, :integer}],
  index: [:integer],
  rows: fn ->
    for {port, i} <- Enum.with_index(MyApp.Ports.all(), 1) do
      {i, %{1 => i, 2 => port.name, 5 => port.speed, 8 => if(port.up?, do: 1, else: 2)}}
    end
  end
)

Options

  • :columns - the column numbers and their types, as a list of {column, type} or a map
  • :index - the INDEX objects' kinds, in order (default [:integer]): :integer, :string (length-prefixed), :implied_string, :ip_address, :oid, :implied_oid
  • :rows - a zero-arity function returning [{index, values}] where index is the index value (or a list of values, one per INDEX object) and values maps column numbers to values; a missing column is noSuchInstance
  • :set - optional fun(index, column, {type, value}) :: :ok | {:error, reason} making the table writable; the row must already exist

Cost

Rows are fetched once per request (every PDU, including each GETBULK of a walk), so one request sees a consistent snapshot. Within that request the first GET or SET encodes every row's index once (O(rows)) and each further lookup is a map lookup; the first GETNEXT encodes and sorts every cell once (O(cells log cells)) and each further step is a binary search. A walk therefore costs one rows call and one sort per PDU, not per object. Tables with tens of thousands of rows are still better served by a handler of their own that can seek directly.

Summary

Functions

Encodes index values as instance sub-identifiers (RFC 2578 section 7.7).

Types

index_kind()

@type index_kind() ::
  :integer | :string | :implied_string | :ip_address | :oid | :implied_oid

Functions

encode_index(values, kinds)

@spec encode_index(term() | [term()], [index_kind()]) :: [non_neg_integer()]

Encodes index values as instance sub-identifiers (RFC 2578 section 7.7).

iex> SnmpKit.Agent.Table.encode_index([{10, 0, 0, 1}, "eth0"], [:ip_address, :string])
[10, 0, 0, 1, 4, ?e, ?t, ?h, ?0]