r1387 + fixed typo
[racktables] / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
9c0b0016
DO
8// Interface function's special.
9$nextorder['odd'] = 'even';
10$nextorder['even'] = 'odd';
11
e673ee24
DO
12// Main menu.
13function renderIndex ()
14{
15 global $root;
16?>
17<table border=0 cellpadding=0 cellspacing=0 width='100%'>
18 <tr>
19 <td>
20 <div style='text-align: center; margin: 10px; '>
21 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
22 <tr>
23 <td>
b325120a
DO
24 <h1><a href='<?php echo $root; ?>?page=rackspace'>Rackspace<br>
25 <?php printImageHREF ('rackspace'); ?></a></h1>
e673ee24
DO
26 </td>
27 <td>
b325120a
DO
28 <h1><a href='<?php echo $root; ?>?page=objects'>Objects<br>
29 <?php printImageHREF ('objects'); ?></a></h1>
e673ee24
DO
30 </td>
31 <td>
b325120a
DO
32 <h1><a href='<?php echo $root; ?>?page=ipv4space'>IPv4 space<br>
33 <?php printImageHREF ('ipv4space'); ?></a></h1>
e673ee24
DO
34 </td>
35 </tr>
36 </table>
37 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
38 <tr>
39 <td>
b325120a
DO
40 <h1><a href='<?php echo $root; ?>?page=config'>Configuration<br>
41 <?php printImageHREF ('config'); ?></a></h1>
e673ee24
DO
42 </td>
43 <td>
da95280e 44 <h1><a href='<?php echo $root; ?>?page=reports'>Reports<br>
b325120a 45 <?php printImageHREF ('reports'); ?></a></h1>
e673ee24 46 </td>
ae545907 47 <td>
b325120a
DO
48 <h1><a href='<?php echo $root; ?>?page=help'>Help<br>
49 <?php printImageHREF ('help'); ?></a></h1>
ae545907 50 </td>
e673ee24
DO
51 </tr>
52 </table>
53 </div>
54 </td>
55 </tr>
56</table>
b325120a 57<?php
e673ee24
DO
58}
59
60function renderRackspace ()
61{
62?>
63 <table border=0 cellpadding=10 cellpadding=1>
b325120a 64<?php
e673ee24
DO
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
9c0b0016
DO
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
e673ee24
DO
69 $order = 'odd';
70 foreach ($rackrowList as $rackrow)
71 {
72 echo "<tr class=row_${order}><th><a href='${root}?page=row&row_id=${rackrow['dict_key']}'>${rackrow['dict_value']}</a></th>";
73 $rackList = getRacksForRow ($rackrow['dict_key']);
74 echo "<td><table border=0 cellspacing=5><tr>";
75 foreach ($rackList as $dummy => $rack)
76 {
77 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
78 echo "<img border=0 width=${rackwidth} height=";
79 echo 3 + 3 + $rack['height'] * 2;
80 echo " title='${rack['height']} units'";
81 echo "src='render_rack_thumb.php?rack_id=${rack['id']}'>";
82 echo "<br>${rack['name']}</a></td>";
83 }
84 echo "</tr></table></tr>\n";
85 $order = $nextorder[$order];
86 }
87 echo "</table>\n";
88}
89
90function renderRow ($row_id)
91{
92 if ($row_id == 0)
93 {
94 showError ('Invalid row_id in renderRow()');
95 return;
96 }
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
98 {
99 showError ('getRackRowInfo() failed in renderRow()');
100 return;
101 }
102 // Main layout starts.
103 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
104
105 // Left portlet with row information.
106 echo "<tr><td class=pcleft>";
51a2330f 107 startPortlet ($rowInfo['dict_value']);
e673ee24 108 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
e673ee24
DO
109 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
110 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
111 echo "</table><br>\n";
112 finishPortlet();
113
114 echo "</td><td class=pcright>";
115
9c0b0016
DO
116 global $root, $nextorder;
117 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
e673ee24
DO
118 $rackList = getRacksForRow ($row_id);
119 $order = 'odd';
120 startPortlet ('Racks');
121 echo "<table border=0 cellspacing=5 align='center'><tr>";
122 foreach ($rackList as $dummy => $rack)
123 {
124 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
9c0b0016
DO
125 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
126 echo (3 + 3 + $rack['height'] * 2) * getConfigVar ('ROW_SCALE');
e673ee24
DO
127 echo " title='${rack['height']} units'";
128 echo "src='render_rack_thumb.php?rack_id=${rack['id']}'>";
129 echo "<br>${rack['name']}</a></td>";
130 $order = $nextorder[$order];
131 }
132 echo "</tr></table>\n";
133 finishPortlet();
134
135 echo "</td></tr></table>";
136}
137
138function showError ($info = '')
139{
140 global $root;
141 echo '<div class=msg_error>An error has occured. ';
142 if (empty ($info))
143 echo 'No additional information is available.';
144 else
145 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
146 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
147}
148
149// This function renders rack as HTML table.
150function renderRack ($rack_id = 0, $hl_obj_id = 0)
151{
152 if ($rack_id == 0)
153 {
154 showError ('Invalid rack_id in renderRack()');
155 return;
156 }
157 if (($rackData = getRackData ($rack_id)) == NULL)
158 {
159 showError ('getRackData() failed in renderRack()');
160 return;
161 }
162 global $root, $pageno, $tabno;
163 markAllSpans ($rackData);
164 if ($hl_obj_id > 0)
165 highlightObject ($rackData, $hl_obj_id);
166 markupObjectProblems ($rackData);
167 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
168 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
169 echo "<center>\n<h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :";
170 // FIXME: use 'bypass'?
171 if ($prev_id != NULL)
172 echo " <a href='${root}?page=rack&rack_id=${prev_id}'>&lt; &lt; &lt;</a>";
173 echo " <a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a>";
174 if ($next_id != NULL)
175 echo " <a href='${root}?page=rack&rack_id=${next_id}'>&gt; &gt; &gt;</a>";
176 echo "</h2>\n";
177 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
178 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
179 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
180 for ($i = $rackData['height']; $i > 0; $i--)
181 {
182 echo "<tr><th>$i</th>";
183 for ($locidx = 0; $locidx < 3; $locidx++)
184 {
185 if (isset ($rackData[$i][$locidx]['skipped']))
186 continue;
187 $state = $rackData[$i][$locidx]['state'];
188 echo "<td class=state_${state}";
189 if (isset ($rackData[$i][$locidx]['hl']))
190 echo $rackData[$i][$locidx]['hl'];
191 if (isset ($rackData[$i][$locidx]['colspan']))
192 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
193 if (isset ($rackData[$i][$locidx]['rowspan']))
194 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
195 echo ">";
196 switch ($state)
197 {
198 case 'T':
199 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
200 if (!empty ($objectData['asset_no']))
201 $prefix = "<div title='${objectData['asset_no']}";
202 else
203 $prefix = "<div title='no asset tag";
204 // Don't tell about label, if it matches common name.
205 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
206 $suffix = ", visible label is \"${objectData['label']}\"'>";
207 else
208 $suffix = "'>";
209 echo $prefix . $suffix;
210 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
211 break;
212 case 'A':
213 echo '<div title="This rackspace does not exist">&nbsp;</div>';
214 break;
215 case 'F':
216 echo '<div title="Free rackspace">&nbsp;</div>';
217 break;
218 case 'U':
219 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
220 break;
221 default:
222 echo '<div title="No data">&nbsp;</div>';
223 break;
224 }
225 echo '</td>';
226 }
227 echo "</tr>\n";
228 }
229 echo "</table></center>\n";
230}
231
232function renderNewObjectForm ()
233{
234 global $pageno, $tabno;
235
236 // Look for current submit.
237 if (isset ($_REQUEST['got_data']))
238 {
239 $log = array();
240 assertUIntArg ('object_type_id');
241 assertStringArg ('object_name', TRUE);
242 assertStringArg ('object_label', TRUE);
243 assertStringArg ('object_barcode', TRUE);
244 assertStringArg ('object_asset_no', TRUE);
245 $type_id = $_REQUEST['object_type_id'];
246 $name = $_REQUEST['object_name'];
247 $label = $_REQUEST['object_label'];
248 $asset_no = $_REQUEST['object_asset_no'];
249 $barcode = $_REQUEST['object_barcode'];
250
251 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
252 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
253 else
254 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderNewObjectForm()');
255 printLog ($log);
256 }
257
258 // Render a form for the next.
259 startPortlet ('Object attributes');
260 echo '<form>';
261 echo "<input type=hidden name=page value=${pageno}>";
262 echo "<input type=hidden name=tab value=${tabno}>";
263 echo '<table border=0 align=center>';
264 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
265 printSelect (getObjectTypeList(), 'object_type_id');
266 echo "</td></tr>\n";
267 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
268 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
269 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
270 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
271 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
272 echo '</form></table>';
273 finishPortlet();
274}
275
276function renderNewRackForm ($row_id)
277{
278 global $pageno, $tabno;
279
280 // Look for current submit.
281 if (isset ($_REQUEST['got_data']))
282 {
283 $log = array();
284 assertStringArg ('rack_name');
285 assertUIntArg ('rack_height');
286 assertStringArg ('rack_comment', TRUE);
287 $name = $_REQUEST['rack_name'];
288 $height = $_REQUEST['rack_height'];
289 $comment = $_REQUEST['rack_comment'];
290
291 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
292 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
293 else
294 $log[] = array ('code' => 'error', 'message' => 'commitAddRack() failed in renderNewRackForm()');
295 printLog ($log);
296 }
297
298 // Render a form for the next.
299 startPortlet ('Rack attributes');
300 echo '<form>';
301 echo "<input type=hidden name=page value=${pageno}>";
302 echo "<input type=hidden name=tab value=${tabno}>";
303 echo "<input type=hidden name=row_id value=${row_id}>";
304 echo '<table border=0 align=center>';
b901bf1f
DO
305 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
306 if ($defh == 0)
307 $defh = '';
a7bc8321 308 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
b901bf1f 309 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=rack_height tabindex=2 value='${defh}'></td></tr>\n";
4134b5c0 310 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
e673ee24
DO
311 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
312 echo '</form></table>';
313 finishPortlet();
314}
315
316function renderEditObjectForm ($object_id)
317{
318 showMessageOrError();
319 // Handle submit.
320 if (isset ($_REQUEST['got_data']))
321 {
322 $log = array();
323 // object_id is already verified by page handler
324 assertUIntArg ('object_type_id');
325 assertStringArg ('object_name', TRUE);
326 assertStringArg ('object_label', TRUE);
327 assertStringArg ('object_barcode', TRUE);
328 assertStringArg ('object_asset_no', TRUE);
329 $type_id = $_REQUEST['object_type_id'];
330 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
331 $has_problems = 'yes';
332 else
333 $has_problems = 'no';
334 $name = $_REQUEST['object_name'];
335 $label = $_REQUEST['object_label'];
336 $barcode = $_REQUEST['object_barcode'];
337 $asset_no = $_REQUEST['object_asset_no'];
338 $comment = $_REQUEST['object_comment'];
339
340 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
341 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
342 else
343 $log[] = array ('code' => 'error', 'message' => 'commitUpdateObject() failed in renderEditObjectForm()');
344 printLog ($log);
345 }
346
347 global $pageno, $tabno;
348 $object = getObjectInfo ($object_id);
349 if ($object == NULL)
350 {
351 showError ('getObjectInfo() failed in renderEditObjectForm()');
352 return;
353 }
354
355 // Render a form for the next submit;
356 echo '<table border=0 width=100%><tr>';
357
358 echo '<td class=pcleft>';
359 startPortlet ('Static attributes');
360 echo '<form>';
361 echo "<input type=hidden name=page value=${pageno}>";
362 echo "<input type=hidden name=tab value=${tabno}>";
363 echo "<input type=hidden name=object_id value=${object_id}>";
364 echo '<table border=0 align=center>';
365 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
366 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
367 echo "</td></tr>\n";
368 // Common attributes.
369 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
370 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
371 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
372 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
373 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
374 if ($object['has_problems'] == 'yes')
375 echo ' checked';
376 echo "></td></tr>\n";
377 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
378 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
379 echo '</form></table><br>';
380 finishPortlet();
381 echo '</td>';
382
383 // Optional attributes.
384 echo '<td class=pcright>';
385 startPortlet ('Optional attributes');
386 $values = getAttrValues ($object_id);
387 global $root;
388 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
389 echo "<tr><th>&nbsp;</th><th>Attribute</th><th>Value</th><th>&nbsp;</th></tr>\n";
0dfb8a2a
DO
390 echo "<form method=post action='${root}process.php'>\n";
391 echo "<input type=hidden name=page value=${pageno}>\n";
392 echo "<input type=hidden name=tab value=${tabno}>\n";
393 echo "<input type=hidden name=op value=upd>\n";
394 echo "<input type=hidden name=object_id value=${object_id}>\n";
395 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
396
397 $i = 0;
e673ee24
DO
398 foreach ($values as $record)
399 {
0dfb8a2a 400 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
e673ee24
DO
401 echo "<tr><td><a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
402 printImageHREF ('delete', 'Delete value');
403 echo "</a></td>";
404 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
405 switch ($record['type'])
406 {
407 case 'uint':
408 case 'float':
409 case 'string':
0dfb8a2a 410 echo "<input type=text name=${i}_value value='${record['value']}'>";
e673ee24
DO
411 break;
412 case 'dict':
413 $chapter = readChapter ($record['chapter_name']);
4c330a14 414 $chapter[0] = '-- NOT SET --';
0dfb8a2a 415 printSelect ($chapter, "${i}_value", $record['key']);
e673ee24
DO
416 break;
417 }
0dfb8a2a
DO
418 echo "</td></tr>\n";
419 $i++;
e673ee24 420 }
0dfb8a2a
DO
421 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
422 echo "</form>";
e673ee24
DO
423 echo "</table>\n";
424 finishPortlet();
425 echo '</td>';
426
427 echo '</tr><tr>';
428
429 echo '<td colspan=2>';
430 startPortlet ('history');
431 renderHistory ($pageno, $object_id);
432 finishPortlet();
433 echo '</td>';
434
435 echo '</tr></table>';
436}
437
438// This is a clone of renderEditObjectForm().
439function renderEditRackForm ($rack_id)
440{
441 // Handle submit.
442 if (isset ($_REQUEST['got_data']))
443 {
444 $log = array();
445 assertUIntArg ('rack_row_id');
446 assertUIntArg ('rack_height');
447 assertStringArg ('rack_name');
448 assertStringArg ('rack_comment', TRUE);
449 $row_id = $_REQUEST['rack_row_id'];
450 $height = $_REQUEST['rack_height'];
451 $name = $_REQUEST['rack_name'];
452 $comment = $_REQUEST['rack_comment'];
453
454 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
455 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
456 else
457 $log[] = array ('code' => 'error', 'message' => 'commitUpdateRack() failed in renderEditRackForm()');
458 printLog ($log);
459 }
460
461 global $pageno, $tabno;
462 $rack = getRackData ($rack_id);
463 if ($rack == NULL)
464 {
465 showError ('getRackData() failed in renderEditRackForm()');
466 return;
467 }
468
469 // Render a form for the next.
470 startPortlet ('Rack attributes');
471 echo '<form>';
472 echo "<input type=hidden name=page value=${pageno}>";
473 echo "<input type=hidden name=tab value=${tabno}>";
474 echo "<input type=hidden name=rack_id value=${rack_id}>";
475 echo '<table border=0 align=center>';
476 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
4c330a14 477 printSelect (readChapter ('RackRow'), 'rack_row_id', $rack['row_id']);
e673ee24
DO
478 echo "</td></tr>\n";
479 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name value='${rack['name']}'></td></tr>\n";
480 echo "<tr><th class=tdright>Height (required):</th><td class=tdleft><input type=text name=rack_height value='${rack['height']}'></td></tr>\n";
481 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment value='${rack['comment']}'></td></tr>\n";
482 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
483 echo '</form></table><br>';
484 finishPortlet();
485
486 startPortlet ('History');
487 renderHistory ($pageno, $rack_id);
488 finishPortlet();
489}
490
491// This is a helper for creators and editors.
492function printSelect ($rowList, $select_name, $selected_id = 1)
493{
494 echo "<select name=${select_name}>";
4c330a14 495 foreach ($rowList as $dict_key => $dict_value)
e673ee24 496 {
4c330a14
DO
497 echo "<option value=${dict_key}";
498 if ($dict_key == $selected_id)
e673ee24 499 echo ' selected';
4c330a14 500 echo ">${dict_value}</option>";
e673ee24
DO
501 }
502 echo "</select>";
503}
504
505// This is a universal editor of rack design/waste.
bb09cca0 506function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
e673ee24
DO
507{
508 if ($rack_id == 0)
509 {
510 showError ('Invalid rack_id in renderGridFrom()');
511 return;
512 }
513 if (($rackData = getRackData ($rack_id)) == NULL)
514 {
515 showError ('getRackData() failed in renderGridFrom()');
516 return;
517 }
518
519 global $root, $pageno, $tabno;
520 $filter($rackData);
521 markupObjectProblems ($rackData);
522
523 // Process form submit.
524 if (isset ($_REQUEST['do_update']))
525 {
526 $log[] = processGridForm ($rackData, $state1, $state2);
527 printLog($log);
528 }
529
530 // Render the result whatever it is.
531 // Main layout.
532 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
533 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
534
535 // Left column with information portlet.
536 echo "<tr><td class=pcleft height='1%' width='50%'>";
537 startPortlet ('Rack information');
538 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
539 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
540 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
541 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
542 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
543 echo "</table>\n";
544 finishPortlet();
545
546 echo "</td>\n";
bb09cca0 547 echo "<td class=pcright>";
e673ee24
DO
548
549 // Grid form.
550 startPortlet ($header);
551 echo "<center>\n";
552 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
553 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
554 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
555 echo "<form action='${root}?'>\n";
556 echo "<input type=hidden name=page value=${pageno}>\n";
557 echo "<input type=hidden name=tab value=${tabno}>\n";
558 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
559 markupAtomGrid ($rackData, $state2);
560 renderAtomGrid ($rackData);
561 echo "</table></center>\n";
562 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
563 finishPortlet();
bb09cca0 564 echo "</td></tr></table>\n";
e673ee24
DO
565}
566
567function renderRackDesign ($rack_id)
568{
bb09cca0 569 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
570}
571
572function renderRackProblems ($rack_id = 0)
573{
bb09cca0 574 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
575}
576
577function startPortlet ($title = '')
578{
579 echo "<div class=portlet><h2>${title}</h2>";
580}
581
582function finishPortlet ()
583{
584 echo "</div>\n";
585}
586
587function printRefsOfType ($refs, $type, $eq)
588{
589 global $root;
590 $gotone=0;
591 foreach ($refs as $ref)
592 {
593 if ($eq($ref['type'], $type))
594 {
595 if ($gotone) echo ', ';
4b2bf583
DO
596 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
597 if (!empty ($ref['name']))
598 echo $ref['name'] . '@';
599 echo "${ref['object_name']}</a>";
e673ee24
DO
600 $gotone=1;
601 }
602 }
603}
604
605function renderRackObject ($object_id = 0)
606{
607 global $root;
608 if ($object_id <= 0)
609 {
610 showError ('Invalid object_id in renderRackObject()');
611 return;
612 }
613 $info = getObjectInfo ($object_id);
614 if ($info == NULL)
615 {
616 showError ('getObjectInfo() failed in renderRackObject()');
617 return;
618 }
619 // Main layout starts.
620 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
621 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
622 // left column with uknown number of portlets
623 echo "<tr><td class=pcleft>";
624 startPortlet ('Object information');
625 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
626 if (!empty ($info['name']))
627 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
9c0b0016 628 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
a0ec6295 629 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
e673ee24
DO
630 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
631 if (!empty ($info['asset_no']))
632 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
a6305acc 633 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('REQUIRE_ASSET_TAG_FOR'))))
a0ec6295 634 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
e673ee24
DO
635 if (!empty ($info['label']))
636 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
637 if (!empty ($info['barcode']))
638 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
639 if ($info['has_problems'] == 'yes')
640 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
641 foreach (getAttrValues ($object_id) as $record)
642 if (!empty ($record['value']))
50a954f6 643 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['a_value']}</td></tr>\n";
e673ee24
DO
644 echo "</table><br>\n";
645 finishPortlet();
646
647 if (!empty ($info['comment']))
648 {
649 startPortlet ('Comment');
650 echo '<div class=commentblock>' . $info['comment'] . '</div>';
651 finishPortlet ();
652 }
653
654 $ports = getObjectPortsAndLinks ($object_id);
655 if (count ($ports))
656 {
657 startPortlet ('Ports and links');
658 usort($ports, 'sortByName');
659 if ($ports)
660 {
661 $hl_port_id = 0;
662 if (isset ($_REQUEST['hl_port_id']))
663 {
664 assertUIntArg ('hl_port_id');
665 $hl_port_id = $_REQUEST['hl_port_id'];
666 }
667 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
668 echo "<tr><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
669 echo "<th>Rem. Object</th><th>Rem. port</th></tr>\n";
670 foreach ($ports as $port)
671 {
672 echo '<tr';
673 if ($hl_port_id == $port['id'])
674 echo ' class=port_highlight';
675 echo "><td>${port['name']}</td><td>${port['label']}</td><td>${port['type']}</td>";
676 echo "<td>${port['l2address']}</td>";
677 if ($port['remote_object_id'])
678 {
679 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
680 echo "<td>${port['remote_name']}</td>";
681 }
682 elseif (!empty ($port['reservation_comment']))
683 {
684 echo "<td><b>Reserved;</b></td>";
685 echo "<td>${port['reservation_comment']}</td>";
686 }
687 else
688 echo '<td>&nbsp;</td><td>&nbsp;</td>';
689 echo "</tr>\n";
690 }
691 echo "</table><br>\n";
692 }
693 finishPortlet();
694 }
695 $addresses = getObjectAddresses ($object_id);
696 usort($addresses, 'sortAddresses');
697 if (count ($addresses))
698 {
f28fbe8b 699 startPortlet ('IPv4 addresses');
e673ee24
DO
700 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
701 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
702 foreach ($addresses as $addr)
703 {
704 if (strlen($addr['address_name'])>40)
705 $address_name = substr($addr['address_name'],0,38).'...';
706 else
707 $address_name = $addr['address_name'];
708
709 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
710 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
711 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
712 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
713
714 if ($addr['address_reserved']=='yes')
715 $class='trwarning';
716 elseif ($addr['type']!='virtual' && $regnum>0)
717 $class='trwarning';
718 elseif ($addr['type']=='regular' && $sharednum>0)
719 $class='trwarning';
720 else
721 $class='';
722
723 echo "<tr class='$class'><td>${addr['name']}</td><td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td>\n";
724
725 if ($addr['address_reserved']=='yes')
726 echo "<b>Reserved;</b> ";
727
728 if ($addr['type'] == 'virtual')
729 {
730 echo "<b>V</b>";
731 if ($notvirtnum > 0)
732 {
733 echo " Owners: ";
734 printRefsOfType($addr['references'], 'virtual', 'neq');
735 }
736 }
737 elseif ($addr['type'] == 'shared')
738 {
739 echo "<b>S</b>";
740 if ($sharednum > 0)
741 {
742 echo " Peers: ";
743 printRefsOfType($addr['references'], 'shared', 'eq');
744 echo ";";
745 }
746 if ($virtnum > 0)
747 {
748 echo " Virtuals: ";
749 printRefsOfType($addr['references'], 'virtual', 'eq');
750 echo ";";
751 }
752 if ($regnum > 0)
753 {
754 echo " Collisions: ";
755 printRefsOfType($addr['references'], 'regular', 'eq');
756 }
757
758 }
759 else
760 {
761 if ($virtnum > 0)
762 {
763 echo " Virtuals: ";
764 printRefsOfType($addr['references'], 'virtual', 'eq');
765 echo ";";
766 }
767 if ($notvirtnum > 0)
768 {
769 echo " Collisions: ";
770 printRefsOfType($addr['references'], 'virtual', 'neq');
771 }
772 }
773
774 echo "</td></tr>\n";
775 }
776 echo "</table><br>\n";
777 finishPortlet();
778 }
779
780 $forwards = getObjectForwards ($object_id);
781 if (count($forwards['in']) or count($forwards['out']))
782 {
f28fbe8b 783 startPortlet('NATv4');
e673ee24
DO
784
785 if (count($forwards['out']))
786 {
787
f28fbe8b 788 echo "<h3>locally performed NAT</h3>";
e673ee24
DO
789
790 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 791 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
792
793 foreach ($forwards['out'] as $pf)
794 {
795 $class='trwarning';
796 $name='';
797 foreach ($addresses as $addr)
798 if ($addr['ip'] == $pf['localip'])
799 {
800 $class='';
801 $name=$addr['name'];
802 break;
803 }
804
805 echo "<tr class='$class'>";
806
f28fbe8b 807 echo "<td>${pf['proto']}</td><td class=tdleft>${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
e673ee24 808
f28fbe8b 809 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
810
811 $address=getIPAddress($pf['remoteip']);
812
813 echo "<td class='description'>";
f28fbe8b
DO
814 if (count ($address['bonds']))
815 foreach($address['bonds'] as $bond)
816 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
817 elseif (!empty ($pf['remote_addr_name']))
818 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
819
820 echo "</td><td class='description'>${pf['description']}</td>";
821
822 echo "</tr>";
823 }
824 echo "</table><br><br>";
825 }
826 if (count($forwards['in']))
827 {
f28fbe8b 828 echo "<h3>arriving NAT connections</h3>";
e673ee24
DO
829
830 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 831 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
832
833 foreach ($forwards['in'] as $pf)
834 {
835 echo "<tr>";
836 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
837
838 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
839
840 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
841 echo "<td class='description'>${pf['description']}</td></tr>";
842 }
843
844 echo "</table><br><br>";
845 }
846 finishPortlet();
847 }
848
849 echo "</td>\n";
850
851 // After left column we have (surprise!) right column with rackspace portled only.
852 echo "<td class=pcright>";
853 // rackspace portlet
854 startPortlet ('Rackspace allocation');
855 // FIXME: now we call getRackData() twice
856 $racks = getResidentRacksData ($object_id);
857 foreach ($racks as $rackData)
858 renderRack ($rackData['id'], $object_id);
859 echo '<br>';
860 finishPortlet();
861 echo "</td></tr>";
862 echo "</table>\n";
863}
864
865function renderRackMultiSelect ($sname, $racks, $selected)
866{
9c0b0016 867 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
e673ee24
DO
868 foreach ($racks as $rack)
869 {
870 echo "<option value=${rack['id']}";
871 if (!(array_search ($rack['id'], $selected) === FALSE))
872 echo ' selected';
6a3a37b2 873 echo">${rack['row_name']}: ${rack['name']}</option>\n";
e673ee24
DO
874 }
875 echo "</select>\n";
876}
877
878function showMessageOrError ()
879{
880 if (isset($_REQUEST['message']))
881 echo "<div class=msg_success>${_REQUEST['message']}</div>";
882 if (isset($_REQUEST['error']))
883 echo "<div class=msg_error>${_REQUEST['error']}</div>";
884}
885
886// This function renders a form for port edition.
887function renderPortsForObject ($object_id = 0)
888{
889 global $root, $pageno, $tabno;
890 if ($object_id <= 0)
891 {
892 showError ('Invalid object_id in renderPortsForObject()');
893 return;
894 }
895 showMessageOrError();
896 startPortlet ('Ports and interfaces');
897 $ports = getObjectPortsAndLinks ($object_id);
898 usort($ports, 'sortByName');
899 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
900 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
901 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
902 foreach ($ports as $port)
903 {
904 echo "<form action='${root}process.php'>";
905 echo "<input type=hidden name=op value=editPort>";
906 echo "<input type=hidden name=page value='${pageno}'>\n";
907 echo "<input type=hidden name=tab value='${tabno}'>\n";
908 echo "<input type=hidden name=port_id value='${port['id']}'>";
909 echo "<input type=hidden name=object_id value='$object_id'>\n";
910 echo "<tr><td><a href='${root}process.php?op=delPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=${port['name']}'>";
911 printImageHREF ('delete', 'Unlink and Delete this port');
912 echo "</a></td>\n";
913 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
914 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
915 echo "<td>${port['type']}</td>\n";
916 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
917 if ($port['remote_object_id'])
918 {
919 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
920 echo "<td>${port['remote_name']}</td>";
921 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
922 echo urlencode ($port['name']);
923 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
924 printImageHREF ('unlink', 'Unlink this port');
925 echo "</a></td>";
926 }
927 elseif (!empty ($port['reservation_comment']))
928 {
929 echo "<td><b>Reserved;</b></td>";
930 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
931 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
932 printImageHREF ('useup', 'Use up this port');
933 echo "</a></td>";
934 }
935 else
936 {
937 echo "<td>&nbsp;</td><td>&nbsp;</td>";
938 echo "<td>";
939 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
940 echo urlencode ($port['name']);
941 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
942 printImageHREF ('link', 'Link this port');
943 echo "</a> <input type=text name=reservation_comment>";
944 echo "</td>\n";
945 }
946 echo "<td><input type='submit' value='OK'></td>";
947 echo "</form></tr>\n";
948 }
949 echo "<form action='${root}process.php'><tr>";
950 echo "<td colspan=2><input type=text size=10 name=port_name tabindex=100></td>\n";
951 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
952 echo "<input type=hidden name=op value=addPort>\n";
953 echo "<input type=hidden name=object_id value='${object_id}'>\n";
954 echo "<input type=hidden name=page value='${pageno}'>\n";
955 echo "<input type=hidden name=tab value='${tabno}'>\n";
956 echo "<td><select name='port_type_id' tabindex=102>\n";
957 $types = getPortTypes();
9c0b0016 958 $default_port_type = getConfigVar ('default_port_type');
e673ee24
DO
959 foreach ($types as $typeid => $typename)
960 {
961 echo "<option value='${typeid}'";
962 if ($typeid == $default_port_type)
963 echo " selected";
964 echo ">${typename}</option>\n";
965 }
966 echo "</select></td>";
967 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
968 echo "<td colspan=4><input type='submit' value='Add a new port' tabindex=104></td></tr></form>";
969 echo "</table><br>\n";
970 finishPortlet();
971
972 startPortlet ('Add/update multiple ports');
973 echo "<form action=${root}process.php method=post>";
974 echo "<input type=hidden name=page value='${pageno}'>\n";
975 echo "<input type=hidden name=tab value='${tabno}'>\n";
976 echo "<input type=hidden name=object_id value='${object_id}'>\n";
977 echo "<input type=hidden name=op value=addMultiPorts>";
978 echo 'Format: <select name=format>';
979 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
980 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
981 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
982 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
983 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
984 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
985 echo "</select>";
986 echo 'Default port type: ';
987 echo "<select name=port_type>\n";
988 foreach ($types as $typeid => $typename)
989 {
990 echo "<option value='${typeid}'";
991 if ($typeid == $default_port_type)
992 echo " selected";
993 echo ">${typename}</option>\n";
994 }
995 echo "</select>";
996 echo "<input type=submit value='Parse output'><br>\n";
997 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
998 echo '</form>';
999 finishPortlet();
1000}
1001
1002function renderNetworkForObject ($object_id=0)
1003{
1004 global $root, $pageno, $tabno;
1005 if ($object_id <= 0)
1006 {
1007 showError ('Invalid object_id in renderNetworkForObject()');
1008 return;
1009 }
1010 showMessageOrError();
1011 startPortlet ('Network Addresses');
1012 $addresses = getObjectAddresses ($object_id);
1013 usort($addresses, 'sortAddresses');
1014 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1015 echo "<tr><th>&nbsp;</th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th>&nbsp</th></tr>\n";
1016 foreach ($addresses as $addr)
1017 {
1018 if (strlen($addr['address_name'])>40)
1019 $address_name = substr($addr['address_name'],0,38).'...';
1020 else
1021 $address_name = $addr['address_name'];
1022
1023 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1024 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1025 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1026 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1027
1028 if ($addr['address_reserved']=='yes')
1029 $class='trwarning';
1030 elseif ($addr['type']!='virtual' && $regnum>0)
1031 $class='trwarning';
1032 elseif ($addr['type']=='regular' && $sharednum>0)
1033 $class='trwarning';
1034 else
1035 $class='';
1036
1037 echo "<form action='process.php'>";
1038 echo "<input type=hidden name=page value='${pageno}'>\n";
1039 echo "<input type=hidden name=tab value='${tabno}'>\n";
1040 echo "<input type=hidden name=op value=editAddressFromObject>";
1041 echo "<input type=hidden name=object_id value='$object_id'>";
1042 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1043 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1044 printImageHREF ('delete', 'Delete this IPv4 address');
1045 echo "</a></td>";
1046 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1047 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1048 echo "<td class='description'>$address_name</td>\n";
1049 echo "<td><select name='bond_type'>";
1050 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1051 {
1052 echo "<option value='$n'";
1053 if ($addr['type'] == $n)
1054 echo " selected";
1055 echo ">$v</option>";
1056 }
1057 echo "</td><td>";
1058 if ($addr['address_reserved']=='yes')
1059 echo "<b>Reserved</b>; ";
1060
1061 if ($addr['type'] == 'virtual')
1062 {
1063 if ($notvirtnum > 0)
1064 {
1065 echo " Owners: ";
1066 printRefsOfType($addr['references'], 'virtual', 'neq');
1067 }
1068 }
1069 elseif ($addr['type'] == 'shared')
1070 {
1071 if ($sharednum > 0)
1072 {
1073 echo " Peers: ";
1074 printRefsOfType($addr['references'], 'shared', 'eq');
1075 echo ";";
1076 }
1077 if ($virtnum > 0)
1078 {
1079 echo " Virtuals: ";
1080 printRefsOfType($addr['references'], 'virtual', 'eq');
1081 echo ";";
1082 }
1083 if ($regnum > 0)
1084 {
1085 echo " Collisions: ";
1086 printRefsOfType($addr['references'], 'regular', 'eq');
1087 }
1088
1089 }
1090 else
1091 {
1092 if ($virtnum > 0)
1093 {
1094 echo " Virtuals: ";
1095 printRefsOfType($addr['references'], 'virtual', 'eq');
1096 echo ";";
1097 }
1098 if ($notvirtnum > 0)
1099 {
1100 echo " Collisions: ";
1101 printRefsOfType($addr['references'], 'virtual', 'neq');
1102 }
1103 }
1104
1105 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1106 }
1107
1108
1109 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1110 echo "<input type=hidden name=page value='${pageno}'>\n";
1111 echo "<input type=hidden name=tab value='${tabno}'>\n";
1112 echo "<input type=hidden name=op value=addAddrFObj>\n";
1113 echo "<input type=hidden name=object_id value='$object_id'>\n";
1114
1115 echo "<td><input type=text name='ip' tabindex=101>\n";
1116 echo "</td><td><select name='type' tabindex=102>";
1117 echo "<option value='regular'>Regular</option>";
1118 echo "<option value='virtual'>Virtual</option>";
1119 echo "<option value='shared'>Shared</option>";
1120 echo "</select>";
1121 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1122 echo "</table><br>\n";
1123 finishPortlet();
1124
1125}
1126
1127function printLog ($log)
1128{
1129 foreach ($log as $record)
1130 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1131}
1132
1133/*
1134The following conditions must be followed:
11351. We can mount onto free atoms only. This means: if any record for an atom
1136already exists in RackSpace, it can't be used for mounting.
11372. We can't unmount from 'W' atoms. Operator should review appropriate comments
1138and either delete them before unmounting or refuse to unmount the object.
1139*/
1140
1141// We extensively use $_REQUEST in the function.
1142function renderRackSpaceForObject ($object_id = 0)
1143{
1144 if ($object_id <= 0)
1145 {
1146 showError ('Invalid object_id in renderRackSpaceForObject()');
1147 return;
1148 }
1149 $is_submit = isset ($_REQUEST['got_atoms']);
1150 $is_update = isset ($_REQUEST['rackmulti'][0]);
1151 $info = getObjectInfo ($object_id);
1152 if ($info == NULL)
1153 {
1154 showError ('getObjectInfo() failed in renderRackSpaceForObject()');
1155 return;
1156 }
1157 // Always process occupied racks plus racks chosen by user. First get racks with
1158 // already allocated rackspace...
1159 $workingRacksData = getResidentRacksData ($object_id);
1160 if ($workingRacksData === NULL)
1161 {
1162 print_r ($workingRacksData);
1163 showError ('getResidentRacksData() failed in renderRackSpaceForObject()');
1164 return;
1165 }
1166
1167 // ...and then add those chosen by user (if any).
1168 if ($is_update)
1169 foreach ($_REQUEST['rackmulti'] as $cand_id)
1170 {
1171 if (!isset ($workingRacksData[$cand_id]))
1172 {
1173 $rackData = getRackData ($cand_id);
1174 if ($rackData == NULL)
1175 {
1176 showError ('getRackData() failed in renderRackSpaceForObject()');
1177 return NULL;
1178 }
1179 $workingRacksData[$cand_id] = $rackData;
1180 }
1181 }
1182
1183 // Do it only once...
1184 foreach ($workingRacksData as &$rackData)
1185 applyObjectMountMask ($rackData, $object_id);
1186 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1187 unset ($rackData);
1188
1189 // Here we process form submit by trying to save all submitted info to database.
1190 if ($is_submit)
1191 {
1192 $oldMolecule = getMoleculeForObject ($object_id);
1193 $worldchanged = FALSE;
1194 $log = array();
1195 foreach ($workingRacksData as $rack_id => $rackData)
1196 {
1197 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1198 $log[] = $logrecord;
1199 if ($logrecord['code'] != 300)
1200 {
1201 $worldchanged = TRUE;
1202 // Reload our working copy after form processing.
1203 $rackData = getRackData ($rack_id);
1204 if ($rackData == NULL)
1205 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in renderRackSpaceForObject()');
1206 applyObjectMountMask ($rackData, $object_id);
1207 $workingRacksData[$rack_id] = $rackData;
1208 }
1209 }
1210 if ($worldchanged)
1211 {
1212 // Log a record.
1213 $newMolecule = getMoleculeForObject ($object_id);
1214 $oc = count ($oldMolecule);
1215 $nc = count ($newMolecule);
1216 $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
1217 $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
1218 global $remote_username;
1219 $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
1220 $query =
1221 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1222 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1223 global $dbxlink;
1224 $result = $dbxlink->query ($query);
1225 if ($result == NULL)
1226 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1227 else
1228 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1229 }
1230 printLog ($log);
1231 }
1232
1233 // This is the time for rendering.
1234 global $root, $pageno, $tabno;
1235 echo "<form id='racks' action='${root}'>";
1236 echo "<input type=hidden name=page value='${pageno}'>\n";
1237 echo "<input type=hidden name=tab value='${tabno}'>\n";
1238 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1239 // Main layout starts.
1240 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1241
1242 // Left portlet with rack list.
1243 echo "<td class=pcleft height='1%'>";
1244 startPortlet ('Racks');
1245 $allRacksData = getRacksForRow();
1246 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1247 echo "<br>";
1248 echo "<br>";
1249 finishPortlet();
1250 echo "</td>";
1251
1252 // Middle portlet with comment and submit.
1253 echo "<td class=pcleft>";
1254 startPortlet ('Comment');
1255 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1256 echo "<input type=submit value='Save' name=got_atoms>\n";
1257 echo "<br>";
1258 echo "<br>";
1259 finishPortlet();
1260 echo "</td>";
1261
1262 // Right portlet with rendered racks. If this form submit is not final, we have to
1263 // reflect the former state of the grid in current form.
1264 echo "<td class=pcright rowspan=2 height='1%'>";
1265 startPortlet ('Working copy');
1266 echo '<table border=0 cellspacing=10 align=center><tr>';
1267 foreach ($workingRacksData as $rack_id => $rackData)
1268 {
1269 // Order is important here: only original allocation is highlighted.
1270 highlightObject ($rackData, $object_id);
1271 markupAtomGrid ($rackData, 'T');
1272 // If we have a form processed, discard user input and show new database
1273 // contents.
1274 if (!$is_submit and $is_update)
1275 mergeGridFormToRack ($rackData);
1276 echo "<td valign=top>";
1277 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1278 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1279 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1280 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1281 renderAtomGrid ($rackData);
9b7468b7
DO
1282 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1283 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1284 echo "</table></center>\n";
1285 echo '</td>';
1286 }
1287 echo "</tr></table>";
1288 finishPortlet();
1289 echo "</td>\n";
1290
1291 echo "</form>\n";
1292 echo "</tr></table>\n";
1293}
1294
1295function renderMolecule ($mdata, $object_id)
1296{
1297 // sort data out
1298 $rackpack = array();
1299 global $loclist;
1300 foreach ($mdata as $dummy => $rua)
1301 {
1302 $rack_id = $rua['rack_id'];
1303 $unit_no = $rua['unit_no'];
1304 $atom = $rua['atom'];
1305 if (!isset ($rackpack[$rack_id]))
1306 {
1307 $rackData = getRackData ($rack_id);
1308 for ($i = $rackData['height']; $i > 0; $i--)
1309 for ($locidx = 0; $locidx < 3; $locidx++)
1310 $rackData[$i][$locidx]['state'] = 'F';
1311 $rackpack[$rack_id] = $rackData;
1312 }
1313 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1314 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1315 }
1316 // now we have some racks to render
1317 foreach ($rackpack as $dummy => $rackData)
1318 {
1319 markAllSpans ($rackData);
1320 echo "<table class=molecule cellspacing=0>\n";
1321 echo "<caption>${rackData['name']}</caption>\n";
1322 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1323 for ($i = $rackData['height']; $i > 0; $i--)
1324 {
1325 echo "<tr><th>$i</th>";
1326 for ($locidx = 0; $locidx < 3; $locidx++)
1327 {
1328 $state = $rackData[$i][$locidx]['state'];
1329 echo "<td class=state_${state}>&nbsp;</td>\n";
1330 }
1331 echo "</tr>\n";
1332 }
1333 echo "</table>\n";
1334 }
1335}
1336
1337function renderUnmountedObjectsPortlet ()
1338{
1339 startPortlet ('Unmounted objects');
1340 $objs = getUnmountedObjects();
1341 if ($objs === NULL)
1342 {
1343 showError ('getUnmountedObjects() failed in renderUnmountedObjectsPortlet()');
1344 return;
1345 }
1346 global $root, $nextorder;
1347 $order = 'odd';
1348 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1349 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1350 foreach ($objs as $obj)
1351 {
1352 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1353 echo "<td>${obj['label']}</td>";
18d94c29
DO
1354 echo "<td>${obj['asset_no']}</td>";
1355 echo "<td>${obj['barcode']}</td></tr>";
e673ee24
DO
1356 $order = $nextorder[$order];
1357 }
1358 echo "</table><br>\n";
1359 finishPortlet();
1360}
1361
1362function renderProblematicObjectsPortlet ()
1363{
1364 startPortlet ('Problematic objects');
1365 $objs = getProblematicObjects();
1366 if ($objs === NULL)
1367 {
1368 showError ('getProblematicObjects() failed in renderProblematicObjectsPortlet()');
1369 return;
1370 }
1371 global $root, $nextorder;
1372 $order = 'odd';
1373 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1374 echo '<tr><th>Type</th><th>Common name</th></tr>';
1375 foreach ($objs as $obj)
1376 {
1377 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1378 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1379 $order = $nextorder[$order];
1380 }
1381 echo "</table><br>\n";
1382 finishPortlet();
1383}
1384
1385function renderObjectGroupSummary ()
1386{
1387 global $root;
1388 $summary = getObjectGroupInfo();
1389 if ($summary === NULL)
1390 {
1391 showError ('getObjectGroupInfo() failed in renderObjectGroupSummary()');
1392 return;
1393 }
1394 echo "<table border=0 class=objectview>\n";
1395 echo "<tr><td class=pcleft width='25%'>";
1396
1397 startPortlet ('Summary');
1398 foreach ($summary as $gi)
1399 {
1400 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1401 }
1402 finishPortlet();
1403
1404 echo '</td><td class=pcright>';
1405 renderUnmountedObjectsPortlet();
1406 echo '</td><td class=pcright>';
1407 renderProblematicObjectsPortlet();
1408 echo "</td></tr></table>\n";
1409}
1410
1411function renderObjectGroup ($group_id = 0)
1412{
1413 global $root;
1414 $summary = getObjectGroupInfo();
1415 if ($summary == NULL)
1416 {
1417 showError ('getObjectGroupInfo() failed in renderObjectGroup()');
1418 return;
1419 }
1420 $objects = getObjectList ($group_id);
1421 if ($objects === NULL)
1422 {
1423 showError ('getObjectList() failed in renderObjectGroup()');
1424 return;
1425 }
1426 echo "<table border=0 class=objectview>\n";
1427 echo "<tr><td class=pcleft width='25%'>";
1428
1429 startPortlet ('All objects');
1430 foreach ($summary as $gi)
1431 {
1432 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1433 }
1434 finishPortlet();
1435
1436 echo '</td><td class=pcright>';
1437
1438 startPortlet ('Object group');
1439 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1440 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
e673ee24
DO
1441 $order = 'odd';
1442 global $nextorder;
1443 foreach ($objects as $obj)
1444 {
1445 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1446 echo "<td>${obj['label']}</td>";
1447 echo "<td>${obj['asset_no']}</td>";
18d94c29 1448 echo "<td>${obj['barcode']}</td>";
e673ee24
DO
1449 if ($obj['rack_id'])
1450 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1451 else
1452 echo '<td>Unmounted</td>';
1453 echo '</tr>';
1454 $order = $nextorder[$order];
1455 }
1456 echo '</table>';
1457 finishPortlet();
1458
1459 echo "</td></tr></table>";
1460}
1461
1462function renderEmptyPortsSelect ($port_id, $type_id)
1463{
1464 $ports = getEmptyPortsOfType($type_id);
1465 usort($ports, 'sortEmptyPorts');
1466 foreach ($ports as $port)
1467 {
1468 if ($port_id == $port['Port_id'])
1469 continue;
1470 echo "<option value='${port['Port_id']}' onclick='getElementById(\"remote_port_name\").value=\"${port['Port_name']}\"; getElementById(\"remote_object_name\").value=\"${port['Object_name']}\";'>${port['Object_name']} ${port['Port_name']}</option>\n";
1471 }
1472}
1473
1474function renderObjectAddressesAndNames ()
1475{
1476 $addresses = getObjectAddressesAndNames();
1477 usort($addresses, 'sortObjectAddressesAndNames');
1478 foreach ($addresses as $address)
1479 {
1480 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1481 }
1482}
1483
1484// History viewer for history-enabled simple dictionaries.
1485function renderHistory ($object_type, $object_id)
1486{
1487 switch ($object_type)
1488 {
1489 case 'row':
1490 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1491 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1492 $extra = 4;
1493 break;
1494 case 'rack':
1495 $query =
1496 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1497 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1498 "natural join Chapter " .
1499 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1500 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>is deleted?</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1501 $extra = 6;
1502 break;
1503 case 'object':
1504 $query =
1505 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1506 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1507 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1508 $header = '<tr><th>change time</th><th>author</th><th>common name</th><th>visible label</th><th>barcode</th><th>asset no</th><th>is deleted?</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
1509 $extra = 9;
1510 break;
1511 default:
1512 showError ("Uknown object type '${object_type}' in renderHistory()");
1513 return;
1514 }
1515 global $dbxlink;
1516 $result = $dbxlink->query ($query);
1517 if ($result == NULL)
1518 {
1519 showError ('SQL query failed in renderHistory()');
1520 return;
1521 }
1522 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1523 $order = 'odd';
1524 global $nextorder;
1525 echo $header;
1526 while ($row = $result->fetch (PDO::FETCH_NUM))
1527 {
1528 echo "<tr class=row_${order}><td>${row[0]}</td>";
1529 for ($i = 1; $i <= $extra; $i++)
1530 echo "<td>" . $row[$i] . "</td>";
1531 echo "</tr>\n";
1532 $order = $nextorder[$order];
1533 }
1534 echo "</table><br>\n";
1535}
1536
1537function renderRackspaceHistory ()
1538{
1539 global $root, $nextorder, $pageno, $tabno;
1540 $order = 'odd';
1541 $history = getRackspaceHistory();
1542 // Show the last operation by default.
1543 if (isset ($_REQUEST['op_id']))
1544 $op_id = $_REQUEST['op_id'];
1545 elseif (isset ($history[0]['mo_id']))
1546 $op_id = $history[0]['mo_id'];
1547 else $op_id = NULL;
1548
1549 $omid = NULL;
1550 $nmid = NULL;
1551 $object_id = 1;
1552 if ($op_id)
1553 list ($omid, $nmid) = getOperationMolecules ($op_id);
1554
1555 // Main layout starts.
1556 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1557
1558 // Left top portlet with old allocation.
1559 echo "<tr><td class=pcleft>";
1560 startPortlet ('Old allocation');
1561 if ($omid)
1562 {
1563 $oldMolecule = getMolecule ($omid);
1564 renderMolecule ($oldMolecule, $object_id);
1565 }
1566 else
1567 echo "nothing";
1568 finishPortlet();
1569
1570 echo '</td><td class=pcright>';
1571
1572 // Right top portlet with new allocation
1573 startPortlet ('New allocation');
1574 if ($nmid)
1575 {
1576 $newMolecule = getMolecule ($nmid);
1577 renderMolecule ($newMolecule, $object_id);
1578 }
1579 else
1580 echo "nothing";
1581 finishPortlet();
1582
1583 echo '</td></tr><tr><td colspan=2>';
1584
1585 // Bottom portlet with list
1586
1587 startPortlet ('Rackspace allocation history');
1588 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1589 echo "<tr><th>timestamp</th><th>author</th><th>rack object ID</th><th>rack object type</th><th>rack object name</th><th>comment</th></tr>\n";
1590 foreach ($history as $row)
1591 {
1592 if ($row['mo_id'] == $op_id)
1593 $class = 'hl';
1594 else
1595 $class = "row_${order}";
1596 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1597 echo "<td>${row['user_name']}</td>";
1598 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1599 echo "</tr>\n";
1600 $order = $nextorder[$order];
1601 }
1602 echo "</table>\n";
1603 finishPortlet();
1604
1605 echo '</td></tr></table>';
1606
1607}
1608
1609function renderAddressspace ()
1610{
1611 global $root;
1612 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1613 $addrspaceList = getAddressspaceList();
1614 echo "<tr><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1615 foreach ($addrspaceList as $iprange)
1616 {
1617 echo "<tr><td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1618 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1619 $range = getIPRange($iprange['id']);
1620 echo "/";
1621 echo count($range['addrlist']);
1622 echo "</td></tr>";
1623 }
1624 echo "</table>\n";
1625}
1626
1627function renderAddNewRange ()
1628{
1629 global $root, $pageno, $tabno;
1630 showMessageOrError();
2a201216
DY
1631
1632 echo "<center><h2>Add New Range</h2></center>\n";
1633 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
2dee289e 1634 echo "<tr><th>Address range</th><th>Name</th><th>C&gt;*</th><th>&nbsp;</th></tr>\n";
2a201216
DY
1635 echo "<form name='add_new_range' action='process.php'>\n";
1636 echo "<input type=hidden name=op value=addRange>\n";
1637 echo "<input type=hidden name=page value='${pageno}'>\n";
1638 echo "<input type=hidden name=tab value='${tabno}'>\n";
1639 echo "<tr><td class='tdcenter'><input type=text name='range' size=18 class='live-validate'></td>\n";
1640 echo "<td class='tdcenter'><input type=text name='name' size='20'></td>\n";
2dee289e 1641 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' checked></td>\n";
2a201216
DY
1642 echo "<td class='tdcenter'><input type=submit value='Add a new range'></td></tr>\n";
1643 echo "</form></table><br><br>\n";
1644
1645 echo "<center><h2>Existing Ranges</h2></center>\n";
1646 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
e673ee24
DO
1647 $addrspaceList = getAddressspaceList();
1648 echo "<tr><th>&nbsp;</th><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1649 foreach ($addrspaceList as $iprange)
1650 {
1651 $range = getIPRange($iprange['id']);
dc462202 1652 $usedips = count ($range['addrlist']);
e673ee24
DO
1653 echo "<tr>";
1654 if ($usedips == 0)
1655 {
1656 echo "<td><a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1657 printImageHREF ('delete', 'Delete this IP range');
1658 echo "</a></td>\n";
1659 }
1660 else
1661 echo "<td>&nbsp</td>";
1662 echo "<td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1663 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1664 echo "/";
1665 echo $usedips;
2a201216 1666 #echo "</td></tr></table>";
e673ee24
DO
1667 echo "</td></tr>";
1668 }
e673ee24
DO
1669}
1670
1671function renderIPRange ()
1672{
1673 global $root;
b901bf1f 1674 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
1675 $id = $_REQUEST['id'];
1676 if (isset($_REQUEST['pg']))
1677 $page = $_REQUEST['pg'];
1678 else
1679 $page=0;
1680
e673ee24
DO
1681 $range = getIPRange($id);
1682 echo "<center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></center>\n";
1683
e673ee24
DO
1684 $startip = $range['ip_bin'] & $range['mask_bin'];
1685 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
1686 $realstartip = $startip;
1687 $realendip = $endip;
1688 $numpages = 0;
1689 if($endip - $startip > $maxperpage)
1690 {
e673ee24
DO
1691 $numpages = ($endip - $startip)/$maxperpage;
1692 $startip = $startip + $page * $maxperpage;
1693 $endip = $startip + $maxperpage-1;
1694 }
1695 echo "<center>";
b901bf1f
DO
1696 if ($numpages)
1697 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
1698 for ($i=0; $i<$numpages; $i++)
1699 {
1700 if ($i == $page)
1701 echo "<b>$i</b> ";
1702 else
1703 echo "<a href='${root}?page=iprange&id=$id&pg=$i'>$i</a> ";
1704 }
1705 echo "</center>";
1706
1707 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
1708 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
1709
1710
1711 for($ip = $startip; $ip<=$endip; $ip++)
1712 {
dcee8072 1713 if (isset ($range['addrlist'][$ip]))
e673ee24
DO
1714 {
1715 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
1716 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
1717 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
1718
1719 $addr = $range['addrlist'][$ip];
1720 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1721 echo "<tr class='trwarning'>";
1722 elseif ( $addr['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1723 echo "<tr class='trwarning'>";
1724 elseif ( $addr['reserved'] == 'yes')
1725 echo "<tr class='trbusy'>";
1726 elseif ( $numshared > 0 || $numreg > 0)
1727 echo "<tr class='trbusy'>";
1728 else
1729 echo "<tr>";
1730
1731 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
1732 if ( $addr['reserved'] == 'yes')
1733 echo "<b>Reserved;</b> ";
1734 foreach ($range['addrlist'][$ip]['references'] as $ref)
1735 {
db88e2de
DO
1736 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
1737 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
1738 echo "${ref['object_name']}</a>; ";
e673ee24
DO
1739 }
1740 echo "</td></tr>\n";
1741 }
1742 else
1743 {
1744 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
1745 }
1746 }
1747
1748 echo "</table>";
1749
1750}
1751
1752function renderIPRangeProperties ()
1753{
1754 global $pageno, $tabno;
1755 $id = $_REQUEST['id'];
1756 showMessageOrError();
1757 $range = getIPRange($id);
1758 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
1759 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1760 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
1761 echo "<input type=hidden name=page value='${pageno}'>\n";
1762 echo "<input type=hidden name=tab value='${tabno}'>\n";
1763 echo "<input type=hidden name=id value='${id}'>";
1764 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${range['name']}'></tr><tr><td colspan=2 class='tdcenter'><input type=submit value='Update range'></td></form></tr>";
1765 echo "</table>\n";
1766
1767}
1768
1769function renderIPAddress ()
1770{
1771 global $root;
1772 $ip = $_REQUEST['ip'];
1773 $address = getIPAddress($ip);
1774 echo "<center><h1>$ip</h1>";
1775 if ($address['exists'] == 1)
1776 echo "<h2>${address['name']}</h2>";
1777 echo "</center>\n";
1778
1779// echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
1780// echo "<tr valign='top'><td>";
1781
1782 startPortlet ('Address assignment');
1783 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1784 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
1785
1786 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1787 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1788 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1789
1790
1791 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1792 $class='trwarning';
1793 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1794 $class='trwarning';
1795 else
1796 $class='';
1797
1798
1799
1800 if ($address['reserved'] == 'yes')
1801 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
1802 foreach ($address['bonds'] as $bond)
1803 {
1804 echo "<tr class='$class'><td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td><td>${bond['name']}</td><td><b>";
1805 switch ($bond['type'])
1806 {
1807 case 'virtual':
1808 echo "Virtual";
1809 break;
1810 case 'shared':
1811 echo "Shared";
1812 break;
1813 case 'regular':
1814 echo "Regular";
1815 break;
1816 }
1817 echo "</b></td></tr>\n";
1818 }
1819 echo "</table><br><br>";
1820 finishPortlet();
1821
1822// echo "</td><td>";
1823// echo "</td></tr></table>";
1824}
1825
1826function renderIPAddressProperties ()
1827{
1828 global $pageno, $tabno;
1829 $ip = $_REQUEST['ip'];
1830 showMessageOrError();
1831 $address = getIPAddress($ip);
1832 echo "<center><h1>$ip</h1></center>\n";
1833 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1834 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
1835 echo "<input type=hidden name=page value='${pageno}'>\n";
1836 echo "<input type=hidden name=tab value='${tabno}'>\n";
1837 echo "<input type=hidden name=ip value='${ip}'>";
1838 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?$address['name']:'')."'></tr>";
1839 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?(($address['reserved']=='yes')?'checked':''):'')."></tr>";
1840 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
1841 echo "</table>\n";
1842
1843}
1844
1845function renderIPAddressAssignment ()
1846{
1847 global $pageno, $tabno, $root;
1848 $ip = $_REQUEST['ip'];
1849 $address = getIPAddress($ip);
1850
1851 showMessageOrError();
1852 echo "<center><h1>$ip</h1></center>\n";
1853
1854
1855 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1856 echo "<tr><th>&nbsp;</th><th>Object name</th><th>Interface name</th><th>Interface type</th><th>&nbsp;</th></tr>\n";
1857
1858 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1859 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1860 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1861
1862
1863 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1864 $class='trwarning';
1865 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1866 $class='trwarning';
1867 else
1868 $class='';
1869
1870
1871
1872 if ($address['reserved'] == 'yes')
1873 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
1874 foreach ($address['bonds'] as $bond)
1875 {
1876 echo "<tr class='$class'><form action='process.php'>";
1877 echo "<input type=hidden name=op value='editBondForAddress'>";
1878 echo "<input type=hidden name=page value='${pageno}'>";
1879 echo "<input type=hidden name=tab value='${tabno}'>";
1880 echo "<input type=hidden name=ip value='$ip'>";
1881 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
1882 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
1883 printImageHREF ('delete', 'Unallocate address');
1884 echo "</a></td>";
1885 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
1886 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
1887 echo "<td><select name='bond_type'>";
1888 switch ($bond['type'])
1889 {
1890 case 'virtual':
1891 echo "<option value='regular'>Regular</option>";
1892 echo "<option value='virtual' selected>Virtual</option>";
1893 echo "<option value='shared'>Shared</option>";
1894 break;
1895 case 'shared':
1896 echo "<option value='regular'>Regular</option>";
1897 echo "<option value='virtual'>Virtual</option>";
1898 echo "<option value='shared' selected>Shared</option>";
1899 break;
1900 case 'regular':
1901 echo "<option value='regular' selected>Regular</option>";
1902 echo "<option value='virtual'>Virtual</option>";
1903 echo "<option value='shared'>Shared</option>";
1904 break;
1905 }
1906 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
1907 }
1908 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
1909 echo "<input type=hidden name=page value='${pageno}'>\n";
1910 echo "<input type=hidden name=tab value='${tabno}'>\n";
1911 echo "<input type='hidden' name='ip' value='$ip'>";
1912 echo "<td colspan=2><select name='object_id'>";
1913
1914 foreach (array(1, 4, 7, 8, 12, 14) as $type)
1915 {
1916 //get all Balck Boxes, Servers, Routers, Switches, UPS, Modems
1917 $objects = getObjectList($type);
1918 foreach ($objects as $object)
1919 echo "<option value='${object['id']}'>${object['dname']}</option>";
1920 }
1921
1922 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
1923 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
1924 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
1925 echo "</table><br><br>";
1926
1927}
1928
1929function renderIPAddressPortForwarding ($object_id=0)
1930{
1931 global $pageno, $tabno, $root;
1932
1933 $info = getObjectInfo ($object_id);
1934 $forwards = getObjectForwards ($object_id);
1935 $addresses = getObjectAddresses ($object_id);
1936 showMessageOrError();
f28fbe8b 1937 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24
DO
1938
1939 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1940 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
e673ee24
DO
1941
1942 foreach ($forwards['out'] as $pf)
1943 {
1944 $class='trwarning';
1945 $name='';
1946 foreach ($addresses as $addr)
1947 if ($addr['ip'] == $pf['localip'])
1948 {
1949 $class='';
1950 $name = $addr['name'];
1951 break;
1952 }
1953
1954 echo "<tr class='$class'>";
1955 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=$object_id&page=${pageno}&tab=${tabno}'><img src='${root}/pix/delete_s.gif' title='Delete port forwarding' border=0 width=16 height=16></a></td>";
f28fbe8b
DO
1956 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
1957 if (!empty ($pf['local_addr_name']))
1958 echo ' (' . $pf['local_addr_name'] . ')';
1959 echo "</td>";
e673ee24
DO
1960 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1961
1962 $address=getIPAddress($pf['remoteip']);
1963
1964 echo "<td class='description'>";
f28fbe8b
DO
1965 if (count ($address['bonds']))
1966 foreach($address['bonds'] as $bond)
1967 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
1968 elseif (!empty ($pf['remote_addr_name']))
1969 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
1970 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'><input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'><input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'><input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'><input type='hidden' name='proto' value='${pf['proto_bin']}'><td class='description'><input type='text' name='description' value='${pf['description']}'> <input type='submit' value='OK'></td></form>";
1971 echo "</tr>";
1972 }
1973 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
1974 echo "<input type='hidden' name='object_id' value='$object_id'>";
1975 echo "<input type=hidden name=page value='${pageno}'>\n";
1976 echo "<input type=hidden name=tab value='${tabno}'>\n";
1977 echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option></select><select name='localip'>";
1978
1979 foreach ($addresses as $addr)
09992c16
DO
1980 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}: ") .
1981 "${addr['ip']}" . (empty ($addr['address_name']) ? '' : " (${addr['address_name']})") . "</option>";
e673ee24
DO
1982
1983 echo "</select>:<input type='text' name='localport' size='4'></td><td><input type='text' name='remoteip' id='remoteip' size='10'>";
1984 echo "<a href='javascript:;' onclick='window.open(\"${root}/find_object_ip_helper.php\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'><img src='${root}/pix/find.png' title='Find object' border=0 height=16 width=16></a>";
1985 echo ":<input type='text' name='remoteport' size='4'></td><td></td><td colspan=1><input type='text' name='description' size='20'> <input type='submit' value='Create Forwarding'></td></tr>";
1986 echo "</form>";
1987
1988 echo "</table><br><br>";
1989
1990
f28fbe8b 1991 echo "<center><h2>arriving NAT connections</h2></center>";
e673ee24
DO
1992 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1993 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
1994
1995 foreach ($forwards['in'] as $pf)
1996 {
1997 echo "<tr>";
1998
1999 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'><img src='${root}/pix/delete_s.gif' title='Delete port forwarding' border=0 width=16 height=16></a></td>";
2000 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2001 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2002 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2003 echo "<td class='description'>${pf['description']}</td></tr>";
2004 }
2005
2006// echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2007// echo "<input type='hidden' name='object_id' value='$object_id'>";
2008// echo "<input type=hidden name=page value='${pageno}'>\n";
2009// echo "<input type=hidden name=tab value='${tabno}'>\n";
2010// echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option><input type='text' name='localip' size='10'>:<input type='text' name='localport' size='4'></td><td><select name='localip'>";
2011// foreach ($addresses as $addr)
2012// echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2013//
2014// echo "</select>:<input type='text' name='remoteport' size='4'></td><td><input type='text' name='description' size='20'></td><td><input type='submit' value='Create Forwarding'></td></tr>";
2015// echo "</form>";
2016 echo "</table><br><br>";
2017
2018
2019}
2020
2021
2022function renderAddMultipleObjectsForm ()
2023{
2024 global $pageno, $tabno, $nextorder;
2025
2026 $type_id = array();
7f791d1d 2027 $global_type_id = 0;
e673ee24
DO
2028 $name = array();
2029 $asset_no = array();
2030 $keepvalues = FALSE;
7f791d1d 2031 $log = array();
e673ee24 2032 // Look for current submit.
7f791d1d 2033 if (isset ($_REQUEST['got_fast_data']))
e673ee24
DO
2034 {
2035 $keepvalues = TRUE;
9c0b0016
DO
2036 $max = getConfigVar ('MASSCOUNT');
2037 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2038 {
2039 if (!isset ($_REQUEST["${i}_object_type_id"]))
2040 {
2041 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2042 break;
2043 }
2044 assertUIntArg ("${i}_object_type_id", TRUE);
2045 assertStringArg ("${i}_object_name", TRUE);
2046 assertStringArg ("${i}_object_label", TRUE);
2047 assertStringArg ("${i}_object_asset_no", TRUE);
2048 assertStringArg ("${i}_object_barcode", TRUE);
2049 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2050 // Save user input for possible rendering.
2051 $name[$i] = $_REQUEST["${i}_object_name"];
2052 $label[$i] = $_REQUEST["${i}_object_label"];
2053 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2054 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2055
2056 // It's better to skip silently than printing a notice.
2057 if ($type_id[$i] == 0)
2058 continue;
2059 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2060 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2061 else
2062 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderAddMultipleObjectsForm()');
2063 }
e673ee24 2064 }
7f791d1d
DO
2065 elseif (isset ($_REQUEST['got_very_fast_data']))
2066 {
2067 $keepvalues = TRUE;
2068 assertUIntArg ('global_type_id', TRUE);
2069 assertStringArg ('namelist', TRUE);
2070 $global_type_id = $_REQUEST['global_type_id'];
2071 if ($global_type_id == 0)
2072 {
2073 if (!empty ($_REQUEST['namelist']))
2074 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2075 else
2076 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2077 }
2078 else
2079 {
2080 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2081 $names1 = explode ('\n', $_REQUEST['namelist']);
2082 $names2 = array();
2083 foreach ($names1 as $line)
2084 {
2085 $parts = explode ('\r', $line);
2086 reset ($parts);
2087 if (empty ($parts[0]))
2088 continue;
2089 else
2090 $names2[] = rtrim ($parts[0]);
2091 }
2092 foreach ($names2 as $cname)
2093 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2094 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2095 else
2096 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2097 }
2098 }
2099 printLog ($log);
e673ee24
DO
2100
2101 // Render a form for the next.
2102 $typelist = getObjectTypeList();
4c330a14 2103 $typelist[0] = 'select type...';
7f791d1d
DO
2104
2105 startPortlet ('Fast way');
e673ee24
DO
2106 echo '<form>';
2107 echo "<input type=hidden name=page value=${pageno}>";
2108 echo "<input type=hidden name=tab value=${tabno}>";
2109 echo '<table border=0 align=center>';
2110 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
7f791d1d 2111 // If a user forgot to select object type on input, we keep his
e673ee24 2112 // previous input in the form.
9c0b0016
DO
2113 $max = getConfigVar ('MASSCOUNT');
2114 for ($i = 0; $i < $max; $i++)
e673ee24 2115 {
7f791d1d 2116 echo '<tr><td>';
e673ee24
DO
2117 printSelect ($typelist, "${i}_object_type_id", 0);
2118 echo '</td>';
2119 echo "<td><input type=text size=30 name=${i}_object_name";
2120 if ($keepvalues and $type_id[$i] == 0)
2121 echo " value='${name[$i]}'";
2122 echo "></td>";
2123 echo "<td><input type=text size=30 name=${i}_object_label";
2124 if ($keepvalues and $type_id[$i] == 0)
2125 echo " value='${label[$i]}'";
2126 echo "></td>";
2127 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2128 if ($keepvalues and $type_id[$i] == 0)
2129 echo " value='${asset_no[$i]}'";
2130 echo "></td>";
2131 echo "<td><input type=text size=10 name=${i}_object_barcode";
2132 if ($keepvalues and $type_id[$i] == 0)
2133 echo " value='${barcode[$i]}'";
2134 echo "></td>";
2135 echo "</tr>\n";
e673ee24 2136 }
7f791d1d 2137 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
e673ee24
DO
2138 echo "</form></table>\n";
2139 finishPortlet();
7f791d1d
DO
2140
2141 startPortlet ('Very fast way');
2142 echo '<form>';
2143 echo "<input type=hidden name=page value=${pageno}>";
2144 echo "<input type=hidden name=tab value=${tabno}>";
2145 echo 'For each line shown below create an object of type ';
2146 printSelect ($typelist, "global_type_id", 0);
2147 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2148 echo "<textarea name=namelist cols=40 rows=25>\n";
2149 if ($keepvalues and $global_type_id == 0)
2150 echo $_REQUEST['namelist'];
2151 echo "</textarea></form>\n";
2152 finishPortlet();
e673ee24
DO
2153}
2154
2155function printGreeting ()
2156{
59cd003e 2157 global $remote_username, $accounts, $root;
e673ee24 2158 $account = $accounts[$remote_username];
4eb5efb7 2159 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2160}
2161
2162function renderSearchResults ()
2163{
2164 global $remote_username, $root;
2165 $terms = trim ($_REQUEST['q']);
2166 if (empty ($terms))
2167 {
2168 showError ('Search string cannot be empty.');
2169 return;
2170 }
2171 if (!authorized ($remote_username, 'object', 'default'))
2172 {
2173 showError ('You are not authorized for viewing information about objects.');
2174 return;
2175 }
2176 // If we search for L2 address, we can either find one or find none.
2177 if
2178 (
2179 preg_match ('/^[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?:[0-9a-f][0-9a-f]?$/i', $terms) or
2180 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms) or
2181 preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms)
2182 )
2183 // Search for L2 address.
2184 {
2185 $result = searchByl2address ($terms);
2186 if ($result !== NULL)
2187 {
2188 echo "<script language='Javascript'>document.location='${root}?page=object";
2189 echo "&hl_port_id=${result['port_id']}";
2190 echo "&object_id=${result['object_id']}';//</script>";
2191 }
2192 else
2193 echo "L2 address '${terms}' not found!";
2194 }
2195 elseif (preg_match ('/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i', $terms))
2196 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2197 {
2198 $terms = substr ($terms, 4);
2199 $result = searchByl2address ($terms);
2200 if ($result !== NULL)
2201 {
2202 echo "<script language='Javascript'>document.location='${root}?page=object";
2203 echo "&hl_port_id=${result['port_id']}";
2204 echo "&object_id=${result['object_id']}';//</script>";
2205 }
2206 else
2207 echo "L2 address '${terms}' not found!";
2208 }
2209 elseif (preg_match ('/^[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9]?[0-9]?[0-9]?$/i', $terms))
2210 // Search for IP address.
2211 {
2212 $result = getRangeByIp ($terms);
2213 if ($result !== NULL)
2214 {
2215 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2216 echo "&ip=${terms}";
2217 echo "';//</script>";
2218 }
2219 else
2220 echo "IP address '${terms}' not found!";
2221 return;
2222 }
2223 else
2224 // Search for objects.
2225 {
2226 $objects = getSearchResults ($terms);
2227 if (count ($objects) == 1)
2228 {
2229 $obj = current ($objects);
2230 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${obj['id']}';//</script>";
2231 }
2232 elseif (count ($objects) > 1)
2233 {
2234 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2235 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2236 $order = 'odd';
2237 global $nextorder;
2238 foreach ($objects as $obj)
2239 {
2240 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2241 echo "<td>${obj['label']}</td>";
2242 echo "<td>${obj['asset_no']}</td>";
2243 echo "<td>${obj['barcode']}</td></tr>";
2244 $order = $nextorder[$order];
2245 }
2246 echo '</table>';
2247 }
2248 else
2249 echo "Object '${terms}' not found!";
2250 }
2251}
2252
2253// This function prints a table of checkboxes to aid the user in toggling mount atoms
2254// from one state to another. The first argument is rack data as
2255// produced by getRackData(), the second is the value used for the 'unckecked' state
2256// and the third is the value used for 'checked' state.
2257// Usage contexts:
2258// for mounting an object: printAtomGrid ($data, 'F', 'T')
2259// for changing rack design: printAtomGrid ($data, 'A', 'F')
2260// for adding rack problem: printAtomGrid ($data, 'F', 'U')
2261// for adding object problem: printAtomGrid ($data, 'T', 'W')
2262
2263function renderAtomGrid ($data)
2264{
2265 $rack_id = $data['id'];
2266 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2267 {
2268 echo "<tr><th>${unit_no}</th>";
2269 for ($locidx = 0; $locidx < 3; $locidx++)
2270 {
2271 $state = $data[$unit_no][$locidx]['state'];
2272 echo "<td class=state_${state}";
2273 if (isset ($data[$unit_no][$locidx]['hl']))
2274 echo $data[$unit_no][$locidx]['hl'];
2275 echo ">";
2276 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2277 echo '<input type=checkbox disabled>';
2278 else
2279 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2280 echo '</td>';
2281 }
2282 echo "</tr>\n";
2283 }
2284}
2285
2286function renderPermissions ()
2287{
2288 startPortlet ('User permissions');
2289 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2290 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2291 global $perms, $nextorder;
2292 $order = 'odd';
2293 foreach ($perms as $username => $pages)
2294 foreach ($pages as $page => $tabs)
2295 foreach ($tabs as $tab => $access)
2296 {
2297 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2298 $order = $nextorder[$order];
2299 }
2300 echo "</table>\n";
2301 finishPortlet();
2302}
2303
2304function renderAccounts ()
2305{
2306 global $nextorder, $accounts;
2307 startPortlet ('User accounts');
2308 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2309 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2310 $order = 'odd';
2311 foreach ($accounts as $user)
2312 {
2313 echo "<tr class=row_${order}><td class=tdleft>${user['user_name']}</td><td class=tdleft>${user['user_realname']}</td></li>";
2314 $order = $nextorder[$order];
2315 }
2316 echo '</table>';
2317 finishPortlet();
2318}
2319
2320function renderAccountsEditForm ()
2321{
2322 global $root, $pageno, $tabno, $accounts;
2323 startPortlet ('User accounts');
2324 showMessageOrError();
2325 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2326 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2327 foreach ($accounts as $account)
2328 {
2329 echo "<form action='${root}process.php'>";
2330 echo "<input type=hidden name=op value=updateAccount>";
2331 echo "<input type=hidden name=page value='${pageno}'>\n";
2332 echo "<input type=hidden name=tab value='${tabno}'>\n";
2333 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2334 echo "<td>";
2335 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2336 {
2337 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2338 printImageHREF ('blockuser', 'disable account');
2339 echo "</a>\n";
2340 }
2341 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2342 {
2343 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2344 printImageHREF ('unblockuser', 'enable account');
2345 echo "</a>\n";
2346 }
2347 // Otherwise skip icon.
2348 echo "</td>";
2349 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2350 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2351 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2352 echo "<td><input type='submit' value='OK'></td>";
2353 echo "</form></tr>\n";
2354 }
2355 echo "<form action='${root}process.php' method=post><tr>";
2356 echo "<input type=hidden name=op value=createAccount>\n";
2357 echo "<input type=hidden name=page value='${pageno}'>\n";
2358 echo "<input type=hidden name=tab value='${tabno}'>\n";
2359 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2360 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2361 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2362 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2363 echo "</table><br>\n";
2364 finishPortlet();
2365}
2366
2367function printChildrenAsOptions ($root, $depth = 0)
2368{
2369 echo "<option value=${root['title']}>";
2370 if ($depth == 0)
2371 echo '* ';
2372 for ($i = 0; $i < $depth; $i++)
2373 echo '-- ';
2374 echo $root['title'];
2375 echo "</option>\n";
2376 foreach ($root['kids'] as $kid)
2377 printChildrenAsOptions ($kid, $depth + 1);
2378}
2379
2380// 1. Find all parentless pages.
2381// 2. For each of them recursively find all children.
2382// 3. Output the tree with recursion tree display.
2383function printPagesTree ()
2384{
2385 global $page;
2386 echo '<pre>';
2387 foreach ($page as $ctitle => $cpage)
2388 if (!isset ($cpage['parent']))
2389 {
2390 $croot['title'] = $ctitle;
2391 $croot['kids'] = getAllChildPages ($ctitle);
2392 printChildrenAsOptions ($croot);
2393 }
2394 echo '</pre>';
2395}
2396
2397function renderPermissionsEditForm ()
2398{
2399 global $root, $pageno, $tabno, $perms, $accounts;
2400 startPortlet ('User permissions');
2401 showMessageOrError();
2402 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2403 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2404 foreach ($perms as $username => $pages)
2405 foreach ($pages as $access_page => $tabs)
2406 foreach ($tabs as $access_tab => $access)
2407 {
2408 echo "<td>";
2409 if ($username != '%')
2410 $userid = $accounts[$username]['user_id'];
2411 else
2412 $userid = 0;
2413 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2414 printImageHREF ('revoke', 'Revoke permission');
2415 echo "</a></td>";
2416 echo "<td>${username}</td>";
2417 echo "<td>${access_page}</td>";
2418 echo "<td>${access_tab}</td>";
2419 echo "<td>${access}</td>";
2420 echo "</tr>\n";
2421 }
2422 echo "<form action='${root}process.php' method=post><tr>";
2423 echo "<input type=hidden name=op value=grant>\n";
2424 echo "<input type=hidden name=page value='${pageno}'>\n";
2425 echo "<input type=hidden name=tab value='${tabno}'>\n";
2426 // FIXME: border=0 doesn't work here for unknown reason
2427 echo "<td>";
a5ae8c2a 2428 printImageHREF ('grant', '', TRUE, 103);
e673ee24
DO
2429 echo "</td>";
2430 echo "<td><select name=access_userid>";
2431 echo "<option value=0>ANY</option>";
2432 foreach ($accounts as $account)
2433 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2434 echo "</select></td>\n";
2435 echo "<td><select name=access_page>";
2436 echo "<option value='%'>ANY</option>";
2437 printPagesTree();
2438 echo "</select></td>";
2439 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2440 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2441 echo "</tr></form>";
2442 echo "</table><br>\n";
2443 finishPortlet();
2444}
2445
e673ee24
DO
2446function renderPortMap ($editable = FALSE)
2447{
2448 global $nextorder, $root, $pageno, $tabno;
2449 showMessageOrError();
2450 startPortlet ("Port compatibility map");
2451 $ptlist = getPortTypes();
2452 $pclist = getPortCompat();
2453 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2454 if ($editable)
2455 {
2456 echo "<form method=post action='${root}process.php'>";
2457 echo "<input type=hidden name=page value='${pageno}'>";
2458 echo "<input type=hidden name=tab value='${tabno}'>";
2459 echo "<input type=hidden name=op value=save>";
2460 }
2461 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2462 echo "<tr><th class=vert_th>&nbsp;</th>";
2463 foreach ($ptlist as $name2)
2464 echo "<th>to ${name2}</th>";
2465 echo "</tr>";
2466 // Make a copy to have an independent array pointer.
2467 $ptlistY = $ptlist;
2468 $order = 'odd';
2469 foreach ($ptlistY as $type1 => $name1)
2470 {
2471 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2472 foreach ($ptlist as $type2 => $name2)
2473 {
2474 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
2475 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
2476 }
2477 echo "</tr>\n";
2478 $order = $nextorder[$order];
2479 }
2480 echo '</table><br>';
2481 if ($editable)
2482 {
2483 echo "<input type=submit value='Save changes'>";
2484 echo "</form>";
2485 }
2486 finishPortlet();
2487}
2488
2489function renderConfigMainpage ()
2490{
2491 global $pageno, $root;
2492 $children = getDirectChildPages ($pageno);
2493 echo '<ul>';
2494 foreach ($children as $cpageno => $child)
2495 {
2496 $ctitle = $child['title']($cpageno);
2497 echo "<li><a href='${root}?page=${cpageno}'>" . $ctitle['name'] . "</li>\n";
2498 }
2499 echo '';
2500 echo '</ul>';
2501}
2502
2503function renderRackPage ($rack_id)
2504{
2505 if ($rack_id == 0)
2506 {
2507 showError ('Invalid rack_id in renderRack()');
2508 return;
2509 }
2510 if (($rackData = getRackData ($rack_id)) == NULL)
2511 {
2512 showError ('getRackData() failed in renderRack()');
2513 return;
2514 }
2515 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2516
2517 // Left column with information.
2518 echo "<td class=pcleft>";
2519 startPortlet ('Rack information');
2520 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2521 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2522 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2523 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
2524 if (!empty ($rackData['comment']))
2525 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2526 echo '</table>';
2527 finishPortlet();
2528 echo '</td>';
2529
2530 // Right column with rendered rack.
2531 echo '<td>';
2532 startPortlet ('Rack diagram');
2533 renderRack ($rack_id);
2534 finishPortlet();
2535 echo '</td>';
2536
2537 echo '</tr></table>';
2538}
2539
2540function renderDictionary ()
2541{
2542 global $nextorder;
2543 $dict = getDict();
2544 echo "<table border=0><tr>";
2545 foreach ($dict as $chapter)
2546 {
2547 echo "<td class=pcleft>";
2548 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2549 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2550 $order = 'odd';
cfadde04 2551 foreach ($chapter['word'] as $key => $value)
e673ee24 2552 {
cfadde04 2553 echo "<tr class=row_${order}><td class=tdleft><div title='key=${key}'>${value}</div></td></tr>";
e673ee24
DO
2554 $order = $nextorder[$order];
2555 }
2556 echo "</table>";
2557 finishPortlet();
2558 echo "</td>";
2559 }
2560 echo "</tr></table>";
2561}
2562
2563function renderDictionaryEditor ()
2564{
2565 global $root, $pageno, $tabno;
2566 showMessageOrError();
2567 $dict = getDict();
2568 echo "<table border=0><tr>";
2569 foreach ($dict as $chapter)
2570 {
2571 echo "<td class=pcleft>";
2572 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2573 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2574 foreach ($chapter['word'] as $key => $value)
2575 {
2576 echo "<form action='${root}process.php' method=post>";
2577 echo "<input type=hidden name=page value='${pageno}'>";
2578 echo "<input type=hidden name=tab value='${tabno}'>";
2579 echo "<input type=hidden name=op value='upd'>";
2580 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2581 echo "<input type=hidden name=dict_key value='${key}'>";
2582 echo '<tr>';
2583 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2584 printImageHREF ('delete', 'Delete word');
2585 echo "</a></td>";
2586 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2587 echo "<td><input type=submit value=OK></td>";
2588 echo '</tr></form>';
2589 }
2590 echo "<form action='${root}process.php' method=post>";
2591 echo "<input type=hidden name=page value='${pageno}'>";
2592 echo "<input type=hidden name=tab value='${tabno}'>";
2593 echo "<input type=hidden name=op value=add>";
2594 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2595 echo '<tr>';
2596 echo "<td>&nbsp;</td>";
2597 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
2598 echo "<td><input type=submit value=OK></td>";
2599 echo '</tr></form>';
2600 echo "</table>";
2601 finishPortlet();
2602 echo "</td>";
2603 }
2604 echo "</tr></table>";
2605}
2606
2607// We don't allow to rename/delete a sticky chapter and we don't allow
2608// to delete a non-empty chapter.
2609function renderChaptersEditor ()
2610{
2611 global $root, $pageno, $tabno;
2612 showMessageOrError();
2613 $dict = getDict();
2614 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2615 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
2616 foreach ($dict as $chapter)
2617 {
2618 $wordcount = count ($chapter['word']);
2619 $sticky = $chapter['sticky'];
2620 echo "<form action='${root}process.php' method=post>";
2621 echo "<input type=hidden name=page value='${pageno}'>";
2622 echo "<input type=hidden name=tab value='${tabno}'>";
2623 echo "<input type=hidden name=op value=upd>";
2624 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2625 echo '<tr>';
2626 echo '<td>';
2627 if ($sticky or $wordcount > 0)
2628 echo '&nbsp;';
2629 else
2630 {
2631 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
2632 printImageHREF ('delete', 'Remove chapter');
2633 echo "</a>";
2634 }
2635 echo '</td>';
2636 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
2637 echo "<td class=tdleft>${wordcount}</td><td>";
2638 if ($sticky)
2639 echo '&nbsp;';
2640 else
2641 echo "<input type=submit value='OK'>";
2642 echo '</td></tr>';
2643 echo '</form>';
2644 }
2645 echo "<form action='${root}process.php' method=post>";
2646 echo "<input type=hidden name=page value='${pageno}'>";
2647 echo "<input type=hidden name=tab value='${tabno}'>";
2648 echo "<input type=hidden name=op value=add>";
2649 echo '<tr><td>';
a5ae8c2a 2650 printImageHREF ('add', '', TRUE);
e673ee24
DO
2651 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
2652 echo '</tr>';
2653 echo '</form>';
2654 echo "</table>\n";
2655}
2656
2657function renderAttributes ()
2658{
2659 global $nextorder;
2660 $attrMap = getAttrMap();
2661 startPortlet ('Optional attributes');
2662 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2663 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
2664 $order = 'odd';
2665 foreach ($attrMap as $attr)
2666 {
2667 echo "<tr class=row_${order}>";
2668 echo "<td class=tdleft>${attr['name']}</td>";
2669 echo "<td class=tdleft>${attr['type']}</td>";
2670 echo '<td class=tdleft>';
2671 if (count ($attr['application']) == 0)
2672 echo '&nbsp;';
2673 else
2674 foreach ($attr['application'] as $app)
2675 if ($attr['type'] == 'dict')
2676 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
2677 else
2678 echo "${app['objtype_name']}<br>";
2679 echo '</td>';
2680 echo "</tr>\n";
2681 $order = $nextorder[$order];
2682 }
2683 echo "</table><br>\n";
2684 finishPortlet();
2685}
2686
2687function renderEditAttributesForm ()
2688{
2689 global $root, $pageno, $tabno;
2690 $attrMap = getAttrMap();
2691 showMessageOrError();
2692 startPortlet ('Optional attributes');
2693 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2694 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
2695 foreach ($attrMap as $attr)
2696 {
2697 echo "<form action='${root}process.php' method=post>";
2698 echo "<input type=hidden name=page value='${pageno}'>";
2699 echo "<input type=hidden name=tab value='${tabno}'>";
2700 echo "<input type=hidden name=op value=upd>";
2701 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
2702 echo '<tr>';
2703 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
2704 printImageHREF ('delete', 'Remove attribute');
2705 echo '</a></td>';
2706 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
2707 echo "<td>${attr['type']}</td>";
2708 echo "<td><input type=submit value='OK'></td>";
2709 echo '</tr>';
2710 echo '</form>';
2711 }
2712 echo "<form action='${root}process.php' method=post>";
2713 echo "<input type=hidden name=page value='${pageno}'>";
2714 echo "<input type=hidden name=tab value='${tabno}'>";
2715 echo "<input type=hidden name=op value=add>";
2716 echo '<tr><td>';
a5ae8c2a 2717 printImageHREF ('add', '', TRUE);
e673ee24
DO
2718 echo "</td><td><input type=text name=attr_name></td>";
2719 echo '<td><select name=attr_type>';
2720 echo '<option value=uint>uint</option>';
2721 echo '<option value=float>float</option>';
2722 echo '<option value=string>string</option>';
2723 echo '<option value=dict>dict</option>';
2724 echo '</select></td>';
2725 echo '</tr>';
2726 echo '</form>';
2727 echo "</table>\n";
2728 finishPortlet();
2729}
2730
2731function renderEditAttrMapForm ()
2732{
2733 global $root, $pageno, $tabno;
2734 $attrMap = getAttrMap();
2735 showMessageOrError();
2736 startPortlet ('Attribute map');
2737 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2738 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
2739 foreach ($attrMap as $attr)
2740 {
2741 if (count ($attr['application']) == 0)
2742 continue;
2743 foreach ($attr['application'] as $app)
2744 {
2745 echo '<tr>';
2746 echo '<td>';
2747 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
2748 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
2749 printImageHREF ('delete', 'Remove mapping');
2750 echo "</a>";
2751 echo '</td>';
2752 echo "<td>${attr['name']}</td>";
2753 echo "<td>${app['objtype_name']}</td>";
2754 echo "<td>";
2755 if ($attr['type'] == 'dict')
2756 echo "${app['chapter_name']}";
2757 else
2758 echo '&nbsp;';
2759 echo "</td></tr>\n";
2760 }
2761 }
2762 echo "<form action='${root}process.php' method=post>";
2763 echo "<input type=hidden name=page value='${pageno}'>";
2764 echo "<input type=hidden name=tab value='${tabno}'>";
2765 echo "<input type=hidden name=op value=add>";
2766 echo '<tr><td>';
a5ae8c2a 2767 printImageHREF ('add', '', TRUE);
e673ee24
DO
2768 echo "</td><td><select name=attr_id>";
2769 $shortType['uint'] = 'U';
2770 $shortType['float'] = 'F';
2771 $shortType['string'] = 'S';
2772 $shortType['dict'] = 'D';
2773 foreach ($attrMap as $attr)
2774 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
2775 echo "</select></td>";
2776 echo '<td>';
2777 printSelect (getObjectTypeList(), 'objtype_id');
2778 echo '</td>';
2779 $dict = getDict();
2780 echo '<td><select name=chapter_no>';
2781 foreach ($dict as $chapter)
2782 if (!$chapter['sticky'])
2783 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
2784 echo '</select></td>';
2785 echo '</tr>';
2786 echo '</form>';
2787 echo "</table>\n";
2788 finishPortlet();
2789}
2790
a5ae8c2a 2791function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
e673ee24 2792{
a5ae8c2a
DO
2793 global $root;
2794 $image['error']['path'] = 'pix/error.png';
2795 $image['error']['width'] = 76;
2796 $image['error']['height'] = 17;
a5ae8c2a
DO
2797 $image['logo']['path'] = 'pix/defaultlogo.png';
2798 $image['logo']['width'] = 210;
2799 $image['logo']['height'] = 40;
2800 $image['rackspace']['path'] = 'pix/racks.png';
2801 $image['rackspace']['width'] = 218;
2802 $image['rackspace']['height'] = 200;
2803 $image['objects']['path'] = 'pix/server.png';
2804 $image['objects']['width'] = 218;
2805 $image['objects']['height'] = 200;
2806 $image['ipv4space']['path'] = 'pix/addressspace.png';
2807 $image['ipv4space']['width'] = 218;
2808 $image['ipv4space']['height'] = 200;
2809 $image['config']['path'] = 'pix/configuration.png';
2810 $image['config']['width'] = 218;
2811 $image['config']['height'] = 200;
2812 $image['reports']['path'] = 'pix/report.png';
2813 $image['reports']['width'] = 218;
2814 $image['reports']['height'] = 200;
2815 $image['help']['path'] = 'pix/help.png';
2816 $image['help']['width'] = 218;
2817 $image['help']['height'] = 200;
2818 $image['reserve']['path'] = 'pix/stop.png';
2819 $image['reserve']['width'] = 16;
2820 $image['reserve']['height'] = 16;
2821 $image['useup']['path'] = 'pix/go.png';
2822 $image['useup']['width'] = 16;
2823 $image['useup']['height'] = 16;
2824 $image['blockuser'] = $image['reserve'];
2825 $image['unblockuser'] = $image['useup'];
2826 $image['link']['path'] = 'pix/link.png';
2827 $image['link']['width'] = 24;
2828 $image['link']['height'] = 24;
2829 $image['unlink']['path'] = 'pix/unlink.png';
2830 $image['unlink']['width'] = 24;
2831 $image['unlink']['height'] = 24;
2832 $image['add']['path'] = 'pix/greenplus.png';
2833 $image['add']['width'] = 16;
2834 $image['add']['height'] = 16;
2835 $image['delete']['path'] = 'pix/delete_s.gif';
2836 $image['delete']['width'] = 16;
2837 $image['delete']['height'] = 16;
2838 $image['grant'] = $image['add'];
2839 $image['revoke'] = $image['delete'];
2840 $image['helphint']['path'] = 'pix/helphint.png';
2841 $image['helphint']['width'] = 24;
2842 $image['helphint']['height'] = 24;
e673ee24
DO
2843 if (!isset ($image[$tag]))
2844 $tag = 'error';
2845 $img = $image[$tag];
a5ae8c2a
DO
2846 if ($do_input == TRUE)
2847 echo
2848 "<input type=image name=submit " .
2849 "src='${root}${img['path']}' " .
2850 "border=0 " .
2851 ($tabindex ? '' : "tabindex=${tabindex}") .
2852 ">";
2853 else
2854 echo
2855 "<img " .
2856 "src='${root}${img['path']}' " .
2857 "width=${img['width']} " .
2858 "height=${img['height']} " .
2859 "border=0 " .
2860 (empty ($title) ? '' : "title='${title}'") .
2861 ">";
e673ee24
DO
2862}
2863
2864// This function returns URL for favourite icon.
2865function getFaviconURL ()
2866{
46100c70
DO
2867 global $root;
2868 return $root . 'pix/racktables.ico';
e673ee24
DO
2869}
2870
2871function renderReportSummary ()
2872{
da95280e
DO
2873 echo "<table width='100%'>\n";
2874 echo "<tr><td class=pcleft>\n";
08b4cb24 2875 startPortlet ("Dictionary/objects stats");
da95280e
DO
2876 echo "<table>\n";
2877 foreach (getDictStats() as $header => $data)
2878 {
2879 echo "<tr><th>${header}:</th><td>${data}</td></tr>\n";
2880 }
2881 echo "</table>\n";
2882 finishPortlet();
2883
2884 echo "</td><td class=pcright>\n";
2885
c461c579
DO
2886 startPortlet ("Here be dragons");
2887 dragon();
2888 dragon();
2889 dragon();
2890 echo 'ASCII art &copy; Daniel C. Au';
2891 finishPortlet();
da95280e
DO
2892 echo "</td></tr>\n";
2893 echo "</table>\n";
c461c579
DO
2894}
2895
2896function dragon ()
2897{
2898?>
2899<div class=dragon><pre><font color="#00ff33">
2900 \||/
2901 | <font color="#ff0000">@</font>___oo
2902 /\ /\ / (__<font color=yellow>,,,,</font>|
2903 ) /^\) ^\/ _)
2904 ) /^\/ _)
2905 ) _ / / _)
2906 /\ )/\/ || | )_)
2907 &lt; &gt; |(<font color=white>,,</font>) )__)
2908 || / \)___)\
2909 | \____( )___) )___
2910 \______(_______<font color=white>;;;</font> __<font color=white>;;;</font>
2911
2912</font></pre></div>
2913<?php
e673ee24
DO
2914}
2915
2916function renderUIConfig ()
2917{
4fe32e78
DY
2918 global $configCache, $nextorder;
2919 showMessageOrError();
0a1b1268 2920 startPortlet ('Current configuration');
c461c579
DO
2921 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
2922 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
4fe32e78 2923 $order = 'odd';
0a1b1268 2924 foreach ($configCache as $v)
4fe32e78 2925 {
c461c579
DO
2926 if ($v['is_hidden'] != 'no')
2927 continue;
2928 echo "<tr class=row_${order}>";
2929 echo "<td class=tdright>${v['description']}</td>\n";
2930 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
2931 $order = $nextorder[$order];
4fe32e78 2932 }
0a1b1268
DO
2933 echo "</table>\n";
2934 finishPortlet();
7865c525
DO
2935}
2936
4fe32e78
DY
2937function renderUIConfigEditForm ()
2938{
c461c579 2939 global $root, $pageno, $tabno, $configCache;
4fe32e78
DY
2940 showMessageOrError();
2941 startPortlet ('Current configuration');
c461c579
DO
2942 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
2943 echo "<tr><th class=tdleft>Option</th>";
2944 echo "<th class=tdleft>Value</th></tr>";
4fe32e78
DY
2945 echo "<form action='${root}process.php'>";
2946 echo "<input type=hidden name=op value='upd'>";
c461c579
DO
2947 echo "<input type=hidden name=page value='${pageno}'>\n";
2948 echo "<input type=hidden name=tab value='${tabno}'>\n";
4fe32e78
DY
2949
2950 $i = 0;
2951 foreach ($configCache as $v)
2952 {
c461c579
DO
2953 if ($v['is_hidden'] != 'no')
2954 continue;
2955 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
2956 echo "<tr><td class=tdright>${v['description']}</td>";
2957 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
2958 echo "</tr>\n";
2959 $i++;
4fe32e78
DY
2960 }
2961 echo "<input type=hidden name=num_vars value=${i}>\n";
c461c579 2962 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
4fe32e78
DY
2963 echo "</form>";
2964 finishPortlet();
2965}
2966
7865c525
DO
2967// This function queries the gateway about current VLAN configuration and
2968// renders a form suitable for submit. Ah, and it does submit processing as well.
111b4a67
DO
2969function renderVLANMembership ($object_id = 0)
2970{
fc8d0004 2971 global $root, $pageno, $tabno, $remote_username;
111b4a67
DO
2972 if ($object_id <= 0)
2973 {
2974 showError ('Invalid object_id in renderVLANMembership()');
2975 return;
2976 }
7865c525
DO
2977
2978 // Handle probable pending submit.
2979 if (isset ($_REQUEST['portcount']))
111b4a67 2980 {
7865c525
DO
2981 $data = getSwitchVLANs ($object_id);
2982 if ($data === NULL)
2da7c9b0 2983 {
7865c525 2984 showError ('getSwitchVLANs() failed in renderVLANMembership() during submit processing');
fc8d0004
DO
2985 return;
2986 }
7865c525
DO
2987 list ($vlanlist, $portlist) = $data;
2988 // Here we just build up 1 set command for the gateway with all of the ports
2989 // included. The gateway is expected to filter unnecessary changes silently
2990 // and to provide a list of responses with either error or success message
2991 // for each of the rest.
2992 assertUIntArg ('portcount');
2993 $nports = $_REQUEST['portcount'];
2994 $prefix = 'set ';
2995 $log = array();
2996 $setcmd = '';
2997 for ($i = 0; $i < $nports; $i++)
2998 if
2999 (
3000 !isset ($_REQUEST['portname_' . $i]) ||
3001 !isset ($_REQUEST['vlanid_' . $i]) ||
3002 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
3003 )
3004 $log[] = array ('code' => 'error', 'message' => "Ignoring mailformed record #${i} in form submit");
3005 elseif
3006 (
3007 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
3008 $portlist[$i]['vlaind'] == 'TRUNK'
3009 )
3010 continue;
3011 else
3012 {
3013 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3014 $prefix = ';';
3015 }
3016 printLog ($log);
3017 // Feed the gateway and interpret its (non)response.
3018 if ($setcmd != '')
3019 printLog (setSwitchVLANs ($object_id, $setcmd));
3020 }
3021
3022 // Reload and render.
3023 $data = getSwitchVLANs ($object_id);
3024 if ($data === NULL)
3025 return;
18cb9495 3026 list ($vlanlist, $portlist, $maclist) = $data;
d28ea105 3027
a684aa6f 3028 echo '<table border=0 width="100%"><tr><td colspan=3>';
d28ea105 3029
2b9e0abd 3030 startPortlet ('Current status');
18cb9495 3031 echo "<table class=widetable cellspacing=3 cellpadding=5 align=center width='100%'><tr>";
7865c525
DO
3032 echo "<form method=post>";
3033 echo "<input type=hidden name=page value='${pageno}'>";
3034 echo "<input type=hidden name=tab value='${tabno}'>";
3035 echo "<input type=hidden name=object_id value=${object_id}>";
0d591525
DO
3036 $portcount = count ($portlist);
3037 echo "<input type=hidden name=portcount value=" . $portcount . ">\n";
7865c525 3038 $portno = 0;
9c0b0016 3039 $ports_per_row = getConfigVar ('PORTS_PER_ROW');
7865c525
DO
3040 foreach ($portlist as $port)
3041 {
3042 // Don't let wide forms break our fancy pages.
9c0b0016 3043 if ($portno % $ports_per_row == 0)
fc8d0004 3044 {
7865c525
DO
3045 if ($portno > 0)
3046 echo "</tr>\n";
0d591525 3047 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + $ports_per_row > $portcount ? $portcount : $portno + $ports_per_row) . "</th>";
fc8d0004 3048 }
18cb9495
DO
3049 echo '<td class=port_';
3050 if ($port['status'] == 'notconnect')
3051 echo 'notconnect';
2b9e0abd
DO
3052 elseif ($port['status'] == 'disabled')
3053 echo 'disabled';
18cb9495
DO
3054 elseif ($port['status'] != 'connected')
3055 echo 'unknown';
3056 elseif (!isset ($maclist[$port['portname']]))
3057 echo 'connected_none';
3058 else
3059 {
3060 $maccount = 0;
3061 foreach ($maclist[$port['portname']] as $vlanid => $addrs)
3062 $maccount += count ($addrs);
3063 if ($maccount == 1)
3064 echo 'connected_single';
3065 else
3066 echo 'connected_multi';
3067 }
3068 echo '>' . $port['portname'] . '<br>';
7865c525
DO
3069 echo "<input type=hidden name=portname_${portno} value=" . $port['portname'] . '>';
3070 if ($port['vlanid'] == 'trunk')
fc8d0004 3071 {
7865c525
DO
3072 echo "<input type=hidden name=vlanid_${portno} value='trunk'>";
3073 echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
fc8d0004 3074 }
7865c525 3075 else
fc8d0004 3076 {
7865c525 3077 echo "<select name=vlanid_${portno}>";
8c7a0e37
DO
3078 // A port may belong to a VLAN, which is absent from the VLAN table, this is normal.
3079 // We must be able to render its SELECT properly at least.
3080 $in_table = FALSE;
d28ea105 3081 foreach ($vlanlist as $v => $d)
fc8d0004 3082 {
7865c525
DO
3083 echo "<option value=${v}";
3084 if ($v == $port['vlanid'])
8c7a0e37 3085 {
7865c525 3086 echo ' selected';
8c7a0e37
DO
3087 $in_table = TRUE;
3088 }
3089 echo ">${v}</option>\n";
fc8d0004 3090 }
8c7a0e37
DO
3091 if (!$in_table)
3092 echo "<option value=${port['vlanid']} selected>${port['vlanid']}</option>\n";
7865c525 3093 echo "</select>";
fc8d0004 3094 }
7865c525
DO
3095 $portno++;
3096 echo "</td>";
111b4a67 3097 }
9c0b0016 3098 echo "</tr><tr><td colspan=" . ($ports_per_row + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
7865c525 3099 finishPortlet();
d28ea105 3100
a684aa6f
DO
3101 echo '</td></tr><tr><td class=pcleft>';
3102 startPortlet ('VLAN table');
3103 echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center width="100%">';
3104 echo "<tr><th>ID</th><th>Description</th></tr>";
3105 $order = 'even';
3106 global $nextorder;
3107 foreach ($vlanlist as $id => $descr)
3108 {
3109 echo "<tr class=row_${order}><td class=tdright>${id}</td><td class=tdleft>${descr}</td></tr>";
3110 $order = $nextorder[$order];
3111 }
3112 echo '</table>';
3113 finishPortlet();
3114
3115 echo '</td><td class=pcright>';
3116
3117 startPortlet ('Color legend');
3118 echo '<table>';
3119 echo "<tr><th>port state</th><th>color code</th></tr>";
3120 echo "<tr><td>not connected</td><td class=port_notconnect>SAMPLE</td></tr>";
3121 echo "<tr><td>disabled</td><td class=port_disabled>SAMPLE</td></tr>";
3122 echo "<tr><td>unknown</td><td class=port_unknown>SAMPLE</td></tr>";
3123 echo "<tr><td>connected with none MAC addresses active</td><td class=port_connected_none>SAMPLE</td></tr>";
3124 echo "<tr><td>connected with 1 MAC addresses active</td><td class=port_connected_single>SAMPLE</td></tr>";
3125 echo "<tr><td>connected with 1+ MAC addresses active</td><td class=port_connected_multi>SAMPLE</td></tr>";
3126 echo '</table>';
3127 finishPortlet();
3128
3129 echo '</td><td class=pcright>';
3130
18cb9495
DO
3131 if (count ($maclist))
3132 {
3133 startPortlet ('MAC address table');
3134 echo '<table border=0 class=cooltable align=center cellspacing=0 cellpadding=5>';
3135 echo "<tr><th>Port</th><th>VLAN ID</th><th>MAC address</th></tr>\n";
3136 $order = 'even';
3137 foreach ($maclist as $portname => $portdata)
3138 foreach ($portdata as $vlanid => $addrgroup)
3139 foreach ($addrgroup as $addr)
3140 {
3141 echo "<tr class=row_${order}><td>$portname</td><td>$vlanid</td><td>$addr</td></tr>\n";
3142 $order = $nextorder[$order];
3143 }
3144 echo '</table>';
3145 finishPortlet();
3146 }
3147
18cb9495
DO
3148 // End of main table.
3149 echo '</td></tr></table>';
111b4a67
DO
3150}
3151
9c67f713
DO
3152// This snippet either renders a form inviting the user to start SNMP query
3153// on the current device or displays the result of the scan.
3154function renderSNMPPortFinder ($object_id = 0)
3155{
3156 global $root, $pageno, $tabno, $remote_username;
3157 if ($object_id <= 0)
3158 {
3159 showError ('Invalid object_id in renderSNMPPortFinder()');
3160 return;
3161 }
dd9afc41 3162// FIXME: check if SNMP PHP extension is available!
9c67f713
DO
3163 if (isset ($_REQUEST['do_scan']))
3164 {
dd9afc41 3165 $log = array();
1c4d54d4
DO
3166// IDs: http://cisco.com/en/US/products/sw/cscowork/ps2064/products_device_support_table09186a0080803bb4.html
3167// 2960: http://www.cisco.com/en/US/products/ps6406/prod_models_comparison.html
65813f73 3168// 2970: http://cisco.com/en/US/products/hw/switches/ps5206/products_qanda_item09186a00801b1750.shtml
563196e8 3169// 3500XL: http://cisco.com/en/US/products/hw/switches/ps637/products_eol_models.html
1c4d54d4 3170// 3560: http://cisco.com/en/US/products/hw/switches/ps5528/products_data_sheet09186a00801f3d7f.html
563196e8 3171// 3750: http://cisco.com/en/US/products/hw/switches/ps5023/products_data_sheet09186a008016136f.html
137b7a50 3172 $ciscomodel[283] = 'WS-C6509-E (9-slot system)';
818e40c7
DO
3173// FIXME: hwtype hardcoded value will become invalid after the Dictionary table transformation
3174// in 0.14.7 version. Either the values will have to be adjusted as well or we have to switch
3175// to value lookup (not reliable).
64d5f2b4 3176 $hwtype[283] = 148;
dd9afc41
DO
3177# $ciscomodel[694] = 'WS-C2960-24TC-L (24 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3178# $ciscomodel[695] = 'WS-C2960-48TC-L (48 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3179 $ciscomodel[696] = 'WS-C2960G-24TC-L (20 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
64d5f2b4 3180 $hwtype[696] = 167;
dd9afc41 3181 $ciscomodel[697] = 'WS-C2960G-48TC-L (44 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
64d5f2b4 3182 $hwtype[697] = 166;
dd9afc41
DO
3183# $ciscomodel[716] = 'WS-C2960-24TT-L (24 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
3184# $ciscomodel[717] = 'WS-C2960-48TT-L (48 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
65813f73 3185 $ciscomodel[527] = 'WS-C2970G-24T (24 Ethernet 10/100/1000 ports)';
64d5f2b4 3186 $hwtype[527] = 210;
65813f73
DO
3187 $ciscomodel[561] = 'WS-C2970G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3188 $hwtype[561] = 115;
137b7a50 3189# $ciscomodel[633] = 'WS-C3560-24TS (24 Ethernet 10/100 ports and 2 10/100/1000 SFP uplinks)';
64d5f2b4 3190# $hwtype[633] = 169;
137b7a50 3191 $ciscomodel[634] = 'WS-C3560-48TS (48 Ethernet 10/100 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3192 $hwtype[634] = 170;
137b7a50 3193# $ciscomodel[563] = 'WS-C3560-24PS (24 Ethernet 10/100 POE ports and 2 10/100/1000 SFP uplinks)';
64d5f2b4 3194# $hwtype[563] = 171;
137b7a50 3195 $ciscomodel[564] = 'WS-C3560-48PS (48 Ethernet 10/100 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3196 $hwtype[564] = 172;
1c4d54d4 3197 $ciscomodel[614] = 'WS-C3560G-24PS (24 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3198 $hwtype[614] = 175;
1c4d54d4 3199 $ciscomodel[615] = 'WS-C3560G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3200 $hwtype[615] = 173;
1c4d54d4 3201 $ciscomodel[616] = 'WS-C3560G-48PS (48 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3202 $hwtype[616] = 176;
1c4d54d4 3203 $ciscomodel[617] = 'WS-C3560G-48TS (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3204 $hwtype[617] = 174;
7a9f3034 3205 $ciscomodel[58] = 'WS-C4503 (3-slot system)';
64d5f2b4 3206 $hwtype[58] = 145;
7a9f3034 3207 $ciscomodel[503] = '4503 (3-slot system)';
64d5f2b4 3208 $hwtype[503] = 145;
7a9f3034 3209 $ciscomodel[59] = 'WS-C4506 (6-slot system)';
64d5f2b4 3210 $hwtype[59] = 156;
7a9f3034 3211 $ciscomodel[502] = '4506 (6-slot system)';
64d5f2b4 3212 $hwtype[502] = 156;
3d61d4ca 3213 $ciscomodel[626] = 'WS-C4948 (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
64d5f2b4 3214 $hwtype[626] = 147;
563196e8 3215 $ciscomodel[659] = 'WS-C4948-10GE (48 Ethernet 10/100/1000 ports and 2 10Gb X2 uplinks)';
64d5f2b4 3216 $hwtype[659] = 377;
dd9afc41
DO
3217 assertStringArg ('community');
3218 $community = $_REQUEST['community'];
3219 $objectInfo = getObjectInfo ($object_id);
3220 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
3221 $sysDescr = snmpget ($endpoints[0], $community, 'sysDescr.0');
3222 // Strip the object type, it's always string here.
3223 $sysDescr = substr ($sysDescr, strlen ('STRING: '));
1c4d54d4 3224 if (strpos ($sysDescr, 'Cisco IOS Software') === 0 or strpos ($sysDescr, 'Cisco Internetwork Operating System Software') === 0)
dd9afc41 3225 $log[] = array ('code' => 'success', 'message' => 'Seems to be a Cisco box');
818e40c7
DO
3226 else
3227 {
3228 $log[] = array ('code' => 'error', 'message' => 'No idea how to handle ' . $sysDescr);
3229 printLog ($log);
3230 return;
3231 }
3232
3233 // It's a Cisco. Go on.
3234 $attrs = getAttrValues ($object_id);
3235 // Only fill in attribute values, if they are not set.
3236 // FIXME: this is hardcoded
3237
3238 if (empty ($attrs[5]['value'])) // SW version
3239 {
3240 $IOSversion = ereg_replace ('^.*, Version ([^ ]+), .*$', '\\1', $sysDescr);
3241 $error = commitUpdateAttrValue ($object_id, 5, $IOSversion);
3242 if ($error == TRUE)
3243 $log[] = array ('code' => 'success', 'message' => 'SW version set to ' . $IOSversion);
3244 else
3245 $log[] = array ('code' => 'error', 'message' => 'Failed settig SW version: ' . $error);
3246 }
3247
3248 if (empty ($attrs[4]['value']) and substr ($IOSversion, 0, 4) == '12.2') // switch OS type
3249 {
64d5f2b4 3250 $error = commitUpdateAttrValue ($object_id, 4, 252);
818e40c7
DO
3251 if ($error == TRUE)
3252 $log[] = array ('code' => 'success', 'message' => 'Switch OS type set to Cisco IOS 12.2');
3253 else
3254 $log[] = array ('code' => 'error', 'message' => 'Failed settig Switch OS type: ' . $error);
3255 }
3256
dd9afc41
DO
3257 $sysObjectID = snmpget ($endpoints[0], $community, 'sysObjectID.0');
3258 // Transform OID
3259 $sysObjectID = substr ($sysObjectID, strlen ('OID: SNMPv2-SMI::enterprises.9.1.'));
3260 if (!isset ($ciscomodel[$sysObjectID]))
3261 {
3262 $log[] = array ('code' => 'error', 'message' => 'Could not guess exact HW model!');
3263 printLog ($log);
3264 return;
3265 }
3266 $log[] = array ('code' => 'success', 'message' => 'HW is ' . $ciscomodel[$sysObjectID]);
818e40c7
DO
3267 if (empty ($attrs[2]['value']) and isset ($hwtype[$sysObjectID])) // switch HW type
3268 {
3269 $error = commitUpdateAttrValue ($object_id, 2, $hwtype[$sysObjectID]);
3270 if ($error == TRUE)
3d61d4ca 3271 $log[] = array ('code' => 'success', 'message' => 'HW type updated Ok');
818e40c7
DO
3272 else
3273 $log[] = array ('code' => 'error', 'message' => 'Failed settig HW type: ' . $error);
3274 }
dd9afc41
DO
3275 // Now fetch ifType, ifDescr and ifPhysAddr and let model-specific code sort the data out.
3276 $ifType = snmpwalkoid ($endpoints[0], $community, 'ifType');
3277 $ifDescr = snmpwalkoid ($endpoints[0], $community, 'ifdescr');
3278 $ifPhysAddress = snmpwalkoid ($endpoints[0], $community, 'ifPhysAddress');
3279 // Combine 3 tables into 1...
3280 $ifList1 = array();
3281 foreach ($ifType as $key => $val)
3282 {
3283 list ($dummy, $ifIndex) = explode ('.', $key);
3284 list ($dummy, $type) = explode (' ', $val);
3285 $ifList1[$ifIndex]['type'] = $type;
3286 }
3287 foreach ($ifDescr as $key => $val)
3288 {
3289 list ($dummy, $ifIndex) = explode ('.', $key);
3290 list ($dummy, $descr) = explode (' ', $val);
3291 $ifList1[$ifIndex]['descr'] = trim ($descr, '"');
3292 }
3293 foreach ($ifPhysAddress as $key => $val)
3294 {
3295 list ($dummy, $ifIndex) = explode ('.', $key);
3296 list ($dummy, $addr) = explode (':', $val);
3297 $addr = str_replace (' ', '', $addr);
3298 $ifList1[$ifIndex]['phyad'] = $addr;
3299 }
3300 // ...and then reverse it inside out to make description the key.
3301 $ifList2 = array();
3302 foreach ($ifList1 as $ifIndex => $data)
3303 {
3304 $ifList2[$data['descr']]['type'] = $data['type'];
3305 $ifList2[$data['descr']]['phyad'] = $data['phyad'];
3306 $ifList2[$data['descr']]['idx'] = $ifIndex;
3307 }
dd9afc41
DO
3308 $newports = 0;
3309 // Now we can directly pick necessary ports from the table accordingly
3310 // to our known hardware model.
3311 switch ($sysObjectID)
3312 {
3313 // FIXME: chassis edge switches often share a common naming scheme, so
3314 // the sequences below have to be generalized. Let's have some duplicated
3315 // code for the time being, as this is the first implementation ever.
3316 case '697': // WS-C2960G-48TC-L
3317 // 44 copper ports: 1X, 2X, 3X...
3318 // 4 combo ports: 45, 46, 47, 48. Don't list SFP connectors atm, as it's not
3319 // clear how to fit them into current Ports table structure.
3320 for ($i = 1; $i <= 48; $i++)
3321 {
3322 $label = ($i >= 45) ? "${i}" : "${i}X";
64d5f2b4 3323 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
dd9afc41
DO
3324 if ($error == '')
3325 $newports++;
3326 else
3327 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3328 }
3329 break;
3330 case '696': // WS-C2960G-24TC-L
3331 // Quite similar to the above.
3332 for ($i = 1; $i <= 24; $i++)
3333 {
3334 $label = ($i >= 21) ? "${i}" : "${i}X";
64d5f2b4 3335 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
dd9afc41
DO
3336 if ($error == '')
3337 $newports++;
3338 else
3339 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3340 }
3341 break;
137b7a50
DO
3342 case '564': // WS-C3560-48PS
3343 case '634': // WS-C3560-48TS
3344 for ($i = 1; $i <= 48; $i++)
3345 {
3346 $label = "${i}X";
64d5f2b4 3347 $error = commitAddPort ($object_id, 'fa0/' . $i, 19, $label, $ifList2["FastEthernet0/${i}"]['phyad']);
137b7a50
DO
3348 if ($error == '')
3349 $newports++;
3350 else
3351 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3352 }
3353 for ($i = 1; $i <= 4; $i++)
3354 {
3355 $label = "${i}";
64d5f2b4 3356 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
137b7a50
DO
3357 if ($error == '')
3358 $newports++;
3359 else
3360 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3361 }
3362 break;
1c4d54d4
DO
3363 case '614': // WS-C3560G-24PS
3364 case '615': // WS-C3560G-24TS
65813f73
DO
3365 case '527': // WS-C2970G-24T
3366 case '561': // WS-C2970G-24TS
1c4d54d4
DO
3367 for ($i = 1; $i <= 24; $i++)
3368 {
3369 $label = "${i}X";
64d5f2b4 3370 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
1c4d54d4
DO
3371 if ($error == '')
3372 $newports++;
3373 else
3374 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3375 }
3376 break;
3377 case '616': // WS-C3560G-48PS
3378 case '617': // WS-C3560G-48TS
3d61d4ca
DO
3379 case '626': // WS-C4948
3380 case '659': // WS-C4948-10GE
1c4d54d4
DO
3381 for ($i = 1; $i <= 48; $i++)
3382 {
3383 $label = "${i}X";
64d5f2b4 3384 $error = commitAddPort ($object_id, 'gi0/' . $i, 24, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
1c4d54d4
DO
3385 if ($error == '')
3386 $newports++;
3387 else
3388 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3389 }
3390 break;
137b7a50
DO
3391 // For modular devices we don't iterate over all possible port names,
3392 // but use the first list to pick everything that looks legitimate
3393 // for this hardware. It would be correct to fetch the list of modules
3394 // installed to generate lists of ports, but who is going to implement
3395 // this?
7a9f3034
DO
3396 case '503': // 4503
3397 case '58': // WS-C4503
3398 case '502': // 4506
3399 case '59': // WS-C4506
137b7a50
DO
3400 case '283': // WS-C6509-E
3401 foreach ($ifList1 as $port)
3402 {
3403 if ($port['type'] != 'ethernet-csmacd(6)')
3404 continue;
3405 // Copper Fa/Gi harvesting is relatively simple, while 10Gig ports can
3406 // have random samples of transciever units.
3407 if (strpos ($port['descr'], 'FastEthernet') === 0) // Fa
3408 {
3409 $prefix = 'fa';
64d5f2b4 3410 $ptype = 19; // RJ-45/100Base-TX
137b7a50
DO
3411 list ($slotno, $portno) = explode ('/', substr ($port['descr'], strlen ('FastEthernet')));
3412 }
3413 elseif (strpos ($port['descr'], 'GigabitEthernet') === 0) // Gi
3414 {
3415 $prefix = 'gi';
64d5f2b4 3416 $ptype = 24; // RJ-45/1000Base-T
137b7a50
DO
3417 list ($slotno, $portno) = explode ('/', substr ($port['descr'], strlen ('GigabitEthernet')));
3418 }
3419 else continue;
3420 $label = "slot ${slotno} port ${portno}";
3421 $pname = "${prefix}${slotno}/${portno}";
3422 $error = commitAddPort ($object_id, $pname, $ptype, $label, $port['phyad']);
3423 if ($error == '')
3424 $newports++;
3425 else
3426 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $pname . ': ' . $error);
3427 }
3428 break;
dd9afc41
DO
3429 default:
3430 showError ("Unexpected sysObjectID '${sysObjectID}' in renderSNMPPortFinder()");
3431 }
64d5f2b4 3432 $error = commitAddPort ($object_id, 'con0', 29, 'console', '');
b8f2fed1
DO
3433 if ($error == '')
3434 $newports++;
3435 else
3436 $log[] = array ('code' => 'error', 'message' => 'Failed to add console port : ' . $error);
dd9afc41
DO
3437 if ($newports > 0)
3438 $log[] = array ('code' => 'success', 'message' => "Added ${newports} new ports");
3439 printLog ($log);
9c67f713
DO
3440 return;
3441 }
dd9afc41
DO
3442 echo "<form method=post>\n";
3443 echo "<input type=hidden name=pageno value='${pageno}'>\n";
3444 echo "<input type=hidden name=tabno value='${pageno}'>\n";
3445?>
3446<p align=center>
3447This switch has no ports listed, that's why you see this form. If you supply SNMP community,
3448I can try atomatic data harvesting on the switch. As soon as at least one relevant port is found,
3449this tab will not be seen any more. Good luck.<br>
3450<input type=text name=community value='public'>
3451<input type=submit name='do_scan' value='Go!'>
3452</p>
b325120a 3453<?php
9c67f713
DO
3454}
3455
b07f617c
DO
3456function renderUIResetForm()
3457{
8dedc926 3458 global $root, $pageno, $tabno;
b07f617c
DO
3459 echo "<form method=post action='${root}process.php'>";
3460 echo "<input type=hidden name=page value=${pageno}>";
3461 echo "<input type=hidden name=tab value=${tabno}>";
3462 echo "<input type=hidden name=op value=go>";
3463 echo "This button will reset user interface configuration to its defaults (except organization name): ";
3464 echo "<input type=submit value='proceed'>";
3465 echo "</form>";
3466}
3467
9b0cf84f
DO
3468function renderFirstRowForm ()
3469{
3470 global $root, $pageno, $tabno;
80c37f85
DO
3471 echo "<form action='${root}process.php'>\n";
3472 echo "<input type=hidden name=page value=dict>\n";
3473 echo "<input type=hidden name=tab value=edit>\n";
3474 echo "<input type=hidden name=op value=add>\n";
3475 echo "<input type=hidden name=chapter_no value=3>\n";
9b0cf84f
DO
3476?>
3477<p align=center>
3478Your rackspace seems to be empty, and this form will create your first rack row,
3479just fill in the name. All the subsequent rack rows will have to be added from the
3480Dictionary edit page in Configuration section.
3481<br>
80c37f85
DO
3482<input type=text name=dict_value value='my server room'>
3483<input type=submit value='OK'>
9b0cf84f
DO
3484</p>
3485<?php
3486}
3487
e673ee24 3488?>