180 lines
4.1 KiB
Go
180 lines
4.1 KiB
Go
|
package v2
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/binary"
|
||
|
|
||
|
cnsm "git.loafle.net/commons_go/network_service_matcher"
|
||
|
cnsms "git.loafle.net/commons_go/network_service_matcher/snmp"
|
||
|
)
|
||
|
|
||
|
type snmpv2VarBinding struct {
|
||
|
VarBindindStart uint8
|
||
|
VarBindLen uint8
|
||
|
ObjectStart uint8
|
||
|
ObjectLen uint8
|
||
|
ValueType uint8
|
||
|
ValueLen uint8
|
||
|
ObjectValue uint64
|
||
|
NullValue uint8
|
||
|
EndIndicator uint8
|
||
|
}
|
||
|
|
||
|
type snmpv2Data struct {
|
||
|
DataType uint8
|
||
|
DataLen uint8
|
||
|
RequestIdType uint8
|
||
|
RequestIdLen uint8
|
||
|
RequestId uint8
|
||
|
ErrorStatusType uint8
|
||
|
ErrorStatusLen uint8
|
||
|
ErrorStatus uint8
|
||
|
ErrorIndexType uint8
|
||
|
ErrorIndexLen uint8
|
||
|
ErrorIndex uint8
|
||
|
|
||
|
VarBinding snmpv2VarBinding
|
||
|
}
|
||
|
|
||
|
type snmpv2 struct {
|
||
|
StartSeq uint8
|
||
|
SeqLen uint8
|
||
|
SNMPVersionType uint8
|
||
|
SNMPVersionLen uint8
|
||
|
SNMPVersion uint8
|
||
|
CommunityVersionType uint8
|
||
|
CommunityVersionLen uint8
|
||
|
Community [6]byte
|
||
|
|
||
|
Data snmpv2Data
|
||
|
}
|
||
|
|
||
|
type SNMPMatcher struct {
|
||
|
cnsm.Matchers
|
||
|
}
|
||
|
|
||
|
func (t *SNMPMatcher) ServiceName() string {
|
||
|
return "SNMP V2"
|
||
|
}
|
||
|
|
||
|
func (t *SNMPMatcher) IsPrePacket() bool {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func (t *SNMPMatcher) HasResponse(index int) bool {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func (t *SNMPMatcher) IsError(info cnsm.MatchInfo, index int, packet *cnsm.Packet) bool {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func (t *SNMPMatcher) Match(info cnsm.MatchInfo, index int, packet *cnsm.Packet) bool {
|
||
|
|
||
|
if packet == nil {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
r := new(bytes.Buffer)
|
||
|
r.Write(packet.Buffer)
|
||
|
|
||
|
s := snmpv2{}
|
||
|
if err := binary.Read(r, binary.BigEndian, &s); err != nil {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
if s.StartSeq != cnsms.SNMP_START_SEQUENCE {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
var p uint8
|
||
|
reader := new(bytes.Buffer)
|
||
|
reader.Write(packet.Buffer)
|
||
|
for idx := 0; idx < 5; idx++ {
|
||
|
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
|
||
|
return false
|
||
|
}
|
||
|
if p == cnsms.SNMP_TYPE_INTEGER {
|
||
|
break
|
||
|
}
|
||
|
p++
|
||
|
}
|
||
|
|
||
|
//finding protocol version type : 0x02 0x01 0x01
|
||
|
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
if p == 0x01 {
|
||
|
if err := binary.Read(reader, binary.BigEndian, &p); err != nil {
|
||
|
return false
|
||
|
}
|
||
|
if p == 0x01 {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
|
||
|
}
|
||
|
|
||
|
func (t *SNMPMatcher) IsSend(port int) bool {
|
||
|
if 161 == port {
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func NewMatcher() cnsm.UDPMatcher {
|
||
|
|
||
|
m := &SNMPMatcher{}
|
||
|
|
||
|
snmpTempBuf := new(bytes.Buffer)
|
||
|
binary.Write(snmpTempBuf, binary.BigEndian, snmpv2{}) //For getting the struct size
|
||
|
|
||
|
snmpDataTempBuf := new(bytes.Buffer)
|
||
|
binary.Write(snmpDataTempBuf, binary.BigEndian, snmpv2Data{}) //For getting the struct size
|
||
|
|
||
|
snmpVarTempBuf := new(bytes.Buffer)
|
||
|
binary.Write(snmpVarTempBuf, binary.BigEndian, snmpv2VarBinding{}) //For getting the struct size
|
||
|
|
||
|
q := snmpv2{}
|
||
|
q.StartSeq = cnsms.SNMP_START_SEQUENCE
|
||
|
q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2
|
||
|
q.SNMPVersionType = cnsms.SNMP_TYPE_INTEGER
|
||
|
q.SNMPVersionLen = 0x01
|
||
|
q.SNMPVersion = cnsms.SNMP_PROTOCOL_VERSION_2c
|
||
|
q.CommunityVersionType = cnsms.SNMP_TYPE_STRING
|
||
|
q.CommunityVersionLen = 0x06
|
||
|
var community [6]byte
|
||
|
copy(community[:], "public")
|
||
|
q.Community = community
|
||
|
q.Data.DataType = cnsms.SNMP_GET_REQUEST
|
||
|
q.Data.DataLen = uint8(len(snmpDataTempBuf.Bytes())) - 2
|
||
|
q.Data.RequestIdType = cnsms.SNMP_TYPE_INTEGER
|
||
|
q.Data.RequestIdLen = 0x01
|
||
|
q.Data.RequestId = 0x01
|
||
|
q.Data.ErrorStatusType = cnsms.SNMP_TYPE_INTEGER
|
||
|
q.Data.ErrorStatusLen = 0x01
|
||
|
q.Data.ErrorStatus = 0x00
|
||
|
q.Data.ErrorIndexType = cnsms.SNMP_TYPE_INTEGER
|
||
|
q.Data.ErrorIndexLen = 0x01
|
||
|
q.Data.ErrorIndex = 0x00
|
||
|
q.Data.VarBinding.VarBindindStart = cnsms.SNMP_START_SEQUENCE
|
||
|
q.Data.VarBinding.VarBindLen = uint8(len(snmpVarTempBuf.Bytes())) - 2
|
||
|
q.Data.VarBinding.ObjectStart = cnsms.SNMP_START_SEQUENCE
|
||
|
q.Data.VarBinding.ObjectLen = uint8(len(snmpVarTempBuf.Bytes())) - 4
|
||
|
q.Data.VarBinding.ValueType = cnsms.SNMP_TYPE_OBJECT
|
||
|
q.Data.VarBinding.ValueLen = 0x08
|
||
|
q.Data.VarBinding.ObjectValue = 0x000001010201062b
|
||
|
q.Data.VarBinding.NullValue = cnsms.SNMP_TYPE_NULL
|
||
|
q.Data.VarBinding.EndIndicator = 0x00
|
||
|
|
||
|
writer := new(bytes.Buffer)
|
||
|
binary.Write(writer, binary.LittleEndian, q)
|
||
|
|
||
|
m.AddPacket(cnsm.NewPacket(writer.Bytes(), writer.Len()))
|
||
|
|
||
|
return m
|
||
|
}
|