#!/bin/sh ######################################### ## Test an IP or domain name for web service, return false if connection(s) fail ## Usage: poke [-av] target[:port] [target[:port] ...] ## -a Report all failures instead of quitting after first (takes longer) ## -v Verbose mode. Reports success or failure (only first failure) ## -2 Run again after 30s and report only target(s) that fail twice ## target Any IP address or domain name, like 192.168.0.1 or www.google.com ## port Check connections on specified port instead of 80 (www) ## ## poke 0.8, (c) 2007-8 by Adam Katz , LGPL v2+ ######################################### ### poke changelog ### 0.8 (2008-05-08) - netcat (nc) is simpler, better, more reliable than nmap say=true ALL() { false; } filter() { echo "$*"; } if type nc >/dev/null 2>&1 then poker() { nc -z -w1 "$1" $2 >/dev/null 2>&1; } # test port w/ 1 sec timeout else # nmap with timeouts (version 4+) is awesome! ... 1s is unreliable my_nmap() { nmap -P0 -sT -T4 --host-timeout=1501 -p "$@" 2>&1; } # fall back to telnet if nmap doesn't report on the requested port if [ -n "`my_nmap 25 localhost |grep '^25/'`" ] then poker() { p=`my_nmap "$2" "$1" |grep "^$2.*open"`; [ -n "$p" ]; } else poker() { echo X |telnet -e X "$1" $2 >/dev/null 2>&1; } fi fi help() { sed -e '/^## /!d' -e 's///' "`which $0 || echo $0`"; } while [ -n "$1" ]; do target="${1%%[:/]*}" port="${1##*:}" [ "$port" = 0 ] && port=6000 # assume host:0 is X11 on display 0 [ "$1" = "$port" ] && port=80 || altport=":$port" if [ "$port" -ge 0 ] 2>/dev/null; then true; else # in case error won't reverse s='[ ]' port=`grep "^[^#]*$port$s" /etc/services 2>/dev/null \ |sed -e "s:/.*::g" -e "s/^.*$s//g" -e 1q` # get port number [ "$port" -gt 0 ] 2>/dev/null || $say "poke: invalid port '${1##*:}'" >&2 fi case "$target" in -2* | -a*2* ) shift; say=true; set placeholder -a "$@" --pause "$@" # do it twice! # filter for dups only; anything that fails only once is okay filter() { echo "$*" |sed 's/ /\n/g' |sort |uniq -d; } ;; --pause* ) sleep 3 ;; -va* | -av*) shift; set placeholder -v -a "$@" ;; -v* | --v* ) say=echo ;; -a* | --a* ) ALL() { [ -n "$*" ] && printf "$*"; true; } ;; -h* | --h* ) help; exit 0 ;; -* | --* ) echo "poke: invalid argument \`$target'" >&2 help|grep ^Usage; exit 2 ;; * ) if poker "$target" $port then hits="$hits $target$altport" ALL && $say "poke: $target is listening on port $port" else misses="$misses $target$altport" $say "poke: could not connect to $target$altport" (! ALL) && exit 1 fi ;; esac shift unset altport done if [ -z "$hits$misses" ]; then echo "poke: too few arguments" >&2 echo "Try \`poke --help' for more information." >&2 exit 2 fi (! ALL) && $say "poke: successfully connected to each of: $hits" misses=`filter $misses` [ -n "$misses" ] && ALL "poke: failed to connect to: $misses\n" \ && exit 1 || exit 0