feat: 实现端口代理工具的核心功能
This commit is contained in:
150
PortProxyTool/PortProxy.cs
Normal file
150
PortProxyTool/PortProxy.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace PortProxyTool;
|
||||
|
||||
public static class PortProxy
|
||||
{
|
||||
public static PortProxyItem[] GetPortProxies()
|
||||
{
|
||||
var output = ExecuteCommand("show all");
|
||||
var lines = output.ToList();
|
||||
var items = new List<PortProxyItem>();
|
||||
|
||||
if (output.Length <= 0) return items.ToArray();
|
||||
PortProxyType? currentType = null;
|
||||
for (var i = 0; i < lines.Count; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
var type = CheckPosition(line);
|
||||
if (type != null)
|
||||
{
|
||||
currentType = type.Value;
|
||||
if (i + 1 >= lines.Count) continue;
|
||||
lines.RemoveAt(i + 1);
|
||||
lines.RemoveAt(i + 1);
|
||||
}
|
||||
else if (currentType != null)
|
||||
{
|
||||
var values = line.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
||||
if (values.Length < 2) continue;
|
||||
var listenAddress = values[0];
|
||||
if (!ushort.TryParse(values[1], out var listenPort))
|
||||
{
|
||||
Remove(type, listenAddress, values[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
string? targetAddress = null;
|
||||
ushort? targetPort = null;
|
||||
if (values.Length >= 4)
|
||||
{
|
||||
targetAddress = values[2];
|
||||
if (!ushort.TryParse(values[3], out var targetPortParse))
|
||||
targetPort = null;
|
||||
else
|
||||
targetPort = targetPortParse;
|
||||
}
|
||||
|
||||
items.Add(new PortProxyItem
|
||||
{
|
||||
Type = currentType.Value,
|
||||
ListenAddress = listenAddress,
|
||||
ListenPort = listenPort,
|
||||
TargetAddress = targetAddress,
|
||||
TargetPort = targetPort
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return items.ToArray();
|
||||
}
|
||||
|
||||
public static string Remove(PortProxyType? type, string listenAddress, string listenPort, string protocol = "tcp")
|
||||
{
|
||||
var output =
|
||||
ExecuteCommand(
|
||||
$"delete {type?.ToString().ToLower()} listenaddress=\"{listenAddress}\" listenport=\"{listenPort}\" protocol=\"{protocol}\"");
|
||||
return output.Length > 0 ? output[0] : string.Empty;
|
||||
}
|
||||
|
||||
public static string Remove(PortProxyItem item)
|
||||
{
|
||||
return Remove(item.Type, item.ListenAddress, item.ListenPort.ToString());
|
||||
}
|
||||
|
||||
public static string Add(PortProxyType type, string listenAddress, ushort listenPort, string connectAddress, ushort connectPort, string protocol = "tcp")
|
||||
{
|
||||
var output =
|
||||
ExecuteCommand(
|
||||
$"delete {type.ToString().ToLower()} listenaddress=\"{listenAddress}\" listenport=\"{listenPort}\" connectAddress=\"{connectAddress}\" connectPort=\"{connectPort}\" protocol=\"{protocol}\"");
|
||||
return output.Length > 0 ? output[0] : string.Empty;
|
||||
}
|
||||
|
||||
public static string Add(PortProxyItem item)
|
||||
{
|
||||
return Add(item.Type, item.ListenAddress, item.ListenPort, item.TargetAddress!, item.TargetPort ?? 0);
|
||||
}
|
||||
|
||||
public static string Set(PortProxyType type, string listenAddress, ushort listenPort, string connectAddress, ushort connectPort, string protocol = "tcp")
|
||||
{
|
||||
var output =
|
||||
ExecuteCommand(
|
||||
$"set {type.ToString().ToLower()} listenaddress=\"{listenAddress}\" listenport=\"{listenPort}\" connectAddress=\"{connectAddress}\" connectPort=\"{connectPort}\" protocol=\"{protocol}\"");
|
||||
return output.Length > 0 ? output[0] : string.Empty;
|
||||
}
|
||||
|
||||
public static string Set(PortProxyItem item)
|
||||
{
|
||||
return Set(item.Type, item.ListenAddress, item.ListenPort, item.TargetAddress!, item.TargetPort ?? 0);
|
||||
}
|
||||
|
||||
private static string[] ExecuteCommand(string command)
|
||||
{
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "netsh",
|
||||
Arguments = $"interface portproxy {command}",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
StandardOutputEncoding = Encoding.UTF8
|
||||
};
|
||||
|
||||
using var process = new Process();
|
||||
process.StartInfo = startInfo;
|
||||
process.Start();
|
||||
var output = process.StandardOutput.ReadToEnd();
|
||||
var error = process.StandardError.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
|
||||
var lines = new List<string>();
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
lines.AddRange(error.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries));
|
||||
lines.AddRange(output.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
return lines.ToArray();
|
||||
}
|
||||
|
||||
private static PortProxyType? CheckPosition(string input)
|
||||
{
|
||||
var ipv4Index = input.IndexOf("ipv4", StringComparison.Ordinal);
|
||||
var ipv6Index = input.IndexOf("ipv6", StringComparison.Ordinal);
|
||||
|
||||
if (ipv4Index != -1 && ipv6Index != -1)
|
||||
{
|
||||
if (ipv4Index < ipv6Index) return PortProxyType.V4ToV6;
|
||||
|
||||
if (ipv4Index > ipv6Index) return PortProxyType.V6ToV4;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ipv4Index != -1) return PortProxyType.V4ToV4;
|
||||
|
||||
if (ipv6Index != -1) return PortProxyType.V6ToV6;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
10
PortProxyTool/PortProxyItem.cs
Normal file
10
PortProxyTool/PortProxyItem.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace PortProxyTool;
|
||||
|
||||
public class PortProxyItem
|
||||
{
|
||||
public required PortProxyType Type { get; set; }
|
||||
public required string ListenAddress { get; set; }
|
||||
public required ushort ListenPort { get; set; }
|
||||
public required string? TargetAddress { get; set; }
|
||||
public required ushort? TargetPort { get; set; }
|
||||
}
|
9
PortProxyTool/PortProxyType.cs
Normal file
9
PortProxyTool/PortProxyType.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace PortProxyTool;
|
||||
|
||||
public enum PortProxyType
|
||||
{
|
||||
V4ToV4,
|
||||
V4ToV6,
|
||||
V6ToV6,
|
||||
V6ToV4
|
||||
}
|
Reference in New Issue
Block a user