Beispiel #1
0
    def test_to_bytes(self):
        tcp_packet1 = TcpPacket(
            source_port=59700,
            dest_port=443,
            sequence_number=1407506493,
            ack_number=3676709599,
            flags=TcpControlBits(ack=True),
            win_size=501,
            urg_pointer=0,
            options=TcpOptions([
                TcpOptions.NOP, TcpOptions.NOP,
                (TcpOptions.TIMESTAMPS, [3252488245, 365238493])
            ]),
        )
        tcp_packet1 = IpPacket(source_addr_str="192.168.1.32",
                               dest_addr_str="35.160.240.60") / tcp_packet1
        self.__test_tcp_packet(PACKET_DUMP_1, tcp_packet1)

        tcp_packet2 = TcpPacket(source_port=44134,
                                dest_port=443,
                                sequence_number=2302261952,
                                ack_number=1291093731,
                                flags=TcpControlBits(ack=True),
                                win_size=496)
        tcp_packet2 = IpPacket(source_addr_str="10.10.128.44",
                               dest_addr_str="40.101.18.242") / tcp_packet2
        self.__test_tcp_packet(PACKET_DUMP_2, tcp_packet2)

        tcp_packet3 = TcpPacket(
            source_port=43480,
            dest_port=2193,
            sequence_number=703011338,
            ack_number=2915529351,
            flags=TcpControlBits(ack=True, psh=True),
            win_size=22461,
            options=TcpOptions([
                TcpOptions.NOP, TcpOptions.NOP,
                (TcpOptions.TIMESTAMPS, [1314978149, 3029537658])
            ]),
        ) / bytearray.fromhex(PACKET_DUMP_3_PAYLOAD)
        tcp_packet3 = IpPacket(source_addr_str="10.10.128.44",
                               dest_addr_str="10.10.144.153") / tcp_packet3
        self.__test_tcp_packet(PACKET_DUMP_3, tcp_packet3)

        tcp_packet4 = TcpPacket(
            source_port=59058,
            dest_port=443,
            sequence_number=746641599,
            ack_number=1952224292,
            flags=TcpControlBits(ack=True, psh=True),
            win_size=2483,
            options=TcpOptions([
                TcpOptions.NOP, TcpOptions.NOP,
                (TcpOptions.TIMESTAMPS, [4044761679, 555562620])
            ]),
        ) / bytearray.fromhex(PACKET_DUMP_4_PAYLOAD)
        tcp_packet4 = IpPacket(source_addr_str="192.168.1.32",
                               dest_addr_str="93.186.225.198") / tcp_packet4
        self.__test_tcp_packet(PACKET_DUMP_4, tcp_packet4)
    def test_from_int(self):
        flags_syn = TcpControlBits.from_int(self.FLAGS_SYN)
        self.assertEqual(self.FLAGS_SYN, flags_syn.flags)

        flags_psh_ack = TcpControlBits.from_int(self.FLAGS_PSH_ACK)
        self.assertEqual(self.FLAGS_PSH_ACK, flags_psh_ack.flags)

        flags_all = TcpControlBits.from_int(self.FLAGS_ALL)
        self.assertEqual(self.FLAGS_ALL, flags_all.flags)
    def test_flags_some_set(self):
        tcp_control_flags = TcpControlBits(ack=True, psh=True)
        self.assertEqual(self.FLAGS_PSH_ACK, tcp_control_flags.flags)

        self.assertTrue(tcp_control_flags.is_flag_set(TcpControlBits.ACK))
        self.assertTrue(tcp_control_flags.is_flag_set(TcpControlBits.PSH))
        self.assertFalse(tcp_control_flags.ns or tcp_control_flags.cwr
                         or tcp_control_flags.urg or tcp_control_flags.ece
                         or tcp_control_flags.rst or tcp_control_flags.syn
                         or tcp_control_flags.fin)
        self.assertTrue(tcp_control_flags.ack and tcp_control_flags.psh)
