From 6f6284f32e20df944a1b8cfdeaa20653345d1c64 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Mon, 30 Oct 2023 13:48:18 +0100 Subject: [PATCH] interfaces: improve wireless channel parsing; closes #5765 Channels for "list chan" and "list txpower" may be in a side by side 2 column layout which makes the current parsing fail and miss half the channels. Replace the parsing with "sturdy" regex to collect all the results and also make sure that all modes and fallback modes have the actual channel information. Also clean the templating in the static PHP file a little in related areas. --- src/www/interfaces.php | 126 +++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 67 deletions(-) diff --git a/src/www/interfaces.php b/src/www/interfaces.php index b69ffaa5f..1436f348f 100644 --- a/src/www/interfaces.php +++ b/src/www/interfaces.php @@ -264,39 +264,40 @@ function get_wireless_modes($interface) $cloned_interface = get_real_interface($interface); if ($cloned_interface) { - $chan_list = "/sbin/ifconfig {$cloned_interface} list chan"; - $stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'"; - $format_list = "/usr/bin/awk '{print \$5 \" \" \$6 \",\" \$1}'"; + $chan_list = shell_safe('/sbin/ifconfig %s list chan', $cloned_interface); + $matches = []; + + preg_match_all('/Channel\s+([^\s]+)\s+:\s+[^\s]+\s+[^\s]+\s+([^\s]+(?:\sht)?)/', $chan_list, $matches); $interface_channels = []; - exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels); - foreach ($interface_channels as $c => $interface_channel) { - $channel_line = explode(",", $interface_channel); - $wireless_mode = trim($channel_line[0]); - $wireless_channel = trim($channel_line[1]); - if (trim($wireless_mode) != "") { - /* if we only have 11g also set 11b channels */ - if ($wireless_mode == "11g") { - if (!isset($wireless_modes["11b"])) { - $wireless_modes["11b"] = array(); - } - } elseif ($wireless_mode == "11g ht") { - if (!isset($wireless_modes["11b"])) { - $wireless_modes["11b"] = array(); - } elseif (!isset($wireless_modes["11g"])) { - $wireless_modes["11g"] = array(); - } - $wireless_mode = "11ng"; - } elseif ($wireless_mode == "11a ht") { - if (!isset($wireless_modes["11a"])) { - $wireless_modes["11a"] = array(); - } - $wireless_mode = "11na"; - } - $wireless_modes[$wireless_mode][$c] = $wireless_channel; - } + foreach (array_keys($matches[0]) as $i) { + $interface_channels[$matches[1][$i]]= $matches[2][$i]; } + + ksort($interface_channels); + + foreach ($interface_channels as $wireless_channel => $wireless_mode) { + switch ($wireless_mode) { + case '11g ht': + $wireless_modes['11g'][] = (string)$wireless_channel; + $wireless_mode = '11ng'; + /* FALLTHROUGH */ + case '11g': + $wireless_modes['11b'][] = (string)$wireless_channel; + break; + case '11a ht': + $wireless_modes['11a'][] = (string)$wireless_channel; + $wireless_mode = '11na'; + break; + default: + break; + } + + $wireless_modes[$wireless_mode][] = (string)$wireless_channel; + } + + ksort($wireless_modes); } return $wireless_modes; @@ -309,19 +310,16 @@ function get_wireless_channel_info($interface) $cloned_interface = get_real_interface($interface); if ($cloned_interface) { - $chan_list = "/sbin/ifconfig {$cloned_interface} list txpower"; - $stack_list = "/usr/bin/awk -F\"Channel \" '{ gsub(/\\*/, \" \"); print \$2 \"\\\n\" \$3 }'"; - $format_list = "/usr/bin/awk '{print \$1 \",\" \$3 \" \" \$4 \",\" \$5 \",\" \$7}'"; + $chan_list = shell_safe('/sbin/ifconfig %s list txpower', $cloned_interface); + $matches = []; - $interface_channels = []; - exec("$chan_list | $stack_list | sort -u | $format_list 2>&1", $interface_channels); + preg_match_all('/Channel\s+([^\s]+)\s+:\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+[^\s]+\s+([^\s]+)/', $chan_list, $matches); - foreach ($interface_channels as $channel_line) { - $channel_line = explode(",", $channel_line); - if (!isset($wireless_channels[$channel_line[0]])) { - $wireless_channels[$channel_line[0]] = $channel_line; - } + foreach (array_keys($matches[0]) as $i) { + $wireless_channels[$matches[1][$i]] = "{$matches[2][$i]} {$matches[3][$i]}@{$matches[4][$i]}/{$matches[5][$i]}"; } + + ksort($wireless_channels); } return $wireless_channels; @@ -3190,18 +3188,15 @@ include("head.inc"); - + 802.11g OFDM @@ -3215,11 +3210,9 @@ include("head.inc"); - + - + @@ -3243,15 +3236,19 @@ include("head.inc"); $wl_channels): - foreach($wl_channels as $wl_channel):?> - - + - + - + @@ -3430,8 +3423,7 @@ include("head.inc"); - +