Fix snmp tools output parsing when they contain Windows eols (#3396)
This commit is contained in:
parent
662e2df779
commit
f9ded8fdd8
|
@ -1,6 +1,7 @@
|
|||
package snmp
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
|
@ -88,7 +89,7 @@ func execCmd(arg0 string, args ...string) ([]byte, error) {
|
|||
if err, ok := err.(*exec.ExitError); ok {
|
||||
return nil, NestedError{
|
||||
Err: err,
|
||||
NestedErr: fmt.Errorf("%s", bytes.TrimRight(err.Stderr, "\n")),
|
||||
NestedErr: fmt.Errorf("%s", bytes.TrimRight(err.Stderr, "\r\n")),
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
|
@ -856,24 +857,26 @@ func snmpTableCall(oid string) (mibName string, oidNum string, oidText string, f
|
|||
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 {
|
||||
lines := bytes.Split(out, []byte{'\n'})
|
||||
for _, line := range lines {
|
||||
if !bytes.HasPrefix(line, []byte(" INDEX")) {
|
||||
scanner := bufio.NewScanner(bytes.NewBuffer(out))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
if !strings.HasPrefix(line, " INDEX") {
|
||||
continue
|
||||
}
|
||||
|
||||
i := bytes.Index(line, []byte("{ "))
|
||||
i := strings.Index(line, "{ ")
|
||||
if i == -1 { // parse error
|
||||
continue
|
||||
}
|
||||
line = line[i+2:]
|
||||
i = bytes.Index(line, []byte(" }"))
|
||||
i = strings.Index(line, " }")
|
||||
if i == -1 { // parse error
|
||||
continue
|
||||
}
|
||||
line = line[:i]
|
||||
for _, col := range bytes.Split(line, []byte(", ")) {
|
||||
tagOids[mibPrefix+string(col)] = struct{}{}
|
||||
for _, col := range strings.Split(line, ", ") {
|
||||
tagOids[mibPrefix+col] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -883,15 +886,16 @@ func snmpTableCall(oid string) (mibName string, oidNum string, oidText string, f
|
|||
if err != nil {
|
||||
return "", "", "", nil, Errorf(err, "getting table columns")
|
||||
}
|
||||
cols := bytes.SplitN(out, []byte{'\n'}, 2)[0]
|
||||
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 bytes.Split(cols, []byte{' '}) {
|
||||
for _, col := range strings.Split(cols, " ") {
|
||||
if len(col) == 0 {
|
||||
continue
|
||||
}
|
||||
col := string(col)
|
||||
_, isTag := tagOids[mibPrefix+col]
|
||||
fields = append(fields, Field{Name: col, Oid: mibPrefix + col, IsTag: isTag})
|
||||
}
|
||||
|
@ -953,18 +957,18 @@ func snmpTranslateCall(oid string) (mibName string, oidNum string, oidText strin
|
|||
return "", "", "", "", err
|
||||
}
|
||||
|
||||
bb := bytes.NewBuffer(out)
|
||||
|
||||
oidText, err = bb.ReadString('\n')
|
||||
if err != nil {
|
||||
return "", "", "", "", Errorf(err, "getting OID text")
|
||||
scanner := bufio.NewScanner(bytes.NewBuffer(out))
|
||||
ok := scanner.Scan()
|
||||
if !ok && scanner.Err() != nil {
|
||||
return "", "", "", "", Errorf(scanner.Err(), "getting OID text")
|
||||
}
|
||||
oidText = oidText[:len(oidText)-1]
|
||||
|
||||
oidText = scanner.Text()
|
||||
|
||||
i := strings.Index(oidText, "::")
|
||||
if i == -1 {
|
||||
// was not found in MIB.
|
||||
if bytes.Index(bb.Bytes(), []byte(" [TRUNCATED]")) >= 0 {
|
||||
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
|
||||
|
@ -974,28 +978,21 @@ func snmpTranslateCall(oid string) (mibName string, oidNum string, oidText strin
|
|||
oidText = oidText[i+2:]
|
||||
}
|
||||
|
||||
if i := bytes.Index(bb.Bytes(), []byte(" -- TEXTUAL CONVENTION ")); i != -1 {
|
||||
bb.Next(i + len(" -- TEXTUAL CONVENTION "))
|
||||
tc, err := bb.ReadString('\n')
|
||||
if err != nil {
|
||||
return "", "", "", "", Errorf(err, "getting textual convention")
|
||||
}
|
||||
tc = tc[:len(tc)-1]
|
||||
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":
|
||||
conversion = "ipaddr"
|
||||
}
|
||||
}
|
||||
} else if strings.HasPrefix(line, "::= { ") {
|
||||
objs := strings.TrimPrefix(line, "::= { ")
|
||||
objs = strings.TrimSuffix(objs, " }")
|
||||
|
||||
i = bytes.Index(bb.Bytes(), []byte("::= { "))
|
||||
bb.Next(i + len("::= { "))
|
||||
objs, err := bb.ReadString('}')
|
||||
if err != nil {
|
||||
return "", "", "", "", Errorf(err, "getting numeric oid")
|
||||
}
|
||||
objs = objs[:len(objs)-1]
|
||||
for _, obj := range strings.Split(objs, " ") {
|
||||
if len(obj) == 0 {
|
||||
continue
|
||||
|
@ -1007,6 +1004,9 @@ func snmpTranslateCall(oid string) (mibName string, oidNum string, oidText strin
|
|||
oidNum += "." + obj
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return mibName, oidNum, oidText, conversion, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue