function getRacktablesObjects($type_id, $attr_id, $attr_value) { $r = usePreparedSelectBlade('select o.id, o.name, o.objtype_id, o.label, i.ip, i.type, i.name as ifname, av.attr_id as zabbix_flag_id, av.uint_value as zabbix_flag_value, av2.attr_id as sw_type_id, av2.uint_value as sw_type_value from Object AS o INNER JOIN IPv4Allocation as i ON (o.id = i.object_id AND o.objtype_id = ?) INNER JOIN AttributeValue av on (av.object_id = o.id AND av.attr_id = ? AND av.uint_value = ?) LEFT JOIN AttributeValue av2 on (av2.object_id = o.id AND av2.attr_id = ?)', array($type_id, $attr_id, $attr_value, RACKTABLES_SOFTWARE_TYPE_ID)); $items = $r->fetchAll(PDO::FETCH_ASSOC); $result = array(); foreach ($items as $item) { $ip = ip_format(ip4_int2bin($item['ip'])); if (!isset($result[$item['id']])) { if (!empty($item['ifname'])) { $item['ip'] = array($item['ifname'] => $ip); } else { $item['ip'] = array($ip); } $result[$item['id']] = $item; } else { if (is_array($result[$item['id']]['ip'])) { if (!empty($item['ifname'])) { $result[$item['id']]['ip'][$item['ifname']] = $ip; } else { $result[$item['id']]['ip'][] = $ip; } } } } return $result; }
function ripeTab($id) { $ripe_db = "http://rest.db.ripe.net/search.xml?source=ripe&query-string="; assertUIntArg('id'); $net = spotEntity('ipv4net', $id); loadIPAddrList($net); $startip = ip4_bin2int($net['ip_bin']); $endip = ip4_bin2int(ip_last($net)); // Get Data from RIPE $ripe_inetnum_str = ip4_format(ip4_int2bin($startip)) . ' - ' . ip4_format(ip4_int2bin($endip)); $ripe_query = $ripe_db . ip4_format(ip4_int2bin($startip)); $ripe_result_str = file_get_contents($ripe_query, false, NULL); $ripe_result = simplexml_load_string($ripe_result_str); // Check inetnum object $ripe_inetnum_check = "/whois-resources/objects/object[@type='inetnum']/attributes/attribute[@name='inetnum'][@value='{$ripe_inetnum_str}']"; $ripe_inetnum = $ripe_result->xpath($ripe_inetnum_check); if (empty($ripe_inetnum)) { echo "<div class=trerror><center><h1>{$net['ip']}/{$net['mask']}</h1><h2>{$net['name']}</h2></center></div>\n"; } else { $ripe_netname_check = "/whois-resources/objects/object[@type='inetnum']/attributes/attribute[@name='netname']"; $ripe_netname = $ripe_result->xpath($ripe_netname_check); $netname = trim($ripe_netname[0]['value']); if (strcmp($netname, $net['name']) != 0) { echo "<div class=trwarning><center><h1>{$net['ip']}/{$net['mask']}</h1><h2>{$net['name']}</h2></center></div><div><center>"; } else { echo "<div class=trok><center><h1>{$net['ip']}/{$net['mask']}</h1><h2>{$net['name']}</h2></center></div><div><center>"; } printOpFormIntro('importRipeData', array('ripe_query' => $ripe_query, 'net_id' => $id, 'net_name' => $netname)); echo "<input type=submit value='Import RIPE records in to comments'></center></div>"; echo "</form>"; } // echo '<em>'.$ripe_query.'</em>'; echo "<table border=0 width='100%'><tr><td class=pcleft>"; $filedir = realpath(dirname(__FILE__)); $ripe_xsl = simplexml_load_file($filedir . '/ripe_html.xsl'); startPortlet("RIPE Information Datatbase<br>{$ripe_inetnum_str}"); $proc = new XSLTProcessor(); $proc->importStyleSheet($ripe_xsl); echo '<div class=commentblock>' . trim($proc->transformToXML($ripe_result)) . '</div>'; finishPortlet(); echo "</td></tr></table>\n"; }
function getIPv4AddressSearchResult($terms) { $query = "select ip, name from IPv4Address where "; $or = ''; $qparams = array(); foreach (explode(' ', $terms) as $term) { $query .= $or . "name like ?"; $or = ' or '; $qparams[] = "%{$term}%"; } $result = usePreparedSelectBlade($query, $qparams); $ret = array(); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $ip_bin = ip4_int2bin($row['ip']); $row['ip'] = $ip_bin; $ret[$ip_bin] = $row; } return $ret; }
function convertSLBTablesToBinIPs() { global $dbxlink; $dbxlink->query("DROP TABLE IF EXISTS `IPv4VS_new`, `IPv4RS_new`, `IPv4VS_old`, `IPv4RS_old`"); $dbxlink->query(<<<END CREATE TABLE `IPv4VS_new` ( `id` int(10) unsigned NOT NULL auto_increment, `vip` varbinary(16) NOT NULL, `vport` smallint(5) unsigned default NULL, `proto` enum('TCP','UDP','MARK') NOT NULL default 'TCP', `name` char(255) default NULL, `vsconfig` text, `rsconfig` text, PRIMARY KEY (`id`), KEY `vip` (`vip`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 END ); $result = $dbxlink->query("SELECT * FROM IPv4VS"); $rows = $result->fetchAll(PDO::FETCH_ASSOC); unset($result); foreach ($rows as $row) { $row['vip'] = ip4_int2bin($row['vip']); usePreparedInsertBlade('IPv4VS_new', $row); } $dbxlink->query(<<<END CREATE TABLE `IPv4RS_new` ( `id` int(10) unsigned NOT NULL auto_increment, `inservice` enum('yes','no') NOT NULL default 'no', `rsip` varbinary(16) NOT NULL, `rsport` smallint(5) unsigned default NULL, `rspool_id` int(10) unsigned default NULL, `rsconfig` text, `comment` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `rsip` (`rsip`), UNIQUE KEY `pool-endpoint` (`rspool_id`,`rsip`,`rsport`), CONSTRAINT `IPRS-FK` FOREIGN KEY (`rspool_id`) REFERENCES `IPv4RSPool` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 END ); $result = $dbxlink->query("SELECT * FROM IPv4RS"); $rows = $result->fetchAll(PDO::FETCH_ASSOC); unset($result); foreach ($rows as $row) { $row['rsip'] = ip4_int2bin($row['rsip']); usePreparedInsertBlade('IPv4RS_new', $row); } $dbxlink->query(<<<END RENAME TABLE \t`IPv4VS` TO `IPv4VS_old`, \t`IPv4VS_new` TO `IPv4VS`, \t`IPv4RS` TO `IPv4RS_old`, \t`IPv4RS_new` TO `IPv4RS` END ); // re-create foreign key in IPv4LB $dbxlink->query("ALTER TABLE `IPv4LB` DROP FOREIGN KEY `IPv4LB-FK-vs_id`"); $dbxlink->query("ALTER TABLE `IPv4LB` ADD CONSTRAINT `IPv4LB-FK-vs_id` FOREIGN KEY (`vs_id`) REFERENCES `IPv4VS` (`id`)"); $dbxlink->query("DROP TABLE `IPv4VS_old`, `IPv4RS_old`"); // re-create foreign key in IPv4RS $dbxlink->query("ALTER TABLE `IPv4RS` DROP FOREIGN KEY `IPRS-FK`"); $dbxlink->query("ALTER TABLE `IPv4RS` ADD CONSTRAINT `IPv4RS-FK` FOREIGN KEY (`rspool_id`) REFERENCES `IPv4RSPool` (`id`) ON DELETE CASCADE"); }
/** * * Fing tab handler * */ function FingTab($id) { $can_import = permitted(NULL, NULL, 'importFingData'); // // allocation settings // // address allocation code, IPv4 networks view $aac_left = array('regular' => '', 'virtual' => '<span class="aac-left" title="Loopback">L:</span>', 'shared' => '<span class="aac-left" title="Shared">S:</span>', 'router' => '<span class="aac-left" title="Router">R:</span>', 'point2point' => '<span class="aac-left" title="Point-to-point">P:</span>'); // // header // global $pageno, $tabno; $maxperpage = getConfigVar('IPV4_ADDRS_PER_PAGE'); $range = spotEntity('ipv4net', $id); loadIPAddrList($range); echo "<center><h1>{$range['ip']}/{$range['mask']}</h1><h2>{$range['name']}</h2></center>\n"; // // execute fing // try { $known_ips = get_fing_scan($range['ip'], $range['mask']); $fing_cfg = get_fing_settings($range['ip'], $range['mask']); $fing_gw = $fing_cfg["gateway"]; } catch (FingException $e) { render_fing_error("Could not get network scan via fing:", $e->getMessage()); return FALSE; } echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>"; startPortlet('overlook fing (via: ' . $fing_gw . ')'); // // pagination // if (isset($_REQUEST['pg'])) { $page = $_REQUEST['pg']; } else { $page = 0; } $startip = ip4_bin2int($range['ip_bin']); $endip = ip4_bin2int(ip_last($range)); $numpages = 0; if ($endip - $startip > $maxperpage) { $numpages = ($endip - $startip) / $maxperpage; $startip = $startip + $page * $maxperpage; $endip = $startip + $maxperpage - 1; } echo "<center>"; if ($numpages) { echo '<h3>' . ip4_format(ip4_int2bin($startip)) . ' ~ ' . ip4_format(ip4_int2bin($endip)) . '</h3>'; } for ($i = 0; $i < $numpages; $i++) { if ($i == $page) { echo "<b>{$i}</b> "; } else { echo "<a href='" . makeHref(array('page' => $pageno, 'tab' => $tabno, 'id' => $id, 'pg' => $i)) . "'>{$i}</a> "; } } echo "</center>"; if ($can_import) { printOpFormIntro('importFingData', array('addrcount' => $endip - $startip + 1)); $box_counter = 1; } echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n"; echo "<tr><th class='tdleft'>address</th><th class='tdleft'>state</th><th class='tdleft'>current name</th><th class='tdleft'>DNS name</th><th class='tdleft'>MAC</th><th class='tdleft'>Allocation</th>"; if ($can_import) { echo '<th>import</th>'; } echo "</tr>\n"; // // Loop through all IPs // $cnt_match = $cnt_missing = $cnt_mismatch = $cnt_total = 0; for ($ip = $startip; $ip <= $endip; $ip++) { $cnt_total++; $print_cbox = FALSE; $ip_bin = ip4_int2bin($ip); $addr = isset($range['addrlist'][$ip_bin]) ? $range['addrlist'][$ip_bin] : array('name' => '', 'reserved' => 'no'); $straddr = ip4_format($ip_bin); list($fing_hostname, $fing_state, $fing_mac_vendor) = get_fing_info($straddr, $known_ips); $ip_is_up = strtoupper($fing_state) == "UP" ? TRUE : FALSE; if ($can_import) { echo "<input type=hidden name=addr_{$cnt_total} value={$straddr}>\n"; echo "<input type=hidden name=descr_{$cnt_total} value={$fing_hostname}>\n"; echo "<input type=hidden name=rsvd_{$cnt_total} value={$addr['reserved']}>\n"; } $skip_dns_check = FALSE; echo "<tr"; // Ignore network and broadcast addresses if ($ip == $startip && $addr['name'] == 'network' || $ip == $endip && $addr['name'] == 'broadcast') { echo " class='trbusy'"; $skip_dns_check = TRUE; } elseif (!$ip_is_up) { echo " class='trnull'"; } // set line color depending if we have the name already in the DB if (!$skip_dns_check) { if ($addr['name'] == $fing_hostname) { if (strlen($fing_hostname)) { echo ' class=trok'; $cnt_match++; } } elseif (!strlen($addr['name']) or !strlen($fing_hostname)) { echo ' class=trwarning'; $print_cbox = TRUE; $cnt_missing++; } else { echo ' class=trerror'; $print_cbox = TRUE; $cnt_mismatch++; } } //IP echo "><td class='tdleft"; if (isset($range['addrlist'][$ip_bin]['class']) and strlen($range['addrlist'][$ip_bin]['class'])) { echo ' ' . $range['addrlist'][$ip_bin]['class']; } echo "'><a href='" . makeHref(array('page' => 'ipaddress', 'ip' => $straddr)) . "'>{$straddr}</a></td>"; //other columns if ($skip_dns_check) { echo "<td class='tdleft'> </td>"; } else { if (!$ip_is_up) { echo "<td class='tdleft'>" . $fing_state . "</td>"; } else { echo "<td class='tdleft'><div class='strong'>" . $fing_state . "</div></td>"; } } echo "<td class=tdleft>{$addr['name']}</td>"; echo "<td class='tdleft'>" . $fing_hostname . "</td>"; echo "<td class='tdleft'>" . $fing_mac_vendor . "</td>"; //allocation echo "<td>"; $delim = ''; if ($addr['reserved'] == 'yes') { echo "<strong>RESERVED</strong> "; $delim = '; '; } foreach ($addr['allocs'] as $ref) { echo $delim . $aac_left[$ref['type']]; echo makeIPAllocLink($ip_bin, $ref, TRUE); $delim = '; '; } if ($delim != '') { $delim = '<br>'; } foreach ($addr['vslist'] as $vs_id) { $vs = spotEntity('ipv4vs', $vs_id); echo $delim . mkA("{$vs['name']}:{$vs['vport']}/{$vs['proto']}", 'ipv4vs', $vs['id']) . '→'; $delim = '<br>'; } foreach ($addr['vsglist'] as $vs_id) { $vs = spotEntity('ipvs', $vs_id); echo $delim . mkA($vs['name'], 'ipvs', $vs['id']) . '→'; $delim = '<br>'; } foreach ($addr['rsplist'] as $rsp_id) { $rsp = spotEntity('ipv4rspool', $rsp_id); echo "{$delim}→" . mkA($rsp['name'], 'ipv4rspool', $rsp['id']); $delim = '<br>'; } echo "</td>"; // import column if ($can_import) { echo '<td>'; if ($print_cbox) { echo "<input type=checkbox name=import_{$cnt_total} id=atom_1_" . $box_counter++ . "_1>"; } else { echo ' '; } echo '</td>'; } echo "</tr>"; } if ($can_import && $box_counter > 1) { echo '<tr><td colspan=4 align=center><input type=submit value="Import selected records"></td><td colspan=2 align=right>'; addJS('js/racktables.js'); echo --$box_counter ? "<a href='javascript:;' onclick=\"toggleColumnOfAtoms(1, 1, {$box_counter})\">(toggle selection)</a>" : ' '; echo '</td></tr>'; } echo "</table>"; if ($can_import) { echo '</form>'; } finishPortlet(); echo "</td><td class=pcright>"; // // PING Statistics // startPortlet('ping stats'); $cnt_ping_up = get_fing_up_count($known_ips); echo "<table border=0 width='100%' cellspacing=0 cellpadding=2>"; echo "<tr class=trok><th class=tdright>Replied to Ping</th><td class=tdleft>{$cnt_ping_up}</td></tr>\n"; echo "<tr class=trwarning><th class=tdright>No Response</th><td class=tdleft>" . ($cnt_total - $cnt_ping_up) . "</td></tr>\n"; echo "</table>\n"; finishPortlet(); // // DNS Statistics // startPortlet('dns stats'); echo "<table border=0 width='100%' cellspacing=0 cellpadding=2>"; echo "<tr class=trok><th class=tdright>Exact matches:</th><td class=tdleft>{$cnt_match}</td></tr>\n"; echo "<tr class=trwarning><th class=tdright>Missing from DB/DNS:</th><td class=tdleft>{$cnt_missing}</td></tr>\n"; if ($cnt_mismatch) { echo "<tr class=trerror><th class=tdright>Mismatches:</th><td class=tdleft>{$cnt_mismatch}</td></tr>\n"; } echo "</table>\n"; finishPortlet(); }
function renderLivePTR($id) { if (isset($_REQUEST['pg'])) { $page = $_REQUEST['pg']; } else { $page = 0; } global $pageno, $tabno; $maxperpage = getConfigVar('IPV4_ADDRS_PER_PAGE'); $range = spotEntity('ipv4net', $id); loadIPAddrList($range); $can_import = permitted(NULL, NULL, 'importPTRData'); echo "<center><h1>{$range['ip']}/{$range['mask']}</h1><h2>{$range['name']}</h2></center>\n"; echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>"; startPortlet('current records'); $startip = ip4_bin2int($range['ip_bin']); $endip = ip4_bin2int(ip_last($range)); $numpages = 0; if ($endip - $startip > $maxperpage) { $numpages = ($endip - $startip) / $maxperpage; $startip = $startip + $page * $maxperpage; $endip = $startip + $maxperpage - 1; } echo "<center>"; if ($numpages) { echo '<h3>' . ip4_format(ip4_int2bin($startip)) . ' ~ ' . ip4_format(ip4_int2bin($endip)) . '</h3>'; } for ($i = 0; $i < $numpages; $i++) { if ($i == $page) { echo "<b>{$i}</b> "; } else { echo "<a href='" . makeHref(array('page' => $pageno, 'tab' => $tabno, 'id' => $id, 'pg' => $i)) . "'>{$i}</a> "; } } echo "</center>"; // FIXME: address counter could be calculated incorrectly in some cases if ($can_import) { printOpFormIntro('importPTRData', array('addrcount' => $endip - $startip + 1)); $idx = 1; $box_counter = 1; } echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n"; echo '<tr><th>address</th><th>current name</th><th>DNS data</th>'; if ($can_import) { echo '<th>import</th>'; } echo '</tr>'; $cnt_match = $cnt_mismatch = $cnt_missing = 0; for ($ip = $startip; $ip <= $endip; $ip++) { // Find the (optional) DB name and the (optional) DNS record, then // compare values and produce a table row depending on the result. $ip_bin = ip4_int2bin($ip); $addr = isset($range['addrlist'][$ip_bin]) ? $range['addrlist'][$ip_bin] : array('name' => '', 'reserved' => 'no'); $straddr = ip4_format($ip_bin); $ptrname = gethostbyaddr($straddr); if ($ptrname == $straddr) { $ptrname = ''; } if ($can_import) { echo "<input type=hidden name=addr_{$idx} value={$straddr}>\n"; echo "<input type=hidden name=descr_{$idx} value={$ptrname}>\n"; echo "<input type=hidden name=rsvd_{$idx} value={$addr['reserved']}>\n"; } echo '<tr'; $print_cbox = FALSE; // Ignore network and broadcast addresses if ($ip == $startip && $addr['name'] == 'network' || $ip == $endip && $addr['name'] == 'broadcast') { echo ' class=trbusy'; } if ($addr['name'] == $ptrname) { if (strlen($ptrname)) { echo ' class=trok'; $cnt_match++; } } elseif (!strlen($addr['name']) or !strlen($ptrname)) { echo ' class=trwarning'; $print_cbox = TRUE; $cnt_missing++; } else { echo ' class=trerror'; $print_cbox = TRUE; $cnt_mismatch++; } echo "><td class='tdleft"; if (isset($range['addrlist'][$ip_bin]['class']) and strlen($range['addrlist'][$ip_bin]['class'])) { echo ' ' . $range['addrlist'][$ip_bin]['class']; } echo "'>" . mkA($straddr, 'ipaddress', $straddr) . '</td>'; echo "<td class=tdleft>{$addr['name']}</td><td class=tdleft>{$ptrname}</td>"; if ($can_import) { echo '<td>'; if ($print_cbox) { echo "<input type=checkbox name=import_{$idx} tabindex={$idx} id=atom_1_" . $box_counter++ . "_1>"; } else { echo ' '; } echo '</td>'; $idx++; } echo "</tr>\n"; } if ($can_import && $box_counter > 1) { echo '<tr><td colspan=3 align=center><input type=submit value="Import selected records"></td><td>'; addJS('js/racktables.js'); echo --$box_counter ? "<a href='javascript:;' onclick=\"toggleColumnOfAtoms(1, 1, {$box_counter})\">(toggle selection)</a>" : ' '; echo '</td></tr>'; } echo "</table>"; if ($can_import) { echo '</form>'; } finishPortlet(); echo "</td><td class=pcright>"; startPortlet('stats'); echo "<table border=0 width='100%' cellspacing=0 cellpadding=2>"; echo "<tr class=trok><th class=tdright>Exact matches:</th><td class=tdleft>{$cnt_match}</td></tr>\n"; echo "<tr class=trwarning><th class=tdright>Missing from DB/DNS:</th><td class=tdleft>{$cnt_missing}</td></tr>\n"; if ($cnt_mismatch) { echo "<tr class=trerror><th class=tdright>Mismatches:</th><td class=tdleft>{$cnt_mismatch}</td></tr>\n"; } echo "</table>\n"; finishPortlet(); echo "</td></tr></table>\n"; }
function PingTab($id) { $pingtimeout = "50"; if (isset($_REQUEST['pg'])) { $page = $_REQUEST['pg']; } else { $page = 0; } global $pageno, $tabno; $maxperpage = getConfigVar('IPV4_ADDRS_PER_PAGE'); $range = spotEntity('ipv4net', $id); loadIPAddrList($range); echo "<center><h1>{$range['ip']}/{$range['mask']}</h1><h2>{$range['name']}</h2></center>\n"; echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>"; startPortlet('icmp ping comparrison:'); $startip = ip4_bin2int($range['ip_bin']); $endip = ip4_bin2int(ip_last($range)); $realstartip = $startip; $realendip = $endip; $numpages = 0; if ($endip - $startip > $maxperpage) { $numpages = ($endip - $startip) / $maxperpage; $startip = $startip + $page * $maxperpage; $endip = $startip + $maxperpage - 1; } echo "<center>"; if ($numpages) { echo '<h3>' . ip4_format(ip4_int2bin($startip)) . ' ~ ' . ip4_format(ip4_int2bin($endip)) . '</h3>'; } for ($i = 0; $i < $numpages; $i++) { if ($i == $page) { echo "<b>{$i}</b> "; } else { echo "<a href='" . makeHref(array('page' => $pageno, 'tab' => $tabno, 'id' => $id, 'pg' => $i)) . "'>{$i}</a> "; } } echo "</center>"; echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n"; echo "<tr><th>address</th><th>name</th><th>response</th></tr>\n"; $idx = 1; $box_counter = 1; $cnt_ok = $cnt_noreply = $cnt_mismatch = 0; for ($ip = $startip; $ip <= $endip; $ip++) { $ip_bin = ip4_int2bin($ip); $addr = isset($range['addrlist'][$ip_bin]) ? $range['addrlist'][$ip_bin] : array('name' => '', 'reserved' => 'no'); $straddr = ip4_format($ip_bin); system("/usr/sbin/fping -q -c 1 -t {$pingtimeout} {$straddr}", $pingreply); // FIXME: This is a huge and ugly IF/ELSE block. Prettify anyone? if (!$pingreply) { if (!empty($addr['name']) and $addr['reserved'] == 'no' or !empty($addr['allocs'])) { echo '<tr class=trok'; $cnt_ok++; } else { echo $addr['reserved'] == 'yes' ? '<tr class=trwarning' : '<tr class=trerror'; $cnt_mismatch++; } } else { if (!empty($addr['name']) and $addr['reserved'] == 'no' or !empty($addr['allocs'])) { echo '<tr class=trwarning'; $cnt_noreply++; } else { echo '<tr'; } } echo "><td class='tdleft"; if (isset($range['addrlist'][$ip_bin]['class']) and strlen($range['addrlist'][$ip_bin]['class'])) { echo ' ' . $range['addrlist'][$ip_bin]['class']; } echo "'><a href='" . makeHref(array('page' => 'ipaddress', 'ip' => $straddr)) . "'>{$straddr}</a></td>"; echo "<td class=tdleft>{$addr['name']}</td><td class=tderror>"; if (!$pingreply) { echo "Yes"; } else { echo "No"; } echo "</td></tr>\n"; $idx++; } echo "</td></tr>"; echo "</table>"; echo "</form>"; finishPortlet(); echo "</td><td class=pcright>"; startPortlet('stats'); echo "<table border=0 width='100%' cellspacing=0 cellpadding=2>"; echo "<tr class=trok><th class=tdright>OKs:</th><td class=tdleft>{$cnt_ok}</td></tr>\n"; echo "<tr class=trwarning><th class=tdright>Did not reply:</th><td class=tdleft>{$cnt_noreply}</td></tr>\n"; if ($cnt_mismatch) { echo "<tr class=trerror><th class=tdright>Unallocated answer:</th><td class=tdleft>{$cnt_mismatch}</td></tr>\n"; } echo "</table>\n"; finishPortlet(); echo "</td></tr></table>\n"; }