Sometimes you need to proove that the server in the middle really receives and transmits each transit packet between 2 hosts
#!/bin/bash | |
function warn { | |
echo -e "$(date +"%F %T") $*" >&2 | |
} | |
function die { | |
warn "$*" | |
exit 13 | |
} | |
while getopts ":s:d:v" OPT; do | |
case "${OPT}" in | |
s) | |
SOURCE="${OPTARG}" | |
;; | |
d) | |
DESTINATION="${OPTARG}" | |
;; | |
v) | |
VERBOSE=1 | |
;; | |
\?) | |
die "Invalid option: -${OPTARG}" | |
;; | |
:) | |
die "Option -${OPTARG} requires an argument" | |
;; | |
esac | |
done | |
[[ -z "${SOURCE}" ]] && die "The source address is undefined" | |
[[ -z "${DESTINATION}" ]] && die "The destination address is undefined" | |
NEXT_PHASE=0 | |
NEXT_SEQ=0 | |
tcpdump -l -n -i any -e "icmp and host ${SOURCE} and host ${DESTINATION}" 2>/dev/null | | |
while :; do | |
[[ "${VERBOSE}" -eq 1 ]] && echo -n ">${NEXT_PHASE}" | |
read LINE | |
INPUT=($(echo "${LINE}" | sed -n -r 's/^[0-9:\.]+ ?(In|Out) .+ ([0-9\.]+) > ([0-9\.]+): ICMP echo (request|reply), id [0-9]+, seq ([0-9]+).*, length [0-9]+$/\1 \2 \3 \4 \5/gp')) | |
NEW_SEQ="${INPUT[4]}" | |
case "${INPUT[3]}" in | |
'request') | |
NEW_PHASE=1 | |
([[ "${INPUT[1]}" == "${SOURCE}" ]] && [[ "${INPUT[2]}" == "${DESTINATION}" ]]) || continue 3 | |
;; | |
'reply') | |
NEW_PHASE=3 | |
([[ "${INPUT[2]}" == "${SOURCE}" ]] && [[ "${INPUT[1]}" == "${DESTINATION}" ]]) || continue 3 | |
;; | |
*) | |
die "(1) The following line looks strange:\n${LINE}" | |
;; | |
esac | |
case "${INPUT[0]}" in | |
'In') | |
;; | |
'Out') | |
NEW_PHASE=$((${NEW_PHASE} + 1)) | |
;; | |
*) | |
die "(2) The following line looks strange:\n${LINE}" | |
;; | |
esac | |
[[ "${NEXT_PHASE}" -eq 0 ]] && NEXT_PHASE="${NEW_PHASE}" | |
[[ "${NEXT_SEQ}" -eq 0 ]] && NEXT_SEQ="${NEW_SEQ}" | |
[[ "${NEXT_PHASE}" -ne "${NEW_PHASE}" ]] && warn "Wrong phase, expected ${NEXT_PHASE}, got ${NEW_PHASE}:\n${LINE}" | |
[[ "${NEXT_SEQ}" -ne "${NEW_SEQ}" ]] && warn "Wrong seq, expected ${NEXT_SEQ}, got ${NEW_SEQ}:\n${LINE}" | |
if [[ ${NEXT_PHASE} -eq 4 ]]; then | |
NEXT_PHASE=1 | |
NEXT_SEQ=$((${NEXT_SEQ} + 1)) | |
else | |
NEXT_PHASE=$((${NEXT_PHASE} + 1)) | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment