Python Scapy L2socket.recv вызывает бесконечное исключение PcapTimeoutElapsed - PullRequest
0 голосов
/ 04 июня 2019

Я использую Scapy для отправки и получения пакетов TCP.Существует основной поток, который отправляет пакеты, и другой поток, который заботится об отправке ACK и обновлении номера ACK.Это соответствующий код из класса AckThread:

    def run(self):
        while not self.event.is_set():
            recv_pkt = None
            received_response=False

            while not received_response:
                try:
                    recv_pkt = self.l2_socket.recv()
                except pcapdnet.PcapTimeoutElapsed:
                    print "except"
                    continue
                if recv_pkt is not None and recv_pkt.haslayer(TCP) and \
                        (recv_pkt.sport == self.tcp_spoofed_conn.tcp_connection.dst_port and
                         recv_pkt.dport == self.tcp_spoofed_conn.tcp_connection.src_port and
                         recv_pkt[IP].src == self.tcp_spoofed_conn.tcp_connection.dst_ip and
                         recv_pkt[IP].dst == self.tcp_spoofed_conn.tcp_connection.src_ip and
                         recv_pkt[Dot1Q].vlan == self.tcp_spoofed_conn.tcp_connection.vlan and
                         recv_pkt[Ether].src == self.tcp_spoofed_conn.tcp_connection.dst_mac and
                         recv_pkt[Ether].dst == self.tcp_spoofed_conn.tcp_connection.src_mac):
                        received_response=True

            if received_response:
                # send ACK to the response

Вот как определяется self.L2_socket (я использовал L2listen и L2socket, и они оба не работали) -

self.l2_socket=conf.L2listen(iface=self.tcp_spoofed_conn.interface)

Я использую свой код для отправки TCP-пакета.От сервера получен ответ (я вижу его в wireshark), но мой код не отправляет на него ACK.Вместо этого «кроме» печатается снова и снова, потому что код продолжает получать исключение PcapTimeoutElapsed и никогда не достигает кода, отправляющего ACK.

Есть идеи, почему это происходит и как я могу это исправить?

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Проверяли ли вы, что ваш ответ Wireshark на TCP соответствует всем вашим критериям для if?

также

while not received_response:

Похоже, что он полностью избыточен, поскольку вы можете просто получить ответ # send ack в коротком выражении if

Я не уверен насчет целого числа исключений pcapdnet, но тот факт, что он генерирует исключения каждый раз, может указывать на то, что вам не хватает какой-то конфигурации для тайм-аутов?

0 голосов
/ 05 июня 2019

Мне как-то удалось заставить это работать. Несколько слов об этом:

  1. Мне удалось заставить его работать, и ACK для отправки. Не совсем уверен, в чем была проблема, и, возможно, это было больше, чем одна проблема (часть из них в части отправки подтверждения).

    Это мой рабочий код для справки-

        while not self.event.is_set():
            try:
                recv_pkt = self.l2_socket.recv()
            except pcapdnet.PcapTimeoutElapsed:
                print "except"
                continue
            if recv_pkt is not None and recv_pkt.haslayer(TCP) and \
                    (recv_pkt[TCP].sport == self.tcp_spoofed_conn.tcp_connection.dst_port and
                     recv_pkt[TCP].dport == self.tcp_spoofed_conn.tcp_connection.src_port and
                     recv_pkt[IP].src == self.tcp_spoofed_conn.tcp_connection.dst_ip and
                     recv_pkt[IP].dst == self.tcp_spoofed_conn.tcp_connection.src_ip and
                     recv_pkt[Dot1Q].vlan == self.tcp_spoofed_conn.tcp_connection.vlan and
                     recv_pkt[Ether].src == self.tcp_spoofed_conn.tcp_connection.dst_mac.lower() and
                     recv_pkt[Ether].dst == self.tcp_spoofed_conn.tcp_connection.src_mac.lower()):

                # send ack 
  1. Важно - исключение все еще возникает во многих итерациях цикла, но код приема пакета достигается в других итерациях цикла. Значение - пакеты принимаются и получают ACK, и это исключение следует игнорировать
  2. Источник исключения имеет отношение к Winpcap, используемому scapy для чтения пакетов. Это код _L2pcapdnetSocket.recv_raw() из scapy\pcapdnet.py
        while pkt is None:
            pkt = self.ins.next()
            if pkt is not None:
                ts, pkt = pkt
            if pkt is None and scapy.consts.WINDOWS:
                raise PcapTimeoutElapsed  # To understand this behavior, have a look at L2pcapListenSocket's note  # noqa: E501

и это примечание, на которое оно ссылается-

            # Note: Timeout with Winpcap/Npcap
            #   The 4th argument of open_pcap corresponds to timeout. In an ideal world, we would  # noqa: E501
            # set it to 0 ==> blocking pcap_next_ex.
            #   However, the way it is handled is very poor, and result in a jerky packet stream.  # noqa: E501
            # To fix this, we set 100 and the implementation under windows is slightly different, as  # noqa: E501
            # everything is always received as non-blocking
            self.ins = open_pcap(iface, MTU, self.promisc, 100, monitor=monitor)  # noqa: E501

Так что я думаю, что нет реального способа избежать этого исключения, и единственный обходной путь - except it и continue.

...