#!/bin/bash # $HeadURL$ $LastChangedRevision$ # Modules . $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; } # Configurable stuff # Other globals main() { local MY_ARGS # Defaults for options OPT_TIMEOUT=5 # Process options special_opts_handler() { case $1 in --timeout=*) OPT_TIMEOUT=${1#*=} ;; *) return 1 ;; esac } miniade_process_options --help-handler=help --special-opts-handler=special_opts_handler MY_ARGS "$@" && set -- "${MY_ARGS[@]}" # Process arguments [ $# -ge 1 ] || miniade_bad_usage # Guts OK=true for CMDLINE_ARG in "$@"; do case $CMDLINE_ARG in gateway) check_hostnames $(ip -4 -o route | sed -nr 's/default via (.*) dev .*/\1/p') || OK=false ;; internet) check_hostnames 8.8.8.8 || OK=false ;; repos) check_urls $(sed -nr 's/^deb ([^ ]+?:\/\/[^ /]+).*/\1/p' /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null | sort -u | paste -d' ' -s) || OK=false ;; *) check_hostnames_or_urls $CMDLINE_ARG || OK=false ;; esac done $OK || miniade_error "$CMDLINE_ARG: not reachable or resolution problem (depending how caller handles this, it may be okay)" } help() { local PROGNAME miniade_get_progname PROGNAME echo "Usage: $PROGNAME [ ] [ --timeout= ] { gateway | repos | internet | } ...>" exit 0 } check_hostnames() { local TARGET_HOSTNAME TARGET_HOSTNAMES STOP_TIMESTAMP NOW_TIMESTAMP TARGET_HOSTNAMES=( "$@" ) for TARGET_HOSTNAME in "${TARGET_HOSTNAMES[@]}"; do miniade_debug 10 "check_hostnames: $TARGET_HOSTNAME: checking ..." STOP_TIMESTAMP=$(($(date +%s) + $OPT_TIMEOUT)) while :; do NOW_TIMESTAMP=$(date +%s) miniade_debug 10 "check_hostnames: NOW_TIMESTAMP=$NOW_TIMESTAMP, STOP_TIMESTAMP=$STOP_TIMESTAMP" # depending which ping we're using, subsecond waits may not be possible. if ping -c 1 -w 1 $TARGET_HOSTNAME > /dev/null 2>/dev/null; then break fi if (($NOW_TIMESTAMP >= $STOP_TIMESTAMP)); then return 1 fi done done } check_urls() { local TARGET_URL TARGET_URLS TARGET_PROTOCOL TARGET_HOSTNAME TARGET_URLS=( "$@" ) [ -w / ] || miniade_error "testing URLs requires root! (because 'nmap -sS' requires root)" for TARGET_URL in "${TARGET_URLS[@]}"; do miniade_debug 10 "check_urls: $TARGET_URL: checking ..." [[ $TARGET_URL =~ (http|https|ftp)://([^/]+)(/.*)? ]] || miniade_internal "check_urls: $TARGET_URL: invalid/unsupported URL" TARGET_PROTOCOL=${BASH_REMATCH[1]} TARGET_HOSTNAME=${BASH_REMATCH[2]} TARGET_PATH=${BASH_REMATCH[3]} miniade_debug 10 "check_urls: TARGET_PROTOCOL=$TARGET_PROTOCOL, TARGET_HOSTNAME=$TARGET_HOSTNAME, TARGET_PATH=$TARGET_PATH" NMAP_CMDLINE="nmap -sS -p $TARGET_PROTOCOL $TARGET_HOSTNAME" miniade_debug 10 "check_urls: calling [$NMAP_CMDLINE] ..." NMAP_OUTPUT=$(eval "$NMAP_CMDLINE" 2>&1) || true if ! [[ $NMAP_OUTPUT =~ open ]]; then miniade_warning "nmap failed (command was '$NMAP_CMDLINE', output was '$NMAP_OUTPUT')" return 1 fi done } check_hostnames_or_urls() { local TARGET_THINGS TARGET_THING TARGET_THINGS=( "$@" ) for TARGET_THING in "${TARGET_THINGS[@]}"; do miniade_debug 10 "check_hostnames_or_urls: TARGET_THING=$TARGET_THING" if [[ $TARGET_THING =~ :// ]]; then check_urls $TARGET_THING || return 1 else check_hostnames $TARGET_THING || return 1 fi done } main "$@"