gomib

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2026 License: MIT Imports: 19 Imported by: 0

README

gomib

Go library for parsing and querying SNMP MIB files.

Supports SMIv1 and SMIv2 modules. Loads MIBs from directories, directory trees, or embedded filesystems. Resolves imports, builds the OID tree, and provides typed access to objects, types, notifications, and conformance definitions.

Install

go get github.com/golangsnmp/gomib

Requires Go 1.24+.

Quick start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/golangsnmp/gomib"
)

func main() {
    m, err := gomib.Load(context.Background(),
        gomib.WithSystemPaths(),
        gomib.WithModules("IF-MIB"),
    )
    if err != nil {
        log.Fatal(err)
    }

    obj := m.Object("ifIndex")
    if obj != nil {
        fmt.Printf("%s  %s  %s  %s\n", obj.Name(), obj.OID(), obj.Type().Name(), obj.Access())
        // ifIndex  1.3.6.1.2.1.2.2.1.1  InterfaceIndex  read-only
    }
}

Loading MIBs

// Load everything from a source (parses all files)
m, err := gomib.Load(ctx, gomib.WithSource(src))

// Load only specific modules and their transitive dependencies.
// Faster when the source contains hundreds of MIBs but you only need a few.
m, err := gomib.Load(ctx, gomib.WithSource(src), gomib.WithModules("IF-MIB", "IP-MIB"))
Sources

Dir searches a single flat directory. DirTree recursively indexes a directory tree. FS wraps an fs.FS (useful with embed.FS). Multi tries multiple sources in order.

// Single directory
src, err := gomib.Dir("/usr/share/snmp/mibs")

// Recursive tree (indexed once at construction)
src, err := gomib.DirTree("/usr/share/snmp/mibs")

// Embedded filesystem
//go:embed mibs
var mibFS embed.FS
src := gomib.FS("embedded", mibFS)

// Combine sources (first match wins)
src := gomib.Multi(systemSrc, vendorSrc)

Must variants (MustDir, MustDirTree) panic on error for use in var blocks.

Files are matched by extension: no extension, .mib, .smi, .txt, .my. Override with WithExtensions. Non-MIB files are filtered during loading by checking for DEFINITIONS and ::= in the content.

Options
gomib.Load(ctx,
    gomib.WithSource(src),
    gomib.WithSystemPaths(),                             // discover net-snmp/libsmi paths
    gomib.WithLogger(slog.Default()),                    // enable debug/trace logging
    gomib.WithStrictness(mib.StrictnessPermissive),    // strictness preset
    gomib.WithDiagnosticConfig(mib.DiagnosticConfig{   // fine-grained control
        Level:  mib.StrictnessNormal,
        FailAt: mib.SeverityError,
        Ignore: []string{"identifier-underscore"},
    }),
)

Querying

Lookup methods take a plain name and return nil if not found:

obj := m.Object("ifIndex")
node := m.Node("ifEntry")
typ := m.Type("DisplayString")

For qualified lookup, scope through the module (see Module-scoped queries below).

Other lookup methods: Node, Type, Notification, Group, Compliance, Capability.

Resolve

Resolve accepts any common format - plain name, qualified name, or numeric OID - and returns the matching node:

node := m.Resolve("ifDescr")                     // plain name
node  = m.Resolve("IF-MIB::ifDescr")             // qualified
node  = m.Resolve("1.3.6.1.2.1.2.2.1.2")        // numeric OID
node  = m.Resolve(".1.3.6.1.2.1.2.2.1.2")       // leading dot

ResolveOID converts any of those formats to a numeric OID, and also handles instance-suffixed forms:

oid, err := m.ResolveOID("IF-MIB::ifDescr.5")    // OID{1,3,6,1,2,1,2,2,1,2,5}
oid, err  = m.ResolveOID("ifDescr.5")             // same result
oid, err  = m.ResolveOID("1.3.6.1.2.1.2.2.1.2")  // numeric pass-through

ResolveOID is the inverse of FormatOID:

formatted := m.FormatOID(oid)       // "IF-MIB::ifDescr.5"
back, _   := m.ResolveOID(formatted) // round-trips to the same OID
OID lookups

For cases where you already know the format, lower-level methods avoid parsing:

oid, _ := mib.ParseOID("1.3.6.1.2.1.2.2.1.1")
node := m.NodeByOID(oid)            // exact match
node  = m.LongestPrefixByOID(oid)   // longest matching prefix
Module-scoped queries
mod := m.Module("IF-MIB")
obj := mod.Object("ifIndex")
typ := mod.Type("InterfaceIndex")
Collections
m.Objects()        // all OBJECT-TYPE definitions
m.Tables()         // tables only
m.Scalars()        // scalars only
m.Columns()        // columns only
m.Rows()           // rows only
m.Types()          // all type definitions
m.Notifications()  // all notifications
m.Groups()         // all groups
m.Compliances()    // all compliances
m.Capabilities()   // all capabilities
m.Modules()        // all loaded modules
OID tree iteration
for node := range m.Nodes() {
    fmt.Println(node.OID(), node.Name(), node.Kind())
}

// Subtree iteration
node := m.Node("ifEntry")
for child := range node.Subtree() {
    fmt.Println(child.Name())
}

Objects

Each Object carries its type, access level, status, and position in the OID tree:

obj := m.Object("ifType")

obj.Name()        // "ifType"
obj.OID()         // 1.3.6.1.2.1.2.2.1.3
obj.Kind()        // column
obj.Access()      // read-only
obj.Status()      // current
obj.Type().Name() // "IANAifType"
obj.Units()       // "" (empty if not set)
obj.Description() // "The type of interface..."
Tables
table := m.Object("ifTable")
table.IsTable()  // true

row := table.Entry()           // ifEntry
cols := row.Columns()          // [ifIndex, ifDescr, ifType, ...]
idxs := row.EffectiveIndexes() // handles AUGMENTS

for _, idx := range idxs {
    fmt.Printf("INDEX %s (implied=%v)\n", idx.Object.Name(), idx.Implied)
}

Navigate from any level: obj.Table() returns the containing table, obj.Row() returns the containing row.

Effective constraints

Constraints can be defined inline on the object or inherited through the type chain. The Effective* methods walk both:

obj.EffectiveEnums()       // enum values
obj.EffectiveBits()        // BITS values
obj.EffectiveRanges()      // value ranges
obj.EffectiveSizes()       // size constraints
obj.EffectiveDisplayHint() // display hint string

Types

Types form chains: a textual convention references a parent type, which may reference another, down to a base SMI type.

typ := m.Type("DisplayString")

typ.Name()                // "DisplayString"
typ.IsTextualConvention() // true
typ.Base()                // OCTET STRING
typ.DisplayHint()         // "255a"
typ.Sizes()               // [{0 255}]
typ.Parent().Name()       // base type reference

// Walk the chain
for t := typ; t != nil; t = t.Parent() {
    fmt.Printf("%s (base: %s)\n", t.Name(), t.Base())
}

// Effective values resolve through the chain
typ.EffectiveBase()        // underlying base type
typ.EffectiveDisplayHint() // first non-empty hint in chain
typ.EffectiveEnums()       // first non-empty enum set

Classification helpers: IsCounter(), IsGauge(), IsString(), IsEnumeration(), IsBits().

Notifications

notif := m.Notification("linkDown")

notif.Name()        // "linkDown"
notif.OID()         // 1.3.6.1.6.3.1.1.5.3
notif.Status()      // current
notif.Description() // "A linkDown trap..."

for _, obj := range notif.Objects() {
    fmt.Printf("  varbind: %s (%s)\n", obj.Name(), obj.OID())
}

Diagnostics

Loading produces diagnostics for issues found during parsing and resolution.

m, err := gomib.Load(ctx, gomib.WithSource(src))

// Check for errors
if m.HasErrors() {
    fmt.Println("errors found")
}

// Inspect all diagnostics
for _, d := range m.Diagnostics() {
    fmt.Printf("[%s] %s: %s (line %d)\n", d.Severity, d.Module, d.Message, d.Line)
}

// Check unresolved references
for _, ref := range m.Unresolved() {
    fmt.Printf("unresolved %s: %s in %s\n", ref.Kind, ref.Symbol, ref.Module)
}
Strictness levels

Four presets control how strictly MIBs are validated:

Level Constant Behavior
Strict StrictnessStrict RFC-only, no fallbacks
Normal StrictnessNormal Default, safe fallbacks for common issues
Permissive StrictnessPermissive Tolerant of vendor MIB violations
Silent StrictnessSilent Accept everything, suppress diagnostics
m, _ := gomib.Load(ctx, gomib.WithSource(src), gomib.WithStrictness(mib.StrictnessPermissive))

For fine-grained control, use WithDiagnosticConfig:

gomib.WithDiagnosticConfig(mib.DiagnosticConfig{
    Level:  mib.StrictnessNormal,
    FailAt: mib.SeverityError,              // fail on Error or worse
    Ignore: []string{"identifier-underscore"}, // suppress specific codes
    Overrides: map[string]mib.Severity{
        "import-not-found": mib.SeverityWarning, // downgrade to warning
    },
})

