#!/usr/bin/env bash
#orange
#sudo ip r a 80.10.246.0/24 via 192.168.1.1
#sudo ip r a 81.253.149.0/24 via 192.168.1.1
#numericable
#sudo ip r a 89.2.0.0/24 via 192.168.0.1
#sfr
#sudo ip r a 109.0.66.0/24 via 192.168.0.1
#free
#sudo ip r a 212.27.40.0/24 via $(ip n s dev usb0 | head -1 | cut -d " " -f1)
#bouygues
#sudo ip r a 194.158.122..0/24 via 192.168.0.1

details=false
Orange=false
OBS=false
Bouygues=false
SFR=false
Numericable=false
Free=false
Google=false
Local=false
Trusted=false
All=false
Random=false
site=""
DNSREP=""

DNS_Orange=(80.10.246.{1,2,3,5,7,129,130,132,134,136} 81.253.149.{1,2,6,9,10})
DNS_OBS=(194.2.0.{20,50})
DNS_Numericable=(89.2.0.{1,2})
DNS_SFR=(109.0.66.{10,11,12,15,20,21,22,25})
DNS_Free=(212.27.40.24{0,1,4,5})
DNS_Google=(8.8.{4.4,8.8})
DNS_Bouygues=(194.158.122.{10,15,53}) #untested
#DNS_FFDN=($(dig +short -t A mondns.eu.org)) #;) <3
DNS_FFDN=(80.67.169.{12,40} 80.67.188.188 89.234.141.66 89.234.186.18 185.233.100.100)


usage() {
	echo "Usage: $0 -u <address> -opbsnfgltar" 1>&2
	echo "-d print details (otherwise hidden) non lying and/or NOERROR but empty A record" 1>&2
	echo "   Operator DNS resolver" 1>&2
	echo "-o Orange" 1>&2
	echo "-p OBS (Orange Pro)" 1>&2
	echo "-b Bouygues" 1>&2
	echo "-s SFR" 1>&2
	echo "-n Numericable" 1>&2
	echo "-f Free" 1>&2
	echo "-g Google" 1>&2
	echo "-l Local" 1>&2
	echo "-t Trusted FFDN <3" 1>&2
	echo "-a All" 1>&2
	echo "-r Randomly pick a dns server from operator's known ones" 1>&2
	echo "MUST have a _specific_ /24 route to theses resolvers (except for p,g,t and l)." 1>&2
	echo "" 1>&2
	echo "Note : For Google, Local and Trusted resolvers, simply exit on NXDOMAIN answer." 1>&2
	echo "Note : For suspicious answers with NOERROR status, also check parent." 1>&2
	echo "" 1>&2
	echo "Output form :" 1>&2
	echo "Operator : answer_status;address;\"TTL A_record\";dns_addr;date;epoch;\"serial ttl (from SOA record)\";-(suspicious)/+ (otherwise);" 1>&2
	exit 1
}

while getopts "U:u:OoPpBbSsNnFfGgLlTtAaHhDdRr" opt; do
#echo $opt
  case $opt in
    D|d)  details=true ;;
    U|u)  site=$OPTARG ;;
    O|o)  Orange=true ;;
    P|p)  OBS=true ;;
    B|b)  Bouygues=true ;;
    S|s)  SFR=true ;;
    N|n)  Numericable=true ;;
    F|f)  Free=true ;;
    G|g)  Google=true ;;
    L|l)  Local=true ;;
    T|t)  Trusted=true ;;
    A|a)  All=true;Orange=true;OBS=true;Bouygues=true;SFR=true;Numericable=true;Free=true;Google=true;Local=true;Trusted=true ;;
    R|r)  Random=true ;;
    H|h)  usage ;;
    \?)   usage ;;
     :)   echo missing argument ;;
  esac
done

[ -z $1 ]&&usage
[ -z $site ]&&usage

#echo -e "Site:"$site "\nOrange:"$Orange "\nOBS:"$OBS "\nBouygues:"$Bouygues "\nSFR:"$SFR "\nNumericable:"$Numericable "\nFree:"$Free "\nGoogle:"$Google "\nLocal:"$Local "\nAll:"$All"\n"

