Search documentation of snmpkit

# SnmpKit.SnmpLib.OID (snmpkit v1.2.0)

Comprehensive OID (Object Identifier) manipulation utilities for SNMP operations.

Provides string/list conversions, tree operations, table utilities, and validation functions needed by both SNMP managers and simulators.

## Features

- String/list format conversions with validation
- Support for both OID formats: "1.3.6.1.2.1.1" and ".1.3.6.1.2.1.1"
- OID tree operations (parent/child relationships)
- SNMP table index parsing and construction
- OID comparison and sorting
- Enterprise OID utilities
- Performance-optimized operations

## OID Format Support

SnmpKit supports both common OID string formats:

- Traditional format: "1.3.6.1.2.1.1.1.0" (Elixir/Erlang style)
- Standard format: ".1.3.6.1.2.1.1.1.0" (RFC standard with leading dot)

Both formats parse to identical internal representations and can be used interchangeably throughout the library.

## Examples

    # Basic conversions - both formats supported
    {:ok, oid_list} = SnmpKit.SnmpLib.OID.string_to_list("1.3.6.1.2.1.1.1.0")
    {:ok, same_list} = SnmpKit.SnmpLib.OID.string_to_list(".1.3.6.1.2.1.1.1.0")
    {:ok, oid_string} = SnmpKit.SnmpLib.OID.list_to_string([1, 3, 6, 1, 2, 1, 1, 1, 0])

    # Tree operations
    true = SnmpKit.SnmpLib.OID.is_child_of?([1, 3, 6, 1, 2, 1, 1, 1, 0], [1, 3, 6, 1, 2, 1])
    {:ok, parent} = SnmpKit.SnmpLib.OID.get_parent([1, 3, 6, 1, 2, 1, 1, 1, 0])

    # Comparison
    :lt = SnmpKit.SnmpLib.OID.compare([1, 3, 6, 1], [1, 3, 6, 2])

    # Table operations
    {:ok, index} = SnmpKit.SnmpLib.OID.extract_table_index([1, 3, 6, 1, 2, 1, 2, 2, 1, 1], [1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1])

# Summary

## Types

index()
oid()
oid_string()
table_oid()

## Functions

build_table_index(values, syntax_list)

Builds a table index from parsed components according to syntax.

build_table_instance(table_oid, index)

Builds a table instance OID from table OID and index.

compare(oid1, oid2)

Compares two OIDs lexicographically.

enterprises()
experimental()
extract_table_index(table_oid, instance_oid)

Extracts table index from an instance OID given the table column OID.

get_children(parent_oid, oid_set)

Gets the immediate children prefix for an OID in a given set.

get_enterprise_number(oid)

Gets the enterprise number from an enterprise OID.

get_next_oid(current_oid, oid_set)

Gets the next OID in lexicographic order from a given set.

get_parent(oid)

Gets the parent OID by removing the last component.

is_child_of?(child_oid, parent_oid)

Checks if one OID is a child of another.

is_enterprise?(oid)
is_experimental?(oid)
is_mib_2?(oid)

Checks if an OID is under a specific standard tree.

is_parent_of?(parent_oid, child_oid)

Checks if one OID is a parent of another.

is_private?(oid)
list_to_string(oid_list)

Converts an OID list to a dot-separated string.

mib_2()

Returns standard SNMP OID prefixes.

normalize(oid)

Normalizes an OID to a consistent format.

parse_table_index(index, syntax_list)

Parses a table index according to index syntax definition.

private()
sort(oid_list)

Sorts a list of OIDs in lexicographic order.

standard_prefix(arg1)

Get standard SNMP OID prefixes.

string_to_list(oid_string)

Converts an OID string to a list of integers.

valid_oid?(oid)

Validates an OID list for correctness.

# Types

# index()

    @type index() :: [non_neg_integer()]

# oid()

    @type oid() :: [non_neg_integer()]

# oid_string()

    @type oid_string() :: String.t()

# table_oid()

    @type table_oid() :: oid()

# Functions

