r4488 ability to suppress logging of ports and IP changes by setting a global variable
[racktables] / wwwroot / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
e82deb48 8require_once 'ajax-interface.php';
65e557dd 9
9c0b0016
DO
10// Interface function's special.
11$nextorder['odd'] = 'even';
12$nextorder['even'] = 'odd';
13
52c836b1
DO
14// address allocation type
15$aat = array
16(
17 'regular' => 'Connected',
18 'virtual' => 'Loopback',
19 'shared' => 'Shared',
20 'router' => 'Router',
21);
beb9e88a 22// address allocation code, IPv4 addresses and objects view
52c836b1
DO
23$aac = array
24(
25 'regular' => '',
26 'virtual' => '<strong>L</strong>',
27 'shared' => '<strong>S</strong>',
28 'router' => '<strong>R</strong>',
29);
beb9e88a
DO
30// address allocation code, IPv4 networks view
31$aac2 = array
32(
33 'regular' => '',
34 'virtual' => '<strong>L:</strong>',
29025f8e 35 'shared' => '<strong>S:</strong>',
beb9e88a
DO
36 'router' => '<strong>R:</strong>',
37);
52c836b1 38
0dabdc53
DO
39$vtdecoder = array
40(
41 'ondemand' => '',
54b7ced3
DO
42 'compulsory' => 'P',
43# 'alien' => 'NT',
0dabdc53
DO
44);
45
46$vtoptions = array
47(
54b7ced3
DO
48 'ondemand' => 'auto',
49 'compulsory' => 'permanent',
50# 'alien' => 'never touch',
0dabdc53
DO
51);
52
e5c4506d
DO
53// This may be populated later onsite, report rendering function will use it.
54// See the $systemreport for structure.
55$localreports = array();
d6adad3e 56
9db67d95
DO
57$CodePressMap = array
58(
59 'sql' => 'sql',
60 'php' => 'php',
61 'html' => 'html',
62 'css' => 'css',
63 'js' => 'javascript',
64);
e5c4506d 65
8d4f7d18
DO
66$attrtypes = array
67(
68 'uint' => '[U] unsigned integer',
69 'float' => '[F] floating point',
70 'string' => '[S] string',
71 'dict' => '[D] dictionary record'
72);
73
f97df464
DO
74function renderInterfaceHTML ($pageno, $tabno, $payload)
75{
76?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
77<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
78<head><title><?php echo getTitle ($pageno); ?></title>
79<?php printPageHeaders(); ?>
80</head>
81<body>
82<table border=0 cellpadding=0 cellspacing=0 width="100%" height="100%" class="maintable">
83 <tr class="mainheader"><td>
84 <table width="100%" cellspacing="0" cellpadding="2" border="0">
85 <tr>
86 <td valign=top><a href="http://racktables.org/"><?php printImageHREF ('logo'); ?></a></td>
87 <td valign=top><div class=greeting><?php printGreeting(); ?></div></td>
88 </tr>
89 </table>
90 </td></tr>
91 <tr><td class="menubar">
92 <table border="0" width="100%" cellpadding="3" cellspacing="0">
93 <tr><?php showPathAndSearch ($pageno); ?></tr>
94 </table>
95 </td></tr>
96 <tr><td><?php showTabs ($pageno, $tabno); ?></td></tr>
97 <tr><td><?php showMessageOrError(); ?></td></tr>
98 <tr><td><?php echo $payload; ?></td></tr>
99</table>
100</body>
101</html>
102<?php
103}
104
e673ee24 105// Main menu.
4b680876
DO
106function renderIndexItem ($ypageno) {
107 global $page;
108 if (permitted($ypageno)) {
21ee3351
AA
109 $title = isset ($page[$ypageno]['title']) ? $page[$ypageno]['title'] : dynamic_title_decoder ($ypageno);
110 if (is_array ($title))
111 $title = $title['name'];
4b680876 112 print " <td>\n";
21ee3351 113 print " <h1><a href='".makeHref(array('page'=>$ypageno))."'>".$title."<br>\n";
4b680876
DO
114 printImageHREF ($ypageno);
115 print "</a></h1>\n";
116 print " </td>\n";
117 } else {
118 print " <td>&nbsp;</td>\n";
119 }
120}
121
e673ee24
DO
122function renderIndex ()
123{
67c5c049 124 global $indexlayout;
e673ee24
DO
125?>
126<table border=0 cellpadding=0 cellspacing=0 width='100%'>
127 <tr>
128 <td>
129 <div style='text-align: center; margin: 10px; '>
a544d2c4 130 <table width='100%' cellspacing=0 cellpadding=20 class=mainmenu border=0>
4b680876 131<?php
67c5c049
DO
132foreach ($indexlayout as $row)
133{
134 echo '<tr>';
135 foreach ($row as $column)
136 if ($column === NULL)
137 echo '<td>&nbsp;</td>';
138 else
139 renderIndexItem ($column);
140 echo '</tr>';
141}
142?>
e673ee24
DO
143 </table>
144 </div>
145 </td>
146 </tr>
147</table>
b325120a 148<?php
e673ee24
DO
149}
150
f3505b35
AA
151function getRenderedAlloc ($object_id, $alloc)
152{
153 $ret = array
154 (
155 'tr_class' => '',
156 'td_ip' => '',
157 'td_network' => '',
158 'td_routed_by' => '',
159 'td_peers' => '',
160 );
161 $dottedquad = $alloc['addrinfo']['ip'];
162
163 $hl_ip_addr = '';
164 if (isset ($_REQUEST['hl_ipv6_addr']))
165 {
166 if ($hl_ipv6 = assertIPv6Arg ('hl_ipv6_addr'))
167 $hl_ip_addr = $hl_ipv6->format();
168 }
169 elseif (isset ($_REQUEST['hl_ipv4_addr']))
170 $hl_ip_addr = $_REQUEST['hl_ipv4_addr'];
171 if ($hl_ip_addr)
172 addAutoScrollScript ("ip-$hl_ip_addr");
173
174 // prepare realm and network info
175 if ($alloc['addrinfo']['version'] == 6)
176 {
177 $ipv6_address = new IPv6Address();
178 $ipv6_address->parse ($dottedquad);
179 $addr_page_name = 'ipv6address';
180 if ($netid = getIPv6AddressNetworkId ($ipv6_address))
181 {
182 $netinfo = spotEntity ('ipv6net', $netid);
183 loadIPv6AddrList ($netinfo);
184 }
185 }
186 else
187 {
188 $addr_page_name = 'ipaddress';
189 if ($netid = getIPv4AddressNetworkId ($dottedquad))
190 {
191 $netinfo = spotEntity ('ipv4net', $netid);
192 loadIPv4AddrList ($netinfo);
193 }
194 }
195
196 $ret['tr_class'] = $alloc['addrinfo']['class'];
197 $td_class = 'tdleft';
198 if ($hl_ip_addr == $dottedquad)
199 $td_class .= ' port_highlight';
200
68c91b9c
AA
201 // render IP change history
202 $ip_title = '';
203 $ip_class = '';
204 if (isset ($alloc['addrinfo']['last_log']))
205 {
206 $log = $alloc['addrinfo']['last_log'];
207 $ip_title = "title='" .
208 htmlspecialchars
209 (
210 $log['user'] . ', ' . formatAge ($log['time']),
211 ENT_QUOTES
212 ) . "'";
213 $ip_class = 'hover-history underline';
214 }
215
f3505b35
AA
216 // render IP address td
217 global $aac;
218 $ret['td_ip'] = "<td class='$td_class'>";
219 if (NULL !== $netid)
68c91b9c 220 $ret['td_ip'] .= "<a name='ip-$dottedquad' class='$ip_class' $ip_title href='" .
f3505b35
AA
221 makeHref (
222 array
223 (
224 'page' => $addr_page_name,
225 'hl_object_id' => $object_id,
226 'ip' => $dottedquad,
227 )
228 ) . "'>" . $dottedquad . "</a>";
229 else
68c91b9c 230 $ret['td_ip'] .= "<span class='$ip_class' $ip_title>$dottedquad</span>";
f3505b35
AA
231 if (getConfigVar ('EXT_IPV4_VIEW') != 'yes')
232 $ret['td_ip'] .= '<small>/' . (NULL === $netid ? '??' : $netinfo['mask']) . '</small>';
233 $ret['td_ip'] .= '&nbsp;' . $aac[$alloc['type']];
234 if (strlen ($alloc['addrinfo']['name']))
235 $ret['td_ip'] .= ' (' . niftyString ($alloc['addrinfo']['name']) . ')';
236 $ret['td_ip'] .= '</td>';
237
238 // render network and routed_by tds
239 if (NULL === $netid)
240 {
241 $ret['td_network'] = "<td class='$td_class sparenetwork'>N/A</td>";
242 $ret['td_routed_by'] = $ret['td_network'];
243 }
244 else
245 {
246 $ret['td_network'] = "<td class='$td_class'>" .
247 getOutputOf ('renderCell', $netinfo) . '</td>';
248
249 // filter out self-allocation
250 $other_routers = array();
251 foreach (findRouters ($netinfo['addrlist']) as $router)
252 if ($router['id'] != $object_id)
253 $other_routers[] = $router;
254 if (count ($other_routers))
255 $ret['td_routed_by'] = getOutputOf ('printRoutersTD', $other_routers);
256 else
257 $ret['td_routed_by'] = "<td class='$td_class'>&nbsp;</td>";
258 }
259
260 // render peers td
261 $ret['td_peers'] = "<td class='$td_class'>";
262 $prefix = '';
263 if ($alloc['addrinfo']['reserved'] == 'yes')
264 {
265 $ret['td_peers'] .= $prefix . '<strong>RESERVED</strong>';
266 $prefix = '; ';
267 }
268 foreach ($alloc['addrinfo']['allocs'] as $allocpeer)
269 {
270 if ($allocpeer['object_id'] == $object_id)
271 continue;
272 $ret['td_peers'] .= $prefix . "<a href='" . makeHref (array ('page' => 'object', 'object_id' => $allocpeer['object_id'])) . "'>";
273 if (isset ($allocpeer['osif']) and strlen ($allocpeer['osif']))
274 $ret['td_peers'] .= $allocpeer['osif'] . '@';
275 $ret['td_peers'] .= $allocpeer['object_name'] . '</a>';
276 $prefix = '; ';
277 }
278 $ret['td_peers'] .= '</td>';
279
280 return $ret;
281}
282
e673ee24
DO
283function renderRackspace ()
284{
95857b5c
DO
285 $found_racks = array();
286 $rows = array();
a8efc03e 287 $cellfilter = getCellFilter();
1ebbf889 288 $rackCount = 0;
95857b5c
DO
289 foreach (getRackRows() as $row_id => $row_name) {
290 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
291 $found_racks = array_merge($found_racks, $rackList);
292 $rows[] = array(
293 'row_id' => $row_id,
294 'row_name' => $row_name,
295 'racks' => $rackList
296 );
1ebbf889 297 $rackCount += count($rackList);
95857b5c 298 }
1ebbf889 299
95857b5c
DO
300 echo "<table class=objview border=0 width='100%'><tr><td class=pcleft>";
301 renderCellFilterPortlet ($cellfilter, 'rack', $found_racks);
489a7502 302 echo '</td><td class=pcright>';
1ebbf889
AA
303
304 if (! renderEmptyResults($cellfilter, 'racks', $rackCount))
e673ee24 305 {
1ebbf889
AA
306 echo '<table border=0 cellpadding=10 cellpadding=1>';
307 // generate thumb gallery
308 global $nextorder;
309 $rackwidth = getRackImageWidth();
310 // Zero value effectively disables the limit.
311 $maxPerRow = getConfigVar ('RACKS_PER_ROW');
312 $order = 'odd';
313 foreach ($rows as $row)
314 {
315 $row_id = $row['row_id'];
316 $row_name = $row['row_name'];
317 $rackList = $row['racks'];
318
319 if (!count ($rackList) and count ($cellfilter['expression']))
320 continue;
321 $rackListIdx = 0;
322 echo "<tr class=row_${order}><th class=tdleft>";
323 echo "<a href='".makeHref(array('page'=>'row', 'row_id'=>$row_id))."${cellfilter['urlextra']}'>";
324 echo "${row_name}</a></th><td><table border=0 cellspacing=5><tr>";
325 if (!count ($rackList))
326 echo "<td>(empty row)</td>";
327 else
328 foreach ($rackList as $rack)
48325652 329 {
1ebbf889
AA
330 if ($rackListIdx > 0 and $maxPerRow > 0 and $rackListIdx % $maxPerRow == 0)
331 {
332 echo '</tr></table></tr>';
333 echo "<tr class=row_${order}><th class=tdleft>${row_name} (continued)";
334 echo "</th><td><table border=0 cellspacing=5><tr>";
335 }
336 echo "<td align=center><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
337 echo "<img border=0 width=${rackwidth} height=";
338 echo getRackImageHeight ($rack['height']);
339 echo " title='${rack['height']} units'";
4afb4c10 340 echo "src='?module=image&img=minirack&rack_id=${rack['id']}'>";
1ebbf889
AA
341 echo "<br>${rack['name']}</a></td>";
342 $rackListIdx++;
48325652 343 }
1ebbf889
AA
344 $order = $nextorder[$order];
345 echo "</tr></table></tr>\n";
346 }
347 echo "</table>\n";
e673ee24 348 }
489a7502 349 echo "</td></tr></table>\n";
e673ee24
DO
350}
351
345fd640
AD
352function renderRackspaceRowEditor ()
353{
354 function printNewItemTR ()
355 {
356 printOpFormIntro ('addRow');
7be51fea
DO
357 echo "<tr><td>";
358 printImageHREF ('create', 'Add new row', TRUE);
359 echo "</td><td><input type=text name=name tabindex=100></td><td>";
345fd640 360 printImageHREF ('create', 'Add new row', TRUE, 101);
7be51fea 361 echo "</td></tr></form>";
345fd640 362 }
d732e47e 363 startPortlet ('Rows');
345fd640 364 echo "<table border=0 cellspacing=0 cellpadding=5 align=center class=widetable>\n";
7be51fea 365 echo "<tr><th>&nbsp;</th><th>Name</th><th>&nbsp;</th></tr>\n";
345fd640
AD
366 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
367 printNewItemTR();
c40666f5 368 foreach (getRackRows() as $row_id => $row_name)
345fd640 369 {
7be51fea 370 echo "<tr><td>";
a8efc03e 371 if ($rc = count (listCells ('rack', $row_id)))
6c18dd08 372 printImageHREF ('nodestroy', "${rc} rack(s) here");
7be51fea 373 else
5af82683 374 {
c40666f5 375 echo "<a href=\"".makeHrefProcess(array('op'=>'delete', 'row_id'=>$row_id))."\">";
7be51fea 376 printImageHREF ('destroy', 'Delete row');
5af82683
DY
377 echo "</a>";
378 }
c40666f5
DO
379 printOpFormIntro ('updateRow', array ('row_id' => $row_id));
380 echo "</td><td><input type=text name=name value='${row_name}'></td><td>";
7be51fea
DO
381 printImageHREF ('save', 'Save changes', TRUE);
382 echo "</form></td></tr>\n";
345fd640
AD
383 }
384 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
385 printNewItemTR();
386 echo "</table><br>\n";
387 finishPortlet();
388}
389
7e1db771 390function renderRow ($row_id)
e673ee24 391{
0cc24e9a 392 $rowInfo = getRackRowInfo ($row_id);
a8efc03e
DO
393 $cellfilter = getCellFilter();
394 $rackList = filterCellList (listCells ('rack', $row_id), $cellfilter['expression']);
e673ee24
DO
395 // Main layout starts.
396 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
397
398 // Left portlet with row information.
399 echo "<tr><td class=pcleft>";
a8ce7234 400 startPortlet ($rowInfo['name']);
e673ee24 401 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
5af82683
DY
402 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
403 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
04d619d0 404 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
114e50af
DO
405 renderProgressBar (getRSUforRackRow ($rackList));
406 echo "</td></tr>\n";
e673ee24
DO
407 echo "</table><br>\n";
408 finishPortlet();
95857b5c 409 renderCellFilterPortlet ($cellfilter, 'rack', $rackList, 'row_id', $row_id);
e673ee24 410
48325652 411 echo "</td><td class=pcright>";
e673ee24 412
4fbb5a00 413 global $nextorder;
d5157018 414 $rackwidth = getRackImageWidth() * getConfigVar ('ROW_SCALE');
f5883ec1
DO
415 // Maximum number of racks per row is proportionally less, but at least 1.
416 $maxPerRow = max (floor (getConfigVar ('RACKS_PER_ROW') / getConfigVar ('ROW_SCALE')), 1);
417 $rackListIdx = 0;
e673ee24
DO
418 $order = 'odd';
419 startPortlet ('Racks');
420 echo "<table border=0 cellspacing=5 align='center'><tr>";
64b95774 421 foreach ($rackList as $rack)
e673ee24 422 {
f5883ec1
DO
423 if ($rackListIdx % $maxPerRow == 0)
424 {
425 if ($rackListIdx > 0)
426 echo '</tr>';
427 echo '<tr>';
428 }
4fbb5a00 429 echo "<td align=center class=row_${order}><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rack['id']))."'>";
d5157018 430 echo "<img border=0 width=${rackwidth} height=" . (getRackImageHeight ($rack['height']) * getConfigVar ('ROW_SCALE'));
e673ee24 431 echo " title='${rack['height']} units'";
4afb4c10 432 echo "src='?module=image&img=minirack&rack_id=${rack['id']}'>";
e673ee24
DO
433 echo "<br>${rack['name']}</a></td>";
434 $order = $nextorder[$order];
f5883ec1 435 $rackListIdx++;
e673ee24
DO
436 }
437 echo "</tr></table>\n";
438 finishPortlet();
e673ee24
DO
439 echo "</td></tr></table>";
440}
441
e673ee24 442// This function renders rack as HTML table.
7e1db771 443function renderRack ($rack_id, $hl_obj_id = 0)
e673ee24 444{
61a1d996
DO
445 $rackData = spotEntity ('rack', $rack_id);
446 amplifyCell ($rackData);
e673ee24
DO
447 markAllSpans ($rackData);
448 if ($hl_obj_id > 0)
449 highlightObject ($rackData, $hl_obj_id);
450 markupObjectProblems ($rackData);
451 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
452 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
d48d8820 453 echo "<center><table border=0><tr valign=middle>";
4fbb5a00 454 echo "<td><h2><a href='".makeHref(array('page'=>'row', 'row_id'=>$rackData['row_id']))."'>${rackData['row_name']}</a> :</h2></td>";
e673ee24
DO
455 // FIXME: use 'bypass'?
456 if ($prev_id != NULL)
9803c56c 457 {
4fbb5a00 458 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$prev_id))."'>";
9803c56c 459 printImageHREF ('prev', 'previous rack');
d48d8820 460 echo "</a></td>";
9803c56c 461 }
4fbb5a00 462 echo "<td><h2><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$rackData['id']))."'>${rackData['name']}</a></h2></td>";
e673ee24 463 if ($next_id != NULL)
9803c56c 464 {
4fbb5a00 465 echo "<td><a href='".makeHref(array('page'=>'rack', 'rack_id'=>$next_id))."'>";
f444c095 466 printImageHREF ('next', 'next rack');
d48d8820 467 echo "</a></td>";
9803c56c 468 }
d48d8820 469 echo "</h2></td></tr></table>\n";
e673ee24 470 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
d08147d6
DO
471 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
472 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
65e557dd 473 addAtomCSS();
e673ee24
DO
474 for ($i = $rackData['height']; $i > 0; $i--)
475 {
d08147d6 476 echo "<tr><th>${i}</th>";
e673ee24
DO
477 for ($locidx = 0; $locidx < 3; $locidx++)
478 {
479 if (isset ($rackData[$i][$locidx]['skipped']))
480 continue;
481 $state = $rackData[$i][$locidx]['state'];
65e557dd 482 echo "<td class='atom state_${state}";
e673ee24
DO
483 if (isset ($rackData[$i][$locidx]['hl']))
484 echo $rackData[$i][$locidx]['hl'];
65e557dd 485 echo "'";
e673ee24
DO
486 if (isset ($rackData[$i][$locidx]['colspan']))
487 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
488 if (isset ($rackData[$i][$locidx]['rowspan']))
489 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
490 echo ">";
491 switch ($state)
492 {
493 case 'T':
fb6e2f57 494 $objectData = spotEntity ('object', $rackData[$i][$locidx]['object_id']);
59a83bd8 495 if (strlen ($objectData['asset_no']))
e673ee24
DO
496 $prefix = "<div title='${objectData['asset_no']}";
497 else
498 $prefix = "<div title='no asset tag";
499 // Don't tell about label, if it matches common name.
0682218d 500 $body = '';
59a83bd8 501 if ($objectData['name'] != $objectData['label'] and strlen ($objectData['label']))
0682218d
AD
502 $body = ", visible label is \"${objectData['label']}\"";
503 // Display list of child objects, if any
504 $objectChildren = getEntityRelatives ('children', 'object', $objectData['id']);
505 if (count($objectChildren) > 0)
506 {
507 foreach ($objectChildren as $child)
508 $childNames[] = $child['name'];
509 natsort($childNames);
510 $suffix = sprintf(", contains %s'>", implode(', ', $childNames));
511 }
e673ee24
DO
512 else
513 $suffix = "'>";
0682218d 514 echo $prefix . $body . $suffix;
4fbb5a00 515 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$objectData['id']))."'>${objectData['dname']}</a></div>";
e673ee24
DO
516 break;
517 case 'A':
518 echo '<div title="This rackspace does not exist">&nbsp;</div>';
519 break;
520 case 'F':
521 echo '<div title="Free rackspace">&nbsp;</div>';
522 break;
523 case 'U':
524 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
525 break;
526 default:
527 echo '<div title="No data">&nbsp;</div>';
528 break;
529 }
530 echo '</td>';
531 }
532 echo "</tr>\n";
533 }
534 echo "</table></center>\n";
535}
536
e673ee24
DO
537function renderNewRackForm ($row_id)
538{
50b4ba85 539 startPortlet ('Add one');
f19c75d6 540 printOpFormIntro ('addRack', array ('got_data' => 'TRUE'));
e673ee24 541 echo '<table border=0 align=center>';
b901bf1f
DO
542 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
543 if ($defh == 0)
544 $defh = '';
72d52730
DO
545 echo "<tr><th class=tdright>Rack name (*):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td>";
546 echo "<td rowspan=4>Assign tags:<br>";
a26a6ccc 547 renderNewEntityTags ('rack');
72d52730 548 echo "</td></tr>\n";
b8094ae4 549 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height1 tabindex=2 value='${defh}'></td></tr>\n";
4134b5c0 550 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
f19c75d6
DO
551 echo "<tr><td class=submit colspan=2>";
552 printImageHREF ('CREATE', 'Add', TRUE);
553 echo "</td></tr></table></form>";
406b54bd 554 finishPortlet();
406b54bd 555
50b4ba85 556 startPortlet ('Add many');
f19c75d6 557 printOpFormIntro ('addRack', array ('got_mdata' => 'TRUE'));
50b4ba85
DO
558 echo '<table border=0 align=center>';
559 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
560 if ($defh == 0)
561 $defh = '';
72d52730
DO
562 echo "<tr><th class=tdright>Height in units (*):</th><td class=tdleft><input type=text name=rack_height2 value='${defh}'></td>";
563 echo "<td rowspan=3 valign=top>Assign tags:<br>";
a26a6ccc 564 renderNewEntityTags ('rack');
72d52730 565 echo "</td></tr>\n";
50b4ba85 566 echo "<tr><th class=tdright>Rack names (*):</th><td class=tdleft><textarea name=rack_names cols=40 rows=25></textarea></td></tr>\n";
f19c75d6
DO
567 echo "<tr><td class=submit colspan=2>";
568 printImageHREF ('CREATE', 'Add', TRUE);
e673ee24
DO
569 echo '</form></table>';
570 finishPortlet();
571}
572
3825c4db 573function renderEditObjectForm()
e673ee24 574{
2c2ea5f6 575 global $pageno, $virtual_obj_types;
3825c4db 576 $object_id = getBypassValue();
fb6e2f57 577 $object = spotEntity ('object', $object_id);
cdd3efe9 578 startPortlet ();
43fb6eaf 579 printOpFormIntro ('update');
cdd3efe9
AD
580
581 // static attributes
e10f583a
DO
582 echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
583 echo "<tr><td>&nbsp;</td><th colspan=2><h2>Attributes</h2></th></tr>";
3825c4db
DO
584 echo '<tr><td>&nbsp;</td><th class=tdright>Type:</th><td class=tdleft>';
585 printSelect (getObjectTypeChangeOptions ($object['id']), array ('name' => 'object_type_id'), $object['objtype_id']);
586 echo '</td></tr>';
22bb04da 587 // baseline info
e10f583a 588 echo "<tr><td>&nbsp;</td><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
2c2ea5f6 589 if (in_array($object['objtype_id'], $virtual_obj_types))
0682218d
AD
590 {
591 echo "<input type=hidden name=object_label value=''>\n";
592 echo "<input type=hidden name=object_asset_no value=''>\n";
0682218d
AD
593 }
594 else
595 {
596 echo "<tr><td>&nbsp;</td><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
597 echo "<tr><td>&nbsp;</td><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
0682218d
AD
598 }
599 // parent selection
600 if (rackObjectTypeMayHaveParent ($object['objtype_id']))
601 {
602 $parents = getEntityRelatives ('parents', 'object', $object_id);
603 foreach ($parents as $link_id => $parent_details)
604 {
605 if (!isset($label))
606 $label = count($parents) > 1 ? 'Containers:' : 'Container:';
607 echo "<tr><td>&nbsp;</td>";
608 echo "<th class=tdright>${label}</th><td class=tdleft>";
609 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$parent_details['entity_id']))."'>${parent_details['name']}</a>";
610 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
611 echo "<a href='".
612 makeHrefProcess(array(
613 'op'=>'unlinkEntities',
614 'link_id'=>$link_id,
615 'object_id'=>$object_id,
616 'page='=>'object',
617 'tab'=>'edit')).
618 "'>";
619 printImageHREF ('cut', 'Unlink container');
620 echo "</a>";
621 echo "</td></tr>\n";
622 $label = '&nbsp;';
623 }
624 echo "<tr><td>&nbsp;</td>";
625 echo "<th class=tdright>Select container:</th><td class=tdleft>";
626 echo "<span";
627 $helper_args = array ('object_id' => $object_id);
628 $popup_args = 'height=700, width=400, location=no, menubar=no, '.
629 'resizable=yes, scrollbars=yes, status=no, titlebar=no, toolbar=no';
630 echo " onclick='window.open(\"" . makeHrefForHelper ('objlist', $helper_args);
631 echo "\",\"findlink\",\"${popup_args}\");'>";
632 printImageHREF ('attach', 'Select a container');
633 echo "</span></td></tr>\n";
634 }
cdd3efe9 635 // optional attributes
e673ee24 636 $values = getAttrValues ($object_id);
0f63538a 637 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
2b98d5a2 638 if (count($values) > 0)
e673ee24 639 {
2b98d5a2
AD
640 $i = 0;
641 foreach ($values as $record)
e673ee24 642 {
2b98d5a2
AD
643 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
644 echo '<tr><td>';
59a83bd8 645 if (strlen ($record['value']))
2b98d5a2 646 {
4fbb5a00 647 echo "<a href='".makeHrefProcess(array('op'=>'clearSticker', 'object_id'=>$object_id, 'attr_id'=>$record['id']))."'>";
2b98d5a2
AD
648 printImageHREF ('clear', 'Clear value');
649 echo '</a>';
650 }
651 else
652 echo '&nbsp;';
653 echo '</td>';
e10f583a 654 echo "<th class=sticker>${record['name']}:</th><td class=tdleft>";
2b98d5a2
AD
655 switch ($record['type'])
656 {
657 case 'uint':
658 case 'float':
659 case 'string':
660 echo "<input type=text name=${i}_value value='${record['value']}'>";
661 break;
662 case 'dict':
7fa7047a 663 $chapter = readChapter ($record['chapter_id'], 'o');
2b98d5a2 664 $chapter[0] = '-- NOT SET --';
f3d274bf 665 $chapter = cookOptgroups ($chapter, $object['objtype_id'], $record['key']);
cd3775e9 666 printNiftySelect ($chapter, array ('name' => "${i}_value"), $record['key']);
2b98d5a2
AD
667 break;
668 }
669 echo "</td></tr>\n";
670 $i++;
e673ee24 671 }
e673ee24 672 }
e10f583a
DO
673 echo "<tr><td>&nbsp;</td><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
674 if ($object['has_problems'] == 'yes')
675 echo ' checked';
676 echo "></td></tr>\n";
abd1e9ac
DO
677 echo "<tr><td>&nbsp;</td><th class=tdright>Actions:</th><td class=tdleft>";
678 echo "<a href='".
3067f362 679 makeHrefProcess(array('op'=>'deleteObject', 'page'=>'depot', 'tab'=>'addmore', 'object_id'=>$object_id)).
abd1e9ac
DO
680 "' onclick=\"javascript:return confirm('Are you sure you want to delete the object?')\">" . getImageHREF ('destroy', 'Delete object') . "</a>";
681 echo "&nbsp;";
682 echo "<a href='".
683 makeHrefProcess(array ('op'=>'resetObject', 'page' => 'object', 'tab' => 'edit', 'object_id' => $object_id)).
684 "' onclick=\"javascript:return confirm('Are you sure you want to reset most of object properties?')\">" . getImageHREF ('clear', 'Reset (cleanup) object') . "</a>";
685 echo "</td></tr>\n";
e10f583a 686 echo "<tr><td colspan=3><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
cdd3efe9 687
e10f583a 688 echo "<tr><th class=submit colspan=3>";
5bbbeaa2 689 printImageHREF ('SAVE', 'Save changes', TRUE);
cdd3efe9 690 echo "</form></th></tr></table>\n";
e673ee24 691 finishPortlet();
e673ee24 692
cdd3efe9 693 echo '<table border=0 width=100%><tr><td>';
e673ee24
DO
694 startPortlet ('history');
695 renderHistory ($pageno, $object_id);
696 finishPortlet();
cdd3efe9 697 echo '</td></tr></table>';
e673ee24
DO
698}
699
700// This is a clone of renderEditObjectForm().
701function renderEditRackForm ($rack_id)
702{
0c2b7c4a 703 global $pageno;
61a1d996
DO
704 $rack = spotEntity ('rack', $rack_id);
705 amplifyCell ($rack);
e673ee24 706
e673ee24 707 startPortlet ('Rack attributes');
7056988c 708 printOpFormIntro ('updateRack');
e673ee24
DO
709 echo '<table border=0 align=center>';
710 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
cd3775e9 711 printSelect (getRackRows(), array ('name' => 'rack_row_id'), $rack['row_id']);
e673ee24
DO
712 echo "</td></tr>\n";
713 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
714 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
715 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
c8187437
DY
716 if (count ($rack['mountedObjects']) == 0)
717 {
718 echo "<tr><th class=tdright>Actions:</th><td class=tdleft><a href='".
719 makeHrefProcess(array('op'=>'deleteRack', 'rack_id'=>$rack_id)).
720 "' onclick=\"javascript:return confirm('Are you sure you want to delete the rack?')\">Delete rack</a></td></tr>\n";
721 }
7056988c
DO
722 echo "<tr><td class=submit colspan=2>";
723 printImageHREF ('SAVE', 'Save changes', TRUE);
724 echo "</td></tr>\n";
e673ee24
DO
725 echo '</form></table><br>';
726 finishPortlet();
727
728 startPortlet ('History');
729 renderHistory ($pageno, $rack_id);
730 finishPortlet();
731}
732
254673dd
DO
733// used by renderGridForm() and renderRackPage()
734function renderRackInfoPortlet ($rackData)
735{
736 startPortlet ('summary');
737 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
738 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
739 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
740 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
04d619d0 741 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
254673dd
DO
742 renderProgressBar (getRSUforRack ($rackData));
743 echo "</td></tr>\n";
744 echo "<tr><th width='50%' class=tdright>Objects:</th><td class=tdleft>";
61a1d996 745 echo count ($rackData['mountedObjects']);
254673dd 746 echo "</td></tr>\n";
9b57f793 747 printTagTRs ($rackData, makeHref(array('page'=>'rackspace', 'tab'=>'default'))."&");
59a83bd8 748 if (strlen ($rackData['comment']))
254673dd
DO
749 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
750 echo '</table>';
751 finishPortlet();
752}
753
e673ee24 754// This is a universal editor of rack design/waste.
7056988c 755// FIXME: switch to using printOpFormIntro()
7e1db771 756function renderGridForm ($rack_id, $filter, $header, $submit, $state1, $state2)
e673ee24 757{
61a1d996
DO
758 $rackData = spotEntity ('rack', $rack_id);
759 amplifyCell ($rackData);
254673dd 760 $filter ($rackData);
e673ee24
DO
761 markupObjectProblems ($rackData);
762
e673ee24
DO
763 // Render the result whatever it is.
764 // Main layout.
765 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
766 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
767
768 // Left column with information portlet.
769 echo "<tr><td class=pcleft height='1%' width='50%'>";
254673dd 770 renderRackInfoPortlet ($rackData);
e673ee24 771 echo "</td>\n";
bb09cca0 772 echo "<td class=pcright>";
e673ee24
DO
773
774 // Grid form.
775 startPortlet ($header);
65e557dd 776 addJS ('js/racktables.js');
e673ee24
DO
777 echo "<center>\n";
778 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c 779 echo "<tr><th width='10%'>&nbsp;</th>";
64259015
DO
780 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
781 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
782 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
4fbb5a00 783 printOpFormIntro ('updateRack');
e673ee24
DO
784 markupAtomGrid ($rackData, $state2);
785 renderAtomGrid ($rackData);
786 echo "</table></center>\n";
787 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
788 finishPortlet();
bb09cca0 789 echo "</td></tr></table>\n";
e673ee24
DO
790}
791
792function renderRackDesign ($rack_id)
793{
bb09cca0 794 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
795}
796
7e1db771 797function renderRackProblems ($rack_id)
e673ee24 798{
bb09cca0 799 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
800}
801
802function startPortlet ($title = '')
803{
804 echo "<div class=portlet><h2>${title}</h2>";
805}
806
807function finishPortlet ()
808{
809 echo "</div>\n";
810}
811
7e1db771 812function renderRackObject ($object_id)
e673ee24 813{
f3505b35 814 global $nextorder, $virtual_obj_types;
fb6e2f57 815 $info = spotEntity ('object', $object_id);
94fe6370 816 amplifyCell ($info);
e673ee24
DO
817 // Main layout starts.
818 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
819 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
820 // left column with uknown number of portlets
821 echo "<tr><td class=pcleft>";
0ab782bc 822 startPortlet ('summary');
e673ee24 823 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
59a83bd8 824 if (strlen ($info['name']))
e673ee24 825 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
94fe6370 826 elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
a0ec6295 827 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
341fd895
DO
828 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft><a href='";
829 echo makeHref (array (
830 'page' => 'depot',
831 'tab' => 'default',
832 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
833 ));
7fa7047a 834 echo "'>" . decodeObjectType ($info['objtype_id'], 'o') . '</a></td></tr>';
59a83bd8 835 if (strlen ($info['asset_no']))
e673ee24 836 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
d4e8ddeb 837 elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
a0ec6295 838 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
59a83bd8 839 if (strlen ($info['label']))
e673ee24 840 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
0682218d
AD
841 if ($parents = getEntityRelatives ('parents', 'object', $object_id))
842 {
843 foreach ($parents as $parent)
844 {
845 if (!isset($label))
846 $label = count($parents) > 1 ? 'Containers:' : 'Container:';
847 echo "<tr><th width='50%' class=tdright>${label}</th><td class=tdleft>";
848 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$parent['entity_id']))."'>${parent['name']}</a>";
849 echo "</td></tr>\n";
850 $label = '&nbsp;';
851 }
852 unset ($label);
853 }
854 if ($children = getEntityRelatives ('children', 'object', $object_id))
855 {
856 foreach ($children as $child)
857 {
858 if (!isset($label))
859 $label = 'Contains:';
860 echo "<tr><th width='50%' class=tdright>${label}</th><td class=tdleft>";
861 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$child['entity_id']))."'>${child['name']}</a>";
862 echo "</td></tr>\n";
863 $label = '&nbsp;';
864 }
865 }
e673ee24
DO
866 if ($info['has_problems'] == 'yes')
867 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
8ad59489 868 foreach (getAttrValues ($object_id) as $record)
59a83bd8 869 if (strlen ($record['value']))
0794fb66
AA
870 {
871 echo "<tr><th width='50%' class=sticker>${record['name']}:</th><td class=sticker>" .
8ad59489 872 formatAttributeValue ($record) .
0794fb66
AA
873 "</td></tr>\n";
874 }
341fd895
DO
875 printTagTRs
876 (
9b57f793 877 $info,
341fd895
DO
878 makeHref
879 (
880 array
881 (
882 'page'=>'depot',
883 'tab'=>'default',
884 'andor' => 'and',
a8efc03e 885 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
341fd895
DO
886 )
887 )."&"
888 );
e673ee24
DO
889 echo "</table><br>\n";
890 finishPortlet();
891
59a83bd8 892 if (strlen ($info['comment']))
e673ee24
DO
893 {
894 startPortlet ('Comment');
6cc5d6cd 895 echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
e673ee24
DO
896 finishPortlet ();
897 }
898
9a90adc4
DO
899 if (count ($logrecords = getLogRecordsForObject ($_REQUEST['object_id'])))
900 {
901 startPortlet ('log records');
902 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
903 $order = 'odd';
904 foreach (getLogRecordsForObject ($_REQUEST['object_id']) as $row)
905 {
906 echo "<tr class=row_${order} valign=top>";
907 echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
c14b5720 908 echo '<td class="slbconf rsvtext">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
9a90adc4
DO
909 echo '</tr>';
910 $order = $nextorder[$order];
911 }
912 echo '</table>';
913 finishPortlet();
914 }
915
65e557dd 916 switchportInfoJS ($object_id); // load JS code to make portnames interactive
e1ae3fb4
AD
917 renderFilesPortlet ('object', $object_id);
918
9f75e165 919 if (count ($info['ports']))
e673ee24 920 {
0ab782bc 921 startPortlet ('ports and links');
9f75e165
DO
922 $hl_port_id = 0;
923 if (isset ($_REQUEST['hl_port_id']))
e673ee24 924 {
0cc24e9a 925 assertUIntArg ('hl_port_id');
9f75e165 926 $hl_port_id = $_REQUEST['hl_port_id'];
65e557dd 927 addAutoScrollScript ("port-$hl_port_id");
9f75e165
DO
928 }
929 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
930 echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
0d59a51c 931 echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
0c7c9f8b
DO
932 echo '<th class=tdcenter colspan=2>Remote object and port</th>';
933 echo '<th class=tdleft>Cable ID</th></tr>';
9f75e165
DO
934 foreach ($info['ports'] as $port)
935 {
936 echo '<tr';
937 if ($hl_port_id == $port['id'])
938 echo ' class=port_highlight';
65e557dd 939 $a_class = isEthernetPort ($port) ? 'port-menu' : '';
a8dc2982 940 echo "><td class='tdleft' NOWRAP><a name='port-${port['id']}' class='ancor interactive-portname nolink $a_class'>${port['name']}</a></td>";
65e557dd
AA
941 echo "<td class=tdleft>${port['label']}</td>";
942 echo "<td class=tdleft>" . formatPortIIFOIF ($port) . "</td><td class=tdleft><tt>${port['l2address']}</tt></td>";
9f75e165 943 if ($port['remote_object_id'])
e673ee24 944 {
5c6225b1 945 echo "<td class=tdleft>" .
a2ea559e 946 formatPortLink ($port['remote_object_id'], $port['remote_object_name'], $port['remote_id'], NULL) .
5c6225b1
AA
947 "</td>";
948 echo "<td class=tdleft>" . formatLoggedSpan ($port['last_log'], $port['remote_name'], 'underline') . "</td>";
0c7c9f8b 949 echo "<td class='tdleft rsvtext'>${port['cableid']}</td>";
e673ee24 950 }
9f75e165 951 else
a8dc2982 952 echo implode ('', formatPortReservation ($port)) . '<td></td>';
9f75e165 953 echo "</tr>";
e673ee24 954 }
fd5edda8 955 if (permitted (NULL, 'ports', 'set_reserve_comment'))
a8dc2982 956 addJS ('js/inplace-edit.js');
9f75e165 957 echo "</table><br>";
e673ee24
DO
958 finishPortlet();
959 }
85970da2 960
21ee3351 961 if (count ($info['ipv4']) + count ($info['ipv6']))
e673ee24 962 {
21ee3351 963 startPortlet ('IP addresses');
e673ee24 964 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
f0ed1181 965 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
0b9c98d7 966 echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
83fdf85f
DO
967 else
968 echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
21ee3351
AA
969
970 // group IP allocations by interface name instead of address family
971 $allocs_by_iface = array();
972 foreach (array ('ipv4', 'ipv6') as $ip_v)
973 foreach ($info[$ip_v] as $dottedquad => $alloc)
974 $allocs_by_iface[$alloc['osif']][$dottedquad] = $alloc;
975
976 // sort allocs array by portnames
977 foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
978 {
979 $is_first_row = TRUE;
f3505b35 980 foreach ($alloclist as $alloc)
b90c3907 981 {
f3505b35
AA
982 $rendered_alloc = getRenderedAlloc ($object_id, $alloc);
983 echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
21ee3351 984
f3505b35 985 // display iface name, same values are grouped into single cell
21ee3351
AA
986 if ($is_first_row)
987 {
988 $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
989 echo "<td class=tdleft $rowspan>$iface_name</td>";
990 $is_first_row = FALSE;
991 }
f3505b35 992 echo $rendered_alloc['td_ip'];
21ee3351 993 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
83fdf85f 994 {
f3505b35
AA
995 echo $rendered_alloc['td_network'];
996 echo $rendered_alloc['td_routed_by'];
21ee3351 997 }
f3505b35
AA
998 echo $rendered_alloc['td_peers'];
999
1000 echo "</tr>\n";
b90c3907 1001 }
e673ee24
DO
1002 }
1003 echo "</table><br>\n";
1004 finishPortlet();
1005 }
1006
94fe6370 1007 $forwards = $info['nat4'];
e673ee24
DO
1008 if (count($forwards['in']) or count($forwards['out']))
1009 {
f28fbe8b 1010 startPortlet('NATv4');
e673ee24
DO
1011
1012 if (count($forwards['out']))
1013 {
1014
f28fbe8b 1015 echo "<h3>locally performed NAT</h3>";
e673ee24 1016
105a3bc8 1017 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1018 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
e673ee24
DO
1019
1020 foreach ($forwards['out'] as $pf)
1021 {
2c817354
DO
1022 $class = 'trerror';
1023 $osif = '';
1024 if (isset ($alloclist [$pf['localip']]))
1025 {
1026 $class = $alloclist [$pf['localip']]['addrinfo']['class'];
1027 $osif = $alloclist [$pf['localip']]['osif'] . ': ';
1028 }
e673ee24 1029 echo "<tr class='$class'>";
4fbb5a00
DY
1030 echo "<td>${pf['proto']}</td><td class=tdleft>${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1031 echo "<td class=tdleft><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
53ef3908 1032 $address = getIPv4Address ($pf['remoteip']);
e673ee24 1033 echo "<td class='description'>";
53ef3908
DO
1034 if (count ($address['allocs']))
1035 foreach($address['allocs'] as $bond)
4fbb5a00 1036 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
59a83bd8 1037 elseif (strlen ($pf['remote_addr_name']))
f28fbe8b 1038 echo '(' . $pf['remote_addr_name'] . ')';
53ef3908 1039 echo "</td><td class='description'>${pf['description']}</td></tr>";
e673ee24
DO
1040 }
1041 echo "</table><br><br>";
1042 }
1043 if (count($forwards['in']))
1044 {
f28fbe8b 1045 echo "<h3>arriving NAT connections</h3>";
105a3bc8 1046 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1047 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
1048 foreach ($forwards['in'] as $pf)
1049 {
1050 echo "<tr>";
4fbb5a00
DY
1051 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
1052 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
1053 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
1054 echo "<td class='description'>${pf['description']}</td></tr>";
1055 }
e673ee24
DO
1056 echo "</table><br><br>";
1057 }
1058 finishPortlet();
1059 }
1060
94fe6370 1061 $pools = $info['ipv4rspools'];
78e7b769
DO
1062 if (count ($pools))
1063 {
300826cb 1064 $order = 'odd';
8128c257 1065 startPortlet ('Real server pools (' . count ($pools) . ')');
78e7b769 1066 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
1f54e1ba 1067 echo "<tr><th>VS</th><th>RS pool</th><th>RS</th><th>VS config</th><th>RS config</th><th>Prio</th></tr>\n";
3d26a66e 1068 foreach ($pools as $vs_id => $vs_info)
78e7b769 1069 {
b1a970c7 1070 echo "<tr valign=top class=row_${order}><td class=tdleft>";
6df2025d 1071 renderCell (spotEntity ('ipv4vs', $vs_id));
b1a970c7 1072 echo "</td><td class=tdleft>";
3d26a66e
AA
1073 renderCell (spotEntity ('ipv4rspool', $vs_info['pool_id']));
1074 echo '</td><td class=tdleft>' . $vs_info['rscount'] . '</td>';
1075 echo "<td class=slbconf>${vs_info['vsconfig']}</td>";
1076 echo "<td class=slbconf>${vs_info['rsconfig']}</td>";
1077 echo "<td class=slbconf>${vs_info['prio']}</td>";
78e7b769 1078 echo "</tr>\n";
300826cb 1079 $order = $nextorder[$order];
78e7b769
DO
1080 }
1081 echo "</table>\n";
1082 finishPortlet();
1083 }
e673ee24
DO
1084 echo "</td>\n";
1085
7056988c 1086 // After left column we have (surprise!) right column with rackspace portlet only.
e673ee24 1087 echo "<td class=pcright>";
2c2ea5f6 1088 if (!in_array($info['objtype_id'], $virtual_obj_types))
0682218d
AD
1089 {
1090 // rackspace portlet
1091 startPortlet ('rackspace allocation');
1092 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1093 renderRack ($rack_id, $object_id);
1094 echo '<br>';
1095 finishPortlet();
1096 }
e673ee24
DO
1097 echo "</td></tr>";
1098 echo "</table>\n";
1099}
1100
1101function renderRackMultiSelect ($sname, $racks, $selected)
1102{
04571888
DO
1103 // Transform the given flat list into a list of groups, each representing a rack row.
1104 $rdata = array();
e673ee24 1105 foreach ($racks as $rack)
04571888
DO
1106 if (!isset ($rdata[$rack['row_name']]))
1107 $rdata[$rack['row_name']] = array ($rack['id'] => $rack['name']);
1108 else
1109 $rdata[$rack['row_name']][$rack['id']] = $rack['name'];
4fbb5a00 1110 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementsByName(\"updateObjectAllocation\")[0].submit()'>\n";
04571888 1111 foreach ($rdata as $optgroup => $racklist)
e673ee24 1112 {
04571888
DO
1113 echo "<optgroup label='${optgroup}'>";
1114 foreach ($racklist as $rack_id => $rack_name)
1115 {
1116 echo "<option value=${rack_id}";
1117 if (!(array_search ($rack_id, $selected) === FALSE))
1118 echo ' selected';
1119 echo">${rack_name}</option>\n";
1120 }
e673ee24
DO
1121 }
1122 echo "</select>\n";
1123}
1124
e673ee24 1125// This function renders a form for port edition.
7e1db771 1126function renderPortsForObject ($object_id)
e673ee24 1127{
3153a326
DO
1128 $prefs = getPortListPrefs();
1129 function printNewItemTR ($prefs)
39b4abd0
DO
1130 {
1131 printOpFormIntro ('addPort');
1132 echo "<tr><td>";
f5ff50f5 1133 printImageHREF ('add', 'add a port', TRUE);
65e557dd 1134 echo "</td><td class='tdleft'><input type=text size=8 name=port_name tabindex=100></td>\n";
cd3775e9
DO
1135 echo "<td><input type=text name=port_label tabindex=101></td><td>";
1136 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 102), $prefs['selected']);
1137 echo "<td><input type=text name=port_l2address tabindex=103 size=18 maxlength=24></td>\n";
9318d2ef
DO
1138 echo "<td colspan=3>&nbsp;</td><td>";
1139 printImageHREF ('add', 'add a port', TRUE, 104);
1140 echo "</td></tr></form>";
39b4abd0 1141 }
a1fc539a 1142 if (getConfigVar('ENABLE_MULTIPORT_FORM') == 'yes' || getConfigVar('ENABLE_BULKPORT_FORM') == 'yes' )
f44fdef9
DO
1143 startPortlet ('Ports and interfaces');
1144 else
1145 echo '<br>';
9f75e165
DO
1146 $object = spotEntity ('object', $object_id);
1147 amplifyCell ($object);
a1fc539a
RF
1148 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes' && getConfigVar('ENABLE_BULKPORT_FORM') == 'yes'){
1149 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1150 echo "<tr><th>&nbsp;</th><th class=tdleft>Local name</th><th class=tdleft>Visible label</th><th class=tdleft>Interface</th><th class=tdleft>Start Number</th>";
1151 echo "<th class=tdleft>Count</th><th>&nbsp;</th></tr>\n";
1152 printOpFormIntro ('addBulkPorts');
1153 echo "<tr><td>";
1154 printImageHREF ('add', 'add ports', TRUE);
1155 echo "</td><td><input type=text size=8 name=port_name tabindex=105></td>\n";
1156 echo "<td><input type=text name=port_label tabindex=106></td><td>";
1157 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 107), $prefs['selected']);
1158 echo "<td><input type=text name=port_numbering_start tabindex=108 size=3 maxlength=3></td>\n";
1159 echo "<td><input type=text name=port_numbering_count tabindex=109 size=3 maxlength=3></td>\n";
1160 echo "<td>&nbsp;</td><td>";
1161 printImageHREF ('add', 'add ports', TRUE, 110);
1162 echo "</td></tr></form>";
1163 echo "</table><br>\n";
1164 }
1165
e673ee24 1166 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
0d59a51c 1167 echo "<tr><th>&nbsp;</th><th class=tdleft>Local name</th><th class=tdleft>Visible label</th><th class=tdleft>Interface</th><th class=tdleft>L2 address</th>";
0c7c9f8b 1168 echo "<th class=tdcenter colspan=2>Cable, Remote object and port</th><th class=tdcenter>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
39b4abd0 1169 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
3153a326 1170 printNewItemTR ($prefs);
45ff9012
AA
1171
1172 // clear ports link
1173 echo "<a href='".
1174 makeHrefProcess(array ('op'=>'deleteAll', 'page' => 'object', 'tab' => 'ports', 'object_id' => $object_id)).
1175 "' onclick=\"javascript:return confirm('Are you sure you want to delete all existing ports?')\">" . getImageHREF ('clear', 'Clear port list') . " Clear port list</a>";
1176
00276508
AA
1177 if (isset ($_REQUEST['hl_port_id']))
1178 {
1179 assertUIntArg ('hl_port_id');
1180 $hl_port_id = intval ($_REQUEST['hl_port_id']);
65e557dd 1181 addAutoScrollScript ("port-$hl_port_id");
00276508 1182 }
65e557dd 1183 switchportInfoJS ($object_id); // load JS code to make portnames interactive
9f75e165 1184 foreach ($object['ports'] as $port)
e673ee24 1185 {
00276508 1186 $tr_class = isset ($hl_port_id) && $hl_port_id == $port['id'] ? 'class="port_highlight"' : '';
7056988c 1187 printOpFormIntro ('editPort', array ('port_id' => $port['id']));
10005279 1188 echo "<tr $tr_class><td><a name='port-${port['id']}' href='".makeHrefProcess(array('op'=>'delPort', 'port_id'=>$port['id'], 'object_id'=>$object_id))."'>";
e673ee24
DO
1189 printImageHREF ('delete', 'Unlink and Delete this port');
1190 echo "</a></td>\n";
65e557dd
AA
1191 $a_class = isEthernetPort ($port) ? 'port-menu' : '';
1192 echo "<td class='tdleft' NOWRAP><input type=text name=name class='interactive-portname $a_class' value='${port['name']}' size=8></td>";
cd3775e9 1193 echo "<td><input type=text name=label value='${port['label']}'></td>";
611170af
AD
1194 if (!$port['remote_object_id'])
1195 {
3153a326
DO
1196 echo '<td>';
1197 if ($port['iif_id'] != 1)
1198 echo '<label>' . $port['iif_name'] . ' ';
cd3775e9 1199 printSelect (getExistingPortTypeOptions ($port['id']), array ('name' => 'port_type_id'), $port['oif_id']);
3153a326
DO
1200 if ($port['iif_id'] != 1)
1201 echo '</label>';
1202 echo '</td>';
611170af
AD
1203 }
1204 else
1205 {
045bab87 1206 echo "<input type=hidden name=port_type_id value='${port['oif_id']}'><td class=tdleft>";
e9d357e1 1207 echo formatPortIIFOIF ($port) . '</td>';
611170af 1208 }
cd3775e9
DO
1209 // 18 is enough to fit 6-byte MAC address in its longest form,
1210 // while 24 should be Ok for WWN
1211 echo "<td><input type=text name=l2address value='${port['l2address']}' size=18 maxlength=24></td>\n";
e673ee24
DO
1212 if ($port['remote_object_id'])
1213 {
5c6225b1 1214 echo "<td>${port['cableid']} " .
a2ea559e 1215 formatLoggedSpan ($port['last_log'], formatPortLink ($port['remote_object_id'], $port['remote_object_name'], $port['remote_id'], NULL)) .
5c6225b1
AA
1216 "</td>";
1217 echo "<td> " . formatLoggedSpan ($port['last_log'], $port['remote_name'], 'underline') .
1218 "<input type=hidden name=reservation_comment value=''></td>";
3153a326 1219 echo "<td class=tdcenter><a href='".
4fbb5a00
DY
1220 makeHrefProcess(array(
1221 'op'=>'unlinkPort',
cd3775e9 1222 'port_id'=>$port['id'],
cd3775e9 1223 'object_id'=>$object_id)).
4fbb5a00 1224 "'>";
5ccd99a0 1225 printImageHREF ('cut', 'Unlink this port');
e673ee24
DO
1226 echo "</a></td>";
1227 }
59a83bd8 1228 elseif (strlen ($port['reservation_comment']))
e673ee24 1229 {
5c6225b1 1230 echo "<td>" . formatLoggedSpan ($port['last_log'], 'Reserved:', 'strong underline') . "</td>";
e673ee24 1231 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
3153a326 1232 echo "<td class=tdcenter><a href='".
4fbb5a00
DY
1233 makeHrefProcess(array(
1234 'op'=>'useup',
1235 'port_id'=>$port['id'],
1236 'object_id'=>$object_id)).
1237 "'>";
39be655e 1238 printImageHREF ('clear', 'Use up this port');
e673ee24
DO
1239 echo "</a></td>";
1240 }
1241 else
1242 {
cd3775e9
DO
1243 //echo "<td>&nbsp;</td><td>&nbsp;</td><td class=tdcenter><a href='javascript:;'";
1244 echo "<td>&nbsp;</td><td>&nbsp;</td><td class=tdcenter><span";
1245 $helper_args = array
1246 (
1247 'port' => $port['id'],
cd3775e9
DO
1248 'in_rack' => 'n',
1249 );
1250 $popup_args = 'height=700, width=400, location=no, menubar=no, '.
9e214652 1251 'resizable=yes, scrollbars=yes, status=no, titlebar=no, toolbar=no';
cd3775e9
DO
1252 echo " ondblclick='window.open(\"" . makeHrefForHelper ('portlist', $helper_args);
1253 echo "\",\"findlink\",\"${popup_args}\");'";
1254 // end of onclick=
1255 $helper_args['in_rack'] = 'y';
1256 echo " onclick='window.open(\"" . makeHrefForHelper ('portlist', $helper_args);
1257 echo "\",\"findlink\",\"${popup_args}\");'";
1258 // end of onclick=
1259 echo '>';
1260 // end of <a>
5ccd99a0 1261 printImageHREF ('plug', 'Link this port');
cd3775e9
DO
1262 echo "</span>";
1263 echo " <input type=text name=reservation_comment></td>\n";
e673ee24 1264 }
5bbbeaa2
DO
1265 echo "<td>";
1266 printImageHREF ('save', 'Save changes', TRUE);
1267 echo "</td></form></tr>\n";
e673ee24 1268 }
39b4abd0 1269 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
3153a326 1270 printNewItemTR ($prefs);
e673ee24 1271 echo "</table><br>\n";
a1fc539a
RF
1272 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes' && getConfigVar('ENABLE_BULKPORT_FORM') == 'yes'){
1273 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1274 echo "<tr><th>&nbsp;</th><th class=tdleft>Local name</th><th class=tdleft>Visible label</th><th class=tdleft>Interface</th><th class=tdleft>Start Number</th>";
1275 echo "<th class=tdleft>Count</th><th>&nbsp;</th></tr>\n";
1276 printOpFormIntro ('addBulkPorts');
1277 echo "<tr><td>";
1278 printImageHREF ('add', 'add ports', TRUE);
1279 echo "</td><td><input type=text size=8 name=port_name tabindex=105></td>\n";
1280 echo "<td><input type=text name=port_label tabindex=106></td><td>";
1281 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type_id', 'tabindex' => 107), $prefs['selected']);
1282 echo "<td><input type=text name=port_numbering_start tabindex=108 size=3 maxlength=3></td>\n";
1283 echo "<td><input type=text name=port_numbering_count tabindex=109 size=3 maxlength=3></td>\n";
1284 echo "<td>&nbsp;</td><td>";
1285 printImageHREF ('add', 'add ports', TRUE, 110);
1286 echo "</td></tr></form>";
1287 echo "</table><br>\n";
1288 }
f44fdef9
DO
1289 if (getConfigVar('ENABLE_MULTIPORT_FORM') == 'yes')
1290 finishPortlet();
1291 if (getConfigVar('ENABLE_MULTIPORT_FORM') != 'yes')
1292 return;
e673ee24
DO
1293
1294 startPortlet ('Add/update multiple ports');
7056988c 1295 printOpFormIntro ('addMultiPorts');
f7a3c94a 1296 echo 'Format: <select name=format tabindex=201>';
e673ee24
DO
1297 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
1298 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
e673ee24 1299 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
351d4dbf 1300 echo '<option value=ssv1>SSV:&lt;interface name&gt; &lt;MAC address&gt;</option>';
e673ee24
DO
1301 echo "</select>";
1302 echo 'Default port type: ';
cd3775e9 1303 printNiftySelect (getNewPortTypeOptions(), array ('name' => 'port_type', 'tabindex' => 202), $prefs['selected']);
f7a3c94a
DO
1304 echo "<input type=submit value='Parse output' tabindex=204><br>\n";
1305 echo "<textarea name=input cols=100 rows=50 tabindex=203></textarea><br>\n";
e673ee24
DO
1306 echo '</form>';
1307 finishPortlet();
1308}
1309
f3505b35 1310function renderIPTabForObject ($object_id, $ip_v)
e673ee24 1311{
f3505b35 1312 function getOpnameByIPFamily ($opname, $ip_v)
e673ee24 1313 {
f3505b35
AA
1314 // do not assemble opnames from the peaces to be able to grep the code by opnames
1315 switch ($opname . '-'. $ip_v)
d7a8186d 1316 {
f3505b35
AA
1317 case 'add-4': return 'addIPv4Allocation';
1318 case 'add-6': return 'addIPv6Allocation';
1319 case 'upd-4': return 'updIPv4Allocation';
1320 case 'upd-6': return 'updIPv6Allocation';
1321 case 'del-4': return 'delIPv4Allocation';
1322 case 'del-6': return 'delIPv6Allocation';
1323 default: throw new InvalidArgException ('$opname or $ip_v', "$opname or $ip_v");
d7a8186d 1324 }
e673ee24 1325 }
f3505b35 1326 function printNewItemTR ($ip_v)
21ee3351
AA
1327 {
1328 global $aat;
f3505b35 1329 printOpFormIntro (getOpnameByIPFamily ('add', $ip_v));
21ee3351
AA
1330 echo "<tr><td>";
1331 printImageHREF ('add', 'allocate', TRUE);
1332 echo "</td>";
1333 echo "<td class=tdleft><input type='text' size='10' name='bond_name' tabindex=100></td>\n";
1334 echo "<td class=tdleft><input type=text name='ip' tabindex=101></td>\n";
1335 echo "<td colspan=2>&nbsp;</td><td>";
1336 printSelect ($aat, array ('name' => 'bond_type', 'tabindex' => 102), 'regular');
1337 echo "</td><td>&nbsp;</td><td>";
1338 printImageHREF ('add', 'allocate', TRUE, 103);
1339 echo "</td></tr></form>";
1340 }
1341 $focus = spotEntity ('object', $object_id);
1342 amplifyCell ($focus);
1343 global $aat;
1344 startPortlet ('Allocations');
1345 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1346 echo '<tr><th>&nbsp;</th><th>OS interface</th><th>IP address</th>';
1347 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1348 echo '<th>network</th><th>routed by</th>';
1349 echo '<th>type</th><th>misc</th><th>&nbsp</th></tr>';
1350
1351 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
f3505b35
AA
1352 printNewItemTR ($ip_v);
1353 foreach ($focus['ipv' . $ip_v] as $alloc) // ['ipv4'] or ['ipv6']
21ee3351 1354 {
f3505b35
AA
1355 $rendered_alloc = getRenderedAlloc ($object_id, $alloc);
1356 printOpFormIntro (getOpnameByIPFamily ('upd', $ip_v), array ('ip' => $alloc['addrinfo']['ip']));
1357 echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
1358
1359 echo "<td><a href='" .
1360 makeHrefProcess
1361 (
1362 array
1363 (
1364 'op' => getOpnameByIPFamily ('del', $ip_v),
1365 'ip' => $alloc['addrinfo']['ip'],
1366 'object_id' => $object_id
1367 )
1368 ) . "'>" .
1369 getImageHREF ('delete', 'Delete this IP address') .
1370 "</a></td>";
1371 echo "<td class=tdleft><input type='text' name='bond_name' value='${alloc['osif']}' size=10></td>";
1372 echo $rendered_alloc['td_ip'];
21ee3351
AA
1373 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
1374 {
f3505b35
AA
1375 echo $rendered_alloc['td_network'];
1376 echo $rendered_alloc['td_routed_by'];
21ee3351 1377 }
f3505b35
AA
1378 echo '<td>' . getSelect ($aat, array ('name' => 'bond_type'), $alloc['type']) . "</td>";
1379 echo $rendered_alloc['td_peers'];
1380 echo "<td>" .getImageHREF ('save', 'Save changes', TRUE) . "</td>";
1381
1382 echo "</form></tr>\n";
21ee3351
AA
1383 }
1384 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
f3505b35 1385 printNewItemTR ($ip_v);
21ee3351
AA
1386
1387 echo "</table><br>\n";
1388 finishPortlet();
f3505b35
AA
1389}
1390
1391function renderIPv4ForObject ($object_id)
1392{
1393 renderIPTabForObject ($object_id, '4');
1394}
21ee3351 1395
f3505b35
AA
1396function renderIPv6ForObject ($object_id)
1397{
1398 renderIPTabForObject ($object_id, '6');
21ee3351
AA
1399}
1400
08408472
AA
1401// This function is deprecated. Do not rely on its internals,
1402// it will probably be removed in the next major relese.
1403// Use new showError, showWarning, showSuccess functions.
8ab645cf
AA
1404// Log array is stored in $_SESSION['log']. Its format is simple: plain ordered array
1405// with values having keys 'c' (both message code and severity) and 'a' (sprintf arguments array)
1cb6adf5 1406function showMessageOrError ()
e673ee24 1407{
8ab645cf 1408 if (empty ($_SESSION['log']))
1cb6adf5 1409 return;
8ab645cf
AA
1410 $msginfo = array
1411 (
1412// records 0~99 with success messages
1413 0 => array ('code' => 'success', 'format' => '%s'),
1414 5 => array ('code' => 'success', 'format' => 'added record "%s" successfully'),
1415 6 => array ('code' => 'success', 'format' => 'updated record "%s" successfully'),
1416 7 => array ('code' => 'success', 'format' => 'deleted record "%s" successfully'),
1417 8 => array ('code' => 'success', 'format' => 'Port %s successfully linked with %s'),
1418 10 => array ('code' => 'success', 'format' => 'Added %u ports, updated %u ports, encountered %u errors.'),
1419 21 => array ('code' => 'success', 'format' => 'Generation complete'),
1420 26 => array ('code' => 'success', 'format' => 'updated %u records successfully'),
1421 37 => array ('code' => 'success', 'format' => 'added %u records successfully'),
1422 38 => array ('code' => 'success', 'format' => 'removed %u records successfully'),
1423 41 => array ('code' => 'success', 'format' => 'uplink ports reverb queued'),
1424 43 => array ('code' => 'success', 'format' => 'Saved successfully.'),
1425 44 => array ('code' => 'success', 'format' => '%s failures and %s successfull changes.'),
1426 48 => array ('code' => 'success', 'format' => 'added a record successfully'),
1427 49 => array ('code' => 'success', 'format' => 'deleted a record successfully'),
1428 51 => array ('code' => 'success', 'format' => 'updated a record successfully'),
1429 57 => array ('code' => 'success', 'format' => 'Reset complete'),
1430 62 => array ('code' => 'success', 'format' => 'gw: %s'),
1431 63 => array ('code' => 'success', 'format' => '%u change request(s) have been processed'),
1432 66 => array ('code' => 'success', 'format' => "File sent Ok via handler '%s'"),
1433 67 => array ('code' => 'success', 'format' => "Tag rolling done, %u objects involved"),
1434 71 => array ('code' => 'success', 'format' => 'File "%s" was linked successfully'),
1435 72 => array ('code' => 'success', 'format' => 'File was unlinked successfully'),
1436 81 => array ('code' => 'success', 'format' => "SNMP: completed '%s' work"),
1437 82 => array ('code' => 'success', 'format' => "Bulk port creation was successful. %u ports created, %u failed"),
1438 87 => array ('code' => 'success', 'format' => '802.1Q recalculate: %d ports changed on %d switches'),
8628ae44 1439// records 100~199 with fatal error messages
8ab645cf
AA
1440 100 => array ('code' => 'error', 'format' => '%s'),
1441 109 => array ('code' => 'error', 'format' => 'failed updating a record'),
1442// 123
1443 131 => array ('code' => 'error', 'format' => 'invalid format requested'),
1444 141 => array ('code' => 'error', 'format' => 'Encountered %u errors, updated %u record(s)'),
1445 149 => array ('code' => 'error', 'format' => 'Turing test failed'),
1446 150 => array ('code' => 'error', 'format' => 'Can only change password under DB authentication.'),
1447 151 => array ('code' => 'error', 'format' => 'Old password doesn\'t match.'),
1448 152 => array ('code' => 'error', 'format' => 'New passwords don\'t match.'),
1449 154 => array ('code' => 'error', 'format' => "Verification error: %s"),
1450 155 => array ('code' => 'error', 'format' => 'Save failed.'),
1451 159 => array ('code' => 'error', 'format' => 'Permission denied moving port %s from VLAN%u to VLAN%u'),
1452 161 => array ('code' => 'error', 'format' => 'Endpoint not found. Please either set FQDN attribute or assign an IP address to the object.'),
1453 162 => array ('code' => 'error', 'format' => 'More than one IP address is assigned to this object, please configure FQDN attribute.'),
1454 164 => array ('code' => 'error', 'format' => 'Gateway failure: %s.'),
1455 166 => array ('code' => 'error', 'format' => 'gw: %s'),
1456 170 => array ('code' => 'error', 'format' => 'There is no network for IP address "%s"'),
1457 172 => array ('code' => 'error', 'format' => 'Malformed request'),
1458 179 => array ('code' => 'error', 'format' => 'Expired form has been declined.'),
1459 188 => array ('code' => 'error', 'format' => "Fatal SNMP failure"),
1460 189 => array ('code' => 'error', 'format' => "Unknown OID '%s'"),
1461 191 => array ('code' => 'error', 'format' => "deploy was blocked due to conflicting configuration versions"),
f0ff4930 1462
8628ae44 1463// records 200~299 with warnings
8ab645cf
AA
1464 200 => array ('code' => 'warning', 'format' => '%s'),
1465 201 => array ('code' => 'warning', 'format' => 'nothing happened...'),
1466 202 => array ('code' => 'warning', 'format' => 'gw: %s'),
1467 206 => array ('code' => 'warning', 'format' => 'Rack is not empty'),
57777e4a 1468
24d3182a 1469// records 300~399 with notices
8ab645cf 1470 300 => array ('code' => 'neutral', 'format' => '%s'),
24d3182a 1471
8ab645cf
AA
1472 );
1473 // Handle the arguments. Is there any better way to do it?
1474 foreach ($_SESSION['log'] as $record)
1475 {
1476 if (!isset ($record['c']) or !isset ($msginfo[$record['c']]))
1477 {
1478 echo '<div class=msg_neutral>(this message was lost)</div>';
1479 continue;
1480 }
1481 if (isset ($record['a']))
1482 switch (count ($record['a']))
baf37d01 1483 {
8ab645cf
AA
1484 case 1:
1485 $msgtext = sprintf
1486 (
1487 $msginfo[$record['c']]['format'],
1488 $record['a'][0]
1489 );
1490 break;
1491 case 2:
1492 $msgtext = sprintf
1493 (
1494 $msginfo[$record['c']]['format'],
1495 $record['a'][0],
1496 $record['a'][1]
1497 );
1498 break;
1499 case 3:
1500 $msgtext = sprintf
1501 (
1502 $msginfo[$record['c']]['format'],
1503 $record['a'][0],
1504 $record['a'][1],
1505 $record['a'][2]
1506 );
1507 break;
1508 case 4:
1509 default:
1510 $msgtext = sprintf
1511 (
1512 $msginfo[$record['c']]['format'],
1513 $record['a'][0],
1514 $record['a'][1],
1515 $record['a'][2],
1516 $record['a'][3]
1517 );
1518 break;
baf37d01 1519 }
8ab645cf
AA
1520 else
1521 $msgtext = $msginfo[$record['c']]['format'];
1522 echo '<div class=msg_' . $msginfo[$record['c']]['code'] . ">${msgtext}</div>";
baf37d01 1523 }
8ab645cf 1524 unset ($_SESSION['log']);
e673ee24
DO
1525}
1526
65e557dd
AA
1527// renders two tables: port link status and learned MAC list
1528function renderPortsInfo($object_id)
1529{
1530 global $nextorder;
1531 echo "<table width='100%'><tr>";
1532
1533 if (permitted (NULL, NULL, 'get_link_status'))
1534 {
1535 try
1536 {
1537 $linkStatus = gwRetrieveDeviceConfig ($object_id, 'getportstatus');
1538 }
1539 catch (RackTablesError $e) {}
1540 if (! empty ($linkStatus))
1541 {
1542 echo "<td valign='top' width='50%'>";
1543 startPortlet('Link status');
1544 echo "<table width='80%' class='widetable' cellspacing=0 cellpadding='5px' align='center'><tr><th>Port<th>Link status<th>Link info</tr>";
1545 $order = 'even';
1546 foreach ($linkStatus as $pn => $link)
1547 {
1548 echo "<tr class='row_$order'>";
1549 $order = $nextorder[$order];
1550 echo '<td>' . $pn;
1551 echo '<td>' . $link['status'];
1552 $info = '';
1553 if (isset ($link['speed']))
1554 $info .= $link['speed'];
1555 if (isset ($link['duplex']))
1556 {
1557 if (! empty ($info))
1558 $info .= ', ';
1559 $info .= $link['duplex'];
1560 }
1561 echo '<td>' . $info;
1562 echo '</tr>';
1563 }
1564 echo "</table></td>";
1565 finishPortlet();
1566 }
1567 }
1568
1569 try
1570 {
1571 $macList = sortPortList (gwRetrieveDeviceConfig ($object_id, 'getmaclist'));
1572 }
1573 catch (RackTablesError $e) {}
1574 if (! empty ($macList))
1575 {
1576 echo "<td valign='top' width='50%'>";
1577 $rendered_macs = '';
1578 $mac_count = 0;
1579 $rendered_macs .= "<table width='80%' class='widetable' cellspacing=0 cellpadding='5px' align='center'><tr><th>MAC<th>Vlan<th>Port</tr>";
1580 $order = 'even';
1581 foreach ($macList as $pn => $list)
1582 {
1583 $order = $nextorder[$order];
1584 foreach ($list as $item)
1585 {
1586 ++$mac_count;
1587 $rendered_macs .= "<tr class='row_$order'>";
1588 $rendered_macs .= '<td style="font-family: monospace">' . $item['mac'];
1589 $rendered_macs .= '<td>' . $item['vid'];
1590 $rendered_macs .= '<td>' . $pn;
1591 $rendered_macs .= '</tr>';
1592 }
1593 }
1594 $rendered_macs .= "</table></td>";
1595
1596 startPortlet("Learned MACs ($mac_count)");
1597 echo $rendered_macs;
1598 finishPortlet();
1599 }
1600
1601 echo "</td></tr></table>";
1602}
1603
e673ee24 1604/*
51c18782 1605The following conditions must be met:
e673ee24
DO
16061. We can mount onto free atoms only. This means: if any record for an atom
1607already exists in RackSpace, it can't be used for mounting.
16082. We can't unmount from 'W' atoms. Operator should review appropriate comments
1609and either delete them before unmounting or refuse to unmount the object.
1610*/
7e1db771 1611function renderRackSpaceForObject ($object_id)
e673ee24 1612{
e673ee24
DO
1613 // Always process occupied racks plus racks chosen by user. First get racks with
1614 // already allocated rackspace...
51c18782 1615 $workingRacksData = getResidentRacksData ($object_id);
e673ee24 1616 // ...and then add those chosen by user (if any).
2135fd83 1617 if (isset($_REQUEST['rackmulti']))
e673ee24 1618 foreach ($_REQUEST['rackmulti'] as $cand_id)
e673ee24
DO
1619 if (!isset ($workingRacksData[$cand_id]))
1620 {
0cc24e9a 1621 $rackData = spotEntity ('rack', $cand_id);
61a1d996 1622 amplifyCell ($rackData);
e673ee24
DO
1623 $workingRacksData[$cand_id] = $rackData;
1624 }
51690ad4 1625
e673ee24
DO
1626 // Main layout starts.
1627 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1628
1629 // Left portlet with rack list.
1630 echo "<td class=pcleft height='1%'>";
1631 startPortlet ('Racks');
a8efc03e 1632 $allRacksData = listCells ('rack');
6d42599c
AA
1633
1634 // filter rack list to match only racks having common tags with the object (reducing $allRacksData)
1635 if (! isset ($_REQUEST['show_all_racks']) and getConfigVar ('FILTER_RACKLIST_BY_TAGS') == 'yes')
1636 {
1637 $matching_racks = array();
1638 $object = spotEntity ('object', $object_id);
1639 $matched_tags = array();
1640 foreach ($allRacksData as $rack)
1641 foreach ($object['etags'] as $tag)
1642 if (tagOnChain ($tag, $rack['etags']) or tagOnChain ($tag, $rack['itags']))
1643 {
1644 $matching_racks[$rack['id']] = $rack;
1645 $matched_tags[$tag['id']] = $tag;
1646 break;
1647 }
1648 // add current object's racks even if they dont match filter
1649 foreach ($workingRacksData as $rack_id => $rack)
1650 if (! isset ($matching_racks[$rack_id]))
1651 $matching_racks[$rack_id] = $rack;
1652 // if matching racks found, and rack list is reduced, show 'show all' link
1653 if (count ($matching_racks) and count ($matching_racks) != count ($allRacksData))
1654 {
1655 $filter_text = '';
1656 foreach ($matched_tags as $tag)
1657 $filter_text .= (empty ($filter_text) ? '' : ' or ') . '{' . $tag['tag'] . '}';
1658 $href_show_all = trim($_SERVER['REQUEST_URI'], '&');
1659 $href_show_all .= htmlspecialchars('&show_all_racks=1');
1660 echo "(filtered by <span class='filter-text'>$filter_text</span>, <a href='$href_show_all'>show all</a>)<p>";
1661 $allRacksData = $matching_racks;
1662 }
1663 }
1664
4b8d413e 1665 if (count ($allRacksData) <= getConfigVar ('RACK_PRESELECT_THRESHOLD'))
61a1d996 1666 foreach ($allRacksData as $rack)
51c18782
DO
1667 if (!array_key_exists ($rack['id'], $workingRacksData))
1668 {
1669 amplifyCell ($rack);
1670 $workingRacksData[$rack['id']] = $rack;
1671 }
1672 foreach (array_keys ($workingRacksData) as $rackId)
1673 applyObjectMountMask ($workingRacksData[$rackId], $object_id);
1674 printOpFormIntro ('updateObjectAllocation');
4b8d413e 1675 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
51c18782 1676 echo "<br><br>";
e673ee24
DO
1677 finishPortlet();
1678 echo "</td>";
1679
1680 // Middle portlet with comment and submit.
1681 echo "<td class=pcleft>";
1682 startPortlet ('Comment');
1683 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1684 echo "<input type=submit value='Save' name=got_atoms>\n";
51c18782 1685 echo "<br><br>";
e673ee24
DO
1686 finishPortlet();
1687 echo "</td>";
1688
1689 // Right portlet with rendered racks. If this form submit is not final, we have to
1690 // reflect the former state of the grid in current form.
1691 echo "<td class=pcright rowspan=2 height='1%'>";
1692 startPortlet ('Working copy');
65e557dd 1693 addJS ('js/racktables.js');
e673ee24
DO
1694 echo '<table border=0 cellspacing=10 align=center><tr>';
1695 foreach ($workingRacksData as $rack_id => $rackData)
1696 {
1697 // Order is important here: only original allocation is highlighted.
1698 highlightObject ($rackData, $object_id);
1699 markupAtomGrid ($rackData, 'T');
1700 // If we have a form processed, discard user input and show new database
1701 // contents.
51c18782 1702 if (isset ($_REQUEST['rackmulti'][0])) // is an update
e673ee24
DO
1703 mergeGridFormToRack ($rackData);
1704 echo "<td valign=top>";
1705 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1706 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
57c69e9c 1707 echo "<tr><th width='10%'>&nbsp;</th>";
64259015
DO
1708 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1709 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1710 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24 1711 renderAtomGrid ($rackData);
57c69e9c 1712 echo "<tr><th width='10%'>&nbsp;</th>";
64259015
DO
1713 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '0', ${rackData['height']})\">Front</a></th>";
1714 echo "<th width='50%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '1', ${rackData['height']})\">Interior</a></th>";
1715 echo "<th width='20%'><a href='javascript:;' oncontextmenu=\"blockToggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']}); return false;\" onclick=\"toggleColumnOfAtoms('${rack_id}', '2', ${rackData['height']})\">Back</a></th></tr>\n";
e673ee24
DO
1716 echo "</table></center>\n";
1717 echo '</td>';
1718 }
1719 echo "</tr></table>";
1720 finishPortlet();
1721 echo "</td>\n";
1722
1723 echo "</form>\n";
1724 echo "</tr></table>\n";
1725}
1726
1727function renderMolecule ($mdata, $object_id)
1728{
1729 // sort data out
1730 $rackpack = array();
1731 global $loclist;
64b95774 1732 foreach ($mdata as $rua)
e673ee24
DO
1733 {
1734 $rack_id = $rua['rack_id'];
1735 $unit_no = $rua['unit_no'];
1736 $atom = $rua['atom'];
1737 if (!isset ($rackpack[$rack_id]))
1738 {
61a1d996
DO
1739 $rackData = spotEntity ('rack', $rack_id);
1740 amplifyCell ($rackData);
e673ee24
DO
1741 for ($i = $rackData['height']; $i > 0; $i--)
1742 for ($locidx = 0; $locidx < 3; $locidx++)
1743 $rackData[$i][$locidx]['state'] = 'F';
1744 $rackpack[$rack_id] = $rackData;
1745 }
1746 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1747 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1748 }
1749 // now we have some racks to render
65e557dd 1750 addAtomCSS();
64b95774 1751 foreach ($rackpack as $rackData)
e673ee24
DO
1752 {
1753 markAllSpans ($rackData);
1754 echo "<table class=molecule cellspacing=0>\n";
1755 echo "<caption>${rackData['name']}</caption>\n";
1756 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1757 for ($i = $rackData['height']; $i > 0; $i--)
1758 {
1759 echo "<tr><th>$i</th>";
1760 for ($locidx = 0; $locidx < 3; $locidx++)
1761 {
1762 $state = $rackData[$i][$locidx]['state'];
65e557dd 1763 echo "<td class='atom state_${state}'>&nbsp;</td>\n";
e673ee24
DO
1764 }
1765 echo "</tr>\n";
1766 }
1767 echo "</table>\n";
1768 }
1769}
1770
23cdc7e9 1771function renderDepot ()
e673ee24 1772{
23cdc7e9 1773 global $pageno, $nextorder;
23cdc7e9
DO
1774 $cellfilter = getCellFilter();
1775 $objects = filterCellList (listCells ('object'), $cellfilter['expression']);
1776
1777 echo "<table border=0 class=objectview>\n";
1778 echo "<tr><td class=pcleft>";
1779
1ebbf889 1780 if (! renderEmptyResults ($cellfilter, 'objects', count($objects)))
e673ee24 1781 {
4899096d 1782 if (count($objects) > 0)
1ebbf889 1783 {
4899096d
AD
1784 startPortlet ('Objects (' . count ($objects) . ')');
1785 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
81659c05 1786 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Row/Rack</th></tr>';
4899096d
AD
1787 $order = 'odd';
1788 foreach ($objects as $obj)
1789 {
1790 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $obj['id'])
1791 $secondclass = 'tdleft port_highlight';
1792 else
1793 $secondclass = 'tdleft';
1794 echo "<tr class=row_${order} valign=top><td class='${secondclass}'><a href='".makeHref(array('page'=>'object', 'object_id'=>$obj['id']))."'><strong>${obj['dname']}</strong></a>";
1795 if (count ($obj['etags']))
1796 echo '<br><small>' . serializeTags ($obj['etags'], makeHref(array('page'=>$pageno, 'tab'=>'default')) . '&') . '</small>';
1797 echo "</td><td class='${secondclass}'>${obj['label']}</td>";
1798 echo "<td class='${secondclass}'>${obj['asset_no']}</td>";
4899096d
AD
1799 if ($obj['rack_id'])
1800 echo "<td class='${secondclass}'><a href='".makeHref(array('page'=>'row', 'row_id'=>$obj['row_id']))."'>${obj['Row_name']}</a>/<a href='".makeHref(array('page'=>'rack', 'rack_id'=>$obj['rack_id']))."'>${obj['Rack_name']}</a></td>";
1801 else
1802 echo "<td class='${secondclass}'>Unmounted</td>";
1803 echo '</tr>';
1804 $order = $nextorder[$order];
1805 }
1806 echo '</table>';
1807 finishPortlet();
1ebbf889 1808 }
4899096d
AD
1809 else
1810 echo '<h2>No objects exist</h2>';
e673ee24 1811 }
23cdc7e9
DO
1812
1813 echo "</td><td class=pcright width='25%'>";
1814
95857b5c 1815 renderCellFilterPortlet ($cellfilter, 'object', $objects);
23cdc7e9 1816 echo "</td></tr></table>\n";
e673ee24
DO
1817}
1818
1ebbf889
AA
1819// This function returns TRUE if the result set is too big to be rendered, and no filter is set.
1820// In this case it renders the describing message instead.
1821function renderEmptyResults($cellfilter, $entities_name, $count = NULL)
1822{
1823 if (!$cellfilter['is_empty'])
1824 return FALSE;
1825 if (isset ($_REQUEST['show_all_objects']))
1826 return FALSE;
1827 $max = intval(getConfigVar('MAX_UNFILTERED_ENTITIES'));
1828 if (0 == $max || $count <= $max)
1829 return FALSE;
1830
1831 $href_show_all = trim($_SERVER['REQUEST_URI'], '&');
1832 $href_show_all .= htmlspecialchars('&show_all_objects=1');
1833 $suffix = isset ($count) ? " ($count)" : '';
1834 echo <<<END
1835<p>Please set a filter to display the corresponging $entities_name.
1836<br><a href="$href_show_all">Show all $entities_name$suffix</a>
1837END;
1838 return TRUE;
1839}
1840
e673ee24
DO
1841// History viewer for history-enabled simple dictionaries.
1842function renderHistory ($object_type, $object_id)
1843{
1844 switch ($object_type)
1845 {
1846 case 'row':
a5c589d2 1847 $query = "select ctime, user_name, name, comment from RackRowHistory where id = ? order by ctime";
aa9a0fb4
DO
1848 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>rack row comment</th></tr>';
1849 $extra = 3;
e673ee24
DO
1850 break;
1851 case 'rack':
1852 $query =
aa9a0fb4 1853 "select ctime, user_name, rh.name, rr.name as name, rh.height, rh.comment " .
51690ad4 1854 "from RackHistory as rh left join RackRow as rr on rh.row_id = rr.id " .
a5c589d2 1855 "where rh.id = ? order by ctime";
aa9a0fb4
DO
1856 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1857 $extra = 5;
e673ee24
DO
1858 break;
1859 case 'object':
1860 $query =
81659c05 1861 "select ctime, user_name, RackObjectHistory.name as name, label, asset_no, has_problems, dict_value, comment " .
00f6f1e4 1862 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key join Chapter on Dictionary.chapter_id = Chapter.id " .
a5c589d2 1863 "where Chapter.name = 'RackObjectType' and RackObjectHistory.id=? order by ctime";
81659c05 1864 $header = '<tr><th>change time</th><th>author</th><th>common name</th><th>visible label</th><th>asset no</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
6d513f04 1865 $extra = 7;
e673ee24
DO
1866 break;
1867 default:
3a089a44 1868 throw new InvalidArgException ('object_type', $object_type);
e673ee24 1869 }
a5c589d2 1870 $result = usePreparedSelectBlade ($query, array ($object_id));
e673ee24
DO
1871 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1872 $order = 'odd';
1873 global $nextorder;
1874 echo $header;
1875 while ($row = $result->fetch (PDO::FETCH_NUM))
1876 {
1877 echo "<tr class=row_${order}><td>${row[0]}</td>";
1878 for ($i = 1; $i <= $extra; $i++)
1879 echo "<td>" . $row[$i] . "</td>";
1880 echo "</tr>\n";
1881 $order = $nextorder[$order];
1882 }
1883 echo "</table><br>\n";
1884}
1885
1886function renderRackspaceHistory ()
1887{
4fbb5a00 1888 global $nextorder, $pageno, $tabno;
e673ee24
DO
1889 $order = 'odd';
1890 $history = getRackspaceHistory();
1891 // Show the last operation by default.
1892 if (isset ($_REQUEST['op_id']))
1893 $op_id = $_REQUEST['op_id'];
1894 elseif (isset ($history[0]['mo_id']))
1895 $op_id = $history[0]['mo_id'];
1896 else $op_id = NULL;
1897
1898 $omid = NULL;
1899 $nmid = NULL;
1900 $object_id = 1;
1901 if ($op_id)
1902 list ($omid, $nmid) = getOperationMolecules ($op_id);
1903
1904 // Main layout starts.
1905 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1906
1907 // Left top portlet with old allocation.
1908 echo "<tr><td class=pcleft>";
1909 startPortlet ('Old allocation');
1910 if ($omid)
1911 {
1912 $oldMolecule = getMolecule ($omid);
1913 renderMolecule ($oldMolecule, $object_id);
1914 }
1915 else
1916 echo "nothing";
1917 finishPortlet();
1918
1919 echo '</td><td class=pcright>';
1920
1921 // Right top portlet with new allocation
1922 startPortlet ('New allocation');
1923 if ($nmid)
1924 {
1925 $newMolecule = getMolecule ($nmid);
1926 renderMolecule ($newMolecule, $object_id);
1927 }
1928 else
1929 echo "nothing";
1930 finishPortlet();
737a3f72 1931
e673ee24 1932 echo '</td></tr><tr><td colspan=2>';
737a3f72 1933
e673ee24
DO
1934 // Bottom portlet with list
1935
1936 startPortlet ('Rackspace allocation history');
1937 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
7fa7047a 1938 echo "<tr><th>timestamp</th><th>author</th><th>object</th><th>comment</th></tr>\n";
e673ee24
DO
1939 foreach ($history as $row)
1940 {
1941 if ($row['mo_id'] == $op_id)
1942 $class = 'hl';
1943 else
1944 $class = "row_${order}";
4fbb5a00 1945 echo "<tr class=${class}><td><a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'op_id'=>$row['mo_id']))."'>${row['ctime']}</a></td>";
7fa7047a
DO
1946 echo "<td>${row['user_name']}</td><td>";
1947 renderCell (spotEntity ('object', $row['ro_id']));
9c6222ef 1948 echo '</td><td>' . niftyString ($row['comment'], 0) . '</td></tr>';
e673ee24
DO
1949 $order = $nextorder[$order];
1950 }
1951 echo "</table>\n";
1952 finishPortlet();
737a3f72 1953
e673ee24 1954 echo '</td></tr></table>';
e673ee24
DO
1955}
1956
1f54e1ba 1957function renderIPv4SpaceRecords ($tree, $baseurl, $target = 0, $knight, $level = 1)
d65353ad
DO
1958{
1959 $self = __FUNCTION__;
ca4eb604
DO
1960 static $vdomlist = NULL;
1961 if ($vdomlist == NULL and getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
e829e76b 1962 $vdomlist = getVLANDomainOptions();
00276508
AA
1963
1964 // scroll page to the highlighted item
1965 if ($target && isset ($_REQUEST['hl_net']))
65e557dd 1966 addAutoScrollScript ("net-$target");
00276508 1967
d65353ad
DO
1968 foreach ($tree as $item)
1969 {
64347dcf 1970 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
64347dcf 1971 loadIPv4AddrList ($item); // necessary to compute router list and address counter
64347dcf
DO
1972 else
1973 {
1974 $item['addrlist'] = array();
1975 $item['addrc'] = 0;
1976 }
b1e39212
DO
1977 $used = $item['addrc'];
1978 $maxdirect = $item['addrt'];
1979 $maxtotal = binInvMaskFromDec ($item['mask']) + 1;
0137d53c
DO
1980 if (isset ($item['id']))
1981 {
1f54e1ba 1982 $decor = array ('indent' => $level);
fec0c8da 1983 if ($item['symbol'] == 'node-collapsed')
00276508 1984 $decor['symbolurl'] = "${baseurl}&eid=" . $item['id'];
fec0c8da 1985 elseif ($item['symbol'] == 'node-expanded')
00276508 1986 $decor['symbolurl'] = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}" : '');
0137d53c 1987 echo "<tr valign=top>";
21ee3351 1988 if ($target == $item['id'] && isset ($_REQUEST['hl_net']))
ee8688c4 1989 $decor['tdclass'] = 'port_highlight';
21ee3351 1990 printIPNetInfoTDs ($item, $decor);
0137d53c 1991 echo "<td class=tdcenter>";
64347dcf
DO
1992 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
1993 {
b1e39212
DO
1994 renderProgressBar ($maxdirect ? $used/$maxdirect : 0);
1995 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ? '' : "/${maxtotal}") . '</small>';
64347dcf
DO
1996 }
1997 else
b1e39212 1998 echo "<small>${maxdirect}</small>";
64347dcf 1999 echo "</td>";
ca4eb604
DO
2000 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2001 {
a5f9d1ca
DO
2002 echo '<td class=tdleft>';
2003 if (count ($item['8021q']))
ca4eb604 2004 {
a5f9d1ca
DO
2005 echo '<ul>';
2006 foreach ($item['8021q'] as $binding)
2007 {
2008 echo '<li><a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $binding['domain_id'] . '-' . $binding['vlan_id'])) . '">';
e829e76b
DO
2009 // FIXME: would formatVLANName() do this?
2010 echo $binding['vlan_id'] . '@' . niftyString ($vdomlist[$binding['domain_id']], 15) . '</a></li>';
a5f9d1ca
DO
2011 }
2012 echo '</ul>';
ca4eb604
DO
2013 }
2014 echo '</td>';
2015 }
0137d53c 2016 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
4a47d34b 2017 printRoutersTD (findRouters ($item['addrlist']), getConfigVar ('IPV4_TREE_RTR_AS_CELL'));
0137d53c 2018 echo "</tr>";
fec0c8da 2019 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
1f54e1ba 2020 $self ($item['kids'], $baseurl, $target, $knight, $level + 1);
0137d53c
DO
2021 }
2022 else
2023 {
0137d53c 2024 echo "<tr valign=top>";
21ee3351 2025 printIPNetInfoTDs ($item, array ('indent' => $level, 'knight' => $knight, 'tdclass' => 'sparenetwork'));
0137d53c 2026 echo "<td class=tdcenter>";
64347dcf
DO
2027 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2028 {
b1e39212
DO
2029 renderProgressBar ($used/$maxtotal, 'sparenetwork');
2030 echo "<br><small>${used}/${maxtotal}</small>";
64347dcf
DO
2031 }
2032 else
b1e39212 2033 echo "<small>${maxtotal}</small>";
ee3eac34
DO
2034 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2035 echo '</td><td>&nbsp;</td>';
64347dcf 2036 echo "</td><td>&nbsp;</td></tr>";
0137d53c 2037 }
d65353ad
DO
2038 }
2039}
2040
21ee3351
AA
2041function renderIPv6SpaceRecords ($tree, $baseurl, $target = 0, $knight, $level = 1)
2042{
2043 $self = __FUNCTION__;
2044 static $vdomlist = NULL;
2045 if ($vdomlist == NULL and getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2046 $vdomlist = getVLANDomainOptions();
00276508
AA
2047
2048 // scroll page to the highlighted item
2049 if ($target && isset ($_REQUEST['hl_net']))
65e557dd 2050 addAutoScrollScript ("net-$target");
00276508 2051
21ee3351
AA
2052 foreach ($tree as $item)
2053 {
2054 if (getConfigVar ('IPV4_TREE_SHOW_USAGE') == 'yes')
2055 loadIPv6AddrList ($item); // necessary to compute router list and address counter
2056 else
2057 {
2058 $item['addrlist'] = array();
2059 $item['addrc'] = 0;
2060 }
2061 if (isset ($item['id']))
2062 {
2063 $decor = array ('indent' => $level);
2064 if ($item['symbol'] == 'node-collapsed')
00276508 2065 $decor['symbolurl'] = "${baseurl}&eid=" . $item['id'];
21ee3351
AA
2066 elseif ($item['symbol'] == 'node-expanded')
2067 $decor['symbolurl'] = $baseurl . ($item['parent_id'] ? "&eid=${item['parent_id']}#net6id${item['parent_id']}" : '');
2068 echo "<tr valign=top>";
2069 if ($target == $item['id'] && isset ($_REQUEST['hl_net']))
2070 $decor['tdclass'] .= ' port_highlight';
2071 printIPNetInfoTDs ($item, $decor);
2072 echo "<td class=tdcenter>";
21ee3351
AA
2073 // show net usage
2074 echo formatIPv6NetUsage ($item['addrc'], $item['mask']);
2075 echo "</td>";
2076 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2077 {
2078 echo '<td class=tdleft>';
2079 if (count ($item['8021q']))
2080 {
2081 echo '<ul>';
2082 foreach ($item['8021q'] as $binding)
2083 {
2084 echo '<li><a href="' . makeHref (array ('page' => 'vlan', 'vlan_ck' => $binding['domain_id'] . '-' . $binding['vlan_id'])) . '">';
2085 // FIXME: would formatVLANName() do this?
2086 echo $binding['vlan_id'] . '@' . niftyString ($vdomlist[$binding['domain_id']], 15) . '</a></li>';
2087 }
2088 echo '</ul>';
2089 }
2090 echo '</td>';
2091 }
2092 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2093 printRoutersTD (findRouters ($item['addrlist']), getConfigVar ('IPV4_TREE_RTR_AS_CELL'));
2094 echo "</tr>";
2095 if ($item['symbol'] == 'node-expanded' or $item['symbol'] == 'node-expanded-static')
2096 $self ($item['kids'], $baseurl, $target, $knight, $level + 1);
2097 }
2098 /* do not display spare networks
2099 else
2100 { // display spare networks
2101 echo "<tr valign=top>";
2102 printIPNetInfoTDs ($item, array ('indent' => $level, 'knight' => $knight, 'tdclass' => 'sparenetwork'));
2103 echo "<td class=tdcenter>";
2104 echo formatIPv6NetUsage ($item['addrc'], $item['mask']);
2105 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2106 echo '</td><td>&nbsp;</td>';
2107 echo "</td><td>&nbsp;</td></tr>";
2108 }*/
2109 }
2110}
2111
2112// if $used is NULL, returns only human-formatted mask.
2113// Otherwise returns "$used in/of " . human-formatted-mask
2114function formatIPv6NetUsage ($used, $mask)
2115{
2116 $prefixes = array
2117 (
2118 0 => '',
2119 3 => 'k',
2120 6 => 'M',
2121 9 => 'G',
2122 12 => 'T',
2123 15 => 'P',
2124 18 => 'E',
2125 21 => 'Z',
2126 24 => 'Y',
2127 );
2128
2129 if ($mask <= 64)
2130 {
2131 $what = '/64 net';
2132 $preposition = 'in';
2133 $mask += 64;
2134 }
2135 else
2136 {
2137 $what = 'IP';
2138 $preposition = 'of';
2139 }
2140 $what .= (0 == $mask % 64 ? '' : 's');
2141 $addrc = isset ($used) ? "$used $preposition " : '';
2142
2143 $dec_order = intval ((128 - $mask) / 10) * 3;
2144 $mult = isset ($prefixes[$dec_order]) ? $prefixes[$dec_order] : '??';
2145
2146 $cnt = 1 << ((128 - $mask) % 10);
2147 if ($cnt == 1 && $mult == '')
2148 $cnt = 'single';
2149
2150 return "<small>${addrc}${cnt}${mult} ${what}</small>";
2151}
2152
04d619d0 2153function renderIPv4Space ()
e673ee24 2154{
4fbb5a00 2155 global $pageno, $tabno;
31c941ec 2156 $cellfilter = getCellFilter();
1f54e1ba
DO
2157 $netlist = listCells ('ipv4net');
2158 $allcount = count ($netlist);
2159 $netlist = filterCellList ($netlist, $cellfilter['expression']);
573214e0 2160 array_walk ($netlist, 'amplifyCell');
4fbb5a00 2161
94a40058 2162 $netcount = count ($netlist);
5388794d
DO
2163 // expand request can take either natural values or "ALL". Zero means no expanding.
2164 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2165 $tree = prepareIPv4Tree ($netlist, $eid);
3630d1fb
DO
2166
2167 echo "<table border=0 class=objectview>\n";
2168 echo "<tr><td class=pcleft>";
1ebbf889
AA
2169 if (! renderEmptyResults($cellfilter, 'IPv4 nets', count($tree)))
2170 {
2171 startPortlet ("networks (${netcount})");
2172 echo '<h4>';
2173 if ($eid === 0)
2174 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2175 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2176 $cellfilter['urlextra'] . "'>expand all</a>)";
2177 elseif ($eid === 'ALL')
2178 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2179 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2180 else
2181 {
2182 $netinfo = spotEntity ('ipv4net', $eid);
2183 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='" .
2184 makeHref (array ('page' => $pageno, 'tab' => $tabno)) .
2185 $cellfilter['urlextra'] . "'>auto-collapse</a> / <a href='" .
2186 makeHref (array ('page' => $pageno, 'tab' => $tabno, 'eid' => 'ALL')) .
2187 $cellfilter['urlextra'] . "'>expand&nbsp;all</a>)";
2188 }
2189 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2190 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2191 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2192 echo '<th>VLAN</th>';
2193 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2194 echo "<th>routed by</th>";
2195 echo "</tr>\n";
2196 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2197 renderIPv4SpaceRecords ($tree, $baseurl, $eid, $netcount == $allcount and getConfigVar ('IPV4_ENABLE_KNIGHT') == 'yes');
2198 echo "</table>\n";
2199 finishPortlet();
5388794d 2200 }
1ebbf889 2201
74ccacff 2202 echo '</td><td class=pcright>';
95857b5c 2203 renderCellFilterPortlet ($cellfilter, 'ipv4net', $netlist);
74ccacff 2204 echo "</td></tr></table>\n";
f973f491 2205}
a7fe7729 2206
21ee3351
AA
2207function renderIPv6Space ()
2208{
2209 global $pageno, $tabno;
2210 $cellfilter = getCellFilter();
2211 $netlist = listCells ('ipv6net');
2212 $allcount = count ($netlist);
2213 $netlist = filterCellList ($netlist, $cellfilter['expression']);
2214 array_walk ($netlist, 'amplifyCell');
2215
2216 $netcount = count ($netlist);
2217 // expand request can take either natural values or "ALL". Zero means no expanding.
2218 $eid = isset ($_REQUEST['eid']) ? $_REQUEST['eid'] : 0;
2219 $tree = prepareIPv6Tree ($netlist, $eid);
2220
2221 echo "<table border=0 class=objectview>\n";
2222 echo "<tr><td class=pcleft>";
2223 if (! renderEmptyResults($cellfilter, 'IPv6 nets', count($tree)))
2224 {
2225 startPortlet ("networks (${netcount})");
2226 echo '<h4>';
2227 if ($eid === 0)
2228 echo 'auto-collapsing at threshold ' . getConfigVar ('TREE_THRESHOLD') .
2229 " (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno, 'eid'=>'ALL')) .
2230 $cellfilter['urlextra'] . "'>expand all</a>)";
2231 elseif ($eid === 'ALL')
2232 echo "expanding all (<a href='".makeHref(array('page'=>$pageno, 'tab'=>$tabno)) .
2233 $cellfilter['urlextra'] . "'>auto-collapse</a>)";
2234 else
2235 {
2236 $netinfo = spotEntity ('ipv6net', $eid);
2237 echo "expanding ${netinfo['ip']}/${netinfo['mask']} (<a href='" .
2238 makeHref (array ('page' => $pageno, 'tab' => $tabno)) .
2239 $cellfilter['urlextra'] . "'>auto-collapse</a> / <a href='" .
2240 makeHref (array ('page' => $pageno, 'tab' => $tabno, 'eid' => 'ALL')) .
2241 $cellfilter['urlextra'] . "'>expand&nbsp;all</a>)";
2242 }
2243 echo "</h4><table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2244 echo "<tr><th>prefix</th><th>name/tags</th><th>capacity</th>";
2245 if (getConfigVar ('IPV4_TREE_SHOW_VLAN') == 'yes')
2246 echo '<th>VLAN</th>';
2247 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2248 echo "<th>routed by</th>";
2249 echo "</tr>\n";
2250 $baseurl = makeHref(array('page'=>$pageno, 'tab'=>$tabno)) . $cellfilter['urlextra'];
2251 renderIPv6SpaceRecords ($tree, $baseurl, $eid, $netcount == $allcount and getConfigVar ('IPV4_ENABLE_KNIGHT') == 'yes');
2252 echo "</table>\n";
2253 finishPortlet();
2254 }
2255
2256 echo '</td><td class=pcright>';
2257 renderCellFilterPortlet ($cellfilter, 'ipv6net', $netlist);
2258 echo "</td></tr></table>\n";
2259}
2260
1f54e1ba
DO
2261function renderSLBDefConfig()
2262{
2263 $defaults = getSLBDefaults ();
2264 startPortlet ('SLB default configs');
2265 echo '<table cellspacing=0 cellpadding=5 align=center>';
2266 printOpFormIntro ('save');
2267 echo '<tr><th class=tdright>VS config</th><td colspan=2><textarea tabindex=103 name=vsconfig rows=10 cols=80>' . htmlspecialchars($defaults['vs']) . '</textarea></td>';
2268 echo '<td rowspan=2>';
2269 printImageHREF ('SAVE', 'Save changes', TRUE);
2270 echo '</td></tr>';
2271 echo '<tr><th class=tdright>RS config</th><td colspan=2><textarea tabindex=104 name=rsconfig rows=10 cols=80>' . htmlspecialchars($defaults['rs']) . '</textarea></td></tr>';
2272 echo '</form></table>';
2273 finishPortlet();
2274}
2275
f973f491
DO
2276function renderIPv4SLB ()
2277{
4fbb5a00 2278 global $page, $nextorder;
a7fe7729 2279
6fec9f39 2280 startPortlet ('SLB configuration');
b3c50e6c 2281 echo "<table border=0 width='100%'><tr>";
ee437dab 2282 foreach (array ('ipv4vslist', 'ipv4rsplist', 'rservers', 'lbs') as $pno)
4fbb5a00 2283 echo "<td><h3><a href='".makeHref(array('page'=>$pno))."'>" . $page[$pno]['title'] . "</a></h3></td>";
b3c50e6c
DO
2284 echo '</tr></table>';
2285 finishPortlet();
2286
c3bdc503 2287 $summary = getSLBSummary();
6fec9f39 2288 startPortlet ('SLB tactical overview');
4cadac8f
DO
2289 // A single id-keyed array isn't used here to preserve existing
2290 // order of LBs returned by getSLBSummary()
c3bdc503
DO
2291 $lblist = array();
2292 $lbdname = array();
4cadac8f 2293 foreach ($summary as $vipdata)
da04825a 2294 foreach (array_keys ($vipdata['lblist']) as $lb_object_id)
c3bdc503
DO
2295 if (!in_array ($lb_object_id, $lblist))
2296 {
fb6e2f57 2297 $oi = spotEntity ('object', $lb_object_id);
c3bdc503
DO
2298 $lbdname[$lb_object_id] = $oi['dname'];
2299 $lblist[] = $lb_object_id;
2300 }
2301 if (!count ($summary))
2302 echo 'none configured';
2303 else
2304 {
80e85ea1 2305 $order = 'odd';
c3bdc503 2306 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1a970c7 2307 echo "<tr valign=top><td>&nbsp;</td>";
c3bdc503 2308 foreach ($lblist as $lb_object_id)
b1a970c7 2309 {
4fbb5a00 2310 #echo "<th><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$lb_object_id))."'>" . $lbdname[$lb_object_id] . "</a></th>";
b1a970c7
DO
2311 echo '<td>';
2312 renderLBCell ($lb_object_id);
2313 echo '</td>';
2314 }
c3bdc503 2315 echo "</tr>\n";
4cadac8f
DO
2316 foreach ($summary as $vsid => $vsdata)
2317 {
b1a970c7 2318 echo "<tr class=row_${order}><td class=tdleft>";
6df2025d 2319 renderCell (spotEntity ('ipv4vs', $vsid));
6fec9f39 2320 echo "</td>";
4cadac8f 2321 foreach ($lblist as $lb_object_id)
da04825a 2322 {
60fbcece 2323 echo '<td class=tdleft>';
2b4eee17 2324 if (!isset ($vsdata['lblist'][$lb_object_id]))
da04825a
DO
2325 echo '&nbsp;';
2326 else
6fec9f39
DO
2327 {
2328 echo $vsdata['lblist'][$lb_object_id]['size'];
4fbb5a00 2329// echo " (<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$vsdata['lblist'][$lb_object_id]['id'])). "'>";
79a9edb4 2330// echo $vsdata['lblist'][$lb_object_id]['name'] . '</a>)';
6fec9f39 2331 }
da04825a
DO
2332 echo '</td>';
2333 }
2334 echo "</tr>\n";
80e85ea1 2335 $order = $nextorder[$order];
4cadac8f 2336 }
c3bdc503
DO
2337 echo "</table>\n";
2338 }
a7fe7729 2339 finishPortlet ();
e673ee24
DO
2340}
2341
04d619d0 2342function renderIPv4SpaceEditor ()
e673ee24 2343{
a262e150 2344 // IPv4 validator
65e557dd
AA
2345 addJs ('js/live_validation.js');
2346 $regexp = addslashes ('^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$');
2347 addJs (<<<END
2348$(document).ready(function () {
2349 document.add_new_range.range.setAttribute('match', '$regexp');
2350 Validate.init();
2351});
2352END
2353 , TRUE);
a262e150 2354
f857f71f
DO
2355 function printNewItemTR ()
2356 {
2357 startPortlet ('Add new');
2358 echo '<table border=0 cellpadding=10 align=center>';
2359 // This form requires a name, so JavaScript validator can find it.
2360 // No printOpFormIntro() hence
2361 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2362 echo "<input type=hidden name=op value=addIPv4Prefix>\n";
2363 // tags column
2364 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2365 renderNewEntityTags ('ipv4net');
2366 echo '</td>';
2367 // inputs column
2368 $prefix_value = empty ($_REQUEST['set-prefix']) ? '' : $_REQUEST['set-prefix'];
2369 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=18 class='live-validate' tabindex=1 value='${prefix_value}'></td>";
2370 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2371 echo "<tr><th class=tdright>connected network</th><td class=tdleft><input type=checkbox name='is_bcast' tabindex=3></td></tr>";
2372 echo "<tr><td colspan=2>";
2373 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2374 echo '</td></tr>';
2375 echo "</form></table><br><br>\n";
2376 finishPortlet();
2377 }
2a201216 2378
f857f71f
DO
2379 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2380 printNewItemTR();
ab1283b7 2381 if (count ($addrspaceList = listCells ('ipv4net')))
e673ee24 2382 {
e43a2de4 2383 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
04d619d0 2384 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
b1e39212 2385 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>capacity</th></tr>";
d3dcdfbb
DO
2386 array_walk ($addrspaceList, 'amplifyCell');
2387 $tree = prepareIPv4Tree ($addrspaceList, 'ALL');
2388 // this is only called for having "trace" set
2389 treeFromList ($addrspaceList);
0c16ef0c 2390 foreach ($addrspaceList as $netinfo)
e673ee24 2391 {
b1e39212
DO
2392 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2393 // now we have all subnets listed in netinfo
2394 loadIPv4AddrList ($netinfo);
2395 $used = $netinfo['addrc'];
2396 $maxdirect = $netinfo['addrt'];
2397 $maxtotal = binInvMaskFromDec ($netinfo['mask']) + 1;
e43a2de4 2398 echo "<tr valign=top><td>";
21ee3351
AA
2399 if (count ($netinfo['addrlist']) && getConfigVar ('IPV4_JAYWALK') == 'no')
2400 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
2401 else
e43a2de4
DO
2402 {
2403 echo "<a href='".makeHrefProcess(array('op'=>'delIPv4Prefix', 'id'=>$netinfo['id']))."'>";
2404 printImageHREF ('destroy', 'Delete this prefix');
2405 echo "</a>";
2406 }
21ee3351
AA
2407 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv4net', 'id' => $netinfo['id'])) . '">';
2408 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
2409 echo '<td class=tdleft>' . niftyString ($netinfo['name']);
2410 if (count ($netinfo['etags']))
2411 echo '<br><small>' . serializeTags ($netinfo['etags']) . '</small>';
2412 echo '</td><td>';
2413 renderProgressBar ($maxdirect ? $used/$maxdirect : 0);
2414 echo "<br><small>${used}/${maxdirect}" . ($maxdirect == $maxtotal ? '' : "/${maxtotal}") . '</small></td>';
2415 echo '</tr>';
2416 }
2417 echo "</table>";
2418 finishPortlet();
2419 }
2420 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2421 printNewItemTR();
2422}
e43a2de4 2423
21ee3351
AA
2424function renderIPv6SpaceEditor ()
2425{
2426 // IPv6 validator
65e557dd
AA
2427 addJs ('js/live_validation.js');
2428 $regexp = addslashes ('^[a-fA-F0-9:]*:[a-fA-F0-9:\.]*/\d{1,3}$');
2429 addJs (<<<END
2430$(document).ready(function () {
2431 document.add_new_range.range.setAttribute('match', '$regexp');
2432 Validate.init();
2433});
2434END
2435 , TRUE);
21ee3351
AA
2436
2437 function printNewItemTR ()
2438 {
2439 startPortlet ('Add new');
2440 echo '<table border=0 cellpadding=10 align=center>';
2441 // This form requires a name, so JavaScript validator can find it.
2442 // No printOpFormIntro() hence
2443 echo "<form method=post name='add_new_range' action='".makeHrefProcess()."'>\n";
2444 echo "<input type=hidden name=op value=addIPv6Prefix>\n";
2445 // tags column
2446 echo '<tr><td rowspan=4><h3>assign tags</h3>';
2447 renderNewEntityTags ('ipv4net');
2448 echo '</td>';
2449 // inputs column
2450 $prefix_value = empty ($_REQUEST['set-prefix']) ? '' : $_REQUEST['set-prefix'];
2451 echo "<th class=tdright>prefix</th><td class=tdleft><input type=text name='range' size=36 class='live-validate' tabindex=1 value='${prefix_value}'></td>";
2452 echo "<tr><th class=tdright>name</th><td class=tdleft><input type=text name='name' size='20' tabindex=2></td></tr>";
2453 echo "<tr><td colspan=2>";
2454 printImageHREF ('CREATE', 'Add a new network', TRUE, 4);
2455 echo '</td></tr>';
2456 echo "</form></table><br><br>\n";
2457 finishPortlet();
2458 }
2459
2460 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
2461 printNewItemTR();
2462 if (count ($addrspaceList = listCells ('ipv6net')))
2463 {
2464 startPortlet ('Manage existing (' . count ($addrspaceList) . ')');
2465 echo "<table class='widetable' border=0 cellpadding=5 cellspacing=0 align='center'>\n";
2466 echo "<tr><th>&nbsp;</th><th>prefix</th><th>name</th><th>capacity</th></tr>";
2467 array_walk ($addrspaceList, 'amplifyCell');
2468 $tree = prepareIPv6Tree ($addrspaceList, 'ALL');
2469 // this is only called for having "trace" set
2470 treeFromList ($addrspaceList);
2471 foreach ($addrspaceList as $netinfo)
2472 {
2473 $netinfo = peekNode ($tree, $netinfo['trace'], $netinfo['id']);
2474 // now we have all subnets listed in netinfo
2475 loadIPv6AddrList ($netinfo);
2476 echo "<tr valign=top><td>";
2477 if (count ($netinfo['addrlist']) && getConfigVar ('IPV4_JAYWALK') == 'no')
2478 printImageHREF ('nodestroy', 'There are ' . count ($netinfo['addrlist']) . ' allocations inside');
2479 else
2480 {
2481 echo "<a href='".makeHrefProcess (array ('op' => 'delIPv6Prefix', 'id' => $netinfo['id'])) . "'>";
2482 printImageHREF ('destroy', 'Delete this prefix');
2483 echo "</a>";
e43a2de4 2484 }
21ee3351 2485 echo '</td><td class=tdleft><a href="' . makeHref (array ('page' => 'ipv6net', 'id' => $netinfo['id'])) . '">';
ab1283b7 2486 echo "${netinfo['ip']}/${netinfo['mask']}</a></td>";
1f54e1ba
DO
2487 echo '<td class=tdleft>' . niftyString ($netinfo['name']);
2488 if (count ($netinfo['etags']))
2489 echo '<br><small>' . serializeTags ($netinfo['etags']) . '</small>';
2490 echo '</td><td>';
21ee3351 2491 echo formatIPv6NetUsage ($netinfo['addrc'], $netinfo['mask']);
b1e39212 2492 echo '</tr>';
e673ee24 2493 }
04d619d0
DO
2494 echo "</table>";
2495 finishPortlet();
e673ee24 2496 }
f857f71f
DO
2497 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
2498 printNewItemTR();
e673ee24
DO
2499}
2500
beb9e88a 2501function renderIPv4Network ($id)
e673ee24 2502{
c8824ff4 2503 global $pageno, $tabno, $aac2, $netmaskbylen, $wildcardbylen;
e673ee24 2504
d724d290 2505 $range = spotEntity ('ipv4net', $id);
a5f9d1ca 2506 amplifyCell ($range);
b6b87070 2507 loadIPv4AddrList ($range);
2034d968 2508 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
99ab184f
DO
2509 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>";
2510 echo htmlspecialchars ($range['name'], ENT_QUOTES, 'UTF-8') . "</h2></td></tr>\n";
2034d968
DO
2511
2512 echo "<tr><td class=pcleft width='50%'>";
2513 startPortlet ('summary');
2514 $total = ($range['ip_bin'] | $range['mask_bin_inv']) - ($range['ip_bin'] & $range['mask_bin']) + 1;
2515 $used = count ($range['addrlist']);
2516 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
04d619d0
DO
2517
2518 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2034d968
DO
2519 renderProgressBar ($used/$total);
2520 echo "&nbsp;${used}/${total}</td></tr>\n";
04d619d0 2521
001e61fa
DO
2522 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2523 {
3444ecf2
DO
2524 // Build a backtrace from all parent networks.
2525 $clen = $range['mask'];
2526 $backtrace = array();
2527 while (NULL !== ($upperid = getIPv4AddressNetworkId ($range['ip'], $clen)))
2528 {
d724d290 2529 $upperinfo = spotEntity ('ipv4net', $upperid);
3444ecf2 2530 $clen = $upperinfo['mask'];
d724d290 2531 $backtrace[] = $upperinfo;
3444ecf2
DO
2532 }
2533 $arrows = count ($backtrace);
d724d290 2534 foreach (array_reverse ($backtrace) as $ainfo)
001e61fa 2535 {
3444ecf2
DO
2536 echo "<tr><th width='50%' class=tdright>";
2537 for ($i = 0; $i < $arrows; $i++)
2538 echo '&uarr;';
2539 $arrows--;
5d3dcb8d 2540 echo "</th><td class=tdleft>";
6df2025d 2541 renderCell ($ainfo);
5d3dcb8d 2542 echo "</td></tr>";
001e61fa 2543 }
3444ecf2 2544 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
5d3dcb8d 2545 echo "<td class=tdleft>";
6df2025d 2546 renderCell ($range);
5d3dcb8d 2547 echo "</td></tr>";
001e61fa
DO
2548 // FIXME: get and display nested networks
2549 // $theitem = pickLeaf ($ipv4tree, $id);
2550 }
2551
545478d0
DO
2552 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2553 echo $netmaskbylen[$range['mask']];
2554 echo "</td></tr>\n";
04d619d0 2555
c607ab55
DO
2556 echo "<tr><th width='50%' class=tdright>Netmask:</th><td class=tdleft>";
2557 printf ('0x%08X', binMaskFromDec ($range['mask']));
2558 echo "</td></tr>\n";
2559
545478d0
DO
2560 echo "<tr><th width='50%' class=tdright>Wildcard bits:</th><td class=tdleft>";
2561 echo $wildcardbylen[$range['mask']];
2562 echo "</td></tr>\n";
04d619d0 2563
a5f9d1ca 2564 foreach ($range['8021q'] as $item)
cbf78395 2565 {
a5f9d1ca 2566 $vlaninfo = getVLANInfo ($item['domain_id'] . '-' . $item['vlan_id']);
cbf78395 2567 echo '<tr><th width="50%" class=tdright>VLAN:</th><td class=tdleft><a href="';
a5f9d1ca 2568 echo makeHref (array ('page' => 'vlan', 'vlan_ck' => $vlaninfo['vlan_ck'])) . '">';
a72aa89f 2569 echo formatVLANName ($vlaninfo, 'markup long');
ce85f5c8 2570 echo '</a></td></tr>';
cbf78395 2571 }
3a4f4023 2572 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers = findRouters ($range['addrlist'])))
04d619d0 2573 {
57dece2f 2574 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
f3d0cb20 2575 printRoutersTD ($routers);
57dece2f 2576 echo "</tr>\n";
04d619d0
DO
2577 }
2578
9b57f793 2579 printTagTRs ($range, makeHref(array('page'=>'ipv4space', 'tab'=>'default'))."&");
2034d968
DO
2580 echo "</table><br>\n";
2581 finishPortlet();
e1ae3fb4 2582
99ab184f
DO
2583 if (strlen ($range['comment']))
2584 {
2585 startPortlet ('Comment');
2586 echo '<div class=commentblock>' . string_insert_hrefs (htmlspecialchars ($range['comment'], ENT_QUOTES, 'UTF-8')) . '</div>';
2587 finishPortlet ();
2588 }
2589
e1ae3fb4 2590 renderFilesPortlet ('ipv4net', $id);
2034d968 2591 echo "</td>\n";
e673ee24 2592
2034d968
DO
2593 echo "<td class=pcright>";
2594 startPortlet ('details');
e673ee24
DO
2595 $startip = $range['ip_bin'] & $range['mask_bin'];
2596 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
2597 $realstartip = $startip;
2598 $realendip = $endip;
e673ee24 2599
00276508
AA
2600 if (isset ($_REQUEST['hl_ipv4_addr']))
2601 {
2602 $hl_ip = ip2long ($_REQUEST['hl_ipv4_addr']);
2603 $hl_dottedquad = ip_long2quad ($hl_ip);
65e557dd 2604 addAutoScrollScript ("ip-$hl_dottedquad"); // scroll page to highlighted ip
00276508
AA
2605 }
2606
79b57b18
AA
2607 // pager
2608 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2609 $address_count = $endip - $startip + 1;
2610 $page = 0;
2611 if ($address_count > $maxperpage && $maxperpage > 0)
2612 {
2613 $page = isset ($_REQUEST['pg']) ? $_REQUEST['pg'] : (isset ($hl_ip) ? intval (($hl_ip - $startip) / $maxperpage) : 0);
2614 if ($numpages = ceil ($address_count / $maxperpage))
2615 {
2616 echo "<center>";
2617 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
2618 for ($i = 0; $i < $numpages; $i++)
2619 if ($i == $page)
2620 echo "<b>$i</b> ";
2621 else
2622 echo "<a href='".makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $id, 'pg' => $i)) . "'>$i</a> ";
2623 echo "</center>";
2624 }
2625 $startip = $startip + $page * $maxperpage;
2626 $endip = min ($startip + $maxperpage - 1, $endip);
2627 }
2628
beb9e88a 2629 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
e673ee24
DO
2630 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2631
b2035dca 2632 for ($ip = $startip; $ip <= $endip; $ip++) :
00276508
AA
2633 $dottedquad = ip_long2quad($ip);
2634 $secondstyle = 'tdleft' . (isset ($hl_ip) && $hl_ip == $ip ? ' port_highlight' : '');
b2035dca 2635 if (!isset ($range['addrlist'][$ip]))
e673ee24 2636 {
a8dc2982
AA
2637 echo "<tr><td class=tdleft><a class='ancor' name='ip-$dottedquad' href='" . makeHref(array('page'=>'ipaddress', 'ip' => $dottedquad)) . "'>$dottedquad</a></td>";
2638 echo "<td class='rsv-port ${secondstyle}'><span class='rsvtext'></span></td><td class='${secondstyle}'>&nbsp;</td></tr>\n";
b2035dca
DO
2639 continue;
2640 }
b2035dca 2641 $addr = $range['addrlist'][$ip];
68c91b9c
AA
2642 // render IP change history
2643 $title = '';
2644 $history_class = '';
2645 if (isset ($addr['last_log']))
2646 {
2647 $title = ' title="' . htmlspecialchars ($addr['last_log']['user'] . ', ' . formatAge ($addr['last_log']['time']) , ENT_QUOTES) . '"';
2648 $history_class = 'hover-history underline';
2649 }
2d318652 2650 echo "<tr class='${addr['class']}'>";
68c91b9c 2651 echo "<td class=tdleft><a class='ancor $history_class' $title name='ip-$dottedquad' href='".makeHref(array('page'=>'ipaddress', 'ip'=>$addr['ip']))."'>${addr['ip']}</a></td>";
a8dc2982
AA
2652 echo "<td class='${secondstyle} " .
2653 (empty ($addr['allocs']) || !empty ($addr['name']) ? 'rsv-port' : '') .
2654 "'><span class='rsvtext'>${addr['name']}</span></td><td class='${secondstyle}'>";
b2035dca
DO
2655 $delim = '';
2656 $prologue = '';
2657 if ( $addr['reserved'] == 'yes')
2658 {
2d318652 2659 echo "<strong>RESERVED</strong> ";
b2035dca
DO
2660 $delim = '; ';
2661 }
2d318652 2662 foreach ($range['addrlist'][$ip]['allocs'] as $ref)
b2035dca 2663 {
beb9e88a 2664 echo $delim . $aac2[$ref['type']];
68c91b9c 2665 echo "<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id'], 'tab' => 'default', 'hl_ipv4_addr'=>$addr['ip']))."'>";
59a83bd8 2666 echo $ref['name'] . (!strlen ($ref['name']) ? '' : '@');
b2035dca
DO
2667 echo "${ref['object_name']}</a>";
2668 $delim = '; ';
2669 }
2670 if ($delim != '')
2671 {
6131056c 2672 $delim = '';
b2035dca
DO
2673 $prologue = '<br>';
2674 }
2d318652 2675 foreach ($range['addrlist'][$ip]['lblist'] as $ref)
b2035dca
DO
2676 {
2677 echo $prologue;
602663f4 2678 $prologue = '';
4fbb5a00
DY
2679 echo "${delim}<a href='".makeHref(array('page'=>'object', 'object_id'=>$ref['object_id']))."'>";
2680 echo "${ref['object_name']}</a>:<a href='".makeHref(array('page'=>'ipv4vs', 'vs_id'=>$ref['vs_id']))."'>";
b2035dca
DO
2681 echo "${ref['vport']}/${ref['proto']}</a>&rarr;";
2682 $delim = '; ';
2683 }
2684 if ($delim != '')
2685 {
2686 $delim = '';
2687 $prologue = '<br>';
e673ee24 2688 }
2d318652 2689 foreach ($range['addrlist'][$ip]['rslist'] as $ref)
b2035dca
DO
2690 {
2691 echo $prologue;
2692 $prologue = '';
4fbb5a00 2693 echo "${delim}&rarr;${ref['rsport']}@<a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$ref['rspool_id']))."'>";
b2035dca
DO
2694 echo "${ref['rspool_name']}</a>";
2695 $delim = '; ';
2696 }
2697 echo "</td></tr>\n";
2698 endfor;
2727c7df 2699 // end of iteration
a8dc2982
AA
2700 if (permitted (NULL, NULL, 'set_reserve_comment'))
2701 addJS ('js/inplace-edit.js');
e673ee24
DO
2702
2703 echo "</table>";
2034d968
DO
2704 finishPortlet();
2705 echo "</td></tr></table>\n";
e673ee24
DO
2706}
2707
21ee3351
AA
2708// based on renderIPv4Network
2709function renderIPv6Network ($id)
2710{
2711 $range = spotEntity ('ipv6net', $id);
2712 amplifyCell ($range);
2713 loadIPv6AddrList ($range);
2714 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
2715 echo "<tr><td colspan=2 align=center><h1>${range['ip']}/${range['mask']}</h1><h2>";
2716 echo htmlspecialchars ($range['name'], ENT_QUOTES, 'UTF-8') . "</h2></td></tr>\n";
2717
2718 echo "<tr><td class=pcleft width='50%'>";
2719 startPortlet ('summary');
2720 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2721 echo "<tr><th width='50%' class=tdright>%% used:</th><td class=tdleft>";
2722 echo "&nbsp;" . formatIPv6NetUsage (count ($range['addrlist']), $range['mask']) . "</td></tr>\n";
2723
2724 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
2725 {
2726 // Build a backtrace from all parent networks.
2727 $backtrace = array();
2728 $current = $range;
2729 while ($current['parent_id'])
2730 {
2731 $current = spotEntity ('ipv6net', $current['parent_id']);
2732 $backtrace[] = $current;
2733 }
2734 $arrows = count ($backtrace);
2735 foreach (array_reverse ($backtrace) as $ainfo)
2736 {
2737 echo "<tr><th width='50%' class=tdright>";
2738 for ($i = 0; $i < $arrows; $i++)
2739 echo '&uarr;';
2740 $arrows--;
2741 echo "</th><td class=tdleft>";
2742 renderCell ($ainfo);
2743 echo "</td></tr>";
2744 }
2745 echo "<tr><th width='50%' class=tdright>&rarr;</th>";
2746 echo "<td class=tdleft>";
2747 renderCell ($range);
2748 echo "</td></tr>";
2749 // FIXME: get and display nested networks
2750 }
2751
2752 foreach ($range['8021q'] as $item)
2753 {
2754 $vlaninfo = getVLANInfo ($item['domain_id'] . '-' . $item['vlan_id']);
2755 echo '<tr><th width="50%" class=tdright>VLAN:</th><td class=tdleft><a href="';
2756 echo makeHref (array ('page' => 'vlan', 'vlan_ck' => $vlaninfo['vlan_ck'])) . '">';
2757 echo formatVLANName ($vlaninfo, 'markup long');
2758 echo '</a></td></tr>';
2759 }
2760 if (getConfigVar ('EXT_IPV4_VIEW') == 'yes' and count ($routers = findRouters ($range['addrlist'])))
2761 {
2762 echo "<tr><th width='50%' class=tdright>Routed by:</th>";
2763 printRoutersTD ($routers);
2764 echo "</tr>\n";
2765 }
2766
2767 printTagTRs ($range, makeHref (array ('page' => 'ipv6space', 'tab' => 'default')) . "&");
2768 echo "</table><br>\n";
2769 finishPortlet();
2770
2771 if (strlen ($range['comment']))
2772 {
2773 startPortlet ('Comment');
2774 echo '<div class=commentblock>' . string_insert_hrefs (htmlspecialchars ($range['comment'], ENT_QUOTES, 'UTF-8')) . '</div>';
2775 finishPortlet ();
2776 }
2777
2778 renderFilesPortlet ('ipv6net', $id);
2779 echo "</td>\n";
2780
2781 // render address list
2782 echo "<td class=pcright>";
2783 startPortlet ('details');
2784 renderIPv6NetworkAddresses ($range);
2785 finishPortlet();
2786 echo "</td></tr></table>\n";
2787}
2788
2789// Used solely by renderSeparator
2790function renderEmptyIPv6 ($ip, $hl_ip)
2791{
2792 $class = 'tdleft';
2793 if (isset ($hl_ip) && $ip == $hl_ip)
2794 $class .= ' port_highlight';
2795 $fmt = $ip->format();
a8dc2982
AA
2796 echo "<tr><td class=tdleft><a class='ancor' name='ip-$fmt' href='" . makeHref (array ('page' => 'ipv6address', 'ip' => $fmt)) . "'>" . $fmt;
2797 echo "</a></td><td class='${class} rsv-port'><span class='rsvtext'></span></td><td class='${class}'>&nbsp;</td></tr>\n";
21ee3351
AA
2798}
2799
2800// Renders empty table line to shrink empty IPv6 address ranges.
2801// If the range consists of single address, renders the address instead of empty line.
2802// Renders address $hl_ip inside the range.
2803// Used solely by renderIPv6NetworkAddresses
2804function renderSeparator ($first, $after, $hl_ip)
2805{
2806 $self = __FUNCTION__;
522b6f90 2807 if (strcmp ($first->getBin(), $after->getBin()) >= 0)
21ee3351
AA
2808 return;
2809 if ($first->next() == $after)
2810 renderEmptyIPv6 ($first, $hl_ip);
522b6f90 2811 elseif (isset ($hl_ip) && strcmp ($hl_ip->getBin(), $first->getBin()) >= 0 && strcmp ($hl_ip->getBin(), $after->getBin()) < 0)
21ee3351
AA
2812 { // $hl_ip is inside the range $first - ($after-1)
2813 $self ($first, $hl_ip, $hl_ip);
2814 renderEmptyIPv6 ($hl_ip, $hl_ip);
2815 $self ($hl_ip->next(), $after, $hl_ip);
2816 }
2817 else
2818 echo "<tr><td colspan=3 class=tdleft></td></tr>\n";
2819}
2820
2821// calculates page number which contains given $ip (used by renderIPv6NetworkAddresses)
2822function getPageNumOfIPv6 ($list, $ip, $maxperpage)
2823{
2824 if (intval ($maxperpage) <= 0 || count ($list) <= $maxperpage)
2825 return 0;
522b6f90 2826 $bin_ip = $ip->getBin();
21ee3351
AA
2827 $keys = array_keys ($list);
2828 for ($i = 1; $i <= count ($keys); $i++)
2829 if (strcmp ($keys[$i-1], $bin_ip) >= 0)
2830 return intval ($i / $maxperpage);
2831 return intval (count ($list) / $maxperpage);
2832}
2833
2834function renderIPv6NetworkAddresses ($netinfo)
2835{
2836 global $pageno, $tabno, $aac2;
2837 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center' width='100%'>\n";
2838 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
2839
2840 $hl_ip = new IPv6Address;
2841 if (! isset ($_REQUEST['hl_ipv6_addr']) || ! $hl_ip->parse ($_REQUEST['hl_ipv6_addr']))
2842 $hl_ip = NULL;
00276508 2843 else
65e557dd 2844 addAutoScrollScript ('ip-' . $hl_ip->format());
21ee3351
AA
2845
2846 $prev_ip = $netinfo['ip_bin']; // really this is the next to previosly seen ip.
2847 $addresses = $netinfo['addrlist'];
2848 ksort ($addresses);
2849
2850 // pager
2851 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
2852 if (count ($addresses) > $maxperpage && $maxperpage > 0)
2853 {
2854 $page = isset ($_REQUEST['pg']) ? $_REQUEST['pg'] : (isset ($hl_ip) ? getPageNumOfIPv6 ($addresses, $hl_ip, $maxperpage) : 0);
2855 $numpages = ceil (count ($addresses) / $maxperpage);
2856 echo "<center><h3>$numpages pages:</h3>";
2857 for ($i=0; $i<$numpages; $i++)
2858 {
2859 if ($i == $page)
2860 echo "<b>$i</b> ";
2861 else
2862 echo "<a href='" . makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $netinfo['id'], 'pg' => $i)) . "'>$i</a> ";
2863 }
2864 echo "</center>";
2865 }
2866
2867 $i = 0;
2868 $interruped = FALSE;
2869 foreach ($addresses as $bin_ip => $addr)
2870 {
2871 if (isset ($page))
2872 {
2873 ++$i;
2874 if ($i <= $maxperpage * $page)
2875 continue;
2876 elseif ($i > $maxperpage * ($page + 1))
2877 {
2878 $interruped = TRUE;
2879 break;
2880 }
2881 }
2882
2883 $ipv6 = new IPv6Address ($bin_ip);
2884 if ($ipv6 != $prev_ip)
2885 renderSeparator ($prev_ip, $ipv6, $hl_ip);
2886 $prev_ip = $ipv6->next();
2887
2888 $secondstyle = 'tdleft';
2889 if (isset ($hl_ip) && $hl_ip == $ipv6)
2890 $secondstyle .= ' port_highlight';
2891 echo "<tr class='${addr['class']}'>";
a8dc2982
AA
2892 echo "<td class=tdleft><a class='ancor' name='ip-${addr['ip']}' href='" . makeHref (array ('page' => 'ipv6address', 'ip' => $addr['ip'])) . "'>${addr['ip']}</a></td>";
2893 echo "<td class='${secondstyle} " .
2894 (empty ($addr['allocs']) || !empty ($addr['name']) ? 'rsv-port' : '') .
2895 "'><span class='rsvtext'>${addr['name']}</span></td><td class='${secondstyle}'>";
21ee3351
AA
2896 $delim = '';
2897 $prologue = '';
2898 if ( $addr['reserved'] == 'yes')
2899 {
2900 echo "<strong>RESERVED</strong> ";
2901 $delim = '; ';
2902 }
2903 foreach ($addr['allocs'] as $ref)
2904 {
2905 echo $delim . $aac2[$ref['type']];
2906 echo "<a href='" . makeHref (array ('page' => 'object', 'object_id' => $ref['object_id'], 'hl_ipv6_addr' => $addr['ip'])) . "'>";
2907 echo $ref['name'] . (!strlen ($ref['name']) ? '' : '@');
2908 echo "${ref['object_name']}</a>";
2909 $delim = '; ';
2910 }
2911 if ($delim != '')
2912 {
2913 $delim = '';
2914 $prologue = '<br>';
2915 }
2916 echo "</td></tr>\n";
2917 }
2918 if (! $interruped)
2919 renderSeparator ($prev_ip, $netinfo['ip_bin']->get_last_subnet_address ($netinfo['mask'])->next(), $hl_ip);
2920 if (isset ($page))
2921 { // bottom pager
2922 echo "<tr><td colspan=3>";
2923 if ($page > 0)
2924 echo "<a href='" . makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $netinfo['id'], 'pg' => $page - 1)) . "'><< prev</a> ";
2925 if ($page < $numpages - 1)
2926 echo "<a href='" . makeHref (array ('page' => $pageno, 'tab' => $tabno, 'id' => $netinfo['id'], 'pg' => $page + 1)) . "'>next >></a> ";
2927 echo "</td></tr>";
2928 }
2929 echo "</table>";
a8dc2982
AA
2930 if (permitted (NULL, NULL, 'set_reserve_comment'))
2931 addJS ('js/inplace-edit.js');
21ee3351
AA
2932}
2933
2934function renderIPNetworkProperties ($id)
e673ee24 2935{
21ee3351
AA
2936 global $pageno;
2937 $netdata = spotEntity ($pageno, $id);
53ef3908 2938 echo "<center><h1>${netdata['ip']}/${netdata['mask']}</h1></center>\n";
e673ee24 2939 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 2940 printOpFormIntro ('editRange');
99ab184f
DO
2941 echo '<tr><td class=tdright><label for=nameinput>Name:</label></td>';
2942 echo "<td class=tdleft><input type=text name=name id=nameinput size=80 maxlength=255 value='";
2943 echo htmlspecialchars ($netdata['name'], ENT_QUOTES, 'UTF-8') . "'></tr>";
2944 echo '<tr><td class=tdright><label for=commentinput>Comment:</label></td>';
2945 echo "<td class=tdleft><textarea name=comment id=commentinput cols=80 rows=25>\n";
2946 echo htmlspecialchars ($netdata['comment'], ENT_QUOTES, 'UTF-8') . "</textarea></tr>";
53ef3908
DO
2947 echo "<tr><td colspan=2 class=tdcenter>";
2948 printImageHREF ('SAVE', 'Save changes', TRUE);
2949 echo "</td></form></tr></table>\n";
e673ee24
DO
2950}
2951
21ee3351 2952function renderIPAddress ($dottedquad)
e673ee24 2953{
46098972 2954 global $aat, $nextorder;
21ee3351 2955 $address = getIPAddress ($dottedquad);
68225375 2956 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
21ee3351 2957 echo "<tr><td colspan=2 align=center><h1>${address['ip']}</h1></td></tr>\n";
e673ee24 2958
68225375
DO
2959 echo "<tr><td class=pcleft>";
2960 startPortlet ('summary');
2961 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
423c4216
DO
2962 if (strlen ($address['name']))
2963 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${address['name']}</td></tr>";
04d619d0 2964 echo "<tr><th width='50%' class=tdright>Allocations:</th><td class=tdleft>" . count ($address['allocs']) . "</td></tr>\n";
21ee3351
AA
2965 if ($address['version'] == 4)
2966 {
2967 echo "<tr><th width='50%' class=tdright>Originated NAT connections:</th><td class=tdleft>" . count ($address['outpf']) . "</td></tr>\n";
2968 echo "<tr><th width='50%' class=tdright>Arriving NAT connections:</th><td class=tdleft>" . count ($address['inpf']) . "</td></tr>\n";
2969 echo "<tr><th width='50%' class=tdright>SLB virtual services:</th><td class=tdleft>" . count ($address['lblist']) . "</td></tr>\n";
2970 echo "<tr><th width='50%' class=tdright>SLB real servers:</th><td class=tdleft>" . count ($address['rslist']) . "</td></tr>\n";
2971 }
68225375
DO
2972 echo "</table><br>\n";
2973 finishPortlet();
2974 echo "</td>\n";
e673ee24 2975
68225375 2976 echo "<td class=pcright>";
f74d96c6 2977 if (isset ($address['class']))
59bebe2b 2978 {
8e700dd1 2979 startPortlet ('allocations');
2d318652
DO
2980 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
2981 echo "<tr><th>object</th><th>OS interface</th><th>allocation type</th></tr>\n";
2982 $class = $address['class'];
2983 // render all allocation records for this address the same way
59bebe2b 2984 if ($address['reserved'] == 'yes')
2d318652
DO
2985 echo "<tr class='${class}'><td colspan=2>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td></tr>";
2986 foreach ($address['allocs'] as $bond)
59bebe2b 2987 {
8e700dd1
DO
2988 if (isset ($_REQUEST['hl_object_id']) and $_REQUEST['hl_object_id'] == $bond['object_id'])
2989 $secondclass = 'tdleft port_highlight';
2990 else
2991 $secondclass = 'tdleft';
68c91b9c 2992 echo "<tr class='$class'><td class=tdleft><a href='" . makeHref (array ('page' => 'object', 'object_id' => $bond['object_id'], 'tab' => 'default', 'hl_ipv' . $address['version'] . '_addr' => $address['ip'])) . "'>${bond['object_name']}</td><td class='${secondclass}'>${bond['name']}</td><td class='${secondclass}'><strong>";
52c836b1
DO
2993 echo $aat[$bond['type']];
2994 echo "</strong></td></tr>\n";
59bebe2b
DO
2995 }
2996 echo "</table><br><br>";
2997 finishPortlet();
2998 }
e673ee24 2999
f3d0cb20
DO
3000 // FIXME: The returned list is structured differently, than we expect it to be. One of the sides
3001 // must be fixed.
21ee3351 3002 if (! empty ($address['lblist']))
e673ee24 3003 {
2d318652
DO
3004 startPortlet ('Virtual services (' . count ($address['lblist']) . ')');
3005 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
46098972
DO
3006 echo "<tr><th>VS</th><th>LB</th></tr>\n";
3007 $order = 'odd';
2d318652 3008 foreach ($address['lblist'] as $vsinfo)
e673ee24 3009 {
46098972
DO
3010 echo "<tr valign=top class=row_${order}><td class=tdleft>";
3011 renderCell (spotEntity ('ipv4vs', $vsinfo['vs_id']));
3012 echo "</td><td class=tdleft>";
3013 renderLBCell ($vsinfo['object_id']);
3014 echo "</td></tr>";
3015 $order = $nextorder[$order];
e673ee24 3016 }
59bebe2b
DO
3017 echo "</table><br><br>";
3018 finishPortlet();
e673ee24 3019 }
5fe1ed76 3020
21ee3351 3021 if (! empty ($address['rslist']))
5fe1ed76
DO
3022 {
3023 startPortlet ('Real servers (' . count ($address['rslist']) . ')');
2d318652 3024 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
53f4b619 3025 echo "<tr><th>&nbsp;</th><th>port</th><th>RS pool</th></tr>\n";
5fe1ed76
DO
3026 foreach ($address['rslist'] as $rsinfo)
3027 {
3028 echo "<tr><td>";
3029 if ($rsinfo['inservice'] == 'yes')
3030 printImageHREF ('inservice', 'in service');
3031 else
3032 printImageHREF ('notinservice', 'NOT in service');
4fbb5a00 3033 echo "</td><td class=tdleft>${rsinfo['rsport']}</td><td class=tdleft><a href='".makeHref(array('page'=>'ipv4rspool', 'pool_id'=>$rsinfo['rspool_id']))."'>";
2d318652 3034 echo $rsinfo['rspool_name'] . "</a></td></tr>\n";
5fe1ed76
DO
3035 }
3036 echo "</table><br><br>";
3037 finishPortlet();
3038 }
3039
21ee3351 3040 if (! empty ($address['outpf']))
68225375 3041 {
105a3bc8 3042 startPortlet ('departing NAT rules');
2d318652 3043 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
3044 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
3045 foreach ($address['outpf'] as $rule)
b62ff880 3046 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8 3047 echo "</table>";
68225375
DO
3048 finishPortlet();
3049 }
105a3bc8 3050
21ee3351 3051 if (! empty ($address['inpf']))
105a3bc8
DO
3052 {
3053 startPortlet ('arriving NAT rules');
2d318652 3054 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center' width='100%'>\n";
105a3bc8
DO
3055 echo "<tr><th>proto</th><th>from</th><th>to</th><th>comment</th></tr>\n";
3056 foreach ($address['inpf'] as $rule)
b62ff880 3057 echo "<tr><td>${rule['proto']}</td><td>${rule['localip']}:${rule['localport']}</td><td>${rule['remoteip']}:${rule['remoteport']}</td><td>${rule['description']}</td></tr>";
105a3bc8
DO
3058 echo "</table>";
3059 finishPortlet();
3060 }
3061
68225375
DO
3062 echo "</td></tr>";
3063 echo "</table>\n";
e673ee24
DO
3064}
3065
21ee3351 3066function renderIPAddressProperties ($dottedquad)
e673ee24 3067{
21ee3351
AA
3068 $address = getIPAddress ($dottedquad);
3069 echo "<center><h1>${address['ip']}</h1></center>\n";
7056988c 3070
1fbc9fd6 3071 startPortlet ('update');
e673ee24 3072 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
7056988c 3073 printOpFormIntro ('editAddress');
2d318652
DO
3074 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${address['name']}'></tr>";
3075 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ";
3076 echo ($address['reserved']=='yes') ? 'checked' : '';
f3d274bf 3077 echo "></tr><tr><td class=tdleft>";
53ef3908 3078 printImageHREF ('SAVE', 'Save changes', TRUE);
f3d274bf 3079 echo "</td></form><td class=tdright>";
59a83bd8 3080 if (!strlen ($address['name']) and $address['reserved'] == 'no')
f3d274bf
DO
3081 printImageHREF ('CLEAR gray');
3082 else
3083 {
3084 printOpFormIntro ('editAddress', array ('name' => '', 'reserved' => ''));
3085 printImageHREF ('CLEAR', 'Release', TRUE);
3086 echo "</form>";
3087 }
3088 echo "</td></tr></table>\n";
1fbc9fd6 3089 finishPortlet();
e673ee24
DO
3090}
3091
21ee3351 3092function renderIPAddressAllocations ($dottedquad)
e673ee24 3093{
21ee3351 3094 function printNewItemTR ($opname)
39b4abd0
DO
3095 {
3096 global $aat;
21ee3351 3097 printOpFormIntro ($opname);
39b4abd0 3098 echo "<tr><td>";
9318d2ef 3099 printImageHREF ('add', 'allocate', TRUE);
8d4f7d18 3100 echo "</td><td>";
31babb65 3101 printSelect (getNarrowObjectList ('IPV4OBJ_LISTSRC'), array ('name' => 'object_id', 'tabindex' => 100));
8d4f7d18 3102 echo "</td><td><input type=text tabindex=101 name=bond_name size=10></td><td>";
01abf1de 3103 printSelect ($aat, array ('name' => 'bond_type', 'tabindex' => 102, 'regular'));
9318d2ef 3104 echo "</td><td>";
f5ff50f5 3105 printImageHREF ('add', 'allocate', TRUE, 103);
9318d2ef 3106 echo "</td></form></tr>";
39b4abd0 3107 }
b82cce3f 3108 global $aat;
e673ee24 3109
21ee3351
AA
3110 $address = getIPAddress ($dottedquad);
3111 $opname = $address['version'] == 6 ? 'addIPv6Allocation' : 'addIPv4Allocation';
3112 echo "<center><h1>${address['ip']}</h1></center>\n";
105a3bc8 3113 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
2d318652 3114 echo "<tr><th>&nbsp;</th><th>object</th><th>OS interface</th><th>allocation type</th><th>&nbsp;</th></tr>\n";
e673ee24 3115
39b4abd0 3116 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
21ee3351 3117 printNewItemTR($opname);
f74d96c6 3118 if (isset ($address['class']))
e673ee24 3119 {
f74d96c6
DO
3120 $class = $address['class'];
3121 if ($address['reserved'] == 'yes')
3122 echo "<tr class='${class}'><td colspan=3>&nbsp;</td><td class=tdleft><strong>RESERVED</strong></td><td>&nbsp;</td></tr>";
3123 foreach ($address['allocs'] as $bond)
3124 {
3125 echo "<tr class='$class'>";
21ee3351
AA
3126 printOpFormIntro
3127 (
3128 $address['version'] == 6 ? 'updIPv6Allocation' : 'updIPv4Allocation',
3129 array ('object_id' => $bond['object_id'])
3130 );
3131 echo "<td><a href='"
3132 . makeHrefProcess
3133 (
3134 array
3135 (
3136 'op' => $address['version'] == 6 ? 'delIPv6Allocation' : 'delIPv4Allocation',
3137 'ip' => $address['ip'],
3138 'object_id' => $bond['object_id']
3139 )
3140 )
3141 . "'>";
f74d96c6
DO
3142 printImageHREF ('delete', 'Unallocate address');
3143 echo "</a></td>";
21ee3351 3144 echo "<td><a href='" . makeHref (array ('page' => 'object', 'object_id' => $bond['object_id'], 'hl_ipv' . $address['version'] . '_addr' => $address['ip'])) . "'>${bond['object_name']}</td>";
f74d96c6 3145 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td><td>";
cd3775e9 3146 printSelect ($aat, array ('name' => 'bond_type'), $bond['type']);
f74d96c6
DO
3147 echo "</td><td>";
3148 printImageHREF ('save', 'Save changes', TRUE);
3149 echo "</td></form></tr>\n";
3150 }
e673ee24 3151 }
39b4abd0 3152 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
21ee3351 3153 printNewItemTR($opname);
e673ee24 3154 echo "</table><br><br>";
e673ee24
DO
3155}
3156
7e1db771 3157function renderNATv4ForObject ($object_id)
e673ee24 3158{
9318d2ef
DO
3159 function printNewItemTR ($alloclist)
3160 {
9318d2ef
DO
3161 printOpFormIntro ('addNATv4Rule');
3162 echo "<tr align='center'><td>";
3163 printImageHREF ('add', 'Add new NAT rule', TRUE);
3164 echo '</td><td>';
cd3775e9 3165 printSelect (array ('TCP' => 'TCP', 'UDP' => 'UDP'), array ('name' => 'proto'));
9318d2ef
DO
3166 echo "<select name='localip' tabindex=1>";
3167
3168 foreach ($alloclist as $dottedquad => $alloc)
3169 {
43eb71f1
DO
3170 $name = (!isset ($alloc['addrinfo']['name']) or !strlen ($alloc['addrinfo']['name'])) ? '' : (' (' . niftyString ($alloc['addrinfo']['name']) . ')');
3171 $osif = (!isset ($alloc['osif']) or !strlen ($alloc['osif'])) ? '' : ($alloc['osif'] . ': ');
9318d2ef
DO
3172 echo "<option value='${dottedquad}'>${osif}${dottedquad}${name}</option>";
3173 }
3174
3175 echo "</select>:<input type='text' name='localport' size='4' tabindex=2></td>";
3176 echo "<td><input type='text' name='remoteip' id='remoteip' size='10' tabindex=3>";
39106006
DO
3177 echo "<a href='javascript:;' onclick='window.open(\"" . makeHrefForHelper ('inet4list');
3178 echo "\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
9318d2ef
DO
3179 printImageHREF ('find', 'Find object');
3180 echo "</a>";
3181 echo ":<input type='text' name='remoteport' size='4' tabindex=4></td><td></td>";
3182 echo "<td colspan=1><input type='text' name='description' size='20' tabindex=5></td><td>";
f5ff50f5 3183 printImageHREF ('add', 'Add new NAT rule', TRUE, 6);
9318d2ef
DO
3184 echo "</td></tr></form>";
3185 }
e673ee24 3186
94fe6370
DO
3187 $focus = spotEntity ('object', $object_id);
3188 amplifyCell ($focus);
f28fbe8b 3189 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24 3190
105a3bc8 3191 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
d54b9495 3192 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th><th>&nbsp;</th></tr>\n";
e673ee24 3193
9318d2ef 3194 if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
94fe6370
DO
3195 printNewItemTR ($focus['ipv4']);
3196 foreach ($focus['nat4']['out'] as $pf)
e673ee24 3197 {
2c817354
DO
3198 $class = 'trerror';
3199 $osif = '';
94fe6370 3200 if (isset ($focus['ipv4'][$pf['localip']]))
2c817354 3201 {
94fe6370
DO
3202 $class = $focus['ipv4'][$pf['localip']]['addrinfo']['class'];
3203 $osif = $focus['ipv4'][$pf['localip']]['osif'] . ': ';
2c817354 3204 }
e673ee24
DO
3205
3206 echo "<tr class='$class'>";
4fbb5a00
DY
3207 echo "<td><a href='".
3208 makeHrefProcess(array(
3209 'op'=>'delNATv4Rule',
3210 'localip'=>$pf['localip'],
3211 'localport'=>$pf['localport'],
3212 'remoteip'=>$pf['remoteip'],
3213 'remoteport'=>$pf['remoteport'],
3214 'proto'=>$pf['proto'],
3215 'object_id'=>$object_id)).
3216 "'>";
4de22e7e
DO
3217 printImageHREF ('delete', 'Delete NAT rule');
3218 echo "</a></td>";
4fbb5a00 3219 echo "<td>${pf['proto']}/${osif}<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}";
59a83bd8 3220 if (strlen ($pf['local_addr_name']))
f28fbe8b
DO
3221 echo ' (' . $pf['local_addr_name'] . ')';
3222 echo "</td>";
4fbb5a00 3223 echo "<td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24 3224
53ef3908 3225 $address = getIPv4Address ($pf['remoteip']);
e673ee24
DO
3226
3227 echo "<td class='description'>";
53ef3908
DO
3228 if (count ($address['allocs']))
3229 foreach ($address['allocs'] as $bond)
4fbb5a00 3230 echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
59a83bd8 3231 elseif (strlen ($pf['remote_addr_name']))
f28fbe8b 3232 echo '(' . $pf['remote_addr_name'] . ')';
7056988c
DO
3233 printOpFormIntro
3234 (
3235 'updNATv4Rule',
3236 array
3237 (
3238 'localip' => $pf['localip'],
3239 'localport' => $pf['localport'],
3240 'remoteip' => $pf['remoteip'],
3241 'remoteport' => $pf['remoteport'],
3242 'proto' => $pf['proto']
3243 )
3244 );
3245 echo "</td><td class='description'>";
d54b9495
DO
3246 echo "<input type='text' name='description' value='${pf['description']}'></td><td>";
3247 printImageHREF ('save', 'Save changes', TRUE);
3248 echo "</td></form></tr>";
e673ee24 3249 }
9318d2ef 3250 if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
94fe6370 3251 printNewItemTR ($focus['ipv4']);
e673ee24
DO
3252
3253 echo "</table><br><br>";
94fe6370
DO
3254 if (!count ($focus['nat4']))
3255 return;
e673ee24 3256
f28fbe8b 3257 echo "<center><h2>arriving NAT connections</h2></center>";
105a3bc8 3258 echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
e673ee24
DO
3259 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
3260
94fe6370 3261 foreach ($focus['nat4']['in'] as $pf)
e673ee24 3262 {
4fbb5a00
DY
3263 echo "<tr><td><a href='".
3264 makeHrefProcess(array(
3265 'op'=>'delNATv4Rule',
3266 'localip'=>$pf['localip'],
3267 'localport'=>$pf['localport'],
3268 'remoteip'=>$pf['remoteip'],
3269 'remoteport'=>$pf['remoteport'],
3270 'proto'=>$pf['proto'],
3271 'object_id'=>$pf['object_id']
3272 )).
3273 "'>";
4de22e7e
DO
3274 printImageHREF ('delete', 'Delete NAT rule');
3275 echo "</a></td>";
4fbb5a00
DY
3276 echo "<td>${pf['proto']}/<a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['localip']))."'>${pf['localip']}</a>:${pf['localport']}</td>";
3277 echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
3278 echo "</td><td><a href='".makeHref(array('page'=>'ipaddress', 'tab'=>'default', 'ip'=>$pf['remoteip']))."'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
3279 echo "<td class='description'>${pf['description']}</td></tr>";
3280 }
3281
e673ee24 3282 echo "</table><br><br>";
e673ee24
DO
3283}
3284
e673ee24
DO
3285function renderAddMultipleObjectsForm ()
3286{
2c2ea5f6 3287 global $virtual_obj_types;
7fa7047a 3288 $typelist = readChapter (CHAP_OBJTYPE, 'o');
4c330a14 3289 $typelist[0] = 'select type...';
7fa7047a 3290 $typelist = cookOptgroups ($typelist);
a1886a78
DO
3291 $max = getConfigVar ('MASSCOUNT');
3292 $tabindex = 100;
7f791d1d 3293
0682218d 3294 // create a list containing only physical object types
0682218d
AD
3295 $phys_typelist = $typelist;
3296 foreach ($phys_typelist['other'] as $key => $value)
3297 {
2c2ea5f6