Created
February 26, 2026 13:36
-
-
Save mbeijen/8d42972f28fff8102140b81c7014cade to your computer and use it in GitHub Desktop.
netcap: capture and sum bytes send for command
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| if [[ $# -lt 1 ]]; then | |
| echo "usage: netcap <command> [args...]" | |
| exit 1 | |
| fi | |
| RAND=$(head -c 32 /dev/urandom | tr -dc a-z0-9 | head -c 6) | |
| NS="netcap-$RAND" | |
| VETH_HOST="veth-$RAND" | |
| VETH_NS="eth0" | |
| SUBNET="10.200.200.0/24" | |
| HOST_IP="10.200.200.1" | |
| NS_IP="10.200.200.2" | |
| PCAP="capture-${$}.pcap" | |
| cleanup() { | |
| ip link del "$VETH_HOST" 2>/dev/null || true | |
| ip netns del "$NS" 2>/dev/null || true | |
| rm -rf /etc/netns/$NS 2>/dev/null || true | |
| } | |
| trap cleanup EXIT | |
| # Pre-clean in case previous run crashed | |
| ip link del "$VETH_HOST" 2>/dev/null || true | |
| ip netns del "$NS" 2>/dev/null || true | |
| echo "[+] Creating namespace" | |
| ip netns add "$NS" | |
| mkdir -p /etc/netns/$NS | |
| echo "nameserver 1.1.1.1" > /etc/netns/$NS/resolv.conf | |
| echo "nameserver 8.8.8.8" >> /etc/netns/$NS/resolv.conf | |
| echo "[+] Creating veth pair" | |
| VETH_PEER="vpeer-$RAND" | |
| ip link add "$VETH_HOST" type veth peer name "$VETH_PEER" | |
| ip link set "$VETH_PEER" netns "$NS" | |
| ip netns exec "$NS" ip link set "$VETH_PEER" name "$VETH_NS" | |
| echo "[+] Configuring host side" | |
| ip addr add "$HOST_IP/24" dev "$VETH_HOST" | |
| ip link set "$VETH_HOST" up | |
| echo "[+] Configuring namespace side" | |
| ip netns exec "$NS" ip addr add "$NS_IP/24" dev "$VETH_NS" | |
| ip netns exec "$NS" ip link set "$VETH_NS" up | |
| ip netns exec "$NS" ip link set lo up | |
| ip netns exec "$NS" ip route add default via "$HOST_IP" | |
| echo "[+] Enabling NAT" | |
| iptables -t nat -A POSTROUTING -s "$SUBNET" -j MASQUERADE | |
| echo "[+] Starting tcpdump → $PCAP" | |
| tcpdump -i "$VETH_HOST" -w "$PCAP" '(tcp or udp) and not multicast' & | |
| TCPDUMP_PID=$! | |
| sleep 0.5 | |
| echo "[+] Running command in namespace" | |
| ip netns exec "$NS" "$@" | |
| sleep 0.5 | |
| kill "$TCPDUMP_PID" | |
| wait "$TCPDUMP_PID" 2>/dev/null || true | |
| echo "[+] Calculating totals..." | |
| TOTAL_BYTES=$(tcpdump -nn -r "$PCAP" 2>/dev/null | \ | |
| awk ' | |
| /length/ { | |
| for (i=1; i<=NF; i++) { | |
| if ($i == "length") { | |
| sum += $(i+1) | |
| } | |
| } | |
| } | |
| END { print sum+0 }' | |
| ) | |
| human() { | |
| local bytes=$1 | |
| if (( bytes > 1024*1024 )); then | |
| printf "%.2f MiB" "$(echo "$bytes / 1024 / 1024" | bc -l)" | |
| elif (( bytes > 1024 )); then | |
| printf "%.2f KiB" "$(echo "$bytes / 1024" | bc -l)" | |
| else | |
| printf "%d B" "$bytes" | |
| fi | |
| } | |
| echo | |
| echo "Traffic summary:" | |
| echo " Packets: $(tcpdump -r "$PCAP" 2>/dev/null | wc -l)" | |
| echo " Total: $(human "$TOTAL_BYTES")" | |
| echo | |
| echo "[+] Capture saved to $PCAP" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment