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