package cassandra import ( "bytes" "encoding/binary" "loafle.com/overflow/commons_go/matcher/packet" "loafle.com/overflow/commons_go/model/scaninfo" ) const ( COMPRESSION = "COMPRESSION" CQL_VERSION = "CQL_VERSION" ) type cassandra struct { Version uint8 Flags uint8 Stream uint16 Opcode uint8 Length uint32 } type CassandraMatcher struct { packets []*packet.Packet } func NewCassandraMatcher() *CassandraMatcher { cassMatcher := &CassandraMatcher{} c := cassandra{ Version: 4, Flags: 0, Stream: 0, Opcode: 5, Length: 0, } writer := new(bytes.Buffer) binary.Write(writer, binary.LittleEndian, c) cassMatcher.packets = append(cassMatcher.packets, packet.NewPacket(writer.Bytes(), writer.Len())) return cassMatcher } func (t *CassandraMatcher) ServiceName() string { return "Cassandra" } func (t *CassandraMatcher) PacketCount() int { return len(t.packets) } func (t *CassandraMatcher) Packet(index int) *packet.Packet { return t.packets[index] } func (t *CassandraMatcher) IsError(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool { return false } func (t *CassandraMatcher) IsNoResponse(index int) bool { return false } func (t *CassandraMatcher) IsPrePacket() bool { return false } func (t *CassandraMatcher) Match(index int, packet *packet.Packet, info scaninfo.ServiceScanInfo) bool { if packet == nil { return false } reader := new(bytes.Buffer) reader.Write(packet.Buffer) c := cassandra{} if err := binary.Read(reader, binary.BigEndian, &c); err != nil { return false } if c.Version != 0x84 { return false } if c.Flags != 0x00 { return false } if c.Stream != 0x00 { return false } if c.Opcode != 0x06 { return false } var itemcount uint16 if binary.Read(reader, binary.BigEndian, &itemcount) != nil { return false } if itemcount != 0 && itemcount != 2 { return false } return true }