Giter Club home page Giter Club logo

wapsnmp's Introduction

WapSnmp : SNMP client for golang

This is an open-source SNMP client library for Go. This allows you to query SNMP servers for any variable, given it's OID (no MIB resolution). It is released under the Apache 2.0 licence.

This library has been written to be in Go style and that means it should be very resistent to all error conditions. It's entirely non-blocking/asynchronous and very, very fast. It's also surprisingly small and easy to understand. Excellent test coverage is provided.

It supports the following SNMP operations:

  • Get
  • GetMultiple
  • Set
  • SetMultiple
  • GetNext
  • GetBulk
  • GetTable (use getBulk to get an entire subtree)

All of these are implemented with timeout support, and correct error/retry handling.

It supports SNMPv2c or lower (not 3, due to it's complexity), and supports all methods provided as part of that standard. Get, GetMultiple (which are really the same request, but ...), GetNext and GetBulk.

It has been tested on juniper and cisco devices and has proven to remain stable over long periods of time.

Example usage of the library:

func DoGetTableTest(target string) {
      community := "public"
      version := SNMPv2c

      oid := MustParseOid(".1.3.6.1.4.1.2636.3.2.3.1.20")

      fmt.Printf("Contacting %v %v %v\n", target, community, version)
      wsnmp, err := NewWapSNMP(target, community, version, 2*time.Second, 5)
      defer wsnmp.Close()
      if err != nil {
              fmt.Printf("Error creating wsnmp => %v\n", wsnmp)
              return
      }

      table, err := wsnmp.GetTable(oid)
      if err != nil {
              fmt.Printf("Error getting table => %v\n", wsnmp)
              return
      }
      for k, v := range table {
              fmt.Printf("%v => %v\n", k, v)
      }
}

This library can also be used as a ASN1 BER parser.

The library has native support for a whole lot of SNMP types :

  • Boolean
  • Integer
  • OctetString (string)
  • Oids
  • Null
  • Counter32
  • Counter64
  • Gauge32
  • TimeTicks
  • EndOfMibView

And this should be easy to expand.

wapsnmp's People

Contributors

cdevr avatar minusnine avatar subito avatar icholy avatar zielu avatar

Stargazers

池边树下 avatar Scot Bontrager avatar  avatar blueice avatar Caliban-li avatar Siger Yang avatar  avatar Doru Carastan avatar  avatar  avatar gaokens avatar  avatar Denys Sedchenko avatar kkkmmu avatar Swarvanu Sengupta avatar Mohan Prasath avatar Dragos Varovici avatar Yang Huan avatar Dmitry avatar  avatar Jeff Li avatar Kevin Golding avatar heidsoft avatar Michel Beloshitsky avatar Jim avatar hiro.suzuki avatar domacHQ avatar Yuanteng (Jeff) Pei avatar Michael Davies avatar Lucas Bremgartner avatar Thibault NORMAND avatar Mat Evans avatar wahaha88 avatar Matt Vinall avatar Emmaly avatar  avatar Nachi Ueno avatar Steve Shaw avatar LzmCoding avatar Railsmechanic avatar  avatar Mark deVilliers avatar Ondrej Fabry avatar deknos avatar mitchell amihod avatar Robert K avatar Bai Long avatar Chris Gambrell avatar Ben Ritcey avatar Fedor V avatar Kevin McDonald avatar Max Kamashev avatar Sung-jin Brian Hong avatar  avatar Paulo Pereira avatar Luke Kalbfleisch avatar Satish Puranam avatar Andrew Griffin avatar Nathan Owens avatar  avatar  avatar  avatar Will Pierce avatar Mordy Ovits avatar sgn avatar Ilia Gavrilin avatar Sebastian Schuler avatar  avatar forrest.sun avatar Hroi Sigurdsson avatar Athanasios Douitsis avatar Sam Freiberg avatar Ingo Oeser avatar Nick Craig-Wood avatar Arne Hormann avatar

Watchers

Athanasios Douitsis avatar  avatar James Cloos avatar blueice avatar Allen Flickinger avatar  avatar Mordy Ovits avatar  avatar  avatar  avatar Scot Bontrager avatar billy avatar  avatar

wapsnmp's Issues

type 65 not recognized

When trying to GetTable() with oid: 1.3.6.1.2.1.31.1.1.1.1 on a cisco WS-C3560G-48PS-S, I get an error stating that type 65 is not recognized.

I looked up type 65 (0x41) or Counter32 and found that it is basically an unsigned int that increases monotonically.

Adding the following case to DecodeSequence() seems to give me correct values, but I don't think it is a "correct" solution. I know very little about BER
case Counter32:
decodedValue, err := DecodeInteger(berValue)
if err != nil {
return nil, err
}
result = append(result, decodedValue)

Thank's for the great library!

Calls to Poll use fixed timeout

Hi there,

In looking at the code, I see that the calls to Poll from Get in snmp.go use a 500ms fixed timeout. Has this been found to be a good value, or would it make sense to pass the users provided timeout in NewWapSNMP?

Thanks,
Nathan

Using WSDL files for description methods

In our SNMP server we using WSDL file for description all methods and resources.
We store this file is local.
Can I use local WSDL file for generation methods our SNMP server?

License info

Hello,

Could you specify under what license the code is being released?

Great work by the way!

Counter64 Support

Hello,

The library doesn't seem to support 64-bit counters such as those in the ifXTable: http://tools.cisco.com/Support/SNMP/do/BrowseOID.do?local=en&translate=Translate&objectInput=1.3.6.1.2.1.31.1.1.1

I have taken a look at DecodeSequence in ber.go and have added the following to the BERType table to make it work:

        case AsnCounter64:
            val, err := DecodeUInt(berValue)
            if err != nil {
                return nil, fmt.Errorf("error decoding integer %v: %v", berValue, err)
            }
            result = append(result, Counter64(val))

Why is the OID required to start with .1.3?

.I have a use-case where I need to lookup .1.0.8802 OIDs - they are perfectly fine and work, but I can't use them with your library.

If I remove the check, the requests seem to work, but all I get for a response is a "did not understand type 128" which looks like "No Instance found" - but there is an instance for sure, because if I look it up using snmpget it returns a STRING.

EncodeInteger/EncodeUint Issue

Looks like EncodeInteger and EncodeUint produce the wrong byte array for some values.

Example:
encodedID := wapsnmp.EncodeInteger(int64(16495265))
// encodedID = [251 178 161]
// should be [0 251 178 161]

This causes the value to be decoded as -281951 instead of 16495265.

Here are some more.

RequestID Encoded Decoded
16495265 [251 178 161] -281951
9544834 [145 164 130] -7232382
10479253 [159 230 149] -6297963
14231300 [217 39 4] -2545916
16167221 [246 177 53] -609995
9640701 [147 26 253] -7136515
16474587 [251 97 219] -302629
11990425 [182 245 153] -4786791
9237227 [140 242 235] -7539989

udp_stub_connection.go and flag.PrintDefaults()

When the udp_stub_connection.go file exists flag.PrintDefaults will add test parameters on output.
Maybe because of udpStub struct ?

$ ./mysnmp -h
Usage of ./mysnmp:
-host="": host
-test.bench="": regular expression to select benchmarks to run
-test.benchmem=false: print memory allocations for benchmarks
-test.benchtime=1s: approximate run time for each benchmark
....

Issue with negative Oid values

A value like -91 (as reported by snmpget) returns as 16777125 in WapSNMP.

I havent found the cause yet, but i'll do a pull request if i find it.

buffer error?

Good day.

I have a strange error.

This part of the code:

hardwareInfo,herr := SnmpServer.GetTable([]int{1,3,6,1,2,1,47,1,1,1,1,2})
if herr != nil {
fmt.Printf("Error getting table => %v\n", SnmpServer)
return
}
for currentOID, currentData := range hardwareInfo {
fmt.Printf("Current: %s -> %s\n",currentOID,currentData)
if result,:=regexp.MatchString("^X[0-9][0-9][0-9].*", currentData.(string));result {
hoid,
:=strconv.Atoi(regexp.MustCompile("[0-9]+$").FindString(currentOID))
fmt.Printf("Found: %s -> %s\n",currentOID,currentData)
fmt.Printf("Get: %s%d\n","1.3.6.1.2.1.47.1.1.1.1.11.",hoid)
serialInfo,_:=SnmpServer.Get([]int{1,3,6,1,2,1,47,1,1,1,1,11,hoid})
fmt.Printf("%T : %v\n",serialInfo,serialInfo)
}
}

I run my program twice without recompiling, and:
Output log:

./getequipment

2015/02/19 10:37:45 Couldn't read. Retrying. Retry 0/5
Current: .1.3.6.1.2.1.47.1.1.1.1.2.1 -> X670-48x
Found: .1.3.6.1.2.1.47.1.1.1.1.2.1 -> X670-48x
Get: 1.3.6.1.2.1.47.1.1.1.1.11.1
2015/02/19 10:37:48 Couldn't read. Retrying. Retry 0/5
string : 1215G-02547
Current: .1.3.6.1.2.1.47.1.1.1.1.2.2 -> PowerSupply Slot-1
Current: .1.3.6.1.2.1.47.1.1.1.1.2.3 -> PowerSupply-Internal
Current: .1.3.6.1.2.1.47.1.1.1.1.2.4 -> PowerSupply Slot-2
Current: .1.3.6.1.2.1.47.1.1.1.1.2.5 -> PowerSupply-External
Current: .1.3.6.1.2.1.47.1.1.1.1.2.6 -> FanTray

./getequipment

2015/02/19 10:37:52 Couldn't read. Retrying. Retry 0/5
Current: .1.3.6.1.2.1.47.1.1.1.1.2.1 -> X670-48x
Found: .1.3.6.1.2.1.47.1.1.1.1.2.1 -> X670-48x
Get: 1.3.6.1.2.1.47.1.1.1.1.11.1
2015/02/19 10:37:55 Couldn't read. Retrying. Retry 0/5
string : X670-48x
Current: .1.3.6.1.2.1.47.1.1.1.1.2.2 -> PowerSupply Slot-1
Current: .1.3.6.1.2.1.47.1.1.1.1.2.3 -> PowerSupply-Internal
Current: .1.3.6.1.2.1.47.1.1.1.1.2.4 -> PowerSupply Slot-2
Current: .1.3.6.1.2.1.47.1.1.1.1.2.5 -> PowerSupply-External
Current: .1.3.6.1.2.1.47.1.1.1.1.2.6 -> FanTray

When I see the serial number - it is right. But it happens once in ten.
Your code is very beautiful and simple, but I do not see the error.

Various bugs/issues for discussion

Hi Christope,

I’ve taken a quick look at the WapSNMP code and have found a few issues you may wish to take a look at:

1) ber.go - DecodeSequence

Problem: If the sequence contains EndOfMibView, an error is thrown and no values are returned. This error in turn will bubble up causing a whole GetTable or GetBulk call to fail.

Suggestion: Return EndOfMibView as a type like other types.

2) ber.go - DecodeSequence

Problem: Similar to above, hitting an unknown type at any point in a sequence, table scan, or GetMulitple will cause an error and it’s not possible to read any returned data.

Suggestion: Return an “Unsupported” type as a value, and continue, rather than raising an error at this low level. Callers can then handle on an individual OID basis as they see fit.

3) oid.go - DecodeOid

Problem: The test len(raw) < 2 is not correct. A zero length, or 0x00 (zero) OID is valid. This code failed when doing table scans on a few real world devices (e.g. Routers, NAS Servers, etc.).

Suggestion: return &Oid{}, nil

4) snmp.go - GetTable

Problem: The logic in GetTable seems to be faulty. The code to determine newLastOid assume the interaction order on the results map is deterministic. newLastOid will not be the numeric last oid, but instead a random OID (see iteration order). This bug causes very slow table walk because of overlapping pages are requested, and worse, it will randomly silently fail as there is a chance that lastOid == newLastOid.

Suggestion: I don’t think map[string] is the best data structure for this purpose. An ordered array of struct{OID, Value} may be a better choice, however this change would mean breaking the API. A non-braking solution would be to write your own ordering logic to determine the last OID (but this will be slower).

5) utils/goTable.go
Problem: There seems to be a minor case issue:

-       version := wapSnmp.SNMPv2c
+       version := wapsnmp.SNMPv2c

-       oid, err := wapSnmp.ParseOid(*oidasstring)
+       oid, err := wapsnmp.ParseOid(*oidasstring)

I’d welcome your thoughts/comments on these issues, and if appropriate I can propose some fixes and/or work with you to test.

Thanks for your hard work and making SNMP first-class in Go!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.