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