refactor: snmp to use gosmi (#9518)

This commit is contained in:
Mya 2021-11-30 15:47:50 -07:00 committed by GitHub
parent c875e45422
commit 7675ce6d19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 7576 additions and 810 deletions

View File

@ -10,6 +10,8 @@ type ClientConfig struct {
Retries int `toml:"retries"`
// Values: 1, 2, 3
Version uint8 `toml:"version"`
// Path to mib files
Path []string `toml:"path"`
// Parameters for Version 1 & 2
Community string `toml:"community"`

188
internal/snmp/translate.go Normal file
View File

@ -0,0 +1,188 @@
package snmp
import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"github.com/influxdata/telegraf"
"github.com/sleepinggenius2/gosmi"
"github.com/sleepinggenius2/gosmi/types"
)
// must init, append path for each directory, load module for every file
// or gosmi will fail without saying why
var m sync.Mutex
func LoadMibsFromPath(paths []string, log telegraf.Logger) error {
m.Lock()
defer m.Unlock()
gosmi.Init()
var folders []string
for _, mibPath := range paths {
gosmi.AppendPath(mibPath)
folders = append(folders, mibPath)
err := filepath.Walk(mibPath, func(path string, info os.FileInfo, err error) error {
// symlinks are files so we need to double check if any of them are folders
// Will check file vs directory later on
if info.Mode()&os.ModeSymlink != 0 {
link, err := os.Readlink(path)
if err != nil {
log.Warnf("Bad symbolic link %v", link)
}
folders = append(folders, link)
}
return nil
})
if err != nil {
return fmt.Errorf("Filepath could not be walked %v", err)
}
for _, folder := range folders {
err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
// checks if file or directory
if info.IsDir() {
gosmi.AppendPath(path)
} else if info.Mode()&os.ModeSymlink == 0 {
_, err := gosmi.LoadModule(info.Name())
if err != nil {
log.Warnf("Module could not be loaded %v", err)
}
}
return nil
})
if err != nil {
return fmt.Errorf("Filepath could not be walked %v", err)
}
}
folders = []string{}
}
return nil
}
// The following is for snmp_trap
type MibEntry struct {
MibName string
OidText string
}
func TrapLookup(oid string) (e MibEntry, err error) {
var node gosmi.SmiNode
node, err = gosmi.GetNodeByOID(types.OidMustFromString(oid))
// ensure modules are loaded or node will be empty (might not error)
if err != nil {
return e, err
}
e.OidText = node.RenderQualified()
i := strings.Index(e.OidText, "::")
if i == -1 {
return e, fmt.Errorf("not found")
}
e.MibName = e.OidText[:i]
e.OidText = e.OidText[i+2:]
return e, nil
}
// The following is for snmp
func GetIndex(oidNum string, mibPrefix string) (col []string, tagOids map[string]struct{}, err error) {
// first attempt to get the table's tags
tagOids = map[string]struct{}{}
// mimcks grabbing INDEX {} that is returned from snmptranslate -Td MibName
node, err := gosmi.GetNodeByOID(types.OidMustFromString(oidNum))
if err != nil {
return []string{}, map[string]struct{}{}, fmt.Errorf("getting submask: %w", err)
}
for _, index := range node.GetIndex() {
//nolint:staticcheck //assaignment to nil map to keep backwards compatibilty
tagOids[mibPrefix+index.Name] = struct{}{}
}
// grabs all columns from the table
// mimmicks grabbing everything returned from snmptable -Ch -Cl -c public 127.0.0.1 oidFullName
col = node.GetRow().AsTable().ColumnOrder
return col, tagOids, nil
}
//nolint:revive //Too many return variable but necessary
func SnmpTranslateCall(oid string) (mibName string, oidNum string, oidText string, conversion string, err error) {
var out gosmi.SmiNode
var end string
if strings.ContainsAny(oid, "::") {
// split given oid
// for example RFC1213-MIB::sysUpTime.0
s := strings.Split(oid, "::")
// node becomes sysUpTime.0
node := s[1]
if strings.ContainsAny(node, ".") {
s = strings.Split(node, ".")
// node becomes sysUpTime
node = s[0]
end = "." + s[1]
}
out, err = gosmi.GetNode(node)
if err != nil {
return oid, oid, oid, oid, err
}
oidNum = "." + out.RenderNumeric() + end
} else if strings.ContainsAny(oid, "abcdefghijklnmopqrstuvwxyz") {
//handle mixed oid ex. .iso.2.3
s := strings.Split(oid, ".")
for i := range s {
if strings.ContainsAny(s[i], "abcdefghijklmnopqrstuvwxyz") {
out, err = gosmi.GetNode(s[i])
if err != nil {
return oid, oid, oid, oid, err
}
s[i] = out.RenderNumeric()
}
}
oidNum = strings.Join(s, ".")
out, _ = gosmi.GetNodeByOID(types.OidMustFromString(oidNum))
} else {
out, err = gosmi.GetNodeByOID(types.OidMustFromString(oid))
oidNum = oid
// ensure modules are loaded or node will be empty (might not error)
// do not return the err as the oid is numeric and telegraf can continue
//nolint:nilerr
if err != nil || out.Name == "iso" {
return oid, oid, oid, oid, nil
}
}
tc := out.GetSubtree()
for i := range tc {
// case where the mib doesn't have a conversion so Type struct will be nil
// prevents seg fault
if tc[i].Type == nil {
break
}
switch tc[i].Type.Name {
case "MacAddress", "PhysAddress":
conversion = "hwaddr"
case "InetAddressIPv4", "InetAddressIPv6", "InetAddress", "IPSIpAddress":
conversion = "ipaddr"
}
}
oidText = out.RenderQualified()
i := strings.Index(oidText, "::")
if i == -1 {
return "", oid, oid, oid, fmt.Errorf("not found")
}
mibName = oidText[:i]
oidText = oidText[i+2:] + end
return mibName, oidNum, oidText, conversion, nil
}

View File

@ -4,19 +4,10 @@ The `snmp` input plugin uses polling to gather metrics from SNMP agents.
Support for gathering individual OIDs as well as complete SNMP tables is
included.
## Prerequisites
## Note about Paths
This plugin uses the `snmptable` and `snmptranslate` programs from the
[net-snmp][] project. These tools will need to be installed into the `PATH` in
order to be located. Other utilities from the net-snmp project may be useful
for troubleshooting, but are not directly used by the plugin.
These programs will load available MIBs on the system. Typically the default
directory for MIBs is `/usr/share/snmp/mibs`, but if your MIBs are in a
different location you may need to make the paths known to net-snmp. The
location of these files can be configured in the `snmp.conf` or via the
`MIBDIRS` environment variable. See [`man 1 snmpcmd`][man snmpcmd] for more
information.
Path is a global variable, separate snmp instances will append the specified
path onto the global path variable
## Configuration
@ -38,6 +29,9 @@ information.
## SNMP version; can be 1, 2, or 3.
# version = 2
## Path to mib files
# path = ["/usr/share/snmp/mibs"]
## SNMP community string.
# community = "public"
@ -260,7 +254,7 @@ oid = "CISCO-POWER-ETHERNET-EXT-MIB::cpeExtPsePortEntPhyIndex"
Partial result (removed agent_host and host columns from all following outputs in this section):
```shell
```text
> ciscoPower,index=1.2 EntPhyIndex=1002i,PortPwrConsumption=6643i 1621460628000000000
> ciscoPower,index=1.6 EntPhyIndex=1006i,PortPwrConsumption=10287i 1621460628000000000
> ciscoPower,index=1.5 EntPhyIndex=1005i,PortPwrConsumption=8358i 1621460628000000000
@ -313,7 +307,7 @@ is_tag = true
Result:
```shell
```text
> ciscoPowerEntity,EntPhysicalName=GigabitEthernet1/2,index=1.2 EntPhyIndex=1002i,PortPwrConsumption=6643i 1621461148000000000
> ciscoPowerEntity,EntPhysicalName=GigabitEthernet1/6,index=1.6 EntPhyIndex=1006i,PortPwrConsumption=10287i 1621461148000000000
> ciscoPowerEntity,EntPhysicalName=GigabitEthernet1/5,index=1.5 EntPhyIndex=1005i,PortPwrConsumption=8358i 1621461148000000000
@ -357,7 +351,5 @@ interface,agent_host=127.0.0.1,ifDescr=eth0,ifIndex=2,source=example.org ifAdmin
interface,agent_host=127.0.0.1,ifDescr=lo,ifIndex=1,source=example.org ifAdminStatus=1i,ifInDiscards=0i,ifInErrors=0i,ifInNUcastPkts=0i,ifInOctets=51555569i,ifInUcastPkts=339097i,ifInUnknownProtos=0i,ifLastChange=0i,ifMtu=65536i,ifOperStatus=1i,ifOutDiscards=0i,ifOutErrors=0i,ifOutNUcastPkts=0i,ifOutOctets=51555569i,ifOutQLen=0i,ifOutUcastPkts=339097i,ifSpecific=".0.0",ifSpeed=10000000i,ifType=24i 1575509815000000000
```
[net-snmp]: http://www.net-snmp.org/
[man snmpcmd]: http://net-snmp.sourceforge.net/docs/man/snmpcmd.html#lbAK
[metric filtering]: /docs/CONFIGURATION.md#metric-filtering
[metric]: /docs/METRICS.md

View File

@ -1,15 +1,11 @@
package snmp
import (
"bufio"
"bytes"
"encoding/binary"
"errors"
"fmt"
"log"
"math"
"net"
"os/exec"
"strconv"
"strings"
"sync"
@ -21,7 +17,6 @@ import (
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/internal/snmp"
"github.com/influxdata/telegraf/plugins/inputs"
"github.com/influxdata/wlog"
)
const description = `Retrieves SNMP values from remote agents`
@ -42,6 +37,9 @@ const sampleConfig = `
## SNMP version; can be 1, 2, or 3.
# version = 2
## Path to mib files
# path = ["/usr/share/snmp/mibs"]
## Agent host tag; the tag used to reference the source host
# agent_host_tag = "agent_host"
@ -70,36 +68,12 @@ const sampleConfig = `
# priv_protocol = ""
## Privacy password used for encrypted messages.
# priv_password = ""
## Add fields and tables defining the variables you wish to collect. This
## example collects the system uptime and interface variables. Reference the
## full plugin documentation for configuration details.
`
// execCommand is so tests can mock out exec.Command usage.
var execCommand = exec.Command
// execCmd executes the specified command, returning the STDOUT content.
// If command exits with error status, the output is captured into the returned error.
func execCmd(arg0 string, args ...string) ([]byte, error) {
if wlog.LogLevel() == wlog.DEBUG {
quoted := make([]string, 0, len(args))
for _, arg := range args {
quoted = append(quoted, fmt.Sprintf("%q", arg))
}
log.Printf("D! [inputs.snmp] executing %q %s", arg0, strings.Join(quoted, " "))
}
out, err := execCommand(arg0, args...).Output()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
return nil, fmt.Errorf("%s: %w", bytes.TrimRight(err.Stderr, "\r\n"), err)
}
return nil, err
}
return out, nil
}
// Snmp holds the configuration for the plugin.
type Snmp struct {
// The SNMP agent to query. Format is [SCHEME://]ADDR[:PORT] (e.g.
@ -120,12 +94,14 @@ type Snmp struct {
Fields []Field `toml:"field"`
connectionCache []snmpConnection
initialized bool
Log telegraf.Logger `toml:"-"`
}
func (s *Snmp) init() error {
if s.initialized {
return nil
func (s *Snmp) Init() error {
err := snmp.LoadMibsFromPath(s.Path, s.Log)
if err != nil {
return err
}
s.connectionCache = make([]snmpConnection, len(s.Agents))
@ -146,7 +122,6 @@ func (s *Snmp) init() error {
s.AgentHostTag = "agent_host"
}
s.initialized = true
return nil
}
@ -352,6 +327,7 @@ func init() {
MaxRepetitions: 10,
Timeout: config.Duration(5 * time.Second),
Version: 2,
Path: []string{"/usr/share/snmp/mibs"},
Community: "public",
},
}
@ -372,10 +348,6 @@ func (s *Snmp) Description() string {
// Any error encountered does not halt the process. The errors are accumulated
// and returned at the end.
func (s *Snmp) Gather(acc telegraf.Accumulator) error {
if err := s.init(); err != nil {
return err
}
var wg sync.WaitGroup
for i, agent := range s.Agents {
wg.Add(1)
@ -835,6 +807,7 @@ var snmpTableCachesLock sync.Mutex
// snmpTable resolves the given OID as a table, providing information about the
// table and fields within.
//nolint:revive //Too many return variable but necessary
func snmpTable(oid string) (mibName string, oidNum string, oidText string, fields []Field, err error) {
snmpTableCachesLock.Lock()
if snmpTableCaches == nil {
@ -852,6 +825,7 @@ func snmpTable(oid string) (mibName string, oidNum string, oidText string, field
return stc.mibName, stc.oidNum, stc.oidText, stc.fields, stc.err
}
//nolint:revive //Too many return variable but necessary
func snmpTableCall(oid string) (mibName string, oidNum string, oidText string, fields []Field, err error) {
mibName, oidNum, oidText, _, err = SnmpTranslate(oid)
if err != nil {
@ -859,53 +833,12 @@ func snmpTableCall(oid string) (mibName string, oidNum string, oidText string, f
}
mibPrefix := mibName + "::"
oidFullName := mibPrefix + oidText
// first attempt to get the table's tags
tagOids := map[string]struct{}{}
// We have to guess that the "entry" oid is `oid+".1"`. snmptable and snmptranslate don't seem to have a way to provide the info.
if out, err := execCmd("snmptranslate", "-Td", oidFullName+".1"); err == nil {
scanner := bufio.NewScanner(bytes.NewBuffer(out))
for scanner.Scan() {
line := scanner.Text()
col, tagOids, err := snmp.GetIndex(oidNum, mibPrefix)
if !strings.HasPrefix(line, " INDEX") {
continue
}
i := strings.Index(line, "{ ")
if i == -1 { // parse error
continue
}
line = line[i+2:]
i = strings.Index(line, " }")
if i == -1 { // parse error
continue
}
line = line[:i]
for _, col := range strings.Split(line, ", ") {
tagOids[mibPrefix+col] = struct{}{}
}
}
}
// this won't actually try to run a query. The `-Ch` will just cause it to dump headers.
out, err := execCmd("snmptable", "-Ch", "-Cl", "-c", "public", "127.0.0.1", oidFullName)
if err != nil {
return "", "", "", nil, fmt.Errorf("getting table columns: %w", err)
}
scanner := bufio.NewScanner(bytes.NewBuffer(out))
scanner.Scan()
cols := scanner.Text()
if len(cols) == 0 {
return "", "", "", nil, fmt.Errorf("could not find any columns in table")
}
for _, col := range strings.Split(cols, " ") {
if len(col) == 0 {
continue
}
_, isTag := tagOids[mibPrefix+col]
fields = append(fields, Field{Name: col, Oid: mibPrefix + col, IsTag: isTag})
for _, c := range col {
_, isTag := tagOids[mibPrefix+c]
fields = append(fields, Field{Name: c, Oid: mibPrefix + c, IsTag: isTag})
}
return mibName, oidNum, oidText, fields, err
@ -923,6 +856,7 @@ var snmpTranslateCachesLock sync.Mutex
var snmpTranslateCaches map[string]snmpTranslateCache
// snmpTranslate resolves the given OID.
//nolint:revive //Too many return variable but necessary
func SnmpTranslate(oid string) (mibName string, oidNum string, oidText string, conversion string, err error) {
snmpTranslateCachesLock.Lock()
if snmpTranslateCaches == nil {
@ -940,7 +874,7 @@ func SnmpTranslate(oid string) (mibName string, oidNum string, oidText string, c
// is worth it. Especially when it would slam the system pretty hard if lots
// of lookups are being performed.
stc.mibName, stc.oidNum, stc.oidText, stc.conversion, stc.err = snmpTranslateCall(oid)
stc.mibName, stc.oidNum, stc.oidText, stc.conversion, stc.err = snmp.SnmpTranslateCall(oid)
snmpTranslateCaches[oid] = stc
}
@ -948,73 +882,3 @@ func SnmpTranslate(oid string) (mibName string, oidNum string, oidText string, c
return stc.mibName, stc.oidNum, stc.oidText, stc.conversion, stc.err
}
func snmpTranslateCall(oid string) (mibName string, oidNum string, oidText string, conversion string, err error) {
var out []byte
if strings.ContainsAny(oid, ":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") {
out, err = execCmd("snmptranslate", "-Td", "-Ob", oid)
} else {
out, err = execCmd("snmptranslate", "-Td", "-Ob", "-m", "all", oid)
if err, ok := err.(*exec.Error); ok && err.Err == exec.ErrNotFound {
// Silently discard error if snmptranslate not found and we have a numeric OID.
// Meaning we can get by without the lookup.
return "", oid, oid, "", nil
}
}
if err != nil {
return "", "", "", "", err
}
scanner := bufio.NewScanner(bytes.NewBuffer(out))
ok := scanner.Scan()
if !ok && scanner.Err() != nil {
return "", "", "", "", fmt.Errorf("getting OID text: %w", scanner.Err())
}
oidText = scanner.Text()
i := strings.Index(oidText, "::")
if i == -1 {
// was not found in MIB.
if bytes.Contains(out, []byte("[TRUNCATED]")) {
return "", oid, oid, "", nil
}
// not truncated, but not fully found. We still need to parse out numeric OID, so keep going
oidText = oid
} else {
mibName = oidText[:i]
oidText = oidText[i+2:]
}
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, " -- TEXTUAL CONVENTION ") {
tc := strings.TrimPrefix(line, " -- TEXTUAL CONVENTION ")
switch tc {
case "MacAddress", "PhysAddress":
conversion = "hwaddr"
case "InetAddressIPv4", "InetAddressIPv6", "InetAddress", "IPSIpAddress":
conversion = "ipaddr"
}
} else if strings.HasPrefix(line, "::= { ") {
objs := strings.TrimPrefix(line, "::= { ")
objs = strings.TrimSuffix(objs, " }")
for _, obj := range strings.Split(objs, " ") {
if len(obj) == 0 {
continue
}
if i := strings.Index(obj, "("); i != -1 {
obj = obj[i+1:]
oidNum += "." + obj[:strings.Index(obj, ")")]
} else {
oidNum += "." + obj
}
}
break
}
}
return mibName, oidNum, oidText, conversion, nil
}

View File

@ -1,103 +0,0 @@
//go:build generate
// +build generate
package main
import (
"bufio"
"bytes"
"fmt"
"os"
"os/exec"
"strings"
)
// This file is a generator used to generate the mocks for the commands used by the tests.
// These are the commands to be mocked.
var mockedCommands = [][]string{
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.1.1"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.1.2"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", "1.0.0.1.1"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.1"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.1.0"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.5"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.2.3"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".1.0.0.0.1.7"},
{"snmptranslate", "-Td", "-Ob", ".iso.2.3"},
{"snmptranslate", "-Td", "-Ob", "-m", "all", ".999"},
{"snmptranslate", "-Td", "-Ob", "TEST::server"},
{"snmptranslate", "-Td", "-Ob", "TEST::server.0"},
{"snmptranslate", "-Td", "-Ob", "TEST::testTable"},
{"snmptranslate", "-Td", "-Ob", "TEST::connections"},
{"snmptranslate", "-Td", "-Ob", "TEST::latency"},
{"snmptranslate", "-Td", "-Ob", "TEST::description"},
{"snmptranslate", "-Td", "-Ob", "TEST::hostname"},
{"snmptranslate", "-Td", "-Ob", "IF-MIB::ifPhysAddress.1"},
{"snmptranslate", "-Td", "-Ob", "BRIDGE-MIB::dot1dTpFdbAddress.1"},
{"snmptranslate", "-Td", "-Ob", "TCP-MIB::tcpConnectionLocalAddress.1"},
{"snmptranslate", "-Td", "TEST::testTable.1"},
{"snmptable", "-Ch", "-Cl", "-c", "public", "127.0.0.1", "TEST::testTable"},
}
type mockedCommandResult struct {
stdout string
stderr string
exitError bool
}
func main() {
if err := generate(); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
}
func generate() error {
f, err := os.OpenFile("snmp_mocks_test.go", os.O_RDWR, 0644)
if err != nil {
return err
}
br := bufio.NewReader(f)
var i int64
for l, err := br.ReadString('\n'); err == nil; l, err = br.ReadString('\n') {
i += int64(len(l))
if l == "// BEGIN GO GENERATE CONTENT\n" {
break
}
}
f.Truncate(i)
f.Seek(i, 0)
fmt.Fprintf(f, "var mockedCommandResults = map[string]mockedCommandResult{\n")
for _, cmd := range mockedCommands {
ec := exec.Command(cmd[0], cmd[1:]...)
out := bytes.NewBuffer(nil)
err := bytes.NewBuffer(nil)
ec.Stdout = out
ec.Stderr = err
ec.Env = []string{
"MIBDIRS=+./testdata",
}
var mcr mockedCommandResult
if err := ec.Run(); err != nil {
if err, ok := err.(*exec.ExitError); !ok {
mcr.exitError = true
} else {
return fmt.Errorf("executing %v: %s", cmd, err)
}
}
mcr.stdout = string(out.Bytes())
mcr.stderr = string(err.Bytes())
cmd0 := strings.Join(cmd, "\000")
mcrv := fmt.Sprintf("%#v", mcr)[5:] // trim `main.` prefix
fmt.Fprintf(f, "%#v: %s,\n", cmd0, mcrv)
}
f.Write([]byte("}\n"))
f.Close()
return exec.Command("gofmt", "-w", "snmp_mocks_test.go").Run()
}

View File

@ -1,93 +0,0 @@
package snmp
import (
"fmt"
"os"
"os/exec"
"strings"
"testing"
)
type mockedCommandResult struct {
stdout string
stderr string
exitError bool
}
func mockExecCommand(arg0 string, args ...string) *exec.Cmd {
args = append([]string{"-test.run=TestMockExecCommand", "--", arg0}, args...)
cmd := exec.Command(os.Args[0], args...)
cmd.Stderr = os.Stderr // so the test output shows errors
return cmd
}
// This is not a real test. This is just a way of mocking out commands.
//
// Idea based on https://github.com/golang/go/blob/7c31043/src/os/exec/exec_test.go#L568
func TestMockExecCommand(_ *testing.T) {
var cmd []string
for _, arg := range os.Args {
if arg == "--" {
cmd = []string{}
continue
}
if cmd == nil {
continue
}
cmd = append(cmd, arg)
}
if cmd == nil {
return
}
cmd0 := strings.Join(cmd, "\000")
mcr, ok := mockedCommandResults[cmd0]
if !ok {
cv := fmt.Sprintf("%#v", cmd)[8:] // trim `[]string` prefix
//nolint:errcheck,revive
fmt.Fprintf(os.Stderr, "Unmocked command. Please add the following to `mockedCommands` in snmp_mocks_generate.go, and then run `go generate`:\n\t%s,\n", cv)
//nolint:revive // error code is important for this "test"
os.Exit(1)
}
//nolint:errcheck,revive
fmt.Printf("%s", mcr.stdout)
//nolint:errcheck,revive
fmt.Fprintf(os.Stderr, "%s", mcr.stderr)
if mcr.exitError {
//nolint:revive // error code is important for this "test"
os.Exit(1)
}
//nolint:revive // error code is important for this "test"
os.Exit(0)
}
func init() {
execCommand = mockExecCommand
}
// BEGIN GO GENERATE CONTENT
var mockedCommandResults = map[string]mockedCommandResult{
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0": {stdout: "TEST::testTable\ntestTable OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 0 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.1.1": {stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.1.2": {stdout: "TEST::1.2\nanonymous#1 OBJECT-TYPE\n -- FROM\tTEST\n::= { iso(1) 0 testOID(0) 1 2 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x001.0.0.1.1": {stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.1": {stdout: "TEST::server\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.1.0": {stdout: "TEST::server.0\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) server(1) 0 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.5": {stdout: "TEST::testTableEntry.5\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 5 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.2.3": {stdout: "iso.2.3\niso OBJECT-TYPE\n -- FROM\t#-1\n::= { iso(1) 2 3 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.1.0.0.0.1.7": {stdout: "TEST::testTableEntry.7\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) std(0) testOID(0) testTable(0) testTableEntry(1) 7 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00.iso.2.3": {stdout: "iso.2.3\niso OBJECT-TYPE\n -- FROM\t#-1\n::= { iso(1) 2 3 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00-m\x00all\x00.999": {stdout: ".999\n [TRUNCATED]\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::server": {stdout: "TEST::server\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::server.0": {stdout: "TEST::server.0\nserver OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) server(1) 0 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::testTable": {stdout: "TEST::testTable\ntestTable OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 0 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::connections": {stdout: "TEST::connections\nconnections OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tINTEGER\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 2 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::latency": {stdout: "TEST::latency\nlatency OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 3 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::description": {stdout: "TEST::description\ndescription OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) testTable(0) testTableEntry(1) 4 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TEST::hostname": {stdout: "TEST::hostname\nhostname OBJECT-TYPE\n -- FROM\tTEST\n SYNTAX\tOCTET STRING\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n::= { iso(1) 0 testOID(0) 1 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00IF-MIB::ifPhysAddress.1": {stdout: "IF-MIB::ifPhysAddress.1\nifPhysAddress OBJECT-TYPE\n -- FROM\tIF-MIB\n -- TEXTUAL CONVENTION PhysAddress\n SYNTAX\tOCTET STRING\n DISPLAY-HINT\t\"1x:\"\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n DESCRIPTION\t\"The interface's address at its protocol sub-layer. For\n example, for an 802.x interface, this object normally\n contains a MAC address. The interface's media-specific MIB\n must define the bit and byte ordering and the format of the\n value of this object. For interfaces which do not have such\n an address (e.g., a serial line), this object should contain\n an octet string of zero length.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) interfaces(2) ifTable(2) ifEntry(1) ifPhysAddress(6) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00BRIDGE-MIB::dot1dTpFdbAddress.1": {stdout: "BRIDGE-MIB::dot1dTpFdbAddress.1\ndot1dTpFdbAddress OBJECT-TYPE\n -- FROM\tBRIDGE-MIB\n -- TEXTUAL CONVENTION MacAddress\n SYNTAX\tOCTET STRING (6) \n DISPLAY-HINT\t\"1x:\"\n MAX-ACCESS\tread-only\n STATUS\tcurrent\n DESCRIPTION\t\"A unicast MAC address for which the bridge has\n forwarding and/or filtering information.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) dot1dBridge(17) dot1dTp(4) dot1dTpFdbTable(3) dot1dTpFdbEntry(1) dot1dTpFdbAddress(1) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00-Ob\x00TCP-MIB::tcpConnectionLocalAddress.1": {stdout: "TCP-MIB::tcpConnectionLocalAddress.1\ntcpConnectionLocalAddress OBJECT-TYPE\n -- FROM\tTCP-MIB\n -- TEXTUAL CONVENTION InetAddress\n SYNTAX\tOCTET STRING (0..255) \n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n DESCRIPTION\t\"The local IP address for this TCP connection. The type\n of this address is determined by the value of\n tcpConnectionLocalAddressType.\n\n As this object is used in the index for the\n tcpConnectionTable, implementors should be\n careful not to create entries that would result in OIDs\n with more than 128 subidentifiers; otherwise the information\n cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3.\"\n::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) tcp(6) tcpConnectionTable(19) tcpConnectionEntry(1) tcpConnectionLocalAddress(2) 1 }\n", stderr: "", exitError: false},
"snmptranslate\x00-Td\x00TEST::testTable.1": {stdout: "TEST::testTableEntry\ntestTableEntry OBJECT-TYPE\n -- FROM\tTEST\n MAX-ACCESS\tnot-accessible\n STATUS\tcurrent\n INDEX\t\t{ server }\n::= { iso(1) 0 testOID(0) testTable(0) 1 }\n", stderr: "", exitError: false},
"snmptable\x00-Ch\x00-Cl\x00-c\x00public\x00127.0.0.1\x00TEST::testTable": {stdout: "server connections latency description \nTEST::testTable: No entries\n", stderr: "", exitError: false},
}

View File

@ -1,10 +1,9 @@
//go:generate go run -tags generate snmp_mocks_generate.go
package snmp
import (
"fmt"
"net"
"os/exec"
"path/filepath"
"sync"
"testing"
"time"
@ -63,33 +62,42 @@ func (tsc *testSNMPConnection) Walk(oid string, wf gosnmp.WalkFunc) error {
var tsc = &testSNMPConnection{
host: "tsc",
values: map[string]interface{}{
".1.0.0.0.1.1.0": "foo",
".1.0.0.0.1.1.1": []byte("bar"),
".1.0.0.0.1.1.2": []byte(""),
".1.0.0.0.1.102": "bad",
".1.0.0.0.1.2.0": 1,
".1.0.0.0.1.2.1": 2,
".1.0.0.0.1.2.2": 0,
".1.0.0.0.1.3.0": "0.123",
".1.0.0.0.1.3.1": "0.456",
".1.0.0.0.1.3.2": "0.000",
".1.0.0.0.1.3.3": "9.999",
".1.0.0.0.1.5.0": 123456,
".1.0.0.1.1": "baz",
".1.0.0.1.2": 234,
".1.0.0.1.3": []byte("byte slice"),
".1.0.0.2.1.5.0.9.9": 11,
".1.0.0.2.1.5.1.9.9": 22,
".1.0.0.0.1.6.0": ".1.0.0.0.1.7",
".1.0.0.3.1.1.10": "instance",
".1.0.0.3.1.1.11": "instance2",
".1.0.0.3.1.1.12": "instance3",
".1.0.0.3.1.2.10": 10,
".1.0.0.3.1.2.11": 20,
".1.0.0.3.1.2.12": 20,
".1.0.0.3.1.3.10": 1,
".1.0.0.3.1.3.11": 2,
".1.0.0.3.1.3.12": 3,
".1.3.6.1.2.1.3.1.1.1.0": "foo",
".1.3.6.1.2.1.3.1.1.1.1": []byte("bar"),
".1.3.6.1.2.1.3.1.1.1.2": []byte(""),
".1.3.6.1.2.1.3.1.1.102": "bad",
".1.3.6.1.2.1.3.1.1.2.0": 1,
".1.3.6.1.2.1.3.1.1.2.1": 2,
".1.3.6.1.2.1.3.1.1.2.2": 0,
".1.3.6.1.2.1.3.1.1.3.0": "1.3.6.1.2.1.3.1.1.3",
".1.3.6.1.2.1.3.1.1.5.0": 123456,
".1.0.0.0.1.1.0": "foo",
".1.0.0.0.1.1.1": []byte("bar"),
".1.0.0.0.1.1.2": []byte(""),
".1.0.0.0.1.102": "bad",
".1.0.0.0.1.2.0": 1,
".1.0.0.0.1.2.1": 2,
".1.0.0.0.1.2.2": 0,
".1.0.0.0.1.3.0": "0.123",
".1.0.0.0.1.3.1": "0.456",
".1.0.0.0.1.3.2": "0.000",
".1.0.0.0.1.3.3": "9.999",
".1.0.0.0.1.5.0": 123456,
".1.0.0.1.1": "baz",
".1.0.0.1.2": 234,
".1.0.0.1.3": []byte("byte slice"),
".1.0.0.2.1.5.0.9.9": 11,
".1.0.0.2.1.5.1.9.9": 22,
".1.0.0.0.1.6.0": ".1.0.0.0.1.7",
".1.0.0.3.1.1.10": "instance",
".1.0.0.3.1.1.11": "instance2",
".1.0.0.3.1.1.12": "instance3",
".1.0.0.3.1.2.10": 10,
".1.0.0.3.1.2.11": 20,
".1.0.0.3.1.2.12": 20,
".1.0.0.3.1.3.10": 1,
".1.0.0.3.1.3.11": 2,
".1.0.0.3.1.3.12": 3,
},
}
@ -104,6 +112,7 @@ func TestSampleConfig(t *testing.T) {
ClientConfig: snmp.ClientConfig{
Timeout: config.Duration(5 * time.Second),
Version: 2,
Path: []string{"/usr/share/snmp/mibs"},
Community: "public",
MaxRepetitions: 10,
Retries: 3,
@ -114,6 +123,17 @@ func TestSampleConfig(t *testing.T) {
}
func TestFieldInit(t *testing.T) {
testDataPath, err := filepath.Abs("./testdata")
require.NoError(t, err)
s := &Snmp{
ClientConfig: snmp.ClientConfig{
Path: []string{testDataPath},
},
}
err = s.Init()
require.NoError(t, err)
translations := []struct {
inputOid string
inputName string
@ -125,8 +145,6 @@ func TestFieldInit(t *testing.T) {
{".1.2.3", "foo", "", ".1.2.3", "foo", ""},
{".iso.2.3", "foo", "", ".1.2.3", "foo", ""},
{".1.0.0.0.1.1", "", "", ".1.0.0.0.1.1", "server", ""},
{".1.0.0.0.1.1.0", "", "", ".1.0.0.0.1.1.0", "server.0", ""},
{".999", "", "", ".999", ".999", ""},
{"TEST::server", "", "", ".1.0.0.0.1.1", "server", ""},
{"TEST::server.0", "", "", ".1.0.0.0.1.1.0", "server.0", ""},
{"TEST::server", "foo", "", ".1.0.0.0.1.1", "foo", ""},
@ -134,6 +152,7 @@ func TestFieldInit(t *testing.T) {
{"IF-MIB::ifPhysAddress.1", "", "none", ".1.3.6.1.2.1.2.2.1.6.1", "ifPhysAddress.1", "none"},
{"BRIDGE-MIB::dot1dTpFdbAddress.1", "", "", ".1.3.6.1.2.1.17.4.3.1.1.1", "dot1dTpFdbAddress.1", "hwaddr"},
{"TCP-MIB::tcpConnectionLocalAddress.1", "", "", ".1.3.6.1.2.1.6.19.1.2.1", "tcpConnectionLocalAddress.1", "ipaddr"},
{".999", "", "", ".999", ".999", ""},
}
for _, txl := range translations {
@ -147,100 +166,111 @@ func TestFieldInit(t *testing.T) {
}
func TestTableInit(t *testing.T) {
tbl := Table{
Oid: ".1.0.0.0",
Fields: []Field{
{Oid: ".999", Name: "foo"},
{Oid: "TEST::description", Name: "description", IsTag: true},
},
}
err := tbl.Init()
testDataPath, err := filepath.Abs("./testdata")
require.NoError(t, err)
require.Equal(t, "testTable", tbl.Name)
s := &Snmp{
ClientConfig: snmp.ClientConfig{
Path: []string{testDataPath},
},
Tables: []Table{
{Oid: ".1.3.6.1.2.1.3.1",
Fields: []Field{
{Oid: ".999", Name: "foo"},
{Oid: ".1.3.6.1.2.1.3.1.1.1", Name: "atIfIndex", IsTag: true},
{Oid: "RFC1213-MIB::atPhysAddress", Name: "atPhysAddress"},
}},
},
}
err = s.Init()
require.NoError(t, err)
require.Len(t, tbl.Fields, 5)
require.Contains(t, tbl.Fields, Field{Oid: ".999", Name: "foo", initialized: true})
require.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.1", Name: "server", IsTag: true, initialized: true})
require.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.2", Name: "connections", initialized: true})
require.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.3", Name: "latency", initialized: true})
require.Contains(t, tbl.Fields, Field{Oid: ".1.0.0.0.1.4", Name: "description", IsTag: true, initialized: true})
require.Equal(t, "atTable", s.Tables[0].Name)
require.Len(t, s.Tables[0].Fields, 5)
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".999", Name: "foo", initialized: true})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.3.6.1.2.1.3.1.1.1", Name: "atIfIndex", initialized: true, IsTag: true})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.3.6.1.2.1.3.1.1.2", Name: "atPhysAddress", initialized: true, Conversion: "hwaddr"})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.3.6.1.2.1.3.1.1.3", Name: "atNetAddress", initialized: true, IsTag: true})
}
func TestSnmpInit(t *testing.T) {
testDataPath, err := filepath.Abs("./testdata")
require.NoError(t, err)
s := &Snmp{
Tables: []Table{
{Oid: "TEST::testTable"},
{Oid: "RFC1213-MIB::atTable"},
},
Fields: []Field{
{Oid: "TEST::hostname"},
{Oid: "RFC1213-MIB::atPhysAddress"},
},
ClientConfig: snmp.ClientConfig{
Path: []string{testDataPath},
},
}
err := s.init()
err = s.Init()
require.NoError(t, err)
require.Len(t, s.Tables[0].Fields, 4)
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.1", Name: "server", IsTag: true, initialized: true})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.2", Name: "connections", initialized: true})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.3", Name: "latency", initialized: true})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.0.0.0.1.4", Name: "description", initialized: true})
require.Len(t, s.Tables[0].Fields, 3)
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.3.6.1.2.1.3.1.1.1", Name: "atIfIndex", IsTag: true, initialized: true})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.3.6.1.2.1.3.1.1.2", Name: "atPhysAddress", initialized: true, Conversion: "hwaddr"})
require.Contains(t, s.Tables[0].Fields, Field{Oid: ".1.3.6.1.2.1.3.1.1.3", Name: "atNetAddress", IsTag: true, initialized: true})
require.Equal(t, Field{
Oid: ".1.0.0.1.1",
Name: "hostname",
Oid: ".1.3.6.1.2.1.3.1.1.2",
Name: "atPhysAddress",
Conversion: "hwaddr",
initialized: true,
}, s.Fields[0])
}
func TestSnmpInit_noTranslate(t *testing.T) {
// override execCommand so it returns exec.ErrNotFound
defer func(ec func(string, ...string) *exec.Cmd) { execCommand = ec }(execCommand)
execCommand = func(_ string, _ ...string) *exec.Cmd {
return exec.Command("snmptranslateExecErrNotFound")
}
s := &Snmp{
Fields: []Field{
{Oid: ".1.1.1.1", Name: "one", IsTag: true},
{Oid: ".1.1.1.2", Name: "two"},
{Oid: ".1.1.1.3"},
{Oid: ".9.1.1.1.1", Name: "one", IsTag: true},
{Oid: ".9.1.1.1.2", Name: "two"},
{Oid: ".9.1.1.1.3"},
},
Tables: []Table{
{Name: "testing",
Fields: []Field{
{Oid: ".1.1.1.4", Name: "four", IsTag: true},
{Oid: ".1.1.1.5", Name: "five"},
{Oid: ".1.1.1.6"},
{Oid: ".9.1.1.1.4", Name: "four", IsTag: true},
{Oid: ".9.1.1.1.5", Name: "five"},
{Oid: ".9.1.1.1.6"},
}},
},
ClientConfig: snmp.ClientConfig{
Path: []string{},
},
}
err := s.init()
err := s.Init()
require.NoError(t, err)
require.Equal(t, ".1.1.1.1", s.Fields[0].Oid)
require.Equal(t, ".9.1.1.1.1", s.Fields[0].Oid)
require.Equal(t, "one", s.Fields[0].Name)
require.Equal(t, true, s.Fields[0].IsTag)
require.Equal(t, ".1.1.1.2", s.Fields[1].Oid)
require.Equal(t, ".9.1.1.1.2", s.Fields[1].Oid)
require.Equal(t, "two", s.Fields[1].Name)
require.Equal(t, false, s.Fields[1].IsTag)
require.Equal(t, ".1.1.1.3", s.Fields[2].Oid)
require.Equal(t, ".1.1.1.3", s.Fields[2].Name)
require.Equal(t, ".9.1.1.1.3", s.Fields[2].Oid)
require.Equal(t, ".9.1.1.1.3", s.Fields[2].Name)
require.Equal(t, false, s.Fields[2].IsTag)
require.Equal(t, ".1.1.1.4", s.Tables[0].Fields[0].Oid)
require.Equal(t, ".9.1.1.1.4", s.Tables[0].Fields[0].Oid)
require.Equal(t, "four", s.Tables[0].Fields[0].Name)
require.Equal(t, true, s.Tables[0].Fields[0].IsTag)
require.Equal(t, ".1.1.1.5", s.Tables[0].Fields[1].Oid)
require.Equal(t, ".9.1.1.1.5", s.Tables[0].Fields[1].Oid)
require.Equal(t, "five", s.Tables[0].Fields[1].Name)
require.Equal(t, false, s.Tables[0].Fields[1].IsTag)
require.Equal(t, ".1.1.1.6", s.Tables[0].Fields[2].Oid)
require.Equal(t, ".1.1.1.6", s.Tables[0].Fields[2].Name)
require.Equal(t, ".9.1.1.1.6", s.Tables[0].Fields[2].Oid)
require.Equal(t, ".9.1.1.1.6", s.Tables[0].Fields[2].Name)
require.Equal(t, false, s.Tables[0].Fields[2].IsTag)
}
@ -255,7 +285,7 @@ func TestSnmpInit_noName_noOid(t *testing.T) {
},
}
err := s.init()
err := s.Init()
require.Error(t, err)
}
@ -269,7 +299,7 @@ func TestGetSNMPConnection_v2(t *testing.T) {
Community: "foo",
},
}
err := s.init()
err := s.Init()
require.NoError(t, err)
gsc, err := s.getConnection(0)
@ -305,7 +335,7 @@ func TestGetSNMPConnectionTCP(t *testing.T) {
s := &Snmp{
Agents: []string{"tcp://127.0.0.1:56789"},
}
err := s.init()
err := s.Init()
require.NoError(t, err)
wg.Add(1)
@ -346,7 +376,7 @@ func TestGetSNMPConnection_v3(t *testing.T) {
EngineTime: 2,
},
}
err := s.init()
err := s.Init()
require.NoError(t, err)
gsc, err := s.getConnection(0)
@ -463,7 +493,7 @@ func TestGetSNMPConnection_v3_blumenthal(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
s := tc.Config
err := s.init()
err := s.Init()
require.NoError(t, err)
gsc, err := s.getConnection(0)
@ -491,7 +521,7 @@ func TestGetSNMPConnection_caching(t *testing.T) {
s := &Snmp{
Agents: []string{"1.2.3.4", "1.2.3.5", "1.2.3.5"},
}
err := s.init()
err := s.Init()
require.NoError(t, err)
gs1, err := s.getConnection(0)
require.NoError(t, err)
@ -613,7 +643,7 @@ func TestGosnmpWrapper_get_retry(t *testing.T) {
require.Equal(t, (gs.Retries+1)*2, reqCount)
}
func TestTableBuild_walk(t *testing.T) {
func TestTableBuild_walk_noTranslate(t *testing.T) {
tbl := Table{
Name: "mytable",
IndexAsTag: true,
@ -642,22 +672,11 @@ func TestTableBuild_walk(t *testing.T) {
Oid: ".1.0.0.2.1.5",
OidIndexLength: 1,
},
{
Name: "myfield6",
Oid: ".1.0.0.0.1.6",
Translate: true,
},
{
Name: "myfield7",
Oid: ".1.0.0.0.1.6",
Translate: false,
},
},
}
tb, err := tbl.Build(tsc, true)
require.NoError(t, err)
require.Equal(t, tb.Name, "mytable")
rtr1 := RTableRow{
Tags: map[string]string{
@ -669,8 +688,6 @@ func TestTableBuild_walk(t *testing.T) {
"myfield3": float64(0.123),
"myfield4": 11,
"myfield5": 11,
"myfield6": "testTableEntry.7",
"myfield7": ".1.0.0.0.1.7",
},
}
rtr2 := RTableRow{
@ -709,6 +726,80 @@ func TestTableBuild_walk(t *testing.T) {
require.Contains(t, tb.Rows, rtr4)
}
func TestTableBuild_walk_Translate(t *testing.T) {
testDataPath, err := filepath.Abs("./testdata")
require.NoError(t, err)
s := &Snmp{
ClientConfig: snmp.ClientConfig{
Path: []string{testDataPath},
},
}
err = s.Init()
require.NoError(t, err)
tbl := Table{
Name: "atTable",
IndexAsTag: true,
Fields: []Field{
{
Name: "ifIndex",
Oid: "1.3.6.1.2.1.3.1.1.1",
IsTag: true,
},
{
Name: "atPhysAddress",
Oid: "1.3.6.1.2.1.3.1.1.2",
Translate: false,
},
{
Name: "atNetAddress",
Oid: "1.3.6.1.2.1.3.1.1.3",
Translate: true,
},
},
}
err = tbl.Init()
require.NoError(t, err)
tb, err := tbl.Build(tsc, true)
require.NoError(t, err)
require.Equal(t, tb.Name, "atTable")
rtr1 := RTableRow{
Tags: map[string]string{
"ifIndex": "foo",
"index": "0",
},
Fields: map[string]interface{}{
"atPhysAddress": 1,
"atNetAddress": "atNetAddress",
},
}
rtr2 := RTableRow{
Tags: map[string]string{
"ifIndex": "bar",
"index": "1",
},
Fields: map[string]interface{}{
"atPhysAddress": 2,
},
}
rtr3 := RTableRow{
Tags: map[string]string{
"index": "2",
},
Fields: map[string]interface{}{
"atPhysAddress": 0,
},
}
require.Len(t, tb.Rows, 3)
require.Contains(t, tb.Rows, rtr1)
require.Contains(t, tb.Rows, rtr2)
require.Contains(t, tb.Rows, rtr3)
}
func TestTableBuild_noWalk(t *testing.T) {
tbl := Table{
Name: "mytable",
@ -784,7 +875,6 @@ func TestGather(t *testing.T) {
connectionCache: []snmpConnection{
tsc,
},
initialized: true,
}
acc := &testutil.Accumulator{}
@ -831,7 +921,6 @@ func TestGather_host(t *testing.T) {
connectionCache: []snmpConnection{
tsc,
},
initialized: true,
}
acc := &testutil.Accumulator{}

1467
plugins/inputs/snmp/testdata/bridgeMib vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,554 @@
SNMPv2-SMI DEFINITIONS ::= BEGIN
-- the path to the root
org OBJECT IDENTIFIER ::= { iso 3 } -- "iso" = 1
dod OBJECT IDENTIFIER ::= { org 6 }
internet OBJECT IDENTIFIER ::= { dod 1 }
directory OBJECT IDENTIFIER ::= { internet 1 }
mgmt OBJECT IDENTIFIER ::= { internet 2 }
mib-2 OBJECT IDENTIFIER ::= { mgmt 1 }
transmission OBJECT IDENTIFIER ::= { mib-2 10 }
experimental OBJECT IDENTIFIER ::= { internet 3 }
private OBJECT IDENTIFIER ::= { internet 4 }
enterprises OBJECT IDENTIFIER ::= { private 1 }
security OBJECT IDENTIFIER ::= { internet 5 }
snmpV2 OBJECT IDENTIFIER ::= { internet 6 }
-- transport domains
snmpDomains OBJECT IDENTIFIER ::= { snmpV2 1 }
-- transport proxies
snmpProxys OBJECT IDENTIFIER ::= { snmpV2 2 }
-- module identities
snmpModules OBJECT IDENTIFIER ::= { snmpV2 3 }
-- Extended UTCTime, to allow dates with four-digit years
-- (Note that this definition of ExtUTCTime is not to be IMPORTed
-- by MIB modules.)
ExtUTCTime ::= OCTET STRING(SIZE(11 | 13))
-- format is YYMMDDHHMMZ or YYYYMMDDHHMMZ
-- where: YY - last two digits of year (only years
-- between 1900-1999)
-- YYYY - last four digits of the year (any year)
-- MM - month (01 through 12)
-- DD - day of month (01 through 31)
-- HH - hours (00 through 23)
-- MM - minutes (00 through 59)
-- Z - denotes GMT (the ASCII character Z)
--
-- For example, "9502192015Z" and "199502192015Z" represent
-- 8:15pm GMT on 19 February 1995. Years after 1999 must use
-- the four digit year format. Years 1900-1999 may use the
-- two or four digit format.
-- definitions for information modules
MODULE-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"LAST-UPDATED" value(Update ExtUTCTime)
"ORGANIZATION" Text
"CONTACT-INFO" Text
"DESCRIPTION" Text
RevisionPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
RevisionPart ::=
Revisions
| empty
Revisions ::=
Revision
| Revisions Revision
Revision ::=
"REVISION" value(Update ExtUTCTime)
"DESCRIPTION" Text
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
OBJECT-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- names of objects
-- (Note that these definitions of ObjectName and NotificationName
-- are not to be IMPORTed by MIB modules.)
ObjectName ::=
OBJECT IDENTIFIER
NotificationName ::=
OBJECT IDENTIFIER
-- syntax of objects
-- the "base types" defined here are:
-- 3 built-in ASN.1 types: INTEGER, OCTET STRING, OBJECT IDENTIFIER
-- 8 application-defined types: Integer32, IpAddress, Counter32,
-- Gauge32, Unsigned32, TimeTicks, Opaque, and Counter64
ObjectSyntax ::=
CHOICE {
simple
SimpleSyntax,
-- note that SEQUENCEs for conceptual tables and
-- rows are not mentioned here...
application-wide
ApplicationSyntax
}
-- built-in ASN.1 types
SimpleSyntax ::=
CHOICE {
-- INTEGERs with a more restrictive range
-- may also be used
integer-value -- includes Integer32
INTEGER (-2147483648..2147483647),
-- OCTET STRINGs with a more restrictive size
-- may also be used
string-value
OCTET STRING (SIZE (0..65535)),
objectID-value
OBJECT IDENTIFIER
}
-- indistinguishable from INTEGER, but never needs more than
-- 32-bits for a two's complement representation
Integer32 ::=
INTEGER (-2147483648..2147483647)
-- application-wide types
ApplicationSyntax ::=
CHOICE {
ipAddress-value
IpAddress,
counter-value
Counter32,
timeticks-value
TimeTicks,
arbitrary-value
Opaque,
big-counter-value
Counter64,
unsigned-integer-value -- includes Gauge32
Unsigned32
}
-- in network-byte order
-- (this is a tagged type for historical reasons)
IpAddress ::=
[APPLICATION 0]
IMPLICIT OCTET STRING (SIZE (4))
-- this wraps
Counter32 ::=
[APPLICATION 1]
IMPLICIT INTEGER (0..4294967295)
-- this doesn't wrap
Gauge32 ::=
[APPLICATION 2]
IMPLICIT INTEGER (0..4294967295)
-- an unsigned 32-bit quantity
-- indistinguishable from Gauge32
Unsigned32 ::=
[APPLICATION 2]
IMPLICIT INTEGER (0..4294967295)
-- hundredths of seconds since an epoch
TimeTicks ::=
[APPLICATION 3]
IMPLICIT INTEGER (0..4294967295)
-- for backward-compatibility only
Opaque ::=
[APPLICATION 4]
IMPLICIT OCTET STRING
-- for counters that wrap in less than one hour with only 32 bits
Counter64 ::=
[APPLICATION 6]
IMPLICIT INTEGER (0..18446744073709551615)
-- definition for objects
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
"SYNTAX" Syntax
UnitsPart
"MAX-ACCESS" Access
"STATUS" Status
"DESCRIPTION" Text
ReferPart
IndexPart
DefValPart
VALUE NOTATION ::=
value(VALUE ObjectName)
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement),
-- a textual convention (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
UnitsPart ::=
"UNITS" Text
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
IndexPart ::=
"INDEX" "{" IndexTypes "}"
| "AUGMENTS" "{" Entry "}"
| empty
IndexTypes ::=
IndexType
| IndexTypes "," IndexType
IndexType ::=
"IMPLIED" Index
| Index
Index ::=
-- use the SYNTAX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
Entry ::=
-- use the INDEX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
DefValPart ::= "DEFVAL" "{" Defvalue "}"
| empty
Defvalue ::= -- must be valid for the type specified in
-- SYNTAX clause of same OBJECT-TYPE macro
value(ObjectSyntax)
| "{" BitsValue "}"
BitsValue ::= BitNames
| empty
BitNames ::= BitName
| BitNames "," BitName
BitName ::= identifier
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- definitions for notifications
NOTIFICATION-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
ObjectsPart
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE NotificationName)
ObjectsPart ::=
"OBJECTS" "{" Objects "}"
| empty
Objects ::=
Object
| Objects "," Object
Object ::=
value(ObjectName)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- definitions of administrative identifiers
zeroDotZero OBJECT-IDENTITY
STATUS current
DESCRIPTION
"A value used for null identifiers."
::= { 0 0 }
TEXTUAL-CONVENTION MACRO ::=
BEGIN
TYPE NOTATION ::=
DisplayPart
"STATUS" Status
"DESCRIPTION" Text
ReferPart
"SYNTAX" Syntax
VALUE NOTATION ::=
value(VALUE Syntax) -- adapted ASN.1
DisplayPart ::=
"DISPLAY-HINT" Text
| empty
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in [2]
Text ::= value(IA5String)
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
END
MODULE-COMPLIANCE MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
ModulePart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
ModulePart ::=
Modules
Modules ::=
Module
| Modules Module
Module ::=
-- name of module --
"MODULE" ModuleName
MandatoryPart
CompliancePart
ModuleName ::=
-- identifier must start with uppercase letter
identifier ModuleIdentifier
-- must not be empty unless contained
-- in MIB Module
| empty
ModuleIdentifier ::=
value(OBJECT IDENTIFIER)
| empty
MandatoryPart ::=
"MANDATORY-GROUPS" "{" Groups "}"
| empty
Groups ::=
Group
| Groups "," Group
Group ::=
value(OBJECT IDENTIFIER)
CompliancePart ::=
Compliances
| empty
Compliances ::=
Compliance
| Compliances Compliance
Compliance ::=
ComplianceGroup
| Object
ComplianceGroup ::=
"GROUP" value(OBJECT IDENTIFIER)
"DESCRIPTION" Text
Object ::=
"OBJECT" value(ObjectName)
SyntaxPart
WriteSyntaxPart
AccessPart
"DESCRIPTION" Text
-- must be a refinement for object's SYNTAX clause
SyntaxPart ::= "SYNTAX" Syntax
| empty
-- must be a refinement for object's SYNTAX clause
WriteSyntaxPart ::= "WRITE-SYNTAX" Syntax
| empty
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement),
-- a textual convention (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
AccessPart ::=
"MIN-ACCESS" Access
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
-- a character string as defined in [2]
Text ::= value(IA5String)
END
OBJECT-GROUP MACRO ::=
BEGIN
TYPE NOTATION ::=
ObjectsPart
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
ObjectsPart ::=
"OBJECTS" "{" Objects "}"
Objects ::=
Object
| Objects "," Object
Object ::=
value(ObjectName)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in [2]
Text ::= value(IA5String)
END
InterfaceIndex ::= TEXTUAL-CONVENTION
DISPLAY-HINT "d"
STATUS current
DESCRIPTION
"A unique value, greater than zero, for each interface or
interface sub-layer in the managed system. It is
recommended that values are assigned contiguously starting
from 1. The value for each interface sub-layer must remain
constant at least from one re-initialization of the entity's
network management system to the next re-initialization."
SYNTAX Integer32 (1..2147483647)
MacAddress ::= TEXTUAL-CONVENTION
DISPLAY-HINT "1x:"
STATUS current
DESCRIPTION
"Represents an 802 MAC address represented in the
`canonical' order defined by IEEE 802.1a, i.e., as if it
were transmitted least significant bit first, even though
802.5 (in contrast to other 802.x protocols) requires MAC
addresses to be transmitted most significant bit first."
SYNTAX OCTET STRING (SIZE (6))
END

30
plugins/inputs/snmp/testdata/foo vendored Normal file
View File

@ -0,0 +1,30 @@
FOOTEST-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32 FROM fooImports;
fooTestMIB MODULE-IDENTITY
LAST-UPDATED "2021090800Z"
ORGANIZATION "influx"
CONTACT-INFO
"EMail: influx@email.com"
DESCRIPTION
"MIB module for testing snmp plugin
for telegraf
"
::= { iso 1 }
fooMIBObjects OBJECT IDENTIFIER ::= { iso 2 }
fooOne OBJECT IDENTIFIER ::= { iso 1 }
six OBJECT IDENTIFIER ::= { fooOne 1 }
three OBJECT IDENTIFIER ::= { six 3 }
foo OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"foo mib for testing"
::= { fooMIBObjects 3 }
END

169
plugins/inputs/snmp/testdata/fooImports vendored Normal file
View File

@ -0,0 +1,169 @@
fooImports DEFINITIONS ::= BEGIN
-- the path to the root
org OBJECT IDENTIFIER ::= { iso 1 } -- "iso" = 1
dod OBJECT IDENTIFIER ::= { org 2 }
internet OBJECT IDENTIFIER ::= { dod 3 }
ExtUTCTime ::= OCTET STRING(SIZE(11 | 13))
-- format is YYMMDDHHMMZ or YYYYMMDDHHMMZ
-- where: YY - last two digits of year (only years
-- between 1900-1999)
-- YYYY - last four digits of the year (any year)
-- MM - month (01 through 12)
-- DD - day of month (01 through 31)
-- HH - hours (00 through 23)
-- MM - minutes (00 through 59)
-- Z - denotes GMT (the ASCII character Z)
--
-- For example, "9502192015Z" and "199502192015Z" represent
-- 8:15pm GMT on 19 February 1995. Years after 1999 must use
-- the four digit year format. Years 1900-1999 may use the
-- two or four digit format.
-- definitions for information modules
MODULE-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"LAST-UPDATED" value(Update ExtUTCTime)
"ORGANIZATION" Text
"CONTACT-INFO" Text
"DESCRIPTION" Text
RevisionPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
RevisionPart ::=
Revisions
| empty
Revisions ::=
Revision
| Revisions Revision
Revision ::=
"REVISION" value(Update ExtUTCTime)
"DESCRIPTION" Text
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
OBJECT-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- names of objects
-- (Note that these definitions of ObjectName and NotificationName
-- are not to be IMPORTed by MIB modules.)
ObjectName ::=
OBJECT IDENTIFIER
NotificationName ::=
OBJECT IDENTIFIER
-- indistinguishable from INTEGER, but never needs more than
-- 32-bits for a two's complement representation
Integer32 ::=
INTEGER (-2147483648..2147483647)
-- definition for objects
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
UnitsPart
"MAX-ACCESS" Access
"STATUS" Status
"DESCRIPTION" Text
ReferPart
IndexPart
DefValPart
VALUE NOTATION ::=
value(VALUE ObjectName)
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
UnitsPart ::=
"UNITS" Text
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
IndexPart ::=
"INDEX" "{" IndexTypes "}"
| "AUGMENTS" "{" Entry "}"
| empty
IndexTypes ::=
IndexType
| IndexTypes "," IndexType
IndexType ::=
"IMPLIED" Index
| Index
Entry ::=
-- use the INDEX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
DefValPart ::= "DEFVAL" "{" Defvalue "}"
| empty
BitsValue ::= BitNames
| empty
BitNames ::= BitName
| BitNames "," BitName
BitName ::= identifier
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
END

View File

@ -0,0 +1,84 @@
IF-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32, mib-2,
PhysAddress FROM ifPhysAddressImports;
ifMIB MODULE-IDENTITY
LAST-UPDATED "200006140000Z"
ORGANIZATION "IETF Interfaces MIB Working Group"
CONTACT-INFO
" Keith McCloghrie
Cisco Systems, Inc.
170 West Tasman Drive
San Jose, CA 95134-1706
US
408-526-5260
kzm@cisco.com"
DESCRIPTION
"The MIB module to describe generic objects for network
interface sub-layers. This MIB is an updated version of
MIB-II's ifTable, and incorporates the extensions defined in
RFC 1229."
REVISION "200006140000Z"
DESCRIPTION
"Clarifications agreed upon by the Interfaces MIB WG, and
published as RFC 2863."
REVISION "199602282155Z"
DESCRIPTION
"Revisions made by the Interfaces MIB WG, and published in
RFC 2233."
REVISION "199311082155Z"
DESCRIPTION
"Initial revision, published as part of RFC 1573."
::= { mib-2 31 }
ifMIBObjects OBJECT IDENTIFIER ::= { ifMIB 1 }
interfaces OBJECT IDENTIFIER ::= { mib-2 2 }
ifTable OBJECT-TYPE
SYNTAX SEQUENCE OF IfEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A list of interface entries. The number of entries is
given by the value of ifNumber."
::= { interfaces 2 }
ifEntry OBJECT-TYPE
SYNTAX IfEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry containing management information applicable to a
particular interface."
INDEX { ifIndex }
::= { ifTable 1 }
ifPhysAddress OBJECT-TYPE
SYNTAX PhysAddress
ACCESS read-only
STATUS mandatory
DESCRIPTION
"The interface's address at the protocol layer
immediately `below' the network layer in the
protocol stack. For interfaces which do not have
such an address (e.g., a serial line), this object
should contain an octet string of zero length."
::= { ifEntry 6 }
foo OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"foo mib for testing"
::= { ifEntry 9 }
END

View File

@ -0,0 +1,254 @@
SNMPv2-SMI DEFINITIONS ::= BEGIN
-- the path to the root
org OBJECT IDENTIFIER ::= { iso 3 } -- "iso" = 1
dod OBJECT IDENTIFIER ::= { org 6 }
internet OBJECT IDENTIFIER ::= { dod 1 }
directory OBJECT IDENTIFIER ::= { internet 1 }
mgmt OBJECT IDENTIFIER ::= { internet 2 }
mib-2 OBJECT IDENTIFIER ::= { mgmt 1 }
transmission OBJECT IDENTIFIER ::= { mib-2 10 }
experimental OBJECT IDENTIFIER ::= { internet 3 }
private OBJECT IDENTIFIER ::= { internet 4 }
enterprises OBJECT IDENTIFIER ::= { private 1 }
security OBJECT IDENTIFIER ::= { internet 5 }
snmpV2 OBJECT IDENTIFIER ::= { internet 6 }
-- transport domains
snmpDomains OBJECT IDENTIFIER ::= { snmpV2 1 }
-- transport proxies
snmpProxys OBJECT IDENTIFIER ::= { snmpV2 2 }
-- module identities
snmpModules OBJECT IDENTIFIER ::= { snmpV2 3 }
-- Extended UTCTime, to allow dates with four-digit years
-- (Note that this definition of ExtUTCTime is not to be IMPORTed
-- by MIB modules.)
ExtUTCTime ::= OCTET STRING(SIZE(11 | 13))
-- format is YYMMDDHHMMZ or YYYYMMDDHHMMZ
-- where: YY - last two digits of year (only years
-- between 1900-1999)
-- YYYY - last four digits of the year (any year)
-- MM - month (01 through 12)
-- DD - day of month (01 through 31)
-- HH - hours (00 through 23)
-- MM - minutes (00 through 59)
-- Z - denotes GMT (the ASCII character Z)
--
-- For example, "9502192015Z" and "199502192015Z" represent
-- 8:15pm GMT on 19 February 1995. Years after 1999 must use
-- the four digit year format. Years 1900-1999 may use the
-- two or four digit format.
-- definitions for information modules
MODULE-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"LAST-UPDATED" value(Update ExtUTCTime)
"ORGANIZATION" Text
"CONTACT-INFO" Text
"DESCRIPTION" Text
RevisionPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
RevisionPart ::=
Revisions
| empty
Revisions ::=
Revision
| Revisions Revision
Revision ::=
"REVISION" value(Update ExtUTCTime)
"DESCRIPTION" Text
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
OBJECT-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- names of objects
-- (Note that these definitions of ObjectName and NotificationName
-- are not to be IMPORTed by MIB modules.)
ObjectName ::=
OBJECT IDENTIFIER
NotificationName ::=
OBJECT IDENTIFIER
-- syntax of objects
-- the "base types" defined here are:
-- 3 built-in ASN.1 types: INTEGER, OCTET STRING, OBJECT IDENTIFIER
-- 8 application-defined types: Integer32, IpAddress, Counter32,
-- Gauge32, Unsigned32, TimeTicks, Opaque, and Counter64
ObjectSyntax ::=
CHOICE {
simple
SimpleSyntax,
-- note that SEQUENCEs for conceptual tables and
-- rows are not mentioned here...
application-wide
ApplicationSyntax
}
-- built-in ASN.1 types
SimpleSyntax ::=
CHOICE {
-- INTEGERs with a more restrictive range
-- may also be used
integer-value -- includes Integer32
INTEGER (-2147483648..2147483647),
-- OCTET STRINGs with a more restrictive size
-- may also be used
string-value
OCTET STRING (SIZE (0..65535)),
objectID-value
OBJECT IDENTIFIER
}
-- indistinguishable from INTEGER, but never needs more than
-- 32-bits for a two's complement representation
Integer32 ::=
INTEGER (-2147483648..2147483647)
-- definition for objects
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
"SYNTAX" Syntax
UnitsPart
"MAX-ACCESS" Access
"STATUS" Status
"DESCRIPTION" Text
ReferPart
IndexPart
DefValPart
VALUE NOTATION ::=
value(VALUE ObjectName)
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement),
-- a textual convention (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
UnitsPart ::=
"UNITS" Text
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
IndexPart ::=
"INDEX" "{" IndexTypes "}"
| "AUGMENTS" "{" Entry "}"
| empty
IndexTypes ::=
IndexType
| IndexTypes "," IndexType
IndexType ::=
"IMPLIED" Index
| Index
Index ::=
-- use the SYNTAX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
Entry ::=
-- use the INDEX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
DefValPart ::= "DEFVAL" "{" Defvalue "}"
| empty
Defvalue ::= -- must be valid for the type specified in
-- SYNTAX clause of same OBJECT-TYPE macro
value(ObjectSyntax)
| "{" BitsValue "}"
BitsValue ::= BitNames
| empty
BitNames ::= BitName
| BitNames "," BitName
BitName ::= identifier
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
PhysAddress ::= TEXTUAL-CONVENTION
DISPLAY-HINT "1x:"
STATUS current
DESCRIPTION
"Represents media- or physical-level addresses."
SYNTAX OCTET STRING
END

57
plugins/inputs/snmp/testdata/server vendored Normal file
View File

@ -0,0 +1,57 @@
TEST DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32 FROM fooImports;
TestMIB MODULE-IDENTITY
LAST-UPDATED "2021090800Z"
ORGANIZATION "influx"
CONTACT-INFO
"EMail: influx@email.com"
DESCRIPTION
"MIB module for testing snmp plugin
for telegraf
"
::= { iso 1 }
testingObjects OBJECT IDENTIFIER ::= { iso 0 }
testObjects OBJECT IDENTIFIER ::= { testingObjects 0 }
hostnameone OBJECT IDENTIFIER ::= {testObjects 1 }
hostname OBJECT IDENTIFIER ::= { hostnameone 1 }
testTable OBJECT IDENTIFIER ::= { testObjects 0 }
testMIBObjects OBJECT IDENTIFIER ::= { testTable 1 }
server OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 1 }
connections OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 2 }
latency OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 3 }
description OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 4 }
END

View File

@ -0,0 +1,174 @@
fooImports DEFINITIONS ::= BEGIN
-- the path to the root
org OBJECT IDENTIFIER ::= { iso 1 } -- "iso" = 1
dod OBJECT IDENTIFIER ::= { org 1 }
internet OBJECT IDENTIFIER ::= { dod 1 }
directory OBJECT IDENTIFIER ::= { internet 1 }
mgmt OBJECT IDENTIFIER ::= { internet 1 }
mib-2 OBJECT IDENTIFIER ::= { mgmt 1 }
ExtUTCTime ::= OCTET STRING(SIZE(11 | 13))
-- format is YYMMDDHHMMZ or YYYYMMDDHHMMZ
-- where: YY - last two digits of year (only years
-- between 1900-1999)
-- YYYY - last four digits of the year (any year)
-- MM - month (01 through 12)
-- DD - day of month (01 through 31)
-- HH - hours (00 through 23)
-- MM - minutes (00 through 59)
-- Z - denotes GMT (the ASCII character Z)
--
-- For example, "9502192015Z" and "199502192015Z" represent
-- 8:15pm GMT on 19 February 1995. Years after 1999 must use
-- the four digit year format. Years 1900-1999 may use the
-- two or four digit format.
-- definitions for information modules
MODULE-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"LAST-UPDATED" value(Update ExtUTCTime)
"ORGANIZATION" Text
"CONTACT-INFO" Text
"DESCRIPTION" Text
RevisionPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
RevisionPart ::=
Revisions
| empty
Revisions ::=
Revision
| Revisions Revision
Revision ::=
"REVISION" value(Update ExtUTCTime)
"DESCRIPTION" Text
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
OBJECT-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- names of objects
-- (Note that these definitions of ObjectName and NotificationName
-- are not to be IMPORTed by MIB modules.)
ObjectName ::=
OBJECT IDENTIFIER
NotificationName ::=
OBJECT IDENTIFIER
-- indistinguishable from INTEGER, but never needs more than
-- 32-bits for a two's complement representation
Integer32 ::=
INTEGER (-2147483648..2147483647)
-- definition for objects
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
UnitsPart
"MAX-ACCESS" Access
"STATUS" Status
"DESCRIPTION" Text
ReferPart
IndexPart
DefValPart
VALUE NOTATION ::=
value(VALUE ObjectName)
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
UnitsPart ::=
"UNITS" Text
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
IndexPart ::=
"INDEX" "{" IndexTypes "}"
| "AUGMENTS" "{" Entry "}"
| empty
IndexTypes ::=
IndexType
| IndexTypes "," IndexType
IndexType ::=
"IMPLIED" Index
| Index
Entry ::=
-- use the INDEX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
DefValPart ::= "DEFVAL" "{" Defvalue "}"
| empty
BitsValue ::= BitNames
| empty
BitNames ::= BitName
| BitNames "," BitName
BitName ::= identifier
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
END

View File

@ -1,17 +0,0 @@
# This config provides the data represented in the plugin documentation
# Requires net-snmp >= 5.7
#agentaddress UDP:127.0.0.1:1161
rocommunity public
override .1.0.0.0.1.1.0 octet_str "foo"
override .1.0.0.0.1.1.1 octet_str "bar"
override .1.0.0.0.1.102 octet_str "bad"
override .1.0.0.0.1.2.0 integer 1
override .1.0.0.0.1.2.1 integer 2
override .1.0.0.0.1.3.0 octet_str "0.123"
override .1.0.0.0.1.3.1 octet_str "0.456"
override .1.0.0.0.1.3.2 octet_str "9.999"
override .1.0.0.1.1 octet_str "baz"
override .1.0.0.1.2 uinteger 54321
override .1.0.0.1.3 uinteger 234

57
plugins/inputs/snmp/testdata/tableBuild vendored Normal file
View File

@ -0,0 +1,57 @@
TEST DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32 FROM fooImports;
TestMIB MODULE-IDENTITY
LAST-UPDATED "2021090800Z"
ORGANIZATION "influx"
CONTACT-INFO
"EMail: influx@email.com"
DESCRIPTION
"MIB module for testing snmp plugin
for telegraf
"
::= { iso 1 }
testingObjects OBJECT IDENTIFIER ::= { iso 0 }
testObjects OBJECT IDENTIFIER ::= { testingObjects 0 }
hostnameone OBJECT IDENTIFIER ::= {testObjects 1 }
hostname OBJECT IDENTIFIER ::= { hostnameone 1 }
testTable OBJECT IDENTIFIER ::= { testObjects 0 }
testMIBObjects OBJECT IDENTIFIER ::= { testTable 1 }
myfield1 OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 1 }
myfield2 OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 2 }
myfield3 OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 3 }
myfield4 OBJECT-TYPE
SYNTAX Integer32
ACCESS read-only
STATUS current
DESCRIPTION
"server mib for testing"
::= { testMIBObjects 4 }
END

2613
plugins/inputs/snmp/testdata/tableMib vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,119 @@
RFC1155-SMI DEFINITIONS ::= BEGIN
EXPORTS -- EVERYTHING
internet, directory, mgmt,
experimental, private, enterprises,
OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax,
ApplicationSyntax, NetworkAddress, IpAddress,
Counter, Gauge, TimeTicks, Opaque;
-- the path to the root
internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }
directory OBJECT IDENTIFIER ::= { internet 1 }
mgmt OBJECT IDENTIFIER ::= { internet 2 }
experimental OBJECT IDENTIFIER ::= { internet 3 }
private OBJECT IDENTIFIER ::= { internet 4 }
enterprises OBJECT IDENTIFIER ::= { private 1 }
-- definition of object types
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax)
"ACCESS" Access
"STATUS" Status
VALUE NOTATION ::= value (VALUE ObjectName)
Access ::= "read-only"
| "read-write"
| "write-only"
| "not-accessible"
Status ::= "mandatory"
| "optional"
| "obsolete"
END
-- names of objects in the MIB
ObjectName ::=
OBJECT IDENTIFIER
-- syntax of objects in the MIB
ObjectSyntax ::=
CHOICE {
simple
SimpleSyntax,
-- note that simple SEQUENCEs are not directly
-- mentioned here to keep things simple (i.e.,
-- prevent mis-use). However, application-wide
-- types which are IMPLICITly encoded simple
-- SEQUENCEs may appear in the following CHOICE
application-wide
ApplicationSyntax
}
SimpleSyntax ::=
CHOICE {
number
INTEGER,
string
OCTET STRING,
object
OBJECT IDENTIFIER,
empty
NULL
}
ApplicationSyntax ::=
CHOICE {
address
NetworkAddress,
counter
Counter,
gauge
Gauge,
ticks
TimeTicks,
arbitrary
Opaque
-- other application-wide types, as they are
-- defined, will be added here
}
-- application-wide types
NetworkAddress ::=
CHOICE {
internet
IpAddress
}
IpAddress ::=
[APPLICATION 0] -- in network-byte order
IMPLICIT OCTET STRING (SIZE (4))
Counter ::=
[APPLICATION 1]
IMPLICIT INTEGER (0..4294967295)
Gauge ::=
[APPLICATION 2]
IMPLICIT INTEGER (0..4294967295)
TimeTicks ::=
[APPLICATION 3]
IMPLICIT INTEGER (0..4294967295)
Opaque ::=
[APPLICATION 4] -- arbitrary ASN.1 value,
IMPLICIT OCTET STRING -- "double-wrapped"
END

786
plugins/inputs/snmp/testdata/tcpMib vendored Normal file
View File

@ -0,0 +1,786 @@
TCP-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32, Unsigned32,
Gauge32, Counter32, Counter64, IpAddress, mib-2,
MODULE-COMPLIANCE, OBJECT-GROUP, InetAddress,
InetAddressType, InetPortNumber
FROM tcpMibImports;
tcpMIB MODULE-IDENTITY
LAST-UPDATED "200502180000Z" -- 18 February 2005
ORGANIZATION
"IETF IPv6 MIB Revision Team
http://www.ietf.org/html.charters/ipv6-charter.html"
CONTACT-INFO
"Rajiv Raghunarayan (editor)
Cisco Systems Inc.
170 West Tasman Drive
San Jose, CA 95134
Phone: +1 408 853 9612
Email: <raraghun@cisco.com>
Send comments to <ipv6@ietf.org>"
DESCRIPTION
"The MIB module for managing TCP implementations.
Copyright (C) The Internet Society (2005). This version
of this MIB module is a part of RFC 4022; see the RFC
itself for full legal notices."
REVISION "200502180000Z" -- 18 February 2005
DESCRIPTION
"IP version neutral revision, published as RFC 4022."
REVISION "9411010000Z"
DESCRIPTION
"Initial SMIv2 version, published as RFC 2012."
REVISION "9103310000Z"
DESCRIPTION
"The initial revision of this MIB module was part of
MIB-II."
::= { mib-2 49 }
-- the TCP base variables group
tcp OBJECT IDENTIFIER ::= { mib-2 6 }
-- Scalars
tcpRtoAlgorithm OBJECT-TYPE
SYNTAX INTEGER {
other(1), -- none of the following
constant(2), -- a constant rto
rsre(3), -- MIL-STD-1778, Appendix B
vanj(4), -- Van Jacobson's algorithm
rfc2988(5) -- RFC 2988
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The algorithm used to determine the timeout value used for
retransmitting unacknowledged octets."
::= { tcp 1 }
tcpRtoMin OBJECT-TYPE
SYNTAX Integer32 (0..2147483647)
UNITS "milliseconds"
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The minimum value permitted by a TCP implementation for
the retransmission timeout, measured in milliseconds.
More refined semantics for objects of this type depend
on the algorithm used to determine the retransmission
timeout; in particular, the IETF standard algorithm
rfc2988(5) provides a minimum value."
::= { tcp 2 }
tcpRtoMax OBJECT-TYPE
SYNTAX Integer32 (0..2147483647)
UNITS "milliseconds"
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The maximum value permitted by a TCP implementation for
the retransmission timeout, measured in milliseconds.
More refined semantics for objects of this type depend
on the algorithm used to determine the retransmission
timeout; in particular, the IETF standard algorithm
rfc2988(5) provides an upper bound (as part of an
adaptive backoff algorithm)."
::= { tcp 3 }
tcpMaxConn OBJECT-TYPE
SYNTAX Integer32 (-1 | 0..2147483647)
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The limit on the total number of TCP connections the entity
can support. In entities where the maximum number of
connections is dynamic, this object should contain the
value -1."
::= { tcp 4 }
tcpActiveOpens OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of times that TCP connections have made a direct
transition to the SYN-SENT state from the CLOSED state.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 5 }
tcpPassiveOpens OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of times TCP connections have made a direct
transition to the SYN-RCVD state from the LISTEN state.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 6 }
tcpAttemptFails OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of times that TCP connections have made a direct
transition to the CLOSED state from either the SYN-SENT
state or the SYN-RCVD state, plus the number of times that
TCP connections have made a direct transition to the
LISTEN state from the SYN-RCVD state.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 7 }
tcpEstabResets OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of times that TCP connections have made a direct
transition to the CLOSED state from either the ESTABLISHED
state or the CLOSE-WAIT state.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 8 }
tcpCurrEstab OBJECT-TYPE
SYNTAX Gauge32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of TCP connections for which the current state
is either ESTABLISHED or CLOSE-WAIT."
::= { tcp 9 }
tcpInSegs OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of segments received, including those
received in error. This count includes segments received
on currently established connections.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 10 }
tcpOutSegs OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of segments sent, including those on
current connections but excluding those containing only
retransmitted octets.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 11 }
tcpRetransSegs OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of segments retransmitted; that is, the
number of TCP segments transmitted containing one or more
previously transmitted octets.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 12 }
tcpInErrs OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of segments received in error (e.g., bad
TCP checksums).
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 14 }
tcpOutRsts OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of TCP segments sent containing the RST flag.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 15 }
-- { tcp 16 } was used to represent the ipv6TcpConnTable in RFC 2452,
-- which has since been obsoleted. It MUST not be used.
tcpHCInSegs OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of segments received, including those
received in error. This count includes segments received
on currently established connections. This object is
the 64-bit equivalent of tcpInSegs.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 17 }
tcpHCOutSegs OBJECT-TYPE
SYNTAX Counter64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The total number of segments sent, including those on
current connections but excluding those containing only
retransmitted octets. This object is the 64-bit
equivalent of tcpOutSegs.
Discontinuities in the value of this counter are
indicated via discontinuities in the value of sysUpTime."
::= { tcp 18 }
-- The TCP Connection table
tcpConnectionTable OBJECT-TYPE
SYNTAX SEQUENCE OF TcpConnectionEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A table containing information about existing TCP
connections. Note that unlike earlier TCP MIBs, there
is a separate table for connections in the LISTEN state."
::= { tcp 19 }
tcpConnectionEntry OBJECT-TYPE
SYNTAX TcpConnectionEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A conceptual row of the tcpConnectionTable containing
information about a particular current TCP connection.
Each row of this table is transient in that it ceases to
exist when (or soon after) the connection makes the
transition to the CLOSED state."
INDEX { tcpConnectionLocalAddressType,
tcpConnectionLocalAddress,
tcpConnectionLocalPort,
tcpConnectionRemAddressType,
tcpConnectionRemAddress,
tcpConnectionRemPort }
::= { tcpConnectionTable 1 }
TcpConnectionEntry ::= SEQUENCE {
tcpConnectionLocalAddressType InetAddressType,
tcpConnectionLocalAddress InetAddress,
tcpConnectionLocalPort InetPortNumber,
tcpConnectionRemAddressType InetAddressType,
tcpConnectionRemAddress InetAddress,
tcpConnectionRemPort InetPortNumber,
tcpConnectionState INTEGER,
tcpConnectionProcess Unsigned32
}
tcpConnectionLocalAddressType OBJECT-TYPE
SYNTAX InetAddressType
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The address type of tcpConnectionLocalAddress."
::= { tcpConnectionEntry 1 }
tcpConnectionLocalAddress OBJECT-TYPE
SYNTAX InetAddress
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The local IP address for this TCP connection. The type
of this address is determined by the value of
tcpConnectionLocalAddressType.
As this object is used in the index for the
tcpConnectionTable, implementors should be
careful not to create entries that would result in OIDs
with more than 128 subidentifiers; otherwise the information
cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3."
::= { tcpConnectionEntry 2 }
tcpConnectionLocalPort OBJECT-TYPE
SYNTAX InetPortNumber
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The local port number for this TCP connection."
::= { tcpConnectionEntry 3 }
tcpConnectionRemAddressType OBJECT-TYPE
SYNTAX InetAddressType
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The address type of tcpConnectionRemAddress."
::= { tcpConnectionEntry 4 }
tcpConnectionRemAddress OBJECT-TYPE
SYNTAX InetAddress
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The remote IP address for this TCP connection. The type
of this address is determined by the value of
tcpConnectionRemAddressType.
As this object is used in the index for the
tcpConnectionTable, implementors should be
careful not to create entries that would result in OIDs
with more than 128 subidentifiers; otherwise the information
cannot be accessed by using SNMPv1, SNMPv2c, or SNMPv3."
::= { tcpConnectionEntry 5 }
tcpConnectionRemPort OBJECT-TYPE
SYNTAX InetPortNumber
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The remote port number for this TCP connection."
::= { tcpConnectionEntry 6 }
tcpConnectionState OBJECT-TYPE
SYNTAX INTEGER {
closed(1),
listen(2),
synSent(3),
synReceived(4),
established(5),
finWait1(6),
finWait2(7),
closeWait(8),
lastAck(9),
closing(10),
timeWait(11),
deleteTCB(12)
}
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The state of this TCP connection.
The value listen(2) is included only for parallelism to the
old tcpConnTable and should not be used. A connection in
LISTEN state should be present in the tcpListenerTable.
The only value that may be set by a management station is
deleteTCB(12). Accordingly, it is appropriate for an agent
to return a `badValue' response if a management station
attempts to set this object to any other value.
If a management station sets this object to the value
deleteTCB(12), then the TCB (as defined in [RFC793]) of
the corresponding connection on the managed node is
deleted, resulting in immediate termination of the
connection.
As an implementation-specific option, a RST segment may be
sent from the managed node to the other TCP endpoint (note,
however, that RST segments are not sent reliably)."
::= { tcpConnectionEntry 7 }
tcpConnectionProcess OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The system's process ID for the process associated with
this connection, or zero if there is no such process. This
value is expected to be the same as HOST-RESOURCES-MIB::
hrSWRunIndex or SYSAPPL-MIB::sysApplElmtRunIndex for some
row in the appropriate tables."
::= { tcpConnectionEntry 8 }
-- The TCP Listener table
tcpListenerTable OBJECT-TYPE
SYNTAX SEQUENCE OF TcpListenerEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A table containing information about TCP listeners. A
listening application can be represented in three
possible ways:
1. An application that is willing to accept both IPv4 and
IPv6 datagrams is represented by
a tcpListenerLocalAddressType of unknown (0) and
a tcpListenerLocalAddress of ''h (a zero-length
octet-string).
2. An application that is willing to accept only IPv4 or
IPv6 datagrams is represented by a
tcpListenerLocalAddressType of the appropriate address
type and a tcpListenerLocalAddress of '0.0.0.0' or '::'
respectively.
3. An application that is listening for data destined
only to a specific IP address, but from any remote
system, is represented by a tcpListenerLocalAddressType
of an appropriate address type, with
tcpListenerLocalAddress as the specific local address.
NOTE: The address type in this table represents the
address type used for the communication, irrespective
of the higher-layer abstraction. For example, an
application using IPv6 'sockets' to communicate via
IPv4 between ::ffff:10.0.0.1 and ::ffff:10.0.0.2 would
use InetAddressType ipv4(1))."
::= { tcp 20 }
tcpListenerEntry OBJECT-TYPE
SYNTAX TcpListenerEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A conceptual row of the tcpListenerTable containing
information about a particular TCP listener."
INDEX { tcpListenerLocalAddressType,
tcpListenerLocalAddress,
tcpListenerLocalPort }
::= { tcpListenerTable 1 }
TcpListenerEntry ::= SEQUENCE {
tcpListenerLocalAddressType InetAddressType,
tcpListenerLocalAddress InetAddress,
tcpListenerLocalPort InetPortNumber,
tcpListenerProcess Unsigned32
}
tcpListenerLocalAddressType OBJECT-TYPE
SYNTAX InetAddressType
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The address type of tcpListenerLocalAddress. The value
should be unknown (0) if connection initiations to all
local IP addresses are accepted."
::= { tcpListenerEntry 1 }
tcpListenerLocalAddress OBJECT-TYPE
SYNTAX InetAddress
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The local IP address for this TCP connection.
The value of this object can be represented in three
possible ways, depending on the characteristics of the
listening application:
1. For an application willing to accept both IPv4 and
IPv6 datagrams, the value of this object must be
''h (a zero-length octet-string), with the value
of the corresponding tcpListenerLocalAddressType
object being unknown (0).
2. For an application willing to accept only IPv4 or
IPv6 datagrams, the value of this object must be
'0.0.0.0' or '::' respectively, with
tcpListenerLocalAddressType representing the
appropriate address type.
3. For an application which is listening for data
destined only to a specific IP address, the value
of this object is the specific local address, with
tcpListenerLocalAddressType representing the
appropriate address type.
As this object is used in the index for the
tcpListenerTable, implementors should be
careful not to create entries that would result in OIDs
with more than 128 subidentifiers; otherwise the information
cannot be accessed, using SNMPv1, SNMPv2c, or SNMPv3."
::= { tcpListenerEntry 2 }
tcpListenerLocalPort OBJECT-TYPE
SYNTAX InetPortNumber
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The local port number for this TCP connection."
::= { tcpListenerEntry 3 }
tcpListenerProcess OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The system's process ID for the process associated with
this listener, or zero if there is no such process. This
value is expected to be the same as HOST-RESOURCES-MIB::
hrSWRunIndex or SYSAPPL-MIB::sysApplElmtRunIndex for some
row in the appropriate tables."
::= { tcpListenerEntry 4 }
-- The deprecated TCP Connection table
tcpConnTable OBJECT-TYPE
SYNTAX SEQUENCE OF TcpConnEntry
MAX-ACCESS not-accessible
STATUS deprecated
DESCRIPTION
"A table containing information about existing IPv4-specific
TCP connections or listeners. This table has been
deprecated in favor of the version neutral
tcpConnectionTable."
::= { tcp 13 }
tcpConnEntry OBJECT-TYPE
SYNTAX TcpConnEntry
MAX-ACCESS not-accessible
STATUS deprecated
DESCRIPTION
"A conceptual row of the tcpConnTable containing information
about a particular current IPv4 TCP connection. Each row
of this table is transient in that it ceases to exist when
(or soon after) the connection makes the transition to the
CLOSED state."
INDEX { tcpConnLocalAddress,
tcpConnLocalPort,
tcpConnRemAddress,
tcpConnRemPort }
::= { tcpConnTable 1 }
TcpConnEntry ::= SEQUENCE {
tcpConnState INTEGER,
tcpConnLocalAddress IpAddress,
tcpConnLocalPort Integer32,
tcpConnRemAddress IpAddress,
tcpConnRemPort Integer32
}
tcpConnState OBJECT-TYPE
SYNTAX INTEGER {
closed(1),
listen(2),
synSent(3),
synReceived(4),
established(5),
finWait1(6),
finWait2(7),
closeWait(8),
lastAck(9),
closing(10),
timeWait(11),
deleteTCB(12)
}
MAX-ACCESS read-write
STATUS deprecated
DESCRIPTION
"The state of this TCP connection.
The only value that may be set by a management station is
deleteTCB(12). Accordingly, it is appropriate for an agent
to return a `badValue' response if a management station
attempts to set this object to any other value.
If a management station sets this object to the value
deleteTCB(12), then the TCB (as defined in [RFC793]) of
the corresponding connection on the managed node is
deleted, resulting in immediate termination of the
connection.
As an implementation-specific option, a RST segment may be
sent from the managed node to the other TCP endpoint (note,
however, that RST segments are not sent reliably)."
::= { tcpConnEntry 1 }
tcpConnLocalAddress OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS deprecated
DESCRIPTION
"The local IP address for this TCP connection. In the case
of a connection in the listen state willing to
accept connections for any IP interface associated with the
node, the value 0.0.0.0 is used."
::= { tcpConnEntry 2 }
tcpConnLocalPort OBJECT-TYPE
SYNTAX Integer32 (0..65535)
MAX-ACCESS read-only
STATUS deprecated
DESCRIPTION
"The local port number for this TCP connection."
::= { tcpConnEntry 3 }
tcpConnRemAddress OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS deprecated
DESCRIPTION
"The remote IP address for this TCP connection."
::= { tcpConnEntry 4 }
tcpConnRemPort OBJECT-TYPE
SYNTAX Integer32 (0..65535)
MAX-ACCESS read-only
STATUS deprecated
DESCRIPTION
"The remote port number for this TCP connection."
::= { tcpConnEntry 5 }
-- conformance information
tcpMIBConformance OBJECT IDENTIFIER ::= { tcpMIB 2 }
tcpMIBCompliances OBJECT IDENTIFIER ::= { tcpMIBConformance 1 }
tcpMIBGroups OBJECT IDENTIFIER ::= { tcpMIBConformance 2 }
-- compliance statements
tcpMIBCompliance2 MODULE-COMPLIANCE
STATUS current
DESCRIPTION
"The compliance statement for systems that implement TCP.
A number of INDEX objects cannot be
represented in the form of OBJECT clauses in SMIv2 but
have the following compliance requirements,
expressed in OBJECT clause form in this description
clause:
-- OBJECT tcpConnectionLocalAddressType
-- SYNTAX InetAddressType { ipv4(1), ipv6(2) }
-- DESCRIPTION
-- This MIB requires support for only global IPv4
-- and IPv6 address types.
--
-- OBJECT tcpConnectionRemAddressType
-- SYNTAX InetAddressType { ipv4(1), ipv6(2) }
-- DESCRIPTION
-- This MIB requires support for only global IPv4
-- and IPv6 address types.
--
-- OBJECT tcpListenerLocalAddressType
-- SYNTAX InetAddressType { unknown(0), ipv4(1),
-- ipv6(2) }
-- DESCRIPTION
-- This MIB requires support for only global IPv4
-- and IPv6 address types. The type unknown also
-- needs to be supported to identify a special
-- case in the listener table: a listen using
-- both IPv4 and IPv6 addresses on the device.
--
"
MODULE -- this module
MANDATORY-GROUPS { tcpBaseGroup, tcpConnectionGroup,
tcpListenerGroup }
GROUP tcpHCGroup
DESCRIPTION
"This group is mandatory for systems that are capable
of receiving or transmitting more than 1 million TCP
segments per second. 1 million segments per second will
cause a Counter32 to wrap in just over an hour."
OBJECT tcpConnectionState
SYNTAX INTEGER { closed(1), listen(2), synSent(3),
synReceived(4), established(5),
finWait1(6), finWait2(7), closeWait(8),
lastAck(9), closing(10), timeWait(11) }
MIN-ACCESS read-only
DESCRIPTION
"Write access is not required, nor is support for the value
deleteTCB (12)."
::= { tcpMIBCompliances 2 }
tcpMIBCompliance MODULE-COMPLIANCE
STATUS deprecated
DESCRIPTION
"The compliance statement for IPv4-only systems that
implement TCP. In order to be IP version independent, this
compliance statement is deprecated in favor of
tcpMIBCompliance2. However, agents are still encouraged
to implement these objects in order to interoperate with
the deployed base of managers."
MODULE -- this module
MANDATORY-GROUPS { tcpGroup }
OBJECT tcpConnState
MIN-ACCESS read-only
DESCRIPTION
"Write access is not required."
::= { tcpMIBCompliances 1 }
-- units of conformance
tcpGroup OBJECT-GROUP
OBJECTS { tcpRtoAlgorithm, tcpRtoMin, tcpRtoMax,
tcpMaxConn, tcpActiveOpens,
tcpPassiveOpens, tcpAttemptFails,
tcpEstabResets, tcpCurrEstab, tcpInSegs,
tcpOutSegs, tcpRetransSegs, tcpConnState,
tcpConnLocalAddress, tcpConnLocalPort,
tcpConnRemAddress, tcpConnRemPort,
tcpInErrs, tcpOutRsts }
STATUS deprecated
DESCRIPTION
"The tcp group of objects providing for management of TCP
entities."
::= { tcpMIBGroups 1 }
tcpBaseGroup OBJECT-GROUP
OBJECTS { tcpRtoAlgorithm, tcpRtoMin, tcpRtoMax,
tcpMaxConn, tcpActiveOpens,
tcpPassiveOpens, tcpAttemptFails,
tcpEstabResets, tcpCurrEstab, tcpInSegs,
tcpOutSegs, tcpRetransSegs,
tcpInErrs, tcpOutRsts }
STATUS current
DESCRIPTION
"The group of counters common to TCP entities."
::= { tcpMIBGroups 2 }
tcpConnectionGroup OBJECT-GROUP
OBJECTS { tcpConnectionState, tcpConnectionProcess }
STATUS current
DESCRIPTION
"The group provides general information about TCP
connections."
::= { tcpMIBGroups 3 }
tcpListenerGroup OBJECT-GROUP
OBJECTS { tcpListenerProcess }
STATUS current
DESCRIPTION
"This group has objects providing general information about
TCP listeners."
::= { tcpMIBGroups 4 }
tcpHCGroup OBJECT-GROUP
OBJECTS { tcpHCInSegs, tcpHCOutSegs }
STATUS current
DESCRIPTION
"The group of objects providing for counters of high speed
TCP implementations."
::= { tcpMIBGroups 5 }
END

View File

@ -0,0 +1,639 @@
SNMPv2-SMI DEFINITIONS ::= BEGIN
-- the path to the root
org OBJECT IDENTIFIER ::= { iso 3 } -- "iso" = 1
dod OBJECT IDENTIFIER ::= { org 6 }
internet OBJECT IDENTIFIER ::= { dod 1 }
directory OBJECT IDENTIFIER ::= { internet 1 }
mgmt OBJECT IDENTIFIER ::= { internet 2 }
mib-2 OBJECT IDENTIFIER ::= { mgmt 1 }
transmission OBJECT IDENTIFIER ::= { mib-2 10 }
experimental OBJECT IDENTIFIER ::= { internet 3 }
private OBJECT IDENTIFIER ::= { internet 4 }
enterprises OBJECT IDENTIFIER ::= { private 1 }
security OBJECT IDENTIFIER ::= { internet 5 }
snmpV2 OBJECT IDENTIFIER ::= { internet 6 }
-- transport domains
snmpDomains OBJECT IDENTIFIER ::= { snmpV2 1 }
-- transport proxies
snmpProxys OBJECT IDENTIFIER ::= { snmpV2 2 }
-- module identities
snmpModules OBJECT IDENTIFIER ::= { snmpV2 3 }
-- Extended UTCTime, to allow dates with four-digit years
-- (Note that this definition of ExtUTCTime is not to be IMPORTed
-- by MIB modules.)
ExtUTCTime ::= OCTET STRING(SIZE(11 | 13))
-- format is YYMMDDHHMMZ or YYYYMMDDHHMMZ
-- where: YY - last two digits of year (only years
-- between 1900-1999)
-- YYYY - last four digits of the year (any year)
-- MM - month (01 through 12)
-- DD - day of month (01 through 31)
-- HH - hours (00 through 23)
-- MM - minutes (00 through 59)
-- Z - denotes GMT (the ASCII character Z)
--
-- For example, "9502192015Z" and "199502192015Z" represent
-- 8:15pm GMT on 19 February 1995. Years after 1999 must use
-- the four digit year format. Years 1900-1999 may use the
-- two or four digit format.
-- definitions for information modules
MODULE-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"LAST-UPDATED" value(Update ExtUTCTime)
"ORGANIZATION" Text
"CONTACT-INFO" Text
"DESCRIPTION" Text
RevisionPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
RevisionPart ::=
Revisions
| empty
Revisions ::=
Revision
| Revisions Revision
Revision ::=
"REVISION" value(Update ExtUTCTime)
"DESCRIPTION" Text
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
OBJECT-IDENTITY MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- names of objects
-- (Note that these definitions of ObjectName and NotificationName
-- are not to be IMPORTed by MIB modules.)
ObjectName ::=
OBJECT IDENTIFIER
NotificationName ::=
OBJECT IDENTIFIER
-- syntax of objects
-- the "base types" defined here are:
-- 3 built-in ASN.1 types: INTEGER, OCTET STRING, OBJECT IDENTIFIER
-- 8 application-defined types: Integer32, IpAddress, Counter32,
-- Gauge32, Unsigned32, TimeTicks, Opaque, and Counter64
ObjectSyntax ::=
CHOICE {
simple
SimpleSyntax,
-- note that SEQUENCEs for conceptual tables and
-- rows are not mentioned here...
application-wide
ApplicationSyntax
}
-- built-in ASN.1 types
SimpleSyntax ::=
CHOICE {
-- INTEGERs with a more restrictive range
-- may also be used
integer-value -- includes Integer32
INTEGER (-2147483648..2147483647),
-- OCTET STRINGs with a more restrictive size
-- may also be used
string-value
OCTET STRING (SIZE (0..65535)),
objectID-value
OBJECT IDENTIFIER
}
-- indistinguishable from INTEGER, but never needs more than
-- 32-bits for a two's complement representation
Integer32 ::=
INTEGER (-2147483648..2147483647)
-- application-wide types
ApplicationSyntax ::=
CHOICE {
ipAddress-value
IpAddress,
counter-value
Counter32,
timeticks-value
TimeTicks,
arbitrary-value
Opaque,
big-counter-value
Counter64,
unsigned-integer-value -- includes Gauge32
Unsigned32
}
-- in network-byte order
-- (this is a tagged type for historical reasons)
IpAddress ::=
[APPLICATION 0]
IMPLICIT OCTET STRING (SIZE (4))
-- this wraps
Counter32 ::=
[APPLICATION 1]
IMPLICIT INTEGER (0..4294967295)
-- this doesn't wrap
Gauge32 ::=
[APPLICATION 2]
IMPLICIT INTEGER (0..4294967295)
-- an unsigned 32-bit quantity
-- indistinguishable from Gauge32
Unsigned32 ::=
[APPLICATION 2]
IMPLICIT INTEGER (0..4294967295)
-- hundredths of seconds since an epoch
TimeTicks ::=
[APPLICATION 3]
IMPLICIT INTEGER (0..4294967295)
-- for backward-compatibility only
Opaque ::=
[APPLICATION 4]
IMPLICIT OCTET STRING
-- for counters that wrap in less than one hour with only 32 bits
Counter64 ::=
[APPLICATION 6]
IMPLICIT INTEGER (0..18446744073709551615)
-- definition for objects
OBJECT-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
"SYNTAX" Syntax
UnitsPart
"MAX-ACCESS" Access
"STATUS" Status
"DESCRIPTION" Text
ReferPart
IndexPart
DefValPart
VALUE NOTATION ::=
value(VALUE ObjectName)
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement),
-- a textual convention (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
UnitsPart ::=
"UNITS" Text
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
IndexPart ::=
"INDEX" "{" IndexTypes "}"
| "AUGMENTS" "{" Entry "}"
| empty
IndexTypes ::=
IndexType
| IndexTypes "," IndexType
IndexType ::=
"IMPLIED" Index
| Index
Index ::=
-- use the SYNTAX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
Entry ::=
-- use the INDEX value of the
-- correspondent OBJECT-TYPE invocation
value(ObjectName)
DefValPart ::= "DEFVAL" "{" Defvalue "}"
| empty
Defvalue ::= -- must be valid for the type specified in
-- SYNTAX clause of same OBJECT-TYPE macro
value(ObjectSyntax)
| "{" BitsValue "}"
BitsValue ::= BitNames
| empty
BitNames ::= BitName
| BitNames "," BitName
BitName ::= identifier
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- definitions for notifications
NOTIFICATION-TYPE MACRO ::=
BEGIN
TYPE NOTATION ::=
ObjectsPart
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE NotificationName)
ObjectsPart ::=
"OBJECTS" "{" Objects "}"
| empty
Objects ::=
Object
| Objects "," Object
Object ::=
value(ObjectName)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in section 3.1.1
Text ::= value(IA5String)
END
-- definitions of administrative identifiers
zeroDotZero OBJECT-IDENTITY
STATUS current
DESCRIPTION
"A value used for null identifiers."
::= { 0 0 }
TEXTUAL-CONVENTION MACRO ::=
BEGIN
TYPE NOTATION ::=
DisplayPart
"STATUS" Status
"DESCRIPTION" Text
ReferPart
"SYNTAX" Syntax
VALUE NOTATION ::=
value(VALUE Syntax) -- adapted ASN.1
DisplayPart ::=
"DISPLAY-HINT" Text
| empty
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in [2]
Text ::= value(IA5String)
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
END
MODULE-COMPLIANCE MACRO ::=
BEGIN
TYPE NOTATION ::=
"STATUS" Status
"DESCRIPTION" Text
ReferPart
ModulePart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
ModulePart ::=
Modules
Modules ::=
Module
| Modules Module
Module ::=
-- name of module --
"MODULE" ModuleName
MandatoryPart
CompliancePart
ModuleName ::=
-- identifier must start with uppercase letter
identifier ModuleIdentifier
-- must not be empty unless contained
-- in MIB Module
| empty
ModuleIdentifier ::=
value(OBJECT IDENTIFIER)
| empty
MandatoryPart ::=
"MANDATORY-GROUPS" "{" Groups "}"
| empty
Groups ::=
Group
| Groups "," Group
Group ::=
value(OBJECT IDENTIFIER)
CompliancePart ::=
Compliances
| empty
Compliances ::=
Compliance
| Compliances Compliance
Compliance ::=
ComplianceGroup
| Object
ComplianceGroup ::=
"GROUP" value(OBJECT IDENTIFIER)
"DESCRIPTION" Text
Object ::=
"OBJECT" value(ObjectName)
SyntaxPart
WriteSyntaxPart
AccessPart
"DESCRIPTION" Text
-- must be a refinement for object's SYNTAX clause
SyntaxPart ::= "SYNTAX" Syntax
| empty
-- must be a refinement for object's SYNTAX clause
WriteSyntaxPart ::= "WRITE-SYNTAX" Syntax
| empty
Syntax ::= -- Must be one of the following:
-- a base type (or its refinement),
-- a textual convention (or its refinement), or
-- a BITS pseudo-type
type
| "BITS" "{" NamedBits "}"
NamedBits ::= NamedBit
| NamedBits "," NamedBit
NamedBit ::= identifier "(" number ")" -- number is nonnegative
AccessPart ::=
"MIN-ACCESS" Access
| empty
Access ::=
"not-accessible"
| "accessible-for-notify"
| "read-only"
| "read-write"
| "read-create"
-- a character string as defined in [2]
Text ::= value(IA5String)
END
OBJECT-GROUP MACRO ::=
BEGIN
TYPE NOTATION ::=
ObjectsPart
"STATUS" Status
"DESCRIPTION" Text
ReferPart
VALUE NOTATION ::=
value(VALUE OBJECT IDENTIFIER)
ObjectsPart ::=
"OBJECTS" "{" Objects "}"
Objects ::=
Object
| Objects "," Object
Object ::=
value(ObjectName)
Status ::=
"current"
| "deprecated"
| "obsolete"
ReferPart ::=
"REFERENCE" Text
| empty
-- a character string as defined in [2]
Text ::= value(IA5String)
END
InetPortNumber ::= TEXTUAL-CONVENTION
DISPLAY-HINT "d"
STATUS current
DESCRIPTION
"Represents a 16 bit port number of an Internet transport
layer protocol. Port numbers are assigned by IANA. A
current list of all assignments is available from
<http://www.iana.org/>.
The value zero is object-specific and must be defined as
part of the description of any object that uses this
syntax. Examples of the usage of zero might include
situations where a port number is unknown, or when the
value zero is used as a wildcard in a filter."
REFERENCE "STD 6 (RFC 768), STD 7 (RFC 793) and RFC 2960"
SYNTAX Unsigned32 (0..65535)
InetAddress ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION
"Denotes a generic Internet address.
An InetAddress value is always interpreted within the context
of an InetAddressType value. Every usage of the InetAddress
textual convention is required to specify the InetAddressType
object that provides the context. It is suggested that the
InetAddressType object be logically registered before the
object(s) that use the InetAddress textual convention, if
they appear in the same logical row.
The value of an InetAddress object must always be
consistent with the value of the associated InetAddressType
object. Attempts to set an InetAddress object to a value
inconsistent with the associated InetAddressType
must fail with an inconsistentValue error.
When this textual convention is used as the syntax of an
index object, there may be issues with the limit of 128
sub-identifiers specified in SMIv2, STD 58. In this case,
the object definition MUST include a 'SIZE' clause to
limit the number of potential instance sub-identifiers;
otherwise the applicable constraints MUST be stated in
the appropriate conceptual row DESCRIPTION clauses, or
in the surrounding documentation if there is no single
DESCRIPTION clause that is appropriate."
SYNTAX OCTET STRING (SIZE (0..255))
InetAddressType ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION
"A value that represents a type of Internet address.
unknown(0) An unknown address type. This value MUST
be used if the value of the corresponding
InetAddress object is a zero-length string.
It may also be used to indicate an IP address
that is not in one of the formats defined
below.
ipv4(1) An IPv4 address as defined by the
InetAddressIPv4 textual convention.
ipv6(2) An IPv6 address as defined by the
InetAddressIPv6 textual convention.
ipv4z(3) A non-global IPv4 address including a zone
index as defined by the InetAddressIPv4z
textual convention.
ipv6z(4) A non-global IPv6 address including a zone
index as defined by the InetAddressIPv6z
textual convention.
dns(16) A DNS domain name as defined by the
InetAddressDNS textual convention.
Each definition of a concrete InetAddressType value must be
accompanied by a definition of a textual convention for use
with that InetAddressType.
To support future extensions, the InetAddressType textual
convention SHOULD NOT be sub-typed in object type definitions.
It MAY be sub-typed in compliance statements in order to
require only a subset of these address types for a compliant
implementation.
Implementations must ensure that InetAddressType objects
and any dependent objects (e.g., InetAddress objects) are
consistent. An inconsistentValue error must be generated
if an attempt to change an InetAddressType object would,
for example, lead to an undefined InetAddress value. In
particular, InetAddressType/InetAddress pairs must be
changed together if the address type changes (e.g., from
ipv6(2) to ipv4(1))."
SYNTAX INTEGER {
unknown(0),
ipv4(1),
ipv6(2),
ipv4z(3),
ipv6z(4),
dns(16)
}
END

