gsnmpgo

package module
Version: v0.0.0-...-b766576 Latest Latest
Warning

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

Go to latest
Published: Dec 4, 2013 License: GPL-3.0 Imports: 14 Imported by: 0

README

gsnmpgo

Update 8/Mar/13

Work on gsnmpgo has halted. Making the gsnmp C library multithreaded was proving too time consuming. Use http://github.com/soniah/gosnmp instead.

Update 4/Dec/13

Geert-Johan Riemer commented:

I saw your notice on gsnmpgo "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:"

I think this might be solved by locking the requesting goroutine to it's thread using runtime.LockOSThread (http://golang.org/pkg/runtime/#LockOSThread). And make sure requests are always made from that specific goroutine.

(I currently don't have time to work on gsnmpgo, but I thought I'd add this comment for future reference. Sonia.)

About

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.

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

Documentation

See http://godoc.org/github.com/soniah/gsnmpgo or your local go doc server for full documentation:

cd $GOPATH
godoc -http=:6060 &
$preferred_browser http://localhost:6060/pkg &

Installation

See documentation.

Issues

See documentation.

License

gsnmpgo is a go/cgo wrapper around gsnmp.

Copyright (C) 2012-2013 Sonia Hamilton sonia@snowfrog.net.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Note on License

The preferred way to release Go code is under a BSD/MIT/Apache license. However gsnmp is released under the GPL, therefore gsnmpgo must be released under the GPL. See http://www.gnu.org/licenses/gpl-faq.html#IfLibraryIsGPL

Documentation

Overview

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

Constants

View Source
const MAX_URI_COUNT = 50

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

Variables

View Source
var Debug bool // global debugging flag

Functions

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)

Types

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

Path Synopsis
Package enumconv provides helper functions for gocog, used in gsnmpgo/stringers.go.
Package enumconv provides helper functions for gocog, used in gsnmpgo/stringers.go.

Jump to

Keyboard shortcuts

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