From af62c482e2ce75f6fed04633de3171bf8fe23d6f Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Sat, 14 Sep 2024 13:37:17 +0200 Subject: [PATCH] interfaces: add 'spoofmac' device option and enforce it PR: https://forum.opnsense.org/index.php?topic=42798.0 --- src/etc/inc/interfaces.inc | 29 +++++++++++++++++++++++++---- src/www/interfaces.php | 19 +++++++++++++------ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index fb2468a31..6266ef90f 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -2331,12 +2331,13 @@ function interface_configure($verbose = false, $interface = 'wan', $reload = fal $realif = get_real_interface($interface); $realifv6 = get_real_interface($interface, 'inet6'); + $devices = plugins_devices(); /* get the correct hardware interface if PPP is involved or return the one we have */ $realhwif = interface_ppps_hardware($realif)[0]; /* XXX support all MLPPP devices */ if ($reload) { - foreach (plugins_devices() as $device) { + foreach ($devices as $device) { if (empty($device['function']) || empty($device['names'])) { continue; } @@ -2374,15 +2375,35 @@ function interface_configure($verbose = false, $interface = 'wan', $reload = fal interface_wireless_configure($realif, $wancfg); } + /* get expected and current MAC address from the configuration and system */ + $mac_prev = $ifconfig_details[$realhwif]['macaddr'] ?? ''; + $mac_next = !empty($wancfg['spoofmac']) ? $wancfg['spoofmac'] : ($ifconfig_details[$realhwif]['macaddr_hw'] ?? ''); + + /* + * Disable MAC spoofing if the device type does not support it, + * its use is prohibited or when it is otherwise reserved. + */ + foreach ($devices as $device) { + if (preg_match('/' . $device['pattern'] . '/', $realhwif)) { + if (isset($device['spoofmac']) && $device['spoofmac'] == false) { + $mac_next = ''; + } + break; + } + } + + /* in case of LAGG the empty MAC may be used which we need to ignore */ + if ($mac_next == '00:00:00:00:00:00') { + $mac_next = ''; + } + /* * Do not try to reapply the spoofed MAC if it's already applied. * When ifconfig link is used, it cycles the interface down/up, * which triggers the interface config again, which attempts to * spoof the MAC again which cycles the link again. */ - $mac_prev = $ifconfig_details[$realhwif]['macaddr'] ?? ''; - $mac_next = !empty($wancfg['spoofmac']) ? $wancfg['spoofmac'] : ($ifconfig_details[$realhwif]['macaddr_hw'] ?? ''); - if (!empty($mac_prev) && !empty($mac_next) && $mac_next !== '00:00:00:00:00:00' && strcasecmp($mac_prev, $mac_next)) { + if (!empty($mac_prev) && !empty($mac_next) && strcasecmp($mac_prev, $mac_next)) { /* * When the hardware interface matches the IPv6 interface where we set * the MAC address we can assist in providing the accompanying link-local diff --git a/src/www/interfaces.php b/src/www/interfaces.php index 9c960f2f5..856625158 100644 --- a/src/www/interfaces.php +++ b/src/www/interfaces.php @@ -649,15 +649,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $input_errors[] = gettext("The DHCPv6 Server is active on this interface and it can be used only with a static IPv6 configuration. Please disable the DHCPv6 Server service on this interface first, then change the interface configuration."); } - if ($pconfig['type'] != 'none' || $pconfig['type6'] != 'none') { - foreach (plugins_devices() as $device) { - if (!isset($device['configurable']) || $device['configurable'] == true) { - continue; - } - if (preg_match('/' . $device['pattern'] . '/', $pconfig['if'])) { + foreach (plugins_devices() as $device) { + if (!preg_match('/' . $device['pattern'] . '/', $pconfig['if'])) { + continue; + } + + if (isset($device['configurable']) && $device['configurable'] == false) { + if ($pconfig['type'] != 'none' || $pconfig['type6'] != 'none') { $input_errors[] = gettext('Cannot assign an IP configuration type to a tunnel interface.'); } } + + if (isset($device['spoofmac']) && $device['spoofmac'] == false) { + if (!empty($pconfig['spoofmac'])) { + $input_errors[] = gettext('Cannot assign a MAC address to this type of interface.'); + } + } } switch ($pconfig['type']) {