function renderVLANMembership($object_id)
{
    try {
        $data = getSwitchVLANs($object_id);
    } catch (RTGatewayError $re) {
        showWarning('Device configuration unavailable:<br>' . $re->getMessage());
        return;
    }
    list($vlanlist, $portlist, $maclist) = $data;
    $vlanpermissions = array();
    foreach ($portlist as $port) {
        if (array_key_exists($port['vlanid'], $vlanpermissions)) {
            continue;
        }
        $vlanpermissions[$port['vlanid']] = array();
        foreach (array_keys($vlanlist) as $to) {
            if (permitted(NULL, NULL, 'setPortVLAN', array(array('tag' => '$fromvlan_' . $port['vlanid']), array('tag' => '$vlan_' . $port['vlanid']))) and permitted(NULL, NULL, 'setPortVLAN', array(array('tag' => '$tovlan_' . $to), array('tag' => '$vlan_' . $to)))) {
                $vlanpermissions[$port['vlanid']][] = $to;
            }
        }
    }
    if (isset($_REQUEST['hl_port_id'])) {
        assertUIntArg('hl_port_id');
        $hl_port_id = intval($_REQUEST['hl_port_id']);
        $object = spotEntity('object', $object_id);
        amplifyCell($object);
        foreach ($object['ports'] as $port) {
            if (mb_strlen($port['name']) && $port['id'] == $hl_port_id) {
                $hl_port_name = $port['name'];
                break;
            }
        }
    }
    echo '<table border=0 width="100%"><tr><td colspan=3>';
    startPortlet('Current status');
    echo "<table class=widetable cellspacing=3 cellpadding=5 align=center width='100%'><tr>";
    printOpFormIntro('setPortVLAN');
    $portcount = count($portlist);
    echo "<input type=hidden name=portcount value=" . $portcount . ">\n";
    $portno = 0;
    $ports_per_row = 12;
    foreach ($portlist as $port) {
        // Don't let wide forms break our fancy pages.
        if ($portno % $ports_per_row == 0) {
            if ($portno > 0) {
                echo "</tr>\n";
            }
            echo "<tr><th>" . ($portno + 1) . "-" . ($portno + $ports_per_row > $portcount ? $portcount : $portno + $ports_per_row) . "</th>";
        }
        $td_class = 'port_';
        if ($port['status'] == 'notconnect') {
            $td_class .= 'notconnect';
        } elseif ($port['status'] == 'disabled') {
            $td_class .= 'disabled';
        } elseif ($port['status'] != 'connected') {
            $td_class .= 'unknown';
        } elseif (!isset($maclist[$port['portname']])) {
            $td_class .= 'connected_none';
        } else {
            $maccount = 0;
            foreach ($maclist[$port['portname']] as $vlanid => $addrs) {
                $maccount += count($addrs);
            }
            if ($maccount == 1) {
                $td_class .= 'connected_single';
            } else {
                $td_class .= 'connected_multi';
            }
        }
        if (isset($hl_port_name) and strcasecmp($hl_port_name, $port['portname']) == 0) {
            $td_class .= (strlen($td_class) ? ' ' : '') . 'border_highlight';
        }
        echo "<td class='{$td_class}'>" . $port['portname'] . '<br>';
        echo "<input type=hidden name=portname_{$portno} value=" . $port['portname'] . '>';
        if ($port['vlanid'] == 'trunk') {
            echo "<input type=hidden name=vlanid_{$portno} value='trunk'>";
            echo "<select disabled multiple='multiple' size=1><option>TRUNK</option></select>";
        } elseif ($port['vlanid'] == 'routed') {
            echo "<input type=hidden name=vlanid_{$portno} value='routed'>";
            echo "<select disabled multiple='multiple' size=1><option>ROUTED</option></select>";
        } elseif (!array_key_exists($port['vlanid'], $vlanpermissions) or !count($vlanpermissions[$port['vlanid']])) {
            echo "<input type=hidden name=vlanid_{$portno} value={$port['vlanid']}>";
            echo "<select disabled name=vlanid_{$portno}>";
            echo "<option value={$port['vlanid']} selected>{$port['vlanid']}</option>";
            echo "</select>";
        } else {
            echo "<select name=vlanid_{$portno}>";
            // A port may belong to a VLAN, which is absent from the VLAN table, this is normal.
            // We must be able to render its SELECT properly at least.
            $in_table = FALSE;
            foreach ($vlanpermissions[$port['vlanid']] as $v) {
                echo "<option value={$v}";
                if ($v == $port['vlanid']) {
                    echo ' selected';
                    $in_table = TRUE;
                }
                echo ">{$v}</option>\n";
            }
            if (!$in_table) {
                echo "<option value={$port['vlanid']} selected>{$port['vlanid']}</option>\n";
            }
            echo "</select>";
        }
        $portno++;
        echo "</td>";
    }
    echo "</tr><tr><td colspan=" . ($ports_per_row + 1) . "><input type=submit value='Save changes'></form></td></tr></table>";
    finishPortlet();
    echo '</td></tr><tr><td class=pcleft>';
    startPortlet('VLAN table');
    echo '<table class=cooltable cellspacing=0 cellpadding=5 align=center width="100%">';
    echo "<tr><th>ID</th><th>Description</th></tr>";
    $order = 'even';
    global $nextorder;
    foreach ($vlanlist as $id => $descr) {
        echo "<tr class=row_{$order}><td class=tdright>{$id}</td><td class=tdleft>{$descr}</td></tr>";
        $order = $nextorder[$order];
    }
    echo '</table>';
    finishPortlet();
    echo '</td><td class=pcright>';
    startPortlet('Color legend');
    echo '<table>';
    echo "<tr><th>port state</th><th>color code</th></tr>";
    echo "<tr><td>not connected</td><td class=port_notconnect>SAMPLE</td></tr>";
    echo "<tr><td>disabled</td><td class=port_disabled>SAMPLE</td></tr>";
    echo "<tr><td>unknown</td><td class=port_unknown>SAMPLE</td></tr>";
    echo "<tr><td>connected with none MAC addresses active</td><td class=port_connected_none>SAMPLE</td></tr>";
    echo "<tr><td>connected with 1 MAC addresses active</td><td class=port_connected_single>SAMPLE</td></tr>";
    echo "<tr><td>connected with 1+ MAC addresses active</td><td class=port_connected_multi>SAMPLE</td></tr>";
    echo '</table>';
    finishPortlet();
    echo '</td><td class=pcright>';
    if (count($maclist)) {
        startPortlet('MAC address table');
        echo '<table border=0 class=cooltable align=center cellspacing=0 cellpadding=5>';
        echo "<tr><th>Port</th><th>VLAN ID</th><th>MAC address</th></tr>\n";
        $order = 'even';
        foreach ($maclist as $portname => $portdata) {
            foreach ($portdata as $vlanid => $addrgroup) {
                foreach ($addrgroup as $addr) {
                    echo "<tr class=row_{$order}><td class=tdleft>{$portname}</td><td class=tdleft>{$vlanid}</td>";
                    echo "<td class=tdleft>{$addr}</td></tr>\n";
                    $order = $nextorder[$order];
                }
            }
        }
        echo '</table>';
        finishPortlet();
    }
    // End of main table.
    echo '</td></tr></table>';
}
示例#2
0
function setPortVLAN()
{
    assertUIntArg('portcount');
    try {
        $data = getSwitchVLANs($_REQUEST['object_id']);
    } catch (RTGatewayError $re) {
        return showFuncMessage(__FUNCTION__, 'ERR', array($re->getMessage()));
    }
    list($vlanlist, $portlist) = $data;
    // Here we just build up 1 set command for the gateway with all of the ports
    // included. The gateway is expected to filter unnecessary changes silently
    // and to provide a list of responses with either error or success message
    // for each of the rest.
    $nports = $_REQUEST['portcount'];
    $prefix = 'set ';
    $setcmd = '';
    for ($i = 0; $i < $nports; $i++) {
        genericAssertion('portname_' . $i, 'string');
        genericAssertion('vlanid_' . $i, 'string');
        if ($_REQUEST['portname_' . $i] != $portlist[$i]['portname']) {
            throw new InvalidRequestArgException('portname_' . $i, $_REQUEST['portname_' . $i], 'expected to be ' . $portlist[$i]['portname']);
        }
        if ($_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] || $portlist[$i]['vlanid'] == 'TRUNK') {
            continue;
        }
        $portname = $_REQUEST['portname_' . $i];
        $oldvlanid = $portlist[$i]['vlanid'];
        $newvlanid = $_REQUEST['vlanid_' . $i];
        if (!permitted(NULL, NULL, NULL, array(array('tag' => '$fromvlan_' . $oldvlanid), array('tag' => '$vlan_' . $oldvlanid))) or !permitted(NULL, NULL, NULL, array(array('tag' => '$tovlan_' . $newvlanid), array('tag' => '$vlan_' . $newvlanid)))) {
            showOneLiner(159, array($portname, $oldvlanid, $newvlanid));
            continue;
        }
        $setcmd .= $prefix . $portname . '=' . $newvlanid;
        $prefix = ';';
    }
    // Feed the gateway and interpret its (non)response.
    if ($setcmd == '') {
        showOneLiner(201);
    } else {
        try {
            setSwitchVLANs($_REQUEST['object_id'], $setcmd);
            // shows messages by itself
        } catch (RTGatewayError $e) {
            showFuncMessage(__FUNCTION__, 'ERR', array($e->getMessage()));
        }
    }
}