#!/bin/sh
# /usr/bin/spoofer

. /usr/share/spoofer/spoofer-lib.sh

spoofer_init_config || exit $?

enableTLS=$(      uci_get spoofer general enableTLS 1)
enableIPv4=$(     uci_get spoofer general enableIPv4 1)
enableIPv6=$(     uci_get spoofer general enableIPv6 1)
sharePublic=$(    uci_get spoofer general sharePublic 1)
shareRemedy=$(    uci_get spoofer general shareRemedy 1)
keepResults=$(    uci_get spoofer general keepResults 60)
keepLogs=$(       uci_get spoofer general keepLogs 2)
standaloneMode=$( uci_get spoofer debug standaloneMode 0)
pretendMode=$(    uci_get spoofer debug pretendMode 0)
useDevServer=$(   uci_get spoofer debug useDevServer 0)

PROBER="/usr/bin/spoofer-prober"
OPTIONS="-1 --cafile /usr/share/spoofer/gd_bundle.crt --cafile /usr/share/spoofer/letsencrypt_bundle.pem.txt"
test "$enableTLS" = "0" && OPTIONS="$OPTIONS --no-tls"
test "$enableIPv4" = "1" && OPTIONS="$OPTIONS -4"
test "$enableIPv6" = "1" && OPTIONS="$OPTIONS -6"
test "$standaloneMode" = "1" && OPTIONS="$OPTIONS -S"
test "$pretendMode" = "1" && OPTIONS="$OPTIONS -P"
test "$useDevServer" = "1" && OPTIONS="$OPTIONS -T"
OPTIONS="$OPTIONS -s${sharePublic} -r${shareRemedy}"

case "$*" in
    --postinst)
	# after spoofer_init_config
	exit 0
	;;
    --version)
	$PROBER --version
	exit 0
	;;
    -?|-h|--help)
	cat <<EOF
"$0 [options]" will run spoofer-prober with options according to
spoofer settings in uci, and record summary results.  With current settings,
the command line options will be:
    $PROBER $OPTIONS [options]

EOF
	$PROBER --help
	exit 0
	;;
esac

trap 'uci revert spoofer' EXIT
NOW=$(date +'%s')
LOGFILE=$LOGDIR/spoofer-prober-$(date -d@$NOW +"%Y%m%d-%H%M%S").txt

# delete expired log files and references to them
keeplogs $(($keepLogs - 1))

# create new result record in uci
uci set spoofer.$NOW=result &&
uci reorder spoofer.$NOW=0 && # move new record to beginning of list
uci_set spoofer $NOW start "$NOW" &&
uci_set spoofer $NOW log "$LOGFILE" &&
uci_commit spoofer || exit $?

# run the prober
$PROBER $OPTIONS "$@" >$LOGFILE
STATUS=$?

# summarize results from log into uci
SUMMARYFILE=$LOGDIR/spoofer.summary
awk -- '
    function SET(name, value) { print "set spoofer.'$NOW'." name "=\"" value "\""; }
    function ADD(name, value) { print "add_list spoofer.'$NOW'." name "=\"" value "\""; }
    /^>> +standaloneMode$/ { flags = flags "S"; }
    /^>> +pretendMode$/    { flags = flags "P"; }
    /^>> +useDevServer$/   { flags = flags "T"; }
    /^# ClientMessage / { v=0; }
    /^# ServerMessage \(IPv4\):$/ { v=4; }
    /^# ServerMessage \(IPv6\):$/ { v=6; }
    /^# +clientip: / { if (v) { SET("ipv" v, v flags); SET("clientip" v, $3); } }
    /^# IPv4 Result Summary:$/ { v=4; }
    /^# IPv6 Result Summary:$/ { v=6; }
    /^>> +ASN: / { SET("ASN" v, $NF); }
    /^>> +Spoofed private addresses, outbound: /   { split($0, a, ": +"); SET("privaddr" v, a[2]); }
    /^>> +Spoofed routable addresses, outbound: /  { split($0, a, ": +"); SET("routable" v, a[2]); }
    /^>> +Spoofed private addresses, inbound: /  { split($0, a, ": +"); SET("inprivaddr" v, a[2]); }
    /^>> +Spoofed internal addresses, inbound: / { split($0, a, ": +"); SET("ininternal" v, a[2]); }
    /^Your test results:$/ { footer=1; }
    /^ +https?:.*\/report/ { if (footer) SET("report", $NF); }
    /^[*][*][*].*([Ee]rror|[Ww]arning|[Nn]otice):/ { ADD("message", $0); }
' <$LOGFILE >$SUMMARYFILE || exit $?

uci batch <$SUMMARYFILE || exit $?
rm $SUMMARYFILE

# keep only the first (most recent) $keepResults results
if test "$keepResults" -gt 0; then
    while uci -q show spoofer.@result[$keepResults] >/dev/null; do
	uci delete spoofer.@result[-1]
    done
fi

uci_commit spoofer || exit $?

# if there's a spoofer crontab, reschedule it (in case this script was called
# outside of the cronjob)
if crontab_l | egrep "$PROBERTAG" >/dev/null; then
    /etc/init.d/spoofer start
fi

trap - EXIT
exit $STATUS
