139 lines
2.4 KiB
Go
139 lines
2.4 KiB
Go
package v2
|
|
|
|
import (
|
|
"encoding/asn1"
|
|
"math/rand"
|
|
|
|
osm "git.loafle.net/overflow/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 {
|
|
osm.Matchers
|
|
|
|
requestID int32
|
|
}
|
|
|
|
func (s *SNMPMatcher) Key() string {
|
|
return "SNMP"
|
|
}
|
|
|
|
func (s *SNMPMatcher) Name(matchCtx *osm.MatchCtx) string {
|
|
return "SNMP"
|
|
}
|
|
|
|
func (s *SNMPMatcher) IsPrePacket() bool {
|
|
return false
|
|
}
|
|
|
|
func (s *SNMPMatcher) HasResponse(matchCtx *osm.MatchCtx, index int) bool {
|
|
return true
|
|
}
|
|
|
|
func (s *SNMPMatcher) Match(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) error {
|
|
|
|
if packet == nil || !packet.Valid() {
|
|
return osm.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, &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 osm.NotMatchedError()
|
|
}
|
|
|
|
if len(resp.Bindings) == 0 {
|
|
return osm.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" {
|
|
matchCtx.SetAttribute(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() osm.UDPMatcher {
|
|
|
|
m := &SNMPMatcher{}
|
|
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(osm.NewPacket(buf, len(buf)))
|
|
|
|
return m
|
|
}
|