gsnmpgo: github.com/soniah/gsnmpgo Index | Files | Directories

package gsnmpgo

import "github.com/soniah/gsnmpgo"

Package gsnmpgo is an snmp library for Go; it uses Go/CGo to wrap gsnmp.

gsnmpgo is pre 1.0, therefore API's may change, and tests are minimal.

ISSUES

Snmp walks aren't being done as "GETBULK" when using snmp v2c, rather repeated getnexts are being done ie like snmp v1. The gsnmp C library doesn't implement GETBULK directly, my intention is to write the C code to do it.

Threading: either gsnmp isn't totally thread safe, or I'm making errors with my C calls from Go (more likely). I'm getting aborts with this message:

GLib-WARNING **: g_main_context_prepare(): main loop already active in another thread

My current workaround is to force Query() calls to be synchronous:

var mu sync.Mutex
mu.Lock()
_, _ = gsnmpgo.Query(params)
mu.Unlock()

INSTALLATION

gsnmpgo requires the following libraries, as well as library header files:

glib2.0, gsnmp, gnet-2.0

Here is an example of installation on Ubuntu Precise 12.04.1:

# setup Go
sudo aptitude install golang git
cat >> ~/.bashrc
export GOPATH="${HOME}/go"
^D
mkdir ~/go && source ~/.bashrc && cd ~/go

# install GoLLRB; ignore error about "no Go source files" - GoLLRB has a
# non-standard layout
go get -d github.com/petar/GoLLRB
go install github.com/petar/GoLLRB/llrb

# install tcgl/applog
go get code.google.com/p/tcgl/applog

# install gsnmpgo
go get -d github.com/soniah/gsnmpgo
sudo aptitude install libglib2.0-dev libgsnmp0-dev libgnet-dev
go install github.com/soniah/gsnmpgo

# test working (you will need to edit example.go and
# provide different uris)
cd src/github.com/soniah/gsnmpgo/examples
go run example.go

Builds ok with these C libs (Ubuntu versions shown):

libglib2.0-dev                                 2.32.3-0ubuntu1
libgsnmp0-dev                                  0.3.0-1.1
libgnet-dev                                    2.0.8-2.1

SUMMARY

(most of this code is in examples/example.go)

// do an snmp get; RFC 4088 is used for uris
uri := `snmp://public@192.168.1.10//(1.3.6.1.2.1.1.1.0)`
params := gsnmpgo.NewDefaultParams(uri)
results, err := gsnmpgo.Query(params)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}

// check your results
gsnmpgo.Dump(results)

// turn on debugging
gsnmpgo.Debug = true

SPECIFYING URIS

http://tools.ietf.org/html/rfc4088 is used for specifying snmp uris; as well as doing an snmp get you can also do a snmp getnext or snmp walk:

// GET - notice you can have multiple OIDs
uri := `snmp://public@192.168.1.10//(1.3.6.1.2.1.1.1.0,1.3.6.1.2.1.1.2.0)`

// NEXT - notice the plus sign at the end
uri := `snmp://public@192.168.1.10//1.3.6.1.2.1+`

// WALK - notice the star at the end
// uri := `snmp://public@192.168.1.10//1.3.6.1.2.1.*`

RESULTS

The results are returned as an LLRB tree to provide "ordered map" functionality (ie finding items by "key", and iterating "in order"). Items in the tree are of type QueryResult:

type QueryResult struct {
    Oid   string
    Value Varbinder
}

See http://github.com/petar/GoLLRB for more documentation on using the LLRB tree.

SNMP types are represented by Go types that implement the Varbinder interface (eg "Octet String" is VBT_OctetString, "IP Address" is VBT_IPAddress). Use a type switch to make decisions based on the SNMP type:

ch := results.IterAscend()
for {
    r := <-ch
    if r == nil {
        break
    }
    result := r.(gsnmpgo.QueryResult)
    switch result.Value.(type) {
    case gsnmpgo.VBT_OctetString:
        fmt.Printf("OID %s is an octet string: %s\n", result.Oid, result.Value)
    default:
        fmt.Printf("OID %s is some other type\n", result.Oid)
    }
}

The Varbinder interface has two convenience functions Integer() and String() that allow you to get all your results "as a string" or "as a number":

type Varbinder interface {
    Integer() *big.Int
    fmt.Stringer
}

ch2 := results.IterAscend()
for {
    r := <-ch2
    if r == nil {
        break
    }
    result := r.(gsnmpgo.QueryResult)
    fmt.Printf("OID %s type: %T\n", result.Oid, result.Value)
    fmt.Printf("OID %s as a number: %d\n", result.Oid, result.Value.Integer())
    fmt.Printf("OID %s as a string: %s\n\n", result.Oid, result.Value)
}

Some of the Stringers are smart, for example gsnmpgo.VBT_Timeticks will be formatted as days, hours, etc when returned as a string:

OID 1.3.6.1.2.1.1.3.0 as a number: 4381200
OID 1.3.6.1.2.1.1.3.0 as a string: 0 days, 12:10:12.00

TESTS

The tests use the Verax Snmp Simulator [1]; setup Verax before running "go test":

* download, install and run Verax with the default configuration

* in the gsnmpgo/testing directory, setup these symlinks (or equivalents for your system):

ln -s /usr/local/vxsnmpsimulator/device device
ln -s /usr/local/vxsnmpsimulator/conf/devices.conf.xml devices.conf.xml

* remove randomising elements from Verax device files:

cd testing/device/cisco
sed -i -e 's!\/\/\$.*!!' -e 's!^M!!' cisco_router.txt
cd ../os
sed -i -e 's!\/\/\$.*!!' -e 's!^M!!' os-linux-std.txt

[1] http://www.veraxsystems.com/en/products/snmpsimulator

HELPER FUNCTIONS

There are a number of helper functions. Many of these have tests that serve as example usage.

PartitionAllP()

If you have a many oids to retrieve for a single device, you could:

* send all the oids in one SNMP Get - could cause network problems * do an SNMP BulkWalk - but that isn't implemented yet, and maybe

your target device only supports SNMP v1 anyway

Instead, use PartitionAllP() to break up your large list of OIDs into partitions of n.

Sonia Hamilton, sonia@snowfrog.net, http://www.snowfrog.net.

Index

Package Files

doc.go gsnmpgo.go interface.go stringers.go testing.go union.go

Constants

const MAX_URI_COUNT = 50

the maximum number of paths that can be in a single uri

Variables

var Debug bool // global debugging flag

func CompareVerax

func CompareVerax(t *testing.T, gresults, vresults *llrb.Tree)

func Dump

func Dump(results *llrb.Tree)

Dump is a convenience function for printing the results of a Query.

func LessOID

func LessOID(astruct, bstruct interface{}) bool

LessOID is the LessFunc for GoLLRB

It returns true if oid a is less than oid b.

func OidAsString

func OidAsString(o []int) string

Converts an OID in a slice of int format (eg []int{1, 3, 6, 1} to a string.

func PartitionAllP

func PartitionAllP(current_position, partition_size, slice_length int) bool

PartitionAllP - returns true when dividing a slice into partition_size lengths, including last partition which may be smaller than partition_size.

For example for a slice of 8 items to be broken into partitions of length 3, PartitionAllP returns true for the current_position having the following values:

0 1 2 3 4 5 6 7

T        T     T

'P' stands for Predicate (like foo? in Ruby, foop in Lisp)

func Query

func Query(params *QueryParams) (results *llrb.Tree, err error)

Query takes a URI in RFC 4088 format, does an SNMP query and returns the results.

func ReadVeraxResults

func ReadVeraxResults(filename string) (results *llrb.Tree, err error)

type PduError

type PduError int

type and values for _Ctype_gint32

const (
    GNET_SNMP_PDU_ERR_DONE PduError = iota - 4
    GNET_SNMP_PDU_ERR_PROCEDURE
    GNET_SNMP_PDU_ERR_INTERNAL
    GNET_SNMP_PDU_ERR_NORESPONSE
    GNET_SNMP_PDU_ERR_NOERROR
    GNET_SNMP_PDU_ERR_TOOBIG
    GNET_SNMP_PDU_ERR_NOSUCHNAME
    GNET_SNMP_PDU_ERR_BADVALUE
    GNET_SNMP_PDU_ERR_READONLY
    GNET_SNMP_PDU_ERR_GENERROR
    GNET_SNMP_PDU_ERR_NOACCESS
    GNET_SNMP_PDU_ERR_WRONGTYPE
    GNET_SNMP_PDU_ERR_WRONGLENGTH
    GNET_SNMP_PDU_ERR_WRONGENCODING
    GNET_SNMP_PDU_ERR_WRONGVALUE
    GNET_SNMP_PDU_ERR_NOCREATION
    GNET_SNMP_PDU_ERR_INCONSISTENTVALUE
    GNET_SNMP_PDU_ERR_RESOURCEUNAVAILABLE
    GNET_SNMP_PDU_ERR_COMMITFAILED
    GNET_SNMP_PDU_ERR_UNDOFAILED
    GNET_SNMP_PDU_ERR_AUTHORIZATIONERROR
    GNET_SNMP_PDU_ERR_NOTWRITABLE
    GNET_SNMP_PDU_ERR_INCONSISTENTNAME
)

func (PduError) String

func (pduerror PduError) String() string

Stringer for PduError

type QueryParams

type QueryParams struct {
    Uri     string
    Version SnmpVersion
    Timeout int // timeout in milliseconds
    Retries int // number of retries
    // Nonrep and Maxrep will be used by v2c BULK GETs.
    // From O'Reilly "Essential SNMP": "nonrep is the number of scalar
    // objects that this command will return; rep is the number of
    // instances of each nonscalar object that the command will return."
    Nonrep int
    Maxrep int
    // if Tree is non-nil, it will be used for appending Query()
    // results eg when doing two GETs in a row
    Tree *llrb.Tree
}

Struct of parameters to pass to Query

func NewDefaultParams

func NewDefaultParams(uri string) *QueryParams

NewDefaultParams returns QueryParams with sensible default values

type QueryResult

type QueryResult struct {
    Oid   string
    Value Varbinder
}

A single result, used as an Item in the llrb tree

type SecLevel

type SecLevel int

type and values for _Ctype_GNetSnmpSecLevel

const (
    GNET_SNMP_SECLEVEL_NANP SecLevel = iota
    GNET_SNMP_SECLEVEL_ANP
    GNET_SNMP_SECLEVEL_AP
)

func (SecLevel) String

func (seclevel SecLevel) String() string

Stringer for SecLevel

type SecModel

type SecModel int

type and values for _Ctype_GNetSnmpSecModel

const (
    GNET_SNMP_SECMODEL_ANY SecModel = iota
    GNET_SNMP_SECMODEL_SNMPV1
    GNET_SNMP_SECMODEL_SNMPV2C
    GNET_SNMP_SECMODEL_SNMPV3
)

func (SecModel) String

func (secmodel SecModel) String() string

Stringer for SecModel

type SnmpVersion

type SnmpVersion int

type and values for _Ctype_GNetSnmpVersion

const (
    GNET_SNMP_V1 SnmpVersion = iota
    GNET_SNMP_V2C
    GNET_SNMP_V2P
    GNET_SNMP_V3
)

func (SnmpVersion) String

func (snmpversion SnmpVersion) String() string

Stringer for SnmpVersion

type UriType

type UriType int

type and values for _Ctype_GNetSnmpUriType

const (
    GNET_SNMP_URI_GET UriType = iota
    GNET_SNMP_URI_NEXT
    GNET_SNMP_URI_WALK
)

func (UriType) String

func (uritype UriType) String() string

Stringer for UriType

type VBT_Counter32

type VBT_Counter32 uint32

GNET_SNMP_VARBIND_TYPE_COUNTER32

func (VBT_Counter32) Integer

func (r VBT_Counter32) Integer() *big.Int

func (VBT_Counter32) String

func (r VBT_Counter32) String() string

type VBT_Counter64

type VBT_Counter64 uint64

GNET_SNMP_VARBIND_TYPE_COUNTER64

func (VBT_Counter64) Integer

func (r VBT_Counter64) Integer() *big.Int

func (VBT_Counter64) String

func (r VBT_Counter64) String() string

type VBT_EndOfMibView

type VBT_EndOfMibView struct{}

GNET_SNMP_VARBIND_TYPE_ENDOFMIBVIEW

func (VBT_EndOfMibView) Integer

func (r VBT_EndOfMibView) Integer() *big.Int

func (VBT_EndOfMibView) String

func (r VBT_EndOfMibView) String() string

type VBT_IPAddress

type VBT_IPAddress string

GNET_SNMP_VARBIND_TYPE_IPADDRESS

func (VBT_IPAddress) Integer

func (r VBT_IPAddress) Integer() *big.Int

func (VBT_IPAddress) String

func (r VBT_IPAddress) String() string

type VBT_Integer32

type VBT_Integer32 int32

GNET_SNMP_VARBIND_TYPE_INTEGER32

func (VBT_Integer32) Integer

func (r VBT_Integer32) Integer() *big.Int

func (VBT_Integer32) String

func (r VBT_Integer32) String() string

type VBT_NoSuchInstance

type VBT_NoSuchInstance struct{}

GNET_SNMP_VARBIND_TYPE_NOSUCHINSTANCE

func (VBT_NoSuchInstance) Integer

func (r VBT_NoSuchInstance) Integer() *big.Int

func (VBT_NoSuchInstance) String

func (r VBT_NoSuchInstance) String() string

type VBT_NoSuchObject

type VBT_NoSuchObject struct{}

GNET_SNMP_VARBIND_TYPE_NOSUCHOBJECT

func (VBT_NoSuchObject) Integer

func (r VBT_NoSuchObject) Integer() *big.Int

func (VBT_NoSuchObject) String

func (r VBT_NoSuchObject) String() string

type VBT_Null

type VBT_Null struct{}

GNET_SNMP_VARBIND_TYPE_NULL

func (VBT_Null) Integer

func (r VBT_Null) Integer() *big.Int

func (VBT_Null) String

func (r VBT_Null) String() string

type VBT_ObjectID

type VBT_ObjectID string

GNET_SNMP_VARBIND_TYPE_OBJECTID

func (VBT_ObjectID) Integer

func (r VBT_ObjectID) Integer() *big.Int

func (VBT_ObjectID) String

func (r VBT_ObjectID) String() string

type VBT_OctetString

type VBT_OctetString string

GNET_SNMP_VARBIND_TYPE_OCTETSTRING

func (VBT_OctetString) Integer

func (r VBT_OctetString) Integer() *big.Int

func (VBT_OctetString) String

func (r VBT_OctetString) String() string

type VBT_Opaque

type VBT_Opaque string

GNET_SNMP_VARBIND_TYPE_OPAQUE

func (VBT_Opaque) Integer

func (r VBT_Opaque) Integer() *big.Int

func (VBT_Opaque) String

func (r VBT_Opaque) String() string

type VBT_Timeticks

type VBT_Timeticks uint32

GNET_SNMP_VARBIND_TYPE_TIMETICKS

func (VBT_Timeticks) Integer

func (r VBT_Timeticks) Integer() *big.Int

func (VBT_Timeticks) String

func (r VBT_Timeticks) String() string

type VBT_Unsigned32

type VBT_Unsigned32 uint32

GNET_SNMP_VARBIND_TYPE_UNSIGNED32

func (VBT_Unsigned32) Integer

func (r VBT_Unsigned32) Integer() *big.Int

func (VBT_Unsigned32) String

func (r VBT_Unsigned32) String() string

type VarBindType

type VarBindType int

type and values for _Ctype_GNetSnmpVarBindType

const (
    GNET_SNMP_VARBIND_TYPE_NULL VarBindType = iota
    GNET_SNMP_VARBIND_TYPE_OCTETSTRING
    GNET_SNMP_VARBIND_TYPE_OBJECTID
    GNET_SNMP_VARBIND_TYPE_IPADDRESS
    GNET_SNMP_VARBIND_TYPE_INTEGER32
    GNET_SNMP_VARBIND_TYPE_UNSIGNED32
    GNET_SNMP_VARBIND_TYPE_COUNTER32
    GNET_SNMP_VARBIND_TYPE_TIMETICKS
    GNET_SNMP_VARBIND_TYPE_OPAQUE
    GNET_SNMP_VARBIND_TYPE_COUNTER64
    GNET_SNMP_VARBIND_TYPE_NOSUCHOBJECT
    GNET_SNMP_VARBIND_TYPE_NOSUCHINSTANCE
    GNET_SNMP_VARBIND_TYPE_ENDOFMIBVIEW
)

func (VarBindType) String

func (varbindtype VarBindType) String() string

Stringer for VarBindType

type Varbinder

type Varbinder interface {
    // Integer() needs to handle both signed numbers (int32), as well as
    // unsigned int 64 (uint64). Therefore it returns a *big.Int.
    Integer() *big.Int
    fmt.Stringer
}

Directories

PathSynopsis
enumconvPackage enumconv provides helper functions for gocog, used in gsnmpgo/stringers.go.
examples
testing

Package gsnmpgo imports 14 packages (graph) and is imported by 2 packages. Updated 2013-12-04. Refresh now. Tools for package owners.