Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Last updated: Tuesday 10 March 2026 @ 15:12:13

Network Analysis and Evidence Collection

Important

Ensure you have finished the following labs:

In this lab we will build a network analysis script to automate the collection of evidence for your coursework.

Goal

The goal is to capture:

  • interface configuration

  • routing state

  • service status

  • packet captures

  • latency tests

  • throughput tests

This allows you to produce repeatable evidence for your network analysis.


1: Why automate analysis

When analysing a network manually, it is easy to forget commands or overwrite logs.

Automation ensures:

  • repeatable experiments
  • consistent evidence
  • easier troubleshooting
  • easier report writing

The script will collect outputs that support:

  • traffic analysis
  • routing verification
  • performance evaluation
  • troubleshooting

2: Tools used

The script will rely on these common Linux networking tools.

ToolPurpose
ipinspect interfaces and routes
ssinspect sockets
pinglatency and packet loss
tracepath / traceroutepath discovery
iperf3throughput testing
wgetHTTP testing
tcpdumppacket capture

These tools provide enough evidence for protocol analysis and performance evaluation, use man <tool> to find out more.


3: Create the script

  1. Create a scripts directory if needed:

    Terminal

    mkdir -p ~/scripts
    
  2. Create the script file.

    Terminal

    touch ~/scripts/network-analysis.sh
    chmod +x ~/scripts/network-analysis.sh
    
  3. Open the script.

    Terminal

    vim ~/scripts/network-analysis.sh
    
  4. Add the following header.

    Code

    #!/usr/bin/env bash
    set -euo pipefail
    
    BASE_DIR="/home/pi/network-analysis"
    RUN_ID="$(date +%Y%m%d_%H%M%S)"
    RUN_DIR="$BASE_DIR/$RUN_ID"
    
    INTERFACES=("eth0" "wlan0" "wlan1")
    
    die() { echo "error: $*" >&2; exit 1; }
    
    need_root() {
    [[ $EUID -eq 0 ]] || die "run as root"
    }
    

    Explanation

    Strict mode ensures the script exits on errors and avoids undefined variables.

    Each run gets its own timestamped directory for storing evidence.

  5. Create output directories

    Code

    ensure_dirs() {
        mkdir -p "$RUN_DIR"
    }
    
  6. Save command outputs

    Code

    save_cmd() {
        local file="$1"
        shift
    
        {
            echo "command: $*"
            echo "time: $(date)"
            echo
            "$@"
        } > "$file" 2>&1
    }
    

    Explanation

    This helper runs a command and stores both the command and its output in a log file.

  7. Snapshot function

    Code

    snapshot() {
    
        ensure_dirs
    
        save_cmd "$RUN_DIR/ip_addr.txt" ip addr
        save_cmd "$RUN_DIR/ip_route.txt" ip route
        save_cmd "$RUN_DIR/ip_neigh.txt" ip neigh
        save_cmd "$RUN_DIR/ip_link.txt" ip link
        save_cmd "$RUN_DIR/ss.txt" ss -tulpn
    
        echo "Snapshot saved to $RUN_DIR"
    }
    

    Explanation

    This records the current network configuration.

  8. Packet capture controls

    Code

    capture_start() {
    
        ensure_dirs
    
        for iface in "${INTERFACES[@]}"; do
            tcpdump -i "$iface" -nn -w "$RUN_DIR/capture_$iface.pcap" &
            echo $! > "$RUN_DIR/tcpdump_$iface.pid"
        done
    
    }
    

    Code

    capture_stop() {
    
        for iface in "${INTERFACES[@]}"; do
            if [ -f "$RUN_DIR/tcpdump_$iface.pid" ]; then
                kill "$(cat $RUN_DIR/tcpdump_$iface.pid)"
                rm "$RUN_DIR/tcpdump_$iface.pid"
            fi
        done
    
    }
    
  9. Ping test

    Code

    ping_test() {
    
        ensure_dirs
    
        TARGET="$1"
    
        save_cmd "$RUN_DIR/ping_$TARGET.txt" ping -c 10 "$TARGET"
    }
    
  10. Path discovery

    Code

    path_test() {
    
        ensure_dirs
    
        TARGET="$1"
    
        if command -v traceroute >/dev/null; then
            save_cmd "$RUN_DIR/path_$TARGET.txt" traceroute "$TARGET"
        else
            save_cmd "$RUN_DIR/path_$TARGET.txt" tracepath "$TARGET"
        fi
    
    }
    
  11. Throughput testing

    Code

    iperf_test() {
    
        ensure_dirs
    
        TARGET="$1"
    
        save_cmd "$RUN_DIR/iperf_$TARGET.txt" iperf3 -c "$TARGET"
    }
    
  12. HTTP test

    Code

    http_test() {
    
        ensure_dirs
    
        URL="$1"
    
        save_cmd "$RUN_DIR/http_test.txt" wget -O /dev/null "$URL"
    }
    
  13. Usage

    Code

    usage() {
    
    cat <<EOF
    usage: network-analysis <mode>
    
    modes:
    
    snapshot
    capture-start
    capture-stop
    ping-test <target>
    path-test <target>
    iperf-test <target>
    http-test <url>
    
    EOF
    
    }
    
  14. Main entry point

    Code

    main(){
    
        need_root
    
        case "${1:-}" in
    
        snapshot)
            snapshot
        ;;
    
        capture-start)
            capture_start
        ;;
    
        capture-stop)
            capture_stop
        ;;
    
        ping-test)
            ping_test "$2"
        ;;
    
        path-test)
            path_test "$2"
        ;;
    
        iperf-test)
            iperf_test "$2"
        ;;
    
        http-test)
            http_test "$2"
        ;;
    
        *)
            usage
        ;;
    
        esac
    }
    
    main "$@"
    

4: Testing the script

  1. Run the script with no arguments.

    Code

    bash ~/scripts/network-analysis.sh
    
  2. You should see the usage message.

    Output

    usage: network-analysis <mode>
    
    modes:
    
        snapshot
        capture-start
        capture-stop
        ping-test <target>
        path-test <target>
        iperf-test <target>
        http-test <url>
    
  3. Take a snapshot.

    Terminal

    bash ~/scripts/network-analysis.sh snapshot
    ls network-analysis/20260309_132652/
    
    • note the date time stamp will be unique to when you ran it.

    Output

    ip_addr.txt  ip_link.txt  ip_neigh.txt  ip_route.txt  ss.txt
    
  4. Start packet capture.

    Terminal

    sudo bash ~/scripts/network-analysis.sh capture-start
    
  5. Generate traffic.

    Terminal

    bash ~/scripts/network-analysis.sh ping-test 192.168.50.1
    bash ~/scripts/network-analysis.sh iperf-test 192.168.50.1
    bash ~/scripts/network-analysis.sh path-test 8.8.8.8
    
  6. Stop capture.

    Terminal

    sudo bash ~/scripts/network-analysis.sh capture-stop
    
  7. Check for the results

    Terminal

    lsd -lh network-analysis/*/**
    

    Output

    .rw-r--r-- tcpdump tcpdump   0 B  Mon Mar  9 13:28:42 2026  network-analysis/20260309_132842/capture_eth0.pcap
    .rw-r--r-- tcpdump tcpdump 248 KB Mon Mar  9 13:32:13 2026  network-analysis/20260309_132842/capture_wlan0.pcap
    .rw-r--r-- tcpdump tcpdump   0 B  Mon Mar  9 13:28:42 2026  network-analysis/20260309_132842/capture_wlan1.pcap
    .rw-r--r-- root    root    1.1 KB Mon Mar  9 13:26:52 2026  network-analysis/20260309_132652/ip_addr.txt
    .rw-r--r-- root    root    728 B  Mon Mar  9 13:26:52 2026  network-analysis/20260309_132652/ip_link.txt
    .rw-r--r-- root    root    168 B  Mon Mar  9 13:26:52 2026  network-analysis/20260309_132652/ip_neigh.txt
    .rw-r--r-- root    root    267 B  Mon Mar  9 13:26:52 2026  network-analysis/20260309_132652/ip_route.txt
    .rw-r--r-- root    root    134 B  Mon Mar  9 13:31:39 2026  network-analysis/20260309_132924/iperf_192.168.50.1.txt
    .rw-r--r-- root    root    229 B  Mon Mar  9 13:29:18 2026  network-analysis/20260309_132859/ping_192.168.50.1.txt
    .rw-r--r-- root    root    1.2 KB Mon Mar  9 13:26:52 2026  network-analysis/20260309_132652/ss.txt
    .rw-r--r-- root    root      5 B  Mon Mar  9 13:28:42 2026  network-analysis/20260309_132842/tcpdump_eth0.pid
    .rw-r--r-- root    root      5 B  Mon Mar  9 13:28:42 2026  network-analysis/20260309_132842/tcpdump_wlan0.pid
    .rw-r--r-- root    root      5 B  Mon Mar  9 13:28:42 2026  network-analysis/20260309_132842/tcpdump_wlan1.pid
    
  8. Use batcat on the folders or files to check the contents for the logs such as:

  • ip_route.txt

  • ping_*.txt

  • iperf_*.txt

  • capture_eth0.pcap

  • capture_wlan0.pcap

Use these files for your analysis, using GenAI to help you with this is allowed, .

5: Practice

Use the script with the router modes from the previous lab.

For each mode:

  • run snapshot

  • run capture-start

  • generate traffic

  • run capture-stop

Compare the results for:

  • wired vs wireless

  • isolated vs routed networks

  • internet vs local traffic

This will produce the evidence required for your coursework analysis.

6. Full code

Full code

#!/usr/bin/env bash
set -euo pipefail

BASE_DIR="/home/pi/network-analysis"
RUN_ID="$(date +%Y%m%d_%H%M%S)"
RUN_DIR="$BASE_DIR/$RUN_ID"

INTERFACES=("eth0" "wlan0" "wlan1")

die() { echo "error: $*" >&2; exit 1; }
 
need_root() {
    [[ $EUID -eq 0 ]] || die "run as root"
}

ensure_dirs() {
    mkdir -p "$RUN_DIR"
}

save_cmd() {
    local file="$1"
    shift

    {
        echo "command: $*"
        echo "time: $(date)"
        echo
        "$@"
    } > "$file" 2>&1
}
 
snapshot() {

    ensure_dirs

    save_cmd "$RUN_DIR/ip_addr.txt" ip addr
    save_cmd "$RUN_DIR/ip_route.txt" ip route
    save_cmd "$RUN_DIR/ip_neigh.txt" ip neigh
    save_cmd "$RUN_DIR/ip_link.txt" ip link
    save_cmd "$RUN_DIR/ss.txt" ss -tulpn

    echo "Snapshot saved to $RUN_DIR"
}

capture_start() {

    ensure_dirs

    for iface in "${INTERFACES[@]}"; do
        tcpdump -i "$iface" -nn -w "$RUN_DIR/capture_$iface.pcap" &
        echo $! > "$RUN_DIR/tcpdump_$iface.pid"
    done

}
 
capture_stop() {

    for iface in "${INTERFACES[@]}"; do
        if [ -f "$RUN_DIR/tcpdump_$iface.pid" ]; then
            kill "$(cat /tmp/tcpdump_$iface.pid)"
            rm "$RUN_DIR/tcpdump_$iface.pid"
        fi
    done
}

ping_test() {

    ensure_dirs

    TARGET="$1"

    save_cmd "$RUN_DIR/ping_$TARGET.txt" ping -c 10 "$TARGET"
}

path_test() {

    ensure_dirs

    TARGET="$1"

    if command -v traceroute >/dev/null; then
        save_cmd "$RUN_DIR/path_$TARGET.txt" traceroute "$TARGET"
    else
        save_cmd "$RUN_DIR/path_$TARGET.txt" tracepath "$TARGET"
    fi

}

iperf_test() {

    ensure_dirs

    TARGET="$1"

    save_cmd "$RUN_DIR/iperf_$TARGET.txt" iperf3 -c "$TARGET"
}

http_test() {

    ensure_dirs

    URL="$1"

    save_cmd "$RUN_DIR/http_test.txt" wget -O /dev/null "$URL"
}

usage() {

cat <<EOF
usage: network-analysis <mode>

modes:

    snapshot
    capture-start
    capture-stop
    ping-test <target>
    path-test <target>
    iperf-test <target>
    http-test <url>

EOF

}

main() {

    need_root

    case "${1:-}" in

    snapshot)
        snapshot
    ;;

    capture-start)
        capture_start
    ;;

    capture-stop)
        capture_stop
    ;;

    ping-test)
        ping_test "$2"
    ;;

    path-test)
        path_test "$2"
    ;;

    iperf-test)
        iperf_test "$2"
    ;;

    http-test)
        http_test "$2"
    ;;

    *)
        usage
    ;;

    esac
}

main "$@"