Network packet dissection and protocol analysis are essential capabilities for network administrators, penetration testers, and defensive cybersecurity engineers. When investigating security incidents, troubleshooting latency spikes, or analyzing unauthorized outbound connections, inspecting raw network traffic at the packet level provides definitive visibility.
Scapy is Python's premier interactive packet manipulation library. Unlike simple socket wrappers, Scapy can forge, decode, capture, and dissect packets across virtually every network protocol in the OSI model. In this hands-on tutorial, you will build a custom network sniffer with Berkeley Packet Filters (BPF), dissect TCP/UDP headers, and log live DNS lookups.
OSI Network Layers and Packet Dissection Overview
Prerequisites & Installation
Packet capture requires administrative / root privileges on your network interface adapter.
# Windows requires Npcap (https://npcap.com/)
pip install scapy
| OSI Layer | Protocol Layer | Scapy Class | Dissected Header Fields |
|---|---|---|---|
| Layer 2 (Data Link) | Ethernet | Ether | Source MAC, Destination MAC, EtherType |
| Layer 3 (Network) | IPv4 / IPv6 | IP / IPv6 | Source IP, Destination IP, TTL, Protocol ID |
| Layer 4 (Transport) | TCP / UDP | TCP / UDP | Source Port, Destination Port, Sequence Numbers, TCP Flags (SYN, ACK, FIN) |
| Layer 7 (Application) | DNS / HTTP | DNS / Raw | DNS Query Name, Transaction ID, Application Payload |
Packet Filtering with Berkeley Packet Filters (BPF)
Capturing every packet on a busy Gigabit network interface can overwhelm system CPU and memory buffers within seconds. Scapy integrates directly with kernel-level Berkeley Packet Filters (BPF).
BPF evaluates filter rules directly inside the operating system kernel, discarding irrelevant packets before they are copied into Python user-space memory.
Building a Custom Network Packet Sniffer with Scapy
from scapy.all import sniff, IP, TCP, UDP, DNS, DNSQR
import time
def process_sniffed_packet(packet):
"""Callback function executed for every captured packet passing the filter."""
if packet.haslayer(IP):
src_ip = packet[IP].src
dst_ip = packet[IP].dst
protocol_num = packet[IP].proto
# 1. Dissect DNS Queries
if packet.haslayer(DNS) and packet.haslayer(DNSQR):
query_name = packet[DNSQR].qname.decode('utf-8', errors='ignore')
print(f"[{time.strftime('%X')}] [DNS Query] {src_ip} -> Resolving: {query_name}")
# 2. Dissect TCP Streams & Flags
elif packet.haslayer(TCP):
tcp_layer = packet[TCP]
flags = tcp_layer.sprintf('%TCP.flags%')
print(f"[{time.strftime('%X')}] [TCP {flags:4s}] {src_ip}:{tcp_layer.sport} -> {dst_ip}:{tcp_layer.dport}")
def start_packet_capture(interface="Ethernet", packet_count=20):
print(f"Initiating Scapy capture on interface '{interface}' (Filter: IP Traffic, Count: {packet_count})...")
# Kernel BPF filter only passes IP packets
sniff(iface=interface, filter="ip", prn=process_sniffed_packet, count=packet_count, store=0)
print("Capture session completed.")
if __name__ == "__main__":
# Note: Requires Administrator (Windows) or Root (Linux) privileges
start_packet_capture(packet_count=10)
Defensive Best Practices and Network Security
- Promiscuous Mode Security: Running a packet sniffer places the network adapter into promiscuous mode, allowing it to inspect all broadcast traffic. Ensure packet capture tools are restricted to authorized administrators.
- Encrypting Application Payloads: Unencrypted protocols (like HTTP, FTP, and Telnet) expose session cookies and credentials in plaintext. Enforce TLS 1.3 across all services to prevent eavesdropping.
- Memory Optimization: Always pass 'store=0' to Scapy's sniff() function when running long-term captures to prevent unbounded RAM growth in Python.
Frequently Asked Questions
Q: Why does Scapy require Administrator / Root privileges?
A: Capturing raw network packets requires direct access to raw OS network sockets (SOCK_RAW), which standard user accounts cannot access for security reasons.
Q: Can Scapy save captured packets to PCAP files?
A: Yes. You can write captured packets to standard Wireshark PCAP files using Scapy's wrpcap('output.pcap', packets) function.
0 Comments