duk242

wrtbwmon modified

Nov 1st, 2014
549
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.73 KB | None | 0 0
  1. #!/bin/sh
  2. #
  3. # Traffic logging tool for OpenWRT-based routers
  4. #
  5. # Created by Emmanuel Brucy (e.brucy AT qut.edu.au)
  6. # Modified by Dustin Kerr (wrtbwmon AT duklabs.com) - 1/11/14
  7. # Based on work from Fredrik Erlandsson (erlis AT linux.nu)
  8. # Based on traff_graph script by twist - http://wiki.openwrt.org/RrdTrafficWatch
  9. #
  10. # This program is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU General Public License
  12. # as published by the Free Software Foundation; either version 2
  13. # of the License, or (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program; if not, write to the Free Software
  22. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  23.  
  24. LAN_IFACE=eth0
  25.  
  26. lock()
  27. {
  28.     while [ -f /tmp/wrtbwmon.lock ]; do
  29.         if [ ! -d /proc/$(cat /tmp/wrtbwmon.lock) ]; then
  30.             echo "WARNING : Lockfile detected but process $(cat /tmp/wrtbwmon.lock) does not exist !"
  31.             rm -f /tmp/wrtbwmon.lock
  32.         fi
  33.         sleep 1
  34.     done
  35.     echo $$ > /tmp/wrtbwmon.lock
  36. }
  37.  
  38. unlock()
  39. {
  40.     rm -f /tmp/wrtbwmon.lock
  41. }
  42.  
  43. case ${1} in
  44.  
  45. "setup" )
  46.  
  47.     #Create the RRDIPT CHAIN (it doesn't matter if it already exists).
  48.     /sbin/iptables -N RRDIPT 2> /dev/null
  49.  
  50.     #Add the RRDIPT CHAIN to the FORWARD chain (if non existing).
  51.     /sbin/iptables -L FORWARD --line-numbers -n | grep "RRDIPT" | grep "1" > /dev/null
  52.     if [ $? -ne 0 ]; then
  53.         /sbin/iptables -L FORWARD -n | grep "RRDIPT" > /dev/null
  54.         if [ $? -eq 0 ]; then
  55.             echo "DEBUG : /sbin/iptables chain misplaced, recreating it..."
  56.             /sbin/iptables -D FORWARD -j RRDIPT
  57.         fi
  58.         /sbin/iptables -I FORWARD -j RRDIPT
  59.     fi
  60.  
  61.     #For each host in the ARP table
  62.     grep ${LAN_IFACE} /proc/net/arp | while read IP TYPE FLAGS MAC MASK IFACE
  63.     do
  64.         #Add iptable rules (if non existing).
  65.         /sbin/iptables -nL RRDIPT | grep "${IP} " > /dev/null
  66.         if [ $? -ne 0 ]; then
  67.             /sbin/iptables -I RRDIPT -d ${IP} -j RETURN
  68.             /sbin/iptables -I RRDIPT -s ${IP} -j RETURN
  69.         fi
  70.     done   
  71.     ;;
  72.    
  73. "update" )
  74.     [ -z "${2}" ] && echo "ERROR : Missing argument 2" && exit 1
  75.    
  76.     # Uncomment this line if you want to abort if database not found
  77.     # [ -f "${2}" ] || exit 1
  78.  
  79.     lock
  80.  
  81.     #Read and reset counters
  82.     /sbin/iptables -L RRDIPT -vnxZ -t filter > /tmp/traffic_$$.tmp
  83.  
  84.     grep -v "0x0" /proc/net/arp  | while read IP TYPE FLAGS MAC MASK IFACE
  85.     do
  86.         #Add new data to the graph. Count in Kbs to deal with 16 bits signed values (up to 2G only)
  87.         #Have to use temporary files because of crappy busybox shell
  88.         grep -w ${IP} /tmp/traffic_$$.tmp | while read PKTS BYTES TARGET PROT OPT IFIN IFOUT SRC DST
  89.         do
  90.             [ "${DST}" = "${IP}" ] && echo $((${BYTES}/1000)) > /tmp/in_$$.tmp
  91.             [ "${SRC}" = "${IP}" ] && echo $((${BYTES}/1000)) > /tmp/out_$$.tmp
  92.         done
  93.         if [ -f /tmp/in_$$.tmp ];
  94.             then
  95.             IN=$(cat /tmp/in_$$.tmp)
  96.             OUT=$(cat /tmp/out_$$.tmp)
  97.             rm -f /tmp/in_$$.tmp
  98.             rm -f /tmp/out_$$.tmp
  99.            
  100.             if [ ${IN} -gt 0 -o ${OUT} -gt 0 ];  then
  101.                 echo "DEBUG : New traffic for ${MAC} since last update : ${IN}k:${OUT}k"
  102.            
  103.                 LINE=$(grep ${MAC} ${2})
  104.                 if [ -z "${LINE}" ]; then
  105.                     echo "DEBUG : ${MAC} is a new host !"
  106.                     PEAKUSAGE_IN=0
  107.                     PEAKUSAGE_OUT=0
  108.                     OFFPEAKUSAGE_IN=0
  109.                     OFFPEAKUSAGE_OUT=0
  110.                 else
  111.                     PEAKUSAGE_IN=$(echo ${LINE} | cut -f2 -s -d, )
  112.                     PEAKUSAGE_OUT=$(echo ${LINE} | cut -f3 -s -d, )
  113.                     OFFPEAKUSAGE_IN=$(echo ${LINE} | cut -f4 -s -d, )
  114.                     OFFPEAKUSAGE_OUT=$(echo ${LINE} | cut -f5 -s -d, )
  115.                 fi
  116.                
  117.                 if [ "${3}" = "offpeak" ]; then
  118.                     OFFPEAKUSAGE_IN=$((${OFFPEAKUSAGE_IN}+${IN}))
  119.                     OFFPEAKUSAGE_OUT=$((${OFFPEAKUSAGE_OUT}+${OUT}))
  120.                 else
  121.                     PEAKUSAGE_IN=$((${PEAKUSAGE_IN}+${IN}))
  122.                     PEAKUSAGE_OUT=$((${PEAKUSAGE_OUT}+${OUT}))
  123.                 fi
  124.  
  125.                 grep -v "${MAC}" ${2} > /tmp/db_$$.tmp
  126.                 mv /tmp/db_$$.tmp ${2}
  127.                 echo ${MAC},${PEAKUSAGE_IN},${PEAKUSAGE_OUT},${OFFPEAKUSAGE_IN},${OFFPEAKUSAGE_OUT},$(date "+%d-%m-%Y %H:%M") >> ${2}
  128.             fi
  129.         else
  130.             echo "Skipped file"
  131.         fi
  132.     done
  133.    
  134.     #Free some memory
  135.     rm -f /tmp/*_$$.tmp
  136.     unlock
  137.     ;;
  138.    
  139. "publish" )
  140.  
  141.     [ -z "${2}" ] && echo "ERROR : Missing argument 2" && exit 1
  142.     [ -z "${3}" ] && echo "ERROR : Missing argument 3" && exit 1
  143.    
  144.     USERSFILE="/etc/dnsmasq.conf"
  145.     [ -f "${USERSFILE}" ] || USERSFILE="/tmp/dnsmasq.conf"
  146.     [ -z "${4}" ] || USERSFILE=${4}
  147.     [ -f "${USERSFILE}" ] || USERSFILE="/dev/null"
  148.  
  149.     # first do some number crunching - rewrite the database so that it is sorted
  150.     lock
  151.     touch /tmp/sorted_$$.tmp
  152.     cat ${2} | while IFS=, read MAC PEAKUSAGE_IN PEAKUSAGE_OUT OFFPEAKUSAGE_IN OFFPEAKUSAGE_OUT LASTSEEN
  153.     do
  154.         echo ${PEAKUSAGE_IN},${PEAKUSAGE_OUT},${OFFPEAKUSAGE_IN},${OFFPEAKUSAGE_OUT},${MAC},${LASTSEEN} >> /tmp/sorted_$$.tmp
  155.     done
  156.     unlock
  157.  
  158.         # create HTML page
  159.         echo "<html style=\"background-color: #14171A\"><head><title>Traffic</title><script type=\"text/javascript\">" > ${3}
  160.         echo "function getSize(size) {" >> ${3}
  161.         echo "var prefix=new Array(\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\"); var base=1000;" >> ${3}
  162.         echo "var pos=0; while (size>base) { size/=base; pos++; } if (pos > 2) precision=1000; else precision = 1;" >> ${3}
  163.         echo "return (Math.round(size*precision)/precision)+' '+prefix[pos];}" >> ${3}
  164.         echo "</script></head><body style=\"color: #3B96D8\"><h1>Total Usage :</h1>" >> ${3}
  165.         echo "<table border="1"><tr style=\"background-color: #090b0c\"><th>User</th><th>Peak download</th><th>Peak upload</th><th>Offpeak download</th><th>Offpeak upload</th><th>Last seen</th></tr>" >> ${3}
  166.         echo "<script type=\"text/javascript\">" >> ${3}
  167.  
  168.         echo "var values = new Array(" >> ${3}
  169.         sort -n /tmp/sorted_$$.tmp | while IFS=, read PEAKUSAGE_IN PEAKUSAGE_OUT OFFPEAKUSAGE_IN OFFPEAKUSAGE_OUT MAC LASTSEEN
  170.         do
  171.                 echo "new Array(" >> ${3}
  172.                 USER=$(grep "${MAC}" "${USERSFILE}" | cut -f2 -s -d, )
  173.                 [ -z "$USER" ] && USER=${MAC}
  174.                 echo "\"${USER}\",${PEAKUSAGE_IN}000,${PEAKUSAGE_OUT}000,${OFFPEAKUSAGE_IN}000,${OFFPEAKUSAGE_OUT}000,\"${LASTSEEN}\")," >> ${3}
  175.         done
  176.         echo "0);" >> ${3}
  177.  
  178.         echo "for (i=0; i < values.length-1; i++) {document.write(\"<tr><td>\");" >> ${3}
  179.         echo "document.write(values[i][0]);document.write(\"</td><td>\");" >> ${3}
  180.         echo "document.write(getSize(values[i][1]));document.write(\"</td><td>\");" >> ${3}
  181.         echo "document.write(getSize(values[i][2]));document.write(\"</td><td>\");" >> ${3}
  182.         echo "document.write(getSize(values[i][3]));document.write(\"</td><td>\");" >> ${3}
  183.         echo "document.write(getSize(values[i][4]));document.write(\"</td><td>\");" >> ${3}
  184.         echo "document.write(values[i][5]);document.write(\"</td></tr>\");" >> ${3}
  185.         echo "}</script></table>" >> ${3}
  186.         echo "<br /><small>This page was generated on `date`</small>" 2>&1 >> ${3}
  187.         echo "</body></html>" >> ${3}
  188.  
  189.         #Free some memory
  190.         rm -f /tmp/*_$$.tmp
  191.         ;;
  192.  
  193. *)
  194.     echo "Usage : $0 {setup|update|publish} [options...]"
  195.     echo "Options : "
  196.     echo "   $0 setup"
  197.     echo "   $0 update database_file [offpeak]"
  198.     echo "   $0 publish database_file path_of_html_report [user_file]"
  199.     echo "Examples : "
  200.     echo "   $0 setup"
  201.     echo "   $0 update /tmp/usage.db offpeak"
  202.     echo "   $0 publish /tmp/usage.db /www/user/usage.htm /jffs/users.txt"
  203.     echo "Note : [user_file] is an optional file to match users with their MAC address"
  204.     echo "       Its format is : 00:MA:CA:DD:RE:SS,username , with one entry per line"
  205.     exit
  206.     ;;
  207. esac
Advertisement
Add Comment
Please, Sign In to add comment