function Do_Resolv {
	local site=$1;DNS=$2;
	DNSREP=$(dig +time=1 -t A +short @$DNS $site 2>/dev/null | sort)
	if [[ -z $DNSREP ]];then
		DATE=$(date +%Y%m%d_%H%M%S\;%s)
		REP=$(echo $Operator" : "$(dig -t A +time=2 $site @$DNS | awk -v date="${DATE}" -v dns=$DNS -v site=$site /status/'{print $6";"site";""\""}'/^$site/'{if ( $4=="A" ) print $2" "$5}'/SERVER/'{print "\""";"dns";"}'/WHEN/'{print date";\"\";-;"}') | sed "s/,//;s/;\ /;/;s/"\""\ /"\""/;s/\ "\""/"\""/")
		STATUS=$(echo $REP | awk -F":|;" '{ print $2}')
		if [ $STATUS != "NOERROR" ];then
			echo $REP
		elif $details ;then
			echo $REP
		fi
#todo		Update_DB_With $REP
	elif [[ $DNSREP =~ ^127\. ]]||[[ $DNSREP =~ ^90\.85\.16\.5. ]];then
		DATE=$(date +%Y%m%d_%H%M%S\;%s)
		SOASN=$(dig -t SOA $site @$DNS | grep -A1 -E "AUTHORITY SECTION|ANSWER SECTION" | tail -1 | awk '{ print $7" "$NF}')
		REP=$(echo $Operator" : "$(dig -t A +time=2 $site @$DNS | awk -v date="${DATE}" -v soasn="${SOASN}" -v dns=$DNS -v site=$site /status/'{print $6";"site";""\""}'/^$site/'{if ( $4=="A" ) print $2" "$5}'/SERVER/'{print "\""";"dns";"}'/WHEN/'{print date";\""soasn"\";-;"}') | sed "s/,//;s/;\ /;/;s/"\""\ /"\""/;s/\ "\""/"\""/")
		STATUS=$(echo $REP | awk -F":|;" '{ print $2}')
		echo $REP
		if [ $(echo $site| awk -F"." '{print NF}') -gt 2 ]; then
			Do_Resolv $(echo $site|awk -F"." '{for(i=2; i<NF;i++){printf $i"."}printf $NF"\n"}') $DNS
		fi
#todo		Update_DB_With $REP
	else
		if $details ;then
			DATE=$(date +%Y%m%d_%H%M%S\;%s)
			SOASN=$(dig -t SOA $site @$DNS | grep -A1 -E "AUTHORITY SECTION|ANSWER SECTION" | tail -1 | awk '{ print $7" "$NF}')
			echo $Operator" : NOERROR;"$site";\""$DNSREP"\";"${DNS}";"${DATE}";\""${SOASN}"\";+;"
		fi
		STATUS=NOERROR
	fi
}

function OneOfOrange {
local rand=$[ $RANDOM % ${#DNS_Orange[@]} ]
echo ${DNS_Orange[$rand]}
}
function OneOfOBS {
local rand=$[ $RANDOM % ${#DNS_OBS[@]} ]
echo ${DNS_OBS[$rand]}
}
function OneOfNumericable {
local rand=$[ $RANDOM % ${#DNS_Numericable[@]} ]
echo ${DNS_Numericable[$rand]}
}
function OneOfSFR {
local rand=$[ $RANDOM % ${#DNS_SFR[@]} ]
echo ${DNS_SFR[$rand]}
}
function OneOfFree {
local rand=$[ $RANDOM % ${#DNS_Free[@]} ]
echo ${DNS_Free[$rand]}
}
function OneOfGoogle {
local rand=$[ $RANDOM % ${#DNS_Google[@]} ]
echo ${DNS_Google[$rand]}
}
function OneOfBouygues {
local rand=$[ $RANDOM % ${#DNS_Bouygues[@]} ]
echo ${DNS_Bouygues[$rand]}
}
function OneOfFFDN {
local rand=$[ $RANDOM % ${#DNS_FFDN[@]} ]
echo ${DNS_FFDN[$rand]}
}

if $Local; then
	Operator=Local
	DNS=127.0.0.1
	Do_Resolv $site $DNS
	if [ $STATUS == "NXDOMAIN" ];then echo "NXDOMAIN, not testing others resolvers (if asked)." ; exit ;fi
fi

if $Trusted; then
        Operator=FFDN
        if $Random ;then
                DNS=$(OneOfFFDN)
        else
                DNS=80.67.169.40
        fi
        Do_Resolv $site $DNS
        if [ $STATUS == "NXDOMAIN" ];then echo "NXDOMAIN, not testing others resolvers (if asked)." ; exit ;fi
fi

if $Google; then
        Operator=Google
        if $Random ;then
                DNS=$(OneOfGoogle)
        else
                DNS=8.8.4.4
        fi
        Do_Resolv $site $DNS
        if [ $STATUS == "NXDOMAIN" ];then echo "NXDOMAIN, not testing others resolvers (if asked)." ; exit ;fi
fi

if $Orange; then
	Operator=Orange
	if $Random ;then
		DNS=$(OneOfOrange)
	else
		DNS=80.10.246.1
	fi
	if [[ $(ip r s 80.10.246.0/24 2>/dev/null|grep via) ]]&&[[ $(ip r s 81.253.149.0/24 2>/dev/null|grep via) ]] ;then
		Do_Resolv $site $DNS
#	else
#		echo $Operator": No specific route to DNS."
	fi
fi

if $OBS; then
	Operator=OBS
	if $Random ;then
		DNS=$(OneOfOBS)
	else
		DNS=194.2.0.20
	fi
#	if [[ $(ip r s 194.2.0.0/24 2>/dev/null|grep via) ]] ;then
	Do_Resolv $site $DNS
#	else
#		echo $Operator": No specific route to DNS."
#	fi
fi

if $Bouygues; then
	Operator=Bouygues
	if $Random ;then
		DNS=$(OneOfBouygues)
	else
		DNS=194.158.122.10
	fi
	if [[ $(ip r s 194.158.122.0/24 2>/dev/null|grep via) ]] ;then
		Do_Resolv $site $DNS
#	else
#		echo $Operator": No specific route to DNS."
	fi
fi

if $SFR; then
	Operator=SFR
	if $Random ;then
		DNS=$(OneOfSFR)
	else
		DNS=109.0.66.10
	fi
	if [[ $(ip r s 109.0.66.0/24 2>/dev/null|grep via) ]] ;then
		Do_Resolv $site $DNS
#	else
#		echo $Operator": No specific route to DNS."
	fi
fi

if $Numericable; then
	Operator=Numericable
	if $Random ;then
		DNS=$(OneOfNumericable)
	else
		DNS=89.2.0.2
	fi
	if [[ $(ip r s 89.2.0.0/24 2>/dev/null|grep via) ]] ;then
		Do_Resolv $site $DNS
#	else
#		echo $Operator": No specific route to DNS."
	fi
fi

if $Free; then
	Operator=Free
	if $Random ;then
		DNS=$(OneOfFree)
	else
		DNS=212.27.40.240
	fi
	if [[ $(ip r s 212.27.40.0/24 2>/dev/null|grep via) ]] ;then
		Do_Resolv $site $DNS
#	else
#		echo $Operator": No specific route to DNS."
	fi
fi
