Example #1
0
    def state_conn_finish(self, ts, tcp, to_server):
        # Still acknowledging older packets.
        if self.cli != tcp.ack and self.srv != tcp.ack:
            self.state_conn(ts, tcp, to_server)
            return

        if tcp.flags & dpkt.tcp.TH_ACK:
            if to_server:
                if self.srv != tcp.ack:
                    raise InvalidTcpPacketOrder(tcp)

                # Process any final packets.
                tcp.ack -= 1
                self.state_conn(ts, tcp, to_server)

                # Indicate the end of this connection.
                self.srv = None

            if not to_server:
                if self.cli != tcp.ack:
                    raise InvalidTcpPacketOrder(tcp)

                # Process any final packets.
                tcp.ack -= 1
                self.state_conn(ts, tcp, to_server)

                # Indicate the end of this connection.
                self.cli = None

        if tcp.flags & dpkt.tcp.TH_FIN:
            if to_server:
                self.cli = tcp.seq + 1
            else:
                self.srv = tcp.seq + 1
Example #2
0
    def state_init_ack(self, ts, tcp, to_server):
        # Retransmission of the SYN packet. Let's ignore that for now.
        if to_server and tcp.flags == dpkt.tcp.TH_SYN:
            # self.parent.handle(self.s, ts, TCPRetransmission(),
            #                    None, special="deadhost")
            return

        # Retransmission of the SYN ACK packet. Indicates that the client is
        # not responding within the given timeframe; a potential SYN flood?
        if not to_server and tcp.flags == (dpkt.tcp.TH_SYN | dpkt.tcp.TH_ACK):
            # self.parent.handle(self.s, ts, TCPRetransmission(),
            #                    None, special="synflood")
            return

        # The client has retransmitted the SYN ACK packet twice (usually) and
        # now gives up through a RST packet.
        if not to_server and tcp.flags == dpkt.tcp.TH_RST:
            # self.parent.handle(self.s, ts, TCPRetransmission(),
            #                    None, special="synflood")
            return

        # The client has received a SYN ACK but is no longer interested in
        # connecting to this service and thus quits through a RST.
        if to_server and tcp.flags == dpkt.tcp.TH_RST:
            return

        if not to_server:
            log.warning(
                "The server is spamming the client even though an "
                "ACK has not been provided yet (timestamp %f).", ts)
            return

        # It is possible that a client sends out a request straight away along
        # with the ACK packet (the push flag might also be set)
        if tcp.flags & dpkt.tcp.TH_ACK and tcp.data:
            self.state = "conn"
            self.state_conn(ts, tcp, to_server)
            return

        # You know, let's send a FIN packet.
        if to_server and tcp.flags & dpkt.tcp.TH_FIN:
            self.state = "conn_finish"
            return

        if tcp.flags != dpkt.tcp.TH_ACK:
            raise InvalidTcpPacketOrder(tcp)

        if tcp.seq != self.cli:
            raise UnknownTcpSequenceNumber(tcp)

        if tcp.ack != self.srv:
            raise UnknownTcpSequenceNumber(tcp)

        if tcp.data:
            raise UnexpectedTcpData(tcp)

        self.state = "conn"
Example #3
0
    def state_init_syn_ack(self, ts, tcp, to_server):
        # Retransmission of the SYN packet. Indicates that the server is not
        # responding within the given timeframe and thus might be a dead host.
        if to_server and tcp.flags == dpkt.tcp.TH_SYN:
            # self.parent.handle(self.s, ts, TCPRetransmission(),
            #                    None, special="deadhost")
            return

        # The reply from a server when no service is listening on the given
        # port. Generally speaking the client will retry sending SYN packets.
        if tcp.flags & dpkt.tcp.TH_RST:
            # self.parent.handle(self.s, ts, None, None, special="deadhost")
            self.state = "init_syn"
            return

        # Some PCAPs completely miss out on incoming traffic. Not really sure
        # whether trying to parse this really makes sense, but here we go.
        if to_server and tcp.flags == dpkt.tcp.TH_ACK:
            self.cli, self.srv = tcp.seq, tcp.ack
            return self.state_init_ack(ts, tcp, to_server)

        # Not much to comment here really.
        if not to_server and tcp.flags == dpkt.tcp.TH_ACK:
            log.warning(
                "Server replied with an ACK to a SYN packet "
                "(timestamp %f).", ts)
            return

        # A best guess would be; the SYN ACK/ACK packets were not captured.
        if to_server and tcp.flags & dpkt.tcp.TH_ACK and tcp.data:
            log.warning(
                "We didn't receive SYN ACK or ACK packets but are proceeding "
                "straight away to the TCP data (timestamp %f).", ts)
            self.cli, self.srv, self.state = tcp.seq, tcp.ack, "conn"
            return self.state_conn(ts, tcp, to_server)

        if not to_server and tcp.flags == (dpkt.tcp.TH_PUSH | dpkt.tcp.TH_ACK):
            self.state = "init_syn"
            return

        if to_server or tcp.flags != (dpkt.tcp.TH_SYN | dpkt.tcp.TH_ACK):
            raise InvalidTcpPacketOrder(tcp)

        if tcp.data:
            raise UnexpectedTcpData(tcp)

        self.cli = tcp.ack
        self.srv = tcp.seq + 1
        self.state = "init_ack"
Example #4
0
    def state_init_syn(self, ts, tcp, to_server):
        # When no service is listening on the other end a server may send RST
        # packets back after which the state will be reverted to "init_syn".
        # And thus we have to handle any additional RSTs here as well. (Note
        # that we don't really change the state here, so RSTs from the
        # opposite side will also end up here).
        if tcp.flags & dpkt.tcp.TH_RST:
            return

        if not to_server and tcp.flags != dpkt.tcp.TH_SYN:
            raise InvalidTcpPacketOrder(tcp)

        if not to_server and tcp.data:
            raise UnexpectedTcpData(tcp)

        self.ts = ts
        self.cli = tcp.seq
        self.state = "init_syn_ack"