Beispiel #4
0
    def __init__(self,
                 source_port: int,
                 dest_port: int,
                 sequence_number: int = 0,
                 ack_number: int = 0,
                 flags: TcpControlBits = TcpControlBits(),
                 win_size: int = 65535,
                 urg_pointer: int = 0,
                 options: TcpOptions = TcpOptions()):
        """
        Initializes TCP packet instance

        :param source_port: Source port field value,
            integer in range [0; 65535]
        :param dest_port: Destination port field value,
            integer in range [0; 65535]
        :param sequence_number: Sequence number field value. Has a dual role:
            If the SYN flag is set (1), then this is the initial
                sequence number. The sequence number of the actual first data
                byte and the acknowledged number in the corresponding ACK are
                then this sequence number plus 1.
            If the SYN flag is clear (0), then this is the accumulated sequence
                number of the first data byte of this segment for the current
                session.
        :param ack_number: Acknowledgment number field value. If the ACK flag
            is set then the value of this field is the next sequence number
            that the sender of the ACK is expecting.This acknowledges receipt
            of all prior bytes (if any). The first ACK sent by each end
            acknowledges the other end's initial sequence number itself,
            but no data.
        :param flags: Flags field. Instance of TcpControlBits class. Contains
            9 1-bit flags (control bits)
        :param win_size: Window size field value. The size of the receive
            window, which specifies the number of window size units that the
            sender of this segment is currently willing to receive.
        :param urg_pointer: Urgent pointer field value. If the URG flag is set,
            then this 16-bit field is an offset from the sequence number
            indicating the last urgent data byte.
        :param options: Options field. Instance of TcpOptions class.
        """
        super().__init__()
        self.__source_port = TransportLayerUtils.validate_port_num(source_port)
        self.__dest_port = TransportLayerUtils.validate_port_num(dest_port)
        self.__sequence_number = sequence_number
        self.__ack_number = ack_number
        self.__flags = flags
        self.__win_size = win_size
        self.__urg_pointer = urg_pointer
        self.__options = options
 def test_flags_all_set(self):
     tcp_control_flags = TcpControlBits(ns=True,
                                        cwr=True,
                                        urg=True,
                                        ece=True,
                                        ack=True,
                                        psh=True,
                                        rst=True,
                                        syn=True,
                                        fin=True)
     self.assertTrue(tcp_control_flags.ns and tcp_control_flags.cwr
                     and tcp_control_flags.urg and tcp_control_flags.ece
                     and tcp_control_flags.ack and tcp_control_flags.psh
                     and tcp_control_flags.rst and tcp_control_flags.syn
                     and tcp_control_flags.fin)
     self.assertEqual(self.FLAGS_ALL, tcp_control_flags.flags)
Beispiel #6
0
    def from_bytes(packet_bytes: bytes):
        header_bytes = packet_bytes[:TcpUtils.TCP_HEADER_LENGTH_BYTES]
        payload_and_options = packet_bytes[TcpUtils.TCP_HEADER_LENGTH_BYTES:]
        header_fields = struct.unpack(TcpPacket.TCP_HEADER_FORMAT,
                                      header_bytes)

        source_port = header_fields[0]
        dest_port = header_fields[1]
        seq_num = header_fields[2]
        ack_num = header_fields[3]
        data_offset_flags = header_fields[4]
        win_size = header_fields[5]
        # 6-th item is checksum, don't need to extract it,
        # since it will be calculated later
        urg_pointer = header_fields[7]

        # take first 4 bits
        data_offset = data_offset_flags >> 12
        # take 5-th, 6-th, 7-th bits
        reserved_bits = (data_offset_flags >> 9) & 7
        if reserved_bits != 0:
            raise ValueError("Reserved bits should be set to zero")
        # take last 9 bits
        flags = TcpControlBits.from_int(data_offset_flags & 511)

        # compute options field length in bytes
        options_len = (data_offset - TcpUtils.TCP_HEADER_LENGTH) * 4
        options = TcpOptions.from_bytes(payload_and_options[:options_len])

        tcp_header = TcpPacket(
            dest_port=dest_port,
            source_port=source_port,
            sequence_number=seq_num,
            ack_number=ack_num,
            flags=flags,
            win_size=win_size,
            urg_pointer=urg_pointer,
            options=options,
        )
        payload = payload_and_options[options_len:]
        return tcp_header / payload if len(payload) else tcp_header
Beispiel #7
0
    def test_tcp_ip_payload(self):
        ethernet_header_hex = TCP_IP_PAYLOAD_TEST_CONTEXT["ETHERNET_HEADER"]
        ip_payload_hex = TCP_IP_PAYLOAD_TEST_CONTEXT["IP_PAYLOAD"]
        tcp_payload_hex = TCP_IP_PAYLOAD_TEST_CONTEXT["TCP_PAYLOAD"]
        packet_hex = ethernet_header_hex + ip_payload_hex + tcp_payload_hex

        ethernet_packet = EthernetPacket(dest_mac="e0:d5:5e:21:b0:cb",
                                         source_mac="00:7e:95:02:61:42")
        self.assertEqual(ethernet_header_hex, ethernet_packet.to_bytes().hex())

        ip_packet = IpPacket(source_addr_str="3.123.217.208",
                             dest_addr_str="10.10.128.44",
                             identification=11150,
                             flags=IpFragmentationFlags(df=True),
                             ttl=47,
                             protocol=socket.IPPROTO_TCP)
        tcp_packet = TcpPacket(
            source_port=443,
            dest_port=55978,
            sequence_number=2555500760,
            ack_number=1254966751,
            flags=TcpControlBits(ack=True),
            win_size=10,
            options=TcpOptions([
                TcpOptions.NOP, TcpOptions.NOP,
                (TcpOptions.TIMESTAMPS, [654701382, 3921945890])
            ]),
        )

        packet = ethernet_packet / ip_packet / tcp_packet
        self.assertEqual(packet_hex, packet.to_bytes().hex())
        self.assertEqual(packet,
                         EthernetPacket.from_bytes(bytes.fromhex(packet_hex)))
        self.assertTrue(EthernetPacket in packet)
        self.assertTrue(IpPacket in packet)
        self.assertTrue(TcpPacket in packet)
Beispiel #8
0
    def test_is_response(self):
        # 'syn' sent, wait for 'syn/ack'
        tcp_packet = TcpPacket(source_port=44134,
                               dest_port=443,
                               sequence_number=2302261952,
                               flags=TcpControlBits(syn=True))
        tcp_response = TcpPacket(source_port=443,
                                 dest_port=44134,
                                 ack_number=2302261952 + 1,
                                 flags=TcpControlBits(syn=True, ack=True))
        self.assertTrue(tcp_response.is_response(tcp_packet))

        # 'syn/ack' sent, wait for 'ack'
        tcp_packet2 = TcpPacket(source_port=44134,
                                dest_port=443,
                                sequence_number=2302261952,
                                flags=TcpControlBits(syn=True, ack=True))
        tcp_response2 = TcpPacket(source_port=443,
                                  dest_port=44134,
                                  ack_number=2302261952 + 1,
                                  flags=TcpControlBits(ack=True))
        self.assertTrue(tcp_response2.is_response(tcp_packet2))

        # 'syn' sent, wait for 'rst' received
        tcp_packet3 = TcpPacket(source_port=44134,
                                dest_port=443,
                                flags=TcpControlBits(syn=True))
        tcp_response3 = TcpPacket(source_port=443,
                                  dest_port=44134,
                                  flags=TcpControlBits(rst=True))
        self.assertTrue(tcp_response3.is_response(tcp_packet3))

        # ports mismatch
        tcp_packet4 = TcpPacket(source_port=44134, dest_port=443)
        tcp_response4 = TcpPacket(source_port=443, dest_port=44135)
        self.assertFalse(tcp_response4.is_response(tcp_packet4))

        # 'syn' sent, but no 'syn/ack' received
        tcp_packet5 = TcpPacket(source_port=44134,
                                dest_port=443,
                                sequence_number=2302261952,
                                flags=TcpControlBits(syn=True))
        tcp_response5 = TcpPacket(
            source_port=443,
            dest_port=44134,
            ack_number=2302261953,
        )
        self.assertFalse(tcp_response5.is_response(tcp_packet5))

        # 'syn' sent, 'syn/ack' received, but seq/ack numbers mismatch
        tcp_packet6 = TcpPacket(source_port=44134,
                                dest_port=443,
                                sequence_number=2302261952,
                                flags=TcpControlBits(syn=True))
        tcp_response6 = TcpPacket(source_port=443,
                                  dest_port=44134,
                                  flags=TcpControlBits(syn=True, ack=True))
        self.assertFalse(tcp_response6.is_response(tcp_packet6))

        # 'rst' sent, no response expected
        tcp_packet7 = TcpPacket(source_port=44134,
                                dest_port=443,
                                flags=TcpControlBits(rst=True))
        tcp_response7 = TcpPacket(
            source_port=443,
            dest_port=44134,
        )
        self.assertFalse(tcp_response7.is_response(tcp_packet7))

        # 20 bytes of data sent, 'ack' expected
        tcp_packet8 = TcpPacket(
            source_port=44134,
            dest_port=443,
            flags=TcpControlBits(ack=True),
            sequence_number=2302261952,
        ) / bytes(20)
        tcp_response8 = TcpPacket(source_port=443,
                                  dest_port=44134,
                                  flags=TcpControlBits(ack=True),
                                  ack_number=2302261952 + 20)
        self.assertTrue(tcp_response8.is_response(tcp_packet8))
 def test_flags_none_set(self):
     tcp_control_flags = TcpControlBits()
     self.assertEqual(0, tcp_control_flags.flags)
 def test_flags_one_set(self):
     tcp_control_flags = TcpControlBits(syn=True)
     self.assertEqual(self.FLAGS_SYN, tcp_control_flags.flags)
     self.assertTrue(tcp_control_flags.is_flag_set(TcpControlBits.SYN))
     self.assertTrue(tcp_control_flags.syn)