diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2015-03-04 20:32:26 +0000 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2015-03-04 20:32:26 +0000 |
commit | 4c960fa90a975d20f75a1ecabd217247f1922c8f (patch) | |
tree | 598bf7ec385d3f54ee1c31412e4633a064f042b6 | |
parent | 9003b50b13da624ca45f3e0cf99abb623b8d026b (diff) | |
download | dnsmasq-4c960fa90a975d20f75a1ecabd217247f1922c8f.tar.gz |
New version of contrib/reverse-dns
-rw-r--r-- | contrib/reverse-dns/README | 22 | ||||
-rw-r--r-- | contrib/reverse-dns/reverse_dns.sh | 29 | ||||
-rw-r--r-- | contrib/reverse-dns/reverse_replace.sh | 131 |
3 files changed, 125 insertions, 57 deletions
diff --git a/contrib/reverse-dns/README b/contrib/reverse-dns/README index f87eb77..2ec4df1 100644 --- a/contrib/reverse-dns/README +++ b/contrib/reverse-dns/README @@ -1,18 +1,18 @@ -Hi.
+The script reads stdin and replaces all IP addresses with names before
+outputting it again. IPs from private networks are reverse looked up
+via dns. Other IP adresses are searched for in the dnsmasq query log.
+This gives names (CNAMEs if I understand DNS correctly) that are closer
+to the name the client originally asked for then the names obtained by
+reverse lookup. Just run
-To translate my routers netstat-nat output into names that actually talk
-to me I have started writing to simple shell scripts. They require
+netstat -n -4 | ./reverse_replace.sh
+
+to see what it does. It needs
log-queries
log-facility=/var/log/dnsmasq.log
-to be set. With
-
-netstat-nat -n -4 | reverse_replace.sh
-
-I get retranslated output.
-
-Sincerely,
-Joachim
+in the dnsmasq configuration.
+The script runs on debian (with ash installed) and on busybox.
diff --git a/contrib/reverse-dns/reverse_dns.sh b/contrib/reverse-dns/reverse_dns.sh deleted file mode 100644 index c0fff30..0000000 --- a/contrib/reverse-dns/reverse_dns.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# $Id: reverse_dns.sh 4 2015-02-17 20:14:59Z jo $ -# -# Usage: reverse_dns.sh IP -# Uses the dnsmasq query log to lookup the name -# that was last queried to return the given IP. -# - -IP=$1 -qmIP=`echo $IP | sed 's#\.#\\.#g'` -LOG=/var/log/dnsmasq.log - -IP_regex='^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' - -if ! [[ $IP =~ $IP_regex ]]; then - echo -n $IP - exit -fi - -NAME=`tac $LOG | \ - grep " is $IP" | head -1 | \ - sed "s#.* \([^ ]*\) is $qmIP.*#\1#" ` - -if [ -z "$NAME" ]; then - echo -n $IP -else - echo -n $NAME -fi - diff --git a/contrib/reverse-dns/reverse_replace.sh b/contrib/reverse-dns/reverse_replace.sh index a11c164..5b4aebd 100644 --- a/contrib/reverse-dns/reverse_replace.sh +++ b/contrib/reverse-dns/reverse_replace.sh @@ -1,28 +1,125 @@ -#!/bin/bash -# $Id: reverse_replace.sh 4 2015-02-17 20:14:59Z jo $ +#!/bin/ash +# $Id: reverse_replace.sh 18 2015-03-01 16:12:35Z jo $ # # Usage e.g.: netstat -n -4 | reverse_replace.sh # Parses stdin for IP4 addresses and replaces them -# with names retrieved by reverse_dns.sh +# with names retrieved by parsing the dnsmasq log. +# This currently only gives CNAMEs. But these +# usually tell ou more than the mones from reverse +# lookups. +# +# This has been tested on debian and asuswrt. Plese +# report successful tests on other platforms. +# +# Author: Joachim Zobel <jz-2014@heute-morgen.de> +# License: Consider this MIT style licensed. You can +# do as you ike, but you must not remove my name. # -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -DNS=$DIR/reverse_dns.sh +LOG=/var/log/dnsmasq.log +MAX_LINES=15000 -# sed regex +# sed regex do match IPs IP_regex='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' +# private IP ranges +IP_private='\(^127\.\)\|\(^192\.168\.\)\|\(^10\.\)\|\(^172\.1[6-9]\.\)\|\(^172\.2[0-9]\.\)\|\(^172\.3[0-1]\.\)' -while read LINE; do - if grep --quiet $IP_regex <<< "$LINE"; then - IPs=`sed "s#.*\b\($IP_regex\)\b.*#\1 #g" <<< "$LINE"` - IPs=($IPs) - for IP in "${IPs[@]}" - do - NAME=`$DNS $IP` - # echo "$NAME is $IP"; - LINE="${LINE/$IP/$NAME}" - done +####################################################################### +# Find Commands + +HOST=nslookup +if type host > /dev/null 2>&1; then + # echo "No need for nslookup, host is there" + HOST=host +fi + +####################################################################### +# Functions + +# Use shell variables for an (IP) lookup table +create_lookup_table() +{ + # Parse log into lookup table + local CMDS="$( tail -"$MAX_LINES" "$LOG" | \ + grep " is $IP_regex" | \ + sed "s#.* \([^ ]*\) is \($IP_regex\).*#set_val \2 \1;#" )" + + local IFS=' +' + for CMD in $CMDS + do + eval $CMD + done +} + +set_val() +{ + local _IP=$(echo $1 | tr . _) + local KEY="__IP__$_IP" + eval "$KEY"=$2 +} + +get_val() +{ + local _IP=$(echo $1 | tr . _) + local KEY="__IP__$_IP" + eval echo -n '${'"$KEY"'}' +} + +dns_lookup() +{ + local IP=$1 + + local RTN="$($HOST $IP | \ + sed 's#\s\+#\n#g' | \ + grep -v '^$' | \ + tail -1 | tr -d '\n' | \ + sed 's#\.$##')" + if echo $RTN | grep -q NXDOMAIN; then + echo -n $IP + else + echo -n "$RTN" + fi +} + +reverse_dns() +{ + local IP=$1 + + # Skip if it is not an IP + if ! echo $IP | grep -q "^$IP_regex$"; then + echo -n $IP + return + fi + + # Do a dns lookup, if it is a local IP + if echo $IP | grep -q $IP_private; then + dns_lookup $IP + return fi + + local NAME="$(get_val $IP)" + + if [ -z "$NAME" ]; then + echo -n $IP + else + echo -n $NAME + fi +} + +####################################################################### +# Main +create_lookup_table + +while read LINE; do + for IP in $(echo "$LINE" | \ + sed "s#\b\($IP_regex\)\b#\n\1\n#g" | \ + grep $IP_regex) + do + NAME=`reverse_dns $IP ` + # echo "$NAME $IP" + LINE=`echo "$LINE" | sed "s#$IP#$NAME#" ` + done echo $LINE -done < /dev/stdin +done |