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
|
||||
|
||||
## 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 = ""
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package snmp
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue