-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c875e45
commit 7675ce6
Showing
25 changed files
with
7,574 additions
and
808 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.