Exemplo n.º 1
0
    PrintingStatus format_data(ctsConfig::StatusFormatting _format, long long _current_time, bool _clear_status) throw()
    {
        ctsTcpStatistics tcp_data(ctsConfig::Settings->TcpStatusDetails.snap_view(_clear_status));
        ctsConnectionStatistics connection_data(ctsConfig::Settings->ConnectionStatusDetails.snap_view(_clear_status));

        long long time_elapsed = tcp_data.end_time.get() - tcp_data.start_time.get();

        if (_format == ctsConfig::StatusFormatting::Csv) {
            unsigned long characters_written = 0;
            // converting milliseconds to seconds before printing
            characters_written += this->append_csvoutput(characters_written, TimeSliceLength, static_cast<float>(_current_time / 1000.0));

            // calculating # of bytes that were sent between the previous format() and current call to format()
            characters_written += this->append_csvoutput(
                                      characters_written,
                                      SendBytesPerSecondLength,
                                      (time_elapsed > 0LL) ? static_cast<unsigned long>(tcp_data.bytes_sent.get() * 1000LL / time_elapsed) : 0LL);
            // calculating # of bytes that were received between the previous format() and current call to format()
            characters_written += this->append_csvoutput(
                                      characters_written,
                                      RecvBytesPerSecondLength,
                                      (time_elapsed > 0LL) ? static_cast<unsigned long>(tcp_data.bytes_recv.get() * 1000LL / time_elapsed) : 0LL);

            characters_written += this->append_csvoutput(characters_written, CurrentTransactionsLength, connection_data.active_connection_count.get());
            characters_written += this->append_csvoutput(characters_written, CompletedTransactionsLength, connection_data.successful_completion_count.get());
            characters_written += this->append_csvoutput(characters_written, ConnectionErrorsLength, connection_data.connection_error_count.get());
            characters_written += this->append_csvoutput(characters_written, ProtocolErrorsLength, connection_data.protocol_error_count.get(), false); // no comma at the end
            this->terminate_string(characters_written);

        } else {
            // converting milliseconds to seconds before printing
            this->right_justify_output(TimeSliceOffset, TimeSliceLength, static_cast<float>(_current_time / 1000.0));

            // calculating # of bytes that were sent between the previous format() and current call to format()
            this->right_justify_output(
                SendBytesPerSecondOffset,
                SendBytesPerSecondLength,
                (time_elapsed > 0LL) ? static_cast<unsigned long>(tcp_data.bytes_sent.get() * 1000LL / time_elapsed) : 0LL);
            // calculating # of bytes that were received between the previous format() and current call to format()
            this->right_justify_output(
                RecvBytesPerSecondOffset,
                RecvBytesPerSecondLength,
                (time_elapsed > 0LL) ? static_cast<unsigned long>(tcp_data.bytes_recv.get() * 1000LL / time_elapsed) : 0LL);

            this->right_justify_output(CurrentTransactionsOffset, CurrentTransactionsLength, connection_data.active_connection_count.get());
            this->right_justify_output(CompletedTransactionsOffset, CompletedTransactionsLength, connection_data.successful_completion_count.get());
            this->right_justify_output(ConnectionErrorsOffset, ConnectionErrorsLength, connection_data.connection_error_count.get());
            this->right_justify_output(ProtocolErrorsOffset, ProtocolErrorsLength, connection_data.protocol_error_count.get());
            this->terminate_string(ProtocolErrorsOffset);
        }

        return PrintComplete;
    }
