SnmpKit ๐Ÿš€

Hex.pmDocumentationLicenseBuild Status

A modern, comprehensive SNMP toolkit for Elixir - featuring a unified API, pure Elixir implementation, and powerful device simulation.

SnmpKit is a complete SNMP (Simple Network Management Protocol) solution built from the ground up in pure Elixir. It provides a clean, organized API for SNMP operations, MIB management, and realistic device simulation - perfect for network monitoring, testing, and development.

โœจ Key Features

๐Ÿš€ Quick Start

Installation

Add snmpkit to your list of dependencies in mix.exs:

def deps do
[
{:snmpkit, "~> 0.2.0"}
]
end

Unified API Examples

SnmpKit provides a clean, organized API through context-based modules:

๐Ÿ“ก SNMP Operations (SnmpKit.SNMP)

# Basic SNMP operations
{:ok, description} = SnmpKit.SNMP.get("192.168.1.1", "sysDescr.0")
{:ok, uptime} = SnmpKit.SNMP.get("192.168.1.1", "sysUpTime.0")
# Walk operations
{:ok, system_info} = SnmpKit.SNMP.walk("192.168.1.1", "system")
{:ok, interface_table} = SnmpKit.SNMP.get_table("192.168.1.1", "ifTable")
# Bulk operations for efficiency
{:ok, results} = SnmpKit.SNMP.bulk_walk("192.168.1.1", "interfaces")
# Multi-target operations
{:ok, results} = SnmpKit.SNMP.get_multi([
{"host1", "sysDescr.0"},
{"host2", "sysUpTime.0"},
{"host3", "ifInOctets.1"}
])
# Pretty formatting
{:ok, formatted} = SnmpKit.SNMP.get_pretty("192.168.1.1", "sysUpTime.0")
# Returns: "12 days, 4:32:10.45"
# Async operations
task = SnmpKit.SNMP.get_async("192.168.1.1", "sysDescr.0")
{:ok, result} = Task.await(task)

๐Ÿ“š MIB Operations (SnmpKit.MIB)

# OID name resolution
{:ok, oid} = SnmpKit.MIB.resolve("sysDescr.0")
# Returns: [1, 3, 6, 1, 2, 1, 1, 1, 0]
# Reverse lookup
{:ok, name} = SnmpKit.MIB.reverse_lookup([1, 3, 6, 1, 2, 1, 1, 1, 0])
# Returns: "sysDescr.0"
# MIB compilation and loading
{:ok, compiled} = SnmpKit.MIB.compile("MY-CUSTOM-MIB.mib")
{:ok, _} = SnmpKit.MIB.load(compiled)
# Tree navigation
{:ok, children} = SnmpKit.MIB.children([1, 3, 6, 1, 2, 1, 1])
{:ok, parent} = SnmpKit.MIB.parent([1, 3, 6, 1, 2, 1, 1, 1, 0])

๐Ÿงช Device Simulation (SnmpKit.Sim)

# Load a device profile
{:ok, profile} = SnmpKit.SnmpSim.ProfileLoader.load_profile(
:cable_modem,
{:walk_file, "priv/walks/cable_modem.walk"}
)
# Start a simulated device
{:ok, device} = SnmpKit.Sim.start_device(profile, port: 1161)
# Create a population of devices for testing
device_configs = [
%{type: :cable_modem, port: 30001, community: "public"},
%{type: :switch, port: 30002, community: "public"},
%{type: :router, port: 30003, community: "private"}
]
{:ok, devices} = SnmpKit.Sim.start_device_population(device_configs)

๐ŸŽฏ Direct Access (Backward Compatibility)

For convenience, common operations are also available directly:

# These work the same as their SnmpKit.SNMP.* equivalents
{:ok, value} = SnmpKit.get("192.168.1.1", "sysDescr.0")
{:ok, results} = SnmpKit.walk("192.168.1.1", "system")
# MIB resolution
{:ok, oid} = SnmpKit.resolve("sysDescr.0")

Advanced Features

Engine Management and Performance

# Start the SNMP engine for advanced features
{:ok, _engine} = SnmpKit.SNMP.start_engine()
# Get performance statistics
{:ok, stats} = SnmpKit.SNMP.get_engine_stats()
# Batch operations for efficiency
requests = [
%{type: :get, target: "host1", oid: "sysDescr.0"},
%{type: :walk, target: "host2", oid: "interfaces"}
]
{:ok, results} = SnmpKit.SNMP.engine_batch(requests)
# Circuit breaker for reliability
{:ok, result} = SnmpKit.SNMP.with_circuit_breaker("unreliable.host", fn ->
SnmpKit.SNMP.get("unreliable.host", "sysDescr.0")
end)

