diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 4367118..61c5b23 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -1962,6 +1962,23 @@ return ("$num {$units[$i]}"); } + +function unformat_number($formated_num) { + $num = strtoupper($formated_num); + + if ( strpos($num,"T") !== false ) { + $num = str_replace("T","",$num) * 1000 * 1000 * 1000 * 1000; + } else if ( strpos($num,"G") !== false ) { + $num = str_replace("G","",$num) * 1000 * 1000 * 1000; + } else if ( strpos($num,"M") !== false ) { + $num = str_replace("M","",$num) * 1000 * 1000; + } else if ( strpos($num,"K") !== false ) { + $num = str_replace("K","",$num) * 1000; + } + + return $num; +} + function update_filter_reload_status($text, $new=false) { global $g; diff --git a/src/usr/local/bin/iftop_parse.awk b/src/usr/local/bin/iftop_parse.awk new file mode 100644 index 0000000..093538f --- /dev/null +++ b/src/usr/local/bin/iftop_parse.awk @@ -0,0 +1,39 @@ +BEGIN { + FS = " " + numlist = 0 + nblines = 15 +} +{ + if ( numlist == 1 && $1 == "--------------------------------------------------------------------------------------------" ) { + exit + } + + if ( numlist == 0 && $1 == "--------------------------------------------------------------------------------------------" ) { + numlist = 1 + next + } + + if ( numlist == 1 ) { + if ( $0 ~ "=>" && nblines > 0 ) { + SENDER = $2 + STX = pfFormat($4) + getline + RECEIVER = $1 + RTX = pfFormat($3) + printf "%s;%s;%s\n", SENDER, RTX, STX + printf "%s;%s;%s\n", RECEIVER, STX, RTX + nblines-- + if ( nblines < 1 ) { + exit + } + } + next + } +} +END { +} + +function pfFormat(str) { + sub("b","",str) + return str +} \ No newline at end of file diff --git a/src/usr/local/bin/iftop_parser.sh b/src/usr/local/bin/iftop_parser.sh new file mode 100755 index 0000000..b357974 --- /dev/null +++ b/src/usr/local/bin/iftop_parser.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# Usage +if [ $# -ne 1 -a $# -ne 2 ]; then + echo "Usage : $0 iface" + exit +fi + +# files paths +pid_file=/var/run/iftop_${1}.pid +cache_file=/var/db/iftop_${1}.log +awk_script=/usr/local/bin/iftop_parse.awk + +# Binaries paths +DATE=/bin/date +STAT=/usr/bin/stat +CUT=/usr/bin/cut +PS=/bin/ps +GREP=/usr/bin/grep +CAT=/bin/cat +RM=/bin/rm +IFTOP=/usr/local/sbin/iftop +AWK=/usr/bin/awk + +# test if pid file exist +if [ -f $pid_file ]; then + # check how old is the file + curTS=`$DATE +%s` + pidTS=`$STAT -r $pid_file | $CUT -d " " -f 10` + # if more than 10 seconds, + # it must be a dead pid file (process killed?) + # or a stucked process that we should kill + if [ $(( curTS - pidTS )) -gt 10 ]; then + oldPID=`$CAT $pid_file` + # test if pid still exist + run=`$PS -p $oldPID | $GREP -F $0` + if [ "$run" != "" ]; then + kill -9 $oldPID + fi + $RM $pid_file + $RM $cache_file 2>> /dev/null + else + if [ -s $cache_file ]; then + $CAT $cache_file + fi + fi +else + echo -n $$ > $pid_file + $IFTOP -nNb -i $1 -s 1 -o 2s -t 2>> /dev/null | $AWK -f $awk_script > ${cache_file}.tmp + $CAT ${cache_file}.tmp > $cache_file + $CAT $cache_file + $RM $pid_file +fi \ No newline at end of file diff --git a/src/usr/local/www/bandwidth_by_ip.php b/src/usr/local/www/bandwidth_by_ip.php index 804c7c9..50dffdf 100644 --- a/src/usr/local/www/bandwidth_by_ip.php +++ b/src/usr/local/www/bandwidth_by_ip.php @@ -109,7 +109,64 @@ } } -$_grb = exec("/usr/local/bin/rate -i {$real_interface} -nlq 1 -Aba 20 {$sort_method} {$ratesubnet} | tr \"|\" \" \" | awk '{ printf \"%s:%s:%s:%s:%s\\n\", $1, $2, $4, $6, $8 }'", $listedIPs); + +//get the mode +$mode = !empty($_REQUEST['mode']) ? $_REQUEST['mode'] : ''; +if ($mode == "iftop") { + $current_ts = time(); + if ( file_exists("/var/run/iftop_{$real_interface}.pid") ) { + $statPID = stat("/var/run/iftop_{$real_interface}.pid"); + $since = $current_ts - $statPID['mtime']; + if ( $since < 5 && file_exists("/var/db/iftop_{$real_interface}.log") ) { + $listedIPs=file("/var/db/iftop_{$real_interface}.log"); + } else { + if ( isvalidpid("/var/run/iftop_{$real_interface}.pid") ) { + killbypid("/var/run/iftop_{$real_interface}.pid"); + } + unlink("/var/run/iftop_{$real_interface}.pid"); + $_grb = exec("/usr/local/bin/iftop_parser.sh {$real_interface} $current_ts", $listedIPs); + } + } else { + // refresh iftop infos + $_grb = exec("/usr/local/bin/iftop_parser.sh {$real_interface} $current_ts", $listedIPs); + } + + // order and group by + foreach ($listedIPs as $k => $line){ + if ($line != "") { + $arrLine = explode (";", $line); + $ip = $arrLine[0]; + $in = unformat_number($arrLine[1]); + $out = unformat_number($arrLine[2]); + if ( isset($arr_in[$ip]) ) { + $arr_in[$ip] += $in; + $arr_out[$ip] += $out; + } else { + $arr_in[$ip] = $in; + $arr_out[$ip] = $out; + } + } + } + + if ($sort == "out") { + arsort($arr_out,SORT_NUMERIC); + $arrIP = array_keys($arr_out); + } else { + arsort($arr_in,SORT_NUMERIC); + $arrIP = array_keys($arr_in); + } + + unset($listedIPs); + $listedIPs[] = ""; + $listedIPs[] = ""; + foreach ($arrIP as $k => $ip) { + $listedIPs[] = $ip.";".format_number($arr_in[$ip],2).";".format_number($arr_out[$ip],2); + } + +} else { + $_grb = exec("/usr/local/bin/rate -i {$real_interface} -nlq 1 -Aba 20 {$sort_method} {$ratesubnet} | tr \"|\" \" \" | awk '{ printf \"%s;%s;%s;%s;%s\\n\", $1, $2, $4, $6, $8 }'", $listedIPs); +} + $someinfo = false; for ($x=2; $x<12; $x++) { @@ -119,7 +176,7 @@ // echo $bandwidthinfo; $emptyinfocounter = 1; if ($bandwidthinfo != "") { - $infoarray = explode (":", $bandwidthinfo); + $infoarray = explode (";", $bandwidthinfo); if (($filter == "all") || (($filter == "local") && (ip_in_subnet($infoarray[0], $intsubnet))) || (($filter == "remote") && (!ip_in_subnet($infoarray[0], $intsubnet)))) { @@ -159,4 +216,4 @@ if ($someinfo == false) { echo gettext("no info"); } -?> +?> \ No newline at end of file diff --git a/src/usr/local/www/status_graph.php b/src/usr/local/www/status_graph.php index 9e08cd5..048396b 100644 --- a/src/usr/local/www/status_graph.php +++ b/src/usr/local/www/status_graph.php @@ -77,7 +77,8 @@ $curbackgroundupdate = $_POST['backgroundupdate']; $curinvert = $_POST['invert']; $cursmoothing = $_POST['smoothfactor']; - + $curmode = $_POST['mode']; + // Save data to config if (isset($_POST['save'])) { $pconfig = array(); @@ -88,6 +89,7 @@ $pconfig["backgroundupdate"] = $curbackgroundupdate; $pconfig["smoothfactor"] = $cursmoothing; $pconfig["invert"] = $curinvert; + $pconfig["mode"] = $curmode; $config["traffic_graphs"] = array(); $config["traffic_graphs"] = $pconfig; write_config("Traffic Graphs settings updated"); @@ -102,6 +104,7 @@ $curbackgroundupdate = $pconfig['backgroundupdate']; $cursmoothing = $pconfig['smoothfactor']; $curinvert = $pconfig['invert']; + $curmode = $pconfig['mode'];; } else { // initialize when no config details are present if (empty($ifdescrs["wan"])) { @@ -117,6 +120,7 @@ $curbackgroundupdate = ""; $cursmoothing = 0; $curinvert = ""; + $curmode = ""; } } @@ -183,6 +187,16 @@ ) ))->setHelp('Display'); +$group->add(new Form_Select( + 'mode', + null, + $curmode, + array ( + 'rate' => gettext('rate (standard)'), + 'iftop' => gettext('iftop (experimental)') + ) +))->setHelp('Mode'); + $section->add($group); $group2 = new Form_Group('Controls');