Python Scapy L2socket.recv 导致无限 PcapTimeoutElapsed 异常

Python Scapy L2socket.recv cause infinite PcapTimeoutElapsed exception

我正在使用 Scapy 发送和接收 TCP 数据包。有一个发送数据包的主线程,另一个线程负责发送 ACK 和更新 ACK 号。 这是来自 AckThread class:

的相关代码
    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的定义方式(我同时使用了L2listenL2socket,但它们都不起作用)-

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

我使用我的代码发送 TCP 数据包。从服务器收到了一个响应(我可以在 wireshark 中看到它),但我的代码没有向它发送 ACK。相反, "except" 被一遍又一遍地打印,因为代码不断收到 PcapTimeoutElapsed 异常,并且永远不会到达发送 ACK 的代码。

知道为什么会这样吗?我该如何解决?

您是否检查过您的 wireshark 对 TCP 的响应是否满足您的 if 的所有条件?

还有

while not received_response:

似乎完全多余,因为您可以在粗壮的 if 语句中使用 # send ack 响应

我不确定 pcapdnet 异常的内部情况,但它每次都抛出异常的事实表明您是否缺少一些超时配置?

我设法让它工作了。关于这个的几句话:

  1. 我设法使它工作,并发送了 ACK。不太确定是什么问题,也许不止一个问题(其中一部分在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. 重要-多次循环仍然抛出异常,但在其他循环迭代中到达了收包代码。含义- 数据包已收到并被确认,应忽略此异常
  2. 异常的来源与scapy使用Winpcap读取数据包有关。这是 _L2pcapdnetSocket.recv_raw() 来自 scapy\pcapdnet.py
  3. 的代码
        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 它和 continue.