# build_table_index(values, syntax_list)

    @spec build_table_index(term(), term()) :: {:ok, index()} | {:error, atom()}

Builds a table index from parsed components according to syntax.

## Examples

    {:ok, [42]} = SnmpKit.SnmpLib.OID.build_table_index(42, :integer)
    {:ok, [4, 116, 101, 115, 116]} = SnmpKit.SnmpLib.OID.build_table_index("test", {:variable_string})

# build_table_instance(table_oid, index)

    @spec build_table_instance(table_oid(), index()) :: {:ok, oid()} | {:error, atom()}

Builds a table instance OID from table OID and index.

## Parameters

- `table_oid`: Base table column OID
- `index`: Table index as list of integers

## Returns

- `{:ok, instance_oid}` if successful
- `{:error, reason}` if construction fails

## Examples

    table_oid = [1, 3, 6, 1, 2, 1, 2, 2, 1, 1]
    index = [1]
    {:ok, [1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1]} = SnmpKit.SnmpLib.OID.build_table_instance(table_oid, index)

# compare(oid1, oid2)

    @spec compare(oid(), oid()) :: :lt | :eq | :gt

Compares two OIDs lexicographically.

## Returns

- `:lt` if oid1 < oid2
- `:eq` if oid1 == oid2
- `:gt` if oid1 > oid2

## Examples

    :lt = SnmpKit.SnmpLib.OID.compare([1, 3, 6, 1], [1, 3, 6, 2])
    :eq = SnmpKit.SnmpLib.OID.compare([1, 3, 6, 1], [1, 3, 6, 1])
    :gt = SnmpKit.SnmpLib.OID.compare([1, 3, 6, 2], [1, 3, 6, 1])

# enterprises()

    @spec enterprises() :: oid()

# experimental()

    @spec experimental() :: oid()

# extract_table_index(table_oid, instance_oid)

    @spec extract_table_index(table_oid(), oid()) :: {:ok, index()} | {:error, atom()}

Extracts table index from an instance OID given the table column OID.

## Parameters

- `table_oid`: Base table column OID
- `instance_oid`: Full instance OID including index

## Returns

- `{:ok, index}` if successful
- `{:error, reason}` if extraction fails

## Examples

    table_oid = [1, 3, 6, 1, 2, 1, 2, 2, 1, 1]
    instance_oid = [1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 1]
    {:ok, [1]} = SnmpKit.SnmpLib.OID.extract_table_index(table_oid, instance_oid)

# get_children(parent_oid, oid_set)

    @spec get_children(oid(), [oid()]) :: [oid()]

Gets the immediate children prefix for an OID in a given set.

## Parameters

- `parent_oid`: The parent OID
- `oid_set`: Set of OIDs to search

## Returns

- List of immediate child OIDs

## Examples

    children = SnmpKit.SnmpLib.OID.get_children([1, 3, 6, 1], [[1, 3, 6, 1, 2], [1, 3, 6, 1, 4], [1, 3, 6, 1, 2, 1]])
    # Returns [[1, 3, 6, 1, 2], [1, 3, 6, 1, 4]]

# get_enterprise_number(oid)

    @spec get_enterprise_number(oid()) :: {:ok, non_neg_integer()} | {:error, atom()}

Gets the enterprise number from an enterprise OID.

## Examples

    {:ok, 9} = SnmpKit.SnmpLib.OID.get_enterprise_number([1, 3, 6, 1, 4, 1, 9, 1, 1])
    {:error, :not_enterprise_oid} = SnmpKit.SnmpLib.OID.get_enterprise_number([1, 3, 6, 1, 2, 1])

# get_next_oid(current_oid, oid_set)

    @spec get_next_oid(oid(), [oid()]) :: {:ok, oid()} | {:error, atom()}

Gets the next OID in lexicographic order from a given set.

## Parameters

- `current_oid`: The current OID
- `oid_set`: Set of OIDs to search (must be sorted)

## Returns

- `{:ok, next_oid}` if found
- `{:error, :end_of_mib}` if no next OID exists

