wapsnmp

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2023 License: Apache-2.0 Imports: 9 Imported by: 19

README

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.

Documentation

Overview

Package wapsnmp provides an SNMP query library.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeInteger

func DecodeInteger(toparse []byte) (int64, error)

DecodeInteger decodes an integer.

Will error out if it's longer than 64 bits.

func DecodeLength

func DecodeLength(toparse []byte) (uint64, int, error)

DecodeLength returns the length and the length of the length or an error.

Caveats: Does not support indefinite length. Couldn't find any SNMP packet dump actually using that.

func DecodeSequence

func DecodeSequence(toparse []byte) ([]interface{}, error)

DecodeSequence decodes BER binary data into into *[]interface{}.

func DecodeUInt

func DecodeUInt(toparse []byte) (uint64, error)

DecodeUInt decodes an unsigned int.

Will error out if it's longer than 64 bits.

func EncodeInteger

func EncodeInteger(toEncode int64) []byte

EncodeInteger encodes an integer to BER format.

func EncodeLength

func EncodeLength(length uint64) []byte

EncodeLength encodes an integer value as a BER compliant length value.

func EncodeSequence

func EncodeSequence(toEncode []interface{}) ([]byte, error)

EncodeSequence will encode an []interface{} into an SNMP bytestream.

func EncodeUInt

func EncodeUInt(toEncode uint64) []byte

EncodeUInt encodes an unsigned integer to BER format.

func RandomRequestID

func RandomRequestID() int

RandomRequestID generates a valid SNMP request ID.

Types

type BERType

type BERType uint8

BERType is a type for Type of the TLV field.

const (
	AsnBoolean     BERType = 0x01
	AsnInteger     BERType = 0x02
	AsnBitStr      BERType = 0x03
	AsnOctetStr    BERType = 0x04
	AsnNull        BERType = 0x05
	AsnObjectID    BERType = 0x06
	AsnSequence    BERType = 0x10
	AsnSet         BERType = 0x11
	AsnUniversal   BERType = 0x00
	AsnApplication BERType = 0x40
	AsnContext     BERType = 0x80
	AsnPrivate     BERType = 0xC0
	AsnPrimitive   BERType = 0x00
	AsnConstructor BERType = 0x20

	AsnLongLen     BERType = 0x80
	AsnExtensionID BERType = 0x1F
	AsnBit8        BERType = 0x80

	Integer     BERType = AsnUniversal | 0x02
	Integer32   BERType = AsnUniversal | 0x02
	Bitstring   BERType = AsnUniversal | 0x03
	Octetstring BERType = AsnUniversal | 0x04
	Null        BERType = AsnUniversal | 0x05
	UOid        BERType = AsnUniversal | 0x06
	Sequence    BERType = AsnConstructor | 0x10

	AsnIpaddress BERType = AsnApplication | 0x00
	AsnCounter   BERType = AsnApplication | 0x01
	AsnCounter32 BERType = AsnApplication | 0x01
	AsnGauge     BERType = AsnApplication | 0x02
	AsnGauge32   BERType = AsnApplication | 0x02
	AsnTimeticks BERType = AsnApplication | 0x03
	Opaque       BERType = AsnApplication | 0x04
	AsnCounter64 BERType = AsnApplication | 0x06

	AsnGetRequest     BERType = 0xa0
	AsnGetNextRequest BERType = 0xa1
	AsnGetResponse    BERType = 0xa2
	AsnSetRequest     BERType = 0xa3
	AsnGetBulkRequest BERType = 0xa5
	AsnTrapV2         BERType = 0xa7

	NoSuchInstance BERType = 0x81
	EndOfMibView   BERType = 0x82
)

Constants for the different types of the TLV fields.

type Counter

type Counter uint32

Counter is a type to distinguish Counter32 from just an int.

type Counter64

type Counter64 uint64

Counter64 is a type to distinguish Counter64 from just an int.

type Gauge

type Gauge uint32

Gauge is a type to distinguish Gauge32 from just an int.

type Gauge64

type Gauge64 uint64

Gauge64 is a type to distinguish Gauge64 from just an int.

type Oid

type Oid []int

Oid is the SNMP object identifier type.

func DecodeOid

func DecodeOid(raw []byte) (*Oid, error)

DecodeOid decodes a ASN.1 BER raw oid into an Oid instance.

func MustParseOid

func MustParseOid(o string) Oid

MustParseOid parses a string oid to an Oid instance. Panics on error.

func ParseOid

func ParseOid(oid string) (Oid, error)

ParseOid a text format oid into an Oid instance.

func (Oid) Copy

func (o Oid) Copy() Oid

Copy copies an oid into a new object instance.

func (Oid) Encode

func (o Oid) Encode() ([]byte, error)

Encode encodes the oid into an ASN.1 BER byte array.

func (Oid) String

func (o Oid) String() string

String returns the string representation for this oid object.

func (Oid) Within

func (o Oid) Within(other Oid) bool

Within determines if an oid has this oid instance as a prefix.

E.g. MustParseOid("1.2.3").Within(MustParseOid("1.2")) => true.