Exemplo n.º 2
0
void process_tcp(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	struct {
		unsigned src_port;
		unsigned dst_port;
		unsigned seqno;
		unsigned ackno;
		unsigned header_length;
		unsigned flags;
		unsigned window;
		unsigned checksum;
		unsigned urgent;
	} tcp;

	ferret->statistics.tcp++;

	if (length == 0) {
		FRAMERR(frame, "tcp: frame empty\n");
		return;
	}
	if (length < 20) {
		FRAMERR(frame, "tcp: frame too short\n");
		return;
	}

/*
	    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/

	tcp.src_port = ex16be(px+0);
	tcp.dst_port = ex16be(px+2);
	tcp.seqno = ex32be(px+4);
	tcp.ackno = ex32be(px+8);
	tcp.header_length = px[12]>>2;
	tcp.flags = px[13];
	tcp.window = ex16be(px+14);
	tcp.checksum = ex16be(px+16);
	tcp.urgent = ex16be(px+18);

	frame->src_port = tcp.src_port;
	frame->dst_port = tcp.dst_port;

	if (tcp.header_length < 20) {
		/* Regress: defcon2008\dump027.pcap(39901) */
		//FRAMERR(frame, "tcp: header too short, expected length=20, found length=%d\n", tcp.header_length);
		return;
	}
	if (tcp.header_length > length) {
		//FRAMERR(frame, "tcp: header too short, expected length=%d, found length=%d\n", tcp.header_length, length);
		return;
	}
	if ((tcp.flags & 0x20) && tcp.urgent > 0) {
		FRAMERR(frame, "tcp: found %d bytes of urgent data\n", tcp.urgent);
		return;
	}

	/* Check the checksum */
	if (!validate_tcp_checksum(px, length, frame->src_ipv4, frame->dst_ipv4)) {
		/* Regress: defcon2008-msnmsgr.pcap(24066) */
		ferret->statistics.errs_tcp_checksum++;		
		return;
	}

	/*TODO: need to check checksum */

	if (tcp.header_length > 20) {
		unsigned o = 20;
		unsigned max = tcp.header_length;

		while (o < tcp.header_length) {
			unsigned tag = px[o++];
			unsigned len;

			if (tag == 0)
				break;
			if (tag == 1)
				continue;

			if (o >= max) {
				FRAMERR(frame, "tcp: options too long\n");
				break;
			}
			len = px[o++];

			if (len < 2) {
				FRAMERR(frame, "tcp: invalid length field\n");
				break;
			}
			if (o+len-2 > max) {
				FRAMERR(frame, "tcp: options too long\n");
				break;
			}

			switch (tag) {
			case 0x02: /* max seg size */
				if (len != 4)
					FRAMERR(frame, "tcp: unknown length: option=%d, length=%d\n", tag, len);
				break;
			case 0x04: /* SACK permitted */
				if (len != 2)
					FRAMERR(frame, "tcp: unknown length: option=%d, length=%d\n", tag, len);
				break;
			case 0x05: /* SACK */
				break;
			case 0x08: /*timestamp*/
				break;
			case 0x03: /*window scale*/
				break;
			default:
				FRAMERR(frame, "tcp: unknown option=%d, length=%d\n", tag, len);
			}

			o += len-2;
		}
	}


	SAMPLE(ferret,"TCP", JOT_NUM("flags", tcp.flags));

	/* Process an "acknowledgement". Among other things, this will identify
	 * when packets have been missed: if the other side claims to have
	 * received a packet, but we never saw it, then we know that it was
	 * dropped somewhere on the network (probably because we are getting
	 * a weak signal via wireless). */
	if (tcp.flags & TCP_ACK) {
		tcp_ack_data(ferret, frame, tcp.ackno);
	}

	switch (tcp.flags & 0x3F) {
	case TCP_SYN:
		tcp_syn(ferret, frame);
		break;
	case TCP_SYN|TCP_ACK:
		tcp_synack(ferret, frame);
		break;
	case TCP_FIN:
	case TCP_FIN|TCP_ACK:
	case TCP_FIN|TCP_ACK|TCP_PSH:
		tcp_fin(ferret, frame);
		break;
	case TCP_ACK:
	case TCP_ACK|TCP_PSH:
		if (length > tcp.header_length)
			tcp_data(ferret, frame, px+tcp.header_length, length-tcp.header_length, tcp.seqno, tcp.ackno);
		break;
	case TCP_RST:
	case TCP_RST|TCP_ACK:
		break;
	case 0x40|TCP_ACK:
		break;
	case TCP_RST|TCP_ACK|TCP_FIN:
	case TCP_RST|TCP_ACK|TCP_PSH:
		break;
	default:
		FRAMERR(frame, "tcp: unexpected combo of flags: 0x%03x\n", tcp.flags);
	}
}