function quick_search($q) { global $conf, $self; // // *** Quick Search *** // // If it's an IP or MAC address (string or numeric): // Look for an interface and display associated host record // Look for the subnet that IP is on and display a single subnet record // If it's a string: // Look for a hostname // Look for an alias name (and display associated hosts) // Look for a subnet name printmsg("DEBUG => quick_search({$q}) called", 3); // Check to see if it is a MAC.. do it here instead of in the next interface section // so that we can properly find multiple hosts with the same mac $mac = mac_mangle($q, 1); if ($mac != -1) { printmsg("DEBUG => quick_search() Looks like a MAC, Returning mac = {$q}", 3); return array('hosts', array('mac' => $q)); } // See if $q identifies an interface record (by IP, MAC, etc) list($status, $rows, $record) = ona_find_interface($q); // If it was, display the associated host record if ($rows) { printmsg("DEBUG => quick_search() returning host match (ID={$record['host_id']})", 3); return array('hosts', array('host_id' => $record['host_id'])); } // See if $q identifies a subnet record (by IP, ID, or Description) list($status, $rows, $record) = ona_find_subnet($q); // If it was, display the associated subnet record if ($rows) { printmsg("DEBUG => quick_search() returning subnet match (ID={$record['id']})", 3); return array('subnets', array('subnet_id' => $record['id'])); } // Well, I guess we'll assume $q is a hostname/alias search printmsg("DEBUG => quick_search() found no subnet or host match. Returning hostname = {$q}", 3); return array('hosts', array('hostname' => $q)); }
function get_subnet_html($subnet_ip) { global $conf, $self, $onadb; global $font_family, $color, $style, $images; $html = $js = ''; $font_color = '#FFFFFF'; $style['content_box'] = <<<EOL margin: 10px 20px; padding: 2px 4px; background-color: #FFFFFF; vertical-align: top; EOL; $style['label_box'] = <<<EOL font-weight: bold; padding: 2px 4px; border: solid 1px {$color['border']}; background-color: {$color['window_content_bg']}; EOL; // Load the subnet record list($status, $rows, $subnet) = ona_find_subnet($subnet_ip); // If we didn't get one, tell them to add a record here if ($rows == 0 or $status) { // Calculate what the end of this block is so we can reccomend the max subnet size // GD: add IPv6 functionnality by imposing GMP use when not ipv4 subnet list($status, $rows, $subnets) = db_get_records($onadb, "subnets", "ip_addr > " . ip_mangle($subnet_ip, 'numeric'), "ip_addr", 1); if (!is_ipv4($subnet_ip)) { if ($rows >= 1) { $subnet_ip_end = gmp_sub(gmp_init($subnets[0]['ip_addr']), 1); $size = gmp_add(gmp_sub($subnet_ip_end, $subnet_ip), 1); if (gmp_mod($size, 2) == 1) { gmp_sub($size, 1); } // GD: very bad way to get the mask ... but gmp_log() does not exist ! for ($mask = 65; $mask > 48; $mask--) { if (gmp_cmp($size, gmp_pow("2", $mask)) > 0) { $mask++; break; } } $subnet['ip_addr'] = ip_mangle(gmp_strval($subnet_ip), 'dotted'); $subnet['ip_addr_end'] = ip_mangle(gmp_strval($subnet_ip_end), 'dotted'); $str_subnet_ip = gmp_strval($subnet_ip); $size = gmp_strval($size); } else { $subnet_ip_end = -1; $size = 0; } } else { if ($rows >= 1) { $subnet_ip_end = $subnets[0]['ip_addr'] - 1; $size = $subnet_ip_end - $subnet_ip + 1; if ($size % 2 == 1) { $size--; } $mask = ceil(32 - log($size) / log(2)); $subnet['ip_addr'] = ip_mangle($subnet_ip, 'dotted'); $subnet['ip_addr_end'] = ip_mangle($subnet_ip_end, 'dotted'); $str_subnet_ip = $subnet_ip; } else { $subnet_ip_end = -1; $size = 0; } } $html .= <<<EOL <!-- NO SUBNET --> <table cellspacing="0" border="0" cellpadding="0"> <!-- LABEL --> <tr><td width=100% colspan="2" nowrap="true" style="{$style['label_box']}"> <a title="Add a new subnet here" class="act" onClick="xajax_window_submit('edit_subnet', 'ip_addr=>{$str_subnet_ip}', 'editor');" >Add a subnet here</a> </td></tr> <tr> <td align="right" nowrap="true" style="color: {$font_color};"><b>IP Range</b> </td> <td class="padding" nowrap="true" align="left" style="color: {$font_color};">{$subnet['ip_addr']} - {$subnet['ip_addr_end']} ({$size} addresses)</td> </tr> EOL; $largest_subnet = array(0, 0, 0); // -- IPv4 if (is_ipv4($subnet_ip)) { $ip = $subnet_ip; while ($ip < $subnet_ip_end) { // find the largest mask for the specified ip $myip = ip_mangle($ip, 'dotted'); $mymask = $mask; while ($mymask <= 30) { $ip1 = ip_mangle($ip, 'binary'); $ip2 = str_pad(substr($ip1, 0, $mymask), 32, '0'); $mysize = pow(2, 32 - $mymask); $myhosts = $mysize - 2; $ip1 = ip_mangle($ip1, 'dotted'); $ip2 = ip_mangle($ip2, 'dotted'); if ($ip1 == $ip2 and $ip + $mysize - 1 <= $subnet_ip_end) { break; } $mymask++; } if ($mymask == 31) { break; } if ($mysize > $largest_subnet[2]) { $largest_subnet = array(ip_mangle($ip, 'dotted'), $mymask, $mysize); } $html .= <<<EOL <!-- <tr> <td align="right" nowrap="true" style="color: {$font_color};"> </td> <td class="padding" align="left" style="color: {$font_color};">{$myip} /{$mymask} ({$myhosts} hosts)</td> </tr> --> EOL; // Increment $ip $ip += $mysize; } // remove 2 for gateway and broadcast $largest_subnet[2] = $largest_subnet[2] - 2; } else { $ip = gmp_init($subnet_ip); // GD: trying to avoid falling into time/memory-trap // Won't enter in the loop if difference between IP and next subnet IP is too big // (more than 5 x /64) if (gmp_cmp(gmp_sub($subnet_ip_end, $ip), gmp_mul("18446744073709551616", "5")) > 0) { $html .= <<<EOL \t<tr> \t<td align="right" nowrap="true" style="color: {$font_color};"> </td> \t<td align="right" nowrap="true" style="color: {$font_color};">Next Subnet too far away</td> \t<tr> EOL; return array($html, $js); } while (gmp_cmp($ip, $subnet_ip_end) < 0) { // find the largest mask for the specified ip $myip = ip_mangle(gmp_strval($ip), 'dotted'); $mymask = $mask; while ($mymask <= 64) { $ip1 = ip_mangle(gmp_strval($ip), 'bin128'); $ip2 = str_pad(substr($ip1, 0, $mymask), 128, '0'); $mysize = gmp_pow("2", 128 - $mymask); $myhosts = gmp_strval(gmp_sub($mysize, 2)); $ip1 = ip_mangle($ip1, 'dotted'); $ip2 = ip_mangle($ip2, 'dotted'); if (strcmp($ip1, $ip2) == 0 and gmp_cmp(gmp_sub(gmp_add($ip, $mysize), 1), $subnet_ip_end) <= 0) { break; } $mymask++; } if ($mymask == 90) { break; } if (gmp_cmp($mysize, $largest_subnet[2]) > 0) { $largest_subnet = array(ip_mangle(gmp_strval($ip), 'dotted'), $mymask, $mysize); } $html .= <<<EOL <!-- <tr> <td align="right" nowrap="true" style="color: {$font_color};"> </td> <td class="padding" align="left" style="color: {$font_color};">{$mask} {$myip} /{$mymask} ({$myhosts} hosts)td> </tr> --> EOL; // Increment $ip $ip = gmp_add($ip, $mysize); } // DON'T remove 2 for gateway and broadcast $largest_subnet[2] = gmp_strval($largest_subnet[2]); } $html .= <<<EOL <tr> <td align="right" nowrap="true" style="color: {$font_color};"><b>Largest block</b> </td> <td class="padding" nowrap="true" align="left" style="color: {$font_color};">{$largest_subnet[0]} /{$largest_subnet[1]} ({$largest_subnet[2]} usable hosts)</td> </tr> </table> EOL; return array($html, $js); } // -- // -- FOUND SUBNET IN DB // -- // Convert IP and Netmask to a presentable format $subnet['ip_addr'] = ip_mangle($subnet['ip_addr'], 'dotted'); $subnet['ip_mask'] = ip_mangle($subnet['ip_mask'], 'dotted'); $subnet['ip_mask_cidr'] = ip_mangle($subnet['ip_mask'], 'cidr'); list($status, $rows, $type) = ona_get_subnet_type_record(array('id' => $subnet['subnet_type_id'])); $subnet['type'] = $type['display_name']; // Calculate the percentage of the subnet that's used (total size - allocated hosts - dhcp pool size) $usage_html = get_subnet_usage_html($subnet['id']); foreach (array_keys((array) $subnet) as $key) { $subnet[$key] = htmlentities($subnet[$key], ENT_QUOTES, $conf['php_charset']); } foreach (array_keys((array) $location) as $key) { $location[$key] = htmlentities($location[$key], ENT_QUOTES, $conf['php_charset']); } $html .= <<<EOL <!-- SUBNET INFORMATION --> <table cellspacing="0" border="0" cellpadding="0"> <!-- LABEL --> <tr><td width=100% colspan="2" nowrap="true" style="{$style['label_box']}"> <a title="View subnet. ID: {$subnet['id']}" class="nav" onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_subnet\\', \\'subnet_id=>{$subnet['id']}\\', \\'display\\')');" >{$subnet['name']}</a> </td></tr> <tr> <td align="right" nowrap="true" style="color: {$font_color};"><b>IP Address</b> </td> <td class="padding" align="left" style="color: {$font_color};">{$subnet['ip_addr']} /{$subnet['ip_mask_cidr']}</td> </tr> <tr> <td align="right" nowrap="true" style="color: {$font_color};"><b>Usage</b> </td> <td class="padding" align="left" style="color: {$font_color};">{$usage_html}</td> </tr> EOL; if ($subnet['type']) { $html .= <<<EOL <tr> <td align="right" nowrap="true" style="color: {$font_color};"><b>Type</b> </td> <td class="padding" align="left" style="color: {$font_color};">{$subnet['type']} </td> </tr> EOL; } $html .= <<<EOL </table> EOL; return array($html, $js); }
function message_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; // Default expiration $exp_default = "+6 week"; $pri_default = 3; // Priority is one of the following: // 0 = Informational // 1 = red or high // 2 = yellow or medium // 3 = green or low printmsg("DEBUG => message_add({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['subnet'] and !$options['host'] or !$options['message'] and (!$options['expiration'] and !$options['priority'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM message_add-v{$version} Adds the provided message to the host or subnet specified Synopsis: message_add Required: host=NAME[.DOMAIN]|IP hostname or IP of the host OR subnet=NAME|IP name or IP of the subnet message="STRING" the content of the message Optional: priority=NUMBER device/model type or ID (default: {$pri_default}) expiration=DATE date to expire message (default: NOW {$exp_default}s) Notes: Priority is one of the following: 0 = blue or Informational 1 = red or high 2 = yellow or medium 3 = green or low EOM ); } // If they provided a hostname / ID let's look it up if ($options['host']) { list($status, $rows, $host) = ona_find_host($options['host']); $table_name_ref = 'hosts'; $table_id_ref = $host['id']; $desc = $host['fqdn']; } else { if ($options['subnet']) { list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); $table_name_ref = 'subnets'; $table_id_ref = $subnet['id']; $desc = $subnet['name']; } } // If we didn't get a record then exit if (!$host['id'] and !$subnet['id']) { printmsg("DEBUG => No host or subnet found!", 3); $self['error'] = "ERROR => No host or subnet found!"; return array(4, $self['error'] . "\n"); } // Set the priority $priority = array_key_exists('priority', $options) ? $options['priority'] : $pri_default; if ($priority > 3 or $priority < 0 or !is_numeric($priority)) { $self['error'] = "ERROR => Priority must be a number between 0 and 3!"; return array(4, $self['error'] . "\n"); } // Get a username or "anonymous" $username = isset($_SESSION['username']) ? $_SESSION['username'] : "******"; // Expiration date format if ($options['expiration']) { $expiration = date("Y-m-d G:i:s", strtotime($options['expiration'])); } else { $expiration = date("Y-m-d G:i:s", strtotime($exp_default)); } // TODO: there should probably be some sort of security checks on the message that is passed in. // I suspect this could be a security issue. SQL injection etc. list($status, $rows) = db_insert_record($onadb, 'messages', array('table_name_ref' => $table_name_ref, 'table_id_ref' => $table_id_ref, 'priority' => $priority, 'username' => $username, 'expiration' => $expiration, 'message_text' => $options['message'])); if ($status or !$rows) { $self['error'] = "ERROR => message_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } $text = "INFO => Message ADDED to: {$desc}\n"; // Return the message file return array(0, $text); }
function dhcp_server_del($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_server_del({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is yes) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Return the usage summary if we need to if ($options['help'] or !($options['subnet'] and $options['server'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_server_del-v{$version} Removes a subnet record from a DHCP server Synopsis: dhcp_server_del [KEY=VALUE] ... Required: subnet=NAME or ID subnet name or ID server=NAME[.DOMAIN] or ID server name or ID Optional: commit=[Y|N] commit db transaction (no) Notes: DOMAIN will default to {$conf['dns_defaultdomain']} if not specified EOM ); } // Determine the entry itself exists list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); // Test to see that we were able to find the specified record if (!$subnet['id']) { printmsg("DEBUG => Unable to find the subnet record using {$options['subnet']}!", 3); $self['error'] = "ERROR => Unable to find the subnet record using {$options['subnet']}!"; return array(4, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_server_del(): Found subnet, {$subnet['name']}", 3); if ($options['server']) { // Determine the server is valid list($status, $rows, $host) = ona_find_host($options['server']); if (!$host['id']) { printmsg("DEBUG => The server ({$options['server']}) does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(2, $self['error'] . "\n"); } } //printmsg("DEBUG => dhcp_server_del(): Found server, {$host['FQDN']}", 3); // Test that this subnet is even assigned to the server list($status, $rows, $dhcpserver) = ona_get_dhcp_server_subnet_record(array('host_id' => $host['id'], 'subnet_id' => $subnet['id'])); if (!$rows) { printmsg("DEBUG => Unable to find {$subnet['name']} on server {$host['fqdn']}", 3); $self['error'] = "ERROR => Unable to find {$subnet['name']} on server {$host['fqdn']}"; return array(11, $self['error'] . "\n"); } // If "commit" is yes, delete the record if ($options['commit'] == 'Y') { // Check permissions if (!auth('advanced') or !authlvl($host['LVL']) or !authlvl($subnet['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // check if allowed to remove subnet from server // check for pool assigned to the server itself list($status, $rows, $pools) = db_get_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); foreach ($pools as $pool) { if ($pool['dhcp_failover_group_id']) { $foundfg = 0; list($status, $rows, $primary) = ona_get_dhcp_failover_group_record(array('id' => $pool['dhcp_failover_group_id'], 'primary_server_id' => $host['id'])); if ($rows) { $foundfg++; } list($status, $rows, $secondary) = ona_get_dhcp_failover_group_record(array('id' => $pool['dhcp_failover_group_id'], 'secondary_server_id' => $host['id'])); if ($rows) { $foundfg++; } // if a subnet/server pair is found in dhcp pools, don't allow removal if ($foundfg > 0) { printmsg("DEBUG => Subnet ({$subnet['name']}) has a pool assigned to this Server ({$host['fqdn']}), which is part of a failover group. The server must be removed from the failover group first.", 3); $self['error'] = "ERROR => Subnet ({$subnet['name']}) has a pool assigned to this Server ({$host['fqdn']}), which is part of a failover group. The server must be removed from the failover group first."; return array(12, $self['error'] . "\n"); } } } // MP: remove this after testing. dhcp options should not stop us from dis-associating a subnet from a server // Not really sure why I have this.. probably left over cruft from old thoughts // // check if there are any DHCP parameters assigned to the subnet // list($status, $rows, $tmp) = ona_get_dhcp_option_entry_record(array('subnet_id' => $subnet['id'])); // // // if so, check that this is not the last DHCP server that services this subnet // if ($rows > 0) { // list($status, $rows, $tmp) = ona_get_dhcp_server_subnet_record(array('subnet_id' => $subnet['id'])); // // // If this is the last DHCP server that services this subnet, don't allow removal until DHCP parameters are removed // if($rows <= 1){ // printmsg("DEBUG => Subnet ({$subnet['name']}) has DHCP parameters assigned which need to be removed first",3); // $self['error'] = "ERROR => Subnet ({$subnet['name']}) has DHCP parameters assigned which need to be removed first"; // return(array(12, $self['error'] . "\n")); // } // } // delete record from dhcp_server_subnets list($status, $rows) = db_delete_records($onadb, 'dhcp_server_subnets', array('id' => $dhcpserver['id'])); if ($status) { $self['error'] = "ERROR => dhcp_server_del() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP Subnet/Server Pair DELETED: {$subnet['name']}/{$host['fqdn']} "; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); } // Otherwise display the record that would have been deleted $text = <<<EOL Record(s) NOT DELETED (see "commit" option) Displaying record(s) that would have been removed: {$subnet['name']} from: {$host['fqdn']} EOL; return array(6, $text); }
function rpt_get_data($form) { global $base, $onadb; // If they want to perform a scan on an existing file if ($form['subnet']) { $rptdata['scansource'] = "Based on an existing scan file for '{$form['subnet']}'"; //$xml = shell_exec("{$nmapcommand} -sP -R -oX - {$form['subnet']}"); list($status, $rows, $subnet) = ona_find_subnet($form['subnet']); if ($rows) { $netip = ip_mangle($subnet['ip_addr'], 'dotted'); $netcidr = ip_mangle($subnet['ip_mask'], 'cidr'); $nmapxmlfile = "{$base}/local/nmap_scans/subnets/{$netip}-{$netcidr}.xml"; if (file_exists($nmapxmlfile)) { $xml[0] = xml2ary(file_get_contents($nmapxmlfile)); } else { $self['error'] = "ERROR => The subnet '{$form['subnet']}' does not have an nmap scan XML file on this server. {$nmapxmlfile}"; return array(2, $self['error'] . "\n"); } } else { $self['error'] = "ERROR => The subnet '{$form['subnet']}' does not exist."; return array(2, $self['error'] . "\n"); } } // If they want to build a report on ALL the nmap data if ($form['all']) { $rptdata['scansource'] = "Showing all scan data"; $nmapdir = "{$base}/local/nmap_scans/subnets"; $dh = @opendir($nmapdir); $c = 0; while (false !== ($filename = @readdir($dh))) { if (strpos($filename, 'xml')) { $xml[$c] = xml2ary(file_get_contents($nmapdir . '/' . $filename)); } $c++; } } // If they pass a file from the remote host via CLI if ($form['file']) { $rptdata['scansource'] = "Based on an uploaded XML file"; $nmapxmlfile = $form['file']; // clean up escaped characters $nmapxmlfile = preg_replace('/\\\\"/', '"', $nmapxmlfile); $nmapxmlfile = preg_replace('/\\\\=/', '=', $nmapxmlfile); $nmapxmlfile = preg_replace('/\\\\&/', '&', $nmapxmlfile); $xml[0] = xml2ary($nmapxmlfile); } // loop through all the xml arrays that have been built. for ($z = 0; $z < count($xml); $z++) { // Find out how many total hosts we have in the array $rptdata['totalhosts'] = $xml[$z]['nmaprun']['_c']['runstats']['_c']['hosts']['_a']['total']; $rptdata['runtime'] = $xml[$z]['nmaprun']['_c']['runstats']['_c']['finished']['_a']['timestr']; // pull args to find subnet/cidr $rptdata['args'] = $xml[$z]['nmaprun']['_a']['args']; // process args list($subnetaddr, $netcidr) = explode('/', preg_replace("/.* (.*)\\/(\\d+)\$/", "\\1/\\2", $rptdata['args'])); $netip = ip_mangle($subnetaddr, 'dotted'); $netcidr = ip_mangle($netcidr, 'cidr'); // Process the array for the total amount of hosts reported for ($i = 0; $i < $rptdata['totalhosts']; $i++) { // Clear MAC each itteration of the loop $macaddr = ''; // Gather some info from the nmap XML file $netstatus = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['status']['_a']['state']; $ipaddr = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['address']['_a']['addr']; //$macaddr = $xml['nmaprun']['_c']['host'][$i]['_c']['address']['_a']['addr']; $dnsname = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['hostnames']['_c']['hostname']['_a']['name']; $dnsrows = 0; $dns = array(); // Try the older nmap format if no IP found.. not sure of what differences there are in the XSL used? if (!$ipaddr) { $ipaddr = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['address']['0']['_a']['addr']; $macaddr = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['address']['1']['_a']['addr']; } // Lookup the IP address in the database if ($ipaddr) { list($status, $introws, $interface) = ona_find_interface($ipaddr); if (!$introws) { $interface['ip_addr_text'] = 'NOT FOUND'; list($status, $introws, $tmp) = ona_find_subnet($ipaddr); $interface['subnet_id'] = $tmp['id']; } else { // Lookup the DNS name in the database list($status, $dnsrows, $dnscount) = db_get_records($onadb, 'dns', "interface_id = {$interface['id']}", "", 0); list($status, $dnsptrrows, $dnsptr) = ona_get_dns_record(array('interface_id' => $interface['id'], 'type' => 'PTR')); list($status, $dnsprows, $dns) = ona_get_dns_record(array('id' => $dnsptr['dns_id'])); } } // Find out if this IP falls inside of a pool $inpool = 0; $ip = ip_mangle($ipaddr, 'numeric'); if ($ip > 0) { list($status, $poolrows, $pool) = ona_get_dhcp_pool_record("ip_addr_start <= '{$ip}' AND ip_addr_end >= '{$ip}'"); } if ($poolrows) { $inpool = 1; } // some base logic // if host is up in nmap but no db ip then put in $nodb // if host is up and is in db then put in $noissue // if host is down and not in db then skip // if host is down and in db then put in $nonet // if host is up an in db, does DNS match? // in DNS but not DB // in DB but not DNS // DNS and DB dont match // Setup the base array element for the IP $rptdata['ip'][$ipaddr] = array(); $rptdata['ip'][$ipaddr]['netstatus'] = $netstatus; $rptdata['ip'][$ipaddr]['netip'] = $ipaddr; $rptdata['ip'][$ipaddr]['netdnsname'] = strtolower($dnsname); if ($macaddr != -1) { $rptdata['ip'][$ipaddr]['netmacaddr'] = $macaddr; } $rptdata['ip'][$ipaddr]['inpool'] = $inpool; $rptdata['ip'][$ipaddr]['dbip'] = $interface['ip_addr_text']; $rptdata['ip'][$ipaddr]['dbsubnetid'] = $interface['subnet_id']; $rptdata['ip'][$ipaddr]['dbdnsrows'] = $dnsrows; if (!$dns['fqdn']) { // lets see if its a PTR record if ($dnsptrrows) { // If we have a PTR for this interface, use it (never if built from ona?) $rptdata['ip'][$ipaddr]['dbdnsname'] = $dns['fqdn']; $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $dnsp['fqdn']; } else { // find the hosts primary DNS record list($status, $hostrows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); if ($host['fqdn']) { $host['fqdn'] = "({$host['fqdn']})"; } if ($dnsrows) { list($status, $dnstmprows, $dnstmp) = ona_get_dns_record(array('interface_id' => $interface['id'])); $rptdata['ip'][$ipaddr]['dbdnsname'] = $dnstmp['fqdn']; } else { $rptdata['ip'][$ipaddr]['dbdnsname'] = 'NO PTR'; } $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $host['fqdn']; } } else { if ($dnsptrrows > 1) { $rptdata['ip'][$ipaddr]['dbdnsname'] = $dns['fqdn']; $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $dnsp['fqdn']; } else { $rptdata['ip'][$ipaddr]['dbdnsname'] = $dns['fqdn']; $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $dnsp['fqdn']; } } $rptdata['ip'][$ipaddr]['dbmacaddr'] = $interface['mac_addr']; $rptdata['netip'] = $netip; $rptdata['netcidr'] = $netcidr; if ($form['all']) { $rptdata['all'] = 1; } if ($form['update_response']) { $rptdata['update_response'] = 1; } } } return array(0, $rptdata); }
function ws_display_list($window_name, $form = '') { global $conf, $self, $onadb; global $images, $color, $style; $html = ''; $js = ''; // If the user supplied an array in a string, build the array and store it in $form $form = parse_options_string($form); // Find the "tab" we're on $tab = $_SESSION['ona'][$form['form_id']]['tab']; // Build js to refresh this list $refresh = "xajax_window_submit('{$window_name}', xajax.getFormValues('{$form['form_id']}'), 'display_list');"; // If it's not a new query, load the previous query from the session // into $form and save the current page and filter in the session. // Also find/set the "page" we're viewing $page = 1; if ($form['page'] and is_numeric($form['page'])) { $form = array_merge($form, (array) $_SESSION['ona'][$form['form_id']][$tab]['q']); $_SESSION['ona'][$form['form_id']][$tab]['page'] = $page = $form['page']; $_SESSION['ona'][$form['form_id']][$tab]['filter'] = $form['filter']; } printmsg("DEBUG => Displaying subnets list page: {$page}", 1); // Calculate the SQL query offset (based on the page being displayed) $offset = $conf['search_results_per_page'] * ($page - 1); if ($offset == 0) { $offset = -1; } // Search results go in here $results = array(); $count = 0; // // *** ADVANCED SUBNET SEARCH *** // FIND RESULT SET // // Start building the "where" clause for the sql query to find the subnets to display $where = ""; $and = ""; // enable or disable wildcards $wildcard = '%'; if ($form['nowildcard']) { $wildcard = ''; } // DISPLAY ALL if ($form['all_flag']) { $where .= $and . "id > 0"; $and = " AND "; } // SUBNET ID if ($form['subnet_id']) { $where .= $and . "id = " . $form['subnet_id']; $and = " AND "; } // VLAN ID if ($form['vlan_id']) { $where .= $and . "vlan_id = " . $onadb->qstr($form['vlan_id']); $and = " AND "; } // SUBNET TYPE if ($form['nettype']) { $where .= $and . "subnet_type_id = " . $onadb->qstr($form['nettype']); $and = " AND "; } // find subnets that are associated with dhcp server if ($form['server_id']) { $where .= $and . "id IN (SELECT subnet_id FROM dhcp_server_subnets WHERE host_id = " . $onadb->qstr($form['server_id']) . ')'; $and = " AND "; } // SUBNET NAME if ($form['subnetname']) { // This field is always upper case $form['subnetname'] = strtoupper($form['subnetname']); $where .= $and . "name LIKE " . $onadb->qstr($wildcard . $form['subnetname'] . $wildcard); $and = " AND "; } // IP ADDRESS if ($form['ip_subnet']) { // Build $ip and $ip_end from $form['ip_subnet'] and $form['ip_subnet_thru'] $ip = ip_complete($form['ip_subnet'], '0'); if ($form['ip_subnet_thru']) { $ip = ip_complete($form['ip_subnet'], '0'); $ip_end = ip_complete($form['ip_subnet_thru'], '255'); // Find out if $ip and $ip_end are valid $ip = ip_mangle($ip, 'numeric'); $ip_end = ip_mangle($ip_end, 'numeric'); if ($ip != -1 and $ip_end != -1) { // Find subnets between the specified ranges $where .= $and . " ip_addr >= " . $ip . " AND ip_addr <= " . $ip_end; $and = " AND "; } } else { list($status, $rows, $record) = ona_find_subnet($ip); if ($rows) { $where .= $and . " id = " . $record['id']; $and = " AND "; } } } // tag if ($form['tag_net']) { $where .= $and . "id in (select reference from tags where type like 'subnet' and name like " . $onadb->qstr($form['tag_net']) . ")"; $and = " AND "; } // custom attribute type if ($form['custom_attribute_type_net']) { $where .= $and . "id in (select table_id_ref from custom_attributes where table_name_ref like 'subnets' and custom_attribute_type_id = (SELECT id FROM custom_attribute_types WHERE name = " . $onadb->qstr($form['custom_attribute_type_net']) . "))"; $and = " AND "; $cavaluetype = "and custom_attribute_type_id = (SELECT id FROM custom_attribute_types WHERE name = " . $onadb->qstr($form['custom_attribute_type_net']) . ")"; } // custom attribute value if ($form['ca_value_net']) { $where .= $and . "id in (select table_id_ref from custom_attributes where table_name_ref like 'subnets' {$cavaluetype} and value like " . $onadb->qstr($wildcard . $form['ca_value_net'] . $wildcard) . ")"; $and = " AND "; } // display a nice message when we dont find all the records if ($where == '' and $form['content_id'] == 'search_results_list') { $js .= "el('search_results_msg').innerHTML = 'Unable to find subnets matching your query, showing all records';"; } // Wild card .. if $where is still empty, add a 'ID > 0' to it so you see everything. if ($where == '') { $where = 'id > 0'; } // Do the SQL Query $filter = ''; if ($form['filter']) { // Subnet namess are always upper case $form['filter'] = strtoupper($form['filter']); $filter = ' AND name LIKE ' . $onadb->qstr('%' . $form['filter'] . '%'); } list($status, $rows, $results) = db_get_records($onadb, 'subnets', $where . $filter, "ip_addr", $conf['search_results_per_page'], $offset); // If we got less than search_results_per_page, add the current offset to it // so that if we're on the last page $rows still has the right number in it. if ($rows > 0 and $rows < $conf['search_results_per_page']) { $rows += $conf['search_results_per_page'] * ($page - 1); } else { if ($rows >= $conf['search_results_per_page']) { list($status, $rows, $records) = db_get_records($onadb, 'subnets', $where . $filter, "", 0); } } $count = $rows; // // *** BUILD HTML LIST *** // $html .= <<<EOL <!-- Subnet Results --> <table id="{$form['form_id']}_subnet_list" class="list-box" cellspacing="0" border="0" cellpadding="0"> <!-- Table Header --> <tr> <td class="list-header" align="center" style="{$style['borderR']};">Name</td> <td class="list-header" align="center" style="{$style['borderR']};">Subnet</td> <td class="list-header" align="center" style="{$style['borderR']};">Usage</td> <td class="list-header" align="center" style="{$style['borderR']};">Type</td> <td class="list-header" align="center"> </td> </tr> EOL; // Loop and display each record foreach ($results as $record) { // Get additional info about eash subnet record // // Convert IP and Netmask to a presentable format $record['ip_addr'] = ip_mangle($record['ip_addr'], 'dotted'); $record['ip_mask'] = ip_mangle($record['ip_mask'], 'dotted'); $record['IP_SUBNET_MASK_CIDR'] = ip_mangle($record['ip_mask'], 'cidr'); list($status, $rows, $type) = ona_get_subnet_type_record(array('id' => $record['subnet_type_id'])); $record['type'] = $type['display_name']; // Calculate the percentage of the subnet that's used (total size - allocated hosts - dhcp pool size) $usage_html = get_subnet_usage_html($record['id']); // Escape data for display in html foreach (array_keys($record) as $key) { $record[$key] = htmlentities($record[$key], ENT_QUOTES, $conf['php_charset']); } $primary_object_js = "xajax_window_submit('work_space', 'xajax_window_submit(\\'display_subnet\\', \\'subnet_id=>{$record['id']}\\', \\'display\\')');"; $html .= <<<EOL <tr onMouseOver="this.className='row-highlight'" onMouseOut="this.className='row-normal'"> <td class="list-row"> <a title="View subnet. ID: {$record['id']}" class="nav" onClick="{$primary_object_js}" >{$record['name']}</a> </td> <td class="list-row" align="left"> {$record['ip_addr']} <span title="{$record['ip_mask']}">/{$record['IP_SUBNET_MASK_CIDR']}</span> </td> <td class="list-row" align="center" style="vertical-align: middle;"> {$usage_html} </td> <td class="list-row" align="left"> {$record['type']} </td> <td class="list-row" align="right"> <form id="{$form['form_id']}_list_subnet_{$record['id']}" ><input type="hidden" name="subnet_id" value="{$record['id']}" ><input type="hidden" name="js" value="{$refresh}" ></form> <a title="Display subnet map" class="act" onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_block_map\\', \\'ip_block_start=>{$record['ip_addr']}\\', \\'display\\');');" ><img src="{$images}/silk/shape_align_left.png" border="0"></a> EOL; if (auth('subnet_modify')) { $html .= <<<EOL <a title="Edit subnet" class="act" onClick="xajax_window_submit('edit_subnet', xajax.getFormValues('{$form['form_id']}_list_subnet_{$record['id']}'), 'editor');" ><img src="{$images}/silk/page_edit.png" border="0"></a> EOL; } if (auth('subnet_del')) { $html .= <<<EOL <a title="Delete subnet" class="act" onClick="var doit=confirm('Are you sure you want to delete this subnet?'); if (doit == true) xajax_window_submit('edit_subnet', xajax.getFormValues('{$form['form_id']}_list_subnet_{$record['id']}'), 'delete');" ><img src="{$images}/silk/delete.png" border="0"></a> EOL; } $html .= <<<EOL </td> </tr> EOL; } $html .= <<<EOL </table> EOL; // Build page links if there are any $html .= get_page_links($page, $conf['search_results_per_page'], $count, $window_name, $form['form_id']); // If there was only 1 result, and we're about to display results in the "Search Results" window, display it. if ($count == 1 and $form['content_id'] == 'search_results_list' and $form['filter'] == '') { $js .= $primary_object_js; } // Insert the new html into the content div specified // Instantiate the xajaxResponse object $response = new xajaxResponse(); $response->addAssign("{$form['form_id']}_{$tab}_count", "innerHTML", "({$count})"); $response->addAssign($form['content_id'], "innerHTML", $html); if ($js) { $response->addScript($js); } return $response->getXML(); }
function custom_attribute_display($options = "") { // The important globals global $conf, $self, $onadb; $text_array = array(); // Version - UPDATE on every edit! $version = '1.02'; printmsg("DEBUG => custom_attribute_display({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['host'] and !$options['id'] and !$options['subnet'] and !$options['vlan']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM custom_attribute_display-v{$version} Display the custom attribute specified or attributes for a host Synopsis: custom_attribute_display Where: id=ID custom attribute ID OR host=ID or NAME[.DOMAIN] display custom attributes for specified host OR subnet=ID or NAME display custom attributes for specified subnet OR vlan=NAME display custom attributes for specified VLAN Optional: type=ID or NAME If you specify a type and a host or subnet you will only get back a 1 or a 0 indicating that that type is set or not set for the host or subnet EOM ); } // if a type was set, check if it is associated with the host or subnet and return 1 or 0 if ($options['type']) { $field = is_numeric($options['type']) ? 'id' : 'name'; list($status, $rows, $catype) = ona_get_custom_attribute_type_record(array($field => $options['type'])); // error if we cant find the type specified if (!$catype['id']) { $self['error'] = "ERROR => The custom attribute type specified, {$options['type']}, does not exist!"; return array(5, $self['error']); } $where['custom_attribute_type_id'] = $catype['id']; } // Search for the host first if ($options['host']) { list($status, $rows, $host) = ona_find_host($options['host']); // Error if the host doesn't exist if (!$host['id']) { $self['error'] = "ERROR => The host specified, {$options['host']}, does not exist!"; return array(2, $self['error']); } else { $where['table_id_ref'] = $host['id']; $where['table_name_ref'] = 'hosts'; list($status, $rows, $cas) = db_get_records($onadb, 'custom_attributes', $where); } $anchor = 'host'; $desc = $host['fqdn']; } // Search for subnet if ($options['subnet']) { list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); // Error if the record doesn't exist if (!$subnet['id']) { $self['error'] = "ERROR => The subnet specified, {$options['subnet']}, does not exist!"; return array(3, $self['error']); } else { $where['table_id_ref'] = $subnet['id']; $where['table_name_ref'] = 'subnets'; list($status, $rows, $cas) = db_get_records($onadb, 'custom_attributes', $where); } $anchor = 'subnet'; $desc = $subnet['description']; } // Search for vlan if ($options['vlan']) { list($status, $rows, $vlan) = ona_find_vlan($options['vlan']); // Error if the record doesn't exist if (!$vlan['id']) { $self['error'] = "ERROR => The VLAN specified, {$options['vlan']}, does not exist!"; return array(3, $self['error']); } else { $where['table_id_ref'] = $vlan['id']; $where['table_name_ref'] = 'vlans'; list($status, $rows, $cas) = db_get_records($onadb, 'custom_attributes', $where); } $anchor = 'vlan'; $desc = $vlan['description']; } // Now find the ID of the record, returns a specific record only if ($options['id']) { list($status, $rows, $ca) = ona_get_custom_attribute_record(array('id' => $options['id'])); if (!$ca['id']) { $self['error'] = "ERROR => The custom attribute specified, {$options['id']}, is invalid!"; return array(4, $self['error']); } $text_array = $ca; $text .= "CUSTOM ATTRIBUTE ENTRY RECORD ({$ca['id']})\n"; $text .= format_array($ca); } elseif ($options['type']) { // If we requested type, now is the time to return a response if it is found associated. if ($cas[0]) { $text .= '1'; $text_array['has_attribute'] = 'Y'; } else { $text .= '0'; $text_array['has_attribute'] = 'N'; } } else { // Build text to return $text .= strtoupper($anchor) . " CUSTOM ATTRIBUTE RECORDS ({$desc})\n"; // Display the record(s) $i = 0; do { $text .= "\nASSOCIATED CUSTOM ATTRIBUTE ENTRY RECORD ({$i} of {$rows})\n"; $text .= format_array($cas[$i]); list($status, $carows, $ca) = ona_get_custom_attribute_type_record(array('id' => $cas[$i]['custom_attribute_type_id'])); $text_array[$ca['name']] = $cas[$i]['value']; $i++; } while ($i < $rows); } // change the output format if other than default if ($options['format'] == 'json') { $text = $text_array; } if ($options['format'] == 'yaml') { $text = $text_array; } // Return the success notice return array(0, $text); }
function subnet_nextip($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg('DEBUG => subnet_del(' . $options . ') called', 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is no) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Return the usage summary if we need to if ($options['help'] or !$options['subnet']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM subnet_del-v{$version} Return the next available IP address on a subnet. Synopsis: subnet_nextip [KEY=VALUE] ... Required: subnet=IP or ID select subnet by search string Optional: offset=NUMBER Starting offset to find next available IP output=[dotted|numeric] Return the number as a dotted or numeric value DEFAULT: numeric EOM ); } // Find the subnet record we're deleting list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); if ($status or !$rows) { $self['error'] = "ERROR => Subnet not found"; return array(2, $self['error'] . "\n"); } // Create a few variables that will be handy later $num_ips = 0xffffffff - $subnet['ip_mask']; $last_ip = $subnet['ip_addr'] + $num_ips - 1; // check that offset is a number if (isset($options['offset']) and !is_numeric($options['offset'])) { $self['error'] = "ERROR => Offset must be a numeric number"; return array(3, $self['error'] . "\n"); } else { $offsetmsg = " beyond offset {$options['offset']}"; } // make sure the offset does not extend beyond the specified subnet if ($options['offset'] >= $num_ips - 1) { $self['error'] = "ERROR => Offset extends beyond specified subnet boundary"; return array(4, $self['error'] . "\n"); } if (!isset($options['output'])) { $options['output'] = '1'; } else { if ($options['output'] != 'dotted' && $options['output'] != 'numeric') { $self['error'] = "ERROR => Output option must be 'dotted' or 'numeric'"; return array(5, $self['error'] . "\n"); } } // Find the first number based on our subnet and offset $ip = $subnet['ip_addr'] + $options['offset']; // Make sure we skip past the subnet IP to the first usable IP if ($ip == $subnet['ip_addr']) { $ip++; } // Start looping through our IP addresses until we find an available one while ($ip <= $last_ip) { // Find out if the ip is used in an interface list($status, $rows, $interfaces) = db_get_records($onadb, 'interfaces', array('ip_addr' => $ip)); // If we find a free address.. check that it is not in a DHCP pool if (!$rows) { list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', "{$ip} >= ip_addr_start AND {$ip} <= ip_addr_end"); if ($rows) { $ip = $pool['ip_addr_end']; } else { break; } } $ip++; // increment by one and check again } // If we checked all the IPs, make sure we are not on the broadcast IP of the subnet if ($ip == $last_ip + 1) { $self['error'] = "ERROR => No available IP addresses found on subnet{$offsetmsg}"; return array(5, $self['error'] . "\n"); } // return the IP return array(0, ip_mangle($ip, $options['output']) . "\n"); }
function dhcp_pool_modify($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_pool_modify({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['pool'] and ($options['set_failover_group'] or $options['set_start'] or $options['set_end'] or $options['set_llength'] or $options['set_lgrace'] or $options['set_lrenewal'] or $options['set_lrebind']))) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_pool_modify-v{$version} Updates a dhcp pool in the database pointing to the specified identifier Synopsis: dhcp_pool_modify [KEY=VALUE] ... Where: pool=ID Table ID for the pool Optional: set_failover_group=ID group identifier set_server=NAME[.DOMAIN] or ID server identifier set_start=IP Start ip address of pool set_end=IP End IP of pool set_llength=NUMBER Lease Time. Default ({$conf['dhcp_pool']['llength']}) set_lgrace=NUMBER Lease Grace Period. Default ({$conf['dhcp_pool']['lgrace']}) set_lrenewal=NUMBER Lease Renewal. Default ({$conf['dhcp_pool']['lrenewal']}) set_lrebind=NUMBER Lease Rebind. Default ({$conf['dhcp_pool']['lrebind']}) EOM ); } // get the existing pool to edit list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', array('id' => $options['pool'])); if (!$rows) { printmsg("DEBUG => Unable to find the DHCP pool record using id: {$options['id']}!", 3); $self['error'] = "ERROR => Unable to find a pool using id: {$options['pool']}"; return array(1, $self['error'] . "\n"); } // set the pool id in the set variable $SET['id'] = $pool['id']; // NOTE: currently modify pool does not allow you to change subnets // Get subnet info.. list($status, $rows, $subnet) = ona_find_subnet($pool['subnet_id']); $SET['subnet_id'] = $subnet['id']; // make sure that the start address is actually part of an existing subnet if ($options['set_start']) { list($status, $rows, $subnetstart) = ona_find_subnet(ip_mangle($options['set_start'], 'dotted')); if (!$rows) { printmsg("DEBUG => Unable to find a subnet related to starting address ({$options['set_start']})!", 3); $self['error'] = "ERROR => Unable to find a subnet related to your starting address of {$options['set_start']}."; return array(1, $self['error'] . "\n"); } if ($subnetstart['id'] != $pool['subnet_id']) { printmsg("DEBUG => The starting address ({$options['set_start']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!", 3); $self['error'] = "ERROR => The starting address ({$options['set_start']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!"; return array(1, $self['error'] . "\n"); } } // make sure that the end address is actually part of an existing subnet if ($options['set_end']) { list($status, $rows, $subnetend) = ona_find_subnet(ip_mangle($options['set_end'], 'dotted')); if (!$rows) { printmsg("DEBUG => Unable to find a subnet related to ending address ({$options['set_end']})!", 3); $self['error'] = "ERROR => Unable to find a subnet related to your ending address of {$options['set_end']}."; return array(1, $self['error'] . "\n"); } if ($subnetend['id'] != $pool['subnet_id']) { printmsg("DEBUG => The ending address ({$options['set_end']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!", 3); $self['error'] = "ERROR => The ending address ({$options['set_end']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!"; return array(1, $self['error'] . "\n"); } } // Assign which failover group to use if ($options['set_failover_group'] == 0) { $desc = 'Not using a failover group'; $SET['dhcp_failover_group_id'] = 0; } else { list($status, $rows, $fg) = ona_get_dhcp_failover_group_record(array('id' => $options['set_failover_group'])); if (!$fg['id']) { printmsg("DEBUG => The failover_group specified ({$options['set_failover_group']}) does not exist", 3); $self['error'] = "ERROR => The failover_group specified ({$options['set_failover_group']}) does not exist!"; return array(4, $self['error'] . "\n"); } // get the server names for the two servers list($fail_host1, $fail_zone1) = ona_find_host($fg['primary_server_id']); list($fail_host2, $fail_zone2) = ona_find_host($fg['secondary_server_id']); $desc = $fail_host1['fqdn'] . '/' . $fail_host2['fqdn']; $SET['dhcp_failover_group_id'] = $fg['id']; } // check that start and end are not the same //if ($options['set_start'] and $options['set_end'] and $options['set_start'] == $options['set_end']) { // printmsg("DEBUG => The start and end IP addresses (" . ip_mangle($options['set_start'],'dotted') . ") cannot be the same!",3); // $self['error'] = "ERROR => The start and end IP addresses (" . ip_mangle($options['set_start'],'dotted') . ") cannot be the same!"; // return(array(2, $self['error'] . "\n")); //} if ($options['set_start']) { $start_dec = ip_mangle($options['set_start'], 'numeric'); } else { $start_dec = $pool['ip_addr_start']; } if ($options['set_end']) { $end_dec = ip_mangle($options['set_end'], 'numeric'); } else { $end_dec = $pool['ip_addr_end']; } $net_end = 4294967295 - $subnet['ip_mask'] + $subnet['ip_addr']; // Validate that the IP address supplied isn't the base or broadcast of the subnet if ($start_dec == $subnet['ip_addr'] or $end_dec == $subnet['ip_addr']) { printmsg("DEBUG => IP address can't be a subnet's base address (" . ip_mangle($subnet['ip_addr'], 'dotted') . ")!", 3); $self['error'] = "ERROR => IP address can't be a subnet's base address (" . ip_mangle($subnet['ip_addr'], 'dotted') . ")!"; return array(7, $self['error'] . "\n"); } if ($start_dec == $net_end or $end_dec == $net_end) { printmsg("DEBUG => IP address can't be a subnet's broadcast address (" . ip_mangle($net_end, 'dotted') . ")!", 3); $self['error'] = "ERROR => IP address can't be the subnet broadcast address(" . ip_mangle($net_end, 'dotted') . ")!"; return array(8, $self['error'] . "\n"); } // check that start is not after the end if ($start_dec > $end_dec) { printmsg("DEBUG => The start IP addresses (" . ip_mangle($start_dec, 'dotted') . ") falls after the end IP address (" . ip_mangle($end_dec, 'dotted') . ")!", 3); $self['error'] = "ERROR => The start IP addresses (" . ip_mangle($start_dec, 'dotted') . ") falls after the end IP address(" . ip_mangle($end_dec, 'dotted') . ")!"; return array(2, $self['error'] . "\n"); } // check for existing hosts inside the pool range list($status, $rows, $interface) = db_get_records($onadb, 'interfaces', 'subnet_id = ' . $subnet['id'] . ' AND ip_addr BETWEEN ' . $start_dec . ' AND ' . $end_dec, '', 0); if ($rows) { printmsg("DEBUG => IP conflict: Specified range (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") encompasses {$rows} host(s)!", 3); $self['error'] = "ERROR => IP conflict: Specified range (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") encompasses {$rows} host(s)"; return array(4, $self['error'] . "\n"); } // *** Check to see if the new pool overlaps any existing pools *** // // Look for overlaps like this (where new pool address starts inside an existing pool): // [ -- new pool -- ] // [ -- old pool --] list($status, $rows, $tmp) = db_get_record($onadb, 'dhcp_pools', 'id != ' . $SET['id'] . ' AND ' . $start_dec . ' BETWEEN ip_addr_start AND ip_addr_end'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict: New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") starts inside an existing pool!", 3); $self['error'] = "ERROR => Pool address conflict! New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") starts inside an existing pool."; return array(5, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$tmp['id']}\n"); } // Look for overlaps like this (where the new pool ends inside an existing pool): // [ -- new pool -- ] // [ -- old pool --] list($status, $rows, $tmp) = db_get_record($onadb, 'dhcp_pools', 'id != ' . $SET['id'] . ' AND ' . $end_dec . ' BETWEEN ip_addr_start AND ip_addr_end'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict: New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") ends inside an existing pool!", 3); $self['error'] = "ERROR => Pool address conflict! New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") ends inside an existing pool."; return array(6, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$tmp['id']}\n"); } // Look for overlaps like this (where the new pool entirely overlaps an existing pool): // [ -------- new pool --------- ] // [ -- old pool --] list($status, $rows, $tmp) = db_get_record($onadb, 'dhcp_pools', 'id != ' . $SET['id'] . ' AND (ip_addr_start BETWEEN ' . $start_dec . ' AND ' . $end_dec . ' OR ip_addr_end BETWEEN ' . $start_dec . ' AND ' . $end_dec . ')'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict: New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") would encompass an existing pool!", 3); $self['error'] = "ERROR => Pool address conflict! New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") would encompass an existing pool."; return array(7, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$tmp['id']}\n"); } // Check permissions if (!auth('advanced') or !authlvl($subnet['lvl'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(8, $self['error'] . "\n"); } // define the remaining entries if (array_key_exists('set_lgrace', $options)) { $SET['lease_grace_period'] = $options['set_lgrace']; } if (array_key_exists('set_llength', $options)) { $SET['lease_length'] = $options['set_llength']; } if (array_key_exists('set_lrenewal', $options)) { $SET['lease_renewal_time'] = $options['set_lrenewal']; } if (array_key_exists('set_lrebind', $options)) { $SET['lease_rebind_time'] = $options['set_lrebind']; } // Set the IPs if you got this far $SET['ip_addr_start'] = $start_dec; $SET['ip_addr_end'] = $end_dec; // Get the DHCP pool record before updating (logging) list($status, $rows, $original_pool) = ona_get_dhcp_pool_record(array('id' => $SET['id'])); // Update the record list($status, $rows) = db_update_record($onadb, 'dhcp_pools', array('id' => $SET['id']), $SET); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_pool_modify() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $add_to_error . $self['error'] . "\n"); } $success_start = ip_mangle($SET['ip_addr_start'], 'dotted'); $success_end = ip_mangle($SET['ip_addr_end'], 'dotted'); // Get the DHCP pool record after updating (logging) list($status, $rows, $new_pool) = ona_get_dhcp_pool_record(array('id' => $SET['id'])); // Return the success notice $self['error'] = "INFO => DHCP pool UPDATED:{$original_pool['id']}: {$success_start}-{$success_end} on {$subnet['name']}."; $log_msg = "INFO => DHCP pool UPDATED:{$original_pool['id']}: "; $more = ""; foreach (array_keys($original_pool) as $key) { if ($original_pool[$key] != $new_pool[$key]) { $log_msg .= $more . $key . "[" . $original_pool[$key] . "=>" . $new_pool[$key] . "]"; $more = ";"; } } // only print to logfile if a change has been made to the record if ($more != '') { printmsg($self['error'], 0); printmsg($log_msg, 0); } return array(0, $add_to_error . $self['error'] . "\n"); }
function dhcp_entry_display($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => dhcp_entry_display({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['host'] and !$options['server'] and !$options['subnet']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_entry_display-v{$version} Displays an dhcp_entry record from the database Synopsis: dhcp_entry_display [KEY=VALUE] ... Required: host=NAME[.DOMAIN] or id hostname or id of the host to display OR subnet=NAME or id description or id of the subnet to display OR server=NAME[.DOMAIN] or id hostname or id of the server to display Notes: * DOMAIN will default to {$conf['dns_defaultdomain']} if not specified EOM ); } if ($options['host']) { // Determine the host is valid list($status, $rows, $host) = ona_find_host($options['host']); if (!$host['id']) { printmsg("DEBUG => The host specified, {$options['host']}, does not exist!", 3); $self['error'] = "ERROR => The host specified, {$options['host']}, does not exist!"; return array(2, $self['error'] . "\n"); } $anchor = 'host'; $desc = $host['FQDN']; $where = array('HOST_id' => $host['id']); } elseif ($options['subnet']) { // Determine the subnet is valid list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); if (!$subnet['id']) { printmsg("DEBUG => The subnet specified, {$options['subnet']}, does not exist!", 3); $self['error'] = "ERROR => The subnet specified, {$options['subnet']}, does not exist!"; return array(3, $self['error'] . "\n"); } $anchor = 'subnet'; $desc = "{$subnet['DESCRIPTION']} (" . ip_mangle($subnet['IP_ADDRESS']) . ")"; $where = array('NETWORK_id' => $subnet['id']); } elseif ($options['server']) { // Determine the server is valid list($status, $rows, $host) = ona_find_host($options['server']); if (!$host['id']) { printmsg("DEBUG => The server specified, {$options['server']}, does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(4, $self['error'] . "\n"); } // Determine the host that was found is actually a server list($status, $rows, $server) = ona_get_server_record(array('HOST_id' => $host['id'])); if (!$server['id']) { printmsg("DEBUG => The host specified, {$host['FQDN']}, is not a server!", 3); $self['error'] = "ERROR => The host specified, {$host['FQDN']}, is not a server!"; return array(5, $self['error'] . "\n"); } $anchor = 'server'; $desc = $host['FQDN']; $where = array('SERVER_id' => $server['id']); } // Debugging printmsg("DEBUG => dhcp_entry_display(): Found {$anchor}: {$desc}", 3); // Build text to return $text = strtoupper($anchor) . " RECORD ({$desc})\n"; // Display the record(s) $i = 0; do { list($status, $rows, $entry) = ona_get_dhcp_entry_record($where); if ($rows == 0) { $text .= "\nNO ASSOCIATED DHCP ENTRY RECORDS\n"; break; } $i++; $text .= "\nASSOCIATED DHCP ENTRY RECORD ({$i} of {$rows})\n"; $text .= format_array($entry); } while ($i < $rows); // Return the success notice return array(0, $text); }
function ws_editor($window_name, $form = '') { global $conf, $self, $onadb; global $font_family, $color, $style, $images; $window = array(); // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // If an array in a string was provided, build the array and store it in $form $form = parse_options_string($form); if ($form['server']) { list($status, $rows, $host) = ona_find_host($form['server']); } if ($form['host_id']) { list($status, $rows, $host) = ona_find_host($form['host_id']); } if ($form['subnet_id']) { list($status, $rows, $subnet) = ona_find_subnet($form['subnet_id']); } if ($form['subnet']) { list($status, $rows, $subnet) = ona_find_subnet($form['subnet']); } // Escape data for display in html foreach (array_keys((array) $host) as $key) { $host[$key] = htmlentities($host[$key], ENT_QUOTES, $conf['php_charset']); } // Set the window title: $window['title'] = "Assign subnet to server"; // Javascript to run after the window is built $window['js'] = <<<EOL /* Put a minimize icon in the title bar */ el('{$window_name}_title_r').innerHTML = ' <a onClick="toggle_window(\\'{$window_name}\\');" title="Minimize window" style="cursor: pointer;"><img src="{$images}/icon_minimize.gif" border="0" /></a>' + el('{$window_name}_title_r').innerHTML; /* Put a help icon in the title bar */ el('{$window_name}_title_r').innerHTML = ' <a href="{$_ENV['help_url']}{$window_name}" target="null" title="Help" style="cursor: pointer;"><img src="{$images}/silk/help.png" border="0" /></a>' + el('{$window_name}_title_r').innerHTML; suggest_setup('dhcp_server_name', 'suggest_dhcp_server_name'); suggest_setup('dhcp_subnet_name', 'suggest_dhcp_subnet_name'); el('dhcp_server_name').focus(); EOL; // Define the window's inner html $window['html'] = <<<EOL <!-- DHCP server Edit Form --> <form id="{$window_name}_form" onSubmit="return false;"> <input type="hidden" name="js" value="{$form['js']}"> <table cellspacing="0" border="0" cellpadding="0" style="background-color: {$color['window_content_bg']}; padding-left: 20px; padding-right: 20px; padding-top: 5px; padding-bottom: 5px;"> <tr> <td align="left" nowrap="true"><b><u>Assign Subnet</u></b> </td> <td class="padding" align="left" width="100%"> </td> </tr> <tr> <td class="input_required" align="right" nowrap="true"> Server </td> <td class="padding" align="left" width="100%"> <input id="dhcp_server_name" name="server" alt="Server name" value="{$host['fqdn']}" class="edit" type="text" size="34" maxlength="255" > <div id="suggest_dhcp_server_name" class="suggest"></div> </td> </tr> <tr> <td class="input_required" align="right" nowrap="true"> Subnet </td> <td class="padding" align="left" width="100%"> <input id="dhcp_subnet_name" name="subnet" alt="Subnet name" value="{$subnet['name']}" class="edit" type="text" size="34" maxlength="255" > <div id="suggest_dhcp_subnet_name" class="suggest"></div> </td> </tr> <tr> <td align="right" valign="top" nowrap="true"> </td> <td class="padding" align="right" width="100%"> <input type="hidden" name="overwrite" value="{$overwrite}"> <input class="edit" type="button" name="cancel" value="Cancel" onClick="removeElement('{$window_name}');"> <input class="edit" type="button" name="submit" value="Save" accesskey=" " onClick="xajax_window_submit('{$window_name}', xajax.getFormValues('{$window_name}_form'), 'save');" > </td> </tr> </table> </form> EOL; return window_open($window_name, $window); }
function interface_move($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => interface_move({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.04'; // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['start'] or !$options['new_start']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM interface_move-v{$version} Moves all interface addresses from one subnet to another. The initial range of IPs does not have to be consecutive. The new range of IPs will be used sequentially. Synopsis: interface_move [KEY=VALUE] ... IP block to move: (source) start=IP first IP to move [end=IP] last IP to move New IP block: (destination) new_start=IP first new IP address [new_end=IP] last new IP address Optional: commit=[yes|no] commit db transaction (no) EOM ); } // Set options[force] and options[create_a] to N if it's not set $options['commit'] = sanitize_YN($options['commit'], 'N'); // Find the "start" subnet record by IP address list($status, $rows, $old_subnet) = ona_find_subnet($options['start']); if (!$old_subnet or !$old_subnet['id']) { printmsg("DEBUG => Source start address ({$options['start']}) isn't valid!", 3); $self['error'] = "ERROR => Source (start) address specified isn't valid!"; return array(2, $self['error'] . "\n"); } // If they specified an "END" address, make sure it's valid and on the same subnet if ($options['end']) { // Find an interface record by something in that interface's record list($status, $rows, $old_subnet_end) = ona_find_subnet($options['end']); // If we didn't get a record then exit if (!$old_subnet_end or !$old_subnet_end['id']) { printmsg("DEBUG => Source end address ({$options['end']}) isn't valid!", 3); $self['error'] = "ERROR => Source (end) address specified isn't valid!"; return array(3, $self['error'] . "\n"); } if ($old_subnet_end['id'] != $old_subnet['id']) { printmsg("DEBUG => Both source addresses ({$options['start']} and {$options['end']}) must be on the same subnet!", 3); $self['error'] = "ERROR => Both the source addresses (start and end) must be on the same subnet!"; return array(4, $self['error'] . "\n"); } } else { printmsg("DEBUG => Only moving one host source={$options['start']}!", 3); $options['end'] = $options['start']; } // Find the "end" subnet record by IP address list($status, $rows, $new_subnet) = ona_find_subnet($options['new_start']); // If we didn't get a record then exit if (!$new_subnet or !$new_subnet['id']) { printmsg("DEBUG => Destination start address ({$options['new_start']}) isn't valid!", 3); $self['error'] = "ERROR => Destination (new_start) address specified isn't valid!"; return array(2, $self['error'] . "\n"); } // Make sure the "old" and "new" subnets are different subnets if ($old_subnet['id'] == $new_subnet['id']) { printmsg("DEBUG => Both the source IP range ({$options['start']}+) and the destination IP range ({$options['new_start']}+) are on the same subnet!", 3); $self['error'] = "ERROR => Both the source IP range and the destination IP range are on the same subnet!"; return array(2, $self['error'] . "\n"); } // If they specified a "new_end" address, make sure it's valid and on the same subnet as the new_start subnet if ($options['new_end']) { // Find an interface record by something in that interface's record list($status, $rows, $new_subnet_end) = ona_find_subnet($options['new_end']); // If we didn't get a record then exit if (!$new_subnet_end or !$new_subnet_end['id']) { printmsg("DEBUG => Destination end address ({$options['new_end']}) isn't valid!", 3); $self['error'] = "ERROR => Destination (new_end) address specified isn't valid!"; return array(3, $self['error'] . "\n"); } if ($new_subnet_end['id'] != $new_subnet['id']) { printmsg("DEBUG => Both destination addresses ({$options['new_start']} and {$options['new_end']}) must be on the same subnet!", 3); $self['error'] = "ERROR => Both the destination addresses (new_start and new_end) must be on the same subnet!"; return array(4, $self['error'] . "\n"); } } else { printmsg("DEBUG => Only moving one host destination={$options['new_start']}!", 3); $options['new_end'] = $options['new_start']; } // Check permissions at the subnet level if (!auth('interface_modify')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(13, $self['error'] . "\n"); } // An array for all the interface records we'll be moving $to_move = array(); // Message to display if we succeed $message = ""; // Load all the interface records we'll be moving $i = 0; do { // FIXME: this should do a more advanced query someday! (like checking that the ipaddress is >= start and <= end list($status, $rows, $interface) = ona_get_interface_record(array('subnet_id' => $old_subnet['id']), 'ip_addr'); if ($rows == 0) { break; } $i++; if ($interface['ip_addr'] >= ip_mangle($options['start'], 'numeric')) { if ($interface['ip_addr'] <= ip_mangle($options['end'], 'numeric')) { $to_move[$i] = $interface; } } } while ($i < $rows); $total_to_move = count($to_move); $total_assigned = 0; // If there's nothing to do, tell them if ($total_to_move == 0) { printmsg("DEBUG => There are no interfaces in the source address block!", 3); $self['error'] = "ERROR => There are no interfaces in the source address block!"; return array(6, $self['error'] . "\n"); } // Make sure we have a high enough "LVL" to modify the associated hosts foreach ($to_move as $interface) { // Load the associated host record list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); list($status, $rows, $dns) = ona_get_dns_record(array('id' => $host['primary_dns_id'], 'type' => 'A')); // Check permissions at the subnet level if (!authlvl($host['LVL'])) { $self['error'] = "Permission denied! Can't modify Host: {$host['id']} {$dns['fqdn']}"; printmsg($self['error'], 0); return array(14, $self['error'] . "\n"); } // Check to see if the host has any interfaces in the destination subnet // MP: this is now allowed // list($status, $rows, $interface) = ona_get_interface_record(array('host_id' => $interface['host_id'], 'subnet_id' => $new_subnet['id'])); // if ($status or $rows) { // printmsg("DEBUG => Source host {$ddns['fqdn']} already has an interface on the destination subnet!",3); // $self['error'] = "ERROR => Source host {$dns['fqdn']} (ID {$host['id']}) already has an interface on the destination subnet!"; // return(array(15, $self['error'] . "\n")); // } } // Get the numeric version of the start/end addresses we are moving interfaces to // .. and make sure that the $low_ip and $high_ip are not subnet or broadcast addresses! $low_ip = ip_mangle($options['new_start'], 'numeric'); $high_ip = ip_mangle($options['new_end'], 'numeric'); if ($low_ip == $new_subnet['ip_addr']) { $low_ip++; } $num_hosts = 0xffffffff - $new_subnet['ip_mask']; if ($high_ip == $new_subnet['ip_addr'] + $num_hosts) { $high_ip--; } printmsg("INFO => Asked to move {$total_to_move} interfaces to new range: " . ip_mangle($low_ip, 'dotted') . ' - ' . ip_mangle($high_ip, 'dotted'), 0); // Loop through each interface we need to move, and find an available address for it. $pool_interfering = 0; foreach (array_keys($to_move) as $i) { while ($low_ip <= $high_ip) { list($status, $rows, $interface) = ona_get_interface_record(array('ip_addr' => $low_ip)); if ($rows == 0 and $status == 0) { // Since the IP seems available, let's double check and make sure it's not in a DHCP address pool list($status, $rows, $pool) = ona_get_dhcp_pool_record("ip_addr_start < '{$low_ip}' AND ip_addr_end > '{$low_ip}'"); if ($rows == 0 and $status == 0) { // The IP is available, lets use it! $to_move[$i]['new_ip_address'] = $low_ip; $total_assigned++; $low_ip++; break; } $pool_interfering = 1; printmsg("DEBUG => Couldn't use the DHCP POOL address: " . ip_mangle($low_ip, 'dotted'), 3); } $low_ip++; } } // If total_assigned != total_to_move, error - not enough free IP addresses in destination subnet! if ($total_assigned != $total_to_move) { printmsg("DEBUG => The destination IP range doesn't have enough free IP addresses!", 3); $self['error'] = "ERROR => The destination IP range doesn't have enough free IP addresses!\n"; if ($pool_interfering) { $self['error'] .= "INFO => Some IPs in the destination range were part of a DHCP pool range.\n"; } return array(6, $self['error']); } // Display what we would have done if "commit" isn't "yes" if ($options['commit'] != "Y") { $self['error'] = "Interface(s) NOT MOVED (see \"commit\" option)"; $text = $self['error'] . "\n" . "Displaying {$total_to_move} interface(s) that would have been moved:\n\n"; foreach ($to_move as $interface) { // Get display the hostname we would have moved, as well as it's IP address. list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); list($status, $rows, $dns) = ona_get_dns_record(array('id' => $host['primary_dns_id'], 'type' => 'A')); $hostname = strtolower("{$dns['fqdn']}"); $text .= " " . ip_mangle($interface['ip_addr'], 'dotted') . " -> " . ip_mangle($interface['new_ip_address'], 'dotted') . "\t({$hostname})\n"; } $text .= "\n"; return array(7, $text); } // Loop through and update each interface's IP_ADDRESS and SUBNET_ID $text = "SUCCESS => {$total_to_move} interface(s) moved\n"; $text .= "Interface(s) moved:\n\n"; foreach ($to_move as $interface) { list($status, $rows) = ona_update_record("interfaces", array('id' => $interface['id']), array('ip_addr' => $interface['new_ip_address'], 'subnet_id' => $new_subnet['id'])); if ($status != 0 or $rows != 1) { $self['error'] = "ERROR => Database update failed! {$self['error']}"; return array(8, $self['error'] . "\n"); } // Get display the hostname we would have moved, as well as its IP address. list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); list($status, $rows, $dns) = ona_get_dns_record(array('id' => $host['primary_dns_id'], 'type' => 'A')); $hostname = strtolower("{$dns['fqdn']}"); $text .= " " . ip_mangle($interface['ip_addr'], 'dotted') . " -> " . ip_mangle($interface['new_ip_address'], 'dotted') . "\t({$hostname})\n"; } // Return the success notice return array(0, $text); }
function ws_save($window_name, $form = '') { global $base, $include, $conf, $self, $onadb; // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Instantiate the xajaxResponse object $response = new xajaxResponse(); $js = ''; // Validate input if (!$form['start'] and !$form['end']) { $response->addScript("alert('Please complete all fields to continue!');"); return $response->getXML(); } list($status, $rows, $subnet) = ona_find_subnet($form['subnet_id']); $start_dec = ip_mangle($form['start'], 'numeric'); $end_dec = ip_mangle($form['end'], 'numeric'); $net_end = 4294967295 - $subnet['ip_mask'] + $subnet['ip_addr']; // check the ips are part of the subnet you are on if ($start_dec < $subnet['ip_addr'] or $start_dec > $net_end or ($end_dec < $subnet['ip_addr'] or $end_dec > $net_end)) { $response->addScript("alert('Save failed: ERROR => The pool range you specified is not part of the subnet: {$subnet['name']}!');"); return $response->getXML(); } // Decide if we're editing or adding $module = 'dhcp_pool_add'; if ($form['id']) { $module = 'dhcp_pool_modify'; $form['pool'] = $form['id']; $form['set_start'] = $form['start']; $form['set_end'] = $form['end']; $form['set_llength'] = $form['llength']; $form['set_lgrace'] = $form['lgrace']; $form['set_lrenewal'] = $form['lrenewal']; $form['set_lrebind'] = $form['lrebind']; $form['set_failover_group'] = $form['failover_group']; } // Run the module list($status, $output) = run_module($module, $form); // If the module returned an error code display a popup warning if ($status) { $js .= "alert('Save failed: " . preg_replace('/[\\s\']+/', ' ', $self['error']) . "');"; } else { $js .= "removeElement('{$window_name}');"; // If there's JS, add it to $js so we'll send it to the browser later. if ($form['js']) { $js .= $form['js']; } } // Insert the new table into the window $response->addScript($js); return $response->getXML(); }
function ws_display_list($window_name, $form = '') { global $conf, $self, $onadb; global $images, $color, $style; $html = ''; $js = ''; // If the user supplied an array in a string, build the array and store it in $form $form = parse_options_string($form); // Find the "tab" we're on $tab = $_SESSION['ona'][$form['form_id']]['tab']; // Build js to refresh this list $refresh = "xajax_window_submit('{$window_name}', xajax.getFormValues('{$form['form_id']}'), 'display_list');"; // Search results go in here $results = array(); $count = 0; // NETWORK ID if (is_numeric($form['subnet_id'])) { } // Do the SQL Query list($status, $count, $results) = db_get_records($onadb, 'interfaces', "subnet_id = " . $onadb->qstr($form['subnet_id']), 'ip_addr', -1, -1); // make an array of ips from our results $iplist = array(); foreach ($results as $record) { $iplist["{$record['ip_addr']}"] = 'used'; } list($status, $rows, $subnet) = ona_find_subnet($form['subnet_id']); // Create a few variables that will be handy later $num_ips = 0xffffffff - $subnet['ip_mask']; $last_ip = $subnet['ip_addr'] + $num_ips - 1; $currip = $subnet['ip_addr'] + 1; // Get a list of blocks that touches this subnet list($status, $blockrows, $blocks) = db_get_records($onadb, 'blocks', "{$subnet['ip_addr']} BETWEEN ip_addr_start AND ip_addr_end OR {$last_ip} BETWEEN ip_addr_start AND ip_addr_end OR ip_addr_start BETWEEN {$subnet['ip_addr']} and {$last_ip}"); // Get a list of dhcp pools on the selected subnet list($status, $rows, $pools) = db_get_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); // Add DHCP pool addresses into the list of used ips foreach ($pools as $pool) { for ($ip = $pool['ip_addr_start']; $ip <= $pool['ip_addr_end']; $ip++) { $iplist["{$ip}"] = 'pool-' . $pool['id']; } } // // *** BUILD HTML LIST *** // $html .= <<<EOL <!-- Host Results --> <table id="{$form['form_id']}_full_host_list" class="list-box" cellspacing="0" border="0" cellpadding="0"> <!-- Table Header --> <tr> <td class="list-header" align="center" style="{$style['borderR']};" title="IP Block Association">B</td> <td class="list-header" align="center" style="{$style['borderR']};">IP Address</td> <td class="list-header" align="center" style="{$style['borderR']};">Last Response</td> <td class="list-header" align="center" style="{$style['borderR']};">[Name] Desc</td> <td class="list-header" align="center" style="{$style['borderR']};">Host Name</td> <td class="list-header" align="center" style="{$style['borderR']};">Device Type</td> <td class="list-header" align="center" style="{$style['borderR']};">Host Notes</td> </tr> EOL; // Loop and display each ip on the subnet while ($currip <= $last_ip) { $loc = array(); $host = array(); $interface = array(); $interfaces = 0; $record = array(); $interface_style = ''; $clusterhtml = ''; $rowstyle = 'background-color: #E9FFE1'; $rowid = 'byip_available'; $currip_txt = ip_mangle($currip, 'dotted'); $interface['desc'] = '<span style="color: #aaaaaa;">AVAILABLE</span>'; $nameval = <<<EOL <a title="Add host" class="act" onClick="xajax_window_submit('edit_host', 'ip_addr=>{$currip_txt}', 'editor');" ></a> <a title="Add host" class="act" onClick="xajax_window_submit('edit_host', 'ip_addr=>{$currip_txt}', 'editor');" >Add a new host</a> <a title="Add interface" class="act" onClick="xajax_window_submit('edit_interface', 'ip_addr=>{$currip_txt}', 'editor');" ></a> <a title="Add interface" class="act" onClick="xajax_window_submit('edit_interface', 'ip_addr=>{$currip_txt}', 'editor');" >Add interface to an existing host</a> EOL; // If the current ip is one allocated on this subnet lets do some stuff if (array_key_exists($currip, $iplist)) { $rowid = 'byip_allocated'; $rowstyle = ''; // check if it is a pool range list($pooltype, $poolid) = explode('-', $iplist[$currip]); if ($pooltype == 'pool') { $interface['desc'] = '<span style="color: #aaaaaa;">DHCP Pool</span>'; $rowstyle = 'background-color: #FFFBD6'; $nameval = <<<EOL <a title="Edit Pool" class="act" onClick="xajax_window_submit('edit_dhcp_pool', 'subnet=>{$subnet['id']},id=>{$poolid}', 'editor');" ><img src="{$images}/silk/page_add.png" border="0"></a> <a title="Edit Pool" class="act" onClick="xajax_window_submit('edit_dhcp_pool', 'subnet=>{$subnet['id']},id=>{$poolid}', 'editor');" >Edit DHCP Pool</a> EOL; } else { // Get host record list($status, $rows, $host) = ona_find_host($currip); // Get the interface info list($status, $rows, $interface) = ona_find_interface($currip); // Count how many interface rows this host hasand assign it back to the interfaces variable list($status, $interfaces, $records) = db_get_records($onadb, 'interfaces', 'host_id = ' . $onadb->qstr($host['id']), "", 0); // get interface cluster info list($status, $intclusterrows, $intcluster) = db_get_records($onadb, 'interface_clusters', "interface_id = {$interface['id']}"); if ($intclusterrows > 0) { $clusterscript = "onMouseOver=\"wwTT(this, event,\n 'id', 'tt_interface_cluster_list_{$interface['id']}',\n 'type', 'velcro',\n 'styleClass', 'wwTT_niceTitle',\n 'direction', 'south',\n 'javascript', 'xajax_window_submit(\\'tooltips\\', \\'tooltip=>interface_cluster_list,id=>tt_interface_cluster_list_{$interface['id']},interface_id=>{$interface['id']}\\');'\n );\""; $clusterhtml .= <<<EOL <img src="{$images}/silk/sitemap.png" {$clusterscript} /> EOL; } // set the name value for an allocated host $nameval = <<<EOL <a title="View host. ID: {$host['id']}" class="nav" onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_host\\', \\'host_id=>{$host['id']}\\', \\'display\\')');" >{$host['name']}</a >.<a title="View domain. ID: {$host['domain_id']}" class="domain" onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$host['domain_id']}\\', \\'display\\')');" >{$host['domain_fqdn']}</a> EOL; // Make it bold if we have more than one interface on this host if ($interfaces > 1) { $interface_style = 'font-weight: bold;'; } // Device Description list($status, $rows, $device) = ona_find_device($host['device_id']); list($status, $rows, $device_type) = ona_get_device_type_record(array('id' => $device['device_type_id'])); list($status, $rows, $role) = ona_get_role_record(array('id' => $device_type['role_id'])); list($status, $rows, $model) = ona_get_model_record(array('id' => $device_type['model_id'])); list($status, $rows, $manufacturer) = ona_get_manufacturer_record(array('id' => $model['manufacturer_id'])); $record['device'] = "{$manufacturer['name']}, {$model['name']} ({$role['name']})"; $record['device'] = str_replace('Unknown', '?', $record['device']); $record['notes_short'] = truncate($host['notes'], 40); $interface['description_short'] = truncate($interface['description'], 40); if ($interface['name']) { $interface['name'] = "[{$interface['name']}]"; } $interface['desc'] = "{$interface['name']} {$interface['description_short']}"; // Format the date and colorize if its older than 2 months if ($interface['last_response']) { $interface['last_response'] = date($conf['date_format'], strtotime($interface['last_response'])); if (strtotime($interface['last_response']) < strtotime('-2 month')) { $interface['last_response_fmt'] = 'style=color:red;'; } } // Get location info list($status, $rows, $loc) = ona_get_location_record(array('id' => $device['location_id'])); } // end real host ifblock } // end while loop // Escape data for display in html foreach (array_keys($record) as $key) { $record[$key] = htmlentities($record[$key], ENT_QUOTES, $conf['php_charset']); } $html .= <<<EOL <tr {$rowid}=true style="{$rowstyle}" onMouseOver="this.className='row-highlight'" onMouseOut="this.className='row-normal'"> EOL; // Print color info for any matching blocks $c = 0; $blockcolors = array('#CD5C5C', '#588C7E', '#8C4646', '#FFD700', '#1E90F0', '#8A2BE2', '#32CD32', '#D96459'); if ($blockrows) { $html .= "<td class='list-row' nowrap style='padding:0'>"; foreach ($blocks as $block) { if ($currip >= $block['ip_addr_start'] && $currip <= $block['ip_addr_end']) { $html .= "<span title='{$block['name']}' style='background-color:{$blockcolors[$c]};padding-bottom:4px;float:left;'>  </span> "; } $c++; } } else { // print an empty table cell $html .= "<td class='list-row'>"; } $html .= <<<EOL </td> <td class="list-row" align="left"> EOL; // if it is used, show an edit interface link if ($rowid == 'byip_allocated') { $html .= <<<EOL <a class="nav" style="{$interface_style}" title="Edit interface ID: {$interface['id']}" onClick="xajax_window_submit('edit_interface', 'interface_id=>{$interface['id']}', 'editor');" EOL; if ($interfaces > 1) { $html .= <<<EOL onMouseOver="wwTT(this, event, 'id', 'tt_host_interface_list_{$host['id']}', 'type', 'velcro', 'styleClass', 'wwTT_niceTitle', 'direction', 'south', 'javascript', 'xajax_window_submit(\\'tooltips\\', \\'tooltip=>host_interface_list,id=>tt_host_interface_list_{$host['id']},host_id=>{$host['id']}\\');' );" EOL; } $html .= '>'; } //print out the IP address $html .= $currip_txt; // close the A tag if used above if ($rowid == 'byip_allocated') { $html .= '</a>'; } // Keep on goin with the rest of the line $html .= <<<EOL <span>{$clusterhtml}</span> </td> <td class="list-row" {$interface['last_response_fmt']}>{$interface['last_response']} </td> <td class="list-row"> <span title="{$interface['description']}">{$interface['desc']}</span> </td> <td class="list-row" style="border-left: 1px solid; border-left-color: #aaaaaa;"> {$nameval} </td> <td class="list-row">{$record['device']} </td> <td class="list-row"> <span title="{$host['notes']}">{$record['notes_short']}</span> </td> </tr> EOL; // increment the currip $currip++; } $html .= <<<EOL </table> EOL; $js .= <<<EOL /* Make sure this table is 100% wide */ el('{$form['form_id']}_full_host_list').style.width = el('{$form['form_id']}_table').offsetWidth + 'px'; function togglebyip(name) { tr=document.getElementsByTagName('tr') for (i=0;i<tr.length;i++){ if (tr[i].getAttribute(name)){ if (tr[i].style.display=='none'){tr[i].style.display = '';} else {tr[i].style.display = 'none';} } } } EOL; // Insert the new html into the content div specified // Instantiate the xajaxResponse object $response = new xajaxResponse(); $response->addAssign("{$form['form_id']}_{$tab}_count", "innerHTML", "({$count})"); $response->addAssign($form['content_id'], "innerHTML", $html); if ($js) { $response->addScript($js); } return $response->getXML(); }