0

I'm writing a TCP SYN port scanner. I spin up 15 tasks that each send 64K / 15 packets to 64K ports, and I have a receiver that sits in a loop and prints the responses. However, some of the packets don't make their way back, making the receiver wait in the loop forever.

I'm looking for a way to reliably detect that no more packets are coming so that I can retry getting the missing ones.

async def recv_from(sock, target):
    while True:
        data, addr = await sock.recvfrom(1024)
        if addr[0] == target:
            yield data

async def receiver() -> None:
    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
    ports = list(range(PORTS))
    async for packet in recv_from(sock, '192.168.1.1'):
        if not ports:
            break
        src, dest, flags = unpack(packet)
        if dest == 6969:
            ports.remove(src)
            if flags == 20:
                print("port %d: closed" % src)
            elif flags == 18:
                print("port %d: open" % src)
    sock.close()
    

async def sender(idx: int) -> None:
    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    
    for port in range(idx * int(PORTS / TASKS), (idx + 1) * int(PORTS / TASKS)):
        tcp_packet = build_tcp_packet(port)
        ipv4_packet = build_ipv4_packet()
        await sock.sendto(ipv4_packet + tcp_packet, ('192.168.1.1', port))

    sock.close()


async def main() -> None:
    async with trio.open_nursery() as nursery:
        nursery.start_soon(receiver)
        for i in range(TASKS):
            nursery.start_soon(sender, i)
            await trio.sleep(0.5)

if __name__ == '__main__':
    trio.run(main)
adder
  • 3,512
  • 1
  • 16
  • 28

1 Answers1

0

There is no way to know whether or not a packet is coming other than to wait and assume that it's not coming if you haven't received it. If you didn't get a packet, then you didn't get a packet -- what more can possibly be said? Since you didn't get a packet, you have no additional information since there was no place for such information to be.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278