## Examples

    oid_set = [[1, 3, 6, 1, 2, 1, 1, 1, 0], [1, 3, 6, 1, 2, 1, 1, 2, 0], [1, 3, 6, 1, 2, 1, 1, 3, 0]]
    {:ok, [1, 3, 6, 1, 2, 1, 1, 2, 0]} = SnmpKit.SnmpLib.OID.get_next_oid([1, 3, 6, 1, 2, 1, 1, 1, 0], oid_set)

# get_parent(oid)

    @spec get_parent(oid()) :: {:ok, oid()} | {:error, atom()}

Gets the parent OID by removing the last component.

## Examples

    {:ok, [1, 3, 6, 1, 2, 1, 1, 1]} = SnmpKit.SnmpLib.OID.get_parent([1, 3, 6, 1, 2, 1, 1, 1, 0])
    {:error, :root_oid} = SnmpKit.SnmpLib.OID.get_parent([])
    {:error, :root_oid} = SnmpKit.SnmpLib.OID.get_parent([1])

# is_child_of?(child_oid, parent_oid)

    @spec is_child_of?(oid(), oid()) :: boolean()

Checks if one OID is a child of another.

## Parameters

- `child_oid`: Potential child OID
- `parent_oid`: Potential parent OID

## Returns

- `true` if child_oid is a child of parent_oid
- `false` otherwise

## Examples

    true = SnmpKit.SnmpLib.OID.is_child_of?([1, 3, 6, 1, 2, 1, 1, 1, 0], [1, 3, 6, 1, 2, 1])
    false = SnmpKit.SnmpLib.OID.is_child_of?([1, 3, 6, 1], [1, 3, 6, 1, 2, 1])
    false = SnmpKit.SnmpLib.OID.is_child_of?([1, 3, 6, 2], [1, 3, 6, 1])

# is_enterprise?(oid)

    @spec is_enterprise?(oid()) :: boolean()

# is_experimental?(oid)

    @spec is_experimental?(oid()) :: boolean()

# is_mib_2?(oid)

    @spec is_mib_2?(oid()) :: boolean()

Checks if an OID is under a specific standard tree.

## Examples

    true = SnmpKit.SnmpLib.OID.is_mib_2?([1, 3, 6, 1, 2, 1, 1, 1, 0])
    true = SnmpKit.SnmpLib.OID.is_enterprise?([1, 3, 6, 1, 4, 1, 9, 1, 1])

# is_parent_of?(parent_oid, child_oid)

    @spec is_parent_of?(oid(), oid()) :: boolean()

Checks if one OID is a parent of another.

# is_private?(oid)

    @spec is_private?(oid()) :: boolean()

# list_to_string(oid_list)

    @spec list_to_string(oid()) :: {:ok, oid_string()} | {:error, atom()}

Converts an OID list to a dot-separated string.

## Parameters

- `oid_list`: List of non-negative integers

## Returns

- `{:ok, oid_string}` on success
- `{:error, reason}` on failure

## Examples

    {:ok, "1.3.6.1.2.1.1.1.0"} = SnmpKit.SnmpLib.OID.list_to_string([1, 3, 6, 1, 2, 1, 1, 1, 0])
    {:error, :invalid_oid_list} = SnmpKit.SnmpLib.OID.list_to_string([1, 3, -1, 4])
    {:error, :empty_oid} = SnmpKit.SnmpLib.OID.list_to_string([])

# mib_2()

    @spec mib_2() :: oid()

Returns standard SNMP OID prefixes.

# normalize(oid)

    @spec normalize(oid() | oid_string()) :: {:ok, oid()} | {:error, atom()}

Normalizes an OID to a consistent format.

Accepts either string or list format and returns a list.

## Examples

    {:ok, [1, 3, 6, 1]} = SnmpKit.SnmpLib.OID.normalize("1.3.6.1")
    {:ok, [1, 3, 6, 1]} = SnmpKit.SnmpLib.OID.normalize([1, 3, 6, 1])

