Skip to main content

PacketPulse

Terminal network monitoring and analysis console.

Repository: https://github.com/tejppatil/PacketPulse

pip install packetpulse
packetpulse

A capture backend must be installed first — Npcap on Windows, libpcap on Linux and macOS. See Getting started for the exact steps on your platform.

An interactive menu runs five modules. Every result PacketPulse prints or writes comes from data it actually observed. Where something cannot be determined it says UNKNOWN, NOT OBSERVED or UNAVAILABLE with a reason — it does not fill the field with a guess.

PacketPulse running in a terminal

What it does not do

Read this first. It is the shortest way to understand what the tool is for.

  • It does not decrypt HTTPS. For TLS traffic you get endpoint metadata (addresses, ports, sizes, timing) and the SNI hostname from the ClientHello. Paths, headers, cookies and bodies are encrypted and are not recovered.
  • It does not identify malware. Detections are structural and behavioural indicators with documented weights. A high score means several indicators fired, not that something is malicious.
  • It does not guess which process sent a packet. Attribution requires an exact socket four-tuple match. Anything less is reported as UNKNOWN, or explicitly labelled INFERRED with the reason.
  • It does not call query volume "beaconing". Periodicity is reported only when the intervals between queries are measurably regular.
  • It does not contact external services unless you enable them. Reputation and online GeoIP lookups are off by default.
  • A CLEAN verdict means no indicator fired. It is not a safety guarantee.

Getting started

PacketPulse needs a packet-capture backend from your operating system. Install that first, then the package. The startup steps differ by platform, so follow the section for yours.

Whichever platform you are on, the first thing to run is:

packetpulse   ->   6  (Capabilities)

That prints exactly what works on your host and the reason for anything that does not. It needs no privileges and answers in under a second.


Windows

1. Install Npcap — the capture driver. There is no pip package for it.

Download from https://npcap.com and run the installer.

One installer checkbox decides whether you will need an Administrator terminal:

Checkbox Effect
Restrict Npcap driver's access to Administrators only Ticked → capture requires an elevated terminal
Unticked → capture works as a normal user

Leave WinPcap API-compatible mode ticked. The tool detects which mode you chose and tells you, so you do not have to remember.

2. Install PacketPulse

py -m pip install packetpulse

3. Run it

packetpulse

If capture reports UNAVAILABLE, re-open the terminal as Administrator (right-click → Run as administrator) and try again.

Verified on: Windows 11, Python 3.12, Npcap present, non-elevated — all five pipelines produced real data with verified artifacts.

What is limited on Windows

Limitation Detail
USB forensics unavailable Requires Linux libudev. Reports UNAVAILABLE: requires Linux (libudev); this host is Windows — never an empty section
Process attribution Without an elevated terminal the OS hides other users' sockets, so most packets report Process: UNKNOWN. Run elevated for EXACT attribution
NetBIOS / mDNS names nmblookup and avahi-resolve do not exist on Windows; those fields report UNAVAILABLE
First capture may pause The capture engine loads once per run. Normally ~2 seconds; on a host with many virtual adapters it can take longer, and the tool prints a message while it waits so it is not mistaken for a freeze

Everything else — sniffer, DNS monitor, URL scanner, host profiling, LAN discovery, nmap, and the full pipeline — works on Windows.


Linux (Debian, Ubuntu, Kali)

1. Install the capture library and Python tooling

sudo apt update
sudo apt install -y libpcap0.8 python3-pip python3-venv

libpcap0.8 is the runtime library. Without it PacketPulse reports:

Packet capture UNAVAILABLE: libpcap not found —
  install libpcap (Debian/Kali: apt install libpcap0.8; Fedora: dnf install libpcap)

2. Install PacketPulse

python3 -m venv ~/.venvs/packetpulse
~/.venvs/packetpulse/bin/pip install packetpulse

pyudev is pulled in automatically on Linux, which is what enables USB forensics.

3. Run it — pick one of two ways

Packet capture needs raw-socket access. Either run as root:

sudo ~/.venvs/packetpulse/bin/packetpulse

…or grant the capability once and run as your normal user:

sudo setcap cap_net_raw,cap_net_admin+eip \
    "$(readlink -f ~/.venvs/packetpulse/bin/python3)"

~/.venvs/packetpulse/bin/packetpulse

PacketPulse tests the permission by opening a raw socket rather than assuming root, so the capability route is detected and reported as libpcap.so.1 via granted capability (CAP_NET_RAW).

4. Optional extras — each is probed, and a missing one is named with the package that provides it rather than leaving a blank field:

sudo apt install -y nmap net-tools samba-common-bin avahi-utils
Tool Package Used for
nmap nmap Active port scan in Device Forensics
arp net-tools ARP table (not installed by default on current Kali)
nmblookup samba-common-bin NetBIOS host names
avahi-resolve avahi-utils mDNS host names
blkid util-linux (already present) USB filesystem detail

Verified on: Ubuntu 26.04, Python 3.14.4, psutil 7.2.2, scapy 2.7.0, pyudev 0.24.4 — full test suite passed, USB enumeration ran against real pyudev, and the no-libpcap/no-root path refused cleanly with the message above.

What is limited on Linux

Limitation Detail
Capture needs root or CAP_NET_RAW Without either, capture reports UNAVAILABLE with both remedies. It does not half-run
dmesg is root-restricted Most distributions set kernel.dmesg_restrict; the kernel-log section then reports UNAVAILABLE with that reason
Some tools absent by default Current Kali ships without net-tools, so the ARP table section reports UNAVAILABLE until you install it
scapy 2.6+ on unusual kernels See below

If scapy cannot read your IPv6 route table

On kernels whose rtnetlink does not report an address scope field, scapy 2.6 and later raise KeyError: 'scope' while building their IPv6 routing table — during import, which would otherwise stop PacketPulse from starting at all. Observed on WSL2 (kernel 4.4.0-Microsoft):

scapy Result
2.5.0 imports cleanly
2.6.1 KeyError: 'scope'
2.7.0 KeyError: 'scope'

PacketPulse detects this and disables scapy's IPv6 route autoload (conf.route6_autoload, scapy's own supported switch) so capture proceeds. IPv6 packets are still decoded. The workaround is recorded in every report's limitations, so you always know it was applied. If it ever fails outright, the tool names the remedy:

pip install 'scapy==2.5.0'

macOS

python3 -m venv ~/.venvs/packetpulse
~/.venvs/packetpulse/bin/pip install packetpulse
sudo ~/.venvs/packetpulse/bin/packetpulse

libpcap ships with macOS. Capture requires root. USB forensics is unavailable (it needs Linux libudev) and is reported as such.

Not verified — macOS support is reasoned from the POSIX code paths, which were tested on Linux. Run option 6 first to see what your host reports.


Platform support at a glance

Module Windows Linux / Kali macOS
Packet Sniffer Yes (Npcap) Yes (root or CAP_NET_RAW) Yes (root)
DNS Monitor Yes Yes Yes
URL Scanner — single URL Yes Yes Yes
URL Scanner — live watch Yes Yes Yes
Full Pipeline Yes Yes Yes
Forensics — host profile Yes Yes Yes
Forensics — LAN discovery Yes Yes Yes
Forensics — nmap If installed If installed If installed
Forensics — USB No (needs Linux) Yes No (needs Linux)
Process attribution EXACT only when elevated EXACT under root EXACT under root

Choosing the right interface

On a host with a VPN or tunnel adapter active, the platform's default capture interface is often not the one carrying internet traffic. PacketPulse asks the OS which interface it actually routes through and offers that first, using native system calls rather than scapy's enumeration.

This matters more than it sounds. On the development host, DNS traffic was completely invisible on the default interface and fully visible on the tunnel adapter — a capture on the wrong one would have produced an empty report that looked like a successful scan.

If you capture on the wrong interface you will typically see only local broadcast traffic (mDNS, LLMNR, SSDP) and no internet traffic at all. Every report records which interface was used and warns when it differs from the routing interface.


The five modules

1 — Packet Sniffer

Captures live packets and writes a verified artifact set.

Extracted per packet, when actually present:

  • L2 — source/destination MAC (absent on tunnel interfaces with no Ethernet header)
  • L3 — IPv4/IPv6 addresses, TTL
  • L4 — TCP/UDP ports, TCP flags, sequence, window; ICMP; ARP
  • L7 — DNS queries and answers; HTTP request line, headers and body only when the traffic is genuinely plaintext

Each packet gets an observation, a signal level and a score:

OBSERVED   Potential credential submission over cleartext HTTP  signal=STRONG  score=65/100
  +15   HTTP service port — port 80 (cleartext) with public peer
  +15   Cleartext HTTP — request/response readable on the wire
  +30   Credential-bearing POST over cleartext — POST to path containing 'login'
  +5    External web request — Host header 'example.com' on a public peer

The score is the sum of the indicator weights listed beneath it. There are no fixed confidence percentages: every number shown is one the tool computed and can show its working for.

Artifacts (in pcap_store/): .pcap, .ndjson (one record per packet), .html, .pdf, .json.

The PCAP is streamed to disk as packets arrive and is complete. If the terminal cannot keep up, rendering drops packets and the report says how many — the capture file never does. After capture the PCAP is re-read and its frame count is compared with the session counter; a mismatch is reported.

2 — URL Scanner

Single URL — four checks, of which only those that actually run are reported:

  1. Structure — TLD, IP-as-host, length, subdomain depth, entropy, encoding evasion, punycode, suspicious parameters, executable extensions
  2. TLS — real certificate validation with verification enabled; expiry, protocol version, hostname match
  3. Reputation — VirusTotal, Google Safe Browsing, PhishTank. Optional. Not configured, not enabled or not reachable are each reported distinctly, and never as a clean result
  4. Content — fetched only when enabled, with certificate verification on and a 2 MB response cap

Verdict is derived from the accumulated score (CLEAN < 25 ≤ SUSPICIOUS < 60 ≤ MALICIOUS), or forced to MALICIOUS by a conclusive finding such as a Safe Browsing listing.

Live watch — extracts URLs from real traffic only:

Source What is observed
HTTP Full URL from the request line and Host header
HTTPS SNI hostname only — the payload is encrypted
DNS The queried name
Browser sockets Destination, resolved by reverse DNS; skipped if it does not resolve

Scans run on a bounded worker pool. If traffic outruns capacity the excess is counted and reported, not silently dropped.

3 — DNS Monitor

Observes plaintext DNS on UDP/53. DNS-over-HTTPS and DNS-over-TLS are encrypted and are invisible to this module — if your resolver uses them, this module will correctly report that it saw nothing.

Indicators, each reported with its measurement:

  • Algorithmically generated names — combines character entropy, bigram frequency against common letter pairs, vowel ratio and digit ratio. Three or more indicators is required before a name is called suspicious
  • High query frequency — count, window and rate
  • Periodicity — computed from inter-query intervals as a coefficient of variation. Reported as REGULAR INTERVALS OBSERVED only when intervals are genuinely regular; otherwise IRREGULAR or NOT ESTABLISHED
  • High-abuse TLDs, keyword tokens, long names, hyphen count, punycode

Reverse-DNS (.arpa) and link-local (.local) zones are exempt from structural checks, which they would otherwise fail by definition.

4 — Device Forensics

Every section is labelled OBSERVED, INFERRED or UNAVAILABLE.

  • Host — hostname, OS, CPU, memory, disks, interfaces, open sockets, listening ports, network processes. All read from OS APIs via psutil
  • USB — Linux only, via pyudev. Product, manufacturer, serial, VID/PID, driver, speed, power, and session history
  • LAN — ARP sweep, MAC vendor lookup, hostname resolution, and optional nmap port scan when the binary is present. Without elevation nmap runs a TCP connect scan (-sT); with elevation it uses SYN scan and OS detection. Discovered ports and services come from nmap's own output — nothing is inferred when the scan does not run

OS fingerprinting from TTL and window size is labelled a heuristic and shows its evidence. It is never presented as an identification:

Likely OS: Windows
Evidence : observed TTL 128 implies initial TTL 128 (0 hops away)
Method   : TTL/window heuristic
Confidence: heuristic - not an identification

Only scan networks you are authorised to scan. The nmap option performs an active scan and is off by default.

5 — Full Pipeline

Runs the Sniffer, URL Scanner and DNS Monitor concurrently against one shared interface, one duration and one stop signal. When the duration expires every module is signalled, drained, joined and its reports written before control returns. If a module fails, the failure is reported and the others are shut down cleanly — the pipeline does not claim success.


Configuration

All secrets come from the environment. Nothing is read from source.

export PACKETPULSE_VT_KEY="..."           # VirusTotal (optional)
export PACKETPULSE_GSB_KEY="..."          # Google Safe Browsing (optional)
export PACKETPULSE_PHISHTANK_KEY="..."    # PhishTank (optional)
export PACKETPULSE_GEOIP_DB="/path/GeoLite2-City.mmdb"   # offline GeoIP (optional)

A .env file is loaded if present, searched in this order: the current working directory, then ~/.packetpulse/.env, then the project directory.

GeoIP

  • With PACKETPULSE_GEOIP_DB set, lookups are local, fast and private.
  • Without it, GeoIP is reported as UNAVAILABLE with the reason.
  • Online lookup via ip-api.com exists but is off by default: it transmits every observed address to a third party and is rate limited. When enabled, reports state that it was used and that results are approximate.

Failed lookups are never cached as facts, so one offline session does not permanently degrade later reports.

External reputation

Off by default. When you enable it:

  • Single-URL mode sends the URL you typed.
  • Live mode sends the registered domain only — never full URLs, which would transmit paths and query strings for every site on the monitored network.
  • Requests are rate limited locally against the free-tier quotas.

Reading a report

Every report identifies the session that produced it:

Field Meaning
Session ID Unique per run. Artifacts from different runs never mix
Status PASS (completed, nothing missing), PARTIAL (completed, something unavailable or errored), FAIL (did not complete)
Requested vs measured duration Measured from timestamps, never echoed back from the request
Duration honoured Whether the capture window matched the request
Counters Only what was actually observed
Unavailable features What could not run, and why
Limitations What this report cannot establish
Errors Failures that occurred, never swallowed

"No threats observed in captured data" and "analysis incomplete — capture failed" mean different things, and the reports say which one applies.

Values you will see, and what they mean:

Value Meaning
UNKNOWN Could not be determined from available evidence
NOT OBSERVED Did not appear during the capture window
UNAVAILABLE The capability required is not present — reason given
NOT RESOLVED A lookup was attempted and did not return
INFERRED Derived, not confirmed — basis stated alongside

Development

git clone https://github.com/tejppatil/PacketPulse
cd PacketPulse
pip install -e ".[dev]"
pytest

The test suite covers packet parsing against crafted fixtures, the analysis heuristics, session lifecycle and stop control, and security regressions for path traversal, command injection and HTML injection.

Synthetic packets exist only inside tests. The application itself never fabricates traffic, devices or results.


Security

PacketPulse commonly runs with elevated privileges and parses data controlled by other parties on the network. Accordingly:

  • Names observed on the wire (DNS names, USB serials, URLs) are sanitised and containment-checked before they are used in a filename
  • Captured values are escaped before they enter an HTML report
  • Notification text is sanitised and never interpolated into a shell command
  • TLS verification is never disabled
  • Network responses are size-capped
  • Subprocesses are invoked with argument arrays, never shell=True

Report security issues via the repository issue tracker.


License

MIT. See LICENSE.

Release files for packetpulse 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for packetpulse 2.0.0
File Size Uploaded
packetpulse-2.0.0.tar.gz 133.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for packetpulse 2.0.0
File Interpreter ABI Platform
packetpulse-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 254.1 kB

Release files / packetpulse-2.0.0.tar.gz

Download URL packetpulse-2.0.0.tar.gz
Size 133.9 kB
Tags Source
SHA-256 checksum
How to use checksums
af72ed95ffcb10ea6887ae6f0f2c49aa502da185d1abd3b36695b1844a036e4f
BLAKE2b-256 checksum
How to use checksums
d52aefba78d45e2b2b41f5df3d32be2e65b8a0cac7fead48bd0477b35b1d403e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / packetpulse-2.0.0-py3-none-any.whl

Download URL packetpulse-2.0.0-py3-none-any.whl
Size 120.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fda76c2de69e0830dbe12434acc9180e3931690fd0b933fcbf67629696f13285
BLAKE2b-256 checksum
How to use checksums
2e591d5feb53bd996289d839a0edb91b193bec1fbed4264bfedba7817b00675d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page