Streaming and Large-Scale Operations

# Stream large walks to avoid memory issues
stream = SnmpKit.SNMP.walk_stream("192.168.1.1", "interfaces")
stream
|> Stream.take(1000)
|> Enum.to_list()
# Adaptive bulk operations that optimize themselves
{:ok, results} = SnmpKit.SNMP.adaptive_walk("192.168.1.1", "interfaces")
# Performance benchmarking
{:ok, benchmark} = SnmpKit.SNMP.benchmark_device("192.168.1.1", "system")

๐Ÿ—๏ธ Architecture

SnmpKit is organized into logical, discoverable modules:

๐Ÿ“Š Enterprise Features

DOCSIS and Cable Modem Support

# DOCSIS-specific operations
{:ok, cm_status} = SnmpKit.SNMP.get("10.1.1.100", "docsIfCmtsServiceAdminStatus.1")
{:ok, signal_quality} = SnmpKit.SNMP.get("10.1.1.100", "docsIfSigQSignalNoise.1")
# Load DOCSIS MIBs
{:ok, _} = SnmpKit.MIB.compile("DOCS-CABLE-DEVICE-MIB.mib")
{:ok, _} = SnmpKit.MIB.compile("DOCS-IF-MIB.mib")

Network Monitoring Integration

# Monitor interface statistics
interface_oids = [
"ifInOctets.1", "ifOutOctets.1",
"ifInErrors.1", "ifOutErrors.1"
]
# Collect metrics from multiple devices
devices = ["router1", "router2", "switch1", "switch2"]
results =
for device <- devices,
oid <- interface_oids do
{device, oid, SnmpKit.SNMP.get(device, oid)}
end
# Analyze and format results
analysis = SnmpKit.SNMP.analyze_table(results)

๐Ÿงช Testing and Development

Simulated Devices for Testing

defmodule MyAppTest do
use ExUnit.Case
setup do
# Start a simulated device for testing
{:ok, profile} = SnmpKit.SnmpSim.ProfileLoader.load_profile(:generic_router)
{:ok, device} = SnmpKit.Sim.start_device(profile, port: 1161)
%{device: device, target: "127.0.0.1:1161"}
end
test "can query simulated device", %{target: target} do
{:ok, description} = SnmpKit.SNMP.get(target, "sysDescr.0")
assert description =~ "Simulated Router"
end
end

Performance Testing

# Benchmark different devices and operations
devices = ["fast.device", "slow.device", "unreliable.device"]
benchmarks =
for device <- devices do
SnmpKit.SNMP.benchmark_device(device, "system")
end
# Compare performance characteristics
for {device, {:ok, benchmark}} <- Enum.zip(devices, benchmarks) do
IO.puts "#{device}: avg=#{benchmark.avg_response_time}ms, success_rate=#{benchmark.success_rate}%"
end

๐Ÿ“š Documentation

๐Ÿš€ Migration from Other Libraries

From :snmp (Erlang)

# Before (Erlang SNMP)
:snmp.sync_get(manager, oid, timeout)
# After (SnmpKit)
SnmpKit.SNMP.get("192.168.1.1", "sysDescr.0", timeout: 5000)

From Other Elixir SNMP Libraries

# SnmpKit provides more features with cleaner syntax
{:ok, results} = SnmpKit.SNMP.walk_multi([
{"host1", "interfaces"},
{"host2", "system"}
])
# Built-in formatting and analysis
{:ok, formatted} = SnmpKit.SNMP.walk_pretty("192.168.1.1", "interfaces")

โšก Performance

SnmpKit is designed for high-performance network monitoring:

๐Ÿ”ง Configuration

# config/config.exs
config :snmpkit,
default_community: "public",
default_timeout: 5000,
default_retries: 3,
default_version: :v2c
# For simulation
config :snmpkit, :simulation,
device_profiles_path: "priv/device_profiles",
walk_files_path: "priv/walks"
# For MIB management
config :snmpkit, :mib,
mib_path: ["priv/mibs", "/usr/share/snmp/mibs"],
auto_load_standard_mibs: true

๐Ÿค Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Development Setup

git clone https://github.com/awksedgreep/snmpkit.git
cd snmpkit
mix deps.get
mix test

Running the Test Suite

# Run all tests
mix test
# Run with coverage
mix test --cover
# Run specific test categories
mix test --include docsis
mix test --include integration

๐Ÿ“ˆ Roadmap

๐Ÿ“„ License

SnmpKit is released under the MIT License.

๐Ÿ™ Acknowledgments


Ready to simplify your SNMP operations? Get started with SnmpKit today! ๐Ÿš€

For questions, issues, or feature requests, please visit our GitHub repository.