package snmp import ( "bytes" "encoding/binary" "git.loafle.net/overflow/overflow_probe/matcher/packet" "git.loafle.net/overflow/overflow_probe/model/scaninfo" ) const ( SNMP_START_SEQUENCE uint8 = 0X30 SNMP_TYPE_INTEGER uint8 = 0X02 SNMP_TYPE_STRING uint8 = 0X04 SNMP_TYPE_NULL uint8 = 0X05 SNMP_TYPE_OBJECT uint8 = 0X06 SNMP_GET_REQUEST uint8 = 0XA0 //SNMP_RESPONSE uint8 = 0XA2 SNMP_NO_DESC uint16 = 0X0004 SNMP_END_SEQUENCE uint8 = 0X30 SNMP_PROTOCOL_VERSION_3 uint8 = 0X03 SNMP_PROTOCOL_VERSION_2c uint8 = 0X01 SNMP_MSG_ID_MAX_VALUE uint32 = 0xFFFFFF7F ) 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 SNMPv2Matcher struct { packets []*packet.Packet } func NewSNMPv2Matcher() *SNMPv2Matcher { snmpMatcher := &SNMPv2Matcher{} 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 = SNMP_START_SEQUENCE q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2 q.SNMPVersionType = SNMP_TYPE_INTEGER q.SNMPVersionLen = 0x01 q.SNMPVersion = SNMP_PROTOCOL_VERSION_2c q.CommunityVersionType = SNMP_TYPE_STRING q.CommunityVersionLen = 0x06 var community [6]byte copy(community[:], "public") q.Community = community q.Data.DataType = SNMP_GET_REQUEST q.Data.DataLen = uint8(len(snmpDataTempBuf.Bytes())) - 2 q.Data.RequestIdType = SNMP_TYPE_INTEGER q.Data.RequestIdLen = 0x01 q.Data.RequestId = 0x01 q.Data.ErrorStatusType = SNMP_TYPE_INTEGER q.Data.ErrorStatusLen = 0x01 q.Data.ErrorStatus = 0x00 q.Data.ErrorIndexType = SNMP_TYPE_INTEGER q.Data.ErrorIndexLen = 0x01 q.Data.ErrorIndex = 0x00 q.Data.VarBinding.VarBindindStart = SNMP_START_SEQUENCE q.Data.VarBinding.VarBindLen = uint8(len(snmpVarTempBuf.Bytes())) - 2 q.Data.VarBinding.ObjectStart = SNMP_START_SEQUENCE q.Data.VarBinding.ObjectLen = uint8(len(snmpVarTempBuf.Bytes())) - 4 q.Data.VarBinding.ValueType = SNMP_TYPE_OBJECT q.Data.VarBinding.ValueLen = 0x08 q.Data.VarBinding.ObjectValue = 0x000001010201062b q.Data.VarBinding.NullValue = SNMP_TYPE_NULL q.Data.VarBinding.EndIndicator = 0x00 writer := new(bytes.Buffer) binary.Write(writer, binary.LittleEndian, q) snmpMatcher.packets = append(snmpMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len())) return snmpMatcher } func (t *SNMPv2Matcher) ServiceName() string { return "SNMP" } func (t *SNMPv2Matcher) PacketCount() int { return len(t.packets) } func (t *SNMPv2Matcher) Packet(index int) *packet.Packet { return t.packets[index] } func (t *SNMPv2Matcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool { return false } func (t *SNMPv2Matcher) IsNoResponse(index int) bool { return false } func (t *SNMPv2Matcher) IsPrePacket() bool { return false } func (t *SNMPv2Matcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) 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 != 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 == 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 *SNMPv2Matcher) IsSend(port int) bool { if port == 161 { return true } return false }