1#!/bin/ash
2# $Id: reverse_replace.sh 18 2015-03-01 16:12:35Z jo $
3#
4# Usage e.g.: netstat -n -4 | reverse_replace.sh 
5# Parses stdin for IP4 addresses and replaces them 
6# with names retrieved by parsing the dnsmasq log.
7# This currently only gives CNAMEs. But these 
8# usually tell ou more than the mones from reverse 
9# lookups. 
10#
11# This has been tested on debian and asuswrt. Plese
12# report successful tests on other platforms.
13#
14# Author: Joachim Zobel <jz-2014@heute-morgen.de>
15# License: Consider this MIT style licensed. You can 
16#   do as you ike, but you must not remove my name.
17#
18
19LOG=/var/log/dnsmasq.log
20MAX_LINES=15000
21
22# sed regex do match IPs
23IP_regex='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
24# private IP ranges
25IP_private='\(^127\.\)\|\(^192\.168\.\)\|\(^10\.\)\|\(^172\.1[6-9]\.\)\|\(^172\.2[0-9]\.\)\|\(^172\.3[0-1]\.\)'
26
27#######################################################################
28# Find Commands
29  
30HOST=nslookup
31if type host > /dev/null 2>&1; then
32  # echo "No need for nslookup, host is there"
33  HOST=host
34fi
35
36#######################################################################
37# Functions
38
39# Use shell variables for an (IP) lookup table
40create_lookup_table()
41{
42  # Parse log into lookup table
43  local CMDS="$( tail -"$MAX_LINES" "$LOG" | \
44    grep " is $IP_regex" | \
45    sed "s#.* \([^ ]*\) is \($IP_regex\).*#set_val \2 \1;#" )"
46
47  local IFS='
48'
49  for CMD in $CMDS
50  do
51    eval $CMD
52  done
53}
54
55set_val()
56{
57  local _IP=$(echo $1 | tr . _)
58  local KEY="__IP__$_IP"
59  eval "$KEY"=$2
60}
61
62get_val()
63{
64  local _IP=$(echo $1 | tr . _)
65  local KEY="__IP__$_IP"
66  eval echo -n '${'"$KEY"'}'
67}
68
69dns_lookup()
70{
71  local IP=$1
72
73  local RTN="$($HOST $IP | \
74        sed 's#\s\+#\n#g' | \
75        grep -v '^$' | \
76        tail -1 | tr -d '\n' | \
77        sed 's#\.$##')"
78  if echo $RTN | grep -q NXDOMAIN; then
79    echo -n $IP
80  else
81    echo -n "$RTN"
82  fi     
83}
84
85reverse_dns()
86{
87  local IP=$1
88
89  # Skip if it is not an IP
90  if ! echo $IP | grep -q "^$IP_regex$"; then
91    echo -n $IP
92    return 
93  fi
94    
95  # Do a dns lookup, if it is a local IP
96  if echo $IP | grep -q $IP_private; then
97    dns_lookup $IP
98    return
99  fi
100    
101  local NAME="$(get_val $IP)"
102  
103  if [ -z "$NAME" ]; then
104    echo -n $IP
105  else
106    echo -n $NAME
107  fi
108}
109
110#######################################################################
111# Main
112create_lookup_table
113
114while read LINE; do
115  for IP in $(echo "$LINE" | \
116              sed "s#\b\($IP_regex\)\b#\n\1\n#g" | \
117              grep $IP_regex) 
118  do
119    NAME=`reverse_dns $IP `
120    # echo "$NAME $IP"
121    LINE=`echo "$LINE" | sed "s#$IP#$NAME#" ` 
122  done
123  echo $LINE
124done
125
126