Advanced Usage and Scripting (Part 3 of 4)

1. Advanced NetworkManager Scripting

1.1 Connection Management Scripts

Automated Connection Setup

Script: setup-network.sh
#!/bin/bash
# Automated network setup with validation

CONNECTION_NAME="Production-Eth"
INTERFACE="eth0"
IP_ADDRESS="192.168.1.100/24"
GATEWAY="192.168.1.1"
DNS_SERVERS="8.8.8.8,8.8.4.4,1.1.1.1"
DNS_SEARCH="company.local"

# Function to check if NetworkManager is running
check_nm_running() {
    if ! systemctl is-active --quiet NetworkManager; then
        echo "Error: NetworkManager is not running"
        exit 1
    fi
}

# Function to check if interface exists
check_interface() {
    if ! nmcli device status | grep -q "^$INTERFACE"; then
        echo "Error: Interface $INTERFACE not found"
        exit 1
    fi
}

# Function to create or update connection
setup_connection() {
    if nmcli connection show "$CONNECTION_NAME" &>/dev/null; then
        echo "Connection '$CONNECTION_NAME' exists. Updating..."
        nmcli connection modify "$CONNECTION_NAME" \
            ipv4.method manual \
            ipv4.addresses "$IP_ADDRESS" \
            ipv4.gateway "$GATEWAY" \
            ipv4.dns "$DNS_SERVERS" \
            ipv4.dns-search "$DNS_SEARCH" \
            connection.autoconnect yes \
            connection.autoconnect-priority 10
    else
        echo "Creating new connection '$CONNECTION_NAME'..."
        nmcli connection add \
            type ethernet \
            con-name "$CONNECTION_NAME" \
            ifname "$INTERFACE" \
            ipv4.method manual \
            ipv4.addresses "$IP_ADDRESS" \
            ipv4.gateway "$GATEWAY" \
            ipv4.dns "$DNS_SERVERS" \
            ipv4.dns-search "$DNS_SEARCH" \
            connection.autoconnect yes \
            connection.autoconnect-priority 10
    fi
}

# Function to activate connection
activate_connection() {
    echo "Activating connection..."
    if nmcli connection up "$CONNECTION_NAME"; then
        echo "Connection activated successfully"
    else
        echo "Error: Failed to activate connection"
        exit 1
    fi
}

# Function to verify connectivity
verify_connectivity() {
    echo "Verifying connectivity..."
    
    # Check IP configuration
    IP=$(nmcli -t -f IP4.ADDRESS device show "$INTERFACE" | cut -d: -f2)
    echo "IP Address: $IP"
    
    # Ping gateway
    if ping -c 3 -W 2 "$GATEWAY" &>/dev/null; then
        echo "Gateway reachable: $GATEWAY"
    else
        echo "Warning: Cannot reach gateway"
    fi
    
    # Check DNS
    if ping -c 3 -W 2 8.8.8.8 &>/dev/null; then
        echo "Internet connectivity: OK"
    else
        echo "Warning: No internet connectivity"
    fi
}

# Main execution
main() {
    echo "=== Network Setup Script ==="
    check_nm_running
    check_interface
    setup_connection
    activate_connection
    verify_connectivity
    echo "=== Setup Complete ==="
}

main

Multi-Environment Network Switcher

Script: network-switch.sh
#!/bin/bash
# Switch between different network environments

OFFICE_CONN="Office-Network"
HOME_CONN="Home-Network"
VPN_CONN="Corporate-VPN"

# Function to show current connection
show_current() {
    echo "Currently active connections:"
    nmcli -t -f NAME,DEVICE connection show --active
}

# Function to switch to office network
switch_office() {
    echo "Switching to office network..."
    nmcli connection down "$HOME_CONN" 2>/dev/null
    nmcli connection down "$VPN_CONN" 2>/dev/null
    nmcli connection up "$OFFICE_CONN"
    
    # Set office-specific settings
    nmcli connection modify "$OFFICE_CONN" \
        ipv4.dns "192.168.1.1" \
        ipv4.dns-search "office.company.local"
}

# Function to switch to home network
switch_home() {
    echo "Switching to home network..."
    nmcli connection down "$OFFICE_CONN" 2>/dev/null
    nmcli connection down "$VPN_CONN" 2>/dev/null
    nmcli connection up "$HOME_CONN"
}

# Function to enable VPN
enable_vpn() {
    echo "Enabling VPN..."
    nmcli connection up "$VPN_CONN"
}

