Skip to content

Commit

Permalink
Add support to convert snmp hex strings to integers (#8426)
Browse files Browse the repository at this point in the history
  • Loading branch information
wiardvanrij authored Dec 7, 2020
1 parent 97469f6 commit 1394989
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 15 deletions.
24 changes: 15 additions & 9 deletions plugins/inputs/snmp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,21 @@ option operate similar to the `snmpget` utility.
# is_tag = false

## Apply one of the following conversions to the variable value:
## float(X) Convert the input value into a float and divides by the
## Xth power of 10. Effectively just moves the decimal left
## X places. For example a value of `123` with `float(2)`
## will result in `1.23`.
## float: Convert the value into a float with no adjustment. Same
## as `float(0)`.
## int: Convert the value into an integer.
## hwaddr: Convert the value to a MAC address.
## ipaddr: Convert the value to an IP address.
## float(X): Convert the input value into a float and divides by the
## Xth power of 10. Effectively just moves the decimal left
## X places. For example a value of `123` with `float(2)`
## will result in `1.23`.
## float: Convert the value into a float with no adjustment. Same
## as `float(0)`.
## int: Convert the value into an integer.
## hwaddr: Convert the value to a MAC address.
## ipaddr: Convert the value to an IP address.
## hextoint:X:Y Convert a hex string value to integer. Where X is the Endian
## and Y the bit size. For example: hextoint:LittleEndian:uint64
## or hextoint:BigEndian:uint32. Valid options for the Endian are:
## BigEndian and LittleEndian. For the bit size: uint16, uint32
## and uint64.
##
# conversion = ""
```

Expand Down
47 changes: 41 additions & 6 deletions plugins/inputs/snmp/snmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package snmp
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"log"
"math"
Expand Down Expand Up @@ -574,12 +575,6 @@ func (s *Snmp) getConnection(idx int) (snmpConnection, error) {
}

// fieldConvert converts from any type according to the conv specification
// "float"/"float(0)" will convert the value into a float.
// "float(X)" will convert the value into a float, and then move the decimal before Xth right-most digit.
// "int" will convert the value into an integer.
// "hwaddr" will convert the value into a MAC address.
// "ipaddr" will convert the value into into an IP address.
// "" will convert a byte slice into a string.
func fieldConvert(conv string, v interface{}) (interface{}, error) {
if conv == "" {
if bs, ok := v.([]byte); ok {
Expand Down Expand Up @@ -671,6 +666,46 @@ func fieldConvert(conv string, v interface{}) (interface{}, error) {
return v, nil
}

split := strings.Split(conv, ":")
if split[0] == "hextoint" && len(split) == 3 {

endian := split[1]
bit := split[2]

bv, ok := v.([]byte)
if !ok {
return v, nil
}

if endian == "LittleEndian" {
switch bit {
case "uint64":
v = binary.LittleEndian.Uint64(bv)
case "uint32":
v = binary.LittleEndian.Uint32(bv)
case "uint16":
v = binary.LittleEndian.Uint16(bv)
default:
return nil, fmt.Errorf("invalid bit value (%s) for hex to int conversion", bit)
}
} else if endian == "BigEndian" {
switch bit {
case "uint64":
v = binary.BigEndian.Uint64(bv)
case "uint32":
v = binary.BigEndian.Uint32(bv)
case "uint16":
v = binary.BigEndian.Uint16(bv)
default:
return nil, fmt.Errorf("invalid bit value (%s) for hex to int conversion", bit)
}
} else {
return nil, fmt.Errorf("invalid Endian value (%s) for hex to int conversion", endian)
}

return v, nil
}

if conv == "ipaddr" {
var ipbs []byte

Expand Down
6 changes: 6 additions & 0 deletions plugins/inputs/snmp/snmp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,12 @@ func TestFieldConvert(t *testing.T) {
{[]byte("abcd"), "ipaddr", "97.98.99.100"},
{"abcd", "ipaddr", "97.98.99.100"},
{[]byte("abcdefghijklmnop"), "ipaddr", "6162:6364:6566:6768:696a:6b6c:6d6e:6f70"},
{[]byte{0x00, 0x09, 0x3E, 0xE3, 0xF6, 0xD5, 0x3B, 0x60}, "hextoint:BigEndian:uint64", uint64(2602423610063712)},
{[]byte{0x00, 0x09, 0x3E, 0xE3}, "hextoint:BigEndian:uint32", uint32(605923)},
{[]byte{0x00, 0x09}, "hextoint:BigEndian:uint16", uint16(9)},
{[]byte{0x00, 0x09, 0x3E, 0xE3, 0xF6, 0xD5, 0x3B, 0x60}, "hextoint:LittleEndian:uint64", uint64(6934371307618175232)},
{[]byte{0x00, 0x09, 0x3E, 0xE3}, "hextoint:LittleEndian:uint32", uint32(3812493568)},
{[]byte{0x00, 0x09}, "hextoint:LittleEndian:uint16", uint16(2304)},
}

for _, tc := range testTable {
Expand Down

0 comments on commit 1394989

Please sign in to comment.