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