%PDF- %PDF-
Direktori : /backups/router/usr/local/etc/inc/ |
Current File : //backups/router/usr/local/etc/inc/interfaces.lib.inc |
<?php /* * Copyright (c) 2015-2024 Franco Fichtner <franco@opnsense.org> * 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 legacy_interface_error($cmd, $opt = null) { $msg = 'The command `' . $cmd . '\' failed to execute'; if ($opt !== null) { $msg .= " ({$opt})"; } log_msg($msg, LOG_ERR); } function legacy_interface_listget($flag = 'all') { $cmd_wlan = 'sysctl -n net.wlan.devices'; $cmd = '/sbin/ifconfig -l'; $ifs_wlan = []; $ifs = []; exec($cmd_wlan . ' 2>&1', $out_wlan, $ret_wlan); if (!$ret_wlan && !empty($out_wlan[0])) { $ifs_wlan = explode(' ', $out_wlan[0]); } if ($flag === 'up') { $cmd .= 'u'; } elseif ($flag === 'wlan') { return ($ifs_wlan); } exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); return ($ifs); } if (isset($out[0])) { $ifs = explode(' ', $out[0]); } if (count($ifs_wlan)) { $ifs = array_merge($ifs, $ifs_wlan); } return ($ifs); } function legacy_interface_flags($ifs, $flag, $report_errors = true) { /* $flags isn't escaped because it can be an argument list */ $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' ' . $flag; exec($cmd . ' 2>&1', $out, $ret); if (!empty($ret) && $report_errors) { legacy_interface_error($cmd); } } function legacy_interface_create($ifs, $name = null) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' create'; $new = null; exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); return ($new); } if (isset($out[0])) { $new = $out[0]; } if (!empty($name)) { $cmd = '/sbin/ifconfig ' . escapeshellarg($new) . ' name ' . escapeshellarg($name); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } /* return new name here anyway to force proper device not found errors later */ $new = $name; } return ($new); } function legacy_interface_destroy($ifs) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' destroy'; exec($cmd . ' 2>&1', $out, $ret); if ($ret) { /* disable error reporting to avoid spurious errors on first configuration */ //legacy_interface_error($cmd); } } function legacy_interface_setaddress($ifs, $addr, $family = 4) { $cmd = implode(' ', ['/sbin/ifconfig', escapeshellarg($ifs), $family == 6 ? 'inet6' : 'inet', escapeshellarg($addr), 'alias']); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_interface_deladdress($ifs, $addr, $family = 4) { $cmd = implode(' ', ['/sbin/ifconfig', escapeshellarg($ifs), $family == 6 ? 'inet6' : 'inet', escapeshellarg($addr), '-alias']); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_interface_mtu($ifs, $mtu) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' mtu ' . escapeshellarg($mtu); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_bridge_member($ifs, $member) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' addm ' . escapeshellarg($member); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_vlan_tag($ifs, $member, $tag, $pcp, $proto) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' vlan ' . escapeshellarg($tag) . ' vlandev ' . escapeshellarg($member) . ' vlanpcp ' . escapeshellarg($pcp) . ' vlanproto ' . escapeshellarg($proto); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_vlan_remove_tag($ifs) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' -vlandev'; exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_vlan_pcp($ifs, $pcp) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' vlanpcp ' . escapeshellarg($pcp); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_vlan_proto($ifs, $proto) { $cmd = '/sbin/ifconfig ' . escapeshellarg($ifs) . ' vlanproto ' . escapeshellarg($proto); exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); } } function legacy_interface_stats($ifs = null) { if ($ifs != null) { // only request data for selected interface $cmd = '/usr/local/sbin/ifinfo ' . escapeshellarg($ifs); } else { // all interfaces $cmd = '/usr/local/sbin/ifinfo'; } $stats = []; exec($cmd . ' 2>&1', $out, $ret); if ($ret) { legacy_interface_error($cmd); return $stats; } $current_interface = ''; foreach ($out as $line) { if (preg_match('/^Interface ([^\s]+) \(([^\)]+)\):$/i', $line, $names)) { $stats[$names[1]] = [ 'device' => $names[1], 'driver' => $names[2], ]; $current_interface = $names[1]; } elseif ($current_interface != '') { $stat = explode(':', $line); $stats[$current_interface][trim($stat[0])] = trim($stat[1]); } } if ($ifs != null) { return $stats[$current_interface]; } else { return $stats; } } /** * detect interface capabilities using ifconfig -m * @param string|null $intf * @return array list of interface specifics indexed by physical interface name */ function legacy_interfaces_details($intf = null) { $result = []; if (!empty($intf)) { $tmp_intf = escapeshellarg($intf); } else { $tmp_intf = ''; } $cmd = '/sbin/ifconfig -m -v ' . $tmp_intf; exec($cmd . ' 2>&1', $ifconfig_data, $ret); if ($ret) { /* only error if no explicit interface was chosen */ if (empty($intf)) { legacy_interface_error($cmd, implode(' ', $ifconfig_data)); } return $result; } $vfaces = interfaces_virtual_patterns(); $current_interface = null; foreach ($ifconfig_data as $lineid => $line) { $line_parts = explode(' ', $line); if (strpos(trim($line), 'flags=') !== false && $line[0] != "\t") { $current_interface = explode(':', $line)[0]; $result[$current_interface] = []; $result[$current_interface]["flags"] = []; $result[$current_interface]["capabilities"] = []; $result[$current_interface]["options"] = []; $result[$current_interface]["macaddr"] = "00:00:00:00:00:00"; $result[$current_interface]["ipv4"] = []; $result[$current_interface]["ipv6"] = []; $result[$current_interface]["supported_media"] = []; $result[$current_interface]["is_physical"] = !count(array_intersect(preg_split('/\d+/', $current_interface), $vfaces)); $result[$current_interface]["device"] = $current_interface; if (preg_match("/ mtu ([0-9]*).*$/", $line, $matches)) { $result[$current_interface]["mtu"] = $matches[1]; } if (preg_match("/<(.*)>.*$/", $line, $matches)) { $result[$current_interface]["flags"] = explode(",", strtolower($matches[1])); } } elseif (empty($current_interface)) { // skip parsing, no interface found (yet) continue; } elseif (strpos(trim($line), 'capabilities=') !== false) { // parse capabilities $capabilities = substr($line, strpos($line, '<') + 1, -1); foreach (explode(',', $capabilities) as $capability) { $result[$current_interface]["capabilities"][] = strtolower(trim($capability)); } } elseif (strpos(trim($line), 'options=') === 0) { // parse options $options = substr($line, strpos($line, '<') + 1, -1); foreach (explode(',', $options) as $option) { $result[$current_interface]["options"][] = strtolower(trim($option)); } } elseif (strpos($line, "\tether ") !== false) { // current mac address $result[$current_interface]["macaddr"] = $line_parts[1]; // fill original as well if not found if (!isset($result[$current_interface]['macaddr_hw'])) { $result[$current_interface]['macaddr_hw'] = $line_parts[1]; } } elseif (strpos($line, "\thwaddr ") !== false) { // original mac address $result[$current_interface]['macaddr_hw'] = $line_parts[1]; } elseif (strpos($line, "\tinet ") !== false) { // IPv4 information unset($mask); unset($vhid); for ($i = 0; $i < count($line_parts); ++$i) { if ($line_parts[$i] == 'netmask') { /* look-ahead due to keyword match */ $mask = substr_count(base_convert(hexdec($line_parts[$i + 1]), 10, 2), '1'); ++$i; } elseif ($line_parts[$i] == 'vhid') { /* look-ahead due to keyword match */ $vhid = $line_parts[$i + 1]; ++$i; } } if (isset($mask)) { $tmp = ['ipaddr' => $line_parts[1], 'subnetbits' => $mask, 'tunnel' => false]; if ($line_parts[2] == '-->') { $tmp['tunnel'] = true; $tmp['endpoint'] = $line_parts[3]; } if (isset($vhid)) { $tmp['vhid'] = $vhid; } $result[$current_interface]['ipv4'][] = $tmp; } } elseif (strpos($line, "\tinet6 ") !== false) { // IPv6 information $addr = strtok($line_parts[1], '%'); $tmp = [ 'autoconf' => false, 'deprecated' => false, 'detached' => false, 'ipaddr' => $addr, 'link-local' => !!preg_match('/^fe[89ab][0-9a-f]:/i', $addr), 'tentative' => false, 'tunnel' => false, ]; for ($i = 0; $i < count($line_parts); ++$i) { if ($line_parts[$i] == 'prefixlen') { /* look-ahead due to keyword match */ $tmp['subnetbits'] = intval($line_parts[$i + 1]); ++$i; } elseif ($line_parts[$i] == 'vhid') { /* look-ahead due to keyword match */ $tmp['vhid'] = $line_parts[$i + 1]; ++$i; } elseif ($line_parts[$i] == '-->') { /* look-ahead due to keyword match */ $tmp['endpoint'] = $line_parts[$i + 1]; $tmp['tunnel'] = true; ++$i; } elseif ($line_parts[$i] == 'autoconf') { $tmp['autoconf'] = true; } elseif ($line_parts[$i] == 'deprecated') { $tmp['deprecated'] = true; } elseif ($line_parts[$i] == 'detached') { $tmp['detached'] = true; } elseif ($line_parts[$i] == 'tentative') { $tmp['tentative'] = true; } } if (isset($tmp['subnetbits'])) { $result[$current_interface]['ipv6'][] = $tmp; // sort link local to bottom, leave rest of sorting as-is (primary address on top) usort($result[$current_interface]['ipv6'], function ($a, $b) { return $a['link-local'] - $b['link-local']; }); } } elseif (strpos($line, "\ttunnel ") !== false) { // extract tunnel proto, source and destination $result[$current_interface]["tunnel"] = []; $result[$current_interface]["tunnel"]["proto"] = $line_parts[1]; $result[$current_interface]["tunnel"]["src_addr"] = $line_parts[2]; $result[$current_interface]["tunnel"]["dest_addr"] = $line_parts[4]; } elseif (preg_match("/media: (.*)/", $line, $matches)) { // media, when link is between parenthesis grep only the link part $result[$current_interface]['media'] = $matches[1]; if (preg_match("/media: .*? \((.*?)\)/", $line, $matches)) { $result[$current_interface]['media'] = $matches[1]; } $result[$current_interface]['media_raw'] = substr(trim($line), 7); } elseif (preg_match("/media (.*)/", $line, $matches)) { $result[$current_interface]["supported_media"][] = str_replace(" mediaopt ", " ", trim($matches[1])); } elseif (preg_match("/plugged: (.*)/", $line, $matches)) { $result[$current_interface]['sfp'] = [ 'plugged' => $matches[1] ]; } elseif ( isset($result[$current_interface]['sfp']) && /* safety precaution, plugged should be in the previous line */ preg_match("/vendor:\s+(.*)\s+PN:(.*)\s+SN:\s+(.*)\s+DATE:\s+(.*)/", $line, $matches) ) { $result[$current_interface]['sfp']['vendor'] = $matches[1]; $result[$current_interface]['sfp']['part_number'] = $matches[2]; $result[$current_interface]['sfp']['serial_number'] = $matches[3]; $result[$current_interface]['sfp']['manufacturing_date'] = $matches[4]; } elseif ( isset($result[$current_interface]['sfp']) && preg_match("/module temperature:\s+(.*)\s+voltage:\s+(.*)Volts/", $line, $matches) ) { $result[$current_interface]['sfp']['temperature'] = $matches[1]; $result[$current_interface]['sfp']['voltage'] = $matches[2]; } elseif ( isset($result[$current_interface]['sfp']) && preg_match("/lane\s+(.*):\s+RX power:\s+(.*)\s+TX bias:\s+(.*)/", $line, $matches) ) { $result[$current_interface]['sfp'][sprintf('lane_%s_rx_power', $matches[1])] = $matches[2]; $result[$current_interface]['sfp'][sprintf('lane_%s_tx_bias', $matches[1])] = $matches[3]; } elseif (preg_match("/status: (.*)$/", $line, $matches)) { $result[$current_interface]['status'] = $matches[1]; } elseif (preg_match("/channel (\S*)/", $line, $matches)) { $result[$current_interface]['channel'] = $matches[1]; } elseif (preg_match("/ssid (\".*?\"|\S*)/", $line, $matches)) { $result[$current_interface]['ssid'] = $matches[1]; } elseif (preg_match("/laggproto (\S+) lagghash (\S+)$/", $line, $matches)) { $result[$current_interface]['laggproto'] = $matches[1]; $result[$current_interface]['lagghash'] = $matches[2]; } elseif (preg_match("/laggproto (.*)$/", $line, $matches)) { $result[$current_interface]['laggproto'] = $matches[1]; } elseif (preg_match("/lagg options:(.*)$/", $line, $matches)) { $next_line = $ifconfig_data[$lineid + 1]; $result[$current_interface]['laggoptions'] = ['flags' => explode( ',', strtolower(substr($next_line, strpos($next_line, '<') + 1, -1)) )]; $next_line = $ifconfig_data[$lineid + 2]; $result[$current_interface]['laggoptions']['flowid_shift'] = trim(explode(":", $next_line)[1]); $next_line = $ifconfig_data[$lineid + 3]; if (strpos($next_line, "rr_limit:") !== false) { $result[$current_interface]['laggoptions']['rr_limit'] = trim(explode(":", $next_line)[1]); } } elseif (preg_match("/lagg statistics:(.*)$/", $line, $matches)) { $result[$current_interface]['laggstatistics'] = []; $next_line = $ifconfig_data[$lineid + 1]; $result[$current_interface]['laggstatistics']['active ports'] = trim(explode(":", $next_line)[1]); $next_line = $ifconfig_data[$lineid + 2]; $result[$current_interface]['laggstatistics']['flapping'] = trim(explode(":", $next_line)[1]); } elseif ( preg_match("/laggport: (.*)\Wflags=\d+<(.*)> state=\d+<(.*)>$/", $line, $matches) || preg_match("/laggport: (.*)\Wflags=\d+<(.*)>.*/", $line, $matches) ) { if (empty($result[$current_interface]['laggport'])) { $result[$current_interface]['laggport'] = []; } $result[$current_interface]['laggport'][trim($matches[1])] = [ "flags" => explode(",", strtolower($matches[2])), "state" => isset($matches[3]) ? explode(",", strtolower($matches[3])) : [], ]; } elseif (strpos($line, "\tgroups: ") !== false) { array_shift($line_parts); $result[$current_interface]['groups'] = $line_parts; } elseif (preg_match("/vlan: (.*)\Wvlanproto:\W(.*) vlanpcp:\W(.*) parent interface:\W(.*)$/", $line, $matches)) { $result[$current_interface]['vlan'] = [ "tag" => $matches[1], "proto" => $matches[2], "pcp" => $matches[3], "parent" => $matches[4], ]; } elseif (strpos($line, "\tcarp: ") !== false) { if (empty($result[$current_interface]["carp"])) { $result[$current_interface]["carp"] = []; } $result[$current_interface]["carp"][$line_parts[3]] = array( "status" => $line_parts[1], "vhid" => $line_parts[3], "advbase" => $line_parts[5], "advskew" => $line_parts[7], "peer" => null, "peer6" => null, ); if (isset($ifconfig_data[$lineid + 1]) && strpos($ifconfig_data[$lineid + 1], "peer6") !== false) { preg_match("/\Wpeer (.*)\Wpeer6 (.*)$/", $ifconfig_data[$lineid + 1], $matches); $result[$current_interface]["carp"][$line_parts[3]]['peer'] = $matches[1]; $result[$current_interface]["carp"][$line_parts[3]]['peer6'] = $matches[2]; } } elseif (strpos($line, "\tvxlan") !== false) { if (empty($result[$current_interface]["vxlan"])) { $result[$current_interface]["vxlan"] = []; } $result[$current_interface]["vxlan"]["vni"] = $line_parts[2]; $result[$current_interface]["vxlan"]["local"] = $line_parts[4]; if ($line_parts[5] == "group") { $result[$current_interface]["vxlan"]["group"] = $line_parts[6]; $result[$current_interface]['vxlan']['remote'] = null; } else { $result[$current_interface]['vxlan']['group'] = null; $result[$current_interface]["vxlan"]["remote"] = $line_parts[6]; } } } return $result; } /** * fetch interface details for one interface * @param $intf string interface name * @return array list of interface specifics */ function legacy_interface_details($intf) { $result = []; $details = legacy_interfaces_details($intf); if (isset($details[$intf])) { $result = $details[$intf]; } return $result; } /** * configure interface hardware settings * @param string $ifs interface name */ function configure_interface_hardware($ifs, $intf_details = null) { global $config; $hwsettings = $config['system']; /* XXX this needs fixing, lots of devices are not capable */ if ( strstr($ifs, 'vlan') || strpos($ifs, 'qinq') === 0 || strpos($ifs, 'lo') === 0 || strpos($ifs, 'vxlan') === 0 || strpos($ifs, 'ipsec') === 0 || strpos($ifs, '/') === 0 ) { /* skip checksumming */ return; } if ($intf_details !== null) { $intf_details = $intf_details[$ifs]; } else { $intf_details = legacy_interface_details($ifs); } /* interface overwrites */ foreach ($config['interfaces'] as $iface => $ifconf) { if (!empty($ifconf['if']) && $ifconf['if'] == $ifs) { if (!empty($ifconf['hw_settings_overwrite'])) { $hwsettings = $ifconf; } break; } } if (!empty($intf_details)) { // get current settings $csum_set = in_array('rxcsum', $intf_details['options']) || in_array('txcsum', $intf_details['options']); $csumv6_set = in_array('rxcsum_ipv6', $intf_details['options']) || in_array('txcsum_ipv6', $intf_details['options']); $tso_set = in_array('tso4', $intf_details['options']) || in_array('tso6', $intf_details['options']); $lro_set = in_array('lro', $intf_details['options']); // hardware checksum offloading offloading if (isset($hwsettings['disablechecksumoffloading']) && $csum_set) { legacy_interface_flags($ifs, '-txcsum -rxcsum', false); } elseif (!isset($hwsettings['disablechecksumoffloading']) && !$csum_set) { legacy_interface_flags($ifs, 'txcsum rxcsum', false); } if (isset($hwsettings['disablechecksumoffloading']) && $csumv6_set) { legacy_interface_flags($ifs, '-txcsum6 -rxcsum6', false); } elseif (!isset($hwsettings['disablechecksumoffloading']) && !$csumv6_set) { legacy_interface_flags($ifs, 'txcsum6 rxcsum6', false); } // TCP segmentation offloading if (isset($hwsettings['disablesegmentationoffloading']) && $tso_set) { legacy_interface_flags($ifs, '-tso', false); } elseif (!isset($hwsettings['disablesegmentationoffloading']) && !$tso_set) { legacy_interface_flags($ifs, 'tso', false); } // large receive offload if (isset($hwsettings['disablelargereceiveoffloading']) && $lro_set) { legacy_interface_flags($ifs, '-lro', false); } elseif (!isset($hwsettings['disablelargereceiveoffloading']) && !$lro_set) { legacy_interface_flags($ifs, 'lro', false); } // disable/enable hardware VLAN tags, will be skipped when "Leave default" (option 2) is selected if (!isset($hwsettings['disablevlanhwfilter']) || $hwsettings['disablevlanhwfilter'] == 1) { // probe already selected options $selected_opts = []; foreach ($intf_details['options'] as $opt) { if ($opt == 'vlan_hwtagging') { $selected_opts[] = 'vlanhwtag'; } else { $selected_opts[] = str_replace('_', '', $opt); } } // set one tag at a time to avoid driver issues foreach (array('vlanhwtag', 'vlanhwfilter', 'vlanhwtso', 'vlanhwcsum') as $tag) { if (!isset($hwsettings['disablevlanhwfilter']) && !in_array($tag, $selected_opts)) { legacy_interface_flags($ifs, $tag); } elseif (isset($hwsettings['disablevlanhwfilter']) && in_array($tag, $selected_opts)) { legacy_interface_flags($ifs, '-' . $tag); } } } } } function interfaces_virtual_patterns() { /* list of virtual device type patterns */ return [ '_stf', '_vlan', '_wlan', 'bridge', 'carp', 'enc', 'gif', 'gre', 'ipfw', /* ipfw logging device, not enabled by default */ 'ipsec', 'l2tp', 'lagg', 'lo', 'ng', 'ovpnc', 'ovpns', 'pflog', 'pfsync', 'plip', 'ppp', 'pppoe', 'pptp', 'qinq', 'tap', 'tun', 'vlan', 'vxlan', 'wg', ]; } /* * get_interface_list() - Return a list of all physical interfaces * along with MAC, IPv4 and status. * * $only_active = false -- interfaces that are available in the system * true -- interfaces that are physically connected * * $include_dmesg = false -- skip probing dmesg for more information * true -- probe dmesg for more information */ function get_interface_list($only_active = false, $include_dmesg = false) { $dmesg_arr = []; $iflist = []; if ($include_dmesg) { exec('/sbin/dmesg', $dmesg_arr); } $vfaces = interfaces_virtual_patterns(); $ifnames_wlan = legacy_interface_listget('wlan'); $ifnames_up = legacy_interface_listget('up'); $ifnames = legacy_interface_listget(); $all_interfaces = legacy_config_get_interfaces(['virtual' => false]); $all_interface_data = legacy_interfaces_details(); if ($only_active) { $_ifnames = []; $all_stats = legacy_interface_stats(); foreach ($ifnames as $ifname) { $ifinfo = $all_stats[$ifname]; if (!empty($ifinfo['link state']) && $ifinfo['link state'] == '2') { $_ifnames[] = $ifname; } } $ifnames = $_ifnames; } foreach ($ifnames as $ifname) { $tmp_ifnames = preg_split('/\d+/', $ifname); if (count(array_intersect($tmp_ifnames, $vfaces))) { continue; } if (in_array($ifname, $ifnames_wlan)) { continue; } $ifdata = !empty($all_interface_data[$ifname]) ? $all_interface_data[$ifname] : []; $toput = [ 'up' => in_array($ifname, $ifnames_up), 'ipaddr' => !empty($ifdata['ipv4'][0]['ipaddr']) ? $ifdata['ipv4'][0]['ipaddr'] : null, 'mac' => !empty($ifdata['macaddr']) ? $ifdata['macaddr'] : null, 'dmesg' => '', ]; foreach ($all_interfaces as $name => $int) { if ($int['if'] == $ifname) { $toput['friendly'] = $name; break; } } foreach ($dmesg_arr as $dmesg_line) { $dmesg = []; if (preg_match("/^{$ifname}: <(.*?)>/i", $dmesg_line, $dmesg) == 1) { $toput['dmesg'] = $dmesg[1]; break; } } $iflist[$ifname] = $toput; } return $iflist; }