#!/bin/sh #Ping Radar : ping a list of hosts and display response time #Copyright (C) 2016 Weber Yann # #This program is free software; you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation; either version 3 of the License, or #any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program. If not, see . alias echo='/bin/echo -e' REFRESH=2 verbose=0 res_file=$(mktemp -t hosts_scanner.XXXXXXXXXX) date_cmd="date --rfc-3339=s" lock="${res_file}.lock" pids="" clean_exit() { clear reset echo "Ctrl+C pressed, exiting..." for pid in $(echo $pids) do echo killing $pid kill $pid 2>/dev/null done wait $(echo $pids) rmdir ${res_file}.lock 2>/dev/null rm -v $res_file exit 0 } cidr_nmap_pid="" cidr_nmap_res="" cidr_pids="" clean_cidr() { echo "CIDR killed, cleaning..." kill $cidr_nmap_pid 2>/dev/null for pid in $(echo $cidr_pids $cidr_nmap_pid) do echo CIDR killing $pid kill $pid 2>/dev/null done wait $(echo $cidr_pids $cidr_nmap_pid) rm -v $cidr_nmap_res exit 0 } semlock() { while [ 1 ] do mkdir $1 2>/dev/null && break done } semrelease() { rmdir $1 } upd_ping() { # update ping stat file # $1 host # $2 file # $3 lock # $4 delay lock="$3" test -z "$4" && delay=5 || delay=$4 last_up="never" while [ 1 ] do rep=$(ping -qc 1 $1 2>/dev/null ) ret=$? rep=$(echo $rep | sed -nE 's/.*rtt min\/avg\/max\/mdev = [0-9]+\.[0-9]+\/([0-9]+\.[0-9]+)\/.*$/\1/p') rehost=$(echo $h|sed 's/\./\\./g') semlock $lock if [ $ret -eq 0 ] then last_up=$($date_cmd) #echo "${res}$rep $hstr $last_up" >> $2 else rep="down" #echo "${res}down $hstr $last_up" >> $2 fi sed -i "s/^\\s*$rehost\\s.*$/$(printf "%30s %8s %30s\n" $1 $rep "$last_up")/" "$2" semrelease $lock sleep $delay done } cidr_scan() { # cidr ping scan # $1 cidr # $2 result file # $3 lock # $4 delay test -z "$4" && delay=5 || delay=$4 cidr_nmap_res=$(mktemp -t ping_radar_cidr_nmap.XXXXXXXX) nmap_cmd="nmap -sP -oG $cidr_nmap_res --max-rate=15 --max-hostgroup=5 $1" trap clean_cidr 15 #nmap -sP -oG "$cidr_nmap_res" $1 >/dev/null & $nmap_cmd >/dev/null & cidr_nmap_pid=$! while [ 1 ] do if kill -0 $cidr_nmap_pid 2> /dev/null then semlock $lock echo "CIDR scanning $1" >&2 semrelease $lock rerun=0 else semlock $lock echo "CIDR scanned $1" >&2 semrelease $lock rerun=1 fi for h in $(cat $cidr_nmap_res | grep "Up$" | cut -d " " -f 2) do rehost=$(echo $h|sed 's/\./\\./g') if grep " $rehost " $2 > /dev/null then continue else printf "%30s %8s %30s\n" $h "unknw" "unknwn" >> $res_file upd_ping $h $2 $3 & pid=$! cidr_pids="${cidr_pids}\n$pid" semlock $lock echo "$pid scanning $h" >&2 semrelease $lock fi done sleep $delay if [ $rerun -eq 1 ] then $nmap_cmd >/dev/null & cidr_nmap_pid=$! fi done } usage() { echo "Usage : $0 [-c CONFIG_FILE] [-i HOST [-i HOST [...]]]" >&2 } while getopts c:i: o do case $o in c) HOSTS_FILES="$OPTARG";; *) usage; exit 1;; esac done if [ -z "$HOSTS_FILES" ] then HOSTS_FILES="$HOME/.hosts_scanner" fi if [ ! -f "$HOSTS_FILES" ] then echo "File '$HOSTS_FILES' not found" >&4 usage exit 2 fi trap clean_exit 2 # prepopulate file for h in $(cat "$HOSTS_FILES") do if echo $h |grep -v '/' > /dev/null then printf "%30s %8s %30s\n" $h "unknw" "unknwn" >> $res_file fi done # run scanners for h in $(cat "$HOSTS_FILES" ) do if echo $h |grep -v '/' > /dev/null then upd_ping $h $res_file $lock 5 & else # cidr scan cidr_scan $h $res_file $lock 10 & fi pid=$! pids="${pids}\n$pid" echo "$h updated by $pid" >&2 done sleep 1 loop_count=0 while [ 1 ] do #sleep 1 #continue semlock $lock #clear loop_count=$(expr $loop_count + 1) if [ $loop_count = "5" ] then clear; loop_count=0 fi echo -e "\x1B[0;0HPing radar $($date_cmd)\n$(printf "%30s %8s %30s\n" "host" "ping" "last up")\n$(for i in $(seq 70); do echo -n "="; done)\n$(sed -E -e "s/\snever$/$(tput sgr0)\0/" -e "s/^.* down .*$/$(tput setaf 1)\0$(tput sgr0)/" $res_file)" # echo "Ping radar $($date_cmd)\n" # printf "%30s %8s %30s\n" "host" "ping" "last up" # for i in $(seq 70); do echo -n "="; done # echo "" # # #cat $res_file # # #grep -v " down " $res_file # #grep " down " $res_file # # sed -E -e "s/\snever$/$(tput sgr0)\0/" -e "s/^.* down .*$/$(tput setaf 1)\0$(tput sgr0)/" $res_file semrelease $lock sleep $REFRESH done