Warning
This project is deprecated in favor of iftoprs. It may not receive further updates or bug fixes.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββ βββββββ βββββββ βββββββ βββββββ βββ βββββββ βββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββββββββββββββββ
βββββββββ βββ βββ ββββββββββββββ βββ ββββββ βββ βββββββββββ
βββββββββ βββ βββ ββββββββββ βββ βββ ββββββ βββ βββββββββββ
ββββββ βββ ββββββββββββ βββββββββββββββββββββββββββββββββββββ βββ
ββββββ βββ βββββββ βββ βββββββ βββββββ ββββββββ βββββββ βββ βββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[ REAL-TIME BANDWIDTH SURVEILLANCE // FULL SPECTRUM COLOR ]
>>> JACK IN. WATCH THE DATA FLOW. OWN YOUR NETWORK. <<<
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STATUS: ONLINE THREAT LEVEL: NEON SIGNAL: ββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
"The street finds its own uses for things." -- William Gibson
A colorized fork of iftop that renders real-time bandwidth usage on a network interface, broken down by host pairs. Fully customizable color schemes via config file. Your console, your rules.
SCANNING DEPENDENCIES...
PROBING HARDWARE INTERFACES...
ENUMERATING ATTACK SURFACE...
| Component | Status |
|---|---|
| CMake 3.10+ | REQUIRED |
| libpcap | REQUIRED -- packet capture substrate |
| ncurses (ncursesw on Linux) | REQUIRED -- terminal rendering engine |
| pthreads | REQUIRED -- parallel execution threads |
| Platform | Command |
|---|---|
| Debian/Ubuntu | sudo apt install cmake libpcap-dev libncursesw5-dev |
| Fedora/RHEL | sudo dnf install cmake libpcap-devel ncurses-devel |
| macOS | brew install cmake (libpcap and ncurses ship with Xcode CLI tools) |
| FreeBSD | pkg install cmake |
INITIATING BUILD SEQUENCE...
DECRYPTING SOURCE ARCHIVE...
COMPILING INTRUSION COUNTERMEASURES...
# --- DOWNLOAD THE PAYLOAD ---
git clone https://github.com/MenkeTechnologies/iftopcolor.git
cd iftopcolor
# --- COMPILE THE ICE ---
mkdir build && cd build && cmake ..
make
# --- DEPLOY TO /usr/local/sbin ---
sudo make installMake sure
/usr/local/sbinis in yourPATHor you'll be flatlined at the prompt.
INITIALIZING PACKET SNIFFER...
ELEVATING PRIVILEGES...
ENTERING THE MATRIX...
iftop requires root privileges to capture packets:
sudo iftop SWITCH FUNCTION
ββββββ ββββββββ
-h display help
-n don't do hostname lookups
-N don't convert port numbers to services
-p run in promiscuous mode
-b don't display bar graph of traffic
-B display bandwidth in bytes
-i interface listen on named interface
-f filter code BPF filter for packet selection
-F net/mask show traffic in/out of IPv4 network
-G net6/mask6 show traffic in/out of IPv6 network
-l display and count link-local IPv6 traffic
-P show ports as well as hosts
-Z show owning process per flow
-m limit set upper limit for bandwidth scale
-c config file use alternative configuration file
-o json|csv output in JSON or CSV format (non-interactive)
-t seconds capture duration for export mode
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β KEY ACTION β KEY ACTION β
β βββ ββββββ β βββ ββββββ β
β n Toggle DNS resolution β P Pause display β
β s Toggle source host β h Toggle help β
β d Toggle destination host β b Toggle bar graph β
β t Cycle line display mode β B Cycle bar graph average β
β N Toggle service resolution β T Toggle cumulative totals β
β S Toggle source port β j/k Scroll display β
β D Toggle destination port β f Edit filter code β
β p Toggle port display β l Set screen filter β
β Z Toggle process display β L Lin/log scales β
β 1/2/3 Sort by column β β
β < / > Sort by src/dst name β ! Shell command β
β o Freeze current order β q Quit β
βββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββ
ENGAGING DATA EXFILTRATION PROTOCOL...
SERIALIZING FLOW TELEMETRY...
ROUTING OUTPUT TO STDOUT...
Export mode bypasses the interactive TUI and writes machine-readable output to stdout. Use -o to select the format and -t to set the capture duration.
# JSON snapshots every 2 seconds for 10 seconds
sudo iftop -i en0 -o json -t 10
# CSV with header + data rows
sudo iftop -i en0 -o csv -t 10
# Pipe to jq for live filtering
sudo iftop -i en0 -o json -t 30 | jq '.flows[] | select(.sent_2s > 1000)'JSON output includes a flows array with per-host-pair bandwidth rates (2s, 10s, 40s averages) and cumulative totals, plus a totals section with aggregate stats, peak rates, and cumulative byte counts. All bandwidth values are raw bytes for easy machine parsing.
CSV output prints a header row on first tick, then one row per flow per tick with the same fields.
SCANNING PROCESS TABLE...
MAPPING SOCKETS TO PIDS...
IDENTIFYING NETWORK OWNERS...
The -Z flag enables per-process bandwidth attribution: each flow is annotated with the process name that owns the local socket. Press Z in the TUI to toggle at runtime.
# Show which processes are using bandwidth
sudo iftop -Z
# Include process info in JSON export
sudo iftop -Z -o json -t 10
# Include process info in CSV export
sudo iftop -Z -o csv -t 10The process name appears in [brackets] next to the destination host in the TUI. In JSON export, flows include "pid" and "process_name" fields. In CSV, pid and process_name columns are added.
Platform support:
- macOS: Uses
libproc(proc_pidinfo/proc_pidfdinfo) -- no extra dependencies - Linux: Reads
/proc/net/tcp*+/proc/[pid]/fd/symlinks -- no extra dependencies - Other: Gracefully degrades (process names are empty)
The process name color is configurable via ~/.iftopcolors with the key PROC_NAME_COLOR (default: green bold).
"The sky above the port was the color of television, tuned to a dead channel." Your terminal doesn't have to be.
LOADING CHROMATIC SUBSYSTEM...
PARSING COLOR MATRIX...
APPLYING NEON OVERLAY...
Create ~/.iftopcolors to customize colors. Available colors: red, blue, green, yellow, magenta, cyan, black, white. Each can be bold or nonbold.
# ~/.iftopcolors -- NEON NIGHTCITY PRESET
BOTH_BAR_COLOR blue bold
HOST1_COLOR red nonbold
HOST2_COLOR red bold
SCALE_BAR_COLOR red nonbold
SCALE_MARKERS_COLOR red bold
DL_UL_INDICATOR_COLOR blue bold
TWO_SECOND_TRANSFER_COLUMN_COLOR yellow bold
TEN_SECOND_TRANSFER_COLUMN_COLOR magenta bold
FOURTY_SECOND_TRANSFER_COLUMN_COLOR yellow bold
BOTTOM_BAR_COLOR blue bold
CUM_LABEL_COLOR yellow nonbold
PEAK_LABEL_COLOR magenta bold
RATES_LABEL_COLOR magenta bold
TOTAL_LABEL_COLOR blue bold
CUM_TRANSFER_COLUMN_COLOR magenta nonbold
PEAK_TRANSFER_COLUMN_COLOR magenta nonbold
RECEIVE_BAR_COLOR yellow nonbold
SENT_BAR_COLOR yellow nonbold
PROC_NAME_COLOR green boldDEPLOYING DIAGNOSTIC ROUTINES...
VALIDATING MEMORY SUBSYSTEMS...
INTEGRITY CHECK IN PROGRESS...
A test suite covers core data structures, utilities, packet parsing, UI logic, screen filtering, and export mode: hash tables, address/namespace hashes, service lookup table, sorted lists, vectors, string maps, config file parsing, utility functions, IPv4/IPv6 packet address extraction, bandwidth formatting, sort comparators, regex-based display filtering, and JSON/CSV export output.
mkdir build && cd build && cmake ..
make checkRun a single diagnostic:
make check_hash
./check_hash βββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββ
β SUITE β SUBSYSTEM COVERAGE β TESTS β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββ€
β check_util β xmalloc, xcalloc, xrealloc, xstrdup, xfree, alloc chains β 41 β
β check_vector β Push, pop, remove, resize, iteration, shrink, ptr storage β 68 β
β check_hash β Generic hash: insert, find, delete, collisions, high load β 59 β
β check_addr_hash β IPv4/IPv6 pairs, pool allocator, fast-path, UDP, protocol β 49 β
β check_ns_hash β IPv6 address to hostname cache, adjacent addrs, eviction β 39 β
β check_serv_hash β Port+protocol to service name, protocol differentiation β 27 β
β check_sorted_list β Single insert, batch insert, descending order, destroy β 46 β
β check_stringmap β Binary tree insert, find, special chars, deep chains β 46 β
β check_cfgfile β Config parsing: string, bool, int, float, enum, file IO β 77 β
β check_options β options_make interface fallback, default interface safety β 5 β
β check_packet β assign_addr_pair IPv4/IPv6 TCP/UDP/ICMP, flip, net filter β 19 β
β check_ui_format β readable_size, color/bold parse, sort comparators, history β 38 β
β check_screenfilter β Regex screen filter: set, match, case-insensitive, anchors β 12 β
β check_export β JSON/CSV export: protocol names, addr fmt, escaping, output β 32 β
β check_procinfo β Socket-to-PID mapping: TCP/UDP, IPv4/IPv6, refresh, destroy β 9 β
β check_integration β Cross-module: flows, resolution, config overlay, stress β 50 β
β check_leaks β Full lifecycle leak tests for all data structures (macOS) β 30 β
βββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββ
TOTAL: 647
Leak detection uses macOS leaks --atExit to verify zero unreachable allocations after full create/populate/destroy lifecycles for every data structure.
make leakcheckCovers: vector, generic hash, address hash (pool allocator), ns_hash, serv_table, sorted list (single and batch), stringmap, and config file subsystems.
INITIALIZING PERFORMANCE PROFILER...
WARMING UP EXECUTION CORES...
MEASURING CLOCK CYCLES...
ALL GOVERNORS SET TO MAXIMUM OVERDRIVE...
"Speed is the ultimate weapon in the Net."
Compiled with aggressive optimizations (-O3, -march=native, -flto, -funroll-loops).
# --- FULL BENCHMARK SWEEP ---
mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release ..
make bench
# --- TARGETED STRIKE ---
./bench/run_benchmarks.sh hash
./bench/run_benchmarks.sh vector ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SUITE β MEASURES β
ββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β benchmark_hash β Distribution, insert, find (hit/miss), scaling, delete, iterate β
β benchmark_sorted_list β Single O(n^2) vs batch O(n log n), iteration scaling, destroy, cycles β
β benchmark_vector β Push, pop, remove (front/middle/back), iterate, reallocate, pointers β
β benchmark_pool β Pool vs malloc: insert/delete, churn, multi-block, reuse, post-churn β
β benchmark_stringmap β Sequential vs random keys, find scaling, config-style workload β
β benchmark_ns_hash β IPv6 address cache: insert, find, delete, iteration, churn β
β benchmark_serv_hash β Service cache: insert, lookup, delete, TCP/UDP direct-index arrays β
β benchmark_cfgfile β Config set/get, type parsing, file reading, realistic workload β
ββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DOWNLOADING BENCHMARK DATA FROM CORES...
RENDERING PERFORMANCE HEATMAP...
The pool allocator is a custom slab that recycles fixed-size nodes. No syscalls. No fragmentation. Pure speed.
OPERATION addr_hash [OPTIMIZED] hash [GENERIC] SPEEDUP
βββββββββ βββββββββββββββββββββ ββββββββββββββ βββββββ
Insert 1000 IPv4 flows 10,710 ns/op 23,110 ns/op 2.2x
Find hit (1000 entries) 2.5 ns/op 4.0 ns/op 1.6x
ALLOCATOR SHOOTOUT TIME VERDICT
ββββββββββββββββββ ββββ βββββββ
Pool (insert 2000 + delete) 24.7 ms >>> 2.1x FASTER <<<
Malloc (insert 2000 + delete) 51.6 ms baseline
Hash distribution is near-ideal -- IPv4 stddev 2.26 vs ideal 2.21, IPv6 stddev 2.21 vs ideal 2.21. Virtually zero wasted buckets.
The old serv_hash used a 123-bucket chaining hash with a degenerate hash function that only hashed on protocol -- all TCP entries landed in one bucket, all UDP in another. Every lookup walked the entire chain. The new serv_table uses direct-index arrays for TCP/UDP (port as index) with a small hash fallback for rare protocols. One array dereference. No comparisons. No chains.
IMPLEMENTATION FIND HIT (200 entries) THROUGHPUT MECHANISM
ββββββββββββββ ββββββββββββββββββββββ ββββββββββ βββββββββ
serv_table [NEW] 0.5 ns/op 1.8B ops/s direct array[port]
serv_hash [OLD] 53.4 ns/op 18.7M ops/s chained hash (degenerate)
~~~ 100x FASTER ~~~
Memory cost: 1 MB (two 65536-entry pointer arrays for TCP/UDP). Negligible for a network monitor.
Specialized hash for IPv6 address-to-hostname resolution caching.
VARIANT FIND HIT (200 entries) THROUGHPUT KEY COMPARISON
βββββββ ββββββββββββββββββββββ ββββββββββ ββββββββββββββ
ns_hash 2.6 ns/op 384M ops/s IN6_ARE_ADDR_EQUAL (16-byte memcmp)
At small n the overhead of qsort dominates. Cross the threshold and batch mode pulls away exponentially.
SIZE SINGLE (one-by-one) BATCH (qsort) SPEEDUP
ββββ βββββββββββββββββββ βββββββββββββ βββββββ
100 4,290 ns/op 6,445 ns/op 0.7x [batch overhead]
500 73,450 ns/op 43,656 ns/op 1.7x
1000 230,920 ns/op 98,820 ns/op 2.3x
2000 766,900 ns/op 205,380 ns/op 3.7x
5000 4,585,000 ns/op 613,951 ns/op >>> 7.5x <<<
Sequential keys are a death sentence for an unbalanced binary tree. The structure degenerates into a linked list. Every lookup walks the full chain.
OPERATION (1000 keys) SEQUENTIAL [DEGENERATE] RANDOM [BALANCED-ISH] PENALTY
βββββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββββ βββββββ
Insert 873,510 ns/op 66,974 ns/op 13x
Find hit 758.8 ns/op 56.5 ns/op 13.4x
VERDICT: Sequential keys => O(n) per op. Random keys => O(log n).
Choose your key distribution wisely, choomba.
Flat arrays. No pointers to chase. The CPU cache is your ally.
OPERATION PERFORMANCE
βββββββββ βββββββββββ
push_back 10,000 items 4,435 ns/op amortized O(1)
remove from front (1000 items) 36,240 ns/op O(n) memmove
iterate 10,000 items 574.6 ns/pass ~0.057 ns/element
NOTE: Iteration at cache-line speed. 0.057 ns/element = ~17.5 billion elements/sec.
The bottleneck is your RAM, not the code.
PATCHING SYSTEM VULNERABILITIES...
HARDENING MEMORY SUBSYSTEMS...
STABILIZING CORE ROUTINES...
New -Z flag maps each network flow to the owning process using platform-native APIs (macOS libproc, Linux /proc filesystem). Process names are displayed inline in the TUI and included in JSON/CSV exports. Toggle with Z key at runtime. Gracefully degrades on unsupported platforms or when running without sufficient permissions.
The ns_hash IPv6 address-to-hostname cache had no upper bound -- on long-running sessions with high host churn, it grew without limit, consuming unbounded memory. A cache eviction policy now flushes and resets the cache when it reaches NS_HASH_MAX_ENTRIES (16384). The entry counter is maintained on insert and correctly avoids double-counting when an existing address is re-resolved. This keeps memory usage stable during extended monitoring sessions.
options_make() unconditionally freed and NULLed options.interface, then only restored it from the config file. When no -i flag was passed and no config file entry existed, the NULL pointer was forwarded to pcap_open_live(), causing a segfault on startup. The default interface fallback is now restored after the config lookup.
WARNING: THE FOLLOWING ANOMALIES HAVE BEEN DETECTED IN THE SYSTEM...
RedHat 7.2 -- A bug in the bundled ncurses can cause a segfault. Update ncurses from Rawhide.
Slackware 8.1 -- You may need to upgrade libpcap (via the tcpdump package) to compile.
FreeBSD 4.7 -- Lacks a proper gethostbyaddr_r. Use --with-resolver=... to select an alternative resolver.
Solaris -- iftop must run in promiscuous mode to capture outgoing packets. This is auto-configured; the -p flag disables the non-broadcast packet filter. You may also need ncurses instead of the bundled curses.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Copyright (c) 2026 Jacob Menke and contributors. β
β UNAUTHORIZED REPRODUCTION WILL BE MET WITH FULL ICE. β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ CONNECTION TERMINATED // END OF LINE ββ
ββββββββββββββββββββββββββββββββββββββββββββββββββ


