package v3 import ( "bytes" "encoding/binary" "git.loafle.net/overflow/overflow_discovery/service/matcher" "git.loafle.net/overflow/overflow_probe/matcher/snmp" ) type snmpv3GlobalData struct { GlobalDataStartSeq uint8 GlobalDataLen uint8 MsgIdType uint8 MsgIdLen uint8 MsgId uint32 MsgMaxSizeType uint8 MsgMaxSizeLen uint8 MsgMaxSize [3]uint8 MsgFlagsType uint8 MsgFlagsTypeLen uint8 MsgFlags uint8 MsgSecurityModelType uint8 MsgSecurityModelLen uint8 MsgSecurityModel uint8 } type snmpv3MsgData struct { MsgDataStartSeq uint8 MsgDataLen uint8 ContextEngineId uint16 ContextEngineName uint16 SnmpType uint8 Len uint8 RequestIdType uint8 RequestIdLen uint8 RequestId uint32 ErrorStatusType uint8 ErrorStatusLen uint8 ErrorStatus uint8 ErrorIndexType uint8 ErrorIndexLen uint8 ErrorIndex uint8 EndSeq uint8 EndIndicator uint8 } type snmpv3 struct { StartSeq uint8 SeqLen uint8 SNMPVersionType uint8 SNMPVersionLen uint8 SNMPVersion uint8 MsgGlobalData snmpv3GlobalData Unk1 uint16 Unk2 uint16 MsgAuthoritativeEngineId uint16 MsgAuthoritativeEngineBootsType uint8 MsgAuthoritativeEngineBootsLen uint8 MsgAuthoritativeEngineBoots uint8 MsgAuthoritativeEngineTimeType uint8 MsgAuthoritativeEngineTimeLen uint8 MsgAuthoritativeEngineTime uint8 MsgUserName uint16 MsgAuthenticationParam uint16 MsgPrivacyParam uint16 MsgData snmpv3MsgData } type SNMPMatcher struct { matcher.Matchers } func (t *SNMPMatcher) ServiceName() string { return "SNMP V3" } func (t *SNMPMatcher) IsPrePacket() bool { return false } func (t *SNMPMatcher) HasResponse(index int) bool { return true } func (t *SNMPMatcher) IsError(info matcher.MatchInfo, index int, packet *matcher.Packet) bool { return false } func (t *SNMPMatcher) Match(info matcher.MatchInfo, index int, packet *matcher.Packet) bool { if packet == nil { return false } reader := new(bytes.Buffer) reader.Write(packet.Buffer) s := snmpv3{} if err := binary.Read(reader, binary.LittleEndian, &s); err != nil { return false } if s.StartSeq != snmp.SNMP_START_SEQUENCE { return false } var p uint8 r := new(bytes.Buffer) r.Write(packet.Buffer) for { binary.Read(r, binary.LittleEndian, &p) if p == snmp.SNMP_TYPE_INTEGER { break } } binary.Read(r, binary.BigEndian, &p) if p == 0x01 { binary.Read(r, binary.BigEndian, &p) if p == 0x03 { return true } } return false } func (t *SNMPMatcher) IsSend(port int) bool { if 161 == port { return true } return false } func NewMatcher() matcher.UDPMatcher { m := &SNMPMatcher{} snmpTempBuf := new(bytes.Buffer) binary.Write(snmpTempBuf, binary.BigEndian, snmpv3{}) //For getting the struct size snmpMsgDataTempBuf := new(bytes.Buffer) binary.Write(snmpMsgDataTempBuf, binary.BigEndian, snmpv3MsgData{}) //For getting the struct size snmpGlobalTempBuf := new(bytes.Buffer) binary.Write(snmpGlobalTempBuf, binary.BigEndian, snmpv3GlobalData{}) //For getting the struct size q := snmpv3{} q.StartSeq = snmp.SNMP_START_SEQUENCE q.SeqLen = uint8(len(snmpTempBuf.Bytes())) - 2 q.SNMPVersionType = snmp.SNMP_TYPE_INTEGER q.SNMPVersionLen = 0x01 q.SNMPVersion = snmp.SNMP_PROTOCOL_VERSION_3 q.MsgGlobalData.GlobalDataStartSeq = snmp.SNMP_START_SEQUENCE q.MsgGlobalData.GlobalDataLen = uint8(len(snmpGlobalTempBuf.Bytes())) - 2 q.MsgGlobalData.MsgIdType = snmp.SNMP_TYPE_INTEGER q.MsgGlobalData.MsgIdLen = 0x04 q.MsgGlobalData.MsgId = snmp.SNMP_MSG_ID_MAX_VALUE q.MsgGlobalData.MsgMaxSizeType = snmp.SNMP_TYPE_INTEGER q.MsgGlobalData.MsgMaxSizeLen = 0x03 q.MsgGlobalData.MsgMaxSize[2] = 0xe3 q.MsgGlobalData.MsgMaxSize[1] = 0xff q.MsgGlobalData.MsgMaxSize[0] = 0x00 q.MsgGlobalData.MsgFlagsType = snmp.SNMP_TYPE_STRING q.MsgGlobalData.MsgFlagsTypeLen = 0x01 q.MsgGlobalData.MsgFlags = 0x04 q.MsgGlobalData.MsgSecurityModelType = snmp.SNMP_TYPE_INTEGER q.MsgGlobalData.MsgSecurityModelLen = 0x01 q.MsgGlobalData.MsgSecurityModel = 0x03 q.Unk1 = 0x1004 q.Unk2 = 0x0e30 q.MsgAuthoritativeEngineId = snmp.SNMP_NO_DESC q.MsgAuthoritativeEngineBootsType = snmp.SNMP_TYPE_INTEGER q.MsgAuthoritativeEngineBootsLen = 0x01 q.MsgAuthoritativeEngineBoots = 0x00 q.MsgAuthoritativeEngineTimeType = snmp.SNMP_TYPE_INTEGER q.MsgAuthoritativeEngineTimeLen = 0x01 q.MsgAuthoritativeEngineTime = 0x00 q.MsgUserName = snmp.SNMP_NO_DESC q.MsgAuthenticationParam = snmp.SNMP_NO_DESC q.MsgPrivacyParam = snmp.SNMP_NO_DESC q.MsgData.MsgDataStartSeq = snmp.SNMP_START_SEQUENCE q.MsgData.MsgDataLen = uint8(len(snmpMsgDataTempBuf.Bytes())) - 2 q.MsgData.ContextEngineId = snmp.SNMP_NO_DESC q.MsgData.ContextEngineName = snmp.SNMP_NO_DESC q.MsgData.SnmpType = snmp.SNMP_GET_REQUEST q.MsgData.Len = 0x0E q.MsgData.RequestIdType = snmp.SNMP_TYPE_INTEGER q.MsgData.RequestIdLen = 0x04 q.MsgData.RequestId = 0x00 // q.MsgData.ErrorStatusType = snmp.SNMP_TYPE_INTEGER q.MsgData.ErrorStatusLen = 0x01 q.MsgData.ErrorStatus = 0x00 q.MsgData.ErrorIndexType = snmp.SNMP_TYPE_INTEGER q.MsgData.ErrorIndexLen = 0x01 q.MsgData.ErrorIndex = 0x00 q.MsgData.EndSeq = snmp.SNMP_END_SEQUENCE q.MsgData.EndIndicator = 0x00 writer := new(bytes.Buffer) binary.Write(writer, binary.LittleEndian, q) m.AddPacket(matcher.NewPacket(writer.Bytes(), writer.Len())) return m }