SnmpKit.SnmpLib.PDU (snmpkit v0.6.3)
SNMP PDU (Protocol Data Unit) encoding and decoding with RFC compliance.
Provides comprehensive SNMP PDU functionality combining the best features from multiple SNMP implementations. Supports SNMPv1 and SNMPv2c protocols with high-performance encoding/decoding, robust error handling, and full RFC compliance.
API Documentation
PDU Structure
All PDU functions in this library use a consistent map structure with these fields:
%{
type: :get_request | :get_next_request | :get_response | :set_request | :get_bulk_request,
request_id: non_neg_integer(),
error_status: 0..5,
error_index: non_neg_integer(),
varbinds: [varbind()],
# GETBULK only:
non_repeaters: non_neg_integer(), # Optional, GETBULK requests only
max_repetitions: non_neg_integer() # Optional, GETBULK requests only
}
IMPORTANT: Always use the :type
field (not :pdu_type
) with atom values.
Variable Bindings Format
Variable bindings (varbinds
) support two formats:
- 2-tuple format:
{oid, value}
- Used for responses and simple cases - 3-tuple format:
{oid, type, value}
- Used for requests with explicit type info
# Request varbinds (3-tuple with type information)
[{[1, 3, 6, 1, 2, 1, 1, 1, 0], :null, :null}]
# Response varbinds (2-tuple format)
[{[1, 3, 6, 1, 2, 1, 1, 1, 0], "Linux server"}]
# Response varbinds (3-tuple format also supported)
[{[1, 3, 6, 1, 2, 1, 1, 1, 0], :octet_string, "Linux server"}]
Message Structure
SNMP messages have this structure:
%{
version: 0 | 1, # 0 = SNMPv1, 1 = SNMPv2c
community: binary(), # Community string
pdu: pdu() # PDU map as described above
}
Examples
Building PDUs
# GET request for system description
pdu = SnmpKit.SnmpLib.PDU.build_get_request([1, 3, 6, 1, 2, 1, 1, 1, 0], 123)
# GETBULK request for interface table
pdu = SnmpKit.SnmpLib.PDU.build_get_bulk_request([1, 3, 6, 1, 2, 1, 2, 2, 1], 124, 0, 10)
# SET request
pdu = SnmpKit.SnmpLib.PDU.build_set_request([1, 3, 6, 1, 2, 1, 1, 5, 0], {:octet_string, "New Name"}, 125)
Building Messages
# Complete SNMP message
{:ok, message} = SnmpKit.SnmpLib.PDU.build_message(pdu, "public", :v2c)
# Encode to binary
{:ok, packet} = SnmpKit.SnmpLib.PDU.encode_message(message)
# Decode from binary
{:ok, decoded_message} = SnmpKit.SnmpLib.PDU.decode_message(packet)
Error Responses
# Create error response
error_pdu = SnmpKit.SnmpLib.PDU.create_error_response(original_pdu, :no_such_name, 1)
Summary
Functions
Builds a GETBULK request PDU (SNMPv2c only).
Builds a GETNEXT request PDU.
Builds a GET request PDU.
Builds a GET request PDU with multiple varbinds.
Builds an SNMP message with version, community, and PDU.
Builds a response PDU.
Builds a SET request PDU.
Creates an error response PDU.
Creates an error response PDU.
Alias for decode_message/1.
Decodes an SNMP message from binary format.
Legacy alias for decode/1.
Alias for encode_message/1.
Encodes an SNMP message to binary format.
Legacy alias for encode/1.
Converts an error status code to its atom representation.
Converts an error status atom to its numeric code.
Normalizes an OID to a list of integers.
Normalizes an SNMP type atom.
Validates a PDU structure.
Validates a community string.
Types
@type error_status() :: SnmpKit.SnmpLib.PDU.Constants.error_status()
@type message() :: SnmpKit.SnmpLib.PDU.Constants.message()
@type oid() :: SnmpKit.SnmpLib.PDU.Constants.oid()
@type pdu() :: SnmpKit.SnmpLib.PDU.Constants.pdu()
@type snmp_type() :: SnmpKit.SnmpLib.PDU.Constants.snmp_type()
@type snmp_value() :: SnmpKit.SnmpLib.PDU.Constants.snmp_value()
@type varbind() :: SnmpKit.SnmpLib.PDU.Constants.varbind()
Functions
@spec build_get_bulk_request( oid(), non_neg_integer(), non_neg_integer(), non_neg_integer() ) :: pdu()
Builds a GETBULK request PDU (SNMPv2c only).
Parameters
oid_list
: Single OID list or list of OID lists to requestrequest_id
: Unique request identifiernon_repeaters
: Number of non-repeating variables (default: 0)max_repetitions
: Maximum repetitions for repeating variables (default: 10)
Examples
iex> pdu = SnmpKit.SnmpLib.PDU.build_get_bulk_request([1, 3, 6, 1, 2, 1, 2, 2], 123, 0, 10)
iex> pdu.type
:get_bulk_request
@spec build_get_next_request(oid() | [oid()], non_neg_integer()) :: pdu()
Builds a GETNEXT request PDU.
Parameters
oid_or_oids
: Single OID list or list of OID lists to requestrequest_id
: Unique request identifier
Examples
iex> pdu = SnmpKit.SnmpLib.PDU.build_get_next_request([1, 3, 6, 1, 2, 1, 1], 123)
iex> pdu.type
:get_next_request
@spec build_get_request(oid(), non_neg_integer()) :: pdu()
Builds a GET request PDU.
Parameters
oid
: Single OID as list of integersrequest_id
: Unique request identifier
Examples
iex> pdu = SnmpKit.SnmpLib.PDU.build_get_request([1, 3, 6, 1, 2, 1, 1, 1, 0], 123)
iex> pdu.type
:get_request
@spec build_get_request_multi([varbind()], non_neg_integer()) :: pdu()
Builds a GET request PDU with multiple varbinds.
Parameters
varbinds
: List of variable bindings in format{oid, type, value}
request_id
: Unique request identifier
Examples
iex> varbinds = [{[1, 3, 6, 1, 2, 1, 1, 1, 0], :null, :null}]
iex> pdu = SnmpKit.SnmpLib.PDU.build_get_request_multi(varbinds, 123)
iex> pdu.type
:get_request
@spec build_message(pdu(), binary(), SnmpKit.SnmpLib.PDU.Constants.snmp_version()) :: message()
Builds an SNMP message with version, community, and PDU.
Parameters
pdu
: PDU structure to include in the messagecommunity
: Community string for authenticationversion
: SNMP version
Examples
iex> pdu = SnmpKit.SnmpLib.PDU.build_get_request([1, 3, 6, 1, 2, 1, 1, 1, 0], 123)
iex> message = SnmpKit.SnmpLib.PDU.build_message(pdu, "public", :v2c)
iex> message.version
1
@spec build_response(non_neg_integer(), error_status(), non_neg_integer(), [varbind()]) :: pdu()
Builds a response PDU.
Parameters
request_pdu
: Original request PDU to respond tovarbinds
: List of variable bindings for the responseerror_status
: Error status code (default: 0 for no error)error_index
: Error index (default: 0)
Examples
iex> varbinds = [{[1, 3, 6, 1, 2, 1, 1, 1, 0], :octet_string, "Linux server"}]
iex> pdu = SnmpKit.SnmpLib.PDU.build_response(123, 0, 0, varbinds)
iex> pdu.type
:get_response
@spec build_set_request(oid(), {atom(), any()}, non_neg_integer()) :: pdu()
Builds a SET request PDU.
Parameters
oid_list
: Single OID as list of integerstype_value
: Tuple of{type, value}
for the SET operationrequest_id
: Unique request identifier
Examples
iex> pdu = SnmpKit.SnmpLib.PDU.build_set_request([1, 3, 6, 1, 2, 1, 1, 5, 0], {:octet_string, "Test"}, 123)
iex> pdu.type
:set_request
@spec create_error_response(pdu(), error_status() | atom()) :: pdu()
Creates an error response PDU.
Parameters
request_pdu
: Original request PDUerror_status
: Error status atom or code
Examples
iex> request_pdu = %{type: :get_request, request_id: 123, error_status: 0, error_index: 0, varbinds: []}
iex> error_pdu = SnmpKit.SnmpLib.PDU.create_error_response(request_pdu, :no_such_name)
iex> error_pdu.error_status
2
@spec create_error_response(pdu(), error_status() | atom(), non_neg_integer()) :: pdu()
Creates an error response PDU.
Parameters
request_pdu
: Original request PDUerror_status
: Error status atom or codeerror_index
: Index of the variable that caused the error
Examples
iex> request_pdu = %{type: :get_request, request_id: 123, error_status: 0, error_index: 0, varbinds: []}
iex> error_pdu = SnmpKit.SnmpLib.PDU.create_error_response(request_pdu, :no_such_name, 1)
iex> error_pdu.error_status
2
Alias for decode_message/1.
Decodes an SNMP message from binary format.
Examples
iex> {:ok, binary} = SnmpKit.SnmpLib.PDU.encode_message(%{version: 1, community: "public", pdu: %{type: :get_request, request_id: 123, error_status: 0, error_index: 0, varbinds: []}})
iex> {:ok, _message} = SnmpKit.SnmpLib.PDU.decode_message(binary)
Legacy alias for decode/1.
Alias for encode_message/1.
Encodes an SNMP message to binary format.
Examples
iex> message = %{version: 1, community: "public", pdu: %{type: :get_request, request_id: 123, error_status: 0, error_index: 0, varbinds: []}}
iex> {:ok, _binary} = SnmpKit.SnmpLib.PDU.encode_message(message)
Legacy alias for encode/1.
@spec error_status_to_atom(non_neg_integer()) :: atom()
Converts an error status code to its atom representation.
Examples
iex> SnmpKit.SnmpLib.PDU.error_status_to_atom(2)
:no_such_name
@spec error_status_to_code(atom()) :: non_neg_integer()
Converts an error status atom to its numeric code.
Examples
iex> SnmpKit.SnmpLib.PDU.error_status_to_code(:no_such_name)
2
Normalizes an OID to a list of integers.
Examples
iex> SnmpKit.SnmpLib.PDU.normalize_oid([1, 3, 6, 1, 2, 1, 1, 1, 0])
[1, 3, 6, 1, 2, 1, 1, 1, 0]
Normalizes an SNMP type atom.
Examples
iex> SnmpKit.SnmpLib.PDU.normalize_type(:string)
:octet_string
Validates a PDU structure.
Examples
iex> pdu = %{type: :get_request, request_id: 123, error_status: 0, error_index: 0, varbinds: []}
iex> {:ok, ^pdu} = SnmpKit.SnmpLib.PDU.validate(pdu)
Validates a community string.
Parameters
encoded_message
: Encoded SNMP messageexpected_community
: Expected community string
Examples
iex> :ok = SnmpKit.SnmpLib.PDU.validate_community(encoded_msg, "public")