README ¶
gosnmp ====== [![Build Status](https://travis-ci.org/soniah/gosnmp.svg?branch=master)](https://travis-ci.org/soniah/gosnmp) [![Coverage](http://gocover.io/_badge/github.com/soniah/gosnmp)](http://gocover.io/github.com/soniah/gosnmp) [![GoDoc](https://godoc.org/github.com/soniah/gosnmp?status.png)](http://godoc.org/github.com/soniah/gosnmp) GoSNMP is an SNMP client library written fully in Go. Currently it supports GetRequest, GetNext, GetBulk, Walk (beta, see below), and SetRequest (beta, see below). About ----- **soniah/gosnmp** is based on **alouca/gosnmp** - many thanks to Andreas Louca for starting the project. Thanks also to the following who have contributed: * Chris Dance (@codedance) - Fixes, SNMP Walk functionality and examples, Retry Support * Nathan Owens (@virtuallynathan) - Fixes / Changes * Jacob Dubinsky (@jdubinsky) - All of GetNext and GetBulk * Jon Auer (@jda) - Data truncation fix * Andreas Louca (@alouca) - Original library Overview -------- GoSNMP has the following SNMP functions: * **Get** (single or multiple OIDs) * **GetNext** * **GetBulk** * **Walk** - retrieves a subtree of values using GETNEXT. * **BulkWalk** - retrieves a subtree of values using GETBULK. * **Set** (beta - only supports setting one integer OID) GoSNMP also has the following helper functions: * **ToBigInt** - treat returned values as `*big.Int` * **Partition** - facilitates dividing up large slices of OIDs **soniah/gosnmp** has diverged from **alouca/gosnmp** - your existing code will require slight modification: * the **Get** function has a different method signature * the **NewGoSNMP** function has been removed, use **Connect** instead (see Usage below) * GoSNMP no longer relies on **alouca/gologger** - you can use your logger if it conforms to the simple interface (Print and Printf). Otherwise debugging will be discarded (/dev/null). gosnmp is still under development, therefore API's may change and bugs will be squashed. Test Driven Development is used - you can help by sending packet captures (see Packet Captures below). There may be more than one branch on github. **master** is safe to pull from, other branches unsafe as history may be rewritten. Sonia Hamilton, sonia@snowfrog.net, http://blog.snowfrog.net. Installation ------------ Install via **go get**: go get github.com/soniah/gosnmp Documentation ------------- See http://godoc.org/github.com/soniah/gosnmp or your local go doc server for full documentation, as well as the examples. cd $GOPATH godoc -http=:6060 & $preferred_browser http://localhost:6060/pkg & Usage ----- Here is code from **example/example.go**, demonstrating how to use GoSNMP: ```go // Default is a pointer to a GoSNMP struct that contains sensible defaults // eg port 161, community public, etc g.Default.Target = "192.168.1.10" err := g.Default.Connect() if err != nil { log.Fatalf("Connect() err: %v", err) } defer g.Default.Conn.Close() oids := []string{"1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.7.0"} result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS if err2 != nil { log.Fatalf("Get() err: %v", err2) } for i, variable := range result.Variables { fmt.Printf("%d: oid: %s ", i, variable.Name) // the Value of each variable returned by Get() implements // interface{}. You could do a type switch... switch variable.Type { case g.OctetString: fmt.Printf("string: %s\n", variable.Value.(string)) default: // ... or often you're just interested in numeric values. // ToBigInt() will return the Value as a BigInt, for plugging // into your calculations. fmt.Printf("number: %d\n", g.ToBigInt(variable.Value)) } } ``` Running this example gives the following output (from my printer): % go run example.go 0: oid: 1.3.6.1.2.1.1.4.0 string: Administrator 1: oid: 1.3.6.1.2.1.1.7.0 number: 104 **example/example2.go** is similar to example.go, however is uses a custom &GoSNMP rather than **g.Default**. **example/walkexample.go** demonstrates using ```BulkWalk```. Bugs ---- The following BER types have been implemented: * 0x02 Integer * 0x04 OctetString * 0x06 ObjectIdentifier * 0x40 IPAddress (IPv4 & IPv6) * 0x41 Counter32 * 0x42 Gauge32 * 0x43 TimeTicks * 0x46 Counter64 * 0x80 NoSuchObject * 0x81 NoSuchInstance * 0x82 EndOfMibView The following (less common) BER types haven't been implemented, as I ran out of time or haven't been able to find example devices to query: * 0x00 EndOfContents * 0x01 Boolean * 0x03 BitString * 0x07 ObjectDescription * 0x44 Opaque * 0x45 NsapAddress * 0x47 Uinteger32 Packet Captures --------------- Please create an issue on GitHub with packet captures (upload them somewhere) containing samples of the missing BER types, or of any other bugs you find. Please include 2 or 3 examples of the missing/faulty BER type, interspersed with a couple of other common BER's eg an Integer, a Counter32 ie about 6-8 OIDs. Create your packet captures in the following way: Expected output, obtained via an **snmp** command. For example: % snmpget -On -v2c -c public 203.50.251.17 1.3.6.1.2.1.1.7.0 \ 1.3.6.1.2.1.2.2.1.2.6 1.3.6.1.2.1.2.2.1.5.3 .1.3.6.1.2.1.1.7.0 = INTEGER: 78 .1.3.6.1.2.1.2.2.1.2.6 = STRING: GigabitEthernet0 .1.3.6.1.2.1.2.2.1.5.3 = Gauge32: 4294967295 A packet capture, obtained while running the snmpget. For example: sudo tcpdump -s 0 -i eth0 -w foo.pcap host 203.50.251.17 and port 161 Running the Tests ----------------- Tests are grouped as follows: * Unit tests (validating data packing and marshalling): * `marshal_test.go` * `misc_test.go` * Public API consistency tests: * `gosnmp_api_test.go` * End-to-end integration tests: * `generic_e2e_test.go` * `verax_test.go` The generic end-to-end integration test `generic_e2e_test.go` should work against any SNMP MIB-2 compliant host (e.g. a router, NAS box, printer). To use, edit your host file so `gosnmp-test-host` resolves to the system's IP. The other integration test uses the **Verax Snmp Simulator** [1]: download, install and run it with the default configuration. Then, in the gosnmp directory, run these commands (or equivalents for your system): cd ~/go/src/github.com/soniah/gosnmp ln -s /usr/local/vxsnmpsimulator/device device # remove randomising elements from Verax device files cd device/cisco sed -i -e 's!\/\/\$.*!!' -e 's!^M!!' cisco_router.txt sed -i -e 's/\/\/\^int.unq()\^\/\//2/' cisco_router.txt cd ../os sed -i -e 's!\/\/\$.*!!' -e 's!^M!!' os-linux-std.txt sed -i -e 's/\/\/\^int.unq()\^\/\//2/' os-linux-std.txt cd ~/go/src/github.com/soniah/gosnmp go test To run only the Verax tests: go test -run TestVeraxGet 2>&1 | less I have noticed that the Verax tests randomly fail when using multi-OID Get() requests. I believe these bugs come from Verax not GoSNMP. To run non-Verax tests: % grep -h '^func.*Test' *test.go func TestEnmarshalVarbind(t *testing.T) { func TestEnmarshalVBL(t *testing.T) { ... <snip> # for example go test -run TestEnmarshalMsg # or use the helpful shell script ./non-verax-tests.sh To profile cpu usage: go test -cpuprofile cpu.out go test -c go tool pprof gosnmp.test cpu.out To profile memory usage: go test -memprofile mem.out go test -c go tool pprof gosnmp.test mem.out To check test coverage: go get github.com/axw/gocov/gocov go get github.com/matm/gocov-html gocov test github.com/soniah/gosnmp | gocov-html > gosnmp.html && firefox gosnmp.html & [1] http://www.veraxsystems.com/en/products/snmpsimulator License ------- Some parts of the code are borrowed by the Golang project (specifically some functions for unmarshaling BER responses), which are under the same terms and conditions as the Go language. The rest of the code is under a BSD license. See the LICENSE file for more details.
Documentation ¶
Index ¶
- Constants
- Variables
- func Partition(current_position, partition_size, slice_length int) bool
- func ToBigInt(value interface{}) *big.Int
- type Asn1BER
- type BitStringValue
- type GoSNMP
- func (x *GoSNMP) BulkWalk(rootOid string, walkFn WalkFunc) error
- func (x *GoSNMP) BulkWalkAll(rootOid string) (results []SnmpPDU, err error)
- func (x *GoSNMP) Connect() error
- func (x *GoSNMP) Get(oids []string) (result *SnmpPacket, err error)
- func (x *GoSNMP) GetBulk(oids []string, non_repeaters uint8, max_repetitions uint8) (result *SnmpPacket, err error)
- func (x *GoSNMP) GetNext(oids []string) (result *SnmpPacket, err error)
- func (x *GoSNMP) Set(pdus []SnmpPDU) (result *SnmpPacket, err error)
- func (x *GoSNMP) Walk(rootOid string, walkFn WalkFunc) error
- func (x *GoSNMP) WalkAll(rootOid string) (results []SnmpPDU, err error)
- type Logger
- type PDUType
- type SnmpPDU
- type SnmpPacket
- type SnmpVersion
- type VarBind
- type Variable
- type WalkFunc
Constants ¶
const ( EndOfContents Asn1BER = 0x00 UnknownType = 0x00 Boolean = 0x01 Integer = 0x02 BitString = 0x03 OctetString = 0x04 Null = 0x05 ObjectIdentifier = 0x06 ObjectDescription = 0x07 IpAddress = 0x40 Counter32 = 0x41 Gauge32 = 0x42 TimeTicks = 0x43 Opaque = 0x44 NsapAddress = 0x45 Counter64 = 0x46 Uinteger32 = 0x47 NoSuchObject = 0x80 NoSuchInstance = 0x81 EndOfMibView = 0x82 )
const ( Sequence PDUType = 0x30 GetRequest PDUType = 0xa0 GetNextRequest = 0xa1 GetResponse = 0xa2 SetRequest = 0xa3 Trap = 0xa4 GetBulkRequest = 0xa5 )
const (
// MAX_OIDS is the maximum number of oids allowed in a Get()
MAX_OIDS = 60
)
Variables ¶
Functions ¶
func Partition ¶ added in v1.2.0
Partition - returns true when dividing a slice into partition_size lengths, including last partition which may be smaller than partition_size. This is useful when you have a large array of OIDs to run Get() on. See the tests for example usage.
For example for a slice of 8 items to be broken into partitions of length 3, Partition returns true for the current_position having the following values:
0 1 2 3 4 5 6 7
T T T
func ToBigInt ¶
ToBigInt converts SnmpPDU.Value to big.Int, or returns a zero big.Int for non int-like types (eg strings).
This is a convenience function to make working with SnmpPDU's easier - it reduces the need for type assertions. A big.Int is convenient, as SNMP can return int32, uint32, and uint64.
Types ¶
type BitStringValue ¶
type BitStringValue struct { Bytes []byte // bits packed into bytes. BitLength int // length in bits. }
BitStringValue is the structure to use when you want an ASN.1 BIT STRING type. A bit string is padded up to the nearest byte in memory and the number of valid bits is recorded. Padding bits will be zero.
func (BitStringValue) At ¶
func (b BitStringValue) At(i int) int
At returns the bit at the given index. If the index is out of range it returns false.
func (BitStringValue) RightAlign ¶
func (b BitStringValue) RightAlign() []byte
RightAlign returns a slice where the padding bits are at the beginning. The slice may share memory with the BitString.
type GoSNMP ¶
type GoSNMP struct { // Target is an ipv4 address Target string // Port is a udp port Port uint16 // Community is an SNMP Community string Community string // Version is an SNMP Version Version SnmpVersion // Timeout is the timeout for the SNMP Query Timeout time.Duration // Set the number of retries to attempt within timeout. Retries int // Conn is net connection to use, typically establised using GoSNMP.Connect() Conn net.Conn // Logger is the GoSNMP.Logger to use for debugging. If nil, debugging // output will be discarded (/dev/null). For verbose logging to stdout: // x.Logger = log.New(os.Stdout, "", 0) Logger Logger // contains filtered or unexported fields }
func (*GoSNMP) BulkWalk ¶ added in v1.3.0
BulkWalk retrieves a subtree of values using GETBULK. As the tree is walked walkFn is called for each new value. The function immediately returns an error if either there is an underlaying SNMP error (e.g. GetBulk fails), or if walkFn returns an error.
func (*GoSNMP) BulkWalkAll ¶ added in v1.3.0
Similar to BulkWalk but returns a filled array of all values rather than using a callback function to stream results.
func (*GoSNMP) Get ¶
func (x *GoSNMP) Get(oids []string) (result *SnmpPacket, err error)
Send an SNMP GET request
func (*GoSNMP) GetBulk ¶ added in v1.2.0
func (x *GoSNMP) GetBulk(oids []string, non_repeaters uint8, max_repetitions uint8) (result *SnmpPacket, err error)
send an SNMP GETBULK request
func (*GoSNMP) GetNext ¶ added in v1.2.0
func (x *GoSNMP) GetNext(oids []string) (result *SnmpPacket, err error)
Send an SNMP GETNEXT request
func (*GoSNMP) Set ¶ added in v1.2.0
func (x *GoSNMP) Set(pdus []SnmpPDU) (result *SnmpPacket, err error)
Send an SNMP SET request
func (*GoSNMP) Walk ¶
Walk retrieves a subtree of values using GETNEXT - a request is made for each value, unlike BulkWalk which does this operation in batches. As the tree is walked walkFn is called for each new value. The function immediately returns an error if either there is an underlaying SNMP error (e.g. GetNext fails), or if walkFn returns an error.
type Logger ¶ added in v1.2.0
type Logger interface { Print(v ...interface{}) Printf(format string, v ...interface{}) }
type SnmpPDU ¶
type SnmpPDU struct { // Name is an oid in string format eg "1.3.6.1.4.9.27" Name string // The type of the value eg Integer Type Asn1BER // The value to be set by the SNMP set Value interface{} }
SnmpPDU will be used when doing SNMP Set's
type SnmpPacket ¶
type SnmpVersion ¶
type SnmpVersion uint8
const ( Version1 SnmpVersion = 0x0 Version2c SnmpVersion = 0x1 )
func (SnmpVersion) String ¶
func (s SnmpVersion) String() string