View File

@ -1,97 +0,0 @@
TEST DEFINITIONS ::= BEGIN
testOID ::= { 1 0 0 }
testTable OBJECT-TYPE
SYNTAX SEQUENCE OF testTableEntry
MAX-ACCESS not-accessible
STATUS current
::= { testOID 0 }
testTableEntry OBJECT-TYPE
SYNTAX TestTableEntry
MAX-ACCESS not-accessible
STATUS current
INDEX {
server
}
::= { testTable 1 }
TestTableEntry ::=
SEQUENCE {
server OCTET STRING,
connections INTEGER,
latency OCTET STRING,
description OCTET STRING,
}
server OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testTableEntry 1 }
connections OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
::= { testTableEntry 2 }
latency OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testTableEntry 3 }
description OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testTableEntry 4 }
hostname OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testOID 1 1 }
testSecondaryTable OBJECT-TYPE
SYNTAX SEQUENCE OF testSecondaryTableEntry
MAX-ACCESS not-accessible
STATUS current
::= { testOID 3 }
testSecondaryTableEntry OBJECT-TYPE
SYNTAX TestSecondaryTableEntry
MAX-ACCESS not-accessible
STATUS current
INDEX {
instance
}
::= { testSecondaryTable 1 }
TestSecondaryTableEntry ::=
SEQUENCE {
instance OCTET STRING,
connections INTEGER,
testTableIndex INTEGER,
}
instance OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testSecondaryTableEntry 1 }
connections OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testSecondaryTableEntry 2 }
testTableIndex OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
::= { testSecondaryTableEntry 3 }
END

View File

@ -6,6 +6,11 @@ notifications (traps and inform requests).
Notifications are received on plain UDP. The port to listen is
configurable.
## Note about Paths
Path is a global variable, separate snmp instances will append the specified
path onto the global path variable
## Configuration
```toml

View File

@ -3,28 +3,20 @@ package snmp_trap
import (
"fmt"
"net"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/internal/snmp"
"github.com/influxdata/telegraf/plugins/inputs"
"github.com/sleepinggenius2/gosmi"
"github.com/sleepinggenius2/gosmi/types"
"github.com/gosnmp/gosnmp"
)
var defaultTimeout = config.Duration(time.Second * 5)
type mibEntry struct {
mibName string
oidText string
}
type SnmpTrap struct {
ServiceAddress string `toml:"service_address"`
Timeout config.Duration `toml:"timeout"`
@ -45,7 +37,7 @@ type SnmpTrap struct {
acc telegraf.Accumulator
listener *gosnmp.TrapListener
timeFunc func() time.Time
lookupFunc func(string) (mibEntry, error)
lookupFunc func(string) (snmp.MibEntry, error)
errCh chan error
makeHandlerWrapper func(gosnmp.TrapHandlerFunc) gosnmp.TrapHandlerFunc
@ -102,7 +94,7 @@ func init() {
inputs.Add("snmp_trap", func() telegraf.Input {
return &SnmpTrap{
timeFunc: time.Now,
lookupFunc: lookup,
lookupFunc: snmp.TrapLookup,
ServiceAddress: "udp://:162",
Timeout: defaultTimeout,
Path: []string{"/usr/share/snmp/mibs"},
@ -112,52 +104,13 @@ func init() {
}
func (s *SnmpTrap) Init() error {
// must init, append path for each directory, load module for every file
// or gosmi will fail without saying why
gosmi.Init()
err := s.getMibsPath()
err := snmp.LoadMibsFromPath(s.Path, s.Log)
if err != nil {
s.Log.Errorf("Could not get path %v", err)
}
return nil
}
func (s *SnmpTrap) getMibsPath() error {
var folders []string
for _, mibPath := range s.Path {
gosmi.AppendPath(mibPath)
folders = append(folders, mibPath)
err := filepath.Walk(mibPath, func(path string, info os.FileInfo, err error) error {
if info.Mode()&os.ModeSymlink != 0 {
s, _ := os.Readlink(path)
folders = append(folders, s)
}
return nil
})
if err != nil {
s.Log.Errorf("Filepath could not be walked %v", err)
}
for _, folder := range folders {
err := filepath.Walk(folder, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
gosmi.AppendPath(path)
} else if info.Mode()&os.ModeSymlink == 0 {
_, err := gosmi.LoadModule(info.Name())
if err != nil {
s.Log.Errorf("Module could not be loaded %v", err)
}
}
return nil
})
if err != nil {
s.Log.Errorf("Filepath could not be walked %v", err)
}
}
folders = []string{}
}
return nil
}
func (s *SnmpTrap) Start(acc telegraf.Accumulator) error {
s.acc = acc
s.listener = gosnmp.NewTrapListener()
@ -278,17 +231,16 @@ func (s *SnmpTrap) Start(acc telegraf.Accumulator) error {
func (s *SnmpTrap) Stop() {
s.listener.Close()
defer gosmi.Exit()
err := <-s.errCh
if nil != err {
s.Log.Errorf("Error stopping trap listener %v", err)
}
}
func setTrapOid(tags map[string]string, oid string, e mibEntry) {
func setTrapOid(tags map[string]string, oid string, e snmp.MibEntry) {
tags["oid"] = oid
tags["name"] = e.oidText
tags["mib"] = e.mibName
tags["name"] = e.OidText
tags["mib"] = e.MibName
}
func makeTrapHandler(s *SnmpTrap) gosnmp.TrapHandlerFunc {
@ -348,7 +300,7 @@ func makeTrapHandler(s *SnmpTrap) gosnmp.TrapHandlerFunc {
return
}
var e mibEntry
var e snmp.MibEntry
var err error
e, err = s.lookupFunc(val)
if nil != err {
@ -356,7 +308,7 @@ func makeTrapHandler(s *SnmpTrap) gosnmp.TrapHandlerFunc {
return
}
value = e.oidText
value = e.OidText
// 1.3.6.1.6.3.1.1.4.1.0 is SNMPv2-MIB::snmpTrapOID.0.
// If v.Name is this oid, set a tag of the trap name.
@ -374,7 +326,7 @@ func makeTrapHandler(s *SnmpTrap) gosnmp.TrapHandlerFunc {
return
}
name := e.oidText
name := e.OidText
fields[name] = value
}
@ -396,23 +348,3 @@ func makeTrapHandler(s *SnmpTrap) gosnmp.TrapHandlerFunc {
s.acc.AddFields("snmp_trap", fields, tags, tm)
}
}
func lookup(oid string) (e mibEntry, err error) {
var node gosmi.SmiNode
node, err = gosmi.GetNodeByOID(types.OidMustFromString(oid))
// ensure modules are loaded or node will be empty (might not error)
if err != nil {
return e, err
}
e.oidText = node.RenderQualified()
i := strings.Index(e.oidText, "::")
if i == -1 {
return e, fmt.Errorf("not found")
}
e.mibName = e.oidText[:i]
e.oidText = e.oidText[i+2:]
return e, nil
}

View File

@ -13,6 +13,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal/snmp"
"github.com/influxdata/telegraf/testutil"
)
@ -132,7 +133,7 @@ func TestReceiveTrap(t *testing.T) {
type entry struct {
oid string
e mibEntry
e snmp.MibEntry
}
// If the first pdu isn't type TimeTicks, gosnmp.SendTrap() will
@ -180,23 +181,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -263,16 +264,16 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
".1.2.3.4.5",
mibEntry{
"valueMIB",
"valueOID",
snmp.MibEntry{
MibName: "valueMIB",
OidText: "valueOID",
},
},
{
".1.2.3.0.55",
mibEntry{
"enterpriseMIB",
"enterpriseOID",
snmp.MibEntry{
MibName: "enterpriseMIB",
OidText: "enterpriseOID",
},
},
},
@ -317,16 +318,16 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
".1.2.3.4.5",
mibEntry{
"valueMIB",
"valueOID",
snmp.MibEntry{
MibName: "valueMIB",
OidText: "valueOID",
},
},
{
".1.3.6.1.6.3.1.1.5.1",
mibEntry{
"coldStartMIB",
"coldStartOID",
snmp.MibEntry{
MibName: "coldStartMIB",
OidText: "coldStartOID",
},
},
},
@ -375,23 +376,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -439,23 +440,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -502,23 +503,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -564,23 +565,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -626,23 +627,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -688,23 +689,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -750,23 +751,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -812,23 +813,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -876,23 +877,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -940,23 +941,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -1004,23 +1005,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -1068,23 +1069,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -1132,23 +1133,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -1196,23 +1197,23 @@ func TestReceiveTrap(t *testing.T) {
entries: []entry{
{
oid: ".1.3.6.1.6.3.1.1.4.1.0",
e: mibEntry{
"SNMPv2-MIB",
"snmpTrapOID.0",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "snmpTrapOID.0",
},
},
{
oid: ".1.3.6.1.6.3.1.1.5.1",
e: mibEntry{
"SNMPv2-MIB",
"coldStart",
e: snmp.MibEntry{
MibName: "SNMPv2-MIB",
OidText: "coldStart",
},
},
{
oid: ".1.3.6.1.2.1.1.3.0",
e: mibEntry{
"UNUSED_MIB_NAME",
"sysUpTimeInstance",
e: snmp.MibEntry{
MibName: "UNUSED_MIB_NAME",
OidText: "sysUpTimeInstance",
},
},
},
@ -1260,13 +1261,13 @@ func TestReceiveTrap(t *testing.T) {
timeFunc: func() time.Time {
return fakeTime
},
lookupFunc: func(input string) (mibEntry, error) {
lookupFunc: func(input string) (snmp.MibEntry, error) {
for _, entry := range tt.entries {
if input == entry.oid {
return mibEntry{entry.e.mibName, entry.e.oidText}, nil
return snmp.MibEntry{MibName: entry.e.MibName, OidText: entry.e.OidText}, nil
}
}
return mibEntry{}, fmt.Errorf("unexpected oid")
return snmp.MibEntry{}, fmt.Errorf("unexpected oid")
},
//if cold start be answer otherwise err
Log: testutil.Logger{},
@ -1376,7 +1377,7 @@ func TestGosmiSingleMib(t *testing.T) {
timeFunc: func() time.Time {
return fakeTime
},
lookupFunc: lookup,
lookupFunc: snmp.TrapLookup,
Log: testutil.Logger{},
Version: "2c",
Path: []string{testDataPath},