# parse_table_index(index, syntax_list)

    @spec parse_table_index(index(), term()) :: {:ok, term()} | {:error, atom()}

Parses a table index according to index syntax definition.

## Parameters

- `index`: Raw index from OID
- `syntax`: Index syntax specification

## Returns

- `{:ok, parsed_index}` if successful
- `{:error, reason}` if parsing fails

## Index Syntax Examples

- `:integer` - Single integer index
- `{:string, length}` - Fixed-length string
- `{:variable_string}` - Length-prefixed string
- `[:integer, :integer]` - Multiple integer indices

## Examples

    {:ok, 42} = SnmpKit.SnmpLib.OID.parse_table_index([42], :integer)
    {:ok, "test"} = SnmpKit.SnmpLib.OID.parse_table_index([4, 116, 101, 115, 116], {:variable_string})

# private()

    @spec private() :: oid()

# sort(oid_list)

    @spec sort([oid()]) :: [oid()]

Sorts a list of OIDs in lexicographic order.

## Examples

    sorted = SnmpKit.SnmpLib.OID.sort([[1, 3, 6, 2], [1, 3, 6, 1, 2], [1, 3, 6, 1]])
    # Returns [[1, 3, 6, 1], [1, 3, 6, 1, 2], [1, 3, 6, 2]]

# standard_prefix(arg1)

    @spec standard_prefix(atom()) :: oid() | nil

Get standard SNMP OID prefixes.

## Examples

    iex> SnmpKit.SnmpLib.OID.standard_prefix(:internet)
    [1, 3, 6, 1]

    iex> SnmpKit.SnmpLib.OID.standard_prefix(:mgmt)
    [1, 3, 6, 1, 2]

# string_to_list(oid_string)

    @spec string_to_list(oid_string()) :: {:ok, oid()} | {:error, atom()}

Converts an OID string to a list of integers.

Parses a dot-separated OID string into a list of non-negative integers. Validates each component and ensures the OID format is correct.

## Parameters

- `oid_string`: Dot-separated OID string (e.g., "1.3.6.1.2.1.1.1.0" or ".1.3.6.1.2.1.1.1.0")

## Returns

- `{:ok, oid_list}` on success
- `{:error, reason}` on failure

## Examples

    # Standard SNMP OIDs
    iex> SnmpKit.SnmpLib.OID.string_to_list("1.3.6.1.2.1.1.1.0")
    {:ok, [1, 3, 6, 1, 2, 1, 1, 1, 0]}

    # OIDs with leading dot (standard format)
    iex> SnmpKit.SnmpLib.OID.string_to_list(".1.3.6.1.2.1.1.1.0")
    {:ok, [1, 3, 6, 1, 2, 1, 1, 1, 0]}

    # Short OIDs
    iex> SnmpKit.SnmpLib.OID.string_to_list("1.3.6")
    {:ok, [1, 3, 6]}

    # Short OIDs with leading dot
    iex> SnmpKit.SnmpLib.OID.string_to_list(".1.3.6")
    {:ok, [1, 3, 6]}

    # Error cases
    iex> SnmpKit.SnmpLib.OID.string_to_list("")
    {:error, :empty_oid}

    iex> SnmpKit.SnmpLib.OID.string_to_list("1.3.6.1.a.2")
    {:error, :invalid_oid_string}

    iex> SnmpKit.SnmpLib.OID.string_to_list("1.3.6.1.2.-1")
    {:error, :invalid_oid_string}

# valid_oid?(oid)

    @spec valid_oid?(oid()) :: :ok | {:error, atom()}

Validates an OID list for correctness.

## Returns

- `:ok` if valid
- `{:error, reason}` if invalid

## Examples

    :ok = SnmpKit.SnmpLib.OID.valid_oid?([1, 3, 6, 1, 2, 1, 1, 1, 0])
    {:error, :empty_oid} = SnmpKit.SnmpLib.OID.valid_oid?([])
    {:error, :invalid_component} = SnmpKit.SnmpLib.OID.valid_oid?([1, 3, -1, 4])