Add support to convert snmp hex strings to integers (#8426)
This commit is contained in:
parent
97469f6d85
commit
139498937a
|
|
@ -113,15 +113,21 @@ option operate similar to the `snmpget` utility.
|
||||||
# is_tag = false
|
# is_tag = false
|
||||||
|
|
||||||
## Apply one of the following conversions to the variable value:
|
## Apply one of the following conversions to the variable value:
|
||||||
## float(X) Convert the input value into a float and divides by the
|
## float(X): Convert the input value into a float and divides by the
|
||||||
## Xth power of 10. Effectively just moves the decimal left
|
## Xth power of 10. Effectively just moves the decimal left
|
||||||
## X places. For example a value of `123` with `float(2)`
|
## X places. For example a value of `123` with `float(2)`
|
||||||
## will result in `1.23`.
|
## will result in `1.23`.
|
||||||
## float: Convert the value into a float with no adjustment. Same
|
## float: Convert the value into a float with no adjustment. Same
|
||||||
## as `float(0)`.
|
## as `float(0)`.
|
||||||
## int: Convert the value into an integer.
|
## int: Convert the value into an integer.
|
||||||
## hwaddr: Convert the value to a MAC address.
|
## hwaddr: Convert the value to a MAC address.
|
||||||
## ipaddr: Convert the value to an IP 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 = ""
|
# conversion = ""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package snmp
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
|
@ -574,12 +575,6 @@ func (s *Snmp) getConnection(idx int) (snmpConnection, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fieldConvert converts from any type according to the conv specification
|
// 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) {
|
func fieldConvert(conv string, v interface{}) (interface{}, error) {
|
||||||
if conv == "" {
|
if conv == "" {
|
||||||
if bs, ok := v.([]byte); ok {
|
if bs, ok := v.([]byte); ok {
|
||||||
|
|
@ -671,6 +666,46 @@ func fieldConvert(conv string, v interface{}) (interface{}, error) {
|
||||||
return v, nil
|
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" {
|
if conv == "ipaddr" {
|
||||||
var ipbs []byte
|
var ipbs []byte
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -739,6 +739,12 @@ func TestFieldConvert(t *testing.T) {
|
||||||
{[]byte("abcd"), "ipaddr", "97.98.99.100"},
|
{[]byte("abcd"), "ipaddr", "97.98.99.100"},
|
||||||
{"abcd", "ipaddr", "97.98.99.100"},
|
{"abcd", "ipaddr", "97.98.99.100"},
|
||||||
{[]byte("abcdefghijklmnop"), "ipaddr", "6162:6364:6566:6768:696a:6b6c:6d6e:6f70"},
|
{[]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 {
|
for _, tc := range testTable {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue