#!/bin/sh
#
# newiplookup - Reads router log continuously and saves all unique IP 
#		addresses into a "database" file.
#		Each time your network and another touch for the first time,
#		a reverse DNS lookup is performed, and the result is saved
#		next to the IP address in a new, easier to read log file.
#
# Version 1.0
#
# Copyright Defcronyke Webmaster 2011
#
# You can copy and modify this script for free, but you can never 
# sell it. All modified or unmodified versions of this script must 
# remain completely free and they all must retain this paragraph as 
# well as the Copyright notice above. If this script breaks your shit,
# you're fucked and it's not my problem.
#
# Check http://eternalvoid.net/tutorials/meaningful_router_logs/
# for updated instructions and updated versions of the script.
# Feel free to comment in the comments section if you need any help,
# if you have any feedback, or if you would like to share your
# modified version of the script with the rest of us.
#
# Quick Start: Change the values of first four variables below
#	       (lines 31, 34, 37, and 42), and you're all set!
#______________________________________________________________________________
#

# set routerlog to the log file that comes in to the localhost from the router
routerlog='/var/log/router.log'

# set connectionlog to a log file that will either be created or appended to
connectionlog='/root/.connection_log'

# set ipdb to an ip database file that will either be created or appended to
ipdb='/root/.newiplookupdb'

# set subnetfilter to your local network segment so that you don't
# perform reverse DNS lookups for all your LAN machines
# (this can be an extended grep regular expression)
subnetfilter='192.168.1.*'

# persistent root user only lock. leave this set to actively keep
# file permissions secure. comment this out if you don't want
# to continuously chmod 600 your connectionlog and ipdb files.
secperms=1

# pidfile
pidfile='/var/run/newiplookup.pid'

# copy pid into pidfile
echo $$ > $pidfile

# remove pidfile on SIGINT and SIGTERM
trap "rm $pidfile; exit 1" INT TERM

# var used to notice when the router logfile gets updated. don't change this.
lastlogsize=`du -b $routerlog | cut -f1`

if [ ! -e "$connectionlog" ]; then	# if connectionlog file doesn't exist
  touch "$connectionlog"		# create new connectionlog file
fi

if [ ! -e "$ipdb" ]; then		# if IP database file doesn't exist
  touch "$ipdb"				# create new IP database file
fi

chmod 600 "$connectionlog"		# protect files from unauthorized access
chmod 600 "$ipdb"

while [ true ]; do			# infinite loop

  sleep 1.1				# let's not go crazy now

  					# check if routerlog has any new data
					# if not, skip to the end of the while loop
  if [ `du -b $routerlog | cut -f1` -gt $lastlogsize ]; then
    
    					# update logsize var with new size
    lastlogsize=`du -b $routerlog | cut -f1`

    # uncomment for pretty routerlog output to stdout
    # use this to debug if you're trying to make this
    # script work with other routers
    # tail -1 $routerlog | cut -d" " -f1-3,6,9,10,16-19

    					# save source IP if detected this cycle
    srcip="`tail -1 $routerlog | cut -d"=" -f4 | cut -d" " -f1`"
      
    					# save destination IP if detected this cycle
    dstip="`tail -1 $routerlog | cut -d"=" -f5 | cut -d" " -f1`"
#______________________________________________________________________________________________________________
    					
    # deal with atypical output in the iptables log
    # (this is a work in progress. will work better in next release)

    result1=`echo $srcip | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'`	# test for valid IP address
    sleep 0.2										# allow grep time to finish

    if [ "$result1" = "" ]; then	# if IP is invalid
      srcip=""				# remove it from srcip variable
    fi

    result1=`echo $dstip | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'`	# test for valid IP address
    sleep 0.2										# allow grep time to finish

    if [ "$result1" = "" ]; then	# if IP is invalid
      dstip=""				# remove it from dstip variable
    fi
#______________________________________________________________________________________________________________

     					# make sure source IP is not already logged
    if [ ! "`grep $srcip $ipdb`" ]; then
        
      result2=`echo $srcip | grep -E "$subnetfilter"`	# apply subnetfilter
      sleep 0.2						# wait for command to finish

      if [ "$result2" = "" ]; then			# if IP is from local network
							# don't log or perform lookup
      
        if [ "$srcip" ]; then		# log a new incoming touch
          echo "$srcip" >> $ipdb	# update ip "database"

          revdns=`host $srcip`		# perform reverse DNS lookup and save result in revdns variable
          sleep 0.2			# give host command enough time to finish

	  if [ `echo $revdns | cut -d" " -f2` = "domain" ]; then	# if reverse DNS lookup succeeds
	    revdns=`echo $revdns | cut -d" " -f5`			# remove first PTR because it's unnecessary
	  fi								# (if you have problems and aren't seeing any
									# hostnames, maybe you have to comment this
									# section out?)

					# if lookup fails, make output a bit shorter
	  if [ `echo $revdns | cut -d" " -f1` = "Host" ]; then
	    revdns=`echo $revdns | awk ' -F" " { print $1" "$3" "$4" "$5 }'`
	  fi

	  echo "`date '+%F %a %k:%M:%S %Z'` IN  $srcip  $revdns" >> $connectionlog # write log

					# comment next line to stop output on tty11
	  echo "`date '+%F %a %k:%M:%S %Z'` IN  $srcip  $revdns" >> /dev/tty11 # write log output to tty11

          sleep 0.2			# slow down a bit more so commands can finish
        fi
      fi
    fi

   					# make sure destination IP is not already logged
    if [ ! "`grep $dstip $ipdb`" ]; then

      result2=`echo $dstip | grep -E "$subnetfilter"`	# apply subnetfilter
      sleep 0.2						# wait for command to finish

      if [ "$result2" = "" ]; then			# if IP is from local network
							# don't log or perform lookup

        if [ "$dstip" ]; then		# log a new outgoing touch
          echo "$dstip" >> $ipdb	# update ip "database"

          revdns=`host $dstip`          # perform reverse DNS lookup and save result in revdns variable
	  sleep 0.2                     # give host command enough time to finish

	  if [ `echo $revdns | cut -d" " -f2` = "domain" ]; then	# if reverse DNS lookup succeeds
	    revdns=`echo $revdns | cut -d" " -f5`			# remove first PTR because it's unnecessary
	  fi                                                      	# (if you have problems and aren't seeing any
									# hostnames, maybe you have to comment this
									# section out?)
				
					# if lookup fails, make output a bit shorter
	  if [ `echo $revdns | cut -d" " -f1` = "Host" ]; then
	    revdns=`echo $revdns | awk ' -F" " { print $1" "$3" "$4" "$5 }'`
	  fi

	  echo "`date '+%F %a %k:%M:%S %Z'` OUT $dstip  $revdns" >> $connectionlog	# write log

					# comment next line to stop output on tty11
	  echo "`date '+%F %a %k:%M:%S %Z'` OUT $dstip  $revdns" >> /dev/tty11		# write log output to tty11

	  sleep 0.2			# slow down one last time
        fi
      fi
    fi
      
    if [ "$secperms" ]; then		# persistent root-user-only lock on log and database
      chmod 600 "$connectionlog"
      chmod 600 "$ipdb"
    fi
  fi
done