# Main menu
case "${1:-}" in
    office)
        switch_office
        ;;
    home)
        switch_home
        ;;
    vpn)
        enable_vpn
        ;;
    status)
        show_current
        ;;
    *)
        echo "Usage: $0 {office|home|vpn|status}"
        exit 1
        ;;
esac

1.2 Network Monitoring Scripts

Connection Monitor

#!/bin/bash
# Monitor network connections and log changes

LOG_FILE="/var/log/network-monitor.log"
CHECK_INTERVAL=10  # seconds

log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

get_active_connections() {
    nmcli -t -f NAME connection show --active | sort
}

# Initial state
PREVIOUS_STATE=$(get_active_connections)
log_message "Network monitoring started"

while true; do
    sleep "$CHECK_INTERVAL"
    
    CURRENT_STATE=$(get_active_connections)
    
    if [ "$CURRENT_STATE" != "$PREVIOUS_STATE" ]; then
        log_message "Network state changed"
        log_message "Previous: $PREVIOUS_STATE"
        log_message "Current:  $CURRENT_STATE"
        
        # Get detailed information about changes
        nmcli connection show --active | while read line; do
            log_message "  $line"
        done
        
        PREVIOUS_STATE="$CURRENT_STATE"
    fi
done

Bandwidth and Connection Stats

#!/bin/bash
# Display network statistics

INTERFACE="${1:-eth0}"

# Get current statistics
get_stats() {
    nmcli -f GENERAL,IP4,IP6 device show "$INTERFACE"
    
    echo ""
    echo "=== Traffic Statistics ==="
    
    RX_BYTES=$(cat /sys/class/net/"$INTERFACE"/statistics/rx_bytes)
    TX_BYTES=$(cat /sys/class/net/"$INTERFACE"/statistics/tx_bytes)
    
    RX_MB=$((RX_BYTES / 1024 / 1024))
    TX_MB=$((TX_BYTES / 1024 / 1024))
    
    echo "Received: ${RX_MB} MB"
    echo "Transmitted: ${TX_MB} MB"
    
    echo ""
    echo "=== Active Connections ==="
    nmcli connection show --active
}

get_stats

2. Advanced nm Symbol Analysis

2.1 Symbol Analysis Scripts

Comprehensive Symbol Report

Script: symbol-report.sh
#!/bin/bash
# Generate comprehensive symbol report for a binary

if [ $# -ne 1 ]; then
    echo "Usage: $0 <binary-file>"
    exit 1
fi

BINARY="$1"

if [ ! -f "$BINARY" ]; then
    echo "Error: File not found: $BINARY"
    exit 1
fi

echo "============================================"
echo "Symbol Analysis Report"
echo "File: $BINARY"
echo "Date: $(date)"
echo "============================================"

# File information
echo ""
echo "=== File Information ==="
file "$BINARY"

# Check if stripped
if nm "$BINARY" &>/dev/null; then
    echo "Status: Contains symbols"
else
    echo "Status: Stripped (no symbols)"
    exit 0
fi

# Count symbols by type
echo ""
echo "=== Symbol Counts ==="
echo "Total symbols: $(nm "$BINARY" | wc -l)"
echo "Functions (T): $(nm "$BINARY" | grep -c " T ")"
echo "Static functions (t): $(nm "$BINARY" | grep -c " t ")"
echo "Global variables (D): $(nm "$BINARY" | grep -c " D ")"
echo "Static variables (d): $(nm "$BINARY" | grep -c " d ")"
echo "BSS variables (B/b): $(nm "$BINARY" | grep -c " [Bb] ")"
echo "Undefined (U): $(nm -u "$BINARY" | wc -l)"

# Largest symbols
echo ""
echo "=== Top 10 Largest Symbols ==="
nm --size-sort -S "$BINARY" 2>/dev/null | tail -10

# Undefined symbols (dependencies)
echo ""
echo "=== External Dependencies (Undefined Symbols) ==="
UNDEFINED=$(nm -u "$BINARY" | wc -l)
if [ "$UNDEFINED" -gt 0 ]; then
    echo "Count: $UNDEFINED"
    nm -u "$BINARY" | head -20
    if [ "$UNDEFINED" -gt 20 ]; then
        echo "... and $((UNDEFINED - 20)) more"
    fi
else
    echo "No undefined symbols"
fi

# Dynamic symbols (for shared libraries)
if nm -D "$BINARY" &>/dev/null; then
    echo ""
    echo "=== Dynamic Symbols ==="
    echo "Count: $(nm -D "$BINARY" | wc -l)"
    echo "Exported functions: $(nm -D "$BINARY" | grep -c " T ")"
fi

echo ""
echo "============================================"
echo "Report Complete"
echo "============================================"

Library Dependency Analyzer

Script: analyze-deps.sh
#!/bin/bash
# Analyze library dependencies and symbol resolution

BINARY="$1"

if [ -z "$BINARY" ]; then
    echo "Usage: $0 <binary>"
    exit 1
fi

echo "=== Analyzing: $BINARY ==="
echo ""

# Get undefined symbols
echo "Finding undefined symbols..."
UNDEFINED=$(nm -u "$BINARY" 2>/dev/null | awk '{print $2}')

if [ -z "$UNDEFINED" ]; then
    echo "No undefined symbols found"
    exit 0
fi

# Get library dependencies
echo ""
echo "=== Library Dependencies ==="
LIBS=$(ldd "$BINARY" | grep "=>" | awk '{print $3}')
echo "$LIBS"

echo ""
echo "=== Symbol Resolution ==="

# Check where each undefined symbol is defined
for symbol in $UNDEFINED; do
    echo -n "Checking: $symbol ... "
    
    FOUND=0
    for lib in $LIBS; do
        if [ -f "$lib" ] && nm -D "$lib" 2>/dev/null | grep -q " T $symbol"; then
            echo "Found in: $(basename "$lib")"
            FOUND=1
            break
        fi
    done
    
    if [ $FOUND -eq 0 ]; then
        echo "NOT FOUND - Potential link error!"
    fi
done

2.2 Cross-Reference Tools

Find Symbol Across Multiple Libraries

#!/bin/bash
# Search for a symbol across all system libraries

SYMBOL="$1"
LIB_DIR="/usr/lib/x86_64-linux-gnu"

if [ -z "$SYMBOL" ]; then
    echo "Usage: $0 <symbol-name>"
    exit 1
fi

echo "Searching for symbol: $SYMBOL"
echo "In directory: $LIB_DIR"
echo ""

FOUND=0

for lib in "$LIB_DIR"/*.so*; do
    if [ -f "$lib" ]; then
        if nm -D "$lib" 2>/dev/null | grep -q " [TtDd] $SYMBOL\$"; then
            echo "Found in: $lib"
            nm -D "$lib" | grep " [TtDd] $SYMBOL\$"
            echo ""
            FOUND=1
        fi
    fi
done

if [ $FOUND -eq 0 ]; then
    echo "Symbol not found in any library"
fi

Symbol Conflict Detector

#!/bin/bash
# Detect symbol conflicts in object files

echo "=== Symbol Conflict Detection ==="
echo ""

# Get all global symbols from all object files
ALL_SYMBOLS=$(nm -g *.o 2>/dev/null | grep " T " | awk '{print $3}' | sort)

# Find duplicates
DUPLICATES=$(echo "$ALL_SYMBOLS" | uniq -d)

if [ -z "$DUPLICATES" ]; then
    echo "No duplicate symbols found"
    exit 0
fi

echo "Found duplicate symbols:"
echo ""

for symbol in $DUPLICATES; do
    echo "Conflict: $symbol"
    echo "  Defined in:"
    nm -A *.o 2>/dev/null | grep " T $symbol\$" | awk '{print "    " $1}'
    echo ""
done

3. Integration Scripts

3.1 Network-Aware Build System

#!/bin/bash
# Build script that checks network before downloading dependencies

check_network() {
    echo "Checking network connectivity..."
    
    # Check if NetworkManager is running
    if ! systemctl is-active --quiet NetworkManager; then
        echo "Error: NetworkManager not running"
        return 1
    fi
    
    # Check for active connection
    ACTIVE=$(nmcli -t -f STATE connection show --active)
    if [ -z "$ACTIVE" ]; then
        echo "Error: No active network connection"
        return 1
    fi
    
    # Test internet connectivity
    if ! ping -c 1 -W 2 8.8.8.8 &>/dev/null; then
        echo "Error: No internet connectivity"
        return 1
    fi
    
    echo "Network: OK"
    return 0
}

build_project() {
    echo "Starting build..."
    
    # Your build commands here
    make clean
    make -j$(nproc)
    
    # Analyze resulting binary
    if [ -f ./output/myprogram ]; then
        echo ""
        echo "=== Binary Analysis ==="
        nm --size-sort -S ./output/myprogram | tail -10
    fi
}

# Main
if check_network; then
    build_project
else
    echo "Build aborted: Network issues"
    exit 1
fi

3.2 Automated Testing Framework

#!/bin/bash
# Test suite for network applications

TEST_CONNECTIONS=("Test-LAN" "Test-WAN")
TEST_BINARY="./network_app"

setup_test_env() {
    local conn_name="$1"
    echo "Setting up test environment: $conn_name"
    nmcli connection up "$conn_name"
    sleep 2
}

cleanup_test_env() {
    local conn_name="$1"
    echo "Cleaning up: $conn_name"
    nmcli connection down "$conn_name"
}

check_binary_deps() {
    echo "Checking binary dependencies..."
    
    MISSING=0
    for symbol in $(nm -u "$TEST_BINARY" | awk '{print $2}'); do
        if ! nm -D /usr/lib/*.so 2>/dev/null | grep -q " T $symbol"; then
            echo "  Missing: $symbol"
            MISSING=1
        fi
    done
    
    return $MISSING
}

run_tests() {
    local conn_name="$1"
    
    echo "Running tests with $conn_name..."
    
    # Add your test commands here
    if "$TEST_BINARY" --test; then
        echo "  Tests passed"
        return 0
    else
        echo "  Tests failed"
        return 1
    fi
}

# Main test loop
echo "=== Network Application Test Suite ==="

# Check binary first
if ! check_binary_deps; then
    echo "Error: Missing dependencies"
    exit 1
fi

FAILED=0

for conn in "${TEST_CONNECTIONS[@]}"; do
    setup_test_env "$conn"
    
    if ! run_tests "$conn"; then
        FAILED=1
    fi
    
    cleanup_test_env "$conn"
    echo ""
done

if [ $FAILED -eq 0 ]; then
    echo "All tests passed"
    exit 0
else
    echo "Some tests failed"
    exit 1
fi

4. Automation and Cron Jobs

4.1 Scheduled Network Checks

#!/bin/bash
# Cron job for network health monitoring
# Add to crontab: */5 * * * * /usr/local/bin/network-health.sh

LOG="/var/log/network-health.log"

check_and_log() {
    {
        echo "=== Check at $(date) ==="
        
        # Check active connections
        ACTIVE=$(nmcli -t -f NAME connection show --active | wc -l)
        echo "Active connections: $ACTIVE"
        
        # Test connectivity
        if ping -c 1 -W 2 8.8.8.8 &>/dev/null; then
            echo "Internet: OK"
        else
            echo "Internet: FAILED"
            # Attempt recovery
            nmcli networking off
            sleep 2
            nmcli networking on
        fi
        
        echo ""
    } >> "$LOG"
}

check_and_log

# Rotate log if too large
if [ -f "$LOG" ] && [ $(stat -f%z "$LOG" 2>/dev/null || stat -c%s "$LOG") -gt 1048576 ]; then
    mv "$LOG" "$LOG.old"
fi

4.2 Automated Symbol Auditing

#!/bin/bash
# Daily audit of system binaries
# Add to crontab: 0 2 * * * /usr/local/bin/symbol-audit.sh

AUDIT_DIR="/usr/local/bin"
REPORT="/var/log/symbol-audit-$(date +%Y%m%d).log"

{
    echo "=== Symbol Audit Report ==="
    echo "Date: $(date)"
    echo "Directory: $AUDIT_DIR"
    echo ""
    
    for binary in "$AUDIT_DIR"/*; do
        if [ -x "$binary" ] && file "$binary" | grep -q "ELF"; then
            echo "Checking: $(basename "$binary")"
            
            # Check if stripped
            if nm "$binary" &>/dev/null; then
                SYMBOLS=$(nm "$binary" | wc -l)
                UNDEFINED=$(nm -u "$binary" | wc -l)
                echo "  Symbols: $SYMBOLS, Undefined: $UNDEFINED"
            else
                echo "  Status: Stripped"
            fi
            echo ""
        fi
    done
    
    echo "=== Audit Complete ==="
} > "$REPORT"

# Keep only last 7 days of reports
find /var/log -name "symbol-audit-*.log" -mtime +7 -delete

5. Next Steps

Continue to Part 4 for troubleshooting and best practices.

← Back to NetworkManager Index ↑ Back to EXPANDED