CLI

The cmd/gomib tool provides a command-line interface for MIB operations:

gomib load IF-MIB                    # load and show statistics
gomib get -m IF-MIB ifIndex          # query by name
gomib get -m IF-MIB 1.3.6.1.2.1.2   # query by OID
gomib dump IF-MIB                    # JSON output
gomib lint IF-MIB                    # check for issues
gomib find --all 'if*'               # search by pattern
gomib trace -m IF-MIB ifEntry        # trace resolution
gomib paths                          # show search paths
gomib list                           # list available modules

Use -p PATH to specify MIB search paths (repeatable). Without -p, paths are discovered from net-snmp and libsmi configuration (config files, MIBDIRS/SMIPATH env vars, standard default directories).

See cmd/gomib/README.md for full command reference.

Documentation

Overview

Package gomib loads and resolves SNMP MIB modules.

Call Load with one or more Source values to parse MIB files, resolve cross-module imports, build the OID tree, and return a read-only mib.Mib containing the merged result.

Index

Constants

View Source
const LevelTrace = types.LevelTrace

LevelTrace is a custom log level more verbose than Debug. Use for per-item iteration logging (tokens, OID nodes, imports). Enable with: &slog.HandlerOptions{Level: slog.Level(-8)}

Variables

View Source
var ErrDiagnosticThreshold = errors.New("diagnostic threshold exceeded")

ErrDiagnosticThreshold is returned when diagnostics exceed the configured FailAt severity. The Mib is still returned with all resolved data.

View Source
var ErrMissingModules = errors.New("requested modules not found")

ErrMissingModules is returned when WithModules names are not found in any source. The Mib is still returned with whatever modules could be loaded.

View Source
var ErrNoSources = errors.New("no MIB sources provided")

ErrNoSources is returned when Load is called with no sources.

Functions

func DefaultExtensions

func DefaultExtensions() []string

DefaultExtensions returns the file extensions recognized as MIB files. Empty string matches files with no extension (e.g., "IF-MIB").

func DiscoverSystemPaths added in v0.2.1

func DiscoverSystemPaths() []string

DiscoverSystemPaths returns MIB directories from net-snmp and libsmi configuration, deduplicated and filtered to directories that exist.

func Load

func Load(ctx context.Context, opts ...LoadOption) (*mib.Mib, error)

Load loads MIB modules from configured sources and resolves them.

Example:

m, err := gomib.Load(ctx,
    gomib.WithSource(gomib.MustDirTree("/usr/share/snmp/mibs")),
    gomib.WithModules("IF-MIB", "IP-MIB"),
)

m, err := gomib.Load(ctx, gomib.WithSystemPaths())

Types

type FindResult

type FindResult struct {
	Content []byte
	// Path is used in diagnostic messages to identify the source.
	Path string
}

FindResult holds the content and location of a found MIB file.

type LoadOption

type LoadOption func(*loadConfig)

LoadOption configures Load.

func WithDiagnosticConfig added in v0.1.0

func WithDiagnosticConfig(cfg mib.DiagnosticConfig) LoadOption

WithDiagnosticConfig sets the diagnostic configuration for strictness control. If not set, defaults to Normal strictness (report Minor and above, fail on Severe).

func WithLogger

func WithLogger(logger *slog.Logger) LoadOption

WithLogger sets the logger for debug/trace output. If not set, no logging occurs (zero overhead).

func WithModules added in v0.1.0

func WithModules(names ...string) LoadOption

WithModules restricts loading to the named modules and their dependencies. Omit to load all modules from the configured sources.

func WithSource added in v0.1.0

func WithSource(src ...Source) LoadOption

WithSource appends one or more MIB sources to the load configuration. Sources are searched in the order they are added.

func WithStrictness added in v0.1.0

func WithStrictness(level mib.StrictnessLevel) LoadOption

WithStrictness sets the strictness level using a preset configuration. Convenience wrapper for WithDiagnosticConfig with preset configs.

func WithSystemPaths added in v0.1.0

func WithSystemPaths() LoadOption

WithSystemPaths enables automatic discovery of MIB search paths from net-snmp and libsmi configuration (config files, env vars, defaults). Discovered paths are appended after any explicit source, serving as fallback. When source is nil and WithSystemPaths is set, system paths alone are sufficient.

type Source

type Source interface {
	// Find returns the MIB content for the named module,
	// or fs.ErrNotExist if the module is not available.
	Find(name string) (FindResult, error)

	// ListModules returns all module names known to this source.
	ListModules() ([]string, error)
}

Source provides access to MIB files for the loading pipeline. Implementations are passed to WithSource and searched in order during Load to locate module files by name. The standard implementations are Dir, DirTree, FS, and Multi.

func Dir

func Dir(path string, opts ...SourceOption) (Source, error)

Dir creates a Source that searches a single directory (no recursion). Files are looked up lazily on each Find() call.

func DirTree

func DirTree(root string, opts ...SourceOption) (Source, error)

DirTree creates a Source that recursively indexes a directory tree. It walks the tree once at construction and builds a name->path index. First match wins for duplicate names.

func DiscoverSystemSources added in v0.2.1

func DiscoverSystemSources() []Source

DiscoverSystemSources returns Sources for all discovered system MIB directories.

func FS

func FS(name string, fsys fs.FS, opts ...SourceOption) Source

FS creates a Source backed by an fs.FS (e.g., embed.FS). The name is used in diagnostic paths. The filesystem is lazily indexed on first use.

Unlike Dir and DirTree, FS does not return an error at construction time. This is intentional: embed.FS cannot be walked until the program runs, so validation is deferred to the first Find or ListModules call.

func Multi

func Multi(sources ...Source) Source

Multi combines multiple sources into one. Find() tries each source in order, returning the first match.

func MustDir

func MustDir(path string, opts ...SourceOption) Source

MustDir is like Dir but panics on error.

func MustDirTree

func MustDirTree(root string, opts ...SourceOption) Source

MustDirTree is like DirTree but panics on error.

type SourceOption

type SourceOption func(*sourceConfig)

SourceOption modifies source behavior.

func WithExtensions

func WithExtensions(exts ...string) SourceOption

WithExtensions overrides the default file extensions used to match MIB files. Extensions are normalized to lowercase with a leading dot (e.g. "mib" becomes ".mib"). An empty string matches files with no extension.

Directories

Path Synopsis
cmd
gomib command
Command gomib is a CLI tool for loading, querying, and dumping MIB modules.
Command gomib is a CLI tool for loading, querying, and dumping MIB modules.
gomib-libsmi command
Command gomib-libsmi compares gomib against libsmi for lexer/parser cross-validation.
Command gomib-libsmi compares gomib against libsmi for lexer/parser cross-validation.
gomib-netsnmp command
Command gomib-netsnmp compares gomib against net-snmp for cross-validation.
Command gomib-netsnmp compares gomib against net-snmp for cross-validation.
internal/cliutil
Package cliutil provides shared CLI utilities for gomib command-line tools.
Package cliutil provides shared CLI utilities for gomib command-line tools.
examples
basic command
Load IF-MIB and print a module summary with selected objects.
Load IF-MIB and print a module summary with selected objects.
diagnostics command
Load MIBs at different strictness levels and show diagnostic output.
Load MIBs at different strictness levels and show diagnostic output.
embed command
Use embed.FS with gomib.FS() to load MIBs embedded in the binary.
Use embed.FS with gomib.FS() to load MIBs embedded in the binary.
query command
Show different query patterns: by name, module-scoped, OID, and prefix matching.
Show different query patterns: by name, module-scoped, OID, and prefix matching.
tables command
Load several MIBs and demonstrate the table API: structure, indexes, columns, AUGMENTS relationships, index encoding, and navigation.
Load several MIBs and demonstrate the table API: structure, indexes, columns, AUGMENTS relationships, index encoding, and navigation.
types command
Show type chain walking, textual conventions, and effective constraints.
Show type chain walking, textual conventions, and effective constraints.
internal
ast
Package ast provides Abstract Syntax Tree types for parsed MIB modules.
Package ast provides Abstract Syntax Tree types for parsed MIB modules.
graph
Package graph provides dependency graph construction and analysis for MIB resolution.
Package graph provides dependency graph construction and analysis for MIB resolution.
lexer
Package lexer provides tokenization for SMIv1/SMIv2 MIB source text.
Package lexer provides tokenization for SMIv1/SMIv2 MIB source text.
module
Package module provides a normalized representation of MIB modules.
Package module provides a normalized representation of MIB modules.
parser
Package parser provides MIB parsing into an AST.
Package parser provides MIB parsing into an AST.
testutil
Package testutil provides test assertion helpers.
Package testutil provides test assertion helpers.
types
Package types provides internal types shared across gomib packages.
Package types provides internal types shared across gomib packages.
Package mib provides the resolved, read-only model produced by loading SNMP MIB modules.
Package mib provides the resolved, read-only model produced by loading SNMP MIB modules.
Package smiwrite emits resolved MIB models as canonical SMIv2 text.
Package smiwrite emits resolved MIB models as canonical SMIv2 text.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL