This entry is part 6 of 11 in the series Building Network Tools with Scapy

We’ve sniffed some packets, dig down into packet layers and fields, and even sent some packets. Great job! It’s time to step up our game with Scapy and start really using some of the power Scapy contains. Please Note: this next example is for education and example only. Please be responsible on your network, especially at work!

Scapy Send/Receive Function

Let’s get familiar with the sr(), sr1(), srp(), and srp1() functions. Just like the send(), function, the ‘p’ at the end of the function name means that we’re sending at L2 instead of L3. The functions with a ‘1’ in them mean that Scapy will send the specified packet and end after receiving 1 answer/response instead of continuing to listen for answers/responses. I’ll reference both functions as sr(), but the examples will use the correct function.

Sending an ICMP Echo Request (ping)

The sr() function is used to send a packet or group of packets when you expect a response back. We’ll be sending an ICMP Echo Request (ping) since we can expect some sort of a response back from that. First let’s use the sniff() function to figure out what an ICMP Echo Request looks like in Scapy:

 

In the previous ARP example we changed the dst and src MAC address, but since we’re expecting a response back from another network device we’ll have to leave it up to Scapy to fill those in when it sends the packets. Since we’re building a L3 packet, we can actually leave off the Ether layer since Scapy will handle the generation of that. So let’s start building the IP and ICMP layers. To see the available fields for each layer, and what the default values will be if we don’t specify, use the ls('layer') command:

 

Most of those default values are fine, and src addresses will be filled out automatically by Scapy when it sends the packets. We can spoof those if desired, but again, since we’re expecting a response we need to leave those alone. We’ll be sending a L3 packet and we only expect one response, so we’ll build and send our ICMP packet using the sr1() function:

 

Scapy prints out the response packet

The ‘Received 84 packets’ is referring to the number of non-response packets Scapy sniffed while waiting for the response. It’s not anything to be alarmed about, but just note that on a busy host you might see a big number of packets there. We can also define the ICMP packet directly in the sr1() function like this:

 

We can save the response packet into a variable just like we do when creating a packet:

 

If we’re saving the response, Scapy won’t print it out by default

Two other Scapy functions related to sending and receiving packets are the srloop() and srploop(). The srloop() will send the L3 packet and continue to resend the packet after each response is received. The srploop() does the same thing except for… you guess it, L2 packets! This let’s us simulate the ping command, and with the count argument, we can also define the number of times to loop:

 

Saving the responses puts our packets into an array

As you can see, our Scapy skills are building and you might already have some ideas about how you can use these functions in your own network tools. In the next article, we’ll see how you can build an ARP monitor to keep an ear on the network for possible spoofed ARP replies.

 

Series Navigation<< Scapy p.05 – Sending our First Packet; ARP ResponseScapy p.07 – Monitoring ARP >>

This article has 6 comments

  1. Yixing Jiang

    Hi, I appreciate your work on Scapy. Could you answer this question I posted on StackOverflow? http://stackoverflow.com/questions/20184050/scapy-packet-sent-cannot-be-received

    Basically I sent packets with scapy, but I was not able to receive this packet with another python script.

    Thanks a lot!

    Yixing

    1. matw

      I submitted this answer to your StackOverflow question but I also want to post it here for other readers:

      Looks like you are using Scapy to send the UDP traffic to your localhost interface. In the send() function, specify the appropriate outbound interface to send the traffic out.

      Example:

      send(IP(dst=”127.0.0.1″,src=”111.111.111.111″)/UDP(dport=5005)/”Hello”),iface=”lo0″)

      On my computer, the lo0 is my local loopback interface. To see or set the default interface for Scapy, check out the bottom half of this post for more details on default interface in Scapy.

  2. guling

    hai Mat, maybe you remember me who ask you on your post about monitoring ARP, Im already can get ARP message that just come to my host, and than is it posible that scapy send request like voting? and than the other host reply the answer of the voting, I want to make a program that can verify all of arp message that come. when a host get arp reply (i get the information of arp message from your “monitoring arp” post), the host will send request to another host the right combination of MAC and IP, and the other host will check to its arp cache table

    thanks a lot

    1. Mat

      While it’s certainly possible to send IP and MAC addresses as a payload in a packet with scapy, I’m not exactly sure what you’re asking. I think you would need some sort of service running and listening on multiple machines for this voting request. You would need scapy running on a host to send packets when it receives an ARP request, and also a scapy or Twisted application running on the voting machine in order to receive the packet and check its arp cache table.

Leave a Reply

Your email address will not be published. Required fields are marked *