func (dns *Dns) ReceivedFin(tcpTuple *common.TcpTuple, dir uint8, private protos.ProtocolData) protos.ProtocolData { if private == nil { return nil } conn, ok := private.(*dnsConnectionData) if !ok { return private } stream := conn.Data[dir] if stream == nil || stream.message == nil { return conn } decodedData, err := stream.handleTcpRawData() if err == nil { dns.messageComplete(conn, tcpTuple, dir, decodedData) return conn } if dir == tcp.TcpDirectionReverse { dns.publishResponseError(conn, err) } logp.Debug("dns", "%s addresses %s, length %d", err.Error(), tcpTuple.String(), len(stream.rawData)) return conn }
func (dns *Dns) GapInStream(tcpTuple *common.TcpTuple, dir uint8, nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { if private == nil { return private, true } conn, ok := private.(*dnsConnectionData) if !ok { return private, false } stream := conn.Data[dir] if stream == nil || stream.message == nil { return private, false } decodedData, err := stream.handleTcpRawData() if err == nil { dns.messageComplete(conn, tcpTuple, dir, decodedData) return private, true } if dir == tcp.TcpDirectionReverse { dns.publishResponseError(conn, err) } logp.Debug("dns", "%s addresses %s, length %d", err.Error(), tcpTuple.String(), len(stream.rawData)) logp.Debug("dns", "Dropping the stream %s", tcpTuple.String()) // drop the stream because it is binary Data and it would be unexpected to have a decodable message later return private, true }
func (http *HTTP) handleHTTP( conn *httpConnectionData, m *message, tcptuple *common.TcpTuple, dir uint8, ) { m.TCPTuple = *tcptuple m.Direction = dir m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) http.hideHeaders(m) if m.IsRequest { if isDebug { debugf("Received request with tuple: %s", m.TCPTuple) } conn.requests.append(m) } else { if isDebug { debugf("Received response with tuple: %s", m.TCPTuple) } conn.responses.append(m) http.correlate(conn) } }
func (dns *Dns) GapInStream(tcpTuple *common.TcpTuple, dir uint8, nbytes int, private protos.ProtocolData) (priv protos.ProtocolData, drop bool) { dnsData, ok := private.(dnsPrivateData) if !ok { return private, false } stream := dnsData.Data[dir] if stream == nil || stream.message == nil { return private, false } decodedData, err := decodeDnsData(TransportTcp, stream.data) // Add Notes if the failed stream is the response if err != nil { if dir == tcp.TcpDirectionReverse { dns.publishDecodeFailureNotes(dnsData) } // drop the stream because it is binary and it would be rare to have a decodable message later logp.Debug("dns", NonDnsCompleteMsg+" addresses %s, length %d", tcpTuple.String(), len(stream.data)) return private, true } // publish and ignore the gap. No case should reach this code though ... dns.messageComplete(tcpTuple, dir, stream, decodedData) return private, false }
func (dns *Dns) ReceivedFin(tcpTuple *common.TcpTuple, dir uint8, private protos.ProtocolData) protos.ProtocolData { if private == nil { return private } dnsData, ok := private.(dnsPrivateData) if !ok { return private } if dnsData.Data[dir] == nil { return dnsData } stream := dnsData.Data[dir] if stream.message != nil { decodedData, err := decodeDnsData(TransportTcp, stream.data) if err == nil { dns.messageComplete(tcpTuple, dir, stream, decodedData) } else /*Failed decode */ { if dir == tcp.TcpDirectionReverse { dns.publishDecodeFailureNotes(dnsData) stream.PrepareForNewMessage() } logp.Debug("dns", NonDnsCompleteMsg+" addresses %s, length %d", tcpTuple.String(), len(stream.data)) } } return dnsData }
func (dns *Dns) handleDns(m *DnsMessage, tcpTuple *common.TcpTuple, dir uint8, data []byte, decodedData *layers.DNS) { dnsTuple := DnsTupleFromIpPort(&m.Tuple, TransportTcp, decodedData.ID) m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcpTuple.IpPort()) m.Data = decodedData m.Length = len(data) if decodedData.QR == Query { dns.receivedDnsRequest(&dnsTuple, m) } else /* Response */ { dns.receivedDnsResponse(&dnsTuple, m) } }
func (pgsql *Pgsql) removeTransaction(transList []*PgsqlTransaction, tuple common.TcpTuple, index int) *PgsqlTransaction { trans := transList[index] transList = append(transList[:index], transList[index+1:]...) if len(transList) == 0 { pgsql.transactions.Delete(trans.tuple.Hashable()) } else { pgsql.transactions.Put(tuple.Hashable(), transList) } return trans }
func (http *HTTP) handleHTTP(m *message, tcptuple *common.TcpTuple, dir uint8, rawMsg []byte) { m.TCPTuple = *tcptuple m.Direction = dir m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) m.Raw = rawMsg if m.IsRequest { http.receivedHTTPRequest(m) } else { http.receivedHTTPResponse(m) } }
func (thrift *Thrift) ReceivedFin(tcptuple *common.TcpTuple, dir uint8, private protos.ProtocolData) protos.ProtocolData { trans := thrift.getTransaction(tcptuple.Hashable()) if trans != nil { if trans.Request != nil && trans.Reply == nil { logp.Debug("thrift", "FIN and had only one transaction. Assuming one way") thrift.PublishQueue <- trans thrift.transactions.Delete(trans.tuple.Hashable()) } } return private }
func handleMysql(mysql *Mysql, m *MysqlMessage, tcptuple *common.TcpTuple, dir uint8, raw_msg []byte) { m.TcpTuple = *tcptuple m.Direction = dir m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) m.Raw = raw_msg if m.IsRequest { mysql.receivedMysqlRequest(m) } else { mysql.receivedMysqlResponse(m) } }
func (dns *Dns) handleDns(conn *dnsConnectionData, tcpTuple *common.TcpTuple, decodedData *mkdns.Msg, dir uint8) { message := conn.Data[dir].message dnsTuple := DnsTupleFromIpPort(&message.Tuple, TransportTcp, decodedData.Id) message.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcpTuple.IpPort()) message.Data = decodedData message.Length += DecodeOffset if decodedData.Response { dns.receivedDnsResponse(&dnsTuple, message) conn.prevRequest = nil } else /* Query */ { dns.receivedDnsRequest(&dnsTuple, message) conn.prevRequest = message } }
func (redis *Redis) handleRedis( conn *redisConnectionData, m *redisMessage, tcptuple *common.TcpTuple, dir uint8, ) { m.TcpTuple = *tcptuple m.Direction = dir m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) if m.IsRequest { conn.requests.append(m) // wait for response } else { conn.responses.append(m) redis.correlate(conn) } }
func (dns *Dns) doParse(conn *dnsConnectionData, pkt *protos.Packet, tcpTuple *common.TcpTuple, dir uint8) *dnsConnectionData { stream := conn.Data[dir] payload := pkt.Payload if stream == nil { stream = newStream(pkt, tcpTuple) conn.Data[dir] = stream } else { if stream.message == nil { // nth message of the same stream stream.message = &DnsMessage{Ts: pkt.Ts, Tuple: pkt.Tuple} } stream.rawData = append(stream.rawData, payload...) if len(stream.rawData) > tcp.TCP_MAX_DATA_IN_STREAM { logp.Debug("dns", "Stream data too large, dropping DNS stream") conn.Data[dir] = nil return conn } } decodedData, err := stream.handleTcpRawData() if err != nil { if err == IncompleteMsg { logp.Debug("dns", "Waiting for more raw data") return conn } if dir == tcp.TcpDirectionReverse { dns.publishResponseError(conn, err) } logp.Debug("dns", "%s addresses %s, length %d", err.Error(), tcpTuple.String(), len(stream.rawData)) // This means that malformed requests or responses are being sent... // TODO: publish the situation also if Request conn.Data[dir] = nil return conn } dns.messageComplete(conn, tcpTuple, dir, decodedData) stream.PrepareForNewMessage() return conn }
func (mongodb *Mongodb) handleMongodb( conn *mongodbConnectionData, m *mongodbMessage, tcptuple *common.TcpTuple, dir uint8, ) { m.TcpTuple = *tcptuple m.Direction = dir m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) if m.IsResponse { debugf("MongoDB response message") mongodb.onResponse(conn, m) } else { debugf("MongoDB request message") mongodb.onRequest(conn, m) } }
func (amqp *Amqp) handleAmqp(m *AmqpMessage, tcptuple *common.TcpTuple, dir uint8) { if amqp.mustHideCloseMethod(m) { return } debugf("A message is ready to be handled") m.TcpTuple = *tcptuple m.Direction = dir m.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) if m.Method == "basic.publish" { amqp.handlePublishing(m) } else if m.Method == "basic.deliver" || m.Method == "basic.return" || m.Method == "basic.get-ok" { amqp.handleDelivering(m) } else if m.IsRequest == true { amqp.handleAmqpRequest(m) } else if m.IsRequest == false { amqp.handleAmqpResponse(m) } }
func (dns *Dns) Parse(pkt *protos.Packet, tcpTuple *common.TcpTuple, dir uint8, private protos.ProtocolData) protos.ProtocolData { defer logp.Recover("DNS ParseTcp") logp.Debug("dns", "Parsing packet addressed with %s of length %d.", pkt.Tuple.String(), len(pkt.Payload)) priv := dnsPrivateData{} if private != nil { var ok bool priv, ok = private.(dnsPrivateData) if !ok { priv = dnsPrivateData{} } } payload := pkt.Payload stream := &priv.Data[dir] if *stream == nil { *stream = &DnsStream{ tcpTuple: tcpTuple, data: payload, message: &DnsMessage{Ts: pkt.Ts, Tuple: pkt.Tuple}, } if len(payload) <= DecodeOffset { logp.Debug("dns", EmptyMsg+" addresses %s", tcpTuple.String()) return priv } } else { (*stream).data = append((*stream).data, payload...) dataLength := len((*stream).data) if dataLength > tcp.TCP_MAX_DATA_IN_STREAM { logp.Debug("dns", "Stream data too large, dropping DNS stream") return priv } if dataLength <= DecodeOffset { logp.Debug("dns", EmptyMsg+" addresses %s", tcpTuple.String()) return priv } } data, err := decodeDnsData(TransportTcp, (*stream).data) if err != nil { logp.Debug("dns", NonDnsCompleteMsg+" addresses %s, length %d", tcpTuple.String(), len((*stream).data)) // wait for decoding with the next segment return priv } dns.messageComplete(tcpTuple, dir, *stream, data) return priv }
func (thrift *Thrift) messageComplete(tcptuple *common.TcpTuple, dir uint8, stream *ThriftStream, priv *thriftPrivateData) { var flush bool = false if stream.message.IsRequest { logp.Debug("thrift", "Thrift request message: %s", stream.message.Method) if !thrift.CaptureReply { // enable the stream in the other direction to get the reply stream_rev := priv.Data[1-dir] if stream_rev != nil { stream_rev.skipInput = false } } } else { logp.Debug("thrift", "Thrift response message: %s", stream.message.Method) if !thrift.CaptureReply { // disable stream in this direction stream.skipInput = true // and flush current data flush = true } } // all ok, go to next level stream.message.TcpTuple = *tcptuple stream.message.Direction = dir stream.message.CmdlineTuple = procs.ProcWatcher.FindProcessesTuple(tcptuple.IpPort()) if stream.message.FrameSize == 0 { stream.message.FrameSize = uint32(stream.parseOffset - stream.message.start) } thrift.handleThrift(stream.message) // and reset message stream.PrepareForNewMessage(flush) }
// Parse processes a TCP packet. Return nil if connection // state shall be dropped (e.g. parser not in sync with tcp stream) func (cassandra *cassandra) Parse( pkt *protos.Packet, tcptuple *common.TcpTuple, dir uint8, private protos.ProtocolData, ) protos.ProtocolData { defer logp.Recover("Parse cassandra exception") conn := cassandra.ensureConnection(private) st := conn.streams[dir] if st == nil { st = &stream{} st.parser.init(&cassandra.parserConfig, func(msg *message) error { return conn.trans.onMessage(tcptuple.IpPort(), dir, msg) }) conn.streams[dir] = st } if err := st.parser.feed(pkt.Ts, pkt.Payload); err != nil { debugf("%v, dropping TCP stream for error in direction %v.", err, dir) cassandra.onDropConnection(conn) return nil } return conn }
func (mc *Memcache) memcacheParseTCP( tcpConn *tcpConnectionData, pkt *protos.Packet, tcptuple *common.TcpTuple, dir uint8, ) *tcpConnectionData { // assume we are in sync stream := tcpConn.Streams[dir] if stream == nil { stream = mc.newStream(tcptuple) tcpConn.Streams[dir] = stream } debug("add payload to stream(%p): %v", stream, dir) if err := stream.Append(pkt.Payload); err != nil { debug("%v, dropping TCP streams", err) mc.pushAllTCPTrans(tcpConn.connection) tcpConn.drop(dir) return nil } if tcpConn.connection == nil { tcpConn.connection = &connection{} } else { stopped := tcpConn.connection.timer.Stop() if !stopped { // timer was stopped by someone else, create new connection tcpConn.connection = &connection{} } } conn := tcpConn.connection for stream.Buf.Total() > 0 { debug("stream(%p) try to content", stream) msg, err := stream.parse(pkt.Ts) if err != nil { // parsing error, drop tcp stream and retry with next segement debug("Ignore Memcache message, drop tcp stream: %v", err) mc.pushAllTCPTrans(conn) tcpConn.drop(dir) return nil } if msg == nil { // wait for more data break } stream.reset() tuple := tcptuple.IpPort() err = mc.onTCPMessage(conn, tuple, dir, msg) if err != nil { logp.Warn("error processing memcache message: %s", err) } } conn.timer = time.AfterFunc(mc.tcpTransTimeout, func() { debug("connection=%p timed out", conn) mc.pushAllTCPTrans(conn) }) return tcpConn }