Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions cmd/snmpprobe/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,27 @@ func init() {

func snmpprobe(client mibs.Client, ids ...mibs.ID) error {
if len(ids) == 0 {
var mibList []*mibs.MIB

mibs.WalkMIBs(func(mib *mibs.MIB) {
ids = append(ids, mib.ID)
mibList = append(mibList, mib)
})
}

if probed, err := client.Probe(ids); err != nil {
return err
if probed, err := client.ProbeMIBs(mibList); err != nil {
return err
} else {
for i, ok := range probed {
fmt.Printf("%v = %v\n", mibList[i], ok)
}
}

} else {
for i, ok := range probed {
fmt.Printf("%v = %v\n", ids[i], ok)
if probed, err := client.Probe(ids); err != nil {
return err
} else {
for i, ok := range probed {
fmt.Printf("%v = %v\n", ids[i], ok)
}
}
}

Expand Down
30 changes: 29 additions & 1 deletion mibs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,35 @@ type Client struct {
*client.Client
}

// Probe the MIB at id
// Probe for the existence of given MIBs
func (client Client) ProbeMIBs(mibs []*MIB) ([]bool, error) {
var probed = make([]bool, len(mibs))
var oids []snmp.OID
var mibIndex []int

for i, mib := range mibs {
for _, oid := range mib.OIDs {
oids = append(oids, oid)
mibIndex = append(mibIndex, i)
}
}

if varBinds, err := client.WalkScalars(oids); err != nil {
return probed, err
} else {
for i, varBind := range varBinds {
if err := varBind.ErrorValue(); err != nil {
// not supported
} else {
probed[mibIndex[i]] = true
}
}
}

return probed, nil
}

// Probe for the existence of arbitrary OIDs
func (client Client) Probe(ids []ID) ([]bool, error) {
var oids = make([]snmp.OID, len(ids))
var probed = make([]bool, len(ids))
Expand Down
30 changes: 24 additions & 6 deletions mibs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,48 @@ func (config ConfigID) resolve(mib *MIB) (ID, error) {

type MIBConfig struct {
OID string
OIDs []string
Name string
Objects []ObjectConfig
Tables []TableConfig

oid snmp.OID
}

func (config MIBConfig) build() (MIB, error) {
func (config MIBConfig) makeMIB() (MIB, error) {
if oid, err := snmp.ParseOID(config.OID); err != nil {
return MIB{}, fmt.Errorf("Invalid OID for MIB %v: %v", config.Name, err)
} else {
return makeMIB(config.Name, oid), nil
}
}

func (config MIBConfig) loadOIDs(mib *MIB) error {
for _, o := range config.OIDs {
if oid, err := snmp.ParseOID(o); err != nil {
return fmt.Errorf("Invalid OID %v for MIB %v: %v", o, config.Name, err)
} else {
mib.OIDs.Add(oid)
}
}

return nil
}

func (config MIBConfig) loadMIB() (*MIB, error) {
if buildMIB, err := config.build(); err != nil {
if mib, err := config.makeMIB(); err != nil {
return nil, err
} else if err := config.loadOIDs(&mib); err != nil {
return nil, err
} else {
return registerMIB(buildMIB), nil
return registerMIB(mib), nil
}
}

func (config MIBConfig) loadObjects(mib *MIB) error {
for _, objectConfig := range config.Objects {
if object, err := objectConfig.build(mib); err != nil {
return fmt.Errorf("Invalid Object %v: %v", objectConfig.Name, err)
} else if mib.OIDs.Get(object.OID) == nil {
return fmt.Errorf("Unknown OID %v for Object %v: outside of MIB OIDs %v", object.OID, objectConfig.Name, mib.OIDs)
} else {
mib.registerObject(object)
}
Expand All @@ -69,8 +83,12 @@ func (config MIBConfig) loadTables(mib *MIB, loadContext loadContext) error {
for _, tableConfig := range config.Tables {
if table, err := tableConfig.build(mib); err != nil {
return fmt.Errorf("Invalid Table %v: %v", tableConfig.Name, err)
} else if mib.OIDs.Get(table.OID) == nil {
return fmt.Errorf("Unknown OID %v for Table %v: outside of MIB OIDs %v", table.OID, tableConfig.Name, mib.OIDs)
} else {
loadContext.entryMap[mib.Name+"::"+tableConfig.EntryName] = mib.registerTable(table)
var table = mib.registerTable(table)

loadContext.entryMap[mib.Name+"::"+tableConfig.EntryName] = table
loadContext.augmentsMap[mib.Name+"::"+tableConfig.EntryName] = tableConfig.AugmentsEntry
}
}
Expand Down
18 changes: 18 additions & 0 deletions mibs/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ func TestConfigResolveMIB(t *testing.T) {
}
}

func TestConfigMIBOIDs(t *testing.T) {
if resolveMIB, err := ResolveMIB("TEST2-MIB"); err != nil {
t.Errorf("ResolveMIB TEST2-MIB: %v", err)
} else {
assert.Equal(t, "{.1.0.2 .1.1.5}", resolveMIB.OIDs.String())
}
}

func TestConfigResolve(t *testing.T) {
if id, err := Resolve("TEST2-MIB"); err != nil {
t.Errorf("Resolve TEST2-MIB: %v", err)
Expand Down Expand Up @@ -133,6 +141,11 @@ func TestConfigLookupObject(t *testing.T) {
}
}

func TestConfigFormatObject(t *testing.T) {
assert.Equal(t, "TEST2-MIB::test", FormatOID(snmp.OID{1, 0, 2, 1, 1}))
assert.Equal(t, "TEST2-MIB::test.0", FormatOID(snmp.OID{1, 0, 2, 1, 1, 0}))
}

func TestConfigLookupObjectExt(t *testing.T) {
if object := LookupObject(snmp.OID{1, 1, 5, 1}); object == nil {
t.Errorf("LookupObject .1.1.5.1: %v", nil)
Expand All @@ -141,6 +154,11 @@ func TestConfigLookupObjectExt(t *testing.T) {
}
}

func TestConfigFormatObjectExt(t *testing.T) {
assert.Equal(t, "TEST2-MIB::extObject", FormatOID(snmp.OID{1, 1, 5, 1}))
assert.Equal(t, "TEST2-MIB::extObject.0", FormatOID(snmp.OID{1, 1, 5, 1, 0}))
}

func TestConfigObjectUnknownSyntax(t *testing.T) {
if object, err := ResolveObject("TEST2-MIB::testUnknownSyntax"); err != nil {
t.Errorf("ResolveObject TEST2-MIB::testUnknownSyntax: %v", err)
Expand Down
4 changes: 0 additions & 4 deletions mibs/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ func (id ID) String() string {
}
}

func (id ID) MakeID(name string, ids ...int) ID {
return ID{id.MIB, name, id.OID.Extend(ids...)}
}

func (id ID) FormatOID(oid snmp.OID) string {
if index := id.OID.Index(oid); index == nil {
return oid.String()
Expand Down
38 changes: 17 additions & 21 deletions mibs/mib.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,30 @@ import (
)

func makeMIB(name string, oid snmp.OID) MIB {
var oids snmp.OIDSet

if oid != nil {
oids = snmp.MakeOIDSet(oid)
} else {
// MIB without any OID has an empty OID set
oids = snmp.MakeOIDSet()
}

return MIB{
ID: ID{OID: oid},
Name: name,
Name: name,
OID: oid,
OIDs: oids,

registry: makeRegistry(),
objects: make(map[IDKey]*Object),
tables: make(map[IDKey]*Table),
}
}

type MIB struct {
ID
Name string // shadows ID.Name, which is empty
Name string
OID snmp.OID
OIDs snmp.OIDSet
registry

objects map[IDKey]*Object
Expand All @@ -29,10 +41,6 @@ func (mib *MIB) String() string {
return mib.Name
}

func (mib *MIB) MakeID(name string, ids ...int) ID {
return ID{mib, name, mib.OID.Extend(ids...)}
}

func (mib *MIB) registerObject(object Object) *Object {
mibRegistry.registerOID(object.ID)
mib.registry.register(object.ID)
Expand All @@ -41,12 +49,6 @@ func (mib *MIB) registerObject(object Object) *Object {
return &object
}

func (mib *MIB) RegisterObject(id ID, object Object) *Object {
object.ID = id

return mib.registerObject(object)
}

func (mib *MIB) registerTable(table Table) *Table {
mibRegistry.registerOID(table.ID)
mib.registry.register(table.ID)
Expand All @@ -55,12 +57,6 @@ func (mib *MIB) registerTable(table Table) *Table {
return &table
}

func (mib *MIB) RegisterTable(id ID, table Table) *Table {
table.ID = id

return mib.registerTable(table)
}

/* Resolve MIB-relative ID by human-readable name:
".1.0"
"sysDescr"
Expand All @@ -69,7 +65,7 @@ func (mib *MIB) RegisterTable(id ID, table Table) *Table {
var mibResolveRegexp = regexp.MustCompile("^([^.]+?)?([.][0-9.]+)?$")

func (mib *MIB) Resolve(name string) (ID, error) {
var id = ID{OID: mib.OID}
var id = ID{MIB: mib, OID: mib.OID}
var nameID, nameOID string

if matches := mibResolveRegexp.FindStringSubmatch(name); matches == nil {
Expand Down
7 changes: 5 additions & 2 deletions mibs/mib_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package mibs

import (
"github.com/qmsk/snmpbot/snmp"
"github.com/stretchr/testify/assert"

"testing"
)

var (
TestMIB = RegisterMIB("TEST-MIB", 1, 0, 1)
TestMIB = registerMIB(makeMIB("TEST-MIB", snmp.OID{1, 0, 1}))

TestObject = TestMIB.RegisterObject(TestMIB.MakeID("test", 1, 1), Object{
TestObject = TestMIB.registerObject(Object{
ID: ID{MIB: TestMIB, Name: "test", OID: snmp.OID{1, 0, 1, 1, 1}},
Syntax: DisplayStringSyntax{},
})
)
Expand Down
18 changes: 3 additions & 15 deletions mibs/mibs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,15 @@ import (
var mibRegistry = makeRegistry()

func registerMIB(mib MIB) *MIB {
mib.ID.MIB = &mib

mibRegistry.registerName(mib.ID, mib.Name)
mibRegistry.registerName(ID{MIB: &mib, OID: mib.OID}, mib.Name)

if mib.OID != nil {
mibRegistry.registerOID(mib.ID)
mibRegistry.registerOID(ID{MIB: &mib, OID: mib.OID})
}

return &mib
}

func RegisterMIB(name string, oid ...int) *MIB {
return registerMIB(makeMIB(name, snmp.OID(oid)))
}

func ResolveMIB(name string) (*MIB, error) {
if id, ok := mibRegistry.getName(name); !ok {
return nil, fmt.Errorf("MIB not found: %v", name)
Expand All @@ -34,11 +28,6 @@ func ResolveMIB(name string) (*MIB, error) {

func WalkMIBs(f func(mib *MIB)) {
mibRegistry.walk(func(id ID) {
if id.OID == nil {
// skip MIBs without a top-level OID
return
}

f(id.MIB)
})
}
Expand Down Expand Up @@ -69,8 +58,7 @@ func Resolve(name string) (ID, error) {
} else if mib, err := ResolveMIB(nameMIB); err != nil {
return id, err
} else {
id = mib.ID
id.Name = "" // fixup MIB.ID re-use of Name
id = ID{MIB: mib, OID: mib.OID}
}

if nameID == "" {
Expand Down
3 changes: 3 additions & 0 deletions mibs/test/TEST2-MIB.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"Name": "TEST2-MIB",
"OID": ".1.0.2",
"OIDS": [
".1.1.5"
],
"Objects": [
{
"Name": "test",
Expand Down
12 changes: 9 additions & 3 deletions server/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,23 @@ func (host *Host) init(engine *Engine, config HostConfig) error {

func (host *Host) probe(probeMIBs MIBs) error {
var client = mibs.MakeClient(host.client)
var ids = probeMIBs.ListIDs()
var mibList []*mibs.MIB
var mibs = make(MIBs)

host.log.Infof("Probing MIBs: %v", probeMIBs)

if probed, err := client.Probe(ids); err != nil {
for _, mib := range probeMIBs {
mibList = append(mibList, mib)
}

if probed, err := client.ProbeMIBs(mibList); err != nil {
return err
} else {
for i, ok := range probed {
host.log.Debugf("probe MIB %v => %v", mibList[i], ok)

if ok {
mibs.Add(ids[i].MIB)
mibs.Add(mibList[i])
}
}
}
Expand Down
10 changes: 0 additions & 10 deletions server/mibs.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ func AllMIBs() MIBs {
return mibMap
}

func (mibMap MIBs) ListIDs() []mibs.ID {
var list = make([]mibs.ID, 0, len(mibMap))

for _, mib := range mibMap {
list = append(list, mib.ID)
}

return list
}

func (mibMap MIBs) Add(mib *mibs.MIB) {
mibMap[mib.Name] = mib
}
Expand Down
Loading