type SNMPValue

type SNMPValue struct {
	Oid   Oid
	Value interface{}
}

SNMPValue type to express an oid value pair.

type SNMPVersion

type SNMPVersion uint8

SNMPVersion is a type to indicate which SNMP version is in use.

const (
	SNMPv1  SNMPVersion = 0
	SNMPv2c SNMPVersion = 1
)

List of the supported snmp versions.

type UnsupportedBerType

type UnsupportedBerType []byte

UnsupportedBerType will be used if data couldn't be decoded.

type WapSNMP

type WapSNMP struct {
	Target    string      // Target device for these SNMP events.
	Community string      // Community to use to contact the device.
	Version   SNMPVersion // SNMPVersion to encode in the packets.
	// contains filtered or unexported fields
}

WapSNMP is the type that lets you do SNMP requests.

func NewWapSNMP

func NewWapSNMP(target, community string, version SNMPVersion, timeout time.Duration, retries int) (*WapSNMP, error)

NewWapSNMP creates a new WapSNMP object. Opens a udp connection to the device that will be used for the SNMP packets.

func NewWapSNMPOnConn

func NewWapSNMPOnConn(target, community string, version SNMPVersion, timeout time.Duration, retries int, conn net.Conn) *WapSNMP

NewWapSNMPOnConn creates a new WapSNMP object from an existing net.Conn.

It does not check if the provided target is valid.

func (WapSNMP) Close

func (w WapSNMP) Close() error

Close the net.conn in WapSNMP.

func (WapSNMP) Get

func (w WapSNMP) Get(oid Oid) (interface{}, error)

Get sends an SNMP get request requesting the value for an oid.

Example
target := "1.2.3.4"
community := "public"
version := SNMPv2c

oids := []Oid{
	MustParseOid(".1.3.6.1.2.1.1.1.0"),
	MustParseOid(".1.3.6.1.2.1.1.2.0"),
	MustParseOid(".1.3.6.1.2.1.2.1.0"),
}

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
}

for _, oid := range oids {
	val, err := wsnmp.Get(oid)
	fmt.Printf("Getting %v\n", oid)
	if err != nil {
		fmt.Printf("Get error => %v\n", wsnmp)
		return
	}
	fmt.Printf("Get(%v, %v, %v, %v) => %v\n", target, community, version, oid, val)
}
Output:

func (WapSNMP) GetBulk

func (w WapSNMP) GetBulk(oid Oid, maxRepetitions int) (map[string]interface{}, error)

GetBulk is semantically the same as maxRepetitions getnext requests, but in a single GETBULK SNMP packet.

Caveat: many devices will silently drop GETBULK requests for more than some number of maxrepetitions, if it doesn't work, try with a lower value and/or use GetTable.

Caveat: as codedance (on github) pointed out, iteration order on a map is indeterminate. You can alternatively use GetBulkArray to get the entries as a list, with deterministic iteration order.

Example
target := "1.2.3.4"
community := "public"
version := SNMPv2c

oid := MustParseOid(".1.3.6.1.2.1")

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
}
defer wsnmp.Close()
for {
	results, err := wsnmp.GetBulk(oid, 50)
	if err != nil {
		fmt.Printf("GetBulk error => %v\n", err)
		return
	}
	for o, v := range results {
		fmt.Printf("%v => %v\n", o, v)

		oid = MustParseOid(o)
	}
	/*  Old version without GETBULK
	    result_oid, val, err := wsnmp.GetNext(oid)
	    if err != nil {
	      fmt.Printf("GetNext error => %v\n", err)
	      return
	    }
	    fmt.Printf("GetNext(%v, %v, %v, %v) => %s, %v\n", target, community, version, oid, result_oid, val)
	    oid = *result_oid
	*/
}
Output:

func (WapSNMP) GetBulkArray

func (w WapSNMP) GetBulkArray(oid Oid, maxRepetitions int) ([]SNMPValue, error)

GetBulkArray is the same as GetBulk, but returns it's results as a list, for those who want deterministic iteration instead of convenient access.

func (WapSNMP) GetMultiple

func (w WapSNMP) GetMultiple(oids []Oid) (map[string]interface{}, error)

GetMultiple issues a single GET SNMP request requesting multiple values

func (WapSNMP) GetNext

func (w WapSNMP) GetNext(oid Oid) (*Oid, interface{}, error)

GetNext issues a GETNEXT SNMP request.

func (WapSNMP) GetTable

func (w WapSNMP) GetTable(oid Oid) (map[string]interface{}, error)

GetTable efficiently gets an entire table from an SNMP agent. Uses GETBULK requests to go fast.

Example
target := "1.2.3.4"
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)
}
Output:

func (WapSNMP) Set

func (w WapSNMP) Set(oid Oid, value interface{}) (interface{}, error)

Set sends an SNMP set request to change the value associated with an oid.

func (WapSNMP) SetMultiple

func (w WapSNMP) SetMultiple(toset map[string]interface{}) (map[string]interface{}, error)

SetMultiple issues a single GET SNMP request requesting multiple values

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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