Date created: 01/16/16 17:28:13. Last modified: 04/09/18 08:44:06

ICMP Messages (Frequency)

Two almost completely pointless bash scripts, one to TX a basic ASCII message using IMCP echo requests and one to recieve them using tcpdump and convert the number of echo requests back into the ASCII message. The RX script needs sudo to use tcpdump however the TX script (which is presumably the one that would be used out in the field to phone home) does not:

#!/bin/bash
# Simply call this script with the receivers IP and the message to send;
# ./message_tx.sh 11.22.33.44 "Help Im high and need biscuits"


# Convert the message characters to their ASCII values
msg_to_ascii() {

  local LOOP=0
  local ASCII[${#MESSAGE}]

  while [ $LOOP -lt ${#MESSAGE} ]
  do

    ASCII[$LOOP]=$(echo -n "${MESSAGE:$LOOP:1}" | od -An -tuC | tr -d ' ')
    let LOOP=LOOP+1

  done

  echo -n "${ASCII[*]}"

}


if [ -z "$1" ]
then
    echo "1st argument must be IP/hostname"
    exit 1
fi

if [ -z "$2" ]
then
    echo "2nd argument must be message"
    exit 1
fi


# Defaults
DEST="$1"
MESSAGE="$2"
ASCII=$(msg_to_ascii)
INTER_SYMBOL_PERIOD=3


# Main loop to transmit ASCII numbers as pings
for CHAR in $ASCII
do

    ping -A -c $CHAR $DEST
    sleep $INTER_SYMBOL_PERIOD

done


# Send a final terminal "character"
ping -A -c 1 $DEST
#!/bin/bash
# Call the script using sudo and parse the IP of the transmitting host
# sudo ./message_rx.sh 11.22.33.44

if [ "$EUID" -ne 0 ]
then
  echo "Need to be root for tcpdump"
  exit 1
fi

if [ -z "$1" ]
then
    echo "First argument must be IP/hostname"
    exit 1
fi

set -u


# Defaults
RX_FILE="rx.pcap"
if [ -e $RX_FILE ]; then rm -f $RX_FILE; fi
touch $RX_FILE
RX_COUNT=0
THIS_SECOND=0
LAST_SECOND=0
LINE_COUNT=$(wc -l $RX_FILE | awk '{print $1}')
THIS_LINE_COUNT=0
INTER_SYMBOL_PERIOD=3


# Listen for transmission
stdbuf -o0 tcpdump -tttni any "host $1 and icmp[icmptype] == 8" > $RX_FILE &


# Main loop to read the pcap file
while true
do

    while IFS='' read -r line
    do

        let THIS_LINE_COUNT=THIS_LINE_COUNT+1

        THIS_SECOND=$(echo $line | awk -F ":" '{print $3}' | awk -F "." '{print $1}')

        if [ $((THIS_SECOND-LAST_SECOND)) -ge $INTER_SYMBOL_PERIOD ]
        then

            if [ $RX_COUNT -gt 0 ];
            then
                printf "\x$(printf %x $RX_COUNT)"
            fi

            RX_COUNT=1
            LAST_SECOND=00

        elif [ $((THIS_SECOND-LAST_SECOND)) -lt $INTER_SYMBOL_PERIOD ]
        then

            let RX_COUNT=RX_COUNT+1

        fi


        if [ $THIS_LINE_COUNT -eq $LINE_COUNT ]
        then

            printf "\x$(printf %x $RX_COUNT)"

        fi


    done < $RX_FILE
    echo ""

    RX_COUNT=0
    THIS_TIMESTAMP=0
    LAST_TIMESTAMP=0
    THIS_LINE_COUNT=0

    sleep 5

done