ARP Scanning

Scanning a local network segment with ARP requests instead of ICMP echo (ping) is a stealthier host-discovery technique. ARP traffic is layer 2, rarely logged by host-based firewalls, and often invisible to network monitoring tools that focus on layer 3+. Every host on the segment must respond to ARP requests (it’s how Ethernet works), making ARP scanning highly reliable for discovering live hosts — including those that block ICMP. 1

Scapy ARP scanner

A minimal ARP scanner using Scapy:

#!/usr/bin/env python3
 
from scapy.all import *
 
interface = "eth0"
ip_range = "10.10.0.0/24"
broadcastMac = "ff:ff:ff:ff:ff:ff"
 
packet = Ether(dst=broadcastMac) / ARP(pdst=ip_range)
 
ans, unans = srp(packet, timeout=2, iface=interface, inter=0.1)
 
for send, receive in ans:
    print(receive.sprintf(r"%Ether.src% - %ARP.psrc%"))
  • srp() sends at layer 2 (Ethernet) — required for ARP, unlike sr() which works at layer 3
  • inter=0.1 throttles transmission to 10 packets/second, reducing network noise
  • The r prefix in sprintf(r"...") creates a raw string (Python 3.6+), preventing escape-sequence interpretation of % format specifiers 2

Why ARP over ICMP

ICMP (ping)ARP
Layer3 (IP)2 (Ethernet)
Firewall blockingFrequently blockedCannot be blocked (required for Ethernet)
IDS/IPS monitoringCommonly monitoredRarely monitored
ScopeAny routable hostLocal segment only
Response requiredHost may ignoreHost must respond

The tradeoff is range: ARP scanning only works on the local broadcast domain. For remote networks, use powershell-port-scanning, netcat-based techniques, or nmap with -Pn (treating all hosts as up) instead.

Sources

Related: arp, mac-address, python, ipconfig, linux-reconnaissance-commands, raspberry-pi-network-tap

Footnotes

  1. Scapy Documentation — Usage

  2. Scapy Documentation — Usage