An educational, defensive packet-capture and analysis tool built with Python and Scapy for the CodeAlpha Cyber Security Internship.
- Author and owner: Mahmoud Abdullah
- Email: mahmoudabdulsm@gmail.com
- Task: Basic Network Sniffer
- Primary platform: Linux (developed for Arch Linux)
Basic Network Sniffer captures packets from a selected local interface and turns Scapy packets into a beginner-friendly summary. It can show timestamps, MAC and IP addresses, IP versions, protocols, ports, packet lengths, and a short description. Payload previews are off by default and, when explicitly enabled, are length-limited and escaped for safe terminal display.
This project is for learning how packet headers describe network traffic. It does not decrypt traffic, modify packets, or perform active attacks.
| CodeAlpha requirement | Project implementation |
|---|---|
| Capture packets with Python | sniffer/capture.py coordinates Scapy capture. |
| Analyze packet structure and content | sniffer/parser.py converts supported layers into a structured packet record. |
| Explain how data flows through a network | This README and docs/PROJECT_REPORT.md explain encapsulation and packet flow. |
| Display useful packet information | The formatter presents time, protocol, endpoints, length, summary, and optional safe payload. |
| Support common protocols | Ethernet, ARP, IPv4, IPv6, TCP, UDP, ICMP, reasonable ICMPv6 handling, and safe unknown-protocol fallback are covered. |
| Provide an internship demonstration | The CLI, synthetic tests, report, and docs/VIDEO_SCRIPT.md form a reproducible beginner demo. |
- Scapy-based capture on a user-selected interface
- Interface listing without assuming names such as
eth0orwlan0 - Capture limits by packet count and timeout
- Filters for
all,tcp,udp,icmp,arp,ipv4, andipv6 - Ethernet, ARP, IPv4, IPv6, TCP, UDP, ICMP, and ICMPv6-aware parsing
- Graceful handling of loopback, missing layers, and unknown protocols
- Plain-text mode with
--no-color - Optional, truncated, terminal-safe payload previews
- Optional PCAP export with protection against overwriting an existing file
- Streaming PCAP writes without retaining an unbounded packet list in memory
- Non-promiscuous capture by default to limit collection to locally visible traffic
- Capture summary with protocol counts and elapsed time
- Automated tests built from synthetic packets, never live traffic
Use this tool only on your own device, the loopback interface, a network you own, or a network you have explicit permission to test. Packet captures can contain private information. Obtain authorization, minimize collection, keep captures only as long as necessary, and protect any exported PCAP files.
This project is passive and defensive. It provides no injection, spoofing, traffic modification, decryption, interception, persistence, stealth, exploitation, wireless-attack, remote-collection, or exfiltration features. It never searches payloads for secrets or personal data. Never use it to monitor another person or network without explicit authorization.
CodeAlpha_BasicNetworkSniffer/
├── sniffer/
│ ├── __init__.py
│ ├── capture.py
│ ├── parser.py
│ ├── formatter.py
│ ├── interfaces.py
│ └── models.py
├── tests/
│ ├── test_parser.py
│ ├── test_formatter.py
│ ├── test_interfaces.py
│ └── test_cli.py
├── docs/
│ ├── PROJECT_REPORT.md
│ └── VIDEO_SCRIPT.md
├── main.py
├── requirements.txt
├── requirements-dev.txt
├── pytest.ini
├── .gitignore
├── LICENSE
└── README.md
- Python 3.10 or newer
- Scapy 2.5 or newer
- A packet-capture provider supported by the operating system
- Elevated privileges or carefully scoped capture capabilities when required
pytestandpytest-covonly for development and testing
The runtime dependency list is intentionally minimal: Scapy is the only Python package required to run the sniffer.
Clone or download the repository, enter it, and create an isolated virtual environment:
cd CodeAlpha_BasicNetworkSniffer
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt -r requirements-dev.txtThe virtual environment keeps project packages separate from system Python. It is excluded from Git.
Linux is the primary platform. Scapy may need libpcap for some capture modes
or filters. Install the package supplied by your distribution, then list the
interfaces that Scapy can see:
python main.py --list-interfacesRaw packet capture often requires elevated privileges. Prefer granting only
the capability needed by a controlled Python executable or using sudo for a
short, explicit capture command. Do not permanently run the whole project as
root. The correct choice depends on your operating system and security policy;
sudo is not universally required.
On Arch Linux, install the capture library if it is missing:
sudo pacman -S libpcapUse the Python virtual environment shown above rather than installing project packages into the system Python environment.
Windows packet capture normally requires Npcap and may require an Administrator terminal. Install Npcap from its official source and enable its Scapy-compatible mode if the installer offers that option. Adapter names and loopback behavior differ from Linux, and not every link-layer field is available on every adapter. The project is primarily tested and documented for Linux.
macOS may require elevated capture permission. Interface names and loopback headers differ from Linux, and Berkeley Packet Filter access may be restricted by local security settings. Some MAC or protocol details may therefore be unavailable. The project does not attempt to bypass those controls.
Display all options:
python main.py --helpList interfaces before choosing one:
python main.py --list-interfacesStart a continuous capture using Scapy's selected/default interface:
sudo python main.pyCapture on a specific authorized interface:
sudo python main.py --interface eth0Replace eth0 with a name printed by --list-interfaces. Do not assume that
every system uses eth0 or wlan0.
Stop after 20 packets:
sudo python main.py --count 20--count accepts a positive integer.
Stop after 30 seconds:
sudo python main.py --timeout 30--timeout accepts a positive number of seconds. Count and timeout can be
used together; capture stops when the applicable limit is reached.
The default filter is all. Supported values are all, tcp, udp,
icmp, arp, ipv4, and ipv6:
sudo python main.py --protocol tcp
sudo python main.py --protocol udp
sudo python main.py --protocol icmp
sudo python main.py --protocol arp
sudo python main.py --protocol ipv4
sudo python main.py --protocol ipv6Payload display is disabled by default. Enable it only for authorized, non-sensitive traffic:
sudo python main.py --show-payloadThe default preview limit is 64 bytes. Configure the preview limit with:
sudo python main.py --payload-bytes 64--payload-bytes controls the limit used when --show-payload is also
enabled. A complete explicit example is:
sudo python main.py --show-payload --payload-bytes 64The preview contains only application payload bytes where possible. It is
truncated, escaped, and treated only as text; bytes are never executed or
interpreted as terminal commands. An empty application payload is reported as
No payload. Encrypted HTTPS contents normally remain encrypted and are not
made readable by this tool.
Save only packets from the current authorized session:
sudo python main.py --save-pcap captures/demo.pcapFor a bounded demonstration, combine export with a count:
sudo python main.py --count 20 --save-pcap captures/demo.pcapThe destination must end in lowercase .pcap. The program creates a safe parent
directory when appropriate and refuses to silently overwrite an existing
file. Packets are streamed to a private file instead of accumulated in memory.
Choose a new filename if the destination already exists. PCAP and PCAPNG files,
including uppercase variants and the captures/ directory, are ignored by Git
by default.
Disable colored output for logs, CI, or a basic terminal:
sudo python main.py --count 5 --no-colorPrint the installed project version:
python main.py --versionThe following is illustrative; addresses and interface names vary by system:
Capture configuration
Interface: lo
Filter: icmp
Packet count: 2
Timeout: 10 seconds
Payload preview: disabled
PCAP destination: not saving
Ethical-use reminder: Capture only on this device or a network you are authorized to inspect.
TIME | PROTOCOL | SOURCE | DESTINATION | LENGTH | INFO
12:42:08.120 | ICMP | 127.0.0.1 | 127.0.0.1 | 84 | ICMP 127.0.0.1 -> 127.0.0.1 type=8 code=0; IPv4
12:42:08.120 | ICMP | 127.0.0.1 | 127.0.0.1 | 84 | ICMP 127.0.0.1 -> 127.0.0.1 type=0 code=0; IPv4
Capture complete
Packets captured: 2
Protocol counts: ICMP: 2
Duration: 0.01 seconds
Use two terminals and only the loopback interface reported by your own computer. In terminal 1:
sudo python main.py --interface lo --protocol icmp --count 2 --timeout 10 --no-colorIn terminal 2:
ping -c 1 127.0.0.1On systems where the loopback name is not lo, substitute the exact name from
python main.py --list-interfaces.
Packet capture may require elevated privileges or scoped capabilities. Retry a
single authorized capture with sudo on Linux, or follow your operating
system's documented packet-capture permission model. Avoid running unrelated
commands or an entire shell as root.
Activate the project virtual environment and install runtime requirements:
source .venv/bin/activate
python -m pip install -r requirements.txtInstall libpcap through your operating system's package manager. On Arch
Linux:
sudo pacman -S libpcapRun python main.py --list-interfaces again and copy an interface name exactly.
An interface may disappear, be renamed, or be unavailable inside a container
or virtual machine.
Check that the selected interface is active, that the protocol filter matches
the traffic, and that count or timeout is not too restrictive. Generate
only safe local traffic, such as one loopback ping. An empty result is valid
when no matching packets arrive.
Choose a new destination. Refusing to overwrite preserves earlier evidence and prevents accidental data loss.
The program closes the output safely but does not race-delete paths after a
write or finalization error. A private 0600 empty or partial .pcap may
therefore remain. Review its path from the error message and remove it manually
when it is no longer needed.
Invalid numeric values, unsupported protocols, unavailable interfaces, capture
permission failures, and PCAP write failures produce concise user-facing
messages. Press Ctrl+C to stop a running capture cleanly.
All automated packet tests use synthetic Scapy packets and mocks. The test suite must never start a real capture.
On Linux, Scapy may query interface metadata through a read-only netlink socket while its protocol modules are imported. A heavily sandboxed container can therefore need permission for interface enumeration even though the tests never sniff traffic; run the suite in a normal local shell or CI environment that permits this metadata query.
Run the complete suite:
.venv/bin/python -m pytest -vMeasure meaningful coverage across the sniffer package:
.venv/bin/python -m pytest --cov=sniffer --cov-report=term-missingThe coverage report generated by that command is the authoritative result for the current checkout. The project target is at least 85% meaningful package coverage with zero test failures; this README does not hard-code a result that could become stale.
Additional local checks:
.venv/bin/python -m compileall main.py sniffer tests
git diff --check
git status --shortBefore submitting the repository:
- Run the full test and coverage commands above.
- Confirm that
git status --shortcontains no.venv, cache,.env, log, or capture files. - Review
git difffor private addresses, payloads, secrets, and unrelated files. - Do not add real PCAP files or screenshots containing private traffic.
- Include the README, project report, video script, source code, and tests.
- Create commits and push only after a deliberate review.
- Capturing packets depends on operating-system permissions and adapter support.
- Linux is the primary supported and documented platform.
- Switched networks normally expose only traffic addressed to the local host, broadcasts, and multicasts visible to the selected interface.
- Loopback and non-Ethernet interfaces may not expose MAC addresses.
- IPv6 extension headers and uncommon link types can limit protocol detail.
- Capture filters depend on the local Scapy/libpcap environment.
- Continuous PCAP export can consume substantial disk space; prefer a count or timeout for demonstrations.
- The sniffer does not reassemble streams or fragmented application messages.
- Payload previews are intentionally short and sanitized.
- Encrypted protocols such as HTTPS normally expose metadata, not readable application contents. This project does not decrypt them.
- The tool is a teaching project, not an enterprise monitoring or forensics platform.
MIT License, Copyright (c) 2026 Mahmoud Abdullah. See LICENSE.