I'm using Scapy to send and receive TCP packets. There is a main thread that sends the packets, and another thread that takes care of ACK sending and ACK number update.
This is the relevant code from the 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
This is how self.L2_socket
is defined (I used both L2listen
and L2socket
and they both didn't work)-
self.l2_socket=conf.L2listen(iface=self.tcp_spoofed_conn.interface)
I use my code to send a TCP packet. There is a response received from the server (I can see it in wireshark), but my code doesn't send ACK to it. Instead, "except" is being printed over and over again, because the code keeps getting the PcapTimeoutElapsed
exception, and never reaches the code that send ACK .
Any idea why this is happening and how can I fix it?
I somehow managed to make it work. Few words about this:
I managed to make it work, and the ACK to be sent. Not really sure what was the problem, and maybe it was more than one problem (part of them in the ack sending part).
This is my working code for reference-
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
_L2pcapdnetSocket.recv_raw()
from 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
and this is the note it references-
# 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
So I think there is no real way to avoid this exception, and the only workaround is except
it and continue
.