From 0c8e1a310cae6cef2687af0038afdadfceac9ca3 Mon Sep 17 00:00:00 2001 From: billz Date: Sat, 8 Nov 2025 09:55:03 +0100 Subject: [PATCH] Validate 802.11ax/be specific parameters --- .../Hotspot/Validators/HostapdValidator.php | 109 +++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/src/RaspAP/Networking/Hotspot/Validators/HostapdValidator.php b/src/RaspAP/Networking/Hotspot/Validators/HostapdValidator.php index 83627e11..80dbb832 100644 --- a/src/RaspAP/Networking/Hotspot/Validators/HostapdValidator.php +++ b/src/RaspAP/Networking/Hotspot/Validators/HostapdValidator.php @@ -16,6 +16,15 @@ use RaspAP\Messages\StatusMessage; class HostapdValidator { + // Valid channel widths for 802.11ax (HE) + private const HE_VALID_CHWIDTHS = [0, 1, 2]; // 20/40, 80, 160 MHz + + // Valid channel widths for 802.11be (EHT) + private const EHT_VALID_CHWIDTHS = [0, 1, 2, 3, 4]; // 20, 40, 80, 160, 320 MHz + + // 6 GHz channel range (US) + private const CHANNEL_6GHZ_MIN = 1; + private const CHANNEL_6GHZ_MAX = 233; /** * Validates full hostapd parameter set @@ -64,6 +73,16 @@ class HostapdValidator $goodInput = false; } + // validate 802.11ax specific parameters + if ($post['hw_mode'] === 'ax' && !$this->validateAxParams($post, $status)) { + $goodInput = false; + } + + // validate 802.11be specific parameters + if ($post['hw_mode'] === 'be' && !$this->validateBeParams($post, $status)) { + $goodInput = false; + } + // validate SSID if (empty($post['ssid']) || strlen($post['ssid']) > 32) { $status->addMessage('SSID must be between 1 and 32 characters', 'danger'); @@ -200,9 +219,97 @@ class HostapdValidator 'bridgeStaticIp' => ($post['bridgeStaticIp']), 'bridgeNetmask' => ($post['bridgeNetmask']), 'bridgeGateway' => ($post['bridgeGateway']), - 'bridgeDNS' => ($post['bridgeDNS']) + 'bridgeDNS' => ($post['bridgeDNS']), + 'he_oper_chwidth' => $post['he_oper_chwidth'] ?? null, // 802.11ax parameters + 'he_bss_color' => $post['he_bss_color'] ?? null, // 802.11be parameters + 'eht_oper_chwidth' => $post['eht_oper_chwidth'] ?? null ]; } + /** + * Validates 802.11ax (Wi-Fi 6) specific parameters + * + * @param array $post + * @param StatusMessage $status + * @return bool + */ + private function validateAxParams(array $post, StatusMessage $status): bool + { + $valid = true; + + // Validate HE channel width + if (isset($post['he_oper_chwidth'])) { + $chwidth = (int)$post['he_oper_chwidth']; + if (!in_array($chwidth, self::HE_VALID_CHWIDTHS, true)) { + $status->addMessage('Invalid 802.11ax channel width. Must be 0 (20/40 MHz), 1 (80 MHz), or 2 (160 MHz)', 'danger'); + $valid = false; + } + } + + // Validate BSS color (1-63) + if (isset($post['he_bss_color'])) { + $bssColor = (int)$post['he_bss_color']; + if ($bssColor < 1 || $bssColor > 63) { + $status->addMessage('802.11ax BSS color must be between 1 and 63', 'danger'); + $valid = false; + } + } + + return $valid; + } + + /** + * Validates 802.11be (Wi-Fi 7) specific parameters + * + * @param array $post + * @param StatusMessage $status + * @return bool + */ + private function validateBeParams(array $post, StatusMessage $status): bool + { + $valid = true; + $channel = (int)$post['channel']; + + // Validate EHT channel width + if (isset($post['eht_oper_chwidth'])) { + $chwidth = (int)$post['eht_oper_chwidth']; + + if (!in_array($chwidth, self::EHT_VALID_CHWIDTHS, true)) { + $status->addMessage('Invalid 802.11be channel width. Must be 0-4 (20, 40, 80, 160, or 320 MHz)', 'danger'); + $valid = false; + } + + // 320 MHz only valid on 6 GHz band + if ($chwidth === 4) { + if ($channel < self::CHANNEL_6GHZ_MIN || $channel > self::CHANNEL_6GHZ_MAX) { + $status->addMessage('802.11be 320 MHz channel width is only available on 6 GHz band (channels 1-233)', 'danger'); + $valid = false; + } + } + } + + // Validate BSS color (same as 802.11ax, inherited) + if (isset($post['he_bss_color'])) { + $bssColor = (int)$post['he_bss_color']; + if ($bssColor < 1 || $bssColor > 63) { + $status->addMessage('BSS color must be between 1 and 63', 'danger'); + $valid = false; + } + } + + return $valid; + } + + /** + * Checks if channel is in 6GHz band + * + * @param int $channel + * @return bool + */ + private function is6GHzChannel(int $channel): bool + { + return $channel >= self::CHANNEL_6GHZ_MIN && $channel <= self::CHANNEL_6GHZ_MAX; + } + }