|
|
@@ -690,6 +690,18 @@ public partial class DeviceDetailsWindow : Window
|
|
|
error = $"自定义路由子网掩码格式不正确:{to} {maskText}";
|
|
|
return false;
|
|
|
}
|
|
|
+ if (!TryGetNetworkAddress(to, prefix, out var networkAddress))
|
|
|
+ {
|
|
|
+ routes = [];
|
|
|
+ error = $"自定义路由目标网段格式不正确:{to}";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!string.Equals(to, networkAddress, StringComparison.Ordinal))
|
|
|
+ {
|
|
|
+ routes = [];
|
|
|
+ error = $"自定义路由目标必须是网络地址:当前为 {to}/{prefix},应为 {networkAddress}/{prefix}";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
row.Mask = PrefixToMask(prefix);
|
|
|
result.Add(new RemoteInterfaceRouteConfig { To = $"{to}/{prefix}", Via = via });
|
|
|
}
|
|
|
@@ -824,6 +836,27 @@ public partial class DeviceDetailsWindow : Window
|
|
|
return ip == network || ip == broadcast;
|
|
|
}
|
|
|
|
|
|
+ private static bool TryGetNetworkAddress(string ipText, int prefix, out string networkAddress)
|
|
|
+ {
|
|
|
+ networkAddress = string.Empty;
|
|
|
+ if (prefix < 0 || prefix > 32 || !IPAddress.TryParse(ipText, out var parsed))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ var bytes = parsed.GetAddressBytes();
|
|
|
+ if (bytes.Length != 4)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ var ip = ((uint)bytes[0] << 24) | ((uint)bytes[1] << 16) | ((uint)bytes[2] << 8) | bytes[3];
|
|
|
+ var mask = prefix == 0 ? 0u : uint.MaxValue << (32 - prefix);
|
|
|
+ var network = ip & mask;
|
|
|
+ networkAddress = string.Join('.', new[] { (network >> 24) & 255, (network >> 16) & 255, (network >> 8) & 255, network & 255 });
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
private static bool TryMaskOrPrefixToPrefix(string text, out int prefix)
|
|
|
{
|
|
|
if (int.TryParse(text, out prefix) && prefix >= 0 && prefix <= 32)
|