SnmpKit.SnmpLib.Manager (snmpkit v0.6.3)
High-level SNMP management operations providing a simplified interface for common SNMP tasks.
This module builds on the core SnmpLib functionality to provide production-ready SNMP management capabilities including GET, GETBULK, SET operations with intelligent error handling, connection reuse, and performance optimizations.
Features
- Simple API: High-level functions for common SNMP operations
- Connection Reuse: Efficient socket management for multiple operations
- Error Handling: Comprehensive error handling with meaningful messages
- Performance: Optimized for bulk operations and large-scale polling
- Timeout Management: Configurable timeouts with sensible defaults
- Community Support: Support for different community strings per device
Quick Start
# Simple GET operation
{:ok, {type, value}} = SnmpKit.SnmpLib.Manager.get("192.168.1.1", [1, 3, 6, 1, 2, 1, 1, 1, 0])
# GET with custom community and timeout
{:ok, {type, value}} = SnmpKit.SnmpLib.Manager.get("192.168.1.1", "1.3.6.1.2.1.1.1.0",
community: "private", timeout: 10_000)
# Bulk operations for efficiency
{:ok, results} = SnmpKit.SnmpLib.Manager.get_bulk("192.168.1.1", [1, 3, 6, 1, 2, 1, 2, 2],
max_repetitions: 20)
# SET operation
{:ok, :success} = SnmpKit.SnmpLib.Manager.set("192.168.1.1", [1, 3, 6, 1, 2, 1, 1, 5, 0],
{:string, "New System Name"})
Configuration Options
community
: SNMP community string (default: "public")version
: SNMP version (:v1, :v2c) (default: :v2c)timeout
: Operation timeout in milliseconds (default: 5000)retries
: Number of retry attempts (default: 3)port
: SNMP port (default: 161)local_port
: Local source port (default: 0 for random)
Summary
Functions
Performs an SNMP GET operation to retrieve a single value.
Performs an SNMP GETBULK operation for efficient bulk data retrieval.
Performs multiple GET operations efficiently with connection reuse.
Performs an SNMP GETNEXT operation to retrieve the next value in the MIB tree.
Interprets SNMP errors with enhanced semantics for common cases.
Checks if a host is reachable via SNMP by performing a basic GET operation.
Performs an SNMP SET operation to modify a value on the target device.
Types
@type bulk_opts() :: [ community: community(), version: version(), timeout: pos_integer(), retries: non_neg_integer(), port: pos_integer(), local_port: non_neg_integer(), max_repetitions: pos_integer(), non_repeaters: non_neg_integer() ]
@type community() :: binary()
@type host() :: binary() | :inet.ip_address()
@type manager_opts() :: [ community: community(), version: version(), timeout: pos_integer(), retries: non_neg_integer(), port: pos_integer(), local_port: non_neg_integer() ]
@type oid() :: [non_neg_integer()] | binary()
@type operation_result() :: {:ok, snmp_value()} | {:error, atom() | {atom(), any()}}
@type snmp_value() :: any()
@type varbind() :: {oid(), snmp_value()}
@type version() :: :v1 | :v2c
Functions
@spec get(host(), oid(), manager_opts()) :: {:ok, {atom(), any()}} | {:error, atom() | {:network_error, atom()} | {:socket_error, atom()}}
Performs an SNMP GET operation to retrieve a single value.
Parameters
host
: Target device IP address or hostnameoid
: Object identifier as list or string (e.g., [1,3,6,1,2,1,1,1,0] or "1.3.6.1.2.1.1.1.0")opts
: Configuration options (see module docs for available options)
Returns
{:ok, {type, value}}
: Successfully retrieved the value with its SNMP type{:error, reason}
: Operation failed with reason
Examples
# Basic GET operation (would succeed with real device)
# SnmpKit.SnmpLib.Manager.get("192.168.1.1", [1, 3, 6, 1, 2, 1, 1, 1, 0])
# {:ok, {:octet_string, "Cisco IOS Software"}}
# GET with custom community and timeout (would succeed with real device)
# SnmpKit.SnmpLib.Manager.get("192.168.1.1", "1.3.6.1.2.1.1.1.0", community: "private", timeout: 10_000)
# {:ok, {:octet_string, "Private System Description"}}
# Test that function exists and handles invalid input properly
iex> match?({:error, _}, SnmpKit.SnmpLib.Manager.get("invalid.host", [1, 3, 6, 1, 2, 1, 1, 3, 0], timeout: 100))
true
@spec get_bulk(host(), oid(), bulk_opts()) :: bulk_result()
Performs an SNMP GETBULK operation for efficient bulk data retrieval.
GETBULK is more efficient than multiple GET operations when retrieving multiple consecutive values, especially for table walking operations.
Parameters
host
: Target device IP address or hostnamebase_oid
: Base OID to start the bulk operationopts
: Configuration options including bulk-specific options
Bulk-Specific Options
max_repetitions
: Maximum number of repetitions (default: 10)non_repeaters
: Number of non-repeating variables (default: 0)
Returns
{:ok, varbinds}
: List of {oid, type, value} tuples{:error, reason}
: Operation failed with reason
Examples
# Test that get_bulk function exists and handles invalid input properly
iex> match?({:error, _}, SnmpKit.SnmpLib.Manager.get_bulk("invalid.host", [1, 3, 6, 1, 2, 1, 2, 2], timeout: 100))
true
# High-repetition bulk for large tables
# SnmpKit.SnmpLib.Manager.get_bulk("192.168.1.1", "1.3.6.1.2.1.2.2", max_repetitions: 50)
# {:ok, [...]} Returns up to 50 interface entries
@spec get_multi(host(), [oid()], manager_opts()) :: {:ok, [{oid(), atom(), any() | {:error, any()}}]} | {:error, any()}
Performs multiple GET operations efficiently with connection reuse.
More efficient than individual get/3 calls when retrieving multiple values from the same device by reusing the same socket connection.
Parameters
host
: Target device IP address or hostnameoids
: List of OIDs to retrieveopts
: Configuration options
Returns
{:ok, results}
: List of {oid, type, value} or {oid, {:error, reason}} tuples{:error, reason}
: Connection or overall operation failed
Examples
# Test that get_multi function exists and handles invalid input properly
iex> oids = ["1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.3.0", "1.3.6.1.2.1.1.5.0"]
iex> match?({:error, _}, SnmpKit.SnmpLib.Manager.get_multi("invalid.host", oids, timeout: 100))
true
@spec get_next(host(), oid(), manager_opts()) :: {:ok, {oid(), atom(), any()}} | {:error, atom() | {atom(), any()}}
Performs an SNMP GETNEXT operation to retrieve the next value in the MIB tree.
GETNEXT is used to traverse the MIB tree by retrieving the next available object after the specified OID. This is essential for MIB walking operations and discovering available objects on SNMP devices.
Parameters
host
: Target device IP address or hostnameoid
: Object identifier to get the next value afteropts
: Configuration options
Implementation Details
- SNMP v1: Uses proper GETNEXT PDU for compatibility
- SNMP v2c+: Uses optimized GETBULK with max_repetitions=1
Returns
{:ok, {next_oid, type, value}}
: Next OID and its value as a tuple{:error, reason}
: Operation failed with reason
Examples
# Get next OID after system description
{:ok, {next_oid, type, value}} = SnmpKit.SnmpLib.Manager.get_next("192.168.1.1", "1.3.6.1.2.1.1.1.0")
# SNMP v1 compatibility
{:ok, {next_oid, type, value}} = SnmpKit.SnmpLib.Manager.get_next("192.168.1.1", "1.3.6.1.2.1.1.1.0", version: :v1)
# With custom community
{:ok, {next_oid, type, value}} = SnmpKit.SnmpLib.Manager.get_next("192.168.1.1", "1.3.6.1.2.1.1.1.0",
community: "private", timeout: 10_000)
Interprets SNMP errors with enhanced semantics for common cases.
Provides more specific error interpretation when generic errors like :gen_err
are returned by devices that should return more specific SNMP error codes.
Parameters
error
: The original error returned by SNMP operationsoperation
: The SNMP operation type (:get
,:set
,:get_bulk
)version
: SNMP version (:v1
,:v2c
,:v3
)
Returns
More specific error atom when possible, otherwise the original error.
Examples
# Interpret genErr for GET operations
iex> SnmpKit.SnmpLib.Manager.interpret_error(:gen_err, :get, :v2c)
:no_such_object
iex> SnmpKit.SnmpLib.Manager.interpret_error(:gen_err, :get, :v1)
:no_such_name
iex> SnmpKit.SnmpLib.Manager.interpret_error(:too_big, :get, :v2c)
:too_big
@spec ping(host(), manager_opts()) :: {:ok, :reachable} | {:error, any()}
Checks if a host is reachable via SNMP by performing a basic GET operation.
Useful for device discovery and health checking. Attempts to retrieve sysUpTime (1.3.6.1.2.1.1.3.0) which should be available on all SNMP devices.
Parameters
host
: Target device IP address or hostnameopts
: Configuration options (typically just community and timeout)
Returns
{:ok, :reachable}
: Device responded to SNMP request{:error, reason}
: Device not reachable or SNMP not available
Examples
# Test that ping function exists and handles invalid input properly
iex> match?({:error, _}, SnmpKit.SnmpLib.Manager.ping("invalid.host", timeout: 100))
true
Performs an SNMP SET operation to modify a value on the target device.
Parameters
host
: Target device IP address or hostnameoid
: Object identifier to modifyvalue
: New value as {type, data} tuple (e.g., {:string, "new name"})opts
: Configuration options
Supported Value Types
{:string, binary()}
: OCTET STRING{:integer, integer()}
: INTEGER{:counter32, non_neg_integer()}
: Counter32{:gauge32, non_neg_integer()}
: Gauge32{:timeticks, non_neg_integer()}
: TimeTicks{:ip_address, binary()}
: IpAddress (4 bytes)
Returns
{:ok, :success}
: SET operation completed successfully{:error, reason}
: Operation failed with reason
Examples
# Test that SET function exists and handles invalid input properly
iex> match?({:error, _}, SnmpKit.SnmpLib.Manager.set("invalid.host", [1, 3, 6, 1, 2, 1, 1, 5, 0], {:string, "test"}, timeout: 100))
true