service_matcher-go/snmp/v2/snmpv2.go
2018-08-13 16:48:32 +09:00

146 lines
2.5 KiB
Go

package v2
import (
"encoding/asn1"
"math/rand"
csm "git.loafle.net/commons/service_matcher-go"
)
type snmpv2 struct {
Version int
Community []byte
Data struct {
RequestID int32
ErrorStatus int
ErrorIndex int
Bindings []binding
} `asn1:"tag:0"`
}
type response struct {
ID int32
ErrorStatus int
ErrorIndex int
Bindings []binding
}
type binding struct {
Name asn1.ObjectIdentifier
Value asn1.RawValue
}
var (
null = asn1.RawValue{Class: 0, Tag: 5}
noSuchObject = asn1.RawValue{Class: 2, Tag: 0}
noSuchInstance = asn1.RawValue{Class: 2, Tag: 1}
endOfMibView = asn1.RawValue{Class: 2, Tag: 2}
)
type SNMPMatcher struct {
csm.Matchers
requestID int32
meta csm.Metadata
}
func (s *SNMPMatcher) Key() string {
return "SNMP"
}
func (s *SNMPMatcher) Name() string {
return "SNMP"
}
func (s *SNMPMatcher) Meta() csm.Metadata {
return s.meta
}
func (s *SNMPMatcher) IsPrePacket() bool {
return false
}
func (s *SNMPMatcher) HasResponse(index int) bool {
return true
}
func (s *SNMPMatcher) Match(info csm.MatchInfo, index int, packet *csm.Packet) error {
if packet == nil || packet.Buffer == nil || packet.Len == 0 {
return csm.NoPacketReceivedError()
}
var p struct {
Version int
Community []byte
Data struct {
RequestID int32
ErrorStatus int
ErrorIndex int
Bindings []binding
} `asn1:"tag:2"`
}
if _, err := asn1.Unmarshal(packet.Buffer[0:packet.Len], &p); err != nil {
return err
}
resp := &response{p.Data.RequestID, p.Data.ErrorStatus, p.Data.ErrorIndex, p.Data.Bindings}
if s.requestID != resp.ID {
return csm.NotMatchedError()
}
if len(resp.Bindings) == 0 {
return csm.NotMatchedError()
}
for _, binding := range resp.Bindings {
if len(binding.Value.Bytes) <= 0 {
continue
}
// if binding.Name.String() == "1.3.6.1.2.1.1.5.0" {
s.meta[binding.Name.String()] = string(binding.Value.Bytes)
// }
}
return nil
}
func (s *SNMPMatcher) IsSend(port int) bool {
if 161 == port {
return true
}
return false
}
func NewMatcher() csm.UDPMatcher {
m := &SNMPMatcher{}
m.meta = csm.NewMetadata()
m.requestID = rand.Int31()
p := snmpv2{}
p.Version = 0
p.Community = []byte("test1252serc")
p.Data.RequestID = m.requestID
p.Data.Bindings = []binding{
binding{
Name: []int{1, 3, 6, 1, 2, 1, 1, 5, 0},
Value: null,
},
binding{
Name: []int{1, 3, 6, 1, 2, 1, 1, 1, 0},
Value: null,
},
}
buf, _ := asn1.Marshal(p)
m.AddPacket(csm.NewPacket(buf, len(buf)))
return m
}