r1324 + 2 more Dell disk arrays
[racktables] / inc / interface.php
1 <?php
2 /*
3 *
4 * This file contains frontend functions for RackTables.
5 *
6 */
7
8 // Interface function's special.
9 $nextorder['odd'] = 'even';
10 $nextorder['even'] = 'odd';
11
12 // Main menu.
13 function 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>
24 <h1><a href='<?php echo $root; ?>?page=rackspace'>Rackspace<br>
25 <?php printImageHREF ('rackspace'); ?></a></h1>
26 </td>
27 <td>
28 <h1><a href='<?php echo $root; ?>?page=objects'>Objects<br>
29 <?php printImageHREF ('objects'); ?></a></h1>
30 </td>
31 <td>
32 <h1><a href='<?php echo $root; ?>?page=ipv4space'>IPv4 space<br>
33 <?php printImageHREF ('ipv4space'); ?></a></h1>
34 </td>
35 </tr>
36 </table>
37 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
38 <tr>
39 <td>
40 <h1><a href='<?php echo $root; ?>?page=config'>Configuration<br>
41 <?php printImageHREF ('config'); ?></a></h1>
42 </td>
43 <td>
44 <h1><a href='<?php echo $root; ?>?page=reports'>[ Reports ]<br>
45 <?php printImageHREF ('reports'); ?></a></h1>
46 </td>
47 <td>
48 <h1><a href='<?php echo $root; ?>?page=help'>Help<br>
49 <?php printImageHREF ('help'); ?></a></h1>
50 </td>
51 </tr>
52 </table>
53 </div>
54 </td>
55 </tr>
56 </table>
57 <?php
58 }
59
60 function renderRackspace ()
61 {
62 ?>
63 <table border=0 cellpadding=10 cellpadding=1>
64 <?php
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
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
90 function 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>";
107 startPortlet ($rowInfo['dict_value']);
108 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
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
116 global $root, $nextorder;
117 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
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']}'>";
125 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
126 echo (3 + 3 + $rack['height'] * 2) * getConfigVar ('ROW_SCALE');
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
138 function 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.
150 function 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
232 function 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
276 function 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>';
305 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
306 if ($defh == 0)
307 $defh = '';
308 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
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";
310 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
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
316 function 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";
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;
398 foreach ($values as $record)
399 {
400 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
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':
410 echo "<input type=text name=${i}_value value='${record['value']}'>";
411 break;
412 case 'dict':
413 $chapter = readChapter ($record['chapter_name']);
414 $chapter[] = array ('dict_key' => 0, 'dict_value' => '-- NOT SET --');
415 printSelect ($chapter, "${i}_value", $record['key']);
416 break;
417 }
418 echo "</td></tr>\n";
419 $i++;
420 }
421 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
422 echo "</form>";
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().
439 function 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>";
477 printSelect (getRackRowInfo(), 'rack_row_id', $rack['row_id']);
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.
492 function printSelect ($rowList, $select_name, $selected_id = 1)
493 {
494 echo "<select name=${select_name}>";
495 foreach ($rowList as $dummy => $data)
496 {
497 echo "<option value=${data['dict_key']}";
498 if ($data['dict_key'] == $selected_id)
499 echo ' selected';
500 echo ">${data['dict_value']}</option>";
501 }
502 echo "</select>";
503 }
504
505 // This is a universal editor of rack design/waste.
506 function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
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";
547 echo "<td class=pcright>";
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();
564 echo "</td></tr></table>\n";
565 }
566
567 function renderRackDesign ($rack_id)
568 {
569 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
570 }
571
572 function renderRackProblems ($rack_id = 0)
573 {
574 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
575 }
576
577 function startPortlet ($title = '')
578 {
579 echo "<div class=portlet><h2>${title}</h2>";
580 }
581
582 function finishPortlet ()
583 {
584 echo "</div>\n";
585 }
586
587 function 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 ', ';
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>";
600 $gotone=1;
601 }
602 }
603 }
604
605 function 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";
628 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
629 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
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";
633 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
634 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
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']))
643 echo "<tr><th width='50%' class=opt_attr_th>${record['name']}:</th><td class=tdleft>${record['value']}</td></tr>\n";
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 {
699 startPortlet ('IPv4 addresses');
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 {
783 startPortlet('NATv4');
784
785 if (count($forwards['out']))
786 {
787
788 echo "<h3>locally performed NAT</h3>";
789
790 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
791 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
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
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>";
808
809 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
810
811 $address=getIPAddress($pf['remoteip']);
812
813 echo "<td class='description'>";
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'] . ')';
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 {
828 echo "<h3>arriving NAT connections</h3>";
829
830 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
831 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
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
865 function renderRackMultiSelect ($sname, $racks, $selected)
866 {
867 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
868 foreach ($racks as $rack)
869 {
870 echo "<option value=${rack['id']}";
871 if (!(array_search ($rack['id'], $selected) === FALSE))
872 echo ' selected';
873 echo">${rack['row_name']}:${rack['name']}</option>\n";
874 }
875 echo "</select>\n";
876 }
877
878 function 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.
887 function 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();
958 $default_port_type = getConfigVar ('default_port_type');
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
1002 function 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
1127 function printLog ($log)
1128 {
1129 foreach ($log as $record)
1130 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1131 }
1132
1133 /*
1134 The following conditions must be followed:
1135 1. We can mount onto free atoms only. This means: if any record for an atom
1136 already exists in RackSpace, it can't be used for mounting.
1137 2. We can't unmount from 'W' atoms. Operator should review appropriate comments
1138 and either delete them before unmounting or refuse to unmount the object.
1139 */
1140
1141 // We extensively use $_REQUEST in the function.
1142 function 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);
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";
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
1295 function 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
1337 function 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>';
1349 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
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>";
1354 echo "<td>${obj['asset_no']}</td>";
1355 echo "<td>${obj['barcode']}</td></tr>";
1356 $order = $nextorder[$order];
1357 }
1358 echo "</table><br>\n";
1359 finishPortlet();
1360 }
1361
1362 function 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
1385 function 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
1411 function 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>';
1440 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
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>";
1448 echo "<td>${obj['barcode']}</td>";
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
1462 function 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
1474 function 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.
1485 function 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
1537 function 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
1609 function 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
1627 function renderAddNewRange ()
1628 {
1629 global $root, $pageno, $tabno;
1630 showMessageOrError();
1631
1632 echo "<center><h2>Add New Range</h2></center>\n";
1633 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
1634 echo "<tr><th>Address range</th><th>Name</th><th>C&gt;*</th><th>&nbsp;</th></tr>\n";
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";
1641 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' checked></td>\n";
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";
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']);
1652 $usedips = count ($range['addrlist']);
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;
1666 #echo "</td></tr></table>";
1667 echo "</td></tr>";
1668 }
1669 }
1670
1671 function renderIPRange ()
1672 {
1673 global $root;
1674 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
1675 $id = $_REQUEST['id'];
1676 if (isset($_REQUEST['pg']))
1677 $page = $_REQUEST['pg'];
1678 else
1679 $page=0;
1680
1681 $range = getIPRange($id);
1682 echo "<center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></center>\n";
1683
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 {
1691 $numpages = ($endip - $startip)/$maxperpage;
1692 $startip = $startip + $page * $maxperpage;
1693 $endip = $startip + $maxperpage-1;
1694 }
1695 echo "<center>";
1696 if ($numpages)
1697 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
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 {
1713 if (isset ($range['addrlist'][$ip]))
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 {
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>; ";
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
1752 function 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
1769 function 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
1826 function 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
1845 function 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
1929 function 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();
1937 echo "<center><h2>locally performed NAT</h2></center>";
1938
1939 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1940 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
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>";
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>";
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'>";
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'] . ')';
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)
1980 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}: ") .
1981 "${addr['ip']}" . (empty ($addr['address_name']) ? '' : " (${addr['address_name']})") . "</option>";
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
1991 echo "<center><h2>arriving NAT connections</h2></center>";
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
2022 function renderAddMultipleObjectsForm ()
2023 {
2024 global $pageno, $tabno, $nextorder;
2025
2026 $type_id = array();
2027 $global_type_id = 0;
2028 $name = array();
2029 $asset_no = array();
2030 $keepvalues = FALSE;
2031 $log = array();
2032 // Look for current submit.
2033 if (isset ($_REQUEST['got_fast_data']))
2034 {
2035 $keepvalues = TRUE;
2036 $max = getConfigVar ('MASSCOUNT');
2037 for ($i = 0; $i < $max; $i++)
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 }
2064 }
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);
2100
2101 // Render a form for the next.
2102 $typelist = getObjectTypeList();
2103 $typelist[0]['dict_key'] = 0;
2104 $typelist[0]['dict_value'] = 'select type...';
2105
2106 startPortlet ('Fast way');
2107 echo '<form>';
2108 echo "<input type=hidden name=page value=${pageno}>";
2109 echo "<input type=hidden name=tab value=${tabno}>";
2110 echo '<table border=0 align=center>';
2111 echo "<tr><th>Object type</th><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th></tr>\n";
2112 // If a user forgot to select object type on input, we keep his
2113 // previous input in the form.
2114 $max = getConfigVar ('MASSCOUNT');
2115 for ($i = 0; $i < $max; $i++)
2116 {
2117 echo '<tr><td>';
2118 printSelect ($typelist, "${i}_object_type_id", 0);
2119 echo '</td>';
2120 echo "<td><input type=text size=30 name=${i}_object_name";
2121 if ($keepvalues and $type_id[$i] == 0)
2122 echo " value='${name[$i]}'";
2123 echo "></td>";
2124 echo "<td><input type=text size=30 name=${i}_object_label";
2125 if ($keepvalues and $type_id[$i] == 0)
2126 echo " value='${label[$i]}'";
2127 echo "></td>";
2128 echo "<td><input type=text size=20 name=${i}_object_asset_no";
2129 if ($keepvalues and $type_id[$i] == 0)
2130 echo " value='${asset_no[$i]}'";
2131 echo "></td>";
2132 echo "<td><input type=text size=10 name=${i}_object_barcode";
2133 if ($keepvalues and $type_id[$i] == 0)
2134 echo " value='${barcode[$i]}'";
2135 echo "></td>";
2136 echo "</tr>\n";
2137 }
2138 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
2139 echo "</form></table>\n";
2140 finishPortlet();
2141
2142 startPortlet ('Very fast way');
2143 echo '<form>';
2144 echo "<input type=hidden name=page value=${pageno}>";
2145 echo "<input type=hidden name=tab value=${tabno}>";
2146 echo 'For each line shown below create an object of type ';
2147 printSelect ($typelist, "global_type_id", 0);
2148 echo " <input type=submit name=got_very_fast_data value='Go!'><br>\n";
2149 echo "<textarea name=namelist cols=40 rows=25>\n";
2150 if ($keepvalues and $global_type_id == 0)
2151 echo $_REQUEST['namelist'];
2152 echo "</textarea></form>\n";
2153 finishPortlet();
2154 }
2155
2156 function printGreeting ()
2157 {
2158 global $remote_username, $accounts, $root;
2159 $account = $accounts[$remote_username];
2160 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
2161 }
2162
2163 function renderSearchResults ()
2164 {
2165 global $remote_username, $root;
2166 $terms = trim ($_REQUEST['q']);
2167 if (empty ($terms))
2168 {
2169 showError ('Search string cannot be empty.');
2170 return;
2171 }
2172 if (!authorized ($remote_username, 'object', 'default'))
2173 {
2174 showError ('You are not authorized for viewing information about objects.');
2175 return;
2176 }
2177 // If we search for L2 address, we can either find one or find none.
2178 if
2179 (
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) or
2182 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)
2183 )
2184 // Search for L2 address.
2185 {
2186 $result = searchByl2address ($terms);
2187 if ($result !== NULL)
2188 {
2189 echo "<script language='Javascript'>document.location='${root}?page=object";
2190 echo "&hl_port_id=${result['port_id']}";
2191 echo "&object_id=${result['object_id']}';//</script>";
2192 }
2193 else
2194 echo "L2 address '${terms}' not found!";
2195 }
2196 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))
2197 // STP bridge ID: bridge priotity + port MAC address. Cut off first 4 chars and look for MAC address.
2198 {
2199 $terms = substr ($terms, 4);
2200 $result = searchByl2address ($terms);
2201 if ($result !== NULL)
2202 {
2203 echo "<script language='Javascript'>document.location='${root}?page=object";
2204 echo "&hl_port_id=${result['port_id']}";
2205 echo "&object_id=${result['object_id']}';//</script>";
2206 }
2207 else
2208 echo "L2 address '${terms}' not found!";
2209 }
2210 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))
2211 // Search for IP address.
2212 {
2213 $result = getRangeByIp ($terms);
2214 if ($result !== NULL)
2215 {
2216 echo "<script language='Javascript'>document.location='${root}?page=ipaddress";
2217 echo "&ip=${terms}";
2218 echo "';//</script>";
2219 }
2220 else
2221 echo "IP address '${terms}' not found!";
2222 return;
2223 }
2224 else
2225 // Search for objects.
2226 {
2227 $objects = getSearchResults ($terms);
2228 if (count ($objects) == 1)
2229 {
2230 $obj = current ($objects);
2231 echo "<script language='Javascript'>document.location='${root}?page=object&object_id=${obj['id']}';//</script>";
2232 }
2233 elseif (count ($objects) > 1)
2234 {
2235 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
2236 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>barcode</th></tr>';
2237 $order = 'odd';
2238 global $nextorder;
2239 foreach ($objects as $obj)
2240 {
2241 echo "<tr class=row_${order}><td><a href=\"${root}?page=object&object_id=${obj['id']}\">${obj['dname']}</a></td>";
2242 echo "<td>${obj['label']}</td>";
2243 echo "<td>${obj['asset_no']}</td>";
2244 echo "<td>${obj['barcode']}</td></tr>";
2245 $order = $nextorder[$order];
2246 }
2247 echo '</table>';
2248 }
2249 else
2250 echo "Object '${terms}' not found!";
2251 }
2252 }
2253
2254 // This function prints a table of checkboxes to aid the user in toggling mount atoms
2255 // from one state to another. The first argument is rack data as
2256 // produced by getRackData(), the second is the value used for the 'unckecked' state
2257 // and the third is the value used for 'checked' state.
2258 // Usage contexts:
2259 // for mounting an object: printAtomGrid ($data, 'F', 'T')
2260 // for changing rack design: printAtomGrid ($data, 'A', 'F')
2261 // for adding rack problem: printAtomGrid ($data, 'F', 'U')
2262 // for adding object problem: printAtomGrid ($data, 'T', 'W')
2263
2264 function renderAtomGrid ($data)
2265 {
2266 $rack_id = $data['id'];
2267 for ($unit_no = $data['height']; $unit_no > 0; $unit_no--)
2268 {
2269 echo "<tr><th>${unit_no}</th>";
2270 for ($locidx = 0; $locidx < 3; $locidx++)
2271 {
2272 $state = $data[$unit_no][$locidx]['state'];
2273 echo "<td class=state_${state}";
2274 if (isset ($data[$unit_no][$locidx]['hl']))
2275 echo $data[$unit_no][$locidx]['hl'];
2276 echo ">";
2277 if (!($data[$unit_no][$locidx]['enabled'] === TRUE))
2278 echo '<input type=checkbox disabled>';
2279 else
2280 echo "<input type=checkbox" . $data[$unit_no][$locidx]['checked'] . " name=atom_${rack_id}_${unit_no}_${locidx}>";
2281 echo '</td>';
2282 }
2283 echo "</tr>\n";
2284 }
2285 }
2286
2287 function renderPermissions ()
2288 {
2289 startPortlet ('User permissions');
2290 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2291 echo "<tr><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>";
2292 global $perms, $nextorder;
2293 $order = 'odd';
2294 foreach ($perms as $username => $pages)
2295 foreach ($pages as $page => $tabs)
2296 foreach ($tabs as $tab => $access)
2297 {
2298 echo "<tr class=row_${order}><td class=tdleft>$username</td><td>$page</td><td>$tab</td><td>$access</td></tr>\n";
2299 $order = $nextorder[$order];
2300 }
2301 echo "</table>\n";
2302 finishPortlet();
2303 }
2304
2305 function renderAccounts ()
2306 {
2307 global $nextorder, $accounts;
2308 startPortlet ('User accounts');
2309 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2310 echo "<tr><th class=tdleft>Username</th><th class=tdleft>Real name</th></tr>";
2311 $order = 'odd';
2312 foreach ($accounts as $user)
2313 {
2314 echo "<tr class=row_${order}><td class=tdleft>${user['user_name']}</td><td class=tdleft>${user['user_realname']}</td></li>";
2315 $order = $nextorder[$order];
2316 }
2317 echo '</table>';
2318 finishPortlet();
2319 }
2320
2321 function renderAccountsEditForm ()
2322 {
2323 global $root, $pageno, $tabno, $accounts;
2324 startPortlet ('User accounts');
2325 showMessageOrError();
2326 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2327 echo "<tr><th>op</th><th>Username</th><th>Real name</th><th>Password</th><th>&nbsp;</th></tr>\n";
2328 foreach ($accounts as $account)
2329 {
2330 echo "<form action='${root}process.php'>";
2331 echo "<input type=hidden name=op value=updateAccount>";
2332 echo "<input type=hidden name=page value='${pageno}'>\n";
2333 echo "<input type=hidden name=tab value='${tabno}'>\n";
2334 echo "<input type=hidden name=id value='${account['user_id']}'><tr>";
2335 echo "<td>";
2336 if ($account['user_enabled'] == 'yes' && $account['user_id'] != 1)
2337 {
2338 echo "<a href='${root}process.php?op=disableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2339 printImageHREF ('blockuser', 'disable account');
2340 echo "</a>\n";
2341 }
2342 if ($account['user_enabled'] == 'no' && $account['user_id'] != 1)
2343 {
2344 echo "<a href='${root}process.php?op=enableAccount&page=${pageno}&tab=${tabno}&id=${account['user_id']}'>";
2345 printImageHREF ('unblockuser', 'enable account');
2346 echo "</a>\n";
2347 }
2348 // Otherwise skip icon.
2349 echo "</td>";
2350 echo "<td><input type=text name=username value='${account['user_name']}' size=16></td>";
2351 echo "<td><input type=text name=realname value='${account['user_realname']}' size=24></td>";
2352 echo "<td><input type=password name=password value='${account['user_password_hash']}' size=64></td>";
2353 echo "<td><input type='submit' value='OK'></td>";
2354 echo "</form></tr>\n";
2355 }
2356 echo "<form action='${root}process.php' method=post><tr>";
2357 echo "<input type=hidden name=op value=createAccount>\n";
2358 echo "<input type=hidden name=page value='${pageno}'>\n";
2359 echo "<input type=hidden name=tab value='${tabno}'>\n";
2360 echo "<td colspan=2><input type=text size=16 name=username tabindex=100></td>\n";
2361 echo "<td><input type=text size=24 name=realname tabindex=101></td>";
2362 echo "<td><input type=password size=64 name=password tabindex=102></td>";
2363 echo "<td colspan=4><input type=submit value='Create account' tabindex=103></td></tr></form>";
2364 echo "</table><br>\n";
2365 finishPortlet();
2366 }
2367
2368 function printChildrenAsOptions ($root, $depth = 0)
2369 {
2370 echo "<option value=${root['title']}>";
2371 if ($depth == 0)
2372 echo '* ';
2373 for ($i = 0; $i < $depth; $i++)
2374 echo '-- ';
2375 echo $root['title'];
2376 echo "</option>\n";
2377 foreach ($root['kids'] as $kid)
2378 printChildrenAsOptions ($kid, $depth + 1);
2379 }
2380
2381 // 1. Find all parentless pages.
2382 // 2. For each of them recursively find all children.
2383 // 3. Output the tree with recursion tree display.
2384 function printPagesTree ()
2385 {
2386 global $page;
2387 echo '<pre>';
2388 foreach ($page as $ctitle => $cpage)
2389 if (!isset ($cpage['parent']))
2390 {
2391 $croot['title'] = $ctitle;
2392 $croot['kids'] = getAllChildPages ($ctitle);
2393 printChildrenAsOptions ($croot);
2394 }
2395 echo '</pre>';
2396 }
2397
2398 function renderPermissionsEditForm ()
2399 {
2400 global $root, $pageno, $tabno, $perms, $accounts;
2401 startPortlet ('User permissions');
2402 showMessageOrError();
2403 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
2404 echo "<tr><th>&nbsp;</th><th>Username</th><th>Page</th><th>Tab</th><th>Access</th></tr>\n";
2405 foreach ($perms as $username => $pages)
2406 foreach ($pages as $access_page => $tabs)
2407 foreach ($tabs as $access_tab => $access)
2408 {
2409 echo "<td>";
2410 if ($username != '%')
2411 $userid = $accounts[$username]['user_id'];
2412 else
2413 $userid = 0;
2414 echo "<a href='${root}process.php?op=revoke&page=${pageno}&tab=${tabno}&access_userid=${userid}&access_page=${access_page}&access_tab=${access_tab}'>";
2415 printImageHREF ('revoke', 'Revoke permission');
2416 echo "</a></td>";
2417 echo "<td>${username}</td>";
2418 echo "<td>${access_page}</td>";
2419 echo "<td>${access_tab}</td>";
2420 echo "<td>${access}</td>";
2421 echo "</tr>\n";
2422 }
2423 echo "<form action='${root}process.php' method=post><tr>";
2424 echo "<input type=hidden name=op value=grant>\n";
2425 echo "<input type=hidden name=page value='${pageno}'>\n";
2426 echo "<input type=hidden name=tab value='${tabno}'>\n";
2427 // FIXME: border=0 doesn't work here for unknown reason
2428 echo "<td>";
2429 printImageHREF ('grant', '', TRUE, 103);
2430 echo "</td>";
2431 echo "<td><select name=access_userid>";
2432 echo "<option value=0>ANY</option>";
2433 foreach ($accounts as $account)
2434 echo "<option value=${account['user_id']}>${account['user_name']}</option>";
2435 echo "</select></td>\n";
2436 echo "<td><select name=access_page>";
2437 echo "<option value='%'>ANY</option>";
2438 printPagesTree();
2439 echo "</select></td>";
2440 echo "<td><input type=text size=16 name=access_tab tabindex=102 value=default></td>";
2441 echo "<td><input type=radio name=access_value value=no checked>no <input type=radio name=access_value value=yes>yes</td>";
2442 echo "</tr></form>";
2443 echo "</table><br>\n";
2444 finishPortlet();
2445 }
2446
2447 function renderPortMap ($editable = FALSE)
2448 {
2449 global $nextorder, $root, $pageno, $tabno;
2450 showMessageOrError();
2451 startPortlet ("Port compatibility map");
2452 $ptlist = getPortTypes();
2453 $pclist = getPortCompat();
2454 $pctable = buildPortCompatMatrixFromList ($ptlist, $pclist);
2455 if ($editable)
2456 {
2457 echo "<form method=post action='${root}process.php'>";
2458 echo "<input type=hidden name=page value='${pageno}'>";
2459 echo "<input type=hidden name=tab value='${tabno}'>";
2460 echo "<input type=hidden name=op value=save>";
2461 }
2462 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2463 echo "<tr><th class=vert_th>&nbsp;</th>";
2464 foreach ($ptlist as $name2)
2465 echo "<th>to ${name2}</th>";
2466 echo "</tr>";
2467 // Make a copy to have an independent array pointer.
2468 $ptlistY = $ptlist;
2469 $order = 'odd';
2470 foreach ($ptlistY as $type1 => $name1)
2471 {
2472 echo "<tr class=row_${order}><th class=vert_th style='border-bottom: 0px;'>from $name1</th>";
2473 foreach ($ptlist as $type2 => $name2)
2474 {
2475 echo '<td><input type=checkbox' . ($editable ? " name=atom_${type1}_${type2}" : ' disabled');
2476 echo ($pctable[$type1][$type2] ? ' checked' : '') . '></td>';
2477 }
2478 echo "</tr>\n";
2479 $order = $nextorder[$order];
2480 }
2481 echo '</table><br>';
2482 if ($editable)
2483 {
2484 echo "<input type=submit value='Save changes'>";
2485 echo "</form>";
2486 }
2487 finishPortlet();
2488 }
2489
2490 function renderConfigMainpage ()
2491 {
2492 global $pageno, $root;
2493 $children = getDirectChildPages ($pageno);
2494 echo '<ul>';
2495 foreach ($children as $cpageno => $child)
2496 {
2497 $ctitle = $child['title']($cpageno);
2498 echo "<li><a href='${root}?page=${cpageno}'>" . $ctitle['name'] . "</li>\n";
2499 }
2500 echo '';
2501 echo '</ul>';
2502 }
2503
2504 function renderRackPage ($rack_id)
2505 {
2506 if ($rack_id == 0)
2507 {
2508 showError ('Invalid rack_id in renderRack()');
2509 return;
2510 }
2511 if (($rackData = getRackData ($rack_id)) == NULL)
2512 {
2513 showError ('getRackData() failed in renderRack()');
2514 return;
2515 }
2516 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
2517
2518 // Left column with information.
2519 echo "<td class=pcleft>";
2520 startPortlet ('Rack information');
2521 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
2522 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
2523 echo "<tr><th width='50%' class=tdright>Name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
2524 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
2525 if (!empty ($rackData['comment']))
2526 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
2527 echo '</table>';
2528 finishPortlet();
2529 echo '</td>';
2530
2531 // Right column with rendered rack.
2532 echo '<td>';
2533 startPortlet ('Rack diagram');
2534 renderRack ($rack_id);
2535 finishPortlet();
2536 echo '</td>';
2537
2538 echo '</tr></table>';
2539 }
2540
2541 function renderDictionary ()
2542 {
2543 global $nextorder;
2544 $dict = getDict();
2545 echo "<table border=0><tr>";
2546 foreach ($dict as $chapter)
2547 {
2548 echo "<td class=pcleft>";
2549 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2550 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2551 $order = 'odd';
2552 foreach ($chapter['word'] as $key => $value)
2553 {
2554 echo "<tr class=row_${order}><td class=tdleft><div title='key=${key}'>${value}</div></td></tr>";
2555 $order = $nextorder[$order];
2556 }
2557 echo "</table>";
2558 finishPortlet();
2559 echo "</td>";
2560 }
2561 echo "</tr></table>";
2562 }
2563
2564 function renderDictionaryEditor ()
2565 {
2566 global $root, $pageno, $tabno;
2567 showMessageOrError();
2568 $dict = getDict();
2569 echo "<table border=0><tr>";
2570 foreach ($dict as $chapter)
2571 {
2572 echo "<td class=pcleft>";
2573 startPortlet ($chapter['name'] . ' (' . count ($chapter['word']) . ')');
2574 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2575 foreach ($chapter['word'] as $key => $value)
2576 {
2577 echo "<form action='${root}process.php' method=post>";
2578 echo "<input type=hidden name=page value='${pageno}'>";
2579 echo "<input type=hidden name=tab value='${tabno}'>";
2580 echo "<input type=hidden name=op value='upd'>";
2581 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2582 echo "<input type=hidden name=dict_key value='${key}'>";
2583 echo '<tr>';
2584 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}&dict_key=${key}'>";
2585 printImageHREF ('delete', 'Delete word');
2586 echo "</a></td>";
2587 echo "<td class=tdright><input type=text name=dict_value size=32 value='${value}'></td>";
2588 echo "<td><input type=submit value=OK></td>";
2589 echo '</tr></form>';
2590 }
2591 echo "<form action='${root}process.php' method=post>";
2592 echo "<input type=hidden name=page value='${pageno}'>";
2593 echo "<input type=hidden name=tab value='${tabno}'>";
2594 echo "<input type=hidden name=op value=add>";
2595 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2596 echo '<tr>';
2597 echo "<td>&nbsp;</td>";
2598 echo "<td class=tdright><input type=text name=dict_value size=32></td>";
2599 echo "<td><input type=submit value=OK></td>";
2600 echo '</tr></form>';
2601 echo "</table>";
2602 finishPortlet();
2603 echo "</td>";
2604 }
2605 echo "</tr></table>";
2606 }
2607
2608 // We don't allow to rename/delete a sticky chapter and we don't allow
2609 // to delete a non-empty chapter.
2610 function renderChaptersEditor ()
2611 {
2612 global $root, $pageno, $tabno;
2613 showMessageOrError();
2614 $dict = getDict();
2615 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2616 echo '<tr><th>&nbsp;</th><th>Chapter name</th><th>Words</th><th>&nbsp;</th></tr>';
2617 foreach ($dict as $chapter)
2618 {
2619 $wordcount = count ($chapter['word']);
2620 $sticky = $chapter['sticky'];
2621 echo "<form action='${root}process.php' method=post>";
2622 echo "<input type=hidden name=page value='${pageno}'>";
2623 echo "<input type=hidden name=tab value='${tabno}'>";
2624 echo "<input type=hidden name=op value=upd>";
2625 echo "<input type=hidden name=chapter_no value='${chapter['no']}'>";
2626 echo '<tr>';
2627 echo '<td>';
2628 if ($sticky or $wordcount > 0)
2629 echo '&nbsp;';
2630 else
2631 {
2632 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&chapter_no=${chapter['no']}'>";
2633 printImageHREF ('delete', 'Remove chapter');
2634 echo "</a>";
2635 }
2636 echo '</td>';
2637 echo "<td><input type=text name=chapter_name value='${chapter['name']}'" . ($sticky ? ' disabled' : '') . "></td>";
2638 echo "<td class=tdleft>${wordcount}</td><td>";
2639 if ($sticky)
2640 echo '&nbsp;';
2641 else
2642 echo "<input type=submit value='OK'>";
2643 echo '</td></tr>';
2644 echo '</form>';
2645 }
2646 echo "<form action='${root}process.php' method=post>";
2647 echo "<input type=hidden name=page value='${pageno}'>";
2648 echo "<input type=hidden name=tab value='${tabno}'>";
2649 echo "<input type=hidden name=op value=add>";
2650 echo '<tr><td>';
2651 printImageHREF ('add', '', TRUE);
2652 echo "</td><td colspan=3><input type=text name=chapter_name></td>";
2653 echo '</tr>';
2654 echo '</form>';
2655 echo "</table>\n";
2656 }
2657
2658 function renderAttributes ()
2659 {
2660 global $nextorder;
2661 $attrMap = getAttrMap();
2662 startPortlet ('Optional attributes');
2663 echo "<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center>\n";
2664 echo "<tr><th class=tdleft>Attribute name</th><th class=tdleft>Attribute type</th><th class=tdleft>Applies to</th></tr>";
2665 $order = 'odd';
2666 foreach ($attrMap as $attr)
2667 {
2668 echo "<tr class=row_${order}>";
2669 echo "<td class=tdleft>${attr['name']}</td>";
2670 echo "<td class=tdleft>${attr['type']}</td>";
2671 echo '<td class=tdleft>';
2672 if (count ($attr['application']) == 0)
2673 echo '&nbsp;';
2674 else
2675 foreach ($attr['application'] as $app)
2676 if ($attr['type'] == 'dict')
2677 echo "${app['objtype_name']} (values from '${app['chapter_name']}')<br>";
2678 else
2679 echo "${app['objtype_name']}<br>";
2680 echo '</td>';
2681 echo "</tr>\n";
2682 $order = $nextorder[$order];
2683 }
2684 echo "</table><br>\n";
2685 finishPortlet();
2686 }
2687
2688 function renderEditAttributesForm ()
2689 {
2690 global $root, $pageno, $tabno;
2691 $attrMap = getAttrMap();
2692 showMessageOrError();
2693 startPortlet ('Optional attributes');
2694 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2695 echo '<tr><th>&nbsp;</th><th>Name</th><th>Type</th><th>&nbsp;</th></tr>';
2696 foreach ($attrMap as $attr)
2697 {
2698 echo "<form action='${root}process.php' method=post>";
2699 echo "<input type=hidden name=page value='${pageno}'>";
2700 echo "<input type=hidden name=tab value='${tabno}'>";
2701 echo "<input type=hidden name=op value=upd>";
2702 echo "<input type=hidden name=attr_id value='${attr['id']}'>";
2703 echo '<tr>';
2704 echo "<td><a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&attr_id=${attr['id']}'>";
2705 printImageHREF ('delete', 'Remove attribute');
2706 echo '</a></td>';
2707 echo "<td><input type=text name=attr_name value='${attr['name']}'></td>";
2708 echo "<td>${attr['type']}</td>";
2709 echo "<td><input type=submit value='OK'></td>";
2710 echo '</tr>';
2711 echo '</form>';
2712 }
2713 echo "<form action='${root}process.php' method=post>";
2714 echo "<input type=hidden name=page value='${pageno}'>";
2715 echo "<input type=hidden name=tab value='${tabno}'>";
2716 echo "<input type=hidden name=op value=add>";
2717 echo '<tr><td>';
2718 printImageHREF ('add', '', TRUE);
2719 echo "</td><td><input type=text name=attr_name></td>";
2720 echo '<td><select name=attr_type>';
2721 echo '<option value=uint>uint</option>';
2722 echo '<option value=float>float</option>';
2723 echo '<option value=string>string</option>';
2724 echo '<option value=dict>dict</option>';
2725 echo '</select></td>';
2726 echo '</tr>';
2727 echo '</form>';
2728 echo "</table>\n";
2729 finishPortlet();
2730 }
2731
2732 function renderEditAttrMapForm ()
2733 {
2734 global $root, $pageno, $tabno;
2735 $attrMap = getAttrMap();
2736 showMessageOrError();
2737 startPortlet ('Attribute map');
2738 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
2739 echo '<tr><th>&nbsp;</th><th>Attribute name</th><th>Object type</th><th>Dictionary chapter</th></tr>';
2740 foreach ($attrMap as $attr)
2741 {
2742 if (count ($attr['application']) == 0)
2743 continue;
2744 foreach ($attr['application'] as $app)
2745 {
2746 echo '<tr>';
2747 echo '<td>';
2748 echo "<a href='${root}process.php?page=${pageno}&tab=${tabno}&op=del&";
2749 echo "attr_id=${attr['id']}&objtype_id=${app['objtype_id']}'>";
2750 printImageHREF ('delete', 'Remove mapping');
2751 echo "</a>";
2752 echo '</td>';
2753 echo "<td>${attr['name']}</td>";
2754 echo "<td>${app['objtype_name']}</td>";
2755 echo "<td>";
2756 if ($attr['type'] == 'dict')
2757 echo "${app['chapter_name']}";
2758 else
2759 echo '&nbsp;';
2760 echo "</td></tr>\n";
2761 }
2762 }
2763 echo "<form action='${root}process.php' method=post>";
2764 echo "<input type=hidden name=page value='${pageno}'>";
2765 echo "<input type=hidden name=tab value='${tabno}'>";
2766 echo "<input type=hidden name=op value=add>";
2767 echo '<tr><td>';
2768 printImageHREF ('add', '', TRUE);
2769 echo "</td><td><select name=attr_id>";
2770 $shortType['uint'] = 'U';
2771 $shortType['float'] = 'F';
2772 $shortType['string'] = 'S';
2773 $shortType['dict'] = 'D';
2774 foreach ($attrMap as $attr)
2775 echo "<option value=${attr['id']}>[" . $shortType[$attr['type']] . "] ${attr['name']}</option>";
2776 echo "</select></td>";
2777 echo '<td>';
2778 printSelect (getObjectTypeList(), 'objtype_id');
2779 echo '</td>';
2780 $dict = getDict();
2781 echo '<td><select name=chapter_no>';
2782 foreach ($dict as $chapter)
2783 if (!$chapter['sticky'])
2784 echo "<option value='${chapter['no']}'>${chapter['name']}</option>";
2785 echo '</select></td>';
2786 echo '</tr>';
2787 echo '</form>';
2788 echo "</table>\n";
2789 finishPortlet();
2790 }
2791
2792 function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
2793 {
2794 global $root;
2795 $image['error']['path'] = 'pix/error.png';
2796 $image['error']['width'] = 76;
2797 $image['error']['height'] = 17;
2798 $image['logo']['path'] = 'pix/defaultlogo.png';
2799 $image['logo']['width'] = 210;
2800 $image['logo']['height'] = 40;
2801 $image['rackspace']['path'] = 'pix/racks.png';
2802 $image['rackspace']['width'] = 218;
2803 $image['rackspace']['height'] = 200;
2804 $image['objects']['path'] = 'pix/server.png';
2805 $image['objects']['width'] = 218;
2806 $image['objects']['height'] = 200;
2807 $image['ipv4space']['path'] = 'pix/addressspace.png';
2808 $image['ipv4space']['width'] = 218;
2809 $image['ipv4space']['height'] = 200;
2810 $image['config']['path'] = 'pix/configuration.png';
2811 $image['config']['width'] = 218;
2812 $image['config']['height'] = 200;
2813 $image['reports']['path'] = 'pix/report.png';
2814 $image['reports']['width'] = 218;
2815 $image['reports']['height'] = 200;
2816 $image['help']['path'] = 'pix/help.png';
2817 $image['help']['width'] = 218;
2818 $image['help']['height'] = 200;
2819 $image['reserve']['path'] = 'pix/stop.png';
2820 $image['reserve']['width'] = 16;
2821 $image['reserve']['height'] = 16;
2822 $image['useup']['path'] = 'pix/go.png';
2823 $image['useup']['width'] = 16;
2824 $image['useup']['height'] = 16;
2825 $image['blockuser'] = $image['reserve'];
2826 $image['unblockuser'] = $image['useup'];
2827 $image['link']['path'] = 'pix/link.png';
2828 $image['link']['width'] = 24;
2829 $image['link']['height'] = 24;
2830 $image['unlink']['path'] = 'pix/unlink.png';
2831 $image['unlink']['width'] = 24;
2832 $image['unlink']['height'] = 24;
2833 $image['add']['path'] = 'pix/greenplus.png';
2834 $image['add']['width'] = 16;
2835 $image['add']['height'] = 16;
2836 $image['delete']['path'] = 'pix/delete_s.gif';
2837 $image['delete']['width'] = 16;
2838 $image['delete']['height'] = 16;
2839 $image['grant'] = $image['add'];
2840 $image['revoke'] = $image['delete'];
2841 $image['helphint']['path'] = 'pix/helphint.png';
2842 $image['helphint']['width'] = 24;
2843 $image['helphint']['height'] = 24;
2844 if (!isset ($image[$tag]))
2845 $tag = 'error';
2846 $img = $image[$tag];
2847 if ($do_input == TRUE)
2848 echo
2849 "<input type=image name=submit " .
2850 "src='${root}${img['path']}' " .
2851 "border=0 " .
2852 ($tabindex ? '' : "tabindex=${tabindex}") .
2853 ">";
2854 else
2855 echo
2856 "<img " .
2857 "src='${root}${img['path']}' " .
2858 "width=${img['width']} " .
2859 "height=${img['height']} " .
2860 "border=0 " .
2861 (empty ($title) ? '' : "title='${title}'") .
2862 ">";
2863 }
2864
2865 // This function returns URL for favourite icon.
2866 function getFaviconURL ()
2867 {
2868 global $root;
2869 return $root . 'pix/racktables.ico';
2870 }
2871
2872 function renderReportSummary ()
2873 {
2874 startPortlet ("Here be dragons");
2875 dragon();
2876 dragon();
2877 dragon();
2878 echo 'ASCII art &copy; Daniel C. Au';
2879 finishPortlet();
2880 }
2881
2882 function dragon ()
2883 {
2884 ?>
2885 <div class=dragon><pre><font color="#00ff33">
2886 \||/
2887 | <font color="#ff0000">@</font>___oo
2888 /\ /\ / (__<font color=yellow>,,,,</font>|
2889 ) /^\) ^\/ _)
2890 ) /^\/ _)
2891 ) _ / / _)
2892 /\ )/\/ || | )_)
2893 &lt; &gt; |(<font color=white>,,</font>) )__)
2894 || / \)___)\
2895 | \____( )___) )___
2896 \______(_______<font color=white>;;;</font> __<font color=white>;;;</font>
2897
2898 </font></pre></div>
2899 <?php
2900 }
2901
2902 function renderUIConfig ()
2903 {
2904 global $configCache, $nextorder;
2905 showMessageOrError();
2906 startPortlet ('Current configuration');
2907 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
2908 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
2909 $order = 'odd';
2910 foreach ($configCache as $v)
2911 {
2912 if ($v['is_hidden'] != 'no')
2913 continue;
2914 echo "<tr class=row_${order}>";
2915 echo "<td class=tdright>${v['description']}</td>\n";
2916 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
2917 $order = $nextorder[$order];
2918 }
2919 echo "</table>\n";
2920 finishPortlet();
2921 }
2922
2923 function renderUIConfigEditForm ()
2924 {
2925 global $root, $pageno, $tabno, $configCache;
2926 showMessageOrError();
2927 startPortlet ('Current configuration');
2928 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
2929 echo "<tr><th class=tdleft>Option</th>";
2930 echo "<th class=tdleft>Value</th></tr>";
2931 echo "<form action='${root}process.php'>";
2932 echo "<input type=hidden name=op value='upd'>";
2933 echo "<input type=hidden name=page value='${pageno}'>\n";
2934 echo "<input type=hidden name=tab value='${tabno}'>\n";
2935
2936 $i = 0;
2937 foreach ($configCache as $v)
2938 {
2939 if ($v['is_hidden'] != 'no')
2940 continue;
2941 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
2942 echo "<tr><td class=tdright>${v['description']}</td>";
2943 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
2944 echo "</tr>\n";
2945 $i++;
2946 }
2947 echo "<input type=hidden name=num_vars value=${i}>\n";
2948 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
2949 echo "</form>";
2950 finishPortlet();
2951 }
2952
2953 // This function queries the gateway about current VLAN configuration and
2954 // renders a form suitable for submit. Ah, and it does submit processing as well.
2955 function renderVLANMembership ($object_id = 0)
2956 {
2957 global $root, $pageno, $tabno, $remote_username;
2958 if ($object_id <= 0)
2959 {
2960 showError ('Invalid object_id in renderVLANMembership()');
2961 return;
2962 }
2963
2964 // Handle probable pending submit.
2965 if (isset ($_REQUEST['portcount']))
2966 {
2967 $data = getSwitchVLANs ($object_id);
2968 if ($data === NULL)
2969 {
2970 showError ('getSwitchVLANs() failed in renderVLANMembership() during submit processing');
2971 return;
2972 }
2973 list ($vlanlist, $portlist) = $data;
2974 // Here we just build up 1 set command for the gateway with all of the ports
2975 // included. The gateway is expected to filter unnecessary changes silently
2976 // and to provide a list of responses with either error or success message
2977 // for each of the rest.
2978 assertUIntArg ('portcount');
2979 $nports = $_REQUEST['portcount'];
2980 $prefix = 'set ';
2981 $log = array();
2982 $setcmd = '';
2983 for ($i = 0; $i < $nports; $i++)
2984 if
2985 (
2986 !isset ($_REQUEST['portname_' . $i]) ||
2987 !isset ($_REQUEST['vlanid_' . $i]) ||
2988 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
2989 )
2990 $log[] = array ('code' => 'error', 'message' => "Ignoring mailformed record #${i} in form submit");
2991 elseif
2992 (
2993 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
2994 $portlist[$i]['vlaind'] == 'TRUNK'
2995 )
2996 continue;
2997 else
2998 {
2999 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3000 $prefix = ';';
3001 }
3002 printLog ($log);
3003 // Feed the gateway and interpret its (non)response.
3004 if ($setcmd != '')
3005 printLog (setSwitchVLANs ($object_id, $setcmd));
3006 }
3007
3008 // Reload and render.
3009 $data = getSwitchVLANs ($object_id);
3010 if ($data === NULL)
3011 return;
3012 list ($vlanlist, $portlist, $maclist) = $data;
3013
3014 // This table divides the space into 2 columns.
3015 echo '<table border=0 width="100%"><tr><td class=pcleft>';
3016
3017 // left column: 1 portlet
3018 startPortlet ('VLAN table');
3019 echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center width="100%">';
3020 echo "<tr><th>ID</th><th>Description</th></tr>";
3021 $order = 'even';
3022 global $nextorder;
3023 foreach ($vlanlist as $id => $descr)
3024 {
3025 echo "<tr class=row_${order}><td class=tdright>${id}</td><td class=tdleft>${descr}</td></tr>";
3026 $order = $nextorder[$order];
3027 }
3028 echo '</table>';
3029 finishPortlet();
3030
3031 echo '</td><td class=pcright>';
3032 // Right column: table with 2 rows, each holding 1 portlet
3033 echo '<table border=0 width="100%"><tr><td>';
3034
3035 startPortlet ('Current status');
3036 echo "<table class=widetable cellspacing=3 cellpadding=5 align=center width='100%'><tr>";
3037 echo "<form method=post>";
3038 echo "<input type=hidden name=page value='${pageno}'>";
3039 echo "<input type=hidden name=tab value='${tabno}'>";
3040 echo "<input type=hidden name=object_id value=${object_id}>";
3041 $portcount = count ($portlist);
3042 echo "<input type=hidden name=portcount value=" . $portcount . ">\n";
3043 $portno = 0;
3044 $ports_per_row = getConfigVar ('PORTS_PER_ROW');
3045 foreach ($portlist as $port)
3046 {
3047 // Don't let wide forms break our fancy pages.
3048 if ($portno % $ports_per_row == 0)
3049 {
3050 if ($portno > 0)
3051 echo "</tr>\n";
3052 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + $ports_per_row > $portcount ? $portcount : $portno + $ports_per_row) . "</th>";
3053 }
3054 echo '<td class=port_';
3055 if ($port['status'] == 'notconnect')
3056 echo 'notconnect';
3057 elseif ($port['status'] == 'disabled')
3058 echo 'disabled';
3059 elseif ($port['status'] != 'connected')
3060 echo 'unknown';
3061 elseif (!isset ($maclist[$port['portname']]))
3062 echo 'connected_none';
3063 else
3064 {
3065 $maccount = 0;
3066 foreach ($maclist[$port['portname']] as $vlanid => $addrs)
3067 $maccount += count ($addrs);
3068 if ($maccount == 1)
3069 echo 'connected_single';
3070 else
3071 echo 'connected_multi';
3072 }
3073 echo '>' . $port['portname'] . '<br>';
3074 echo "<input type=hidden name=portname_${portno} value=" . $port['portname'] . '>';
3075 if ($port['vlanid'] == 'trunk')
3076 {
3077 echo "<input type=hidden name=vlanid_${portno} value='trunk'>";
3078 echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
3079 }
3080 else
3081 {
3082 echo "<select name=vlanid_${portno}>";
3083 foreach ($vlanlist as $v => $d)
3084 {
3085 echo "<option value=${v}";
3086 if ($v == $port['vlanid'])
3087 echo ' selected';
3088 echo ">${v}</option>";
3089 }
3090 echo "</select>";
3091 }
3092 $portno++;
3093 echo "</td>";
3094 }
3095 echo "</tr><tr><td colspan=" . ($ports_per_row + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
3096 finishPortlet();
3097
3098 echo '</td></tr><tr><td align=center>';
3099 // second row
3100 if (count ($maclist))
3101 {
3102 startPortlet ('MAC address table');
3103 echo '<table border=0 class=cooltable align=center cellspacing=0 cellpadding=5>';
3104 echo "<tr><th>Port</th><th>VLAN ID</th><th>MAC address</th></tr>\n";
3105 $order = 'even';
3106 foreach ($maclist as $portname => $portdata)
3107 foreach ($portdata as $vlanid => $addrgroup)
3108 foreach ($addrgroup as $addr)
3109 {
3110 echo "<tr class=row_${order}><td>$portname</td><td>$vlanid</td><td>$addr</td></tr>\n";
3111 $order = $nextorder[$order];
3112 }
3113 echo '</table>';
3114 finishPortlet();
3115 }
3116
3117 // End of 2-portlet table.
3118 echo '</td></tr></table>';
3119
3120 // End of main table.
3121 echo '</td></tr></table>';
3122 }
3123
3124 // This snippet either renders a form inviting the user to start SNMP query
3125 // on the current device or displays the result of the scan.
3126 function renderSNMPPortFinder ($object_id = 0)
3127 {
3128 global $root, $pageno, $tabno, $remote_username;
3129 if ($object_id <= 0)
3130 {
3131 showError ('Invalid object_id in renderSNMPPortFinder()');
3132 return;
3133 }
3134 // FIXME: check if SNMP PHP extension is available!
3135 if (isset ($_REQUEST['do_scan']))
3136 {
3137 $log = array();
3138 // IDs: http://cisco.com/en/US/products/sw/cscowork/ps2064/products_device_support_table09186a0080803bb4.html
3139 // 2960: http://www.cisco.com/en/US/products/ps6406/prod_models_comparison.html
3140 // 2970: http://cisco.com/en/US/products/hw/switches/ps5206/products_qanda_item09186a00801b1750.shtml
3141 // 3500XL: http://cisco.com/en/US/products/hw/switches/ps637/products_eol_models.html
3142 // 3560: http://cisco.com/en/US/products/hw/switches/ps5528/products_data_sheet09186a00801f3d7f.html
3143 // 3750: http://cisco.com/en/US/products/hw/switches/ps5023/products_data_sheet09186a008016136f.html
3144 $ciscomodel[283] = 'WS-C6509-E (9-slot system)';
3145 // FIXME: hwtype hardcoded value will become invalid after the Dictionary table transformation
3146 // in 0.14.7 version. Either the values will have to be adjusted as well or we have to switch
3147 // to value lookup (not reliable).
3148 $hwtype[283] = 52;
3149 # $ciscomodel[694] = 'WS-C2960-24TC-L (24 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3150 # $ciscomodel[695] = 'WS-C2960-48TC-L (48 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3151 $ciscomodel[696] = 'WS-C2960G-24TC-L (20 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
3152 $hwtype[696] = 71;
3153 $ciscomodel[697] = 'WS-C2960G-48TC-L (44 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
3154 $hwtype[697] = 70;
3155 # $ciscomodel[716] = 'WS-C2960-24TT-L (24 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
3156 # $ciscomodel[717] = 'WS-C2960-48TT-L (48 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
3157 $ciscomodel[527] = 'WS-C2970G-24T (24 Ethernet 10/100/1000 ports)';
3158 $hwtype[527] = 114;
3159 $ciscomodel[561] = 'WS-C2970G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3160 $hwtype[561] = 115;
3161 # $ciscomodel[633] = 'WS-C3560-24TS (24 Ethernet 10/100 ports and 2 10/100/1000 SFP uplinks)';
3162 # $hwtype[633] = 73;
3163 $ciscomodel[634] = 'WS-C3560-48TS (48 Ethernet 10/100 ports and 4 10/100/1000 SFP uplinks)';
3164 $hwtype[634] = 74;
3165 # $ciscomodel[563] = 'WS-C3560-24PS (24 Ethernet 10/100 POE ports and 2 10/100/1000 SFP uplinks)';
3166 # $hwtype[563] = 75;
3167 $ciscomodel[564] = 'WS-C3560-48PS (48 Ethernet 10/100 POE ports and 4 10/100/1000 SFP uplinks)';
3168 $hwtype[564] = 76;
3169 $ciscomodel[614] = 'WS-C3560G-24PS (24 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
3170 $hwtype[614] = 79;
3171 $ciscomodel[615] = 'WS-C3560G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3172 $hwtype[615] = 77;
3173 $ciscomodel[616] = 'WS-C3560G-48PS (48 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
3174 $hwtype[616] = 80;
3175 $ciscomodel[617] = 'WS-C3560G-48TS (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3176 $hwtype[617] = 78;
3177 $ciscomodel[58] = 'WS-C4503 (3-slot system)';
3178 $hwtype[58] = 49;
3179 $ciscomodel[503] = '4503 (3-slot system)';
3180 $hwtype[503] = 49;
3181 $ciscomodel[59] = 'WS-C4506 (6-slot system)';
3182 $hwtype[59] = 60;
3183 $ciscomodel[502] = '4506 (6-slot system)';
3184 $hwtype[502] = 60;
3185 $ciscomodel[626] = 'WS-C4948 (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3186 $hwtype[626] = 51;
3187 $ciscomodel[659] = 'WS-C4948-10GE (48 Ethernet 10/100/1000 ports and 2 10Gb X2 uplinks)';
3188 assertStringArg ('community');
3189 $community = $_REQUEST['community'];
3190 $objectInfo = getObjectInfo ($object_id);
3191 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
3192 $sysDescr = snmpget ($endpoints[0], $community, 'sysDescr.0');
3193 // Strip the object type, it's always string here.
3194 $sysDescr = substr ($sysDescr, strlen ('STRING: '));
3195 if (strpos ($sysDescr, 'Cisco IOS Software') === 0 or strpos ($sysDescr, 'Cisco Internetwork Operating System Software') === 0)
3196 $log[] = array ('code' => 'success', 'message' => 'Seems to be a Cisco box');
3197 else
3198 {
3199 $log[] = array ('code' => 'error', 'message' => 'No idea how to handle ' . $sysDescr);
3200 printLog ($log);
3201 return;
3202 }
3203
3204 // It's a Cisco. Go on.
3205 $attrs = getAttrValues ($object_id);
3206 // Only fill in attribute values, if they are not set.
3207 // FIXME: this is hardcoded
3208
3209 if (empty ($attrs[5]['value'])) // SW version
3210 {
3211 $IOSversion = ereg_replace ('^.*, Version ([^ ]+), .*$', '\\1', $sysDescr);
3212 $error = commitUpdateAttrValue ($object_id, 5, $IOSversion);
3213 if ($error == TRUE)
3214 $log[] = array ('code' => 'success', 'message' => 'SW version set to ' . $IOSversion);
3215 else
3216 $log[] = array ('code' => 'error', 'message' => 'Failed settig SW version: ' . $error);
3217 }
3218
3219 if (empty ($attrs[4]['value']) and substr ($IOSversion, 0, 4) == '12.2') // switch OS type
3220 {
3221 $error = commitUpdateAttrValue ($object_id, 4, 21);
3222 if ($error == TRUE)
3223 $log[] = array ('code' => 'success', 'message' => 'Switch OS type set to Cisco IOS 12.2');
3224 else
3225 $log[] = array ('code' => 'error', 'message' => 'Failed settig Switch OS type: ' . $error);
3226 }
3227
3228 $sysObjectID = snmpget ($endpoints[0], $community, 'sysObjectID.0');
3229 // Transform OID
3230 $sysObjectID = substr ($sysObjectID, strlen ('OID: SNMPv2-SMI::enterprises.9.1.'));
3231 if (!isset ($ciscomodel[$sysObjectID]))
3232 {
3233 $log[] = array ('code' => 'error', 'message' => 'Could not guess exact HW model!');
3234 printLog ($log);
3235 return;
3236 }
3237 $log[] = array ('code' => 'success', 'message' => 'HW is ' . $ciscomodel[$sysObjectID]);
3238 if (empty ($attrs[2]['value']) and isset ($hwtype[$sysObjectID])) // switch HW type
3239 {
3240 $error = commitUpdateAttrValue ($object_id, 2, $hwtype[$sysObjectID]);
3241 if ($error == TRUE)
3242 $log[] = array ('code' => 'success', 'message' => 'HW type updated Ok');
3243 else
3244 $log[] = array ('code' => 'error', 'message' => 'Failed settig HW type: ' . $error);
3245 }
3246 // Now fetch ifType, ifDescr and ifPhysAddr and let model-specific code sort the data out.
3247 $ifType = snmpwalkoid ($endpoints[0], $community, 'ifType');
3248 $ifDescr = snmpwalkoid ($endpoints[0], $community, 'ifdescr');
3249 $ifPhysAddress = snmpwalkoid ($endpoints[0], $community, 'ifPhysAddress');
3250 // Combine 3 tables into 1...
3251 $ifList1 = array();
3252 foreach ($ifType as $key => $val)
3253 {
3254 l