r1299 + added 3560G handling
[racktables] / inc / interface.php
CommitLineData
b325120a 1<?php
e673ee24
DO
2/*
3*
4* This file contains frontend functions for RackTables.
5*
6*/
7
9c0b0016
DO
8// Interface function's special.
9$nextorder['odd'] = 'even';
10$nextorder['even'] = 'odd';
11
e673ee24
DO
12// Main menu.
13function renderIndex ()
14{
15 global $root;
16?>
17<table border=0 cellpadding=0 cellspacing=0 width='100%'>
18 <tr>
19 <td>
20 <div style='text-align: center; margin: 10px; '>
21 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
22 <tr>
23 <td>
b325120a
DO
24 <h1><a href='<?php echo $root; ?>?page=rackspace'>Rackspace<br>
25 <?php printImageHREF ('rackspace'); ?></a></h1>
e673ee24
DO
26 </td>
27 <td>
b325120a
DO
28 <h1><a href='<?php echo $root; ?>?page=objects'>Objects<br>
29 <?php printImageHREF ('objects'); ?></a></h1>
e673ee24
DO
30 </td>
31 <td>
b325120a
DO
32 <h1><a href='<?php echo $root; ?>?page=ipv4space'>IPv4 space<br>
33 <?php printImageHREF ('ipv4space'); ?></a></h1>
e673ee24
DO
34 </td>
35 </tr>
36 </table>
37 <table width='100%' cellspacing=0 cellpadding=30 class=mainmenu border=0>
38 <tr>
39 <td>
b325120a
DO
40 <h1><a href='<?php echo $root; ?>?page=config'>Configuration<br>
41 <?php printImageHREF ('config'); ?></a></h1>
e673ee24
DO
42 </td>
43 <td>
b325120a
DO
44 <h1><a href='<?php echo $root; ?>?page=reports'>[ Reports ]<br>
45 <?php printImageHREF ('reports'); ?></a></h1>
e673ee24 46 </td>
ae545907 47 <td>
b325120a
DO
48 <h1><a href='<?php echo $root; ?>?page=help'>Help<br>
49 <?php printImageHREF ('help'); ?></a></h1>
ae545907 50 </td>
e673ee24
DO
51 </tr>
52 </table>
53 </div>
54 </td>
55 </tr>
56</table>
b325120a 57<?php
e673ee24
DO
58}
59
60function renderRackspace ()
61{
62?>
63 <table border=0 cellpadding=10 cellpadding=1>
b325120a 64<?php
e673ee24
DO
65 // generate thumb gallery
66 $rackrowList = getRackRowInfo();
9c0b0016
DO
67 global $root, $nextorder;
68 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
e673ee24
DO
69 $order = 'odd';
70 foreach ($rackrowList as $rackrow)
71 {
72 echo "<tr class=row_${order}><th><a href='${root}?page=row&row_id=${rackrow['dict_key']}'>${rackrow['dict_value']}</a></th>";
73 $rackList = getRacksForRow ($rackrow['dict_key']);
74 echo "<td><table border=0 cellspacing=5><tr>";
75 foreach ($rackList as $dummy => $rack)
76 {
77 echo "<td align=center><a href='${root}?page=rack&rack_id=${rack['id']}'>";
78 echo "<img border=0 width=${rackwidth} height=";
79 echo 3 + 3 + $rack['height'] * 2;
80 echo " title='${rack['height']} units'";
81 echo "src='render_rack_thumb.php?rack_id=${rack['id']}'>";
82 echo "<br>${rack['name']}</a></td>";
83 }
84 echo "</tr></table></tr>\n";
85 $order = $nextorder[$order];
86 }
87 echo "</table>\n";
88}
89
90function renderRow ($row_id)
91{
92 if ($row_id == 0)
93 {
94 showError ('Invalid row_id in renderRow()');
95 return;
96 }
97 if (($rowInfo = getRackRowInfo ($row_id)) == NULL)
98 {
99 showError ('getRackRowInfo() failed in renderRow()');
100 return;
101 }
102 // Main layout starts.
103 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
104
105 // Left portlet with row information.
106 echo "<tr><td class=pcleft>";
51a2330f 107 startPortlet ($rowInfo['dict_value']);
e673ee24 108 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
e673ee24
DO
109 echo "<tr><th width='50%' class=tdright>Racks:</th><td class=tdleft>${rowInfo['count']}</td></tr>\n";
110 echo "<tr><th width='50%' class=tdright>Units:</th><td class=tdleft>${rowInfo['sum']}</td></tr>\n";
111 echo "</table><br>\n";
112 finishPortlet();
113
114 echo "</td><td class=pcright>";
115
9c0b0016
DO
116 global $root, $nextorder;
117 $rackwidth = getConfigVar ('rtwidth_0') + getConfigVar ('rtwidth_1') + getConfigVar ('rtwidth_2');
e673ee24
DO
118 $rackList = getRacksForRow ($row_id);
119 $order = 'odd';
120 startPortlet ('Racks');
121 echo "<table border=0 cellspacing=5 align='center'><tr>";
122 foreach ($rackList as $dummy => $rack)
123 {
124 echo "<td align=center class=row_${order}><a href='${root}?page=rack&rack_id=${rack['id']}'>";
9c0b0016
DO
125 echo "<img border=0 width=" . $rackwidth * getConfigVar ('ROW_SCALE') . " height=";
126 echo (3 + 3 + $rack['height'] * 2) * getConfigVar ('ROW_SCALE');
e673ee24
DO
127 echo " title='${rack['height']} units'";
128 echo "src='render_rack_thumb.php?rack_id=${rack['id']}'>";
129 echo "<br>${rack['name']}</a></td>";
130 $order = $nextorder[$order];
131 }
132 echo "</tr></table>\n";
133 finishPortlet();
134
135 echo "</td></tr></table>";
136}
137
138function showError ($info = '')
139{
140 global $root;
141 echo '<div class=msg_error>An error has occured. ';
142 if (empty ($info))
143 echo 'No additional information is available.';
144 else
145 echo "Additional information:<br><p>\n<pre>\n${info}\n</pre></p>";
146 echo "Go back or try starting from <a href='${root}'>index page</a>.<br></div>\n";
147}
148
149// This function renders rack as HTML table.
150function renderRack ($rack_id = 0, $hl_obj_id = 0)
151{
152 if ($rack_id == 0)
153 {
154 showError ('Invalid rack_id in renderRack()');
155 return;
156 }
157 if (($rackData = getRackData ($rack_id)) == NULL)
158 {
159 showError ('getRackData() failed in renderRack()');
160 return;
161 }
162 global $root, $pageno, $tabno;
163 markAllSpans ($rackData);
164 if ($hl_obj_id > 0)
165 highlightObject ($rackData, $hl_obj_id);
166 markupObjectProblems ($rackData);
167 $prev_id = getPrevIDforRack ($rackData['row_id'], $rack_id);
168 $next_id = getNextIDforRack ($rackData['row_id'], $rack_id);
169 echo "<center>\n<h2><a href='${root}?page=row&row_id=${rackData['row_id']}'>${rackData['row_name']}</a> :";
170 // FIXME: use 'bypass'?
171 if ($prev_id != NULL)
172 echo " <a href='${root}?page=rack&rack_id=${prev_id}'>&lt; &lt; &lt;</a>";
173 echo " <a href='${root}?page=rack&rack_id=${rackData['id']}'>${rackData['name']}</a>";
174 if ($next_id != NULL)
175 echo " <a href='${root}?page=rack&rack_id=${next_id}'>&gt; &gt; &gt;</a>";
176 echo "</h2>\n";
177 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
178 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
179 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
180 for ($i = $rackData['height']; $i > 0; $i--)
181 {
182 echo "<tr><th>$i</th>";
183 for ($locidx = 0; $locidx < 3; $locidx++)
184 {
185 if (isset ($rackData[$i][$locidx]['skipped']))
186 continue;
187 $state = $rackData[$i][$locidx]['state'];
188 echo "<td class=state_${state}";
189 if (isset ($rackData[$i][$locidx]['hl']))
190 echo $rackData[$i][$locidx]['hl'];
191 if (isset ($rackData[$i][$locidx]['colspan']))
192 echo ' colspan=' . $rackData[$i][$locidx]['colspan'];
193 if (isset ($rackData[$i][$locidx]['rowspan']))
194 echo ' rowspan=' . $rackData[$i][$locidx]['rowspan'];
195 echo ">";
196 switch ($state)
197 {
198 case 'T':
199 $objectData = getObjectInfo ($rackData[$i][$locidx]['object_id']);
200 if (!empty ($objectData['asset_no']))
201 $prefix = "<div title='${objectData['asset_no']}";
202 else
203 $prefix = "<div title='no asset tag";
204 // Don't tell about label, if it matches common name.
205 if ($objectData['name'] != $objectData['label'] and !empty ($objectData['label']))
206 $suffix = ", visible label is \"${objectData['label']}\"'>";
207 else
208 $suffix = "'>";
209 echo $prefix . $suffix;
210 echo "<a href='${root}?page=object&object_id=${objectData['id']}'>${objectData['dname']}</a></div>";
211 break;
212 case 'A':
213 echo '<div title="This rackspace does not exist">&nbsp;</div>';
214 break;
215 case 'F':
216 echo '<div title="Free rackspace">&nbsp;</div>';
217 break;
218 case 'U':
219 echo '<div title="Problematic rackspace, you CAN\'T mount here">&nbsp;</div>';
220 break;
221 default:
222 echo '<div title="No data">&nbsp;</div>';
223 break;
224 }
225 echo '</td>';
226 }
227 echo "</tr>\n";
228 }
229 echo "</table></center>\n";
230}
231
232function renderNewObjectForm ()
233{
234 global $pageno, $tabno;
235
236 // Look for current submit.
237 if (isset ($_REQUEST['got_data']))
238 {
239 $log = array();
240 assertUIntArg ('object_type_id');
241 assertStringArg ('object_name', TRUE);
242 assertStringArg ('object_label', TRUE);
243 assertStringArg ('object_barcode', TRUE);
244 assertStringArg ('object_asset_no', TRUE);
245 $type_id = $_REQUEST['object_type_id'];
246 $name = $_REQUEST['object_name'];
247 $label = $_REQUEST['object_label'];
248 $asset_no = $_REQUEST['object_asset_no'];
249 $barcode = $_REQUEST['object_barcode'];
250
251 if (commitAddObject ($name, $label, $barcode, $type_id, $asset_no) === TRUE)
252 $log[] = array ('code' => 'success', 'message' => "Added new object '${name}'");
253 else
254 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderNewObjectForm()');
255 printLog ($log);
256 }
257
258 // Render a form for the next.
259 startPortlet ('Object attributes');
260 echo '<form>';
261 echo "<input type=hidden name=page value=${pageno}>";
262 echo "<input type=hidden name=tab value=${tabno}>";
263 echo '<table border=0 align=center>';
264 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
265 printSelect (getObjectTypeList(), 'object_type_id');
266 echo "</td></tr>\n";
267 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name></td></tr>\n";
268 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label></td></tr>\n";
269 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no></td></tr>\n";
270 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode></td></tr>\n";
271 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
272 echo '</form></table>';
273 finishPortlet();
274}
275
276function renderNewRackForm ($row_id)
277{
278 global $pageno, $tabno;
279
280 // Look for current submit.
281 if (isset ($_REQUEST['got_data']))
282 {
283 $log = array();
284 assertStringArg ('rack_name');
285 assertUIntArg ('rack_height');
286 assertStringArg ('rack_comment', TRUE);
287 $name = $_REQUEST['rack_name'];
288 $height = $_REQUEST['rack_height'];
289 $comment = $_REQUEST['rack_comment'];
290
291 if (commitAddRack ($name, $height, $row_id, $comment) === TRUE)
292 $log[] = array ('code' => 'success', 'message' => "Added new rack '${name}'");
293 else
294 $log[] = array ('code' => 'error', 'message' => 'commitAddRack() failed in renderNewRackForm()');
295 printLog ($log);
296 }
297
298 // Render a form for the next.
299 startPortlet ('Rack attributes');
300 echo '<form>';
301 echo "<input type=hidden name=page value=${pageno}>";
302 echo "<input type=hidden name=tab value=${tabno}>";
303 echo "<input type=hidden name=row_id value=${row_id}>";
304 echo '<table border=0 align=center>';
b901bf1f
DO
305 $defh = getConfigVar ('DEFAULT_RACK_HEIGHT');
306 if ($defh == 0)
307 $defh = '';
a7bc8321 308 echo "<tr><th class=tdright>Name (required):</th><td class=tdleft><input type=text name=rack_name tabindex=1></td></tr>\n";
b901bf1f 309 echo "<tr><th class=tdright>Height in units (required):</th><td class=tdleft><input type=text name=rack_height tabindex=2 value='${defh}'></td></tr>\n";
4134b5c0 310 echo "<tr><th class=tdright>Comment:</th><td class=tdleft><input type=text name=rack_comment tabindex=3></td></tr>\n";
e673ee24
DO
311 echo "<tr><td class=submit colspan=2><input type=submit name=got_data value='Create'></td></tr>\n";
312 echo '</form></table>';
313 finishPortlet();
314}
315
316function renderEditObjectForm ($object_id)
317{
318 showMessageOrError();
319 // Handle submit.
320 if (isset ($_REQUEST['got_data']))
321 {
322 $log = array();
323 // object_id is already verified by page handler
324 assertUIntArg ('object_type_id');
325 assertStringArg ('object_name', TRUE);
326 assertStringArg ('object_label', TRUE);
327 assertStringArg ('object_barcode', TRUE);
328 assertStringArg ('object_asset_no', TRUE);
329 $type_id = $_REQUEST['object_type_id'];
330 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
331 $has_problems = 'yes';
332 else
333 $has_problems = 'no';
334 $name = $_REQUEST['object_name'];
335 $label = $_REQUEST['object_label'];
336 $barcode = $_REQUEST['object_barcode'];
337 $asset_no = $_REQUEST['object_asset_no'];
338 $comment = $_REQUEST['object_comment'];
339
340 if (commitUpdateObject ($object_id, $name, $label, $barcode, $type_id, $has_problems, $asset_no, $comment) === TRUE)
341 $log[] = array ('code' => 'success', 'message' => "Updated object '${name}'");
342 else
343 $log[] = array ('code' => 'error', 'message' => 'commitUpdateObject() failed in renderEditObjectForm()');
344 printLog ($log);
345 }
346
347 global $pageno, $tabno;
348 $object = getObjectInfo ($object_id);
349 if ($object == NULL)
350 {
351 showError ('getObjectInfo() failed in renderEditObjectForm()');
352 return;
353 }
354
355 // Render a form for the next submit;
356 echo '<table border=0 width=100%><tr>';
357
358 echo '<td class=pcleft>';
359 startPortlet ('Static attributes');
360 echo '<form>';
361 echo "<input type=hidden name=page value=${pageno}>";
362 echo "<input type=hidden name=tab value=${tabno}>";
363 echo "<input type=hidden name=object_id value=${object_id}>";
364 echo '<table border=0 align=center>';
365 echo "<tr><th class=tdright>Type:</th><td class=tdleft>";
366 printSelect (getObjectTypeList(), 'object_type_id', $object['objtype_id']);
367 echo "</td></tr>\n";
368 // Common attributes.
369 echo "<tr><th class=tdright>Common name:</th><td class=tdleft><input type=text name=object_name value='${object['name']}'></td></tr>\n";
370 echo "<tr><th class=tdright>Visible label:</th><td class=tdleft><input type=text name=object_label value='${object['label']}'></td></tr>\n";
371 echo "<tr><th class=tdright>Asset tag:</th><td class=tdleft><input type=text name=object_asset_no value='${object['asset_no']}'></td></tr>\n";
372 echo "<tr><th class=tdright>Barcode:</th><td class=tdleft><input type=text name=object_barcode value='${object['barcode']}'></td></tr>\n";
373 echo "<tr><th class=tdright>Has problems:</th><td class=tdleft><input type=checkbox name=object_has_problems";
374 if ($object['has_problems'] == 'yes')
375 echo ' checked';
376 echo "></td></tr>\n";
377 echo "<tr><td colspan=2><b>Comment:</b><br><textarea name=object_comment rows=10 cols=80>${object['comment']}</textarea></td></tr>";
378 echo "<tr><th class=submit colspan=2><input type=submit name=got_data value='Update'></td></tr>\n";
379 echo '</form></table><br>';
380 finishPortlet();
381 echo '</td>';
382
383 // Optional attributes.
384 echo '<td class=pcright>';
385 startPortlet ('Optional attributes');
386 $values = getAttrValues ($object_id);
387 global $root;
388 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable>\n";
389 echo "<tr><th>&nbsp;</th><th>Attribute</th><th>Value</th><th>&nbsp;</th></tr>\n";
0dfb8a2a
DO
390 echo "<form method=post action='${root}process.php'>\n";
391 echo "<input type=hidden name=page value=${pageno}>\n";
392 echo "<input type=hidden name=tab value=${tabno}>\n";
393 echo "<input type=hidden name=op value=upd>\n";
394 echo "<input type=hidden name=object_id value=${object_id}>\n";
395 echo '<input type=hidden name=num_attrs value=' . count($values) . ">\n";
396
397 $i = 0;
e673ee24
DO
398 foreach ($values as $record)
399 {
0dfb8a2a 400 echo "<input type=hidden name=${i}_attr_id value=${record['id']}>";
e673ee24
DO
401 echo "<tr><td><a href=${root}process.php?page=${pageno}&tab=${tabno}&op=del&object_id=${object_id}&attr_id=${record['id']}>";
402 printImageHREF ('delete', 'Delete value');
403 echo "</a></td>";
404 echo "<td class=tdright>${record['name']}:</td><td class=tdleft>";
405 switch ($record['type'])
406 {
407 case 'uint':
408 case 'float':
409 case 'string':
0dfb8a2a 410 echo "<input type=text name=${i}_value value='${record['value']}'>";
e673ee24
DO
411 break;
412 case 'dict':
413 $chapter = readChapter ($record['chapter_name']);
414 $chapter[] = array ('dict_key' => 0, 'dict_value' => '-- NOT SET --');
0dfb8a2a 415 printSelect ($chapter, "${i}_value", $record['key']);
e673ee24
DO
416 break;
417 }
0dfb8a2a
DO
418 echo "</td></tr>\n";
419 $i++;
e673ee24 420 }
0dfb8a2a
DO
421 echo "<tr><td colspan=3><input type=submit value='Update'></td></tr>\n";
422 echo "</form>";
e673ee24
DO
423 echo "</table>\n";
424 finishPortlet();
425 echo '</td>';
426
427 echo '</tr><tr>';
428
429 echo '<td colspan=2>';
430 startPortlet ('history');
431 renderHistory ($pageno, $object_id);
432 finishPortlet();
433 echo '</td>';
434
435 echo '</tr></table>';
436}
437
438// This is a clone of renderEditObjectForm().
439function renderEditRackForm ($rack_id)
440{
441 // Handle submit.
442 if (isset ($_REQUEST['got_data']))
443 {
444 $log = array();
445 assertUIntArg ('rack_row_id');
446 assertUIntArg ('rack_height');
447 assertStringArg ('rack_name');
448 assertStringArg ('rack_comment', TRUE);
449 $row_id = $_REQUEST['rack_row_id'];
450 $height = $_REQUEST['rack_height'];
451 $name = $_REQUEST['rack_name'];
452 $comment = $_REQUEST['rack_comment'];
453
454 if (commitUpdateRack ($rack_id, $name, $height, $row_id, $comment) === TRUE)
455 $log[] = array ('code' => 'success', 'message' => "Updated rack '${name}'");
456 else
457 $log[] = array ('code' => 'error', 'message' => 'commitUpdateRack() failed in renderEditRackForm()');
458 printLog ($log);
459 }
460
461 global $pageno, $tabno;
462 $rack = getRackData ($rack_id);
463 if ($rack == NULL)
464 {
465 showError ('getRackData() failed in renderEditRackForm()');
466 return;
467 }
468
469 // Render a form for the next.
470 startPortlet ('Rack attributes');
471 echo '<form>';
472 echo "<input type=hidden name=page value=${pageno}>";
473 echo "<input type=hidden name=tab value=${tabno}>";
474 echo "<input type=hidden name=rack_id value=${rack_id}>";
475 echo '<table border=0 align=center>';
476 echo "<tr><th class=tdright>Rack row:</th><td class=tdleft>";
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.
492function 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.
bb09cca0 506function renderGridForm ($rack_id = 0, $filter, $header, $submit, $state1, $state2)
e673ee24
DO
507{
508 if ($rack_id == 0)
509 {
510 showError ('Invalid rack_id in renderGridFrom()');
511 return;
512 }
513 if (($rackData = getRackData ($rack_id)) == NULL)
514 {
515 showError ('getRackData() failed in renderGridFrom()');
516 return;
517 }
518
519 global $root, $pageno, $tabno;
520 $filter($rackData);
521 markupObjectProblems ($rackData);
522
523 // Process form submit.
524 if (isset ($_REQUEST['do_update']))
525 {
526 $log[] = processGridForm ($rackData, $state1, $state2);
527 printLog($log);
528 }
529
530 // Render the result whatever it is.
531 // Main layout.
532 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
533 echo "<tr><td colspan=2 align=center><h1>${rackData['name']}</h1></td></tr>\n";
534
535 // Left column with information portlet.
536 echo "<tr><td class=pcleft height='1%' width='50%'>";
537 startPortlet ('Rack information');
538 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
539 echo "<tr><th width='50%' class=tdright>Rack name:</th><td class=tdleft>${rackData['name']}</td></tr>\n";
540 echo "<tr><th width='50%' class=tdright>Height:</th><td class=tdleft>${rackData['height']}</td></tr>\n";
541 echo "<tr><th width='50%' class=tdright>Rack row:</th><td class=tdleft>${rackData['row_name']}</td></tr>\n";
542 echo "<tr><th width='50%' class=tdright>Comment:</th><td class=tdleft>${rackData['comment']}</td></tr>\n";
543 echo "</table>\n";
544 finishPortlet();
545
546 echo "</td>\n";
bb09cca0 547 echo "<td class=pcright>";
e673ee24
DO
548
549 // Grid form.
550 startPortlet ($header);
551 echo "<center>\n";
552 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
553 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
554 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
555 echo "<form action='${root}?'>\n";
556 echo "<input type=hidden name=page value=${pageno}>\n";
557 echo "<input type=hidden name=tab value=${tabno}>\n";
558 echo "<input type=hidden name=rack_id value=${rack_id}>\n";
559 markupAtomGrid ($rackData, $state2);
560 renderAtomGrid ($rackData);
561 echo "</table></center>\n";
562 echo "<br><input type=submit name=do_update value='${submit}'></form><br><br>\n";
563 finishPortlet();
bb09cca0 564 echo "</td></tr></table>\n";
e673ee24
DO
565}
566
567function renderRackDesign ($rack_id)
568{
bb09cca0 569 renderGridForm ($rack_id, 'applyRackDesignMask', 'Rack design', 'Set rack design', 'A', 'F');
e673ee24
DO
570}
571
572function renderRackProblems ($rack_id = 0)
573{
bb09cca0 574 renderGridForm ($rack_id, 'applyRackProblemMask', 'Rack problems', 'Mark unusable atoms', 'F', 'U');
e673ee24
DO
575}
576
577function startPortlet ($title = '')
578{
579 echo "<div class=portlet><h2>${title}</h2>";
580}
581
582function finishPortlet ()
583{
584 echo "</div>\n";
585}
586
587function printRefsOfType ($refs, $type, $eq)
588{
589 global $root;
590 $gotone=0;
591 foreach ($refs as $ref)
592 {
593 if ($eq($ref['type'], $type))
594 {
595 if ($gotone) echo ', ';
4b2bf583
DO
596 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
597 if (!empty ($ref['name']))
598 echo $ref['name'] . '@';
599 echo "${ref['object_name']}</a>";
e673ee24
DO
600 $gotone=1;
601 }
602 }
603}
604
605function renderRackObject ($object_id = 0)
606{
607 global $root;
608 if ($object_id <= 0)
609 {
610 showError ('Invalid object_id in renderRackObject()');
611 return;
612 }
613 $info = getObjectInfo ($object_id);
614 if ($info == NULL)
615 {
616 showError ('getObjectInfo() failed in renderRackObject()');
617 return;
618 }
619 // Main layout starts.
620 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
621 echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
622 // left column with uknown number of portlets
623 echo "<tr><td class=pcleft>";
624 startPortlet ('Object information');
625 echo "<table border=0 cellspacing=0 cellpadding=3 width='100%'>\n";
626 if (!empty ($info['name']))
627 echo "<tr><th width='50%' class=tdright>Common name:</th><td class=tdleft>${info['name']}</td></tr>\n";
9c0b0016 628 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
a0ec6295 629 echo "<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>\n";
e673ee24
DO
630 echo "<tr><th width='50%' class=tdright>Object type:</th><td class=tdleft>${info['objtype_name']}</td></tr>\n";
631 if (!empty ($info['asset_no']))
632 echo "<tr><th width='50%' class=tdright>Asset tag:</th><td class=tdleft>${info['asset_no']}</td></tr>\n";
9c0b0016 633 elseif (in_array ($info['objtype_id'], explode (',', getConfigVar ('NAMEFUL_OBJTYPES'))))
a0ec6295 634 echo "<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>\n";
e673ee24
DO
635 if (!empty ($info['label']))
636 echo "<tr><th width='50%' class=tdright>Visible label:</th><td class=tdleft>${info['label']}</td></tr>\n";
637 if (!empty ($info['barcode']))
638 echo "<tr><th width='50%' class=tdright>Barcode:</th><td class=tdleft>${info['barcode']}</td></tr>\n";
639 if ($info['has_problems'] == 'yes')
640 echo "<tr><td colspan=2 class=msg_error>Has problems</td></tr>\n";
641 foreach (getAttrValues ($object_id) as $record)
642 if (!empty ($record['value']))
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 {
f28fbe8b 699 startPortlet ('IPv4 addresses');
e673ee24
DO
700 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
701 echo "<tr><th>Interface name</th><th>IP Address</th><th>Description</th><th>Misc</th></tr>\n";
702 foreach ($addresses as $addr)
703 {
704 if (strlen($addr['address_name'])>40)
705 $address_name = substr($addr['address_name'],0,38).'...';
706 else
707 $address_name = $addr['address_name'];
708
709 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
710 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
711 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
712 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
713
714 if ($addr['address_reserved']=='yes')
715 $class='trwarning';
716 elseif ($addr['type']!='virtual' && $regnum>0)
717 $class='trwarning';
718 elseif ($addr['type']=='regular' && $sharednum>0)
719 $class='trwarning';
720 else
721 $class='';
722
723 echo "<tr class='$class'><td>${addr['name']}</td><td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td class='description'>$address_name</td><td>\n";
724
725 if ($addr['address_reserved']=='yes')
726 echo "<b>Reserved;</b> ";
727
728 if ($addr['type'] == 'virtual')
729 {
730 echo "<b>V</b>";
731 if ($notvirtnum > 0)
732 {
733 echo " Owners: ";
734 printRefsOfType($addr['references'], 'virtual', 'neq');
735 }
736 }
737 elseif ($addr['type'] == 'shared')
738 {
739 echo "<b>S</b>";
740 if ($sharednum > 0)
741 {
742 echo " Peers: ";
743 printRefsOfType($addr['references'], 'shared', 'eq');
744 echo ";";
745 }
746 if ($virtnum > 0)
747 {
748 echo " Virtuals: ";
749 printRefsOfType($addr['references'], 'virtual', 'eq');
750 echo ";";
751 }
752 if ($regnum > 0)
753 {
754 echo " Collisions: ";
755 printRefsOfType($addr['references'], 'regular', 'eq');
756 }
757
758 }
759 else
760 {
761 if ($virtnum > 0)
762 {
763 echo " Virtuals: ";
764 printRefsOfType($addr['references'], 'virtual', 'eq');
765 echo ";";
766 }
767 if ($notvirtnum > 0)
768 {
769 echo " Collisions: ";
770 printRefsOfType($addr['references'], 'virtual', 'neq');
771 }
772 }
773
774 echo "</td></tr>\n";
775 }
776 echo "</table><br>\n";
777 finishPortlet();
778 }
779
780 $forwards = getObjectForwards ($object_id);
781 if (count($forwards['in']) or count($forwards['out']))
782 {
f28fbe8b 783 startPortlet('NATv4');
e673ee24
DO
784
785 if (count($forwards['out']))
786 {
787
f28fbe8b 788 echo "<h3>locally performed NAT</h3>";
e673ee24
DO
789
790 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 791 echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
e673ee24
DO
792
793 foreach ($forwards['out'] as $pf)
794 {
795 $class='trwarning';
796 $name='';
797 foreach ($addresses as $addr)
798 if ($addr['ip'] == $pf['localip'])
799 {
800 $class='';
801 $name=$addr['name'];
802 break;
803 }
804
805 echo "<tr class='$class'>";
806
f28fbe8b 807 echo "<td>${pf['proto']}</td><td class=tdleft>${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
e673ee24 808
f28fbe8b 809 echo "<td class=tdleft><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
e673ee24
DO
810
811 $address=getIPAddress($pf['remoteip']);
812
813 echo "<td class='description'>";
f28fbe8b
DO
814 if (count ($address['bonds']))
815 foreach($address['bonds'] as $bond)
816 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
817 elseif (!empty ($pf['remote_addr_name']))
818 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
819
820 echo "</td><td class='description'>${pf['description']}</td>";
821
822 echo "</tr>";
823 }
824 echo "</table><br><br>";
825 }
826 if (count($forwards['in']))
827 {
f28fbe8b 828 echo "<h3>arriving NAT connections</h3>";
e673ee24
DO
829
830 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 831 echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
e673ee24
DO
832
833 foreach ($forwards['in'] as $pf)
834 {
835 echo "<tr>";
836 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
837
838 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
839
840 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
841 echo "<td class='description'>${pf['description']}</td></tr>";
842 }
843
844 echo "</table><br><br>";
845 }
846 finishPortlet();
847 }
848
849 echo "</td>\n";
850
851 // After left column we have (surprise!) right column with rackspace portled only.
852 echo "<td class=pcright>";
853 // rackspace portlet
854 startPortlet ('Rackspace allocation');
855 // FIXME: now we call getRackData() twice
856 $racks = getResidentRacksData ($object_id);
857 foreach ($racks as $rackData)
858 renderRack ($rackData['id'], $object_id);
859 echo '<br>';
860 finishPortlet();
861 echo "</td></tr>";
862 echo "</table>\n";
863}
864
865function renderRackMultiSelect ($sname, $racks, $selected)
866{
9c0b0016 867 echo "<select name=${sname} multiple size=" . getConfigVar ('MAXSELSIZE') . " onchange='getElementById(\"racks\").submit()'>\n";
e673ee24
DO
868 foreach ($racks as $rack)
869 {
870 echo "<option value=${rack['id']}";
871 if (!(array_search ($rack['id'], $selected) === FALSE))
872 echo ' selected';
ef12e277 873 echo">${rack['row_name']}:${rack['name']}</option>\n";
e673ee24
DO
874 }
875 echo "</select>\n";
876}
877
878function showMessageOrError ()
879{
880 if (isset($_REQUEST['message']))
881 echo "<div class=msg_success>${_REQUEST['message']}</div>";
882 if (isset($_REQUEST['error']))
883 echo "<div class=msg_error>${_REQUEST['error']}</div>";
884}
885
886// This function renders a form for port edition.
887function renderPortsForObject ($object_id = 0)
888{
889 global $root, $pageno, $tabno;
890 if ($object_id <= 0)
891 {
892 showError ('Invalid object_id in renderPortsForObject()');
893 return;
894 }
895 showMessageOrError();
896 startPortlet ('Ports and interfaces');
897 $ports = getObjectPortsAndLinks ($object_id);
898 usort($ports, 'sortByName');
899 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
900 echo "<tr><th>&nbsp;</th><th>Local name</th><th>Visible label</th><th>Port type</th><th>L2 address</th>";
901 echo "<th>Rem. object</th><th>Rem. port</th><th>(Un)link or (un)reserve</th><th>&nbsp;</th></tr>\n";
902 foreach ($ports as $port)
903 {
904 echo "<form action='${root}process.php'>";
905 echo "<input type=hidden name=op value=editPort>";
906 echo "<input type=hidden name=page value='${pageno}'>\n";
907 echo "<input type=hidden name=tab value='${tabno}'>\n";
908 echo "<input type=hidden name=port_id value='${port['id']}'>";
909 echo "<input type=hidden name=object_id value='$object_id'>\n";
910 echo "<tr><td><a href='${root}process.php?op=delPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=${port['name']}'>";
911 printImageHREF ('delete', 'Unlink and Delete this port');
912 echo "</a></td>\n";
913 echo "<td><input type=text name=name value='${port['name']}' size=8></td>";
914 echo "<td><input type=text name=label value='${port['label']}' size=24></td>";
915 echo "<td>${port['type']}</td>\n";
916 echo "<td><input type=text name=l2address value='${port['l2address']}'></td>\n";
917 if ($port['remote_object_id'])
918 {
919 echo "<td><a href='${root}?page=object&object_id=${port['remote_object_id']}'>${port['remote_object_name']}</a></td>";
920 echo "<td>${port['remote_name']}</td>";
921 echo "<td><a href='${root}process.php?op=unlinkPort&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=$object_id&port_name=";
922 echo urlencode ($port['name']);
923 echo "&remote_port_name=${port['remote_name']}&remote_object_name=${port['remote_object_name']}'>";
924 printImageHREF ('unlink', 'Unlink this port');
925 echo "</a></td>";
926 }
927 elseif (!empty ($port['reservation_comment']))
928 {
929 echo "<td><b>Reserved;</b></td>";
930 echo "<td><input type=text name=reservation_comment value='${port['reservation_comment']}'></td>";
931 echo "<td><a href='${root}process.php?op=useup&page=${pageno}&tab=${tabno}&port_id=${port['id']}&object_id=${object_id}'>";
932 printImageHREF ('useup', 'Use up this port');
933 echo "</a></td>";
934 }
935 else
936 {
937 echo "<td>&nbsp;</td><td>&nbsp;</td>";
938 echo "<td>";
939 echo "<a href='javascript:;' onclick='window.open(\"${root}link_helper.php?port=${port['id']}&type=${port['type_id']}&object_id=$object_id&port_name=";
940 echo urlencode ($port['name']);
941 echo "\",\"findlink\",\"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'>";
942 printImageHREF ('link', 'Link this port');
943 echo "</a> <input type=text name=reservation_comment>";
944 echo "</td>\n";
945 }
946 echo "<td><input type='submit' value='OK'></td>";
947 echo "</form></tr>\n";
948 }
949 echo "<form action='${root}process.php'><tr>";
950 echo "<td colspan=2><input type=text size=10 name=port_name tabindex=100></td>\n";
951 echo "<td><input type=text size=24 name=port_label tabindex=101></td>";
952 echo "<input type=hidden name=op value=addPort>\n";
953 echo "<input type=hidden name=object_id value='${object_id}'>\n";
954 echo "<input type=hidden name=page value='${pageno}'>\n";
955 echo "<input type=hidden name=tab value='${tabno}'>\n";
956 echo "<td><select name='port_type_id' tabindex=102>\n";
957 $types = getPortTypes();
9c0b0016 958 $default_port_type = getConfigVar ('default_port_type');
e673ee24
DO
959 foreach ($types as $typeid => $typename)
960 {
961 echo "<option value='${typeid}'";
962 if ($typeid == $default_port_type)
963 echo " selected";
964 echo ">${typename}</option>\n";
965 }
966 echo "</select></td>";
967 echo "<td><input type=text name=port_l2address tabindex=103></td>\n";
968 echo "<td colspan=4><input type='submit' value='Add a new port' tabindex=104></td></tr></form>";
969 echo "</table><br>\n";
970 finishPortlet();
971
972 startPortlet ('Add/update multiple ports');
973 echo "<form action=${root}process.php method=post>";
974 echo "<input type=hidden name=page value='${pageno}'>\n";
975 echo "<input type=hidden name=tab value='${tabno}'>\n";
976 echo "<input type=hidden name=object_id value='${object_id}'>\n";
977 echo "<input type=hidden name=op value=addMultiPorts>";
978 echo 'Format: <select name=format>';
979 echo '<option value=c2900 disabled>Cisco 2900 series: sh int eth</option>';
980 echo '<option value=c3600eth disabled>Cisco 3600 ethernet: sh arp | inc -</option>';
981 echo '<option value=c3600asy>Cisco 3600 async: sh line | inc TTY</option>';
982 echo '<option value=fiwg selected>Foundry ServerIron/FastIron WorkGroup/Edge: sh int br</option>';
983 echo '<option value=fiedge disabled>Foundry FastIron Edge: sh int br</option>';
984 echo '<option value=fisxii>Foundry FastIron SuperX/II4000: sh int br</option>';
985 echo "</select>";
986 echo 'Default port type: ';
987 echo "<select name=port_type>\n";
988 foreach ($types as $typeid => $typename)
989 {
990 echo "<option value='${typeid}'";
991 if ($typeid == $default_port_type)
992 echo " selected";
993 echo ">${typename}</option>\n";
994 }
995 echo "</select>";
996 echo "<input type=submit value='Parse output'><br>\n";
997 echo "<textarea name=input cols=100 rows=50></textarea><br>\n";
998 echo '</form>';
999 finishPortlet();
1000}
1001
1002function renderNetworkForObject ($object_id=0)
1003{
1004 global $root, $pageno, $tabno;
1005 if ($object_id <= 0)
1006 {
1007 showError ('Invalid object_id in renderNetworkForObject()');
1008 return;
1009 }
1010 showMessageOrError();
1011 startPortlet ('Network Addresses');
1012 $addresses = getObjectAddresses ($object_id);
1013 usort($addresses, 'sortAddresses');
1014 echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
1015 echo "<tr><th>&nbsp;</th><th>Interface name</th><th>IP Address</th><th>Description</th><th>Type</th><th>Misc</th><th>&nbsp</th></tr>\n";
1016 foreach ($addresses as $addr)
1017 {
1018 if (strlen($addr['address_name'])>40)
1019 $address_name = substr($addr['address_name'],0,38).'...';
1020 else
1021 $address_name = $addr['address_name'];
1022
1023 $virtnum = countRefsOfType($addr['references'], 'virtual', 'eq');
1024 $sharednum = countRefsOfType($addr['references'], 'shared', 'eq');
1025 $regnum = countRefsOfType($addr['references'], 'regular', 'eq');
1026 $notvirtnum = countRefsOfType($addr['references'], 'virtual', 'neq');
1027
1028 if ($addr['address_reserved']=='yes')
1029 $class='trwarning';
1030 elseif ($addr['type']!='virtual' && $regnum>0)
1031 $class='trwarning';
1032 elseif ($addr['type']=='regular' && $sharednum>0)
1033 $class='trwarning';
1034 else
1035 $class='';
1036
1037 echo "<form action='process.php'>";
1038 echo "<input type=hidden name=page value='${pageno}'>\n";
1039 echo "<input type=hidden name=tab value='${tabno}'>\n";
1040 echo "<input type=hidden name=op value=editAddressFromObject>";
1041 echo "<input type=hidden name=object_id value='$object_id'>";
1042 echo "<input type=hidden name=ip value='${addr['ip']}'>";
1043 echo "<tr class='$class'><td><a href='process.php?op=delAddrFObj&page=${pageno}&tab=${tabno}&ip=${addr['ip']}&object_id=$object_id'>";
1044 printImageHREF ('delete', 'Delete this IPv4 address');
1045 echo "</a></td>";
1046 echo "<td><input type='text' name='bond_name' value='${addr['name']}' size=10></td>";
1047 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td>";
1048 echo "<td class='description'>$address_name</td>\n";
1049 echo "<td><select name='bond_type'>";
1050 foreach (array('regular'=>'Regular', 'virtual'=>'Virtual', 'shared'=>'Shared') as $n => $v)
1051 {
1052 echo "<option value='$n'";
1053 if ($addr['type'] == $n)
1054 echo " selected";
1055 echo ">$v</option>";
1056 }
1057 echo "</td><td>";
1058 if ($addr['address_reserved']=='yes')
1059 echo "<b>Reserved</b>; ";
1060
1061 if ($addr['type'] == 'virtual')
1062 {
1063 if ($notvirtnum > 0)
1064 {
1065 echo " Owners: ";
1066 printRefsOfType($addr['references'], 'virtual', 'neq');
1067 }
1068 }
1069 elseif ($addr['type'] == 'shared')
1070 {
1071 if ($sharednum > 0)
1072 {
1073 echo " Peers: ";
1074 printRefsOfType($addr['references'], 'shared', 'eq');
1075 echo ";";
1076 }
1077 if ($virtnum > 0)
1078 {
1079 echo " Virtuals: ";
1080 printRefsOfType($addr['references'], 'virtual', 'eq');
1081 echo ";";
1082 }
1083 if ($regnum > 0)
1084 {
1085 echo " Collisions: ";
1086 printRefsOfType($addr['references'], 'regular', 'eq');
1087 }
1088
1089 }
1090 else
1091 {
1092 if ($virtnum > 0)
1093 {
1094 echo " Virtuals: ";
1095 printRefsOfType($addr['references'], 'virtual', 'eq');
1096 echo ";";
1097 }
1098 if ($notvirtnum > 0)
1099 {
1100 echo " Collisions: ";
1101 printRefsOfType($addr['references'], 'virtual', 'neq');
1102 }
1103 }
1104
1105 echo "</td><td><input type=submit value='OK'></td></form></tr>\n";
1106 }
1107
1108
1109 echo "<form action='${root}process.php'><tr><td colspan=2><input type='text' size='10' name='name' tabindex=100></td>\n";
1110 echo "<input type=hidden name=page value='${pageno}'>\n";
1111 echo "<input type=hidden name=tab value='${tabno}'>\n";
1112 echo "<input type=hidden name=op value=addAddrFObj>\n";
1113 echo "<input type=hidden name=object_id value='$object_id'>\n";
1114
1115 echo "<td><input type=text name='ip' tabindex=101>\n";
1116 echo "</td><td><select name='type' tabindex=102>";
1117 echo "<option value='regular'>Regular</option>";
1118 echo "<option value='virtual'>Virtual</option>";
1119 echo "<option value='shared'>Shared</option>";
1120 echo "</select>";
1121 echo "</td><td colspan=3><input type='submit' value='Add a new interface' tabindex=103></td></tr></form>";
1122 echo "</table><br>\n";
1123 finishPortlet();
1124
1125}
1126
1127function printLog ($log)
1128{
1129 foreach ($log as $record)
1130 echo "<div class=msg_${record['code']}>${record['message']}</div>";
1131}
1132
1133/*
1134The following conditions must be followed:
11351. We can mount onto free atoms only. This means: if any record for an atom
1136already exists in RackSpace, it can't be used for mounting.
11372. We can't unmount from 'W' atoms. Operator should review appropriate comments
1138and either delete them before unmounting or refuse to unmount the object.
1139*/
1140
1141// We extensively use $_REQUEST in the function.
1142function renderRackSpaceForObject ($object_id = 0)
1143{
1144 if ($object_id <= 0)
1145 {
1146 showError ('Invalid object_id in renderRackSpaceForObject()');
1147 return;
1148 }
1149 $is_submit = isset ($_REQUEST['got_atoms']);
1150 $is_update = isset ($_REQUEST['rackmulti'][0]);
1151 $info = getObjectInfo ($object_id);
1152 if ($info == NULL)
1153 {
1154 showError ('getObjectInfo() failed in renderRackSpaceForObject()');
1155 return;
1156 }
1157 // Always process occupied racks plus racks chosen by user. First get racks with
1158 // already allocated rackspace...
1159 $workingRacksData = getResidentRacksData ($object_id);
1160 if ($workingRacksData === NULL)
1161 {
1162 print_r ($workingRacksData);
1163 showError ('getResidentRacksData() failed in renderRackSpaceForObject()');
1164 return;
1165 }
1166
1167 // ...and then add those chosen by user (if any).
1168 if ($is_update)
1169 foreach ($_REQUEST['rackmulti'] as $cand_id)
1170 {
1171 if (!isset ($workingRacksData[$cand_id]))
1172 {
1173 $rackData = getRackData ($cand_id);
1174 if ($rackData == NULL)
1175 {
1176 showError ('getRackData() failed in renderRackSpaceForObject()');
1177 return NULL;
1178 }
1179 $workingRacksData[$cand_id] = $rackData;
1180 }
1181 }
1182
1183 // Do it only once...
1184 foreach ($workingRacksData as &$rackData)
1185 applyObjectMountMask ($rackData, $object_id);
1186 // Now we workaround an old caveat: http://bugs.php.net/bug.php?id=37410
1187 unset ($rackData);
1188
1189 // Here we process form submit by trying to save all submitted info to database.
1190 if ($is_submit)
1191 {
1192 $oldMolecule = getMoleculeForObject ($object_id);
1193 $worldchanged = FALSE;
1194 $log = array();
1195 foreach ($workingRacksData as $rack_id => $rackData)
1196 {
1197 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1198 $log[] = $logrecord;
1199 if ($logrecord['code'] != 300)
1200 {
1201 $worldchanged = TRUE;
1202 // Reload our working copy after form processing.
1203 $rackData = getRackData ($rack_id);
1204 if ($rackData == NULL)
1205 $log[] = array ('code' => 500, 'message' => 'Working copy update failed in renderRackSpaceForObject()');
1206 applyObjectMountMask ($rackData, $object_id);
1207 $workingRacksData[$rack_id] = $rackData;
1208 }
1209 }
1210 if ($worldchanged)
1211 {
1212 // Log a record.
1213 $newMolecule = getMoleculeForObject ($object_id);
1214 $oc = count ($oldMolecule);
1215 $nc = count ($newMolecule);
1216 $omid = $oc ? createMolecule ($oldMolecule) : 'NULL';
1217 $nmid = $nc ? createMolecule ($newMolecule) : 'NULL';
1218 global $remote_username;
1219 $comment = empty ($_REQUEST['comment']) ? 'NULL' : "'${_REQUEST['comment']}'";
1220 $query =
1221 "insert into MountOperation(object_id, old_molecule_id, new_molecule_id, user_name, comment) " .
1222 "values (${object_id}, ${omid}, ${nmid}, '${remote_username}', ${comment})";
1223 global $dbxlink;
1224 $result = $dbxlink->query ($query);
1225 if ($result == NULL)
1226 $log[] = array ('code' => 'error', 'message' => 'SQL query failed during history logging.');
1227 else
1228 $log[] = array ('code' => 'success', 'message' => 'History logged.');
1229 }
1230 printLog ($log);
1231 }
1232
1233 // This is the time for rendering.
1234 global $root, $pageno, $tabno;
1235 echo "<form id='racks' action='${root}'>";
1236 echo "<input type=hidden name=page value='${pageno}'>\n";
1237 echo "<input type=hidden name=tab value='${tabno}'>\n";
1238 echo "<input type=hidden name=object_id value='${object_id}'>\n";
1239 // Main layout starts.
1240 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
1241
1242 // Left portlet with rack list.
1243 echo "<td class=pcleft height='1%'>";
1244 startPortlet ('Racks');
1245 $allRacksData = getRacksForRow();
1246 renderRackMultiSelect ('rackmulti[]', $allRacksData, array_keys ($workingRacksData));
1247 echo "<br>";
1248 echo "<br>";
1249 finishPortlet();
1250 echo "</td>";
1251
1252 // Middle portlet with comment and submit.
1253 echo "<td class=pcleft>";
1254 startPortlet ('Comment');
1255 echo "<textarea name=comment rows=10 cols=40></textarea><br>\n";
1256 echo "<input type=submit value='Save' name=got_atoms>\n";
1257 echo "<br>";
1258 echo "<br>";
1259 finishPortlet();
1260 echo "</td>";
1261
1262 // Right portlet with rendered racks. If this form submit is not final, we have to
1263 // reflect the former state of the grid in current form.
1264 echo "<td class=pcright rowspan=2 height='1%'>";
1265 startPortlet ('Working copy');
1266 echo '<table border=0 cellspacing=10 align=center><tr>';
1267 foreach ($workingRacksData as $rack_id => $rackData)
1268 {
1269 // Order is important here: only original allocation is highlighted.
1270 highlightObject ($rackData, $object_id);
1271 markupAtomGrid ($rackData, 'T');
1272 // If we have a form processed, discard user input and show new database
1273 // contents.
1274 if (!$is_submit and $is_update)
1275 mergeGridFormToRack ($rackData);
1276 echo "<td valign=top>";
1277 echo "<center>\n<h2>${rackData['name']}</h2>\n";
1278 echo "<table class=rack border=0 cellspacing=0 cellpadding=1>\n";
1279 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1280 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1281 renderAtomGrid ($rackData);
9b7468b7
DO
1282 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th>";
1283 echo "<th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
e673ee24
DO
1284 echo "</table></center>\n";
1285 echo '</td>';
1286 }
1287 echo "</tr></table>";
1288 finishPortlet();
1289 echo "</td>\n";
1290
1291 echo "</form>\n";
1292 echo "</tr></table>\n";
1293}
1294
1295function renderMolecule ($mdata, $object_id)
1296{
1297 // sort data out
1298 $rackpack = array();
1299 global $loclist;
1300 foreach ($mdata as $dummy => $rua)
1301 {
1302 $rack_id = $rua['rack_id'];
1303 $unit_no = $rua['unit_no'];
1304 $atom = $rua['atom'];
1305 if (!isset ($rackpack[$rack_id]))
1306 {
1307 $rackData = getRackData ($rack_id);
1308 for ($i = $rackData['height']; $i > 0; $i--)
1309 for ($locidx = 0; $locidx < 3; $locidx++)
1310 $rackData[$i][$locidx]['state'] = 'F';
1311 $rackpack[$rack_id] = $rackData;
1312 }
1313 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['state'] = 'T';
1314 $rackpack[$rack_id][$unit_no][$loclist[$atom]]['object_id'] = $object_id;
1315 }
1316 // now we have some racks to render
1317 foreach ($rackpack as $dummy => $rackData)
1318 {
1319 markAllSpans ($rackData);
1320 echo "<table class=molecule cellspacing=0>\n";
1321 echo "<caption>${rackData['name']}</caption>\n";
1322 echo "<tr><th width='10%'>&nbsp;</th><th width='20%'>Front</th><th width='50%'>Interior</th><th width='20%'>Back</th></tr>\n";
1323 for ($i = $rackData['height']; $i > 0; $i--)
1324 {
1325 echo "<tr><th>$i</th>";
1326 for ($locidx = 0; $locidx < 3; $locidx++)
1327 {
1328 $state = $rackData[$i][$locidx]['state'];
1329 echo "<td class=state_${state}>&nbsp;</td>\n";
1330 }
1331 echo "</tr>\n";
1332 }
1333 echo "</table>\n";
1334 }
1335}
1336
1337function renderUnmountedObjectsPortlet ()
1338{
1339 startPortlet ('Unmounted objects');
1340 $objs = getUnmountedObjects();
1341 if ($objs === NULL)
1342 {
1343 showError ('getUnmountedObjects() failed in renderUnmountedObjectsPortlet()');
1344 return;
1345 }
1346 global $root, $nextorder;
1347 $order = 'odd';
1348 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1349 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset number</th><th>Barcode</th></tr>';
e673ee24
DO
1350 foreach ($objs as $obj)
1351 {
1352 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1353 echo "<td>${obj['label']}</td>";
18d94c29
DO
1354 echo "<td>${obj['asset_no']}</td>";
1355 echo "<td>${obj['barcode']}</td></tr>";
e673ee24
DO
1356 $order = $nextorder[$order];
1357 }
1358 echo "</table><br>\n";
1359 finishPortlet();
1360}
1361
1362function renderProblematicObjectsPortlet ()
1363{
1364 startPortlet ('Problematic objects');
1365 $objs = getProblematicObjects();
1366 if ($objs === NULL)
1367 {
1368 showError ('getProblematicObjects() failed in renderProblematicObjectsPortlet()');
1369 return;
1370 }
1371 global $root, $nextorder;
1372 $order = 'odd';
1373 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1374 echo '<tr><th>Type</th><th>Common name</th></tr>';
1375 foreach ($objs as $obj)
1376 {
1377 echo "<tr class=row_${order}><td>${obj['objtype_name']}</td>";
1378 echo "<td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></tr>";
1379 $order = $nextorder[$order];
1380 }
1381 echo "</table><br>\n";
1382 finishPortlet();
1383}
1384
1385function renderObjectGroupSummary ()
1386{
1387 global $root;
1388 $summary = getObjectGroupInfo();
1389 if ($summary === NULL)
1390 {
1391 showError ('getObjectGroupInfo() failed in renderObjectGroupSummary()');
1392 return;
1393 }
1394 echo "<table border=0 class=objectview>\n";
1395 echo "<tr><td class=pcleft width='25%'>";
1396
1397 startPortlet ('Summary');
1398 foreach ($summary as $gi)
1399 {
1400 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1401 }
1402 finishPortlet();
1403
1404 echo '</td><td class=pcright>';
1405 renderUnmountedObjectsPortlet();
1406 echo '</td><td class=pcright>';
1407 renderProblematicObjectsPortlet();
1408 echo "</td></tr></table>\n";
1409}
1410
1411function renderObjectGroup ($group_id = 0)
1412{
1413 global $root;
1414 $summary = getObjectGroupInfo();
1415 if ($summary == NULL)
1416 {
1417 showError ('getObjectGroupInfo() failed in renderObjectGroup()');
1418 return;
1419 }
1420 $objects = getObjectList ($group_id);
1421 if ($objects === NULL)
1422 {
1423 showError ('getObjectList() failed in renderObjectGroup()');
1424 return;
1425 }
1426 echo "<table border=0 class=objectview>\n";
1427 echo "<tr><td class=pcleft width='25%'>";
1428
1429 startPortlet ('All objects');
1430 foreach ($summary as $gi)
1431 {
1432 echo "<a href='${root}?page=objgroup&group_id=${gi['id']}'><b>${gi['name']}</b></a> <i>(${gi['count']})</i><br>";
1433 }
1434 finishPortlet();
1435
1436 echo '</td><td class=pcright>';
1437
1438 startPortlet ('Object group');
1439 echo '<br><br><table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
18d94c29 1440 echo '<tr><th>Common name</th><th>Visible label</th><th>Asset tag</th><th>Barcode</th><th>Rack</th></tr>';
e673ee24
DO
1441 $order = 'odd';
1442 global $nextorder;
1443 foreach ($objects as $obj)
1444 {
1445 echo "<tr class=row_${order}><td><a href='${root}?page=object&object_id=${obj['id']}'>${obj['dname']}</a></td>";
1446 echo "<td>${obj['label']}</td>";
1447 echo "<td>${obj['asset_no']}</td>";
18d94c29 1448 echo "<td>${obj['barcode']}</td>";
e673ee24
DO
1449 if ($obj['rack_id'])
1450 echo "<td><a href='${root}?page=rack&rack_id=${obj['rack_id']}'>${obj['Rack_name']}</a></td>";
1451 else
1452 echo '<td>Unmounted</td>';
1453 echo '</tr>';
1454 $order = $nextorder[$order];
1455 }
1456 echo '</table>';
1457 finishPortlet();
1458
1459 echo "</td></tr></table>";
1460}
1461
1462function renderEmptyPortsSelect ($port_id, $type_id)
1463{
1464 $ports = getEmptyPortsOfType($type_id);
1465 usort($ports, 'sortEmptyPorts');
1466 foreach ($ports as $port)
1467 {
1468 if ($port_id == $port['Port_id'])
1469 continue;
1470 echo "<option value='${port['Port_id']}' onclick='getElementById(\"remote_port_name\").value=\"${port['Port_name']}\"; getElementById(\"remote_object_name\").value=\"${port['Object_name']}\";'>${port['Object_name']} ${port['Port_name']}</option>\n";
1471 }
1472}
1473
1474function renderObjectAddressesAndNames ()
1475{
1476 $addresses = getObjectAddressesAndNames();
1477 usort($addresses, 'sortObjectAddressesAndNames');
1478 foreach ($addresses as $address)
1479 {
1480 echo "<option value='${address['ip']}' onclick='getElementById(\"ip\").value=\"${address['ip']}\";'>${address['object_name']} ${address['name']} ${address['ip']}</option>\n";
1481 }
1482}
1483
1484// History viewer for history-enabled simple dictionaries.
1485function renderHistory ($object_type, $object_id)
1486{
1487 switch ($object_type)
1488 {
1489 case 'row':
1490 $query = "select ctime, user_name, name, deleted, comment from RackRowHistory where id = ${object_id} order by ctime";
1491 $header = '<tr><th>change time</th><th>author</th><th>rack row name</th><th>is deleted?</th><th>rack row comment</th></tr>';
1492 $extra = 4;
1493 break;
1494 case 'rack':
1495 $query =
1496 "select ctime, user_name, rh.name, rh.deleted, d.dict_value as name, rh.height, rh.comment " .
1497 "from RackHistory as rh left join Dictionary as d on rh.row_id = d.dict_key " .
1498 "natural join Chapter " .
1499 "where chapter_name = 'RackRow' and rh.id = ${object_id} order by ctime";
1500 $header = '<tr><th>change time</th><th>author</th><th>rack name</th><th>is deleted?</th><th>rack row name</th><th>rack height</th><th>rack comment</th></tr>';
1501 $extra = 6;
1502 break;
1503 case 'object':
1504 $query =
1505 "select ctime, user_name, name, label, barcode, asset_no, deleted, has_problems, dict_value, comment " .
1506 "from RackObjectHistory inner join Dictionary on objtype_id = dict_key natural join Chapter " .
1507 "where chapter_name = 'RackObjectType' and id=${object_id} order by ctime";
1508 $header = '<tr><th>change time</th><th>author</th><th>common name</th><th>visible label</th><th>barcode</th><th>asset no</th><th>is deleted?</th><th>has problems?</th><th>object type</th><th>comment</th></tr>';
1509 $extra = 9;
1510 break;
1511 default:
1512 showError ("Uknown object type '${object_type}' in renderHistory()");
1513 return;
1514 }
1515 global $dbxlink;
1516 $result = $dbxlink->query ($query);
1517 if ($result == NULL)
1518 {
1519 showError ('SQL query failed in renderHistory()');
1520 return;
1521 }
1522 echo '<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>';
1523 $order = 'odd';
1524 global $nextorder;
1525 echo $header;
1526 while ($row = $result->fetch (PDO::FETCH_NUM))
1527 {
1528 echo "<tr class=row_${order}><td>${row[0]}</td>";
1529 for ($i = 1; $i <= $extra; $i++)
1530 echo "<td>" . $row[$i] . "</td>";
1531 echo "</tr>\n";
1532 $order = $nextorder[$order];
1533 }
1534 echo "</table><br>\n";
1535}
1536
1537function renderRackspaceHistory ()
1538{
1539 global $root, $nextorder, $pageno, $tabno;
1540 $order = 'odd';
1541 $history = getRackspaceHistory();
1542 // Show the last operation by default.
1543 if (isset ($_REQUEST['op_id']))
1544 $op_id = $_REQUEST['op_id'];
1545 elseif (isset ($history[0]['mo_id']))
1546 $op_id = $history[0]['mo_id'];
1547 else $op_id = NULL;
1548
1549 $omid = NULL;
1550 $nmid = NULL;
1551 $object_id = 1;
1552 if ($op_id)
1553 list ($omid, $nmid) = getOperationMolecules ($op_id);
1554
1555 // Main layout starts.
1556 echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
1557
1558 // Left top portlet with old allocation.
1559 echo "<tr><td class=pcleft>";
1560 startPortlet ('Old allocation');
1561 if ($omid)
1562 {
1563 $oldMolecule = getMolecule ($omid);
1564 renderMolecule ($oldMolecule, $object_id);
1565 }
1566 else
1567 echo "nothing";
1568 finishPortlet();
1569
1570 echo '</td><td class=pcright>';
1571
1572 // Right top portlet with new allocation
1573 startPortlet ('New allocation');
1574 if ($nmid)
1575 {
1576 $newMolecule = getMolecule ($nmid);
1577 renderMolecule ($newMolecule, $object_id);
1578 }
1579 else
1580 echo "nothing";
1581 finishPortlet();
1582
1583 echo '</td></tr><tr><td colspan=2>';
1584
1585 // Bottom portlet with list
1586
1587 startPortlet ('Rackspace allocation history');
1588 echo "<table border=0 cellpadding=5 cellspacing=0 align=center class=cooltable>\n";
1589 echo "<tr><th>timestamp</th><th>author</th><th>rack object ID</th><th>rack object type</th><th>rack object name</th><th>comment</th></tr>\n";
1590 foreach ($history as $row)
1591 {
1592 if ($row['mo_id'] == $op_id)
1593 $class = 'hl';
1594 else
1595 $class = "row_${order}";
1596 echo "<tr class=${class}><td><a href='${root}?page=${pageno}&tab=${tabno}&op_id=${row['mo_id']}'>${row['ctime']}</a></td>";
1597 echo "<td>${row['user_name']}</td>";
1598 echo "<td>${row['ro_id']}</td><td>${row['objtype_name']}</td><td>${row['name']}</td><td>${row['comment']}</td>\n";
1599 echo "</tr>\n";
1600 $order = $nextorder[$order];
1601 }
1602 echo "</table>\n";
1603 finishPortlet();
1604
1605 echo '</td></tr></table>';
1606
1607}
1608
1609function renderAddressspace ()
1610{
1611 global $root;
1612 echo "<table class='widetable' border=0 cellpadding=10 cellspacing=0 align='center'>\n";
1613 $addrspaceList = getAddressspaceList();
1614 echo "<tr><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1615 foreach ($addrspaceList as $iprange)
1616 {
1617 echo "<tr><td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1618 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1619 $range = getIPRange($iprange['id']);
1620 echo "/";
1621 echo count($range['addrlist']);
1622 echo "</td></tr>";
1623 }
1624 echo "</table>\n";
1625}
1626
1627function renderAddNewRange ()
1628{
1629 global $root, $pageno, $tabno;
1630 showMessageOrError();
2a201216
DY
1631
1632 echo "<center><h2>Add New Range</h2></center>\n";
1633 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
2dee289e 1634 echo "<tr><th>Address range</th><th>Name</th><th>C&gt;*</th><th>&nbsp;</th></tr>\n";
2a201216
DY
1635 echo "<form name='add_new_range' action='process.php'>\n";
1636 echo "<input type=hidden name=op value=addRange>\n";
1637 echo "<input type=hidden name=page value='${pageno}'>\n";
1638 echo "<input type=hidden name=tab value='${tabno}'>\n";
1639 echo "<tr><td class='tdcenter'><input type=text name='range' size=18 class='live-validate'></td>\n";
1640 echo "<td class='tdcenter'><input type=text name='name' size='20'></td>\n";
2dee289e 1641 echo "<td class='tdcenter'><input type=checkbox name='is_bcast' checked></td>\n";
2a201216
DY
1642 echo "<td class='tdcenter'><input type=submit value='Add a new range'></td></tr>\n";
1643 echo "</form></table><br><br>\n";
1644
1645 echo "<center><h2>Existing Ranges</h2></center>\n";
1646 echo "<table class='widetable' border=0 cellpadding=10 align='center'>\n";
e673ee24
DO
1647 $addrspaceList = getAddressspaceList();
1648 echo "<tr><th>&nbsp;</th><th>Address range</th><th>Name</th><th>Total/used addresses</th></tr>";
1649 foreach ($addrspaceList as $iprange)
1650 {
1651 $range = getIPRange($iprange['id']);
dc462202 1652 $usedips = count ($range['addrlist']);
e673ee24
DO
1653 echo "<tr>";
1654 if ($usedips == 0)
1655 {
1656 echo "<td><a href='process.php?op=delRange&page=${pageno}&tab=${tabno}&id=${iprange['id']}'>";
1657 printImageHREF ('delete', 'Delete this IP range');
1658 echo "</a></td>\n";
1659 }
1660 else
1661 echo "<td>&nbsp</td>";
1662 echo "<td><a href='${root}?page=iprange&id=${iprange['id']}'>${iprange['ip']}/${iprange['mask']}</a></td><td>${iprange['name']}</td><td>";
1663 echo ($iprange['ip_bin'] | $iprange['mask_bin_inv']) - ($iprange['ip_bin'] & $iprange['mask_bin'])+1;
1664 echo "/";
1665 echo $usedips;
2a201216 1666 #echo "</td></tr></table>";
e673ee24
DO
1667 echo "</td></tr>";
1668 }
e673ee24
DO
1669}
1670
1671function renderIPRange ()
1672{
1673 global $root;
b901bf1f 1674 $maxperpage = getConfigVar ('IPV4_ADDRS_PER_PAGE');
e673ee24
DO
1675 $id = $_REQUEST['id'];
1676 if (isset($_REQUEST['pg']))
1677 $page = $_REQUEST['pg'];
1678 else
1679 $page=0;
1680
e673ee24
DO
1681 $range = getIPRange($id);
1682 echo "<center><h1>${range['ip']}/${range['mask']}</h1><h2>${range['name']}</h2></center>\n";
1683
e673ee24
DO
1684 $startip = $range['ip_bin'] & $range['mask_bin'];
1685 $endip = $range['ip_bin'] | $range['mask_bin_inv'];
1686 $realstartip = $startip;
1687 $realendip = $endip;
1688 $numpages = 0;
1689 if($endip - $startip > $maxperpage)
1690 {
e673ee24
DO
1691 $numpages = ($endip - $startip)/$maxperpage;
1692 $startip = $startip + $page * $maxperpage;
1693 $endip = $startip + $maxperpage-1;
1694 }
1695 echo "<center>";
b901bf1f
DO
1696 if ($numpages)
1697 echo '<h3>' . long2ip ($startip) . ' ~ ' . long2ip ($endip) . '</h3>';
e673ee24
DO
1698 for ($i=0; $i<$numpages; $i++)
1699 {
1700 if ($i == $page)
1701 echo "<b>$i</b> ";
1702 else
1703 echo "<a href='${root}?page=iprange&id=$id&pg=$i'>$i</a> ";
1704 }
1705 echo "</center>";
1706
1707 echo "<table class='widetable' border=0 cellspacing=0 cellpadding=5 align='center'>\n";
1708 echo "<tr><th>Address</th><th>Name</th><th>Allocation</th></tr>\n";
1709
1710
1711 for($ip = $startip; $ip<=$endip; $ip++)
1712 {
dcee8072 1713 if (isset ($range['addrlist'][$ip]))
e673ee24
DO
1714 {
1715 $numshared = countRefsOfType($range['addrlist'][$ip]['references'], 'shared', 'eq');
1716 $numreg = countRefsOfType($range['addrlist'][$ip]['references'], 'regular', 'eq');
1717 $numvirt = countRefsOfType($range['addrlist'][$ip]['references'], 'virtual', 'eq');
1718
1719 $addr = $range['addrlist'][$ip];
1720 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1721 echo "<tr class='trwarning'>";
1722 elseif ( $addr['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1723 echo "<tr class='trwarning'>";
1724 elseif ( $addr['reserved'] == 'yes')
1725 echo "<tr class='trbusy'>";
1726 elseif ( $numshared > 0 || $numreg > 0)
1727 echo "<tr class='trbusy'>";
1728 else
1729 echo "<tr>";
1730
1731 echo "<td><a href='${root}?page=ipaddress&ip=${addr['ip']}'>${addr['ip']}</a></td><td>${addr['name']}</td><td>";
1732 if ( $addr['reserved'] == 'yes')
1733 echo "<b>Reserved;</b> ";
1734 foreach ($range['addrlist'][$ip]['references'] as $ref)
1735 {
db88e2de
DO
1736 echo "<a href='${root}?page=object&object_id=${ref['object_id']}'>";
1737 echo $ref['name'] . (empty ($ref['name']) ? '' : '@');
1738 echo "${ref['object_name']}</a>; ";
e673ee24
DO
1739 }
1740 echo "</td></tr>\n";
1741 }
1742 else
1743 {
1744 echo "<tr><td><a href='${root}?page=ipaddress&ip=".long2ip($ip)."'>".long2ip($ip)."</a></td><td>&nbsp;</td><td>&nbsp;</td></tr>\n";
1745 }
1746 }
1747
1748 echo "</table>";
1749
1750}
1751
1752function renderIPRangeProperties ()
1753{
1754 global $pageno, $tabno;
1755 $id = $_REQUEST['id'];
1756 showMessageOrError();
1757 $range = getIPRange($id);
1758 echo "<center><h1>${range['ip']}/${range['mask']}</h1></center>\n";
1759 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1760 echo "<form action='process.php'><input type=hidden name=op value=editRange>";
1761 echo "<input type=hidden name=page value='${pageno}'>\n";
1762 echo "<input type=hidden name=tab value='${tabno}'>\n";
1763 echo "<input type=hidden name=id value='${id}'>";
1764 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='${range['name']}'></tr><tr><td colspan=2 class='tdcenter'><input type=submit value='Update range'></td></form></tr>";
1765 echo "</table>\n";
1766
1767}
1768
1769function renderIPAddress ()
1770{
1771 global $root;
1772 $ip = $_REQUEST['ip'];
1773 $address = getIPAddress($ip);
1774 echo "<center><h1>$ip</h1>";
1775 if ($address['exists'] == 1)
1776 echo "<h2>${address['name']}</h2>";
1777 echo "</center>\n";
1778
1779// echo "<table width='100%' cesspadding=5 cellspacing=0 border=0 align='center'>";
1780// echo "<tr valign='top'><td>";
1781
1782 startPortlet ('Address assignment');
1783 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1784 echo "<tr><th>Object name</th><th>Interface name</th><th>Interface type</th></tr>\n";
1785
1786 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1787 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1788 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1789
1790
1791 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1792 $class='trwarning';
1793 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1794 $class='trwarning';
1795 else
1796 $class='';
1797
1798
1799
1800 if ($address['reserved'] == 'yes')
1801 echo "<tr class='$class'><td colspan='3'><b>RESERVED</b></td></tr>";
1802 foreach ($address['bonds'] as $bond)
1803 {
1804 echo "<tr class='$class'><td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td><td>${bond['name']}</td><td><b>";
1805 switch ($bond['type'])
1806 {
1807 case 'virtual':
1808 echo "Virtual";
1809 break;
1810 case 'shared':
1811 echo "Shared";
1812 break;
1813 case 'regular':
1814 echo "Regular";
1815 break;
1816 }
1817 echo "</b></td></tr>\n";
1818 }
1819 echo "</table><br><br>";
1820 finishPortlet();
1821
1822// echo "</td><td>";
1823// echo "</td></tr></table>";
1824}
1825
1826function renderIPAddressProperties ()
1827{
1828 global $pageno, $tabno;
1829 $ip = $_REQUEST['ip'];
1830 showMessageOrError();
1831 $address = getIPAddress($ip);
1832 echo "<center><h1>$ip</h1></center>\n";
1833 echo "<table border=0 cellpadding=10 cellpadding=1 align='center'>\n";
1834 echo "<form action='process.php'><input type=hidden name=op value=editAddress>";
1835 echo "<input type=hidden name=page value='${pageno}'>\n";
1836 echo "<input type=hidden name=tab value='${tabno}'>\n";
1837 echo "<input type=hidden name=ip value='${ip}'>";
1838 echo "<tr><td class='tdright'>Name:</td><td class='tdleft'><input type=text name=name size=20 value='".($address['exists']==1?$address['name']:'')."'></tr>";
1839 echo "<td class='tdright'>Reserved:</td><td class='tdleft'><input type=checkbox name=reserved size=20 ".($address['exists']==1?(($address['reserved']=='yes')?'checked':''):'')."></tr>";
1840 echo "<tr><td colspan=2 class='tdcenter'><input type=submit value='Update address'></td></form></tr>";
1841 echo "</table>\n";
1842
1843}
1844
1845function renderIPAddressAssignment ()
1846{
1847 global $pageno, $tabno, $root;
1848 $ip = $_REQUEST['ip'];
1849 $address = getIPAddress($ip);
1850
1851 showMessageOrError();
1852 echo "<center><h1>$ip</h1></center>\n";
1853
1854
1855 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1856 echo "<tr><th>&nbsp;</th><th>Object name</th><th>Interface name</th><th>Interface type</th><th>&nbsp;</th></tr>\n";
1857
1858 $numshared = countRefsOfType($address['bonds'], 'shared', 'eq');
1859 $numreg = countRefsOfType($address['bonds'], 'regular', 'eq');
1860 $numvirt = countRefsOfType($address['bonds'], 'virtual', 'eq');
1861
1862
1863 if ( ($numshared > 0 && $numreg > 0) || $numreg > 1 )
1864 $class='trwarning';
1865 elseif ( $address['reserved'] == 'yes' and $numshared+$numreg+$numvirt > 0)
1866 $class='trwarning';
1867 else
1868 $class='';
1869
1870
1871
1872 if ($address['reserved'] == 'yes')
1873 echo "<tr class='$class'><td colspan='5'><b>RESERVED</b></td></tr>";
1874 foreach ($address['bonds'] as $bond)
1875 {
1876 echo "<tr class='$class'><form action='process.php'>";
1877 echo "<input type=hidden name=op value='editBondForAddress'>";
1878 echo "<input type=hidden name=page value='${pageno}'>";
1879 echo "<input type=hidden name=tab value='${tabno}'>";
1880 echo "<input type=hidden name=ip value='$ip'>";
1881 echo "<input type=hidden name=object_id value='${bond['object_id']}'>";
1882 echo "<td><a href='process.php?op=delIpAssignment&page=${pageno}&tab=${tabno}&ip=$ip&object_id=${bond['object_id']}'>";
1883 printImageHREF ('delete', 'Unallocate address');
1884 echo "</a></td>";
1885 echo "<td><a href='${root}?page=object&object_id=${bond['object_id']}'>${bond['object_name']}</td>";
1886 echo "<td><input type='text' name='bond_name' value='${bond['name']}' size=10></td>";
1887 echo "<td><select name='bond_type'>";
1888 switch ($bond['type'])
1889 {
1890 case 'virtual':
1891 echo "<option value='regular'>Regular</option>";
1892 echo "<option value='virtual' selected>Virtual</option>";
1893 echo "<option value='shared'>Shared</option>";
1894 break;
1895 case 'shared':
1896 echo "<option value='regular'>Regular</option>";
1897 echo "<option value='virtual'>Virtual</option>";
1898 echo "<option value='shared' selected>Shared</option>";
1899 break;
1900 case 'regular':
1901 echo "<option value='regular' selected>Regular</option>";
1902 echo "<option value='virtual'>Virtual</option>";
1903 echo "<option value='shared'>Shared</option>";
1904 break;
1905 }
1906 echo "</select></td><td><input type='submit' value='OK'></td></form></tr>\n";
1907 }
1908 echo "<form action='process.php'><input type='hidden' name='op' value='bindObjectToIp'>";
1909 echo "<input type=hidden name=page value='${pageno}'>\n";
1910 echo "<input type=hidden name=tab value='${tabno}'>\n";
1911 echo "<input type='hidden' name='ip' value='$ip'>";
1912 echo "<td colspan=2><select name='object_id'>";
1913
1914 foreach (array(1, 4, 7, 8, 12, 14) as $type)
1915 {
1916 //get all Balck Boxes, Servers, Routers, Switches, UPS, Modems
1917 $objects = getObjectList($type);
1918 foreach ($objects as $object)
1919 echo "<option value='${object['id']}'>${object['dname']}</option>";
1920 }
1921
1922 echo "</select></td><td><input type='text' name='bond_name' value='' size=10></td>";
1923 echo "<td><select name='bond_type'><option value='regular'>Regular</option><option value='virtual'>Virtual</option><option value='shared'>Shared</option></select></td>";
1924 echo "<td><input type='submit' value='Assign address'></td></form></tr>";
1925 echo "</table><br><br>";
1926
1927}
1928
1929function renderIPAddressPortForwarding ($object_id=0)
1930{
1931 global $pageno, $tabno, $root;
1932
1933 $info = getObjectInfo ($object_id);
1934 $forwards = getObjectForwards ($object_id);
1935 $addresses = getObjectAddresses ($object_id);
1936 showMessageOrError();
f28fbe8b 1937 echo "<center><h2>locally performed NAT</h2></center>";
e673ee24
DO
1938
1939 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
f28fbe8b 1940 echo "<tr><th></th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Comment</th></tr>\n";
e673ee24
DO
1941
1942 foreach ($forwards['out'] as $pf)
1943 {
1944 $class='trwarning';
1945 $name='';
1946 foreach ($addresses as $addr)
1947 if ($addr['ip'] == $pf['localip'])
1948 {
1949 $class='';
1950 $name = $addr['name'];
1951 break;
1952 }
1953
1954 echo "<tr class='$class'>";
1955 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=$object_id&page=${pageno}&tab=${tabno}'><img src='${root}/pix/delete_s.gif' title='Delete port forwarding' border=0 width=16 height=16></a></td>";
f28fbe8b
DO
1956 echo "<td>${pf['proto']}/${name}: <a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}";
1957 if (!empty ($pf['local_addr_name']))
1958 echo ' (' . $pf['local_addr_name'] . ')';
1959 echo "</td>";
e673ee24
DO
1960 echo "<td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
1961
1962 $address=getIPAddress($pf['remoteip']);
1963
1964 echo "<td class='description'>";
f28fbe8b
DO
1965 if (count ($address['bonds']))
1966 foreach($address['bonds'] as $bond)
1967 echo "<a href='${root}?page=object&tab=default&object_id=${bond['object_id']}'>${bond['object_name']}(${bond['name']})</a> ";
1968 elseif (!empty ($pf['remote_addr_name']))
1969 echo '(' . $pf['remote_addr_name'] . ')';
e673ee24
DO
1970 echo "</td><form action='process.php'><input type='hidden' name='op' value='updPortForwarding'><input type=hidden name=page value='${pageno}'><input type=hidden name=tab value='${tabno}'><input type='hidden' name='object_id' value='$object_id'><input type='hidden' name='localip' value='${pf['localip']}'><input type='hidden' name='localport' value='${pf['localport']}'><input type='hidden' name='remoteip' value='${pf['remoteip']}'><input type='hidden' name='remoteport' value='${pf['remoteport']}'><input type='hidden' name='proto' value='${pf['proto_bin']}'><td class='description'><input type='text' name='description' value='${pf['description']}'> <input type='submit' value='OK'></td></form>";
1971 echo "</tr>";
1972 }
1973 echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
1974 echo "<input type='hidden' name='object_id' value='$object_id'>";
1975 echo "<input type=hidden name=page value='${pageno}'>\n";
1976 echo "<input type=hidden name=tab value='${tabno}'>\n";
1977 echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option></select><select name='localip'>";
1978
1979 foreach ($addresses as $addr)
09992c16
DO
1980 echo "<option value='${addr['ip']}'>" . (empty ($addr['name']) ? '' : "${addr['name']}: ") .
1981 "${addr['ip']}" . (empty ($addr['address_name']) ? '' : " (${addr['address_name']})") . "</option>";
e673ee24
DO
1982
1983 echo "</select>:<input type='text' name='localport' size='4'></td><td><input type='text' name='remoteip' id='remoteip' size='10'>";
1984 echo "<a href='javascript:;' onclick='window.open(\"${root}/find_object_ip_helper.php\", \"findobjectip\", \"height=700, width=400, location=no, menubar=no, resizable=yes, scrollbars=no, status=no, titlebar=no, toolbar=no\");'><img src='${root}/pix/find.png' title='Find object' border=0 height=16 width=16></a>";
1985 echo ":<input type='text' name='remoteport' size='4'></td><td></td><td colspan=1><input type='text' name='description' size='20'> <input type='submit' value='Create Forwarding'></td></tr>";
1986 echo "</form>";
1987
1988 echo "</table><br><br>";
1989
1990
f28fbe8b 1991 echo "<center><h2>arriving NAT connections</h2></center>";
e673ee24
DO
1992 echo "<table class='widetable' cesspadding=5 cellspacing=0 border=0 align='center'>\n";
1993 echo "<tr><th></th><th>Source</th><th>Source objects</th><th>Target</th><th>Description</th></tr>\n";
1994
1995 foreach ($forwards['in'] as $pf)
1996 {
1997 echo "<tr>";
1998
1999 echo "<td><a href='process.php?op=delPortForwarding&localip=${pf['localip']}&localport=${pf['localport']}&remoteip=${pf['remoteip']}&remoteport=${pf['remoteport']}&proto=${pf['proto_bin']}&object_id=${pf['object_id']}&page=${pageno}&tab=${tabno}'><img src='${root}/pix/delete_s.gif' title='Delete port forwarding' border=0 width=16 height=16></a></td>";
2000 echo "<td>${pf['proto']}/<a href='${root}?page=ipaddress&tab=default&ip=${pf['localip']}'>${pf['localip']}</a>:${pf['localport']}</td>";
2001 echo "<td class='description'><a href='${root}?page=object&tab=default&object_id=${pf['object_id']}'>${pf['object_name']}</a>";
2002 echo "</td><td><a href='${root}?page=ipaddress&tab=default&ip=${pf['remoteip']}'>${pf['remoteip']}</a>:${pf['remoteport']}</td>";
2003 echo "<td class='description'>${pf['description']}</td></tr>";
2004 }
2005
2006// echo "<form action='process.php'><input type='hidden' name='op' value='forwardPorts'>";
2007// echo "<input type='hidden' name='object_id' value='$object_id'>";
2008// echo "<input type=hidden name=page value='${pageno}'>\n";
2009// echo "<input type=hidden name=tab value='${tabno}'>\n";
2010// echo "<tr align='center'><td colspan=2><select name='proto'><option value='1'>TCP</option><option value='2'>UDP</option><input type='text' name='localip' size='10'>:<input type='text' name='localport' size='4'></td><td><select name='localip'>";
2011// foreach ($addresses as $addr)
2012// echo "<option value='${addr['ip']}'>${addr['ip']}</option>";
2013//
2014// echo "</select>:<input type='text' name='remoteport' size='4'></td><td><input type='text' name='description' size='20'></td><td><input type='submit' value='Create Forwarding'></td></tr>";
2015// echo "</form>";
2016 echo "</table><br><br>";
2017
2018
2019}
2020
2021
2022function renderAddMultipleObjectsForm ()
2023{
2024 global $pageno, $tabno, $nextorder;
2025
2026 $type_id = array();
7f791d1d 2027 $global_type_id = 0;
e673ee24
DO
2028 $name = array();
2029 $asset_no = array();
2030 $keepvalues = FALSE;
7f791d1d 2031 $log = array();
e673ee24 2032 // Look for current submit.
7f791d1d 2033 if (isset ($_REQUEST['got_fast_data']))
e673ee24
DO
2034 {
2035 $keepvalues = TRUE;
9c0b0016
DO
2036 $max = getConfigVar ('MASSCOUNT');
2037 for ($i = 0; $i < $max; $i++)
e673ee24
DO
2038 {
2039 if (!isset ($_REQUEST["${i}_object_type_id"]))
2040 {
2041 $log[] = array ('code' => 'error', 'message' => "Submitted form is invalid at line " . $i + 1);
2042 break;
2043 }
2044 assertUIntArg ("${i}_object_type_id", TRUE);
2045 assertStringArg ("${i}_object_name", TRUE);
2046 assertStringArg ("${i}_object_label", TRUE);
2047 assertStringArg ("${i}_object_asset_no", TRUE);
2048 assertStringArg ("${i}_object_barcode", TRUE);
2049 $type_id[$i] = $_REQUEST["${i}_object_type_id"];
2050 // Save user input for possible rendering.
2051 $name[$i] = $_REQUEST["${i}_object_name"];
2052 $label[$i] = $_REQUEST["${i}_object_label"];
2053 $asset_no[$i] = $_REQUEST["${i}_object_asset_no"];
2054 $barcode[$i] = $_REQUEST["${i}_object_barcode"];
2055
2056 // It's better to skip silently than printing a notice.
2057 if ($type_id[$i] == 0)
2058 continue;
2059 if (commitAddObject ($name[$i], $label[$i], $barcode[$i], $type_id[$i], $asset_no[$i]) === TRUE)
2060 $log[] = array ('code' => 'success', 'message' => "Added new object '${name[$i]}'");
2061 else
2062 $log[] = array ('code' => 'error', 'message' => 'commitAddObject() failed in renderAddMultipleObjectsForm()');
2063 }
e673ee24 2064 }
7f791d1d
DO
2065 elseif (isset ($_REQUEST['got_very_fast_data']))
2066 {
2067 $keepvalues = TRUE;
2068 assertUIntArg ('global_type_id', TRUE);
2069 assertStringArg ('namelist', TRUE);
2070 $global_type_id = $_REQUEST['global_type_id'];
2071 if ($global_type_id == 0)
2072 {
2073 if (!empty ($_REQUEST['namelist']))
2074 $log[] = array ('code' => 'error', 'message' => 'Object type is not selected, check the form below');
2075 else
2076 $log[] = array ('code' => 'error', 'message' => 'Empty form has been ignored. Cheers.');
2077 }
2078 else
2079 {
2080 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
2081 $names1 = explode ('\n', $_REQUEST['namelist']);
2082 $names2 = array();
2083 foreach ($names1 as $line)
2084 {
2085 $parts = explode ('\r', $line);
2086 reset ($parts);
2087 if (empty ($parts[0]))
2088 continue;
2089 else
2090 $names2[] = rtrim ($parts[0]);
2091 }
2092 foreach ($names2 as $cname)
2093 if (commitAddObject ($cname, '', '', $global_type_id, '') === TRUE)
2094 $log[] = array ('code' => 'success', 'message' => "Added new object '${cname}'");
2095 else
2096 $log[] = array ('code' => 'error', 'message' => "Could not add '${cname}'");
2097 }
2098 }
2099 printLog ($log);
e673ee24
DO
2100
2101 // Render a form for the next.
2102 $typelist = getObjectTypeList();
2103 $typelist[0]['dict_key'] = 0;
7f791d1d
DO
2104 $typelist[0]['dict_value'] = 'select type...';
2105
2106 startPortlet ('Fast way');
e673ee24
DO
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";
7f791d1d 2112 // If a user forgot to select object type on input, we keep his
e673ee24 2113 // previous input in the form.
9c0b0016
DO
2114 $max = getConfigVar ('MASSCOUNT');
2115 for ($i = 0; $i < $max; $i++)
e673ee24 2116 {
7f791d1d 2117 echo '<tr><td>';
e673ee24
DO
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";
e673ee24 2137 }
7f791d1d 2138 echo "<tr><td class=submit colspan=5><input type=submit name=got_fast_data value='Create'></td></tr>\n";
e673ee24
DO
2139 echo "</form></table>\n";
2140 finishPortlet();
7f791d1d
DO
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();
e673ee24
DO
2154}
2155
2156function printGreeting ()
2157{
59cd003e 2158 global $remote_username, $accounts, $root;
e673ee24 2159 $account = $accounts[$remote_username];
4eb5efb7 2160 echo "Hello, ${account['user_realname']}. This is RackTables " . CODE_VERSION . ". Click <a href='${root}?logout'>here</a> to logout.";
e673ee24
DO
2161}
2162
2163function 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
2264function 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
2287function 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
2305function 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
2321function 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
2368function 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.
2384function 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
2398function 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>";
a5ae8c2a 2429 printImageHREF ('grant', '', TRUE, 103);
e673ee24
DO
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
e673ee24
DO
2447function 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
2490function 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
2504function 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
2541function 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';
cfadde04 2552 foreach ($chapter['word'] as $key => $value)
e673ee24 2553 {
cfadde04 2554 echo "<tr class=row_${order}><td class=tdleft><div title='key=${key}'>${value}</div></td></tr>";
e673ee24
DO
2555 $order = $nextorder[$order];
2556 }
2557 echo "</table>";
2558 finishPortlet();
2559 echo "</td>";
2560 }
2561 echo "</tr></table>";
2562}
2563
2564function 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.
2610function 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>';
a5ae8c2a 2651 printImageHREF ('add', '', TRUE);
e673ee24
DO
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
2658function 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
2688function 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>';
a5ae8c2a 2718 printImageHREF ('add', '', TRUE);
e673ee24
DO
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
2732function 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>';
a5ae8c2a 2768 printImageHREF ('add', '', TRUE);
e673ee24
DO
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
a5ae8c2a 2792function printImageHREF ($tag, $title = '', $do_input = FALSE, $tabindex = 0)
e673ee24 2793{
a5ae8c2a
DO
2794 global $root;
2795 $image['error']['path'] = 'pix/error.png';
2796 $image['error']['width'] = 76;
2797 $image['error']['height'] = 17;
2798 $image['favicon']['path'] = 'pix/racktables.ico';
2799 $image['favicon']['width'] = 16;
2800 $image['favicon']['height'] = 16;
2801 $image['logo']['path'] = 'pix/defaultlogo.png';
2802 $image['logo']['width'] = 210;
2803 $image['logo']['height'] = 40;
2804 $image['rackspace']['path'] = 'pix/racks.png';
2805 $image['rackspace']['width'] = 218;
2806 $image['rackspace']['height'] = 200;
2807 $image['objects']['path'] = 'pix/server.png';
2808 $image['objects']['width'] = 218;
2809 $image['objects']['height'] = 200;
2810 $image['ipv4space']['path'] = 'pix/addressspace.png';
2811 $image['ipv4space']['width'] = 218;
2812 $image['ipv4space']['height'] = 200;
2813 $image['config']['path'] = 'pix/configuration.png';
2814 $image['config']['width'] = 218;
2815 $image['config']['height'] = 200;
2816 $image['reports']['path'] = 'pix/report.png';
2817 $image['reports']['width'] = 218;
2818 $image['reports']['height'] = 200;
2819 $image['help']['path'] = 'pix/help.png';
2820 $image['help']['width'] = 218;
2821 $image['help']['height'] = 200;
2822 $image['reserve']['path'] = 'pix/stop.png';
2823 $image['reserve']['width'] = 16;
2824 $image['reserve']['height'] = 16;
2825 $image['useup']['path'] = 'pix/go.png';
2826 $image['useup']['width'] = 16;
2827 $image['useup']['height'] = 16;
2828 $image['blockuser'] = $image['reserve'];
2829 $image['unblockuser'] = $image['useup'];
2830 $image['link']['path'] = 'pix/link.png';
2831 $image['link']['width'] = 24;
2832 $image['link']['height'] = 24;
2833 $image['unlink']['path'] = 'pix/unlink.png';
2834 $image['unlink']['width'] = 24;
2835 $image['unlink']['height'] = 24;
2836 $image['add']['path'] = 'pix/greenplus.png';
2837 $image['add']['width'] = 16;
2838 $image['add']['height'] = 16;
2839 $image['delete']['path'] = 'pix/delete_s.gif';
2840 $image['delete']['width'] = 16;
2841 $image['delete']['height'] = 16;
2842 $image['grant'] = $image['add'];
2843 $image['revoke'] = $image['delete'];
2844 $image['helphint']['path'] = 'pix/helphint.png';
2845 $image['helphint']['width'] = 24;
2846 $image['helphint']['height'] = 24;
e673ee24
DO
2847 if (!isset ($image[$tag]))
2848 $tag = 'error';
2849 $img = $image[$tag];
a5ae8c2a
DO
2850 if ($do_input == TRUE)
2851 echo
2852 "<input type=image name=submit " .
2853 "src='${root}${img['path']}' " .
2854 "border=0 " .
2855 ($tabindex ? '' : "tabindex=${tabindex}") .
2856 ">";
2857 else
2858 echo
2859 "<img " .
2860 "src='${root}${img['path']}' " .
2861 "width=${img['width']} " .
2862 "height=${img['height']} " .
2863 "border=0 " .
2864 (empty ($title) ? '' : "title='${title}'") .
2865 ">";
e673ee24
DO
2866}
2867
2868// This function returns URL for favourite icon.
2869function getFaviconURL ()
2870{
2871 global $root, $image;
2872 return $root . $image['favicon']['path'];
2873}
2874
2875function renderReportSummary ()
2876{
c461c579
DO
2877 startPortlet ("Here be dragons");
2878 dragon();
2879 dragon();
2880 dragon();
2881 echo 'ASCII art &copy; Daniel C. Au';
2882 finishPortlet();
2883}
2884
2885function dragon ()
2886{
2887?>
2888<div class=dragon><pre><font color="#00ff33">
2889 \||/
2890 | <font color="#ff0000">@</font>___oo
2891 /\ /\ / (__<font color=yellow>,,,,</font>|
2892 ) /^\) ^\/ _)
2893 ) /^\/ _)
2894 ) _ / / _)
2895 /\ )/\/ || | )_)
2896 &lt; &gt; |(<font color=white>,,</font>) )__)
2897 || / \)___)\
2898 | \____( )___) )___
2899 \______(_______<font color=white>;;;</font> __<font color=white>;;;</font>
2900
2901</font></pre></div>
2902<?php
e673ee24
DO
2903}
2904
2905function renderUIConfig ()
2906{
4fe32e78
DY
2907 global $configCache, $nextorder;
2908 showMessageOrError();
0a1b1268 2909 startPortlet ('Current configuration');
c461c579
DO
2910 echo '<table class=cooltable border=0 cellpadding=5 cellspacing=0 align=center width="50%">';
2911 echo '<tr><th class=tdleft>Option</th><th class=tdleft>Value</th></tr>';
4fe32e78 2912 $order = 'odd';
0a1b1268 2913 foreach ($configCache as $v)
4fe32e78 2914 {
c461c579
DO
2915 if ($v['is_hidden'] != 'no')
2916 continue;
2917 echo "<tr class=row_${order}>";
2918 echo "<td class=tdright>${v['description']}</td>\n";
2919 echo "<td class=tdleft>${v['varvalue']}</td></tr>";
2920 $order = $nextorder[$order];
4fe32e78 2921 }
0a1b1268
DO
2922 echo "</table>\n";
2923 finishPortlet();
7865c525
DO
2924}
2925
4fe32e78
DY
2926function renderUIConfigEditForm ()
2927{
c461c579 2928 global $root, $pageno, $tabno, $configCache;
4fe32e78
DY
2929 showMessageOrError();
2930 startPortlet ('Current configuration');
c461c579
DO
2931 echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='50%'>\n";
2932 echo "<tr><th class=tdleft>Option</th>";
2933 echo "<th class=tdleft>Value</th></tr>";
4fe32e78
DY
2934 echo "<form action='${root}process.php'>";
2935 echo "<input type=hidden name=op value='upd'>";
c461c579
DO
2936 echo "<input type=hidden name=page value='${pageno}'>\n";
2937 echo "<input type=hidden name=tab value='${tabno}'>\n";
4fe32e78
DY
2938
2939 $i = 0;
2940 foreach ($configCache as $v)
2941 {
c461c579
DO
2942 if ($v['is_hidden'] != 'no')
2943 continue;
2944 echo "<input type=hidden name=${i}_varname value='${v['varname']}'>";
2945 echo "<tr><td class=tdright>${v['description']}</td>";
2946 echo "<td class=tdleft><input type=text name=${i}_varvalue value='${v['varvalue']}' size=24></td>";
2947 echo "</tr>\n";
2948 $i++;
4fe32e78
DY
2949 }
2950 echo "<input type=hidden name=num_vars value=${i}>\n";
c461c579 2951 echo "<tr><td colspan=2><input type=submit value='Save changes'></td></tr>";
4fe32e78
DY
2952 echo "</form>";
2953 finishPortlet();
2954}
2955
7865c525
DO
2956// This function queries the gateway about current VLAN configuration and
2957// renders a form suitable for submit. Ah, and it does submit processing as well.
111b4a67
DO
2958function renderVLANMembership ($object_id = 0)
2959{
fc8d0004 2960 global $root, $pageno, $tabno, $remote_username;
111b4a67
DO
2961 if ($object_id <= 0)
2962 {
2963 showError ('Invalid object_id in renderVLANMembership()');
2964 return;
2965 }
7865c525
DO
2966
2967 // Handle probable pending submit.
2968 if (isset ($_REQUEST['portcount']))
111b4a67 2969 {
7865c525
DO
2970 $data = getSwitchVLANs ($object_id);
2971 if ($data === NULL)
2da7c9b0 2972 {
7865c525 2973 showError ('getSwitchVLANs() failed in renderVLANMembership() during submit processing');
fc8d0004
DO
2974 return;
2975 }
7865c525
DO
2976 list ($vlanlist, $portlist) = $data;
2977 // Here we just build up 1 set command for the gateway with all of the ports
2978 // included. The gateway is expected to filter unnecessary changes silently
2979 // and to provide a list of responses with either error or success message
2980 // for each of the rest.
2981 assertUIntArg ('portcount');
2982 $nports = $_REQUEST['portcount'];
2983 $prefix = 'set ';
2984 $log = array();
2985 $setcmd = '';
2986 for ($i = 0; $i < $nports; $i++)
2987 if
2988 (
2989 !isset ($_REQUEST['portname_' . $i]) ||
2990 !isset ($_REQUEST['vlanid_' . $i]) ||
2991 $_REQUEST['portname_' . $i] != $portlist[$i]['portname']
2992 )
2993 $log[] = array ('code' => 'error', 'message' => "Ignoring mailformed record #${i} in form submit");
2994 elseif
2995 (
2996 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
2997 $portlist[$i]['vlaind'] == 'TRUNK'
2998 )
2999 continue;
3000 else
3001 {
3002 $setcmd .= $prefix . $_REQUEST['portname_' . $i] . '=' . $_REQUEST['vlanid_' . $i];
3003 $prefix = ';';
3004 }
3005 printLog ($log);
3006 // Feed the gateway and interpret its (non)response.
3007 if ($setcmd != '')
3008 printLog (setSwitchVLANs ($object_id, $setcmd));
3009 }
3010
3011 // Reload and render.
3012 $data = getSwitchVLANs ($object_id);
3013 if ($data === NULL)
3014 return;
18cb9495 3015 list ($vlanlist, $portlist, $maclist) = $data;
d28ea105 3016
18cb9495
DO
3017 // This table divides the space into 2 columns.
3018 echo '<table border=0 width="100%"><tr><td class=pcleft>';
d28ea105 3019
18cb9495 3020 // left column: 1 portlet
d28ea105 3021 startPortlet ('VLAN table');
18cb9495 3022 echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center width="100%">';
d28ea105
DO
3023 echo "<tr><th>ID</th><th>Description</th></tr>";
3024 $order = 'even';
3025 global $nextorder;
3026 foreach ($vlanlist as $id => $descr)
3027 {
3028 echo "<tr class=row_${order}><td class=tdright>${id}</td><td class=tdleft>${descr}</td></tr>";
3029 $order = $nextorder[$order];
3030 }
3031 echo '</table>';
3032 finishPortlet();
3033
18cb9495
DO
3034 echo '</td><td class=pcright>';
3035 // Right column: table with 2 rows, each holding 1 portlet
3036 echo '<table border=0 width="100%"><tr><td>';
d28ea105
DO
3037
3038 startPortlet ('Port configuration');
18cb9495 3039 echo "<table class=widetable cellspacing=3 cellpadding=5 align=center width='100%'><tr>";
7865c525
DO
3040 echo "<form method=post>";
3041 echo "<input type=hidden name=page value='${pageno}'>";
3042 echo "<input type=hidden name=tab value='${tabno}'>";
3043 echo "<input type=hidden name=object_id value=${object_id}>";
3044 echo "<input type=hidden name=portcount value=" . count ($portlist) . ">\n";
3045 $portno = 0;
9c0b0016 3046 $ports_per_row = getConfigVar ('PORTS_PER_ROW');
7865c525
DO
3047 foreach ($portlist as $port)
3048 {
3049 // Don't let wide forms break our fancy pages.
9c0b0016 3050 if ($portno % $ports_per_row == 0)
fc8d0004 3051 {
7865c525
DO
3052 if ($portno > 0)
3053 echo "</tr>\n";
9c0b0016 3054 echo "<tr><th>" . ($portno + 1) . "-" . ($portno + $ports_per_row) . "</th>";
fc8d0004 3055 }
18cb9495
DO
3056 echo '<td class=port_';
3057 if ($port['status'] == 'notconnect')
3058 echo 'notconnect';
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>';
7865c525
DO
3074 echo "<input type=hidden name=portname_${portno} value=" . $port['portname'] . '>';
3075 if ($port['vlanid'] == 'trunk')
fc8d0004 3076 {
7865c525
DO
3077 echo "<input type=hidden name=vlanid_${portno} value='trunk'>";
3078 echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
fc8d0004 3079 }
7865c525 3080 else
fc8d0004 3081 {
7865c525 3082 echo "<select name=vlanid_${portno}>";
d28ea105 3083 foreach ($vlanlist as $v => $d)
fc8d0004 3084 {
7865c525
DO
3085 echo "<option value=${v}";
3086 if ($v == $port['vlanid'])
3087 echo ' selected';
3088 echo ">${v}</option>";
fc8d0004 3089 }
7865c525 3090 echo "</select>";
fc8d0004 3091 }
7865c525
DO
3092 $portno++;
3093 echo "</td>";
111b4a67 3094 }
9c0b0016 3095 echo "</tr><tr><td colspan=" . ($ports_per_row + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
7865c525 3096 finishPortlet();
d28ea105 3097
18cb9495
DO
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>';
111b4a67
DO
3122}
3123
9c67f713
DO
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.
3126function 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 }
dd9afc41 3134// FIXME: check if SNMP PHP extension is available!
9c67f713
DO
3135 if (isset ($_REQUEST['do_scan']))
3136 {
dd9afc41 3137 $log = array();
1c4d54d4
DO
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// 3560: http://cisco.com/en/US/products/hw/switches/ps5528/products_data_sheet09186a00801f3d7f.html
137b7a50 3141 $ciscomodel[283] = 'WS-C6509-E (9-slot system)';
818e40c7
DO
3142// FIXME: hwtype hardcoded value will become invalid after the Dictionary table transformation
3143// in 0.14.7 version. Either the values will have to be adjusted as well or we have to switch
3144// to value lookup (not reliable).
7a9f3034 3145 $hwtype[283] = 52;
dd9afc41
DO
3146# $ciscomodel[694] = 'WS-C2960-24TC-L (24 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3147# $ciscomodel[695] = 'WS-C2960-48TC-L (48 Ethernet 10/100 ports and 2 dual-purpose uplinks)';
3148 $ciscomodel[696] = 'WS-C2960G-24TC-L (20 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
7a9f3034 3149 $hwtype[696] = 71;
dd9afc41 3150 $ciscomodel[697] = 'WS-C2960G-48TC-L (44 Ethernet 10/100/1000 ports and 4 dual-purpose uplinks)';
7a9f3034 3151 $hwtype[697] = 70;
dd9afc41
DO
3152# $ciscomodel[716] = 'WS-C2960-24TT-L (24 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
3153# $ciscomodel[717] = 'WS-C2960-48TT-L (48 Ethernet 10/100 ports and 2 10/100/1000 uplinks)';
137b7a50 3154# $ciscomodel[633] = 'WS-C3560-24TS (24 Ethernet 10/100 ports and 2 10/100/1000 SFP uplinks)';
7a9f3034 3155# $hwtype[633] = 73;
137b7a50 3156 $ciscomodel[634] = 'WS-C3560-48TS (48 Ethernet 10/100 ports and 4 10/100/1000 SFP uplinks)';
7a9f3034 3157 $hwtype[634] = 74;
137b7a50 3158# $ciscomodel[563] = 'WS-C3560-24PS (24 Ethernet 10/100 POE ports and 2 10/100/1000 SFP uplinks)';
7a9f3034 3159# $hwtype[563] = 75;
137b7a50 3160 $ciscomodel[564] = 'WS-C3560-48PS (48 Ethernet 10/100 POE ports and 4 10/100/1000 SFP uplinks)';
7a9f3034 3161 $hwtype[564] = 76;
1c4d54d4
DO
3162 $ciscomodel[614] = 'WS-C3560G-24PS (24 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
3163 $hwtype[614] = 79;
3164 $ciscomodel[615] = 'WS-C3560G-24TS (24 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3165 $hwtype[615] = 77;
3166 $ciscomodel[616] = 'WS-C3560G-48PS (48 Ethernet 10/100/1000 POE ports and 4 10/100/1000 SFP uplinks)';
3167 $hwtype[616] = 80;
3168 $ciscomodel[617] = 'WS-C3560G-48TS (48 Ethernet 10/100/1000 ports and 4 10/100/1000 SFP uplinks)';
3169 $hwtype[617] = 78;
7a9f3034
DO
3170 $ciscomodel[58] = 'WS-C4503 (3-slot system)';
3171 $hwtype[58] = 49;
3172 $ciscomodel[503] = '4503 (3-slot system)';
3173 $hwtype[503] = 49;
3174 $ciscomodel[59] = 'WS-C4506 (6-slot system)';
3175 $hwtype[59] = 60;
3176 $ciscomodel[502] = '4506 (6-slot system)';
3177 $hwtype[502] = 60;
dd9afc41
DO
3178 assertStringArg ('community');
3179 $community = $_REQUEST['community'];
3180 $objectInfo = getObjectInfo ($object_id);
3181 $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
3182 $sysDescr = snmpget ($endpoints[0], $community, 'sysDescr.0');
3183 // Strip the object type, it's always string here.
3184 $sysDescr = substr ($sysDescr, strlen ('STRING: '));
1c4d54d4 3185 if (strpos ($sysDescr, 'Cisco IOS Software') === 0 or strpos ($sysDescr, 'Cisco Internetwork Operating System Software') === 0)
dd9afc41 3186 $log[] = array ('code' => 'success', 'message' => 'Seems to be a Cisco box');
818e40c7
DO
3187 else
3188 {
3189 $log[] = array ('code' => 'error', 'message' => 'No idea how to handle ' . $sysDescr);
3190 printLog ($log);
3191 return;
3192 }
3193
3194 // It's a Cisco. Go on.
3195 $attrs = getAttrValues ($object_id);
3196 // Only fill in attribute values, if they are not set.
3197 // FIXME: this is hardcoded
3198
3199 if (empty ($attrs[5]['value'])) // SW version
3200 {
3201 $IOSversion = ereg_replace ('^.*, Version ([^ ]+), .*$', '\\1', $sysDescr);
3202 $error = commitUpdateAttrValue ($object_id, 5, $IOSversion);
3203 if ($error == TRUE)
3204 $log[] = array ('code' => 'success', 'message' => 'SW version set to ' . $IOSversion);
3205 else
3206 $log[] = array ('code' => 'error', 'message' => 'Failed settig SW version: ' . $error);
3207 }
3208
3209 if (empty ($attrs[4]['value']) and substr ($IOSversion, 0, 4) == '12.2') // switch OS type
3210 {
3211 $error = commitUpdateAttrValue ($object_id, 4, 21);
3212 if ($error == TRUE)
3213 $log[] = array ('code' => 'success', 'message' => 'Switch OS type set to Cisco IOS 12.2');
3214 else
3215 $log[] = array ('code' => 'error', 'message' => 'Failed settig Switch OS type: ' . $error);
3216 }
3217
dd9afc41
DO
3218 $sysObjectID = snmpget ($endpoints[0], $community, 'sysObjectID.0');
3219 // Transform OID
3220 $sysObjectID = substr ($sysObjectID, strlen ('OID: SNMPv2-SMI::enterprises.9.1.'));
3221 if (!isset ($ciscomodel[$sysObjectID]))
3222 {
3223 $log[] = array ('code' => 'error', 'message' => 'Could not guess exact HW model!');
3224 printLog ($log);
3225 return;
3226 }
3227 $log[] = array ('code' => 'success', 'message' => 'HW is ' . $ciscomodel[$sysObjectID]);
818e40c7
DO
3228 if (empty ($attrs[2]['value']) and isset ($hwtype[$sysObjectID])) // switch HW type
3229 {
3230 $error = commitUpdateAttrValue ($object_id, 2, $hwtype[$sysObjectID]);
3231 if ($error == TRUE)
3232 $log[] = array ('code' => 'success', 'message' => 'HW type set to ' . $ciscomodel[$sysObjectID]);
3233 else
3234 $log[] = array ('code' => 'error', 'message' => 'Failed settig HW type: ' . $error);
3235 }
dd9afc41
DO
3236 // Now fetch ifType, ifDescr and ifPhysAddr and let model-specific code sort the data out.
3237 $ifType = snmpwalkoid ($endpoints[0], $community, 'ifType');
3238 $ifDescr = snmpwalkoid ($endpoints[0], $community, 'ifdescr');
3239 $ifPhysAddress = snmpwalkoid ($endpoints[0], $community, 'ifPhysAddress');
3240 // Combine 3 tables into 1...
3241 $ifList1 = array();
3242 foreach ($ifType as $key => $val)
3243 {
3244 list ($dummy, $ifIndex) = explode ('.', $key);
3245 list ($dummy, $type) = explode (' ', $val);
3246 $ifList1[$ifIndex]['type'] = $type;
3247 }
3248 foreach ($ifDescr as $key => $val)
3249 {
3250 list ($dummy, $ifIndex) = explode ('.', $key);
3251 list ($dummy, $descr) = explode (' ', $val);
3252 $ifList1[$ifIndex]['descr'] = trim ($descr, '"');
3253 }
3254 foreach ($ifPhysAddress as $key => $val)
3255 {
3256 list ($dummy, $ifIndex) = explode ('.', $key);
3257 list ($dummy, $addr) = explode (':', $val);
3258 $addr = str_replace (' ', '', $addr);
3259 $ifList1[$ifIndex]['phyad'] = $addr;
3260 }
3261 // ...and then reverse it inside out to make description the key.
3262 $ifList2 = array();
3263 foreach ($ifList1 as $ifIndex => $data)
3264 {
3265 $ifList2[$data['descr']]['type'] = $data['type'];
3266 $ifList2[$data['descr']]['phyad'] = $data['phyad'];
3267 $ifList2[$data['descr']]['idx'] = $ifIndex;
3268 }
dd9afc41
DO
3269 $newports = 0;
3270 // Now we can directly pick necessary ports from the table accordingly
3271 // to our known hardware model.
3272 switch ($sysObjectID)
3273 {
3274 // FIXME: chassis edge switches often share a common naming scheme, so
3275 // the sequences below have to be generalized. Let's have some duplicated
3276 // code for the time being, as this is the first implementation ever.
3277 case '697': // WS-C2960G-48TC-L
3278 // 44 copper ports: 1X, 2X, 3X...
3279 // 4 combo ports: 45, 46, 47, 48. Don't list SFP connectors atm, as it's not
3280 // clear how to fit them into current Ports table structure.
3281 for ($i = 1; $i <= 48; $i++)
3282 {
3283 $label = ($i >= 45) ? "${i}" : "${i}X";
3284 $error = commitAddPort ($object_id, 'gi0/' . $i, 11, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
3285 if ($error == '')
3286 $newports++;
3287 else
3288 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3289 }
3290 break;
3291 case '696': // WS-C2960G-24TC-L
3292 // Quite similar to the above.
3293 for ($i = 1; $i <= 24; $i++)
3294 {
3295 $label = ($i >= 21) ? "${i}" : "${i}X";
3296 $error = commitAddPort ($object_id, 'gi0/' . $i, 11, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
3297 if ($error == '')
3298 $newports++;
3299 else
3300 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3301 }
3302 break;
137b7a50
DO
3303 case '564': // WS-C3560-48PS
3304 case '634': // WS-C3560-48TS
3305 for ($i = 1; $i <= 48; $i++)
3306 {
3307 $label = "${i}X";
fcafa7b2 3308 $error = commitAddPort ($object_id, 'fa0/' . $i, 6, $label, $ifList2["FastEthernet0/${i}"]['phyad']);
137b7a50
DO
3309 if ($error == '')
3310 $newports++;
3311 else
3312 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3313 }
3314 for ($i = 1; $i <= 4; $i++)
3315 {
3316 $label = "${i}";
3317 $error = commitAddPort ($object_id, 'gi0/' . $i, 11, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
3318 if ($error == '')
3319 $newports++;
3320 else
3321 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3322 }
3323 break;
1c4d54d4
DO
3324 case '614': // WS-C3560G-24PS
3325 case '615': // WS-C3560G-24TS
3326 for ($i = 1; $i <= 24; $i++)
3327 {
3328 $label = "${i}X";
3329 $error = commitAddPort ($object_id, 'gi0/' . $i, 11, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
3330 if ($error == '')
3331 $newports++;
3332 else
3333 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3334 }
3335 break;
3336 case '616': // WS-C3560G-48PS
3337 case '617': // WS-C3560G-48TS
3338 for ($i = 1; $i <= 48; $i++)
3339 {
3340 $label = "${i}X";
3341 $error = commitAddPort ($object_id, 'gi0/' . $i, 11, $label, $ifList2["GigabitEthernet0/${i}"]['phyad']);
3342 if ($error == '')
3343 $newports++;
3344 else
3345 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $label . ': ' . $error);
3346 }
3347 break;
137b7a50
DO
3348 // For modular devices we don't iterate over all possible port names,
3349 // but use the first list to pick everything that looks legitimate
3350 // for this hardware. It would be correct to fetch the list of modules
3351 // installed to generate lists of ports, but who is going to implement
3352 // this?
7a9f3034
DO
3353 case '503': // 4503
3354 case '58': // WS-C4503
3355 case '502': // 4506
3356 case '59': // WS-C4506
137b7a50
DO
3357 case '283': // WS-C6509-E
3358 foreach ($ifList1 as $port)
3359 {
3360 if ($port['type'] != 'ethernet-csmacd(6)')
3361 continue;
3362 // Copper Fa/Gi harvesting is relatively simple, while 10Gig ports can
3363 // have random samples of transciever units.
3364 if (strpos ($port['descr'], 'FastEthernet') === 0) // Fa
3365 {
3366 $prefix = 'fa';
3367 $ptype = 6; // RJ-45/100Base-TX
3368 list ($slotno, $portno) = explode ('/', substr ($port['descr'], strlen ('FastEthernet')));
3369 }
3370 elseif (strpos ($port['descr'], 'GigabitEthernet') === 0) // Gi
3371 {
3372 $prefix = 'gi';
3373 $ptype = 11; // RJ-45/1000Base-T
3374 list ($slotno, $portno) = explode ('/', substr ($port['descr'], strlen ('GigabitEthernet')));
3375 }
3376 else continue;
3377 $label = "slot ${slotno} port ${portno}";
3378 $pname = "${prefix}${slotno}/${portno}";
3379 $error = commitAddPort ($object_id, $pname, $ptype, $label, $port['phyad']);
3380 if ($error == '')
3381 $newports++;
3382 else
3383 $log[] = array ('code' => 'error', 'message' => 'Failed to add port ' . $pname . ': ' . $error);
3384 }
3385 break;
dd9afc41
DO
3386 default:
3387 showError ("Unexpected sysObjectID '${sysObjectID}' in renderSNMPPortFinder()");
3388 }
3389 if ($newports > 0)
3390 $log[] = array ('code' => 'success', 'message' => "Added ${newports} new ports");
3391 printLog ($log);
9c67f713
DO
3392 return;
3393 }
dd9afc41
DO
3394 echo "<form method=post>\n";
3395 echo "<input type=hidden name=pageno value='${pageno}'>\n";
3396 echo "<input type=hidden name=tabno value='${pageno}'>\n";
3397?>
3398<p align=center>
3399This switch has no ports listed, that's why you see this form. If you supply SNMP community,
3400I can try atomatic data harvesting on the switch. As soon as at least one relevant port is found,
3401this tab will not be seen any more. Good luck.<br>
3402<input type=text name=community value='public'>
3403<input type=submit name='do_scan' value='Go!'>
3404</p>
b325120a 3405<?php
9c67f713
DO
3406}
3407
e673ee24 3408?>