Of course! Using Python with Scapy on Linux is a powerful combination for network analysis, security testing, and development. This guide will walk you through everything you need to know, from installation to practical examples.

Table of Contents
- What is Scapy? (A quick overview)
- Installation on Linux
- Essential Prerequisites
- Your First Scapy Script (The "Hello, World!" of Networking)
- Core Scapy Concepts
- Practical Examples
- Example 1: Network Scanning (ARP Discovery)
- Example 2: Crafting and Sending a Custom Packet (ICMP Echo Request)
- Example 3: Sniffing Packets
- Crucial: Running Scapy with
sudo - Common Pitfalls and Best Practices
- Further Resources
What is Scapy?
Scapy is a Python interactive program that allows you to send, sniff, dissect, and forge network packets. This means you can:
- Create packets from scratch (e.g., a TCP packet with specific flags).
- Send packets and receive responses.
- Sniff live network traffic.
- Dissect packets to understand their contents.
- Forge complex attacks or tools for network testing.
Unlike tools like hping3 or nmap, which are often single-purpose, Scapy is a toolkit. You build your own tools by combining different packet layers.
Installation on Linux
The easiest and most recommended way to install Scapy on a modern Linux distribution (like Ubuntu, Debian, Fedora, or Arch) is using pip.
Update your system's package list:

sudo apt update # For Debian/Ubuntu # or sudo dnf update # For Fedora/CentOS
Install Python and Pip (if not already installed):
sudo apt install python3 python3-pip # For Debian/Ubuntu # or sudo dnf install python3 python3-pip # For Fedora/CentOS
Install Scapy:
pip3 install scapy
This will install Scapy and its core dependencies.
Essential Prerequisites
For Scapy to work fully, especially for sniffing and sending packets at the raw socket level, you need specific Linux capabilities.

sudoaccess: You need root privileges to open raw sockets.libpcapandtcpdump: These are fundamental for packet sniffing. Most likely, they are already installed or can be easily installed.sudo apt install libpcap-dev tcpdump # For Debian/Ubuntu # or sudo dnf install libpcap tcpdump # For Fedora/CentOS
Your First Scapy Script (The "Hello, World!" of Networking)
Let's create a simple script that sends an ICMP Echo Request (the kind of packet ping sends) and waits for a reply.
-
Create a file named
ping_sweep.py:nano ping_sweep.py
-
Add the following code:
from scapy.all import sr, IP, ICMP # The target IP address you want to ping target_ip = "8.8.8.8" # Create the packet # IP() layer sets the destination IP # ICMP() layer creates the ICMP Echo Request packet = IP(dst=target_ip)/ICMP() # Send the packet and wait for a response # sr() sends and receives packets. # It returns two lists: answered packets and unanswered packets. ans, unans = sr(packet, timeout=5, verbose=0) # Process the answered packets for sent_packet, received_packet in ans: # sent_packet is the packet we sent # received_packet is the packet we got back if received_packet.haslayer(ICMP): print(f"Received ICMP reply from {target_ip}") # You can inspect the layers like this: # print(received_packet.summary()) -
Run the script (remember,
sudois required!):sudo python3 ping_sweep.py
If your network connection is working, you should see:
Received ICMP reply from 8.8.8.8
Core Scapy Concepts
-
Packet: In Scapy, a network packet is an object. You build these objects by stacking layers.
# A simple TCP packet tcp_packet = IP(dst="192.168.1.1") / TCP(dport=80, sport=12345)
-
Layers: These are the different parts of a packet (Ethernet, IP, TCP, ICMP, DNS, etc.). You import them from
scapy.all.from scapy.all import Ether, IP, TCP, ICMP
-
Stacking: The operator is used to stack layers. Scapy is smart enough to handle the layering (e.g., it knows an IP packet must go inside an Ethernet frame if you're on a local network).
# An Ethernet frame containing an IP packet containing a TCP packet eth_packet = Ether(dst="aa:bb:cc:dd:ee:ff") / IP(dst="192.168.1.1") / TCP(dport=443)
-
Sending:
send(): Sends packets at layer 2 (Data Link). Doesn't wait for a reply. Good for broadcasts.sr(): Sends and receives packets at layer 3 (Network). Waits for answers. Returns a list of tuples(sent_packet, received_packet).srp(): Sends and receives packets at layer 2 (Data Link). Waits for answers.
-
Sniffing:
sniff(): Captures live packets from the network.- You can use a
prn(print packet) function to process each captured packet. - Use
filterto apply BPF (Berkeley Packet Filter) syntax to only capture specific traffic (e.g., "tcp port 80").
Practical Examples
Example 1: Network Scanning (ARP Discovery)
This script discovers live hosts on your local network by sending ARP requests.
# arp_scan.py
from scapy.all import srp, Ether, ARP, conf
# Get the network interface and its IP
iface = conf.iface
ip = conf.iface.ip
# Scapy's get_if_addr() is more reliable
ip = get_if_addr(iface)
# Calculate the network range
# A simple way: get the first three octets and change the last to .1/24
network = '.'.join(ip.split('.')[:-1]) + '.1/24'
print(f"Scanning network: {network} on interface {iface}")
# Create the ARP packet to ask "who-has" a specific IP
# We'll let Scapy handle the range with the 'iface' parameter
arp_request = ARP(pdst=network)
# Create an Ethernet broadcast frame
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# Stack them
packet = ether / arp_request
# Send and receive at layer 2
# srp() sends and receives packets at layer 2
ans, unans = srp(packet, timeout=2, iface=iface, verbose=0)
print("Available devices in the network:")
print("IP" + " "*18 + "MAC")
print("-----------------------------------")
for sent, received in ans:
# The response packet contains the MAC address
mac = received[1].src
ip = received[1].psrc
print(f"{ip:<20}{mac}")
Run with sudo python3 arp_scan.py.
Example 2: Crafting and Sending a Custom Packet (ICMP Echo Request)
This is a more interactive version of our first example. It sends a single packet and prints a summary of the response.
# custom_ping.py
from scapy.all import sr, IP, ICMP
target_ip = input("Enter the target IP to ping: ")
# Create the packet
packet = IP(dst=target_ip)/ICMP()
print(f"\nSending ICMP Echo Request to {target_ip}...")
# Send and receive, timeout after 5 seconds
ans, unans = sr(packet, timeout=5, verbose=0)
if ans:
for sent_pkt, recv_pkt in ans:
print("\n--- Packet Summary ---")
print("SENT PACKET:")
print(sent_pkt.summary())
print("\nRECEIVED PACKET:")
print(recv_pkt.summary())
else:
print(f"No response received from {target_ip}.")
Run with sudo python3 custom_ping.py.
Example 3: Sniffing Packets
This script sniffs for 10 ICMP packets and prints a summary of each one.
# icmp_sniffer.py
from scapy.all import sniff
# This function is called for each packet
def process_packet(packet):
# We only care about ICMP packets
if packet.haslayer(ICMP):
print("\n--- Captured ICMP Packet ---")
# Print a summary of the packet
print(packet.summary())
print("Starting ICMP packet sniffer for 10 packets...")
print("Press Ctrl+C to stop early.")
# Sniff 10 packets and pass each one to process_packet
sniff(filter="icmp", prn=process_packet, count=10)
print("Sniffing finished.")
Run with sudo python3 icmp_sniffer.py. Now, open another terminal and ping google.com. You'll see the ICMP echo requests and replies captured by your script.
Crucial: Running Scapy with sudo
This cannot be overstated. Scapy requires root privileges to create and send raw packets.
- Why? Normal user applications are not allowed to directly access the network hardware (network cards). This is a security feature of the Linux kernel. Only the
rootuser can open a "raw socket" to build packets from scratch. - How? Always prefix your command with
sudo:sudo python3 your_script.py
- Security Warning: Running scripts as
rootis a security risk. Only run scripts from trusted sources. Be careful what you do with root access.
Common Pitfalls and Best Practices
sudois mandatory: If you getPermission deniedorOperation not permitted, you forgotsudo.- Verbose Mode: Use
verbose=0insr(),send(), etc., to suppress Scapy's default output. Useverbose=1orverbose=2for more details when debugging. - Timeouts: Always set a
timeoutwhen sending packets. Otherwise, your script might hang indefinitely if a host is down or unresponsive. - Firewalls: Your local firewall or a remote host's firewall can block your packets, leading to "unanswered" results. This is normal behavior.
- Use Interactive Mode: For quick testing and learning, use Scapy's interactive console:
sudo scapy
This gives you a Python shell with all Scapy objects pre-loaded. It's fantastic for experimenting.
Further Resources
- Official Scapy Documentation: The best resource. It's comprehensive and has a "Cookbook" with many examples. https://scapy.readthedocs.io/
- Scapy's Packet Reference: A complete list of all packet layers and their fields. https://scapy.readthedocs.io/en/latest/layers.html
- GitHub Repository: For source code and issues. https://github.com/secdev/scapy
- Books: "Black Hat Python" by Justin Seitz is an excellent book that heavily features Scapy for security tasks.
