0

I'm sending a simple ARP request using Scapy. I noticed that it will send multiple packets out though, even when I've only given it a single packet:

from scapy.sendrecv import sr1
from scapy.layers.l2 import ARP
from typing import Optional

def request_mac(target_ip: str, **kwargs) -> Optional[str]:
    req = ARP(pdst=target_ip)
    reply = sr1(req, **kwargs)
    return reply and reply[ARP].hwsrc

request_mac("192.168.123.118", timeout=5)

In Wireshark, I can see that it sends out two ARPs instead of one:

Wireshark Capture

Even though the output only shows one being sent:

Begin emission:
Finished sending 1 packets.
................................................................................................................
Received 112 packets, got 0 answers, remaining 1 packets

If I set the retry parameter to sr1, I get two packets sent for every one I explicitly send.

Is this expected behavior? Is there a way to have it only send one? When I made a port scanner, I didn't see duplicate sends of TCP segments, so it seems like it may be specific to ARPs?

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • I've been able to replicate this on Macos/Linux *provided that the ARP packet is sent in your subnet*. The 2nd packet is sent 2 seconds after the first. This is a problem with both `sr` and `sr1`. – Ross Jacobs Sep 15 '20 at 23:01
  • @RossJacobs Yes, it's about a two second delay between them for me as well. And I'm on Windows. – Carcigenicate Sep 15 '20 at 23:07
  • I'd add an issue on github.com/secdev/scapy. If you need something that works, just use `scapy.layers.l2.arping`. – Ross Jacobs Sep 15 '20 at 23:19
  • @RossJacobs Oh, thanks. It isn't a *huge* deal, there just may be circumstances when I want to limit the traffic that I produce. – Carcigenicate Sep 15 '20 at 23:41
  • It turns out it does the same thing with ICMP packets, which messes up using `sr` with packet sets. I get duplicate replies instead of a reply for each request. – Carcigenicate Sep 23 '20 at 22:10
  • Have you filed a bug report? If this isn't buggy behavior, this is at least *unexpected* behavior, per docs. – Ross Jacobs Sep 23 '20 at 22:28
  • @RossJacobs I forgot to earlier. [Submitted now](https://github.com/secdev/scapy/issues/2831). – Carcigenicate Sep 23 '20 at 23:18
  • @RossJacobs I hate to ping you like this is some kind of chatroom, but out of curiosity, I figured out that I can fix the double sending by disabling IP Forwarding. Do you have IP Forwarding enabled on the computer that you were able to reproduce it on? I noticed that the TTL of the duplicate message is one lower than the first. I think my computer is sending it out of two interfaces, then routing the second message back and decrementing the TTL, or something. – Carcigenicate Sep 25 '20 at 00:23
  • I’m running it on a macbook, so nope. I’ve also verified it on an ubuntu vps. – Ross Jacobs Sep 25 '20 at 00:25
  • Hmm, I have no idea. The decremented TTLs suggest that one packet is being routed before it's sent, but I can't tell why. – Carcigenicate Sep 25 '20 at 00:39
  • ...why do you have TTLs on an ARP packet? – Ross Jacobs Sep 25 '20 at 00:55
  • @RossJacobs I'm writing a `traceroute` program now, so I'm using ICMPs, not ARPs. Same behavior though. – Carcigenicate Sep 25 '20 at 00:55
  • Perhaps post that code in your question as an edit? – Ross Jacobs Sep 25 '20 at 00:56
  • I updated the bug report with my new findings. If this is a bug in Scapy, then this should just be closed, or answered once the bug is confirmed. The ping can be reproduced via `sr(IP(dst=destination_ip, ttl=hop_n) / ICMP())` though. – Carcigenicate Sep 25 '20 at 01:01

1 Answers1

0

That's clearly extraneous ARP traffic. Because the X.X.X.118 in your picture != X.X.X.123 in your code.

As an example, when I run your code, I get exactly one request, and then various arp requests on the network

![ARP requests

In my capture, I see ARP requests for 192.168.128.5 every second from the upstream firewall.

Ross Jacobs
  • 2,962
  • 1
  • 17
  • 27
  • Whoops, the `.123` in my question was a remnant from a previous edit. In the code that generated the output, I am using `.118`. Odd though that you can't reproduce it. – Carcigenicate Sep 15 '20 at 22:28