function guifi_radio_radio_form($radio, $key, &$form_weight = -200)
{
    guifi_log(GUIFILOG_TRACE, sprintf('function _guifi_radio_radio_form(key=%d)', $key), $radio);
    $f['storage'] = guifi_form_hidden_var($radio, array('radiodev_counter'), array('radios', $key));
    $f = array('#type' => 'fieldset', '#title' => t('Radio #') . $key . ' - ' . $radio['mode'] . ' - ' . $radio['ssid'] . ' - ' . count($radio['interfaces']) . ' ' . t('interface(s)'), '#collapsible' => TRUE, '#collapsed' => !isset($radio['unfold']), '#tree' => TRUE, '#weight' => $form_weight++);
    if ($radio['deleted']) {
        $f['deletedMsg'] = array('#type' => 'item', '#value' => guifi_device_item_delete_msg("This radio and has been deleted, " . "deletion will cascade to all properties, including interfaces, " . "links and ip addresses."), '#weight' => $form_weight++);
        $f['deleted'] = array('#type' => 'hidden', '#value' => TRUE);
    }
    if ($radio['new']) {
        $f['new'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'new'), '#value' => TRUE);
    }
    $f['mode'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'mode'), '#value' => $radio['mode']);
    $f['s'] = array('#type' => 'fieldset', '#title' => t('Radio main settings (SSID, MAC, Channel...)'), '#collapsible' => TRUE, '#collapsed' => !isset($radio['unfold_main']), '#tree' => FALSE);
    // DUMMY Radio MAC
    if (empty($radio['mac'])) {
        $radio['mac'] = "00:00:00:00:00:00";
    }
    $f['s']['mac'] = array('#type' => 'textfield', '#title' => t('MAC'), '#required' => TRUE, '#parents' => array('radios', $key, 'mac'), '#size' => 17, '#maxlength' => 17, '#default_value' => $radio["mac"], '#element_validate' => array('guifi_mac_validate'), '#description' => t("Wireless MAC Address.<br />Some configurations won't work if is blank"));
    switch ($radio['mode']) {
        case 'ap':
        case 'mesh':
            $f['s']['ssid'] = array('#type' => 'textfield', '#title' => t('SSID'), '#parents' => array('radios', $key, 'ssid'), '#required' => TRUE, '#size' => 22, '#maxlength' => 22, '#default_value' => $radio["ssid"], '#description' => t("SSID to identify this radio signal."));
            $f['s']['protocol'] = array('#type' => 'select', '#title' => t("Protocol"), '#parents' => array('radios', $key, 'protocol'), '#default_value' => $radio["protocol"], '#options' => guifi_types('protocol'), '#description' => t('Select the protocol where this radio will operate.'), '#ahah' => array('path' => 'guifi/js/channel/' . $key, 'wrapper' => 'select-channel-' . $key, 'method' => 'replace', 'effect' => 'fade'));
            $f['s']['channel'] = guifi_radio_channel_field($key, $radio["channel"], $radio['protocol']);
            $f['s']['chbandwith'] = guifi_radio_channel_bwith_field($key, $radio["chbandwith"]);
            if ($radio['mode'] == 'ap') {
                $f['ap'] = array('#type' => 'fieldset', '#title' => t('Connection acceptance policy'), '#description' => t('Please specify if this radio do accept simple client connections and if a funding is required to contribute for the coverage infrastructure'), '#collapsible' => TRUE, '#collapsed' => $radio["clients_accepted"] == 'Yes' ? false : true, '#tree' => TRUE, '#attributes' => array('class' => 'fieldset-radio'));
                $f['ap']['clients_accepted'] = array('#type' => 'select', '#title' => t("Clients accepted?"), '#parents' => array('radios', $key, 'clients_accepted'), '#default_value' => $radio["clients_accepted"], '#options' => drupal_map_assoc(array(0 => 'Yes', 1 => 'No')), '#description' => t('Do this radio accept connections from clients?'));
                $f['ap']['fund_required'] = array('#type' => 'select', '#title' => t("Policy"), '#parents' => array('radios', $key, 'fund_required'), '#default_value' => $radio["fund_required"], '#options' => guifi_types('contribution'), '#description' => t('Funding required?'));
                $f['ap']['fund_amount'] = array('#type' => 'textfield', '#size' => 12, '#maxlength' => 15, '#required' => false, '#title' => t("Amount"), '#parents' => array('radios', $key, 'fund_amount'), '#default_value' => $radio["fund_amount"], '#attributes' => array('' . 'class' => 'number required', 'min' => 1), '#description' => t('Funding if required'));
                $f['ap']['fund_currency'] = array('#type' => 'select', '#title' => t("Currency"), '#parents' => array('radios', $key, 'fund_currency'), '#default_value' => $radio["fund_currency"], '#options' => drupal_map_assoc(array('€' => 'Euros', '$' => 'US Dollar')));
            } else {
                $f['s']['clients_accepted'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'clients_accepted'), '#value' => $radio["clients_accepted"]);
                $f['s']['fund_required'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'fund_required'), '#value' => $radio["fund_required"]);
                $f['s']['fund_amount'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'fund_amount'), '#value' => $radio["fund_amount"]);
                $f['s']['fund_currency'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'fund_currency'), '#value' => $radio["fund_currency"]);
            }
            break;
        case 'client':
            $inherit_msg = t('Will take it from the connected AP.');
            $f['s']['ssid'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'ssid'), '#title' => t('SSID'), '#default_value' => $radio["ssid"], '#description' => $inherit_msg);
            $f['s']['protocol'] = array('#type' => 'hidden', '#title' => t("Protocol"), '#parents' => array('radios', $key, 'protocol'), '#value' => $radio["protocol"], '#description' => $inherit_msg);
            $f['s']['channel'] = array('#type' => 'hidden', '#title' => t("Channel"), '#parents' => array('radios', $key, 'channel'), '#default_value' => $radio["channel"], '#options' => guifi_types('channel', NULL, NULL, $radio['protocol']), '#description' => $inherit_msg);
            $f['s']['clients_accepted'] = array('#type' => 'hidden', '#parents' => array('radios', $key, 'clients_accepted'), '#value' => $radio["clients_accepted"]);
            break;
    }
    // Antenna settings group
    $f['antenna'] = array('#type' => 'fieldset', '#title' => t('Antenna settings'), '#collapsible' => TRUE, '#collapsed' => !isset($radio['unfold_antenna']), '#tree' => FALSE, '#attributes' => array('class' => 'fieldset-radio'));
    $fw2 = 0;
    $f['antenna']['antenna_angle'] = array('#type' => 'select', '#title' => t("Type (angle)"), '#parents' => array('radios', $key, 'antenna_angle'), '#default_value' => $radio["antenna_angle"], '#options' => guifi_types('antenna'), '#description' => t('Beam width angle'));
    $f['antenna']['antenna_gain'] = array('#type' => 'select', '#title' => t("Gain"), '#parents' => array('radios', $key, 'antenna_gain'), '#default_value' => $radio["antenna_gain"], '#options' => guifi_types('antenna_gain'), '#description' => t('Gain (Db)'));
    $f['antenna']['antenna_azimuth'] = array('#type' => 'textfield', '#title' => t('Degrees (º)'), '#parents' => array('radios', $key, 'antenna_azimuth'), '#size' => 3, '#maxlength' => 3, '#default_value' => $radio["antenna_azimuth"], '#description' => t('Azimuth<br>(0-360º)'));
    $f['antenna']['antenna_mode'] = array('#type' => 'select', '#title' => t("Connector"), '#parents' => array('radios', $key, 'antenna_mode'), '#default_value' => $radio["antenna_mode"], '#options' => array('' => 'Don\'t change', 'Main' => 'Main/Right/Internal', 'Aux' => 'Aux/Left/External'), '#description' => t('Examples:<br />MiniPci: Main/Aux<br />Linksys: Right/Left<br />Nanostation: Internal/External'));
    foreach ($radio['interfaces'] as $iid => $interface) {
        $f['interfaces'][$iid] = guifi_interfaces_form($interface, array('radios', $key, 'interfaces', $iid));
    }
    return $f;
}
/**
 * @file guifi_interfaces.inc.php
 */
function guifi_interfaces_form(&$interface, $ptree)
{
    global $hotspot;
    $cable = FALSE;
    guifi_log(GUIFILOG_TRACE, 'function guifi_interfaces_form()', $interface);
    $key = $ptree[count($ptree) - 1];
    // Interface type shoudn't be NULL
    if ($interface['interface_type'] == NULL) {
        return;
    }
    $it = $interface['interface_type'];
    if ($it == 'Wan') {
        $interface['unfold'] = TRUE;
        $msg = t('Connection to AP');
    } else {
        $msg = $it;
    }
    $f = array('#type' => 'fieldset', '#title' => $msg, '#collapsible' => TRUE, '#collapsed' => !isset($interface['unfold']), '#description' => t('Go to Port connections section to rename interfaces or edit physical links'), '#attributes' => array('class' => 'fieldset-interface-port'));
    $f['interface'] = guifi_form_hidden_var($interface, array('id', 'interface_type', 'radiodev_counter'), $ptree);
    // Cable interface buttons
    if ($ptree[0] == 'interfaces' and !$interface['deleted']) {
        $cable = TRUE;
        $f['interface']['niid'] = array('#type' => 'textfield', '#title' => t('Name'), '#parents' => array_merge($ptree, array('interface_type')), '#disabled' => true, '#size' => 10, '#maxlength' => 60, '#value' => $interface['interface_type'], '#attributes' => array('class' => 'interface-item'));
        if (!empty($interface['connto_did'])) {
            $dname = guifi_get_devicename($interface['connto_did']);
            $dinterfaces = guifi_get_device_interfaces($interface['connto_did'], $interface['connto_iid']);
            $f['interface']['dname'] = array('#type' => 'textfield', '#title' => t('Connects to'), '#disabled' => true, '#size' => 40, '#maxsize' => 256, '#value' => $interface['connto_iid'] ? $dname . ' / ' . $dinterfaces[$interface['connto_iid']] : $dname, '#attributes' => array('class' => 'interface-item'));
        }
        if (!$interface['new']) {
            $f['interface']['AddPublicSubnetMask'] = array('#type' => 'hidden', '#value' => '255.255.255.224', '#parents' => array_merge($ptree, array('AddPublicSubnetMask')), '#prefix' => '<div>&nbsp</div><div id="editInterface-' . $key . '">', '#suffix' => '</div>');
            $f['interface']['AddCableLink'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/addprivatecablelink.png', '#parents' => array_merge($ptree, array('AddCableLink')), '#attributes' => array('title' => t('Link to another device at the node using a private network')), '#ahah' => array('path' => 'guifi/js/add-cable-link/' . $key, 'wrapper' => 'editInterface-' . $key, 'method' => 'replace', 'effect' => 'fade'));
            $f['interface']['AddPublicSubnet'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/insertwlan.png', '#parents' => array_merge($ptree, array('AddPublicSubnet')), '#attributes' => array('title' => t('Allocate a Public Subnetwork to the interface')), '#ahah' => array('path' => 'guifi/js/add-subnet-mask/' . $key, 'wrapper' => 'editInterface-' . $key, 'method' => 'replace', 'effect' => 'fade'));
        } else {
            $f['interface']['msg'] = array('#type' => 'item', '#title' => t('New interface'), '#description' => t('Save to database to add links or allocate subnetworks'));
            $f['interface']['itype']['#disabled'] = false;
        }
    }
    // wds/p2p link, allow to create new links
    if ($it == 'wds/p2p' || $interface['interface_class'] == 'wds/p2p') {
        $f['interface']['AddWDS'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/wdsp2p.png', '#parents' => array_merge($ptree, array('AddWDS', $ptree[1], $ptree[2])), '#attributes' => array('title' => t('Add WDS/P2P link to extend the backbone')), '#submit' => array('guifi_radio_add_wds_submit'));
    }
    if ($interface['deleted']) {
        $f['interface']['deleteMsg'] = array('#type' => 'item', '#value' => t('Deleted'), '#description' => guifi_device_item_delete_msg('This interface has been deleted, ' . 'related addresses and links will be also deleted'));
    } else {
        if ($it != 'wds/p2p' and $interface['interface_class'] != 'wds/p2p' and $it != 'wLan/Lan' and $it != 'Wan') {
            $f['interface']['deleteInterface'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/drop.png', '#parents' => array_merge($ptree, array('deleteInterface')), '#attributes' => array('title' => t('Delete interface')), '#submit' => array('guifi_interfaces_delete_submit'));
        }
    }
    $ipv4Count = 0;
    if (count($interface['ipv4']) > 0) {
        foreach ($interface['ipv4'] as $ka => $ipv4) {
            if (!$ipv4['deleted']) {
                $ipv4Count++;
            }
            $f['ipv4'][$ka] = guifi_device_ipv4_link_form($ipv4, array_merge($ptree, array('ipv4', $ka)), $cable);
        }
    }
    // foreach ipv4
    // Mode Client or client-routed, allow to link to AP
    if ($it == 'Wan' and $ipv4Count == 0) {
        $f['interface']['Link2AP'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/link2ap.png', '#parents' => array('Link2AP', $ptree[1], $interface['id']), '#attributes' => array('title' => t('Create a simple (ap/client) link to an Access Point')), '#submit' => array('guifi_radio_add_link2ap_submit'));
    }
    if ($it != 'HotSpot') {
        $f['#title'] .= ' - ' . $ipv4Count . ' ' . t('address(es)');
    } else {
        $hotspot = TRUE;
    }
    return $f;
}
function guifi_host_host_form($host, $key, &$form_weight = -200)
{
    guifi_log(GUIFILOG_TRACE, sprintf('function _guifi_host_host_form(key=%d)', $key), $host);
    $f['storage'] = guifi_form_hidden_var($host, array('counter'), array('hosts', $key));
    if (empty($host['ipv4'])) {
        $lsav4 = ' ';
    } else {
        $lsav4 = ' ··· ' . t('IPv4:') . ' ' . $host['ipv4'];
    }
    if (empty($host['ipv6'])) {
        $lsav6 = ' ';
    } else {
        $lsav6 = ' ··· ' . t('IPv6:') . ' ' . $host['ipv6'];
    }
    $f = array('#type' => 'fieldset', '#title' => t('Host:') . ' ' . $host['host'] . $lsav4 . $lsav6, '#collapsible' => TRUE, '#collapsed' => !isset($host['unfold']), '#tree' => TRUE, '#weight' => $form_weight++);
    if ($host['host'] == 'ns1' and $host['counter'] == '0') {
        $access = FALSE;
    } else {
        $access = TRUE;
    }
    $f[] = array('#type' => 'textfield', '#access' => $access, '#title' => t('Host Name'), '#parents' => array('hosts', $key, 'host'), '#default_value' => $host['host'], '#weight' => $form_weight++);
    $f[] = array('#type' => 'textfield', '#title' => t("IPv4 Address"), '#parents' => array('hosts', $key, 'ipv4'), '#default_value' => $host['ipv4'], '#element_validate' => array('guifi_ipv4_validate'), '#description' => t('Leave it blank if you want to use an alias (CNAME ) to an external domain.<br /> ex: hostname is an alias of hostname.dyndns.org.') . t('<br>This address is usually the same IP as the domain NameServer.'), '#weight' => $form_weight++);
    $f[] = array('#type' => 'textfield', '#title' => t("IPv6 Address"), '#parents' => array('hosts', $key, 'ipv6'), '#default_value' => $host['ipv6'], '#element_validate' => array('guifi_ipv6_validate'), '#description' => t('Leave it blank if you want to use an alias (CNAME ) to an external domain.<br /> ex: hostname is an alias of hostname.dyndns.org.') . t('<br>This address is usually the same IP as the domain NameServer.'), '#weight' => $form_weight++);
    if ($host['deleted']) {
        $f['deletedMsg'] = array('#type' => 'item', '#value' => guifi_device_item_delete_msg("This host has been deleted"), '#weight' => $form_weight++);
        $f['deleted'] = array('#type' => 'hidden', '#value' => TRUE);
    }
    if ($host['new']) {
        $f['new'] = array('#type' => 'hidden', '#parents' => array('hosts', $key, 'new'), '#value' => TRUE);
    }
    return $f;
}
/**
 * @file guifi_links.inc.php
 */
function guifi_links_form($link, $ipv4, $tree, $multilink)
{
    $lweight = 0;
    // edit link details
    guifi_log(GUIFILOG_TRACE, 'guifi_links_form()', $link);
    $ki = $tree[count($tree) - 3];
    $ka = $tree[count($tree) - 1];
    if (count($tree) > 4) {
        $rk = $tree[1];
    } else {
        $rk = NULL;
    }
    // creating hidden form elements for non-edited fields
    if ($link['new']) {
        $link['id'] = -1;
    }
    // link hidden vars
    $f['storage'] = guifi_form_hidden_var($link, array('id', 'nid', 'device_id', 'interface_id', 'link_type'), array_merge($tree, array('links', $link['id'])));
    // remote interface hidden vars
    $f['interface'] = guifi_form_hidden_var($link['interface'], array('id', 'interface_type', 'radiodev_counter'), array_merge($tree, array('links', $link['id'], 'interface')));
    $f['remote_ipv4'] = guifi_form_hidden_var($link['interface']['ipv4'], array('id', 'interface_id', 'netmask'), array_merge($tree, array('links', $link['id'], 'interface', 'ipv4')));
    // linked node-device
    if ($link['type'] != 'cable') {
        $descr = guifi_get_ap_ssid($link['device_id'], $link['radiodev_counter']);
    } else {
        $descr = guifi_get_interface_descr($link['interface_id']);
    }
    $f['l'] = array('#type' => 'fieldset', '#title' => guifi_get_nodename($link['nid']) . '/' . guifi_get_hostname($link['device_id']), '#collapsible' => TRUE, '#collapsed' => !isset($link['unfold']));
    if ($link['deleted']) {
        $f['l']['#description'] = guifi_device_item_delete_msg('<b>Link deleted</b>.');
    }
    $f['l']['beginTable'] = array('#value' => '<table style="width: 0">');
    if (user_access('administer guifi networks')) {
        if (!$multilink) {
            $f['l']['ipv4'] = array('#type' => 'textfield', '#parents' => array_merge($tree, array('ipv4')), '#size' => 16, '#maxlength' => 16, '#default_value' => $ipv4['ipv4'], '#title' => t('Local IPv4'), '#element_validate' => array('guifi_validate_ip'), '#prefix' => '<td>', '#suffix' => '</td>');
        }
        $f['l']['ipv4_remote'] = array('#type' => 'textfield', '#parents' => array_merge($tree, array('links', $link['id'], 'interface', 'ipv4', 'ipv4')), '#size' => 16, '#maxlength' => 16, '#default_value' => $link['interface']['ipv4']['ipv4'], '#title' => t('Remote IPv4'), '#element_validate' => array('guifi_validate_ip', 'guifi_links_validate_subnet'), '#prefix' => '<td>', '#suffix' => '</td>');
        if (!$multilink) {
            $f['l']['netmask'] = array('#type' => 'select', '#parents' => array_merge($tree, array('netmask')), '#title' => t("Network mask"), '#default_value' => $ipv4['netmask'], '#options' => guifi_types('netmask', 30, 0), '#prefix' => '<td>', '#suffix' => '</td>');
        }
    } else {
        if (!$multilink) {
            $f['l']['ipv4'] = array('#type' => 'value', '#parents' => array_merge($tree, array('ipv4')), '#value' => $ipv4['ipv4']);
            $f['l']['netmask'] = array('#type' => 'value', '#parents' => array_merge($tree, array('netmask')), '#value' => $ipv4['netmask']);
        }
        $f['l']['ipv4_remote'] = array('#type' => 'value', '#parents' => array_merge($tree, array('links', $link['id'], 'interface', 'ipv4', 'ipv4')), '#value' => $link['interface']['ipv4']['ipv4']);
        $f['l']['ipv4_remote_display'] = array('#type' => 'item', '#parents' => array_merge($tree, array('links', $link['id'], 'interface', 'ipv4', 'ipv4')), '#title' => t('Remote IPv4'), '#value' => $link['interface']['ipv4']['ipv4'], '#description' => $link['interface']['ipv4']['netmask'], '#prefix' => '<td>', '#suffix' => '</td>');
    }
    // if network administrator
    $f['l']['overlap'] = array('#type' => 'hidden', '#parents' => array_merge($tree, array('overlap')), '#value' => $ipv4['netmask'], '#element_validate' => array('guifi_links_check_overlap'));
    // Routing
    $f['l']['routing'] = array('#type' => 'select', '#parents' => array_merge($tree, array('links', $link['id'], 'routing')), '#title' => t("Routing"), '#default_value' => $link['routing'], '#options' => guifi_types('routing'), '#prefix' => '<td>', '#suffix' => '</td>');
    // Status
    $f['l']['status'] = array('#type' => 'select', '#parents' => array_merge($tree, array('links', $link['id'], 'flag')), '#title' => t("Status"), '#default_value' => $link['flag'], '#options' => guifi_types('status'), '#prefix' => '<td>', '#suffix' => '</td>');
    // remote interface (cable links)
    if ($link['link_type'] == 'cable') {
        $f['l']['remote_interface_type'] = array('#type' => 'textfield', '#parents' => array_merge($tree, array('links', $link['id'], 'interface', 'interface_type')), '#title' => t("Remote interface"), '#default_value' => $link['interface']['interface_type'], '#size' => 10, '#maxzise' => 60, '#prefix' => '<td>', '#suffix' => '</td>');
    }
    // delete link button
    if ($link['deleted']) {
        $f['deleted_link'] = array('#type' => 'hidden', '#parents' => array_merge($tree, array('deleted_link')), '#value' => TRUE);
    } else {
        $f['l']['delete_link'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/drop.png', '#parents' => array_merge($tree, array('delete_link', $link['id'], $link['nid'], $link['device_id'])), '#attributes' => array('title' => t('Delete link with') . ': ' . guifi_get_interface_descr($link['interface_id'])), '#executes_submit_callback' => TRUE, '#submit' => array('guifi_links_delete_submit'), '#prefix' => '<td>');
    }
    $f['l']['endTable'] = array('#value' => '</td></tr></table>');
    return $f;
}
function guifi_device_ipv4_link_form($ipv4, $tree, $cable = TRUE)
{
    $ki = $tree[count($tree) - 3];
    $ka = $tree[count($tree) - 1];
    if (count($tree) > 4) {
        $rk = $tree[1];
    } else {
        $rk = NULL;
    }
    guifi_log(GUIFILOG_TRACE, 'guifi_device_ipv4_link_form()', $ipv4);
    $f['storage']['ipv4_local'] = guifi_form_hidden_var($ipv4, array('interface_id', 'ipv4_type'), $tree);
    if (count($ipv4['links']) > 1 or $ipv4['netmask'] != '255.255.255.252' and count($ipv4['links']) < 2) {
        // multilink set
        $multilink = TRUE;
        $f['local'] = array('#type' => 'fieldset', '#parents' => $tree, '#title' => $ipv4['ipv4'] . ' / ' . $ipv4['netmask'] . ' - ' . count($ipv4['links']) . ' ' . t('link(s)'), '#collapsible' => TRUE, '#collapsed' => !isset($ipv4['unfold']));
        if ($cable) {
            $f['local']['AddCableLink'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/addcable.png', '#parents' => array_merge($tree, array('AddCableLink')), '#attributes' => array('title' => t('Link to another device using a public IPv4 address')), '#ahah' => array('path' => 'guifi/js/add-cable-link/' . $ipv4['interface_id'] . ',' . $ipv4['id'], 'wrapper' => 'editInterface-' . $ipv4['interface_id'] . '-' . $ipv4['id'], 'method' => 'replace', 'effect' => 'fade'), '#prefix' => '<div id="' . 'editInterface-' . $ipv4['interface_id'] . '-' . $ipv4['id'] . '">', '#suffix' => '</div>');
        }
        if ($ipv4['deleted']) {
            $f['local']['deleteMsg'] = array('#type' => 'item', '#value' => t('Deleted'), '#description' => guifi_device_item_delete_msg('This IPv4 address has been deleted, ' . 'related links will be also deleted'));
        }
        $f['local']['id'] = array('#type' => 'hidden', '#parents' => array_merge($tree, array('id')), '#default_value' => $ipv4['id']);
        if (user_access('administer guifi networks') and !isset($ipv4['deleted'])) {
            $f['local']['ipv4'] = array('#type' => 'textfield', '#parents' => array_merge($tree, array('ipv4')), '#size' => 16, '#maxlength' => 16, '#default_value' => $ipv4['ipv4'], '#title' => t('Local IPv4'), '#prefix' => '<td>', '#suffix' => '</td>');
            $f['local']['netmask'] = array('#type' => 'select', '#parents' => array_merge($tree, array('netmask')), '#title' => t("Network mask"), '#default_value' => $ipv4['netmask'], '#options' => guifi_types('netmask', 32, 0), '#prefix' => '<td align="left">', '#suffix' => '</td>');
        } else {
            $f['local']['ipv4'] = array('#type' => 'value', '#parents' => array_merge($tree, array('ipv4')), '#value' => $ipv4['ipv4']);
            $f['local']['netmask'] = array('#type' => 'value', '#parents' => array_merge($tree, array('netmask')), '#value' => $ipv4['netmask']);
            $f['local']['ipv4_display'] = array('#type' => 'item', '#parents' => array_merge($tree, array('ipv4')), '#title' => t('Local IPv4'), '#value' => $ipv4['ipv4'], '#element_validate' => array('guifi_validate_ip'), '#description' => $ipv4['netmask'], '#prefix' => $prefix, '#prefix' => '<td align="left">', '#suffix' => '</td>');
        }
    } else {
        // singlelink set
        $multilink = FALSE;
    }
    // Deleting the IP address
    if ($multilink and !$ipv4['deleted']) {
        $f['local']['delete_address'] = array('#type' => 'image_button', '#src' => drupal_get_path('module', 'guifi') . '/icons/drop.png', '#parents' => array_merge($tree, array('delete_address')), '#attributes' => array('title' => t('Delete address')), '#submit' => array('guifi_ipv4_delete_submit'), '#prefix' => '<td>', '#suffix' => '</td>');
    } else {
        if ($ipv4['deleted'] and !multilink) {
            $f['local']['delete_address'] = array('#type' => 'item', '#description' => guifi_device_item_delete_msg("Address deleted:"), '#prefix' => '<td>', '#suffix' => '</td>');
        }
    }
    $f['local']['beginTable'] = array('#value' => '<table style="width: 0"><tr>', '#weight' => -99);
    $f['local']['endTable'] = array('#value' => '</tr></table>');
    // foreach link
    if (count($ipv4['links'])) {
        foreach ($ipv4['links'] as $kl => $link) {
            //    if ($link['deleted'])
            //      continue;
            // linked node-device
            $f['local']['links'][$kl] = guifi_links_form($link, $ipv4, $tree, $multilink);
        }
    }
    // foreach link
    return $f;
}