Temporarily add go-agentx (w/ fixes to lexico ordering)

This commit is contained in:
Pim van Pelt
2025-06-09 17:14:28 +02:00
parent 824496c402
commit 771cc6ff48
45 changed files with 2477 additions and 0 deletions

View File

@ -0,0 +1,29 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
// AllocateIndex defiens the pdu allocate index packet.
type AllocateIndex struct {
Variables Variables
}
// Type returns the pdu packet type.
func (ai *AllocateIndex) Type() Type {
return TypeIndexAllocate
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (ai *AllocateIndex) MarshalBinary() ([]byte, error) {
data, err := ai.Variables.MarshalBinary()
if err != nil {
return nil, err
}
return data, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (ai *AllocateIndex) UnmarshalBinary(data []byte) error {
return nil
}

26
go-agentx/pdu/close.go Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
// Close defines the pdu close packet.
type Close struct {
Reason Reason
}
// Type returns the pdu packet type.
func (c *Close) Type() Type {
return TypeClose
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (c *Close) MarshalBinary() ([]byte, error) {
return []byte{byte(c.Reason), 0x00, 0x00, 0x00}, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (c *Close) UnmarshalBinary(data []byte) error {
c.Reason = Reason(data[0])
return nil
}

View File

@ -0,0 +1,29 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
// DeallocateIndex defiens the pdu deallocate index packet.
type DeallocateIndex struct {
Variables Variables
}
// Type returns the pdu packet type.
func (di *DeallocateIndex) Type() Type {
return TypeIndexDeallocate
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (di *DeallocateIndex) MarshalBinary() ([]byte, error) {
data, err := di.Variables.MarshalBinary()
if err != nil {
return nil, err
}
return data, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (di *DeallocateIndex) UnmarshalBinary(data []byte) error {
return nil
}

62
go-agentx/pdu/error.go Normal file
View File

@ -0,0 +1,62 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import "fmt"
// The various pdu packet errors.
const (
ErrorNone Error = 0
ErrorOpenFailed Error = 256
ErrorNotOpen Error = 257
ErrorIndexWrongType Error = 258
ErrorIndexAlreadyAllocated Error = 259
ErrorIndexNoneAvailable Error = 260
ErrorIndexNotAllocated Error = 261
ErrorUnsupportedContext Error = 262
ErrorDuplicateRegistration Error = 263
ErrorUnknownRegistration Error = 264
ErrorUnknownAgentCaps Error = 265
ErrorParse Error = 266
ErrorRequestDenied Error = 267
ErrorProcessing Error = 268
)
// Error defines a pdu packet error.
type Error uint16
func (e Error) String() string {
switch e {
case ErrorNone:
return "ErrorNone"
case ErrorOpenFailed:
return "ErrorOpenFailed"
case ErrorNotOpen:
return "ErrorNotOpen"
case ErrorIndexWrongType:
return "ErrorIndexWrongType"
case ErrorIndexAlreadyAllocated:
return "ErrorIndexAlreadyAllocated"
case ErrorIndexNoneAvailable:
return "ErrorIndexNoneAvailable"
case ErrorIndexNotAllocated:
return "ErrorIndexNotAllocated"
case ErrorUnsupportedContext:
return "ErrorUnsupportedContext"
case ErrorDuplicateRegistration:
return "ErrorDuplicateRegistration"
case ErrorUnknownRegistration:
return "ErrorUnknownRegistration"
case ErrorUnknownAgentCaps:
return "ErrorUnknownAgentCaps"
case ErrorParse:
return "ErrorParse"
case ErrorRequestDenied:
return "ErrorRequestDenied"
case ErrorProcessing:
return "ErrorProcessing"
}
return fmt.Sprintf("ErrorUnknown (%d)", e)
}

45
go-agentx/pdu/flags.go Normal file
View File

@ -0,0 +1,45 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"fmt"
"strings"
)
// The various pdu packet flags.
const (
FlagInstanceRegistration Flags = 1 << 0
FlagNewIndex Flags = 1 << 1
FlagAnyIndex Flags = 1 << 2
FlagNonDefaultContext Flags = 1 << 3
FlagNetworkByteOrder Flags = 1 << 4
)
// Flags defines pdu packet flags.
type Flags byte
func (f Flags) String() string {
result := []string{}
if f&FlagInstanceRegistration != 0 {
result = append(result, "FlagInstanceRegistration")
}
if f&FlagNewIndex != 0 {
result = append(result, "FlagNewIndex")
}
if f&FlagAnyIndex != 0 {
result = append(result, "FlagAnyIndex")
}
if f&FlagNonDefaultContext != 0 {
result = append(result, "FlagNonDefaultContext")
}
if f&FlagNetworkByteOrder != 0 {
result = append(result, "FlagNetworkByteOrder")
}
if len(result) == 0 {
return "(FlagNone)"
}
return fmt.Sprintf("(%s)", strings.Join(result, " | "))
}

40
go-agentx/pdu/get.go Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import "github.com/posteo/go-agentx/value"
// Get defines the pdu get packet.
type Get struct {
SearchRange Range
}
// GetOID returns the oid.
func (g *Get) GetOID() value.OID {
return g.SearchRange.From.GetIdentifier()
}
// SetOID sets the provided oid.
func (g *Get) SetOID(oid value.OID) {
g.SearchRange.From.SetIdentifier(oid)
}
// Type returns the pdu packet type.
func (g *Get) Type() Type {
return TypeGet
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (g *Get) MarshalBinary() ([]byte, error) {
return []byte{}, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (g *Get) UnmarshalBinary(data []byte) error {
if err := g.SearchRange.UnmarshalBinary(data); err != nil {
return err
}
return nil
}

28
go-agentx/pdu/get_next.go Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
// GetNext defines the pdu get next packet.
type GetNext struct {
SearchRanges Ranges
}
// Type returns the pdu packet type.
func (g *GetNext) Type() Type {
return TypeGetNext
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (g *GetNext) MarshalBinary() ([]byte, error) {
return []byte{}, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (g *GetNext) UnmarshalBinary(data []byte) error {
if err := g.SearchRanges.UnmarshalBinary(data); err != nil {
return err
}
return nil
}

61
go-agentx/pdu/header.go Normal file
View File

@ -0,0 +1,61 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"bytes"
"encoding/binary"
"fmt"
)
const (
// HeaderSize defines the total size of a header packet.
HeaderSize = 20
)
// Header defines a pdu packet header
type Header struct {
Version byte
Type Type
Flags Flags
SessionID uint32
TransactionID uint32
PacketID uint32
PayloadLength uint32
}
// MarshalBinary returns the pdu header as a slice of bytes.
func (h *Header) MarshalBinary() ([]byte, error) {
buffer := bytes.NewBuffer([]byte{h.Version, byte(h.Type), byte(h.Flags), 0x00})
binary.Write(buffer, binary.LittleEndian, h.SessionID)
binary.Write(buffer, binary.LittleEndian, h.TransactionID)
binary.Write(buffer, binary.LittleEndian, h.PacketID)
binary.Write(buffer, binary.LittleEndian, h.PayloadLength)
return buffer.Bytes(), nil
}
// UnmarshalBinary sets the header structure from the provided slice of bytes.
func (h *Header) UnmarshalBinary(data []byte) error {
if len(data) < HeaderSize {
return fmt.Errorf("not enough bytes (%d) to unmarshal the header (%d)", len(data), HeaderSize)
}
h.Version, h.Type, h.Flags = data[0], Type(data[1]), Flags(data[2])
buffer := bytes.NewBuffer(data[4:])
binary.Read(buffer, binary.LittleEndian, &h.SessionID)
binary.Read(buffer, binary.LittleEndian, &h.TransactionID)
binary.Read(buffer, binary.LittleEndian, &h.PacketID)
binary.Read(buffer, binary.LittleEndian, &h.PayloadLength)
return nil
}
func (h *Header) String() string {
return "(header " + h.Type.String() + ")"
}

View File

@ -0,0 +1,38 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"fmt"
)
// HeaderPacket defines a container structure for a header and a packet.
type HeaderPacket struct {
Header *Header
Packet Packet
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (hp *HeaderPacket) MarshalBinary() ([]byte, error) {
payloadBytes, err := hp.Packet.MarshalBinary()
if err != nil {
return nil, err
}
hp.Header.Version = 1
hp.Header.Type = hp.Packet.Type()
hp.Header.PayloadLength = uint32(len(payloadBytes))
result, err := hp.Header.MarshalBinary()
if err != nil {
return nil, err
}
return append(result, payloadBytes...), nil
}
func (hp *HeaderPacket) String() string {
return fmt.Sprintf("[head %v, body %v]", hp.Header, hp.Packet)
}

View File

@ -0,0 +1,96 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"bytes"
"encoding/binary"
"github.com/posteo/go-agentx/value"
)
// ObjectIdentifier defines the pdu object identifier packet.
type ObjectIdentifier struct {
Prefix uint8
Include byte
Subidentifiers []uint32
}
// SetInclude sets the include field.
func (o *ObjectIdentifier) SetInclude(value bool) {
if value {
o.Include = 0x01
} else {
o.Include = 0x00
}
}
// GetInclude returns true if the include field ist set, false otherwise.
func (o *ObjectIdentifier) GetInclude() bool {
if o.Include == 0x00 {
return false
}
return true
}
// SetIdentifier set the subidentifiers by the provided oid string.
func (o *ObjectIdentifier) SetIdentifier(oid value.OID) {
o.Subidentifiers = make([]uint32, 0)
if len(oid) > 4 && oid[0] == 1 && oid[1] == 3 && oid[2] == 6 && oid[3] == 1 {
o.Subidentifiers = append(o.Subidentifiers, uint32(1), uint32(3), uint32(6), uint32(1), uint32(oid[4]))
oid = oid[5:]
}
o.Subidentifiers = append(o.Subidentifiers, oid...)
}
// GetIdentifier returns the identifier as an oid string.
func (o *ObjectIdentifier) GetIdentifier() value.OID {
var oid value.OID
if o.Prefix != 0 {
oid = append(oid, 1, 3, 6, 1, uint32(o.Prefix))
}
return append(oid, o.Subidentifiers...)
}
// ByteSize returns the number of bytes, the binding would need in the encoded version.
func (o *ObjectIdentifier) ByteSize() int {
return 4 + len(o.Subidentifiers)*4
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (o *ObjectIdentifier) MarshalBinary() ([]byte, error) {
buffer := bytes.NewBuffer([]byte{byte(len(o.Subidentifiers)), o.Prefix, o.Include, 0x00})
for _, subidentifier := range o.Subidentifiers {
binary.Write(buffer, binary.LittleEndian, &subidentifier)
}
return buffer.Bytes(), nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (o *ObjectIdentifier) UnmarshalBinary(data []byte) error {
count := data[0]
o.Prefix = data[1]
o.Include = data[2]
o.Subidentifiers = make([]uint32, 0)
buffer := bytes.NewBuffer(data[4:])
for index := byte(0); index < count; index++ {
var subidentifier uint32
if err := binary.Read(buffer, binary.LittleEndian, &subidentifier); err != nil {
return err
}
o.Subidentifiers = append(o.Subidentifiers, subidentifier)
}
return nil
}
func (o ObjectIdentifier) String() string {
return o.GetIdentifier().String()
}

View File

@ -0,0 +1,43 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"bytes"
"encoding/binary"
)
// OctetString defines the pdu description packet.
type OctetString struct {
Text string
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (o *OctetString) MarshalBinary() ([]byte, error) {
buffer := &bytes.Buffer{}
binary.Write(buffer, binary.LittleEndian, uint32(len(o.Text)))
buffer.WriteString(o.Text)
for buffer.Len()%4 > 0 {
buffer.WriteByte(0x00)
}
return buffer.Bytes(), nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (o *OctetString) UnmarshalBinary(data []byte) error {
buffer := bytes.NewBuffer(data)
length := uint32(0)
if err := binary.Read(buffer, binary.LittleEndian, &length); err != nil {
return err
}
o.Text = string(data[4 : 4+length])
return nil
}

38
go-agentx/pdu/open.go Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"github.com/posteo/go-agentx/marshaler"
)
// Open defines a pdu open packet.
type Open struct {
Timeout Timeout
ID ObjectIdentifier
Description OctetString
}
// Type returns the pdu packet type.
func (o *Open) Type() Type {
return TypeOpen
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (o *Open) MarshalBinary() ([]byte, error) {
combined := marshaler.NewMulti(&o.Timeout, &o.ID, &o.Description)
combinedBytes, err := combined.MarshalBinary()
if err != nil {
return nil, err
}
return combinedBytes, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (o *Open) UnmarshalBinary(data []byte) error {
return nil
}

14
go-agentx/pdu/packet.go Normal file
View File

@ -0,0 +1,14 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import "encoding"
// Packet defines a general interface for a pdu packet.
type Packet interface {
TypeOwner
encoding.BinaryMarshaler
encoding.BinaryUnmarshaler
}

53
go-agentx/pdu/range.go Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"fmt"
)
// Range defines the pdu search range packet.
type Range struct {
From ObjectIdentifier
To ObjectIdentifier
}
// ByteSize returns the number of bytes, the binding would need in the encoded version.
func (r *Range) ByteSize() int {
return r.From.ByteSize() + r.To.ByteSize()
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (r *Range) MarshalBinary() ([]byte, error) {
r.To.SetInclude(false)
return []byte{}, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (r *Range) UnmarshalBinary(data []byte) error {
if err := r.From.UnmarshalBinary(data); err != nil {
return err
}
if err := r.To.UnmarshalBinary(data[r.From.ByteSize():]); err != nil {
return err
}
return nil
}
func (r Range) String() string {
result := ""
if r.From.GetInclude() {
result += "["
} else {
result += "("
}
result += fmt.Sprintf("%v, %v", r.From, r.To)
if r.To.GetInclude() {
result += "]"
} else {
result += ")"
}
return result
}

27
go-agentx/pdu/ranges.go Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
// Ranges defines the pdu search range list packet.
type Ranges []Range
// MarshalBinary returns the pdu packet as a slice of bytes.
func (r *Ranges) MarshalBinary() ([]byte, error) {
return []byte{}, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (r *Ranges) UnmarshalBinary(data []byte) error {
*r = make([]Range, 0)
for offset := 0; offset < len(data); {
rng := Range{}
if err := rng.UnmarshalBinary(data[offset:]); err != nil {
return err
}
*r = append(*r, rng)
offset += rng.ByteSize()
}
return nil
}

38
go-agentx/pdu/reason.go Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import "fmt"
// The various pdu packet reasons.
const (
ReasonOther Reason = 1
ReasonParseError Reason = 2
ReasonProtocolError Reason = 3
ReasonTimeouts Reason = 4
ReasonShutdown Reason = 5
ReasonByManager Reason = 6
)
// Reason defines a reason.
type Reason byte
func (r Reason) String() string {
switch r {
case ReasonOther:
return "ReasonOther"
case ReasonParseError:
return "ReasonParseError"
case ReasonProtocolError:
return "ReasonProtocolError"
case ReasonTimeouts:
return "ReasonTimeouts"
case ReasonShutdown:
return "ReasonShutdown"
case ReasonByManager:
return "ReasonByManager"
}
return fmt.Sprintf("ReasonUnknown (%d)", r)
}

37
go-agentx/pdu/register.go Normal file
View File

@ -0,0 +1,37 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"github.com/posteo/go-agentx/marshaler"
)
// Register defines the pdu register packet.
type Register struct {
Timeout Timeout
Subtree ObjectIdentifier
}
// Type returns the pdu packet type.
func (r *Register) Type() Type {
return TypeRegister
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (r *Register) MarshalBinary() ([]byte, error) {
combined := marshaler.NewMulti(&r.Timeout, &r.Subtree)
combinedBytes, err := combined.MarshalBinary()
if err != nil {
return nil, err
}
return combinedBytes, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (r *Register) UnmarshalBinary(data []byte) error {
return nil
}

68
go-agentx/pdu/response.go Normal file
View File

@ -0,0 +1,68 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"bytes"
"encoding/binary"
"time"
)
// Response defines the pdu response packet.
type Response struct {
UpTime time.Duration
Error Error
Index uint16
Variables Variables
}
// Type returns the pdu packet type.
func (r *Response) Type() Type {
return TypeResponse
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (r *Response) MarshalBinary() ([]byte, error) {
buffer := &bytes.Buffer{}
upTime := uint32(r.UpTime.Seconds() / 100)
binary.Write(buffer, binary.LittleEndian, &upTime)
binary.Write(buffer, binary.LittleEndian, &r.Error)
binary.Write(buffer, binary.LittleEndian, &r.Index)
vBytes, err := r.Variables.MarshalBinary()
if err != nil {
return nil, err
}
buffer.Write(vBytes)
return buffer.Bytes(), nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (r *Response) UnmarshalBinary(data []byte) error {
buffer := bytes.NewBuffer(data)
upTime := uint32(0)
if err := binary.Read(buffer, binary.LittleEndian, &upTime); err != nil {
return err
}
r.UpTime = time.Second * time.Duration(upTime*100)
if err := binary.Read(buffer, binary.LittleEndian, &r.Error); err != nil {
return err
}
if err := binary.Read(buffer, binary.LittleEndian, &r.Index); err != nil {
return err
}
if err := r.Variables.UnmarshalBinary(data[8:]); err != nil {
return err
}
return nil
}
func (r *Response) String() string {
return "(response " + r.Variables.String() + ")"
}

29
go-agentx/pdu/timeout.go Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import "time"
// Timeout defines the pdu timeout packet.
type Timeout struct {
Duration time.Duration
Priority byte
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (t *Timeout) MarshalBinary() ([]byte, error) {
return []byte{byte(t.Duration.Seconds()), t.Priority, 0x00, 0x00}, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (t *Timeout) UnmarshalBinary(data []byte) error {
t.Duration = time.Duration(data[0]) * time.Second
t.Priority = data[1]
return nil
}
func (t Timeout) String() string {
return t.Duration.String()
}

77
go-agentx/pdu/type.go Normal file
View File

@ -0,0 +1,77 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
// The various pdu packet types.
const (
TypeOpen Type = 1
TypeClose Type = 2
TypeRegister Type = 3
TypeUnregister Type = 4
TypeGet Type = 5
TypeGetNext Type = 6
TypeGetBulk Type = 7
TypeTestSet Type = 8
TypeCommitSet Type = 9
TypeUndoSet Type = 10
TypeCleanupSet Type = 11
TypeNotify Type = 12
TypePing Type = 13
TypeIndexAllocate Type = 14
TypeIndexDeallocate Type = 15
TypeAddAgentCaps Type = 16
TypeRemoveAgentCaps Type = 17
TypeResponse Type = 18
)
// Type defines the pdu packet type.
type Type byte
// TypeOwner defines the interface for an object that provides a type.
type TypeOwner interface {
Type() Type
}
func (t Type) String() string {
switch t {
case TypeOpen:
return "TypeOpen"
case TypeClose:
return "TypeClose"
case TypeRegister:
return "TypeRegister"
case TypeUnregister:
return "TypeUnregister"
case TypeGet:
return "TypeGet"
case TypeGetNext:
return "TypeGetNext"
case TypeGetBulk:
return "TypeGetBulk"
case TypeTestSet:
return "TypeTestSet"
case TypeCommitSet:
return "TypeCommitSet"
case TypeUndoSet:
return "TypeUndoSet"
case TypeCleanupSet:
return "TypeCleanupSet"
case TypeNotify:
return "TypeNotify"
case TypePing:
return "TypePing"
case TypeIndexAllocate:
return "TypeIndexAllocate"
case TypeIndexDeallocate:
return "TypeIndexDeallocate"
case TypeAddAgentCaps:
return "TypeAddAgentCaps"
case TypeRemoveAgentCaps:
return "TypeRemoveAgentCaps"
case TypeResponse:
return "TypeResponse"
}
return "TypeUnknown"
}

View File

@ -0,0 +1,37 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"github.com/posteo/go-agentx/marshaler"
)
// Unregister defines the pdu unregister packet.
type Unregister struct {
Timeout Timeout
Subtree ObjectIdentifier
}
// Type returns the pdu packet type.
func (u *Unregister) Type() Type {
return TypeUnregister
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (u *Unregister) MarshalBinary() ([]byte, error) {
combined := marshaler.NewMulti(&u.Timeout, &u.Subtree)
combinedBytes, err := combined.MarshalBinary()
if err != nil {
return nil, err
}
return combinedBytes, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (u *Unregister) UnmarshalBinary(data []byte) error {
return nil
}

185
go-agentx/pdu/variable.go Normal file
View File

@ -0,0 +1,185 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"bytes"
"encoding/binary"
"fmt"
"net"
"time"
"github.com/posteo/go-agentx/value"
)
// Variable defines the pdu varbind packet.
type Variable struct {
Type VariableType
Name ObjectIdentifier
Value interface{}
}
// Set sets the variable.
func (v *Variable) Set(oid value.OID, t VariableType, value interface{}) {
v.Name.SetIdentifier(oid)
v.Type = t
v.Value = value
}
// ByteSize returns the number of bytes, the binding would need in the encoded version.
func (v *Variable) ByteSize() int {
bytes, err := v.MarshalBinary()
if err != nil {
panic(err)
}
return len(bytes)
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (v *Variable) MarshalBinary() ([]byte, error) {
buffer := &bytes.Buffer{}
binary.Write(buffer, binary.LittleEndian, &v.Type)
buffer.WriteByte(0x00)
buffer.WriteByte(0x00)
nameBytes, err := v.Name.MarshalBinary()
if err != nil {
return nil, err
}
buffer.Write(nameBytes)
switch v.Type {
case VariableTypeInteger:
value := v.Value.(int32)
binary.Write(buffer, binary.LittleEndian, &value)
case VariableTypeOctetString:
octetString := &OctetString{Text: v.Value.(string)}
octetStringBytes, err := octetString.MarshalBinary()
if err != nil {
return nil, err
}
buffer.Write(octetStringBytes)
case VariableTypeNull, VariableTypeNoSuchObject, VariableTypeNoSuchInstance, VariableTypeEndOfMIBView:
break
case VariableTypeObjectIdentifier:
targetOID, err := value.ParseOID(v.Value.(string))
if err != nil {
return nil, err
}
oi := &ObjectIdentifier{}
oi.SetIdentifier(targetOID)
oiBytes, err := oi.MarshalBinary()
if err != nil {
return nil, err
}
buffer.Write(oiBytes)
case VariableTypeIPAddress:
ip := v.Value.(net.IP)
octetString := &OctetString{Text: string(ip)}
octetStringBytes, err := octetString.MarshalBinary()
if err != nil {
return nil, err
}
buffer.Write(octetStringBytes)
case VariableTypeCounter32, VariableTypeGauge32:
value := v.Value.(uint32)
binary.Write(buffer, binary.LittleEndian, &value)
case VariableTypeTimeTicks:
value := uint32(v.Value.(time.Duration).Seconds() * 100)
binary.Write(buffer, binary.LittleEndian, &value)
case VariableTypeOpaque:
octetString := &OctetString{Text: string(v.Value.([]byte))}
octetStringBytes, err := octetString.MarshalBinary()
if err != nil {
return nil, err
}
buffer.Write(octetStringBytes)
case VariableTypeCounter64:
value := v.Value.(uint64)
binary.Write(buffer, binary.LittleEndian, &value)
default:
return nil, fmt.Errorf("unhandled variable type %s", v.Type)
}
return buffer.Bytes(), nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (v *Variable) UnmarshalBinary(data []byte) error {
buffer := bytes.NewBuffer(data)
if err := binary.Read(buffer, binary.LittleEndian, &v.Type); err != nil {
return err
}
offset := 4
if err := v.Name.UnmarshalBinary(data[offset:]); err != nil {
return err
}
offset += v.Name.ByteSize()
switch v.Type {
case VariableTypeInteger:
value := int32(0)
if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil {
return err
}
v.Value = value
case VariableTypeOctetString:
octetString := &OctetString{}
if err := octetString.UnmarshalBinary(data[offset:]); err != nil {
return err
}
v.Value = octetString.Text
case VariableTypeNull, VariableTypeNoSuchObject, VariableTypeNoSuchInstance, VariableTypeEndOfMIBView:
v.Value = nil
case VariableTypeObjectIdentifier:
oid := &ObjectIdentifier{}
if err := oid.UnmarshalBinary(data[offset:]); err != nil {
return err
}
v.Value = oid.GetIdentifier()
case VariableTypeIPAddress:
octetString := &OctetString{}
if err := octetString.UnmarshalBinary(data[offset:]); err != nil {
return err
}
v.Value = net.IP(octetString.Text)
case VariableTypeCounter32, VariableTypeGauge32:
value := uint32(0)
if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil {
return err
}
v.Value = value
case VariableTypeTimeTicks:
value := uint32(0)
if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil {
return err
}
v.Value = time.Duration(value) * time.Second / 100
case VariableTypeOpaque:
octetString := &OctetString{}
if err := octetString.UnmarshalBinary(data[offset:]); err != nil {
return err
}
v.Value = []byte(octetString.Text)
case VariableTypeCounter64:
value := uint64(0)
if err := binary.Read(buffer, binary.LittleEndian, &value); err != nil {
return err
}
v.Value = value
default:
return fmt.Errorf("unhandled variable type %s", v.Type)
}
return nil
}
func (v *Variable) String() string {
return fmt.Sprintf("(variable %s = %v)", v.Type, v.Value)
}

View File

@ -0,0 +1,59 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import "fmt"
// The various variable types.
const (
VariableTypeInteger VariableType = 2
VariableTypeOctetString VariableType = 4
VariableTypeNull VariableType = 5
VariableTypeObjectIdentifier VariableType = 6
VariableTypeIPAddress VariableType = 64
VariableTypeCounter32 VariableType = 65
VariableTypeGauge32 VariableType = 66
VariableTypeTimeTicks VariableType = 67
VariableTypeOpaque VariableType = 68
VariableTypeCounter64 VariableType = 70
VariableTypeNoSuchObject VariableType = 128
VariableTypeNoSuchInstance VariableType = 129
VariableTypeEndOfMIBView VariableType = 130
)
// VariableType defines the type of a variable.
type VariableType uint16
func (v VariableType) String() string {
switch v {
case VariableTypeInteger:
return "VariableTypeInteger"
case VariableTypeOctetString:
return "VariableTypeOctetString"
case VariableTypeNull:
return "VariableTypeNull"
case VariableTypeObjectIdentifier:
return "VariableTypeObjectIdentifier"
case VariableTypeIPAddress:
return "VariableTypeIPAddress"
case VariableTypeCounter32:
return "VariableTypeCounter32"
case VariableTypeGauge32:
return "VariableTypeGauge32"
case VariableTypeTimeTicks:
return "VariableTypeTimeTicks"
case VariableTypeOpaque:
return "VariableTypeOpaque"
case VariableTypeCounter64:
return "VariableTypeCounter64"
case VariableTypeNoSuchObject:
return "VariableTypeNoSuchObject"
case VariableTypeNoSuchInstance:
return "VariableTypeNoSuchInstance"
case VariableTypeEndOfMIBView:
return "VariableTypeEndOfMIBView"
}
return fmt.Sprintf("VariableTypeUnknown (%d)", v)
}

View File

@ -0,0 +1,56 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package pdu
import (
"strings"
"github.com/posteo/go-agentx/value"
)
// Variables defines a list of variable bindings.
type Variables []Variable
// Add adds the provided variable.
func (v *Variables) Add(oid value.OID, t VariableType, value interface{}) {
variable := Variable{}
variable.Set(oid, t, value)
*v = append(*v, variable)
}
// MarshalBinary returns the pdu packet as a slice of bytes.
func (v *Variables) MarshalBinary() ([]byte, error) {
result := []byte{}
for _, variable := range *v {
data, err := variable.MarshalBinary()
if err != nil {
return nil, err
}
result = append(result, data...)
}
return result, nil
}
// UnmarshalBinary sets the packet structure from the provided slice of bytes.
func (v *Variables) UnmarshalBinary(data []byte) error {
*v = make([]Variable, 0)
for offset := 0; offset < len(data); {
variable := Variable{}
if err := variable.UnmarshalBinary(data[offset:]); err != nil {
return err
}
*v = append(*v, variable)
offset += variable.ByteSize()
}
return nil
}
func (v Variables) String() string {
parts := make([]string, len(v))
for index, va := range v {
parts[index] = va.String()
}
return "[variables " + strings.Join(parts, ", ") + "]"
}