Skip to Content
ManagerTables

Tables

Efficiently query SNMP tables.

Overview

SNMP tables are indexed collections of rows. Each row has the same columns, indexed by one or more values. For example, ifTable is indexed by ifIndex:

ifDescr.1 = "lo" ifDescr.2 = "eth0" ifDescr.3 = "eth1" ifType.1 = softwareLoopback(24) ifType.2 = ethernetCsmacd(6) ifType.3 = ethernetCsmacd(6)

get_table

Retrieve an entire table as a structured dict:

from snmpkit.manager import Manager async with Manager("192.168.1.1") as mgr: # Walk ifTable entry OID table = await mgr.get_table("1.3.6.1.2.1.2.2.1") for index, columns in table.items(): print(f"Row {index}: {columns}")

Output:

{ (1,): {2: Value.OctetString(b"lo"), 3: Value.Integer(24), 8: Value.Integer(1)}, (2,): {2: Value.OctetString(b"eth0"), 3: Value.Integer(6), 8: Value.Integer(1)}, (3,): {2: Value.OctetString(b"eth1"), 3: Value.Integer(6), 8: Value.Integer(2)}, }

The return type is dict[tuple[int, ...], dict[int, Value]] where:

  • Keys are index tuples (e.g., (1,) for single-index, (192, 168, 1, 1) for IP-indexed tables)
  • Values are dicts mapping column number to Value

Column Filtering

Only retrieve specific columns:

# Only ifDescr (2) and ifOperStatus (8) table = await mgr.get_table( "1.3.6.1.2.1.2.2.1", columns=[2, 8], ) for index, cols in table.items(): name = str(cols.get(2, "")) status = str(cols.get(8, "")) print(f"Interface {index}: {name} - {'up' if status == '1' else 'down'}")

Bulk Size Tuning

Adjust bulk_size based on table width and network conditions:

# Large tables: bigger batches, fewer round-trips table = await mgr.get_table("1.3.6.1.2.1.2.2.1", bulk_size=50) # Slow devices: smaller batches table = await mgr.get_table("1.3.6.1.2.1.2.2.1", bulk_size=10)

Default bulk_size is 25. Most devices support 25-50. Some older devices may only support 10.

Manual Table Walk

For more control, walk columns individually:

Single Column

async with Manager("192.168.1.1") as mgr: async for oid, value in mgr.bulk_walk("1.3.6.1.2.1.2.2.1.2"): idx = oid.split(".")[-1] print(f"Interface {idx}: {value}")

Multiple Columns

async def get_interface_table(mgr: Manager) -> dict[str, dict]: table = {} base = "1.3.6.1.2.1.2.2.1" columns = { "ifDescr": "2", "ifType": "3", "ifOperStatus": "8", } for col_name, col_id in columns.items(): async for oid, value in mgr.bulk_walk(f"{base}.{col_id}"): idx = oid.split(".")[-1] if idx not in table: table[idx] = {} table[idx][col_name] = value return table

Compound Indices

Some tables have multi-part indices. get_table handles this automatically — the index tuple will have multiple elements:

IP Route Table

# ipRouteTable is indexed by destination IP (4 octets) table = await mgr.get_table("1.3.6.1.2.1.4.21.1") for index, cols in table.items(): # index is a tuple like (10, 0, 0, 0) dest = ".".join(str(i) for i in index) print(f"Route to {dest}")

TCP Connection Table

# tcpConnTable indexed by (localAddr x4, localPort, remoteAddr x4, remotePort) table = await mgr.get_table("1.3.6.1.2.1.6.13.1") for index, cols in table.items(): local_addr = ".".join(str(i) for i in index[:4]) local_port = index[4] remote_addr = ".".join(str(i) for i in index[5:9]) remote_port = index[9] print(f"{local_addr}:{local_port} -> {remote_addr}:{remote_port}")

Common Tables

IF-MIB::ifTable

IF_TABLE_ENTRY = "1.3.6.1.2.1.2.2.1" # Column numbers IF_INDEX = 1 IF_DESCR = 2 IF_TYPE = 3 IF_MTU = 4 IF_SPEED = 5 IF_PHYS_ADDRESS = 6 IF_ADMIN_STATUS = 7 IF_OPER_STATUS = 8 IF_IN_OCTETS = 10 IF_IN_ERRORS = 14 IF_OUT_OCTETS = 16 IF_OUT_ERRORS = 20

IF-MIB::ifXTable (64-bit counters)

IFX_TABLE_ENTRY = "1.3.6.1.2.1.31.1.1.1" IF_NAME = 1 IF_HC_IN_OCTETS = 6 IF_HC_OUT_OCTETS = 10 IF_HIGH_SPEED = 15 IF_ALIAS = 18

Example: Interface Report

import asyncio from snmpkit.manager import Manager async def main(): async with Manager("192.168.1.1") as mgr: table = await mgr.get_table( "1.3.6.1.2.1.2.2.1", columns=[2, 3, 5, 8, 10, 16], ) print(f"{'Name':<15} {'Status':<8} {'Speed':<12} {'In (MB)':<12} {'Out (MB)':<12}") print("-" * 60) for idx, row in sorted(table.items()): name = str(row.get(2, "")) status = "up" if str(row.get(8, "")) == "1" else "down" speed = int(str(row.get(5, "0"))) // 1_000_000 in_mb = int(str(row.get(10, "0"))) / 1024 / 1024 out_mb = int(str(row.get(16, "0"))) / 1024 / 1024 print(f"{name:<15} {status:<8} {speed:<12} {in_mb:<12.1f} {out_mb:<12.1f}") asyncio.run(main())

Next Steps

  • Operations — Full API reference
  • Traps — Trap and notification handling
Last updated on