1<?php 2 3# Check we have been included via subnet-scan-excute.php and not called directly 4require("subnet-scan-check-included.php"); 5 6/* 7 * Discover new hosts with snmp 8 *******************************/ 9 10//title 11print "<h5>"._('Scan results').":</h5><hr>"; 12 13# scan disabled 14if ($User->settings->enableSNMP!="1") { $Result->show("danger", _("SNMP module disbled"), true); } 15# subnet check 16$subnet = $Subnets->fetch_subnet ("id", $_POST['subnetId']); 17if ($subnet===false) { $Result->show("danger", _("Invalid subnet Id"), true); } 18 19# verify that user has write permissionss for subnet 20if($Subnets->check_permission ($User->user, $_POST['subnetId']) != 3) { $Result->show("danger", _('You do not have permissions to modify hosts in this subnet')."!", true, true); } 21 22# set class 23$Snmp = new phpipamSNMP (); 24 25// fetch all existing hosts 26$all_subnet_hosts = (array) $Addresses->fetch_subnet_addresses ($_POST['subnetId']); 27// reindex 28if (sizeof($all_subnet_hosts)>0) { 29 foreach ($all_subnet_hosts as $h) { 30 $subnet_ip_addresses[] = $Subnets->transform_address($h->ip_addr, "dotted"); 31 } 32} 33 34# set selected address fields array 35$selected_ip_fields = $User->settings->IPfilter; 36$selected_ip_fields = explode(";", $selected_ip_fields); 37 38// no errors 39error_reporting(E_ERROR); 40 41# fetch devices that use get_routing_table query 42$devices_used = $Tools->fetch_multiple_objects ("devices", "snmp_queries", "%get_arp_table%", "id", true, true); 43 44# filter out not in this section 45if ($devices_used !== false) { 46 foreach ($devices_used as $d) { 47 // get possible sections 48 $permitted_sections = explode(";", $d->sections); 49 // check 50 if (in_array($subnet->sectionId, $permitted_sections)) { 51 $permitted_devices[] = $d; 52 } 53 } 54} 55 56// if none set die 57if (!isset($permitted_devices)) { $Result->show("danger", _("No devices for SNMP ARP query available"), true); } 58 59// ok, we have devices, connect to each device and do query 60foreach ($permitted_devices as $d) { 61 // init 62 $Snmp->set_snmp_device ($d); 63 // fetch arp table 64 try { 65 $res = $Snmp->get_query("get_arp_table"); 66 // remove those not in subnet 67 if (is_array($res) && sizeof($res)>0) { 68 // save for debug 69 $debug[$d->hostname]["get_arp_table"] = $res; 70 // check 71 foreach ($res as $kr=>$r) { 72 // if is inside subnet 73 if ($Subnets->is_subnet_inside_subnet ($r['ip']."/32", $Subnets->transform_address($subnet->subnet, "dotted")."/".$subnet->mask)===false) { } 74 // check if host already exists, than remove it 75 elseif (in_array($r['ip'], $subnet_ip_addresses)) { } 76 // save 77 else { 78 $found[$d->id][] = $r; 79 } 80 } 81 } 82 // get interfaces 83 $res = $Snmp->get_query("get_interfaces_ip"); 84 // remove those not in subnet 85 if (is_array($res) && sizeof($res)>0) { 86 // save for debug 87 $debug[$d->hostname]["get_interfaces_ip"] = $res; 88 // check 89 foreach ($res as $kr=>$r) { 90 // if is inside subnet 91 if ($Subnets->is_subnet_inside_subnet ($r['ip']."/32", $Subnets->transform_address($subnet->subnet, "dotted")."/".$subnet->mask)===false) { } 92 // check if host already exists, than remove it 93 elseif (in_array($r['ip'], $subnet_ip_addresses)) { } 94 // save 95 else { 96 $found[$d->id][] = $r; 97 } 98 } 99 } 100 } catch (Exception $e) { 101 // save for debug 102 $debug[$d->hostname]['get_arp_table'] = $res; 103 $errors[] = $e->getMessage(); 104 } 105} 106 107# none and errors 108if(sizeof($found)==0 && isset($errors)) { 109 $Result->show("info", _("No new hosts found"), false); 110 $Result->show("warning", implode("<hr>", $errors), false); 111} 112# none 113elseif(sizeof($found)==0) { $Result->show("info", _("No new hosts found")."!", false); } 114# ok 115else { 116 // fetch subnet and set nsid 117 $nsid = $subnet===false ? false : $subnet->nameserverId; 118 119 // fetch custom fields and check for required 120 $Tools = new Tools ($Database); 121 $required_fields = $Tools->fetch_custom_fields ('ipaddresses'); 122 if($required_fields!==false) { 123 foreach ($required_fields as $k=>$f) { 124 if ($f['Null']!="NO") { 125 unset($required_fields[$k]); 126 } 127 } 128 } 129 130 // calculate colspan 131 $colspan = 5 + sizeof(@$required_fields); 132 // port 133 if(in_array('port', $selected_ip_fields)) { $colspan++; } 134 135 136 //form 137 print "<form name='scan-snmp-arp-form' class='scan-snmp-arp-form'>"; 138 print "<input type='hidden' name='csrf_cookie' value='$csrf'>"; 139 print "<table class='table table-striped table-top table-condensed'>"; 140 141 // titles 142 print "<tr>"; 143 print " <th>"._("IP")."</th>"; 144 print " <th>"._("Description")."</th>"; 145 print " <th>"._("MAC")."</th>"; 146 print " <th>"._("Hostname")."</th>"; 147 // port 148 if(in_array('port', $selected_ip_fields)) { 149 print " <th>"._('Port')."</th>"; 150 } 151 // custom 152 if (isset($required_fields)) { 153 foreach ($required_fields as $field) { 154 print "<th>"._($field['name'])."</th>"; 155 } 156 } 157 print " <th></th>"; 158 print "</tr>"; 159 160 // alive 161 $m=0; 162 foreach($found as $deviceid=>$device) { 163 foreach ($device as $ip ) { 164 print "<tr class='result$m'>"; 165 //resolve? 166 $hostname = $DNS->resolve_address($ip['ip'], false, true, $nsid); 167 168 //ip 169 print "<td>$ip[ip]</td>"; 170 //description, ip, device 171 print "<td>"; 172 print " <input type='text' class='form-control input-sm' name='description$m'>"; 173 print " <input type='hidden' name='ip$m' value='$ip[ip]'>"; 174 print " <input type='hidden' name='device$m' value='$deviceid'>"; 175 print "</td>"; 176 // mac 177 print "<td>"; 178 print " <input type='text' class='form-control input-sm' name='mac$m' value='$ip[mac]'>"; 179 print "</td>"; 180 //hostname 181 print "<td>"; 182 print " <input type='text' class='form-control input-sm' name='hostname$m' value='".@$hostname['name']."'>"; 183 print "</td>"; 184 // port 185 if(in_array('port', $selected_ip_fields)) { 186 print "<td>"; 187 print " <input type='text' class='form-control input-sm' name='port$m' value='".@$ip['port']."'>"; 188 print "</td>"; 189 } 190 // custom 191 if (isset($required_fields)) { 192 foreach ($required_fields as $field) { 193 # replace spaces with | 194 $field['nameNew'] = str_replace(" ", "___", $field['name']); 195 196 print ' <td>'. "\n"; 197 198 //set type 199 if(substr($field['type'], 0,3) == "set" || substr($field['type'], 0,4) == "enum") { 200 //parse values 201 $tmp = substr($field['type'], 0,3)=="set" ? explode(",", str_replace(array("set(", ")", "'"), "", $field['type'])) : explode(",", str_replace(array("enum(", ")", "'"), "", $field['type'])); 202 //null 203 if($field['Null']!="NO") { array_unshift($tmp, ""); } 204 205 print "<select name='$field[nameNew]$m' class='form-control input-sm input-w-auto' rel='tooltip' data-placement='right' title='$field[Comment]'>"; 206 foreach($tmp as $v) { 207 if($v==@$address[$field['name']]) { print "<option value='$v' selected='selected'>$v</option>"; } 208 else { print "<option value='$v'>$v</option>"; } 209 } 210 print "</select>"; 211 } 212 //date and time picker 213 elseif($field['type'] == "date" || $field['type'] == "datetime") { 214 // just for first 215 if($timeP==0) { 216 print '<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-datetimepicker.min.css?v='.SCRIPT_PREFIX.'">'; 217 print '<script src="js/bootstrap-datetimepicker.min.js?v='.SCRIPT_PREFIX.'"></script>'; 218 print '<script>'; 219 print '$(document).ready(function() {'; 220 //date only 221 print ' $(".datepicker").datetimepicker( {pickDate: true, pickTime: false, pickSeconds: false });'; 222 //date + time 223 print ' $(".datetimepicker").datetimepicker( { pickDate: true, pickTime: true } );'; 224 225 print '})'; 226 print '</script>'; 227 } 228 $timeP++; 229 230 //set size 231 if($field['type'] == "date") { $size = 10; $class='datepicker'; $format = "yyyy-MM-dd"; } 232 else { $size = 19; $class='datetimepicker'; $format = "yyyy-MM-dd"; } 233 234 //field 235 if(!isset($address[$field['name']])) { print ' <input type="text" class="'.$class.' form-control input-sm input-w-auto" data-format="'.$format.'" name="'. $field['nameNew'].$m .'" maxlength="'.$size.'" '.$delete.' rel="tooltip" data-placement="right" title="'.$field['Comment'].'">'. "\n"; } 236 else { print ' <input type="text" class="'.$class.' form-control input-sm input-w-auto" data-format="'.$format.'" name="'. $field['nameNew'].$m .'" maxlength="'.$size.'" value="'. $address[$field['name']]. '" '.$delete.' rel="tooltip" data-placement="right" title="'.$field['Comment'].'">'. "\n"; } 237 } 238 //boolean 239 elseif($field['type'] == "tinyint(1)") { 240 print "<select name='$field[nameNew]$m' class='form-control input-sm input-w-auto' rel='tooltip' data-placement='right' title='$field[Comment]'>"; 241 $tmp = array(0=>"No",1=>"Yes"); 242 //null 243 if($field['Null']!="NO") { $tmp[2] = ""; } 244 245 foreach($tmp as $k=>$v) { 246 if(strlen(@$address[$field['name']])==0 && $k==2) { print "<option value='$k' selected='selected'>"._($v)."</option>"; } 247 elseif($k==@$address[$field['name']]) { print "<option value='$k' selected='selected'>"._($v)."</option>"; } 248 else { print "<option value='$k'>"._($v)."</option>"; } 249 } 250 print "</select>"; 251 } 252 //default - input field 253 else { 254 print ' <input type="text" class="ip_addr form-control input-sm" name="'. $field['nameNew'].$m .'" placeholder="'. $field['name'] .'" value="'. @$address[$field['name']]. '" size="30" '.$delete.' rel="tooltip" data-placement="right" title="'.$field['Comment'].'">'. "\n"; 255 } 256 257 print " </td>"; 258 } 259 } 260 //remove button 261 print "<td><a href='' class='btn btn-xs btn-danger resultRemove' data-target='result$m'><i class='fa fa-times'></i></a></td>"; 262 print "</tr>"; 263 264 $m++; 265 } 266 } 267 268 //submit 269 print "<tr>"; 270 print " <td colspan='$colspan'>"; 271 print "<div id='subnetScanAddResult'></div>"; 272 print " <a href='' class='btn btn-sm btn-success pull-right' id='saveScanResults' data-script='scan-snmp-arp' data-subnetId='".$_POST['subnetId']."'><i class='fa fa-plus'></i> "._("Add discovered hosts")."</a>"; 273 print " </td>"; 274 print "</tr>"; 275 276 print "</table>"; 277 print "</form>"; 278 279 // print errors 280 if (isset($errors)) { 281 print "<hr>"; 282 foreach ($errors as $e) { 283 print $Result->show ("warning", $e, false); 284 } 285 } 286} 287 288//print scan method 289print "<div class='text-right' style='margin-top:7px;'>"; 290print " <span class='muted'>"; 291print " Scan method: SNMP ARP<hr>"; 292print " Scanned devices: <br>"; 293foreach ($debug as $k=>$d) { 294 print "· ".$k."<br>"; 295} 296print "</span>"; 297print "</div>"; 298 299# show debug? 300if($_POST['debug']==1) { print "<pre>"; print_r($debug); print "</pre>"; }