Warning: this should only be used for testing purposes, as it will leak threads.
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
class Program
{
static void ProxyStream(string stream1name, NetworkStream stream1, string stream2name, NetworkStream stream2)
{
var buffer = new byte[65536];
try
{
while (true)
{
var len = stream1.Read(buffer, 0, 65536);
stream2.Write(buffer, 0, len);
}
}
catch (Exception)
{
Console.WriteLine("Stream from " + stream1name + " to " + stream2name + " closed");
}
}
static void Main(string[] args)
{
if (args.Length != 3)
{
Console.WriteLine("Usage: program.exe localport remoteServerHost remoteServerPort");
Console.WriteLine("Example: program.exe 13389 10.1.2.3 3389");
return;
}
var localPort = int.Parse(args[0]);
var remoteServerHost = args[1];
var remoteServerPort = int.Parse(args[2]);
var l = new TcpListener(IPAddress.Any, localPort);
l.Start();
while (true)
{
var client1 = l.AcceptTcpClient();
var remoteAddress = (client1.Client.RemoteEndPoint as IPEndPoint).Address.ToString();
Console.WriteLine("Accepted session from " + remoteAddress);
var client2 = new TcpClient(remoteServerHost, remoteServerPort);
Console.WriteLine("Created connection to " + remoteServerHost + ":" + remoteServerPort);
new Thread(() => { ProxyStream(remoteAddress, client1.GetStream(), remoteServerHost, client2.GetStream()); }).Start();
new Thread(() => { ProxyStream(remoteServerHost, client2.GetStream(), remoteAddress, client1.GetStream()); }).Start();
}
}
}
Or, if you need this from PowerShell, I would suggest wrapping it (as threads in PowerShell are painful):
$source = '
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
class Program
{
static void ProxyStream(string stream1name, NetworkStream stream1, string stream2name, NetworkStream stream2)
{
var buffer = new byte[65536];
try
{
while (true)
{
var len = stream1.Read(buffer, 0, 65536);
stream2.Write(buffer, 0, len);
}
}
catch (Exception)
{
Console.WriteLine("Stream from " + stream1name + " to " + stream2name + " closed");
}
}
static void Main(string[] args)
{
if (args.Length != 3)
{
Console.WriteLine("Usage: program.exe localport remoteServerHost remoteServerPort");
Console.WriteLine("Example: program.exe 13389 10.1.2.3 3389");
return;
}
var localPort = int.Parse(args[0]);
var remoteServerHost = args[1];
var remoteServerPort = int.Parse(args[2]);
var l = new TcpListener(IPAddress.Any, localPort);
l.Start();
while (true)
{
var client1 = l.AcceptTcpClient();
var remoteAddress = (client1.Client.RemoteEndPoint as IPEndPoint).Address.ToString();
Console.WriteLine("Accepted session from " + remoteAddress);
var client2 = new TcpClient(remoteServerHost, remoteServerPort);
Console.WriteLine("Created connection to " + remoteServerHost + ":" + remoteServerPort);
new Thread(() => { ProxyStream(remoteAddress, client1.GetStream(), remoteServerHost, client2.GetStream()); }).Start();
new Thread(() => { ProxyStream(remoteServerHost, client2.GetStream(), remoteAddress, client1.GetStream()); }).Start();
}
}
}
'
Add-Type `
-TypeDefinition $source `
-Language CSharp `
-OutputAssembly 'c:\windows\temp\tcpproxy.exe' `
-OutputType 'ConsoleApplication'