| 1 | <?php
 | 
  
    | 2 | /*
 | 
  
    | 3 |  * bandwidth_by_ip.php
 | 
  
    | 4 |  *
 | 
  
    | 5 |  * part of pfSense (https://www.pfsense.org)
 | 
  
    | 6 |  * Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
 | 
  
    | 7 |  * All rights reserved.
 | 
  
    | 8 |  *
 | 
  
    | 9 |  * Licensed under the Apache License, Version 2.0 (the "License");
 | 
  
    | 10 |  * you may not use this file except in compliance with the License.
 | 
  
    | 11 |  * You may obtain a copy of the License at
 | 
  
    | 12 |  *
 | 
  
    | 13 |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
  
    | 14 |  *
 | 
  
    | 15 |  * Unless required by applicable law or agreed to in writing, software
 | 
  
    | 16 |  * distributed under the License is distributed on an "AS IS" BASIS,
 | 
  
    | 17 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
  
    | 18 |  * See the License for the specific language governing permissions and
 | 
  
    | 19 |  * limitations under the License.
 | 
  
    | 20 |  */
 | 
  
    | 21 | 
 | 
  
    | 22 | require_once('auth_check.inc');
 | 
  
    | 23 | require_once('interfaces.inc');
 | 
  
    | 24 | require_once('pfsense-utils.inc');
 | 
  
    | 25 | require_once('util.inc');
 | 
  
    | 26 | 
 | 
  
    | 27 | $listedIPs = "";
 | 
  
    | 28 | 
 | 
  
    | 29 | //get interface IP and break up into an array
 | 
  
    | 30 | $interface = $_REQUEST['if'];
 | 
  
    | 31 | $real_interface = get_real_interface($interface);
 | 
  
    | 32 | 
 | 
  
    | 33 | if (!does_interface_exist($real_interface)) {
 | 
  
    | 34 | 	echo gettext("Wrong Interface");
 | 
  
    | 35 | 	return;
 | 
  
    | 36 | }
 | 
  
    | 37 | 
 | 
  
    | 38 | $intip = find_interface_ip($real_interface);
 | 
  
    | 39 | //get interface subnet
 | 
  
    | 40 | $netmask = find_interface_subnet($real_interface);
 | 
  
    | 41 | $intsubnet = gen_subnet($intip, $netmask) . "/$netmask";
 | 
  
    | 42 | 
 | 
  
    | 43 | // see if they want local, remote or all IPs returned
 | 
  
    | 44 | $filter = $_REQUEST['filter'];
 | 
  
    | 45 | 
 | 
  
    | 46 | if ($filter == "") {
 | 
  
    | 47 | 	$filter = "local";
 | 
  
    | 48 | }
 | 
  
    | 49 | 
 | 
  
    | 50 | if ($filter == "local") {
 | 
  
    | 51 | 	$ratesubnet = "-c " . $intsubnet;
 | 
  
    | 52 | } else {
 | 
  
    | 53 | 	// Tell the rate utility to consider the whole internet (0.0.0.0/0)
 | 
  
    | 54 | 	// and to consider local "l" traffic - i.e. traffic within the whole internet
 | 
  
    | 55 | 	// then we can filter the resulting output as we wish below.
 | 
  
    | 56 | 	$ratesubnet = "-lc 0.0.0.0/0";
 | 
  
    | 57 | }
 | 
  
    | 58 | 
 | 
  
    | 59 | //get the sort method
 | 
  
    | 60 | $sort = $_REQUEST['sort'];
 | 
  
    | 61 | if ($sort == "out") {
 | 
  
    | 62 | 	$sort_method = "-T";
 | 
  
    | 63 | } else {
 | 
  
    | 64 | 	$sort_method = "-R";
 | 
  
    | 65 | }
 | 
  
    | 66 | 
 | 
  
    | 67 | // get the desired format for displaying the host name or IP
 | 
  
    | 68 | $hostipformat = $_REQUEST['hostipformat'];
 | 
  
    | 69 | $iplookup = array();
 | 
  
    | 70 | // If hostname, description or FQDN is requested then load the locally-known IP address - host/description mappings into an array keyed by IP address.
 | 
  
    | 71 | if ($hostipformat != "") {
 | 
  
    | 72 | 	if (is_array($config['dhcpd'])) {
 | 
  
    | 73 | 		// Build an array of static-mapped DHCP entries keyed by IP address.
 | 
  
    | 74 | 		foreach ($config['dhcpd'] as $ifdata) {
 | 
  
    | 75 | 			if (is_array($ifdata['staticmap'])) {
 | 
  
    | 76 | 				foreach ($ifdata['staticmap'] as $hostent) {
 | 
  
    | 77 | 					if (($hostent['ipaddr'] != "") && ($hostent['hostname'] != "")) {
 | 
  
    | 78 | 						if ($hostipformat == "descr" && $hostent['descr'] != "") {
 | 
  
    | 79 | 							$iplookup[$hostent['ipaddr']] = $hostent['descr'];
 | 
  
    | 80 | 						} else {
 | 
  
    | 81 | 							$iplookup[$hostent['ipaddr']] = $hostent['hostname'];
 | 
  
    | 82 | 							if ($hostipformat == "fqdn") {
 | 
  
    | 83 | 								$iplookup[$hostent['ipaddr']] .= "." . $config['system']['domain'];
 | 
  
    | 84 | 							}
 | 
  
    | 85 | 						}
 | 
  
    | 86 | 					}
 | 
  
    | 87 | 				}
 | 
  
    | 88 | 			}
 | 
  
    | 89 | 		}
 | 
  
    | 90 | 	}
 | 
  
    | 91 | 	// Add any DNS host override data keyed by IP address.
 | 
  
    | 92 | 	foreach (array('dnsmasq', 'unbound') as $dns_type) {
 | 
  
    | 93 | 		if (isset($config[$dns_type]['enable'])) {
 | 
  
    | 94 | 			if (is_array($config[$dns_type]['hosts'])) {
 | 
  
    | 95 | 				foreach ($config[$dns_type]['hosts'] as $hostent) {
 | 
  
    | 96 | 					if (($hostent['ip'] != "") && ($hostent['host'] != "")) {
 | 
  
    | 97 | 						if ($hostipformat == "descr" && $hostent['descr'] != "") {
 | 
  
    | 98 | 							$iplookup[$hostent['ip']] = $hostent['descr'];
 | 
  
    | 99 | 						} else {
 | 
  
    | 100 | 							$iplookup[$hostent['ip']] = $hostent['host'];
 | 
  
    | 101 | 							if ($hostipformat == "fqdn") {
 | 
  
    | 102 | 								$iplookup[$hostent['ip']] .= "." . $hostent['domain'];
 | 
  
    | 103 | 							}
 | 
  
    | 104 | 						}
 | 
  
    | 105 | 					}
 | 
  
    | 106 | 				}
 | 
  
    | 107 | 			}
 | 
  
    | 108 | 		}
 | 
  
    | 109 | 	}
 | 
  
    | 110 | }
 | 
  
    | 111 | 
 | 
  
    | 112 | //$_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);
 | 
  
    | 113 | 
 | 
  
    | 114 | $_grb = exec("/root/iftop_parser.sh {$real_interface}", $listedIPs);
 | 
  
    | 115 | 
 | 
  
    | 116 | function GMK2bits($val) {
 | 
  
    | 117 | 	$val = strtolower($val);
 | 
  
    | 118 | 	if ( strpos($val,"g") !== false ) {
 | 
  
    | 119 | 		$val = str_replace("g","",$val) * 1000 * 1000 * 1000;
 | 
  
    | 120 | 	} else if ( strpos($val,"m") !== false ) {
 | 
  
    | 121 | 		$val = str_replace("m","",$val) * 1000 * 1000;
 | 
  
    | 122 | 	} else if ( strpos($val,"k") !== false ) {
 | 
  
    | 123 | 		$val = str_replace("k","",$val) * 1000; 
 | 
  
    | 124 | 	} 
 | 
  
    | 125 | 
 | 
  
    | 126 | 	return $val*1;
 | 
  
    | 127 | }
 | 
  
    | 128 | 
 | 
  
    | 129 | function bits2GMK($val) {
 | 
  
    | 130 | 	$units = array ( 0 => "", 1 => "K", 2 => "M", 3 => "G" );
 | 
  
    | 131 | 	$u=0;
 | 
  
    | 132 | 	while ($val > 1000) {
 | 
  
    | 133 | 		$val = $val/1000;
 | 
  
    | 134 | 		$u++;
 | 
  
    | 135 | 	}
 | 
  
    | 136 | 	return round($val,2).$units[$u];
 | 
  
    | 137 | }
 | 
  
    | 138 | 
 | 
  
    | 139 | // order and group by
 | 
  
    | 140 | foreach ($listedIPs as $k => $line){
 | 
  
    | 141 | 	if ($line != "") {
 | 
  
    | 142 | 		$arrLine = explode (";", $line);
 | 
  
    | 143 | 		$ip  = $arrLine[0];
 | 
  
    | 144 | 		$in  = GMK2bits($arrLine[1]);
 | 
  
    | 145 | 		$out = GMK2bits($arrLine[2]);
 | 
  
    | 146 | 		if ( isset($arr_in[$ip]) ) {
 | 
  
    | 147 | 			$arr_in[$ip]  += $in;
 | 
  
    | 148 | 			$arr_out[$ip] += $out; 
 | 
  
    | 149 | 		} else {
 | 
  
    | 150 | 			$arr_in[$ip]  = $in;
 | 
  
    | 151 | 			$arr_out[$ip] = $out;
 | 
  
    | 152 | 		}
 | 
  
    | 153 | 	}
 | 
  
    | 154 | }
 | 
  
    | 155 | 
 | 
  
    | 156 | if ($sort == "out") {
 | 
  
    | 157 | 	arsort($arr_out,SORT_NUMERIC);
 | 
  
    | 158 | 	$arrIP = array_keys($arr_out);
 | 
  
    | 159 | } else {
 | 
  
    | 160 | 	arsort($arr_in,SORT_NUMERIC);
 | 
  
    | 161 | 	$arrIP = array_keys($arr_in);
 | 
  
    | 162 | }
 | 
  
    | 163 | 
 | 
  
    | 164 | unset($listedIPs);
 | 
  
    | 165 | $listedIPs[] = "";
 | 
  
    | 166 | $listedIPs[] = "";
 | 
  
    | 167 | foreach ($arrIP as $k => $ip) {
 | 
  
    | 168 | 	$listedIPs[] = $ip.";".bits2GMK($arr_in[$ip]).";".bits2GMK($arr_out[$ip]);
 | 
  
    | 169 | } 
 | 
  
    | 170 | 
 | 
  
    | 171 |  
 | 
  
    | 172 | $someinfo = false;
 | 
  
    | 173 | for ($x=2; $x<12; $x++) {
 | 
  
    | 174 | 
 | 
  
    | 175 | 	$bandwidthinfo = $listedIPs[$x];
 | 
  
    | 176 | 
 | 
  
    | 177 | 	// echo $bandwidthinfo;
 | 
  
    | 178 | 	$emptyinfocounter = 1;
 | 
  
    | 179 | 	if ($bandwidthinfo != "") {
 | 
  
    | 180 | 		$infoarray = explode (";", $bandwidthinfo);
 | 
  
    | 181 | 		if (($filter == "all") ||
 | 
  
    | 182 | 		    (($filter == "local") && (ip_in_subnet($infoarray[0], $intsubnet))) ||
 | 
  
    | 183 | 		    (($filter == "remote") && (!ip_in_subnet($infoarray[0], $intsubnet)))) {
 | 
  
    | 184 | 			if ($hostipformat == "") {
 | 
  
    | 185 | 				// pass back just the raw IP address
 | 
  
    | 186 | 				$addrdata = $infoarray[0];
 | 
  
    | 187 | 			} else {
 | 
  
    | 188 | 				// $hostipformat is one of "hostname", "descr" or "fqdn" - we want a text representation if we can get it.
 | 
  
    | 189 | 				if ($iplookup[$infoarray[0]] != "") {
 | 
  
    | 190 | 					// We have a local entry, so use it.
 | 
  
    | 191 | 					$addrdata = $iplookup[$infoarray[0]];
 | 
  
    | 192 | 				} else {
 | 
  
    | 193 | 					// Try to reverse lookup the IP address.
 | 
  
    | 194 | 					$addrdata = gethostbyaddr($infoarray[0]);
 | 
  
    | 195 | 					if ($addrdata != $infoarray[0]) {
 | 
  
    | 196 | 						// Reverse lookup returned something other than the IP address (FQDN, we hope!)
 | 
  
    | 197 | 						if ($hostipformat != "fqdn") {
 | 
  
    | 198 | 							// The user does not want the whole FQDN, so only pass back the first part of the name.
 | 
  
    | 199 | 							$name_array = explode(".", $addrdata);
 | 
  
    | 200 | 							$addrdata = $name_array[0];
 | 
  
    | 201 | 						}
 | 
  
    | 202 | 					}
 | 
  
    | 203 | 				}
 | 
  
    | 204 | 			}
 | 
  
    | 205 | 			//print host information;
 | 
  
    | 206 | 			echo $addrdata . ";" . $infoarray[1] . ";" . $infoarray[2] . "|";
 | 
  
    | 207 | 
 | 
  
    | 208 | 			//mark that we collected information
 | 
  
    | 209 | 			$someinfo = true;
 | 
  
    | 210 | 		}
 | 
  
    | 211 | 	}
 | 
  
    | 212 | }
 | 
  
    | 213 | unset($bandwidthinfo, $_grb);
 | 
  
    | 214 | unset($listedIPs);
 | 
  
    | 215 | 
 | 
  
    | 216 | //no bandwidth usage found
 | 
  
    | 217 | if ($someinfo == false) {
 | 
  
    | 218 | 	echo gettext("no info");
 | 
  
    | 219 | }
 | 
  
    | 220 | ?>
 |