%PDF- %PDF-
Direktori : /backups/router/usr/local/etc/inc/ |
Current File : //backups/router/usr/local/etc/inc/console.inc |
<?php /* * Copyright (C) 2015-2022 Franco Fichtner <franco@opnsense.org> * Copyright (C) 2004-2010 Scott Ullrich <sullrich@gmail.com> * Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ function timeout($timer = 7) { while (!isset($key)) { if ($timer >= 9) { echo chr(8) . chr(8) . ($timer == 9 ? chr(32) : null) . "{$timer}"; } else { echo chr(8) . "{$timer}"; } shell_exec('/bin/stty -icanon min 0 time 10'); $key = shell_exec('/bin/dd count=1 status=none'); shell_exec('/bin/stty icanon'); if ($key == '') { unset($key); } $timer--; if ($timer == 0) { break; } } return $key; } function is_interface_mismatch($locked = true) { $mismatch = false; $patterns = []; foreach (plugins_devices() as $device) { if ($device['volatile']) { $patterns[] = "({$device['pattern']})"; } } $regex = count($patterns) ? '/' . implode('|', $patterns) . '/' : null; foreach (legacy_config_get_interfaces(['virtual' => false]) as $ifname => $ifcfg) { if ($locked && !empty($ifcfg['lock'])) { /* Do not mismatch if any lock was issued */ $mismatch = false; break; } elseif (!empty($regex) && preg_match($regex, $ifcfg['if'])) { /* Do not check these interfaces */ continue; } elseif (does_interface_exist($ifcfg['if']) == false) { /* Continue loop, may still find a lock */ $mismatch = true; } } return $mismatch; } function set_networking_interfaces_ports($probe = false) { exec('/sbin/conscontrol mute on'); $ret = _set_networking_interfaces_ports($probe); exec('/sbin/conscontrol mute off'); return $ret; } function _set_networking_interfaces_ports($probe = false) { global $config; $fp = fopen('php://stdin', 'r'); $yes_no_prompt = '[y/N]: '; $interactive = true; $key = null; $iflist = get_interface_list(false, true); $iflist_wlan = legacy_interface_listget('wlan'); $iflist_lagg = []; $iflist_all = []; foreach ($iflist as $iface => $ifa) { $iflist_all[$iface] = $ifa; legacy_interface_flags($iface, 'up'); } if ($probe) { echo PHP_EOL . 'Press any key to start the manual interface assignment: '; $key = timeout(); if (!isset($key)) { $interactive = false; } if ($key != "\n") { echo PHP_EOL; } } if (!empty($iflist)) { echo <<<EOD Do you want to configure LAGGs now? {$yes_no_prompt} EOD; if ($interactive) { $key = chop(fgets($fp)); } else { $key = 'n'; echo $key . PHP_EOL; } if (in_array($key, array('y', 'Y'))) { lagg_setup($iflist, $fp); echo "\n"; } if (isset($config['laggs']['lagg'][0])) { foreach ($config['laggs']['lagg'] as $lagg) { $iflist_lagg[$lagg['laggif']] = $iflist_all[$lagg['laggif']] = [ 'dmesg' => "Link aggregation, member interfaces {$lagg['members']}", 'mac' => '00:00:00:00:00:00', ]; } } echo <<<EOD Do you want to configure VLANs now? {$yes_no_prompt} EOD; if ($interactive) { $key = chop(fgets($fp)); } else { $key = 'n'; echo $key . PHP_EOL; } if (in_array($key, array('y', 'Y'))) { vlan_setup(array_merge($iflist, $iflist_lagg), $fp); } if (isset($config['vlans']['vlan'][0])) { foreach ($config['vlans']['vlan'] as $vlan) { $iflist_all[$vlan['vlanif']] = [ 'dmesg' => "VLAN tag {$vlan['tag']}, parent interface {$vlan['if']}", 'mac' => '00:00:00:00:00:00', ]; } } } /* add WLAN parents now as LAGG/VLAN are not capable of handling it */ foreach ($iflist_wlan as $iface) { $iflist_all[$iface] = [ 'dmesg' => 'WLAN device parent', 'mac' => '00:00:00:00:00:00', ]; } echo <<<EOD Valid interfaces are: EOD; if (empty($iflist_all)) { echo "No interfaces found!\n"; } else { foreach ($iflist_all as $iface => $ifa) { echo sprintf("%-16s %s %s\n", $iface, $ifa['mac'], $ifa['dmesg']); } } echo <<<EOD If you do not know the names of your interfaces, you may choose to use auto-detection. In that case, disconnect all interfaces now before hitting 'a' to initiate auto detection. EOD; $ifnames = array_keys($iflist_all); /* only for non-interactive mode */ do { echo "\nEnter the WAN interface name or 'a' for auto-detection: "; if ($interactive) { $wanif = chop(fgets($fp)); } else { /* more than one interface: put WAN as second one */ $wanif = count($ifnames) > 1 ? $ifnames[1] : ''; echo $wanif . PHP_EOL; } if ($wanif == '') { break; } if ($wanif == 'a') { $wanif = autodetect_interface('WAN', $fp); if ($wanif == '') { continue; } } if (!array_key_exists($wanif, $iflist_all)) { printf("\nInvalid interface name '%s'\n", $wanif); $wanif = ''; } } while ($wanif == ''); do { echo "\nEnter the LAN interface name or 'a' for auto-detection\n" . "NOTE: this enables full Firewalling/NAT mode.\n" . "(or nothing if finished): "; if ($interactive) { $lanif = chop(fgets($fp)); } else { /* at least one interface: put LAN as first one */ $lanif = count($ifnames) > 0 ? $ifnames[0] : ''; echo $lanif . PHP_EOL; } if ($lanif == '') { break; } if ($lanif == 'a') { $lanif = autodetect_interface('LAN', $fp); if ($lanif == '') { continue; } } if (!array_key_exists($lanif, $iflist_all)) { printf("\nInvalid interface name '%s'\n", $lanif); unset($lanif); } if ($wanif != '' && $lanif == $wanif) { $lanif = ''; echo <<<EOD Error: you cannot assign the same interface name twice! EOD; } } while ($lanif == ''); $done = false; while (!$done) { /* optional interfaces */ $optif = []; $i = 0; while (1) { if (isset($optif[$i])) { $i++; } $io = $i + 1; printf("\nEnter the Optional interface %s name or 'a' for auto-detection\n" . "(or nothing if finished): ", $io); if ($interactive) { $optif[$i] = chop(fgets($fp)); } else { /* never configure OPT in automatic assign */ $optif[$i] = ''; echo $optif[$i] . PHP_EOL; } if ($optif[$i] == '') { unset($optif[$i]); $done = true; break; } if ($optif[$i] == 'a') { $optif[$i] = autodetect_interface('OPT' . $io, $fp); if ($optif[$i] == '') { unset($optif[$i]); continue; } } if (!array_key_exists($optif[$i], $iflist_all)) { printf("\nInvalid interface name '%s'\n", $optif[$i]); unset($optif[$i]); continue; } /* check for double assignments */ $ifarr = array_merge([$lanif, $wanif], $optif); $again = false; for ($k = 0; $k < (count($ifarr) - 1); $k++) { for ($j = ($k + 1); $j < count($ifarr); $j++) { if ($ifarr[$k] != '' && $ifarr[$k] == $ifarr[$j]) { $again = true; echo <<<EOD Error: you cannot assign the same interface name twice! EOD; } } } if ($again) { unset($optif[$i]); } } } if ($wanif != '' || $lanif != '' || count($optif)) { echo "\nThe interfaces will be assigned as follows:\n\n"; if ($wanif != '') { echo "WAN -> " . $wanif . "\n"; } if ($lanif != '') { echo "LAN -> " . $lanif . "\n"; } for ($i = 0; $i < count($optif); $i++) { echo "OPT" . ($i + 1) . " -> " . $optif[$i] . "\n"; } } else { echo "\nNo interfaces will be assigned!\n"; } echo <<<EOD Do you want to proceed? {$yes_no_prompt} EOD; if ($interactive) { $key = chop(fgets($fp)); } else { $key = 'y'; echo $key . PHP_EOL; } if (!in_array($key, array('y', 'Y'))) { fclose($fp); return false; } /* * XXX Ideally, at this point we'd import the default settings here, * not hardcode them. It was this way before, so fixing for now. */ if ($lanif != '') { $new = false; if (!isset($config['interfaces']['lan'])) { $new = true; } config_read_array('interfaces', 'lan'); $config['interfaces']['lan']['if'] = $lanif; $config['interfaces']['lan']['enable'] = true; if ($new) { $config['interfaces']['lan']['ipaddr'] = '192.168.1.1'; $config['interfaces']['lan']['subnet'] = '24'; if ($wanif) { $config['interfaces']['lan']['track6-interface'] = 'wan'; $config['interfaces']['lan']['track6-prefix-id'] = '0'; $config['interfaces']['lan']['ipaddrv6'] = 'track6'; $config['interfaces']['lan']['subnetv6'] = '64'; } config_read_array('dhcpd', 'lan', 'range'); $config['dhcpd']['lan']['enable'] = true; $config['dhcpd']['lan']['range']['from'] = '192.168.1.100'; $config['dhcpd']['lan']['range']['to'] = '192.168.1.199'; config_read_array('nat', 'outbound'); $config['nat']['outbound']['mode'] = 'automatic'; } if (in_array($config['interfaces']['lan']['if'], $iflist_wlan)) { config_read_array('interfaces', 'lan', 'wireless'); $config['interfaces']['lan']['if'] .= '_wlan0'; } elseif (isset($config['interfaces']['lan']['wireless'])) { unset($config['interfaces']['lan']['wireless']); } } elseif (isset($config['interfaces']['lan'])) { unset($config['interfaces']['lan']['enable']); interface_reset('lan'); if (isset($config['dhcpd']['lan'])) { unset($config['dhcpd']['lan']); } if (isset($config['dhcpdv6']['lan'])) { unset($config['dhcpdv6']['lan']); } if (isset($config['interfaces']['wan']['blockpriv'])) { unset($config['interfaces']['wan']['blockpriv']); } if (isset($config['nat'])) { unset($config['nat']); } unset($config['interfaces']['lan']); } if ($wanif != '') { config_read_array('interfaces', 'wan'); $config['interfaces']['wan']['if'] = $wanif; $config['interfaces']['wan']['enable'] = true; $config['interfaces']['wan']['ipaddr'] = 'dhcp'; $config['interfaces']['wan']['ipaddrv6'] = 'dhcp6'; $config['interfaces']['wan']['blockbogons'] = true; if ($lanif != '') { $config['interfaces']['wan']['blockpriv'] = true; } if (in_array($config['interfaces']['wan']['if'], $iflist_wlan)) { config_read_array('interfaces', 'wan', 'wireless'); $config['interfaces']['wan']['if'] .= '_wlan0'; } elseif (isset($config['interfaces']['wan']['wireless'])) { unset($config['interfaces']['wan']['wireless']); } } elseif (isset($config['interfaces']['wan'])) { unset($config['interfaces']['wan']['enable']); interface_reset('wan'); unset($config['interfaces']['wan']); } for ($i = 0; $i < count($optif); $i++) { config_read_array('interfaces', 'opt' . ($i + 1)); $config['interfaces']['opt' . ($i + 1)]['if'] = $optif[$i]; $config['interfaces']['opt' . ($i + 1)]['enable'] = true; if (in_array($config['interfaces']['opt' . ($i + 1)]['if'], $iflist_wlan)) { config_read_array('interfaces', 'opt' . ($i + 1), 'wireless'); $config['interfaces']['opt' . ($i + 1)]['if'] .= '_wlan0'; } elseif (isset($config['interfaces']['opt' . ($i + 1)]['wireless'])) { unset($config['interfaces']['opt' . ($i + 1)]['wireless']); } } /* remove all other (old) optional interfaces */ for (; isset($config['interfaces']['opt' . ($i + 1)]); $i++) { unset($config['interfaces']['opt' . ($i + 1)]['enable']); interface_reset('opt' . ($i + 1)); unset($config['interfaces']['opt' . ($i + 1)]); } echo "\nWriting configuration..."; flush(); write_config("Console assignment of interfaces"); echo "done.\n"; fclose($fp); return true; } function autodetect_interface($name, $fp) { $iflist_prev = get_interface_list(true); echo <<<EOD Connect the {$name} interface now and make sure that the link is up. Then press ENTER to continue. EOD; fgets($fp); $iflist = get_interface_list(true); if (is_array($iflist)) { foreach ($iflist as $ifn => $ifa) { if (!isset($iflist_prev[$ifn])) { printf("Detected link-up: %s\n", $ifn); return $ifn; } } } echo "No link-up detected.\n"; return ''; } function lagg_setup($iflist, $fp) { $laggcfg = &config_read_array('laggs', 'lagg'); $yes_no_prompt = '[y/N]: '; if (count($laggcfg)) { echo <<<EOD WARNING: all existing LAGGs will be cleared if you proceed! Do you want to proceed? {$yes_no_prompt} EOD; if (strcasecmp(chop(fgets($fp)), "y") != 0) { return; } } $laggcfg = []; $laggif = 0; $unused_ifs = []; foreach ($iflist as $iface => $ifa) { $unused_ifs[$iface] = $ifa; } while (1) { $lagg = []; $lagg['@attributes'] = ['uuid' => generate_uuid()]; echo "\nLAGG-capable interfaces:\n\n"; foreach ($unused_ifs as $iface => $ifa) { echo sprintf("%-8s %s %s\n", $iface, $ifa['mac'], $ifa['dmesg']); } if (empty($unused_ifs)) { echo "No LAGG-capable interfaces detected.\n"; return; } echo "\nEnter the LAGG members to aggregate (or nothing if finished): "; $members_str = chop(fgets($fp)); if ($members_str) { $members = preg_split('/[\s\t,;]+/', $members_str); $members = array_unique($members); $unused_ifnames = array_keys($unused_ifs); $valid_ifs = array_intersect($unused_ifnames, $members); if (count($members) != count($valid_ifs)) { $invalid_ifs = array_diff($members, $unused_ifnames); printf("\nInvalid interfaces: %s\n", implode(", ", $invalid_ifs)); continue; } $lagg['members'] = implode(',', $members); foreach ($members as $member) { unset($unused_ifs[$member]); } } else { break; } echo 'Enter the LAGG protocol (default:none,lacp,failover,fec,loadbalance,roundrobin): '; $lagg['proto'] = strtolower(chop(fgets($fp))); if (!in_array($lagg['proto'], ['none', 'lacp', 'failover', 'fec', 'loadbalance', 'roundrobin'])) { $lagg['proto'] = 'none'; } if ($lagg['proto'] == "lacp") { echo "Do you want to enable LACP fast timeout? {$yes_no_prompt}"; if (strcasecmp(chop(fgets($fp)), "y") == 0) { $lagg['lacp_fast_timeout'] = true; } } echo 'Enter the LAGG MTU (leave blank for auto): '; $lagg['mtu'] = chop(fgets($fp)); if (!$lagg['mtu']) { $lagg['mtu'] = null; } $lagg['laggif'] = 'lagg' . $laggif; $laggcfg[] = $lagg; $laggif++; } } function vlan_setup($iflist, $fp) { $vlancfg = &config_read_array('vlans', 'vlan'); $yes_no_prompt = '[y/N]: '; if (count($vlancfg)) { echo <<<EOD WARNING: all existing VLANs will be cleared if you proceed! Do you want to proceed? {$yes_no_prompt} EOD; if (strcasecmp(chop(fgets($fp)), "y") != 0) { return; } } $vlancfg = []; $vlanif = 0; while (1) { $vlan = []; echo "\nVLAN-capable interfaces:\n\n"; foreach ($iflist as $iface => $ifa) { echo sprintf("%-8s %s %s\n", $iface, $ifa['mac'], $ifa['dmesg']); } echo "\nEnter the parent interface name for the new VLAN (or nothing if finished): "; $vlan['if'] = chop(fgets($fp)); if ($vlan['if']) { if (!array_key_exists($vlan['if'], $iflist)) { printf("\nInvalid interface name '%s'\n", $vlan['if']); continue; } } else { break; } echo 'Enter the VLAN tag (1-4094): '; $vlan['tag'] = chop(fgets($fp)); $vlan['vlanif'] = "{$vlan['if']}_vlan{$vlan['tag']}"; $vlan['@attributes'] = ['uuid' => generate_uuid()]; if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) { printf("\nInvalid VLAN tag '%s'\n", $vlan['tag']); continue; } $vlancfg[] = $vlan; $vlanif++; } }