Peleus
Peleus

Reputation: 355

What defines Scapy send / receive?

I'm doing some Wi-Fi scripting with Scapy and I wish to do a WPS request. As part of this I need to conduct a series of packets such as EAPOL (Start) followed by receiving an EAP (Request, Identity) packet from the router.

If I do a SRP(EAPOL) with an appropriate packet Scapy will timeout waiting for a response because it seems the identity request isn't an appropriate 'response' to the packet for whatever definition Scapy uses.

Alternatively I tried to start sniff() directly after sending the packet, however it doesn't seem to start in time for picking up the packet.

An independent sniffing thread (started in a separate console window) does see the AP response as below.

RadioTap / Dot11 / LLC / SNAP / EAPOL EAP_PACKET / EAP / Padding

So my questions are

Cheers.

Upvotes: 2

Views: 1113

Answers (1)

juhist
juhist

Reputation: 4314

The send/receive pair is defined by the answers method implemented by a layer.

For example, here is the answers method for the IP layer:

def answers(self, other):
    if not isinstance(other,IP):
        return 0
    if conf.checkIPaddr and (self.dst != other.src):
        return 0
    if ( (self.proto == socket.IPPROTO_ICMP) and
         (isinstance(self.payload, ICMP)) and
         (self.payload.type in [3,4,5,11,12]) ):
        # ICMP error message
        return self.payload.payload.answers(other)

    else:
        if ( (conf.checkIPaddr and (self.src != other.dst)) or
             (self.proto != other.proto) ):
            return 0
        return self.payload.answers(other.payload)

What you want to do is to develop your own answers(request, potential_response) function and receive raw packets. Then, you use YOUR answers function to decide which of the raw packets is the answer.

To receive raw packets, you can use the sniff function:

sniff(count=1,timeout=0.001)

although as you found out, it has the drawback that it does not necessarily start in time. So, you want to take a look at the way sniff is implemented. Internally, it uses conf.L2listen which you can also use.

So, before sending the request, do s=conf.L2listen() and after it, do s.recv(65536) to receive a packet. You can use sel = select([s],[],[],0.001) to wait for a certain amount of time for packets to arrive. If s in sel[0], then data can be read from the socket, otherwise timeout passed.

The timeout parameter is in seconds, so all of my examples specified a timeout of 1 millisecond.

Upvotes: 2

Related Questions