#!/bin/ksh # @(#) Multi ping #..# systems: #..# sites: #..# level: #..# publish: y #..# keys: #..# date: Fri Oct 1 08:34:50 BST 1999 #..# vers: 1.3 04/Aug/2006-08:40 tag=${0##*/} tm=/tmp/${tag} tmp=${tm}$$ rm -rf ${tm}* [ $0 = ${0#/} ] && this=$(pwd -H)/$0 || this=$0 usage="Usage: $tag [-l] [-] - $tag [-l] -sfx" typeset -u rng while [ $# -gt 0 ]; do case "$1" in -v|-x) set "$1" ;; -vi) lockvi $this; exit ;; -view) view $0; exit ;; -about) echo "$tag was written by David Ledger" echo "dledger@ivdcs.co.uk" echo "Free to use at your own risk" echo "Copyright 2004" exit ;; -ver) ver=$(egrep '#..#[ ]*vers:' $this) ver=${ver#"${ver%%[1-9]*}"} print ${ver%%[!0-9.]*} exit ;; -h) $tag --h | ${PAGER-more}; exit ;; --h) echo "$usage" echo "" echo "$tag takes an argument which is an IP network address or" echo "a range specified by two IP host addresses seperated by a" echo "'-' sign. It pings all addresses on that network or in" echo "that range, but does so with a limit of pings active" echo "at once so as to avoid heavy net traffic. defaults" echo "to 10" echo "" echo "The pings are limited to 2 packets. A response is" echo "translated into 'is alive', and a timeout to 'is missing'" echo "" echo "If '-f ' is supplied, a list of responding IP" echo "addresses (or hostnames - see below) is written to" echo ". No validity check is done on ." echo "" echo "" echo "$tag can also be used on hostnames that consist of a" echo "leading alpha string with a trailing numeric component" echo "such as host1, host2, host99, etc. These must be entered" echo "as - eg:" echo "host1-99. Derived hostnames in the range that are not" echo "known by 'nslookup' are silently ignored." echo "If '-f ' is supplied, the names of responding" echo "hosts is written to rather than IP addresses." echo "" echo "This will also work for hostnames with a single embedded" echo "numeric string. Range host1uk to host9uk would be" echo "specified as:" echo "host1-9uk" echo "" echo "Both hostname formats work with fixed or variable width" echo "numeric fields." echo "host1-20 tests hosts host1, host2 ... host9, host10 ..." echo "host20" echo "host01-20 tests hosts host01, host02 ... host09, host10" echo "... host20" echo "host001-100 tests hosts host001, host002 ... host009," echo "host010 ... host099, host100" echo "host01-100 and similar will probably truncate the 100 to" echo "two digits." echo "" echo "If the numeric part of hostnames in in hex rather than" echo "decimal, it may be preceeded by a ':' to mark the" echo "end of the prefix. The presence of a ':' triggers hex" echo "arithmetic increments." echo "Leading '0' preservation is not guaranteed in hex." echo "" exit ;; -f) shift || exit f="$1" ;; -q[0-9]) q=${1#-q} ;; -l[1-9]*) expr "$1" : '-l[0-9][0-9]*' >/dev/null || exit lim=${1#-l} ;; -zz[0-9]*) zz=`expr "$1" : '-zz\([0-9]*\)'` [ "$zz" ] || { print -u2 "?? $1 ??"; exit; } ;; [0-9]*) set -A N `echo "$1" | sed 's/\./ /g;s/-/ - /'` # print -u2 ${#N[*]} i=0; while [ $i -lt ${#N[*]} ]; do [ ${N[$i]} = "-" ] && break i=$((i + 1)) done # print -u2 $i if [ ${#N[*]} -gt $((i \* 2 + 1)) ]; then print -u2 "$usage" print -u2 "bad address range format" exit elif [ $i -eq ${#N[*]} ]; then M[0]=${N[0]} [ $i -gt 1 ] && M[1]=${N[1]} [ $i -gt 2 ] && M[2]=${N[2]} [ $i -gt 3 ] && M[3]=${N[3]} else set -A M ${N[*]} j=$((${#N[*]} - 1)) k=$((i - 1)) while [ $j -gt $i ]; do M[$k]=${N[$j]} N[$j]=""; M[$j]="" j=$((j - 1)) k=$((k - 1)) done N[$i]=""; M[$i]="" fi # print -u2 ${N[*]} # print -u2 ${M[*]} #print -u2 ${a}.${b}.${c}.${d} - ${e}.${f}.${g}.${h} byip=y ;; +([a-z_A-Z])+([0-9])-+([0-9])) pfx=${1%%[0-9]*} rng=${1##*[a-z_A-Z]} sfx="" byname=y ;; +([a-z_A-Z])+([0-9])-+([0-9])+([a-z_A-Z])) pfx=${1%%[0-9]*} sfx=${1##*[0-9]} rng=${1#$pfx} rng=${rng%$sfx} byname=y ;; +([a-z_A-Z0-9]):+([a-z0-9])-+([a-z0-9])) pfx=${1%:*} rng=${1#*:} sfx="" hexin="16i"; hexout="10o" typeset -l h byname=y ;; +([a-z_A-Z0-9]):+([A-Z0-9])-+([zA-Z0-9])) pfx=${1%:*} rng=${1#*:} sfx="" hexin="16i"; hexout="10o" typeset -u h byname=y ;; -) stdin=y ;; *) flgs="$(echo $- | sed 's/h//;s/./-& /g')" echo $* | $tag $flgs -q$q - exit ;; esac shift done set -A uname $(uname -a) case "$uname" in HP-UX) png() { ping $1 -n 2; } ;; SunOS) png() { ping -s $1 2; } ;; esac : ${hexin=""} : ${hexout=""} : ${q=8} mkdir $tmp || exit cleanup() { (sleep 120; rm -rf $tmp) & } trap cleanup 0 : ${zz=5} : ${lim=10} # print -u2 ${N[*]} # print -u2 ${M[*]} if [ "$stdin" ]; then while read h; do set $h for h in $*; do nslookup $h 2>/dev/null | awk ' $1 == "Name:" { ok++; next } $1 == "Address:" { ok *= 2 } END { exit (ok - 2) } '|| { [ $q -lt 8 ] && print -u2 "$h not in DNS" continue; } ( touch $tmp/$h s="$(png $h)" expr "$s" : '.*100% packet loss.*' >/dev/null && print -u2 $h is missing || { [ $f ] && echo $h >> $f print -u2 $h is alive; } rm -f $tmp/$h ) & while [ "`ls $tmp | wc -l`" -ge $lim ]; do sleep $zz done done done while [ "`ls $tmp | wc -l`" -gt 0 ]; do sleep $zz done exit fi if [ "$byname" ]; then x=${rng%-*} y=${rng#*-} [ "${x#0}" != "$x" ] && dig=$(expr "$x" : '.*') #while [ $x -le $y ]; do while [ $(echo "$hexin $y $x -p" | dc) -ge 0 ]; do [ ${dig-0} -gt 0 ] && { [ "$hexin" ] && h=$(printf "%s%0${dig}s%s" $pfx $x $sfx) || h=$(printf "%s%0${dig}d%s" $pfx $x $sfx) } || h=$pfx$x$sfx nslookup $h 2>/dev/null | awk ' $1 == "Name:" { ok++; next } $1 == "Address:" { ok *= 2 } END { exit (ok - 2) } '|| { [ $q -lt 8 ] && print -u2 "$h not in DNS" x=$(echo "$hexin $hexout $x 1+p" | dc) continue; } ( touch $tmp/$h s="$(png $h)" expr "$s" : '.*100% packet loss.*' >/dev/null && print -u2 $h is missing || { [ $f ] && echo $h >> $f print -u2 $h is alive; } rm -f $tmp/$h ) & while [ "`ls $tmp | wc -l`" -ge $lim ]; do sleep $zz done #x=$((x + 1)) x=$(echo "$hexin $hexout $x 1+p" | dc) done while [ "`ls $tmp | wc -l`" -gt 0 ]; do sleep $zz done exit fi [ "$byip" ] || exit w=${N[0]-1} while [ $w -le ${M[0]-254} ]; do x=${N[1]=1} while [ $x -le ${M[1]-254} ]; do y=${N[2]=1} while [ $y -le ${M[2]-254} ]; do z=${N[3]=1} while [ $z -le ${M[3]-254} ]; do n=${w}.${x}.${y}.${z} ( touch $tmp/$n s="$(png $n)" expr "$s" : '.*100% packet loss.*' >/dev/null && print -u2 $n is missing || { [ $f ] && echo $n >> $f print -u2 $n is alive; } rm -f $tmp/$n ) & while [ "`ls $tmp | wc -l`" -ge $lim ]; do sleep $zz done #printf "%d.%d.%d.%d\n" $w $x $y $z z=$((z + 1)) done y=$((y + 1)) done x=$((x + 1)) done w=$((w + 1)) done while [ "`ls $tmp | wc -l`" -gt 0 ]; do sleep $zz done