Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding conversion for DateAndTime ::= TEXTUAL-CONVENTION #696

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions pkg/inputs/snmp/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
CONV_ENGINE_ID = "engine_id"
CONV_REGEXP = "regexp"
CONV_ONE = "to_one"
CONV_TIMESTAMP = "hextodatetime"

ConstantOidPrefix = "1.3.6.1.6.3.1135.6169."
ConstantOidMetricPrefix = ".1.3.6.1.6.3.1136.6169."
Expand Down Expand Up @@ -279,6 +280,8 @@ func GetFromConv(pdu gosnmp.SnmpPDU, conv string, log logger.ContextL) (int64, s
return EngineID(bv)
case CONV_ONE:
return toOne(bv)
case CONV_TIMESTAMP:
return hexToDateTime(bv)
default:
// Otherwise, try out some custom conversions.
split := strings.Split(conv, ":")
Expand Down Expand Up @@ -414,3 +417,67 @@ func fromRegexp(bv []byte, reg string) (int64, string, map[string]string) {
func toOne(bv []byte) (int64, string, map[string]string) {
return 1, string(bv), nil
}

/*
DateAndTime ::= TEXTUAL-CONVENTION

DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
STATUS current
DESCRIPTION
"A date-time specification.

field octets contents range
----- ------ -------- -----
1 1-2 year* 0..65536
2 3 month 1..12
3 4 day 1..31
4 5 hour 0..23
5 6 minutes 0..59
6 7 seconds 0..60
(use 60 for leap-second)
7 8 deci-seconds 0..9
8 9 direction from UTC '+' / '-'
9 10 hours from UTC* 0..13
10 11 minutes from UTC 0..59

* Notes:
- the value of year is in network-byte order
- daylight saving time in New Zealand is +13

For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
displayed as:

1992-5-26,13:30:15.0,-4:0

Note that if only local time is known, then timezone
information (fields 8-10) is not present."
SYNTAX OCTET STRING (SIZE (8 | 11))

E.g. spsActiveAlarmLogTime for SilverPeak SD-WAN devices:
iso.3.6.1.4.1.23867.3.1.1.2.1.1.11.1 = Hex-STRING: 07 E7 0A 1C 15 35 34 00 2B 00 00

Using the conversion above the timestamp value would be converted to:
2023-10-28,21:53:52.0,+0:0
*/
func hexToDateTime(bv []byte) (int64, string, map[string]string) {
if len(bv) != 8 && len(bv) != 11 {
return 0, "", nil // value is 8 or 11 bytes long only.
}

year := binary.BigEndian.Uint16(bv[0:2]) // Network byte order == big endian.
month := uint8(bv[2])
day := uint8(bv[3])
hour := uint8(bv[4])
min := uint8(bv[5])
sec := uint8(bv[6])
deciSec := uint8(bv[7])

if len(bv) == 11 {
dirUtc := string(bv[8:9])
hrsUtc := uint8(bv[9])
minUtc := uint8(bv[10])
return 0, fmt.Sprintf("%d-%d-%d,%d:%d:%d.%d,%s%d:%d", year, month, day, hour, min, sec, deciSec, dirUtc, hrsUtc, minUtc), nil
} else {
return 0, fmt.Sprintf("%d-%d-%d,%d:%d:%d.%d", year, month, day, hour, min, sec, deciSec), nil
}
}
17 changes: 17 additions & 0 deletions pkg/inputs/snmp/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ func TestHexToIP(t *testing.T) {
}
}

func TestHexDatetime(t *testing.T) {
assert := assert.New(t)
l := lt.NewTestContextL(logger.NilContext, t)

tests := map[string][]byte{
"2023-10-28,21:53:52.0,+0:0": []byte{0x07, 0xE7, 0x0A, 0x1C, 0x15, 0x35, 0x34, 0x00, 0x2B, 0x00, 0x00},
"": []byte{0x07, 0xE7, 0x0A}, // Too small
"2023-10-28,21:53:52.1": []byte{0x07, 0xE7, 0x0A, 0x1C, 0x15, 0x35, 0x34, 0x01}, // No timezone.
}

for expt, in := range tests {
pdu := gosnmp.SnmpPDU{Value: in}
_, str, _ := GetFromConv(pdu, CONV_TIMESTAMP, l)
assert.Equal(expt, str, "%s", in)
}
}

func TestEngineID(t *testing.T) {
assert := assert.New(t)
l := lt.NewTestContextL(logger.NilContext, t)
Expand Down
Loading