A high-performance packet monitoring tool built with eBPF, XDP, and Go. The application attaches an XDP program to a network interface and streams IPv4 packet metadata—including Layer 4 port information—to userspace using a Linux eBPF ring buffer.
The monitor is designed to provide low-overhead, real-time visibility into network traffic while allowing all packets to continue through the networking stack (XDP_PASS).
- Features
- Architecture
- Requirements
- Installation
- Building
- Usage
- Output Example
- Project Structure
- How It Works
- Packet Metadata
- Configuration
- Limitations
- Troubleshooting
- Future Improvements
- License
- High-performance XDP packet inspection
- Zero-copy communication via eBPF Ring Buffer
- IPv4 packet monitoring
- TCP and UDP port extraction
- ICMP protocol identification
- Automatic protocol detection
- Dynamic IPv4 header parsing
- Safe verifier-compatible bounds checking
- Root privilege verification
- Graceful shutdown on SIGINT/SIGTERM
- Lightweight userspace written in Go
Incoming Packets
│
▼
Network Interface
│
▼
XDP eBPF Program
│
┌──────────────┴──────────────┐
│ Parse Ethernet Header │
│ Parse IPv4 Header │
│ Parse TCP/UDP Header │
└──────────────┬──────────────┘
│
▼
Ring Buffer Map
│
▼
Go Userspace
│
▼
Console Output
- Linux kernel with eBPF support
- XDP-enabled network driver
- Go 1.20+
- clang/LLVM
- libbpf headers
- root privileges
Required Go packages:
github.com/cilium/ebpf
Clone the repository:
git clone <repository-url>
cd <repository>Install Go dependencies:
go mod tidyGenerate Go bindings from the eBPF program:
go generateBuild the application:
go build -o ebpf-visualizerMonitor the default interface (eth0):
sudo ./ebpf-visualizerMonitor another interface:
sudo ./ebpf-visualizer -i ens33Display help:
./ebpf-visualizer -hTCP:
[TCP ] 192.168.1.10:54231 → 142.250.72.46:443 len=60
UDP:
[UDP ] 192.168.1.15:60120 → 8.8.8.8:53 len=76
ICMP:
[ICMP] 192.168.1.20 → 1.1.1.1 len=84
.
├── bpf/
│ ├── packet_monitor.c # XDP eBPF program
│ └── headers/ # Kernel headers used by bpf2go
├── main.go # Userspace application
├── go.mod
├── go.sum
├── LICENSE
└── README.md
The C source lives in
bpf/rather than the package root. Go's build tooling rejects any package directory containing.cfiles unless cgo is explicitly enabled — even when, as here, the.cfile is never meant to be compiled bygo buildat all (it's built separately bybpf2go/clang for the kernel, not by cgo). Keeping it in a subdirectory is what makesgo install github.com/foxhackerzdevs/ebpf-visualizer@latestwork at all.
The XDP program performs the following steps:
- Reads the Ethernet header.
- Ensures the packet is IPv4.
- Verifies all memory boundaries for verifier safety.
- Parses the IPv4 header.
- Calculates the dynamic IP header size using
ihl. - Parses TCP or UDP headers when applicable.
- Extracts:
- Source IP
- Destination IP
- Source Port
- Destination Port
- Protocol
- Packet Length
- Writes the metadata into a Ring Buffer.
- Returns
XDP_PASSso packets continue through the normal networking stack.
The Go application:
- Removes the memlock limit
- Loads the compiled eBPF object
- Attaches the XDP program
- Opens the Ring Buffer
- Reads events continuously
- Converts binary data into Go structures
- Prints packet information in a human-readable format
The kernel sends the following structure:
struct packet_meta {
__u32 src_ip;
__u32 dst_ip;
__u16 src_port;
__u16 dst_port;
__u16 payload_len;
__u8 protocol;
__u8 pad;
};| Field | Description |
|---|---|
| src_ip | Source IPv4 address |
| dst_ip | Destination IPv4 address |
| src_port | TCP/UDP source port |
| dst_port | TCP/UDP destination port |
| payload_len | IPv4 total length |
| protocol | IP protocol number |
| pad | Alignment padding |
Default:
eth0Custom:
-i <interface>Example:
-i enp0s3| Protocol | Supported |
|---|---|
| IPv4 | ✅ |
| TCP | ✅ |
| UDP | ✅ |
| ICMP | ✅ |
| IPv6 | ❌ |
| ARP | ❌ |
The XDP program includes verifier-friendly safety checks:
- Ethernet bounds validation
- IPv4 bounds validation
- Dynamic IP header length validation
- TCP header bounds validation
- UDP header bounds validation
- Ring buffer allocation failure handling
- Explicit structure padding initialization
The monitor is optimized for high throughput:
- Runs entirely in the XDP hook
- Minimal packet parsing
- Zero-copy Ring Buffer communication
- No packet modifications
- No packet drops (always returns
XDP_PASS) - Low userspace overhead
Current limitations include:
- IPv4 only
- No IPv6 support
- No packet payload capture
- Console output only
- No packet filtering
- No statistics aggregation
- No persistent logging
Run with:
sudo ./ebpf-visualizerList available interfaces:
ip linkPossible reasons:
- Interface does not support XDP.
- Driver does not implement native XDP.
- Another XDP program is already attached.
- Insufficient permissions.
Verify:
- Kernel supports BPF Ring Buffers.
- eBPF program loaded successfully.
- XDP attachment succeeded.
Potential enhancements include:
- IPv6 support
- ARP parsing
- VLAN awareness
- DNS decoding
- HTTP inspection
- Packet filtering
- Prometheus metrics
- JSON output
- PCAP export
- Interactive terminal UI
- Flow tracking
- Per-interface statistics
- Packet rate monitoring
- eBPF maps for counters
- Prometheus exporter
The eBPF program is released under the GPL license:
char LICENSE[] SEC("license") = "GPL";Refer to the project's LICENSE file for the complete licensing terms.
- Linux eBPF subsystem
- XDP (Express Data Path)
- Cilium eBPF Go library
- Linux Kernel networking stack