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 (m *SNMPMatcher) Type() string { return "MONITORING" } func (m *SNMPMatcher) Vendor(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SNMPMatcher) Version(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SNMPMatcher) OsType(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } func (m *SNMPMatcher) OsVersion(matchCtx *osm.MatchCtx) string { return "UNKNOWN" } 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 }