#!/bin/sh state="" state() { case "${1}" in [Dd][Oo][Ww][Nn]) if [ "${state}" != "down" ] then echo "$(date): ${gateway} down" state="down" fi ;; [Uu][Pp]) if [ "${state}" != "up" ] then echo "$(date): ${gateway} up" state="up" fi ;; *) echo "Unhandled '${1}'" >&2 esac } gateway="${1:-66.253.36.1}" intervalms="${2:-1000}" intervals="$(( ${intervalms} / 1000 ))" chasm=3 printf "Pingelating %s every %ums, %u second grace\n" "${gateway}" "${intervalms}" "${chasm}" time="$(date +%s)" last_check="${time}" last_ping="0" ( ping -n -W "${intervalms}" "${gateway}" & echo "pid_ping=${!}" ( while true; do echo "Pingelate"; sleep "${intervals}"; done ) & echo "pid_elate=${!}" ) | while read line do time="$(date +%s)" case "${line}" in pid_*) eval "${line}" trap "kill -TERM ${pid_ping} ${pid_elate}" exit hup int term kill ;; *\ bytes\ from\ ${gateway}:\ *) diff="$(( ${time} - ${last_ping} ))" [ "${diff}" -ge "${chasm}" ] && state up "${time}" "${last_ping}" "${last_check}" "${diff}" "${chasm}" last_ping="${time}" ;; Pingelate) # Was the last ping more than ${chasm} seconds before this checkpoint? diff=$(( ${time} - ${last_ping} )) [ "${diff}" -ge "${chasm}" ] && state down "${time}" "${last_ping}" "${last_check}" "${diff}" "${chasm}" last_check="${time}" ;; *) ;; esac done