SnmpKit.SnmpLib.Types (snmpkit v0.6.3)
SNMP data type validation, formatting, and coercion utilities.
Provides comprehensive support for all SNMP data types including validation, formatting for display, and type coercion between different representations. Includes full support for SNMPv2c exception values.
Supported SNMP Types
- Basic Types: INTEGER, OCTET STRING, NULL, OBJECT IDENTIFIER
- Application Types: Counter32, Gauge32, TimeTicks, Counter64, IpAddress, Opaque
- SNMPv2c Exception Types: NoSuchObject, NoSuchInstance, EndOfMibView
- Constructed Types: SEQUENCE (for complex structures)
SNMPv2c Exception Values
These special values are used in SNMPv2c responses to indicate specific conditions:
:no_such_object
(0x80): The requested object does not exist in the MIB:no_such_instance
(0x81): The object exists but the specific instance does not:end_of_mib_view
(0x82): End of MIB tree reached during GETBULK/walk operations
Features
- Type validation with detailed error reporting
- Human-readable formatting for logging and display
- Type coercion and normalization
- Range checking and constraint validation
- Performance-optimized operations
- RFC-compliant exception value handling
Examples
# Basic type validation
iex> SnmpKit.SnmpLib.Types.validate_counter32(42)
:ok
iex> SnmpKit.SnmpLib.Types.validate_counter32(-1)
{:error, :out_of_range}
# Formatting for display
iex> SnmpKit.SnmpLib.Types.format_timeticks_uptime(4200)
"42 seconds"
iex> SnmpKit.SnmpLib.Types.format_ip_address(<<192, 168, 1, 1>>)
"192.168.1.1"
# Type coercion
iex> SnmpKit.SnmpLib.Types.coerce_value(:counter32, 42)
{:ok, {:counter32, 42}}
iex> SnmpKit.SnmpLib.Types.coerce_value(:string, "test")
{:ok, {:string, "test"}}
# SNMPv2c exception values
iex> SnmpKit.SnmpLib.Types.coerce_value(:no_such_object, nil)
{:ok, {:no_such_object, nil}}
iex> SnmpKit.SnmpLib.Types.coerce_value(:end_of_mib_view, nil)
{:ok, {:end_of_mib_view, nil}}
Summary
Functions
Coerces a value to the specified SNMP type.
Decodes an SNMP typed value back to a native Elixir value.
Encodes a value with automatic type inference or explicit type specification.
Formats bytes as human-readable size.
Formats Counter64 value with appropriate units.
Formats binary data as hexadecimal string.
Formats an IP address from binary format.
Formats a rate value with units.
Formats TimeTicks as human-readable uptime string.
Automatically infers the SNMP type from an Elixir value.
Checks if a type is a binary SNMP type.
Checks if a type is an exception SNMP type.
Checks if a type is a numeric SNMP type.
Returns the maximum value for a numeric SNMP type.
Returns the minimum value for a numeric SNMP type.
Normalizes a type identifier to a consistent format.
Parses a hexadecimal string to binary.
Parses an IP address string into a 4-tuple of integers.
Truncates a string to a maximum length with ellipsis.
Validates a Counter32 value.
Validates a Counter64 value.
Validates a Gauge32 value.
Validates an SNMP integer value.
Validates an IP address value.
Validates an OCTET STRING value.
Validates an OBJECT IDENTIFIER value.
Validates an Opaque value.
Validates a TimeTicks value.
Validates an Unsigned32 value.
Types
@type snmp_type() ::
:integer
| :string
| :null
| :oid
| :counter32
| :gauge32
| :timeticks
| :counter64
| :ip_address
| :opaque
| :no_such_object
| :no_such_instance
| :end_of_mib_view
| :unsigned32
| :octet_string
| :object_identifier
| :boolean
@type snmp_value() :: integer() | binary() | :null | [non_neg_integer()] | {:counter32, non_neg_integer()} | {:gauge32, non_neg_integer()} | {:timeticks, non_neg_integer()} | {:counter64, non_neg_integer()} | {:ip_address, binary()} | {:opaque, binary()} | {:unsigned32, non_neg_integer()} | {:no_such_object, nil} | {:no_such_instance, nil} | {:end_of_mib_view, nil} | {:string, binary()} | {:octet_string, binary()} | {:object_identifier, [non_neg_integer()]} | {:boolean, boolean()}
Functions
@spec coerce_value(snmp_type(), term()) :: {:ok, snmp_value()} | {:error, atom()}
Coerces a value to the specified SNMP type.
Parameters
type
: Target SNMP typeraw_value
: Value to coerce
Returns
{:ok, typed_value}
on success{:error, reason}
on failure
Examples
{:ok, {:counter32, 42}} = SnmpKit.SnmpLib.Types.coerce_value(:counter32, 42)
{:ok, {:string, "test"}} = SnmpKit.SnmpLib.Types.coerce_value(:string, "test")
{:ok, {:ip_address, <<192, 168, 1, 1>>}} = SnmpKit.SnmpLib.Types.coerce_value(:ip_address, {192, 168, 1, 1})
Decodes an SNMP typed value back to a native Elixir value.
Converts SNMP-encoded values back to their most natural Elixir representation, with consistent handling of strings (always returns binaries, not charlists).
Parameters
typed_value
: A tuple of{type, value}
or just a value
Returns
The decoded Elixir value in its most natural form
Examples
"hello" = SnmpKit.SnmpLib.Types.decode_value({:string, "hello"})
"192.168.1.1" = SnmpKit.SnmpLib.Types.decode_value({:ip_address, {192, 168, 1, 1}})
42 = SnmpKit.SnmpLib.Types.decode_value({:counter32, 42})
[1, 3, 6, 1] = SnmpKit.SnmpLib.Types.decode_value({:object_identifier, [1, 3, 6, 1]})
Encodes a value with automatic type inference or explicit type specification.
This is the main entry point for encoding values into SNMP types. It supports both automatic type inference based on the value and explicit type specification.
Parameters
value
: The value to encodeopts
: Options including::type
- Explicit type specification (overrides inference):validate
- Whether to validate the encoded value (default: true)
Returns
{:ok, {type, encoded_value}}
on success{:error, reason}
on failure
Examples
# Automatic type inference
{:ok, {:string, "hello"}} = SnmpKit.SnmpLib.Types.encode_value("hello")
{:ok, {:integer, 42}} = SnmpKit.SnmpLib.Types.encode_value(42)
# Explicit type specification
{:ok, {:ip_address, {192, 168, 1, 1}}} = SnmpKit.SnmpLib.Types.encode_value("192.168.1.1", type: :ip_address)
{:ok, {:counter32, 100}} = SnmpKit.SnmpLib.Types.encode_value(100, type: :counter32)
@spec format_bytes(non_neg_integer()) :: binary()
Formats bytes as human-readable size.
Examples
"1.5 KB" = SnmpKit.SnmpLib.Types.format_bytes(1536)
"2.3 MB" = SnmpKit.SnmpLib.Types.format_bytes(2400000)
@spec format_counter64(non_neg_integer()) :: binary()
Formats Counter64 value with appropriate units.
Examples
"42" = SnmpKit.SnmpLib.Types.format_counter64(42)
"18,446,744,073,709,551,615" = SnmpKit.SnmpLib.Types.format_counter64(18446744073709551615)
Formats binary data as hexadecimal string.
Examples
"48656C6C6F" = SnmpKit.SnmpLib.Types.format_hex(<<"Hello">>)
"DEADBEEF" = SnmpKit.SnmpLib.Types.format_hex(<<0xDE, 0xAD, 0xBE, 0xEF>>)
Formats an IP address from binary format.
Examples
"192.168.1.1" = SnmpKit.SnmpLib.Types.format_ip_address(<<192, 168, 1, 1>>)
"0.0.0.0" = SnmpKit.SnmpLib.Types.format_ip_address(<<0, 0, 0, 0>>)
Formats a rate value with units.
Examples
"100 bps" = SnmpKit.SnmpLib.Types.format_rate(100, "bps")
"1.5 Mbps" = SnmpKit.SnmpLib.Types.format_rate(1500000, "bps")
@spec format_timeticks_uptime(non_neg_integer()) :: binary()
Formats TimeTicks as human-readable uptime string.
Parameters
centiseconds
: Time in centiseconds (hundredths of a second)
Returns
- Human-readable uptime string
Examples
"42 centiseconds" = SnmpKit.SnmpLib.Types.format_timeticks_uptime(42)
"1 second 50 centiseconds" = SnmpKit.SnmpLib.Types.format_timeticks_uptime(150)
"1 minute 30 seconds" = SnmpKit.SnmpLib.Types.format_timeticks_uptime(9000)
"2 hours 15 minutes 30 seconds" = SnmpKit.SnmpLib.Types.format_timeticks_uptime(81300)
Automatically infers the SNMP type from an Elixir value.
Uses intelligent heuristics to determine the most appropriate SNMP type for a given Elixir value.
Examples
:string = SnmpKit.SnmpLib.Types.infer_type("hello")
:integer = SnmpKit.SnmpLib.Types.infer_type(42)
:ip_address = SnmpKit.SnmpLib.Types.infer_type("192.168.1.1")
:object_identifier = SnmpKit.SnmpLib.Types.infer_type([1, 3, 6, 1, 2, 1])
:boolean = SnmpKit.SnmpLib.Types.infer_type(true)
Checks if a type is a binary SNMP type.
Examples
true = SnmpKit.SnmpLib.Types.is_binary_type?(:string)
true = SnmpKit.SnmpLib.Types.is_binary_type?(:opaque)
false = SnmpKit.SnmpLib.Types.is_binary_type?(:integer)
Checks if a type is an exception SNMP type.
Examples
true = SnmpKit.SnmpLib.Types.is_exception_type?(:no_such_object)
false = SnmpKit.SnmpLib.Types.is_exception_type?(:integer)
Checks if a type is a numeric SNMP type.
Examples
true = SnmpKit.SnmpLib.Types.is_numeric_type?(:counter32)
true = SnmpKit.SnmpLib.Types.is_numeric_type?(:integer)
false = SnmpKit.SnmpLib.Types.is_numeric_type?(:string)
@spec max_value(snmp_type()) :: non_neg_integer() | nil
Returns the maximum value for a numeric SNMP type.
Examples
4294967295 = SnmpKit.SnmpLib.Types.max_value(:counter32)
2147483647 = SnmpKit.SnmpLib.Types.max_value(:integer)
Returns the minimum value for a numeric SNMP type.
Examples
-2147483648 = SnmpKit.SnmpLib.Types.min_value(:integer)
0 = SnmpKit.SnmpLib.Types.min_value(:counter32)
Normalizes a type identifier to a consistent format.
Examples
:counter32 = SnmpKit.SnmpLib.Types.normalize_type("counter32")
:integer = SnmpKit.SnmpLib.Types.normalize_type(:integer)
:string = SnmpKit.SnmpLib.Types.normalize_type("octet_string")
Parses a hexadecimal string to binary.
Examples
{:ok, <<"Hello">>} = SnmpKit.SnmpLib.Types.parse_hex_string("48656C6C6F")
{:error, :invalid_hex} = SnmpKit.SnmpLib.Types.parse_hex_string("XYZ")
Parses an IP address string into a 4-tuple of integers.
Parameters
ip_string
: IP address as a string like "192.168.1.1"
Returns
{:ok, {a, b, c, d}}
on success{:error, reason}
on failure
Examples
{:ok, {192, 168, 1, 1}} = SnmpKit.SnmpLib.Types.parse_ip_address("192.168.1.1")
{:ok, {127, 0, 0, 1}} = SnmpKit.SnmpLib.Types.parse_ip_address("127.0.0.1")
{:error, :invalid_format} = SnmpKit.SnmpLib.Types.parse_ip_address("invalid")
@spec truncate_string(binary(), pos_integer()) :: binary()
Truncates a string to a maximum length with ellipsis.
Examples
"hello" = SnmpKit.SnmpLib.Types.truncate_string("hello", 10)
"hello..." = SnmpKit.SnmpLib.Types.truncate_string("hello world", 8)
Validates a Counter32 value.
Counter32 is a 32-bit unsigned integer that wraps around when it reaches its maximum value.
Parameters
value
: Value to validate
Returns
:ok
if valid{:error, reason}
if invalid
Examples
:ok = SnmpKit.SnmpLib.Types.validate_counter32(42)
:ok = SnmpKit.SnmpLib.Types.validate_counter32(4294967295)
{:error, :out_of_range} = SnmpKit.SnmpLib.Types.validate_counter32(-1)
{:error, :not_integer} = SnmpKit.SnmpLib.Types.validate_counter32("42")
Validates a Counter64 value.
Counter64 is a 64-bit unsigned integer for high-speed interfaces.
Validates a Gauge32 value.
Gauge32 is a 32-bit unsigned integer that represents a non-negative integer value. Unlike Counter32, it does not wrap around.
Validates an SNMP integer value.
SNMP INTEGER is a signed 32-bit integer.
Validates an IP address value.
IP address should be a 4-byte binary or a tuple of 4 integers.
Examples
:ok = SnmpKit.SnmpLib.Types.validate_ip_address(<<192, 168, 1, 1>>)
:ok = SnmpKit.SnmpLib.Types.validate_ip_address({192, 168, 1, 1})
{:error, :invalid_length} = SnmpKit.SnmpLib.Types.validate_ip_address(<<192, 168, 1>>)
Validates an OCTET STRING value.
OCTET STRING should be a binary with reasonable length limits.
Validates an OBJECT IDENTIFIER value.
OID should be a list of non-negative integers.
Validates an Opaque value.
Opaque is used for arbitrary binary data.
Validates a TimeTicks value.
TimeTicks represents time in hundredths of a second (centiseconds).
Validates an Unsigned32 value.
Unsigned32 is a 32-bit unsigned integer.