I am messing around with an SNMP library in Go and came up with a type Field
that defines an SNMP BER encoded field according to this document. Each field consists of a type, length, and value, where the type is an ASN.1 type, length is the length of the field's value, and the value can be another field, a sequence of fields, or a sequence of bytes. This made me think about the possibility of recursively defining an SNMP message. Here is some code I came up with, but I'm stuck trying to translate it into a recursive structure:
package main
import "fmt"
// ASN.1 BER encoded types.
type ASN1BER byte
const (
Integer ASN1BER = 0x02
BitString = 0x03
OctetString = 0x04
Null = 0x05
ObjectIdentifier = 0x06
Sequence = 0x30
GetRequest = 0xa0
)
// SNMP versions.
type Version byte
const (
Version1 Version = 0x00
Version2c = 0x01
)
// SNMP message field.
type Field struct {
Type ASN1BER
Len int
Value interface{}
}
func main() {
// SNMP Message
msg := &Field{Type: Sequence, Len: 44, Value: []*Field{
// SNMP Version
{Type: Integer, Len: 1, Value: Version2c},
// Community String
{Type: OctetString, Len: 7, Value: []byte("private")},
// Get-Request PDU
{Type: GetRequest, Len: 30, Value: []*Field{
// Request ID
{Type: Integer, Len: 1, Value: []byte{0x01}},
// Error Status
{Type: Integer, Len: 1, Value: []byte{0x00}},
// Error Index
{Type: Integer, Len: 1, Value: []byte{0x00}},
// Varbind List
{Type: Sequence, Len: 19, Value: []*Field{
// Varbind
{Type: Sequence, Len: 17, Value: []*Field{
// OID 1.3.6.1.4.1.2680.1.2.7.3.2.0
{Type: ObjectIdentifier, Len: 13, Value: []byte{0x2b, 0x06, 0x01, 0x04, 0x01, 0x94, 0x78, 0x01, 0x02, 0x07, 0x03, 0x02, 0x00}},
// Value
{Type: Null, Len: 0},
}}},
}},
}},
}
fmt.Println(msg)
}
Is it possible to represent the SNMP message recursively? If so, what would be the base case(s) and the recursive case(s)? The goal is to be able to recursively print, encode, and decode SNMP messages.