diff --git a/DearFTP/Connection/Commands/PassiveCommand.cs b/DearFTP/Connection/Commands/PassiveCommand.cs
index e353952..c57e57a 100644
--- a/DearFTP/Connection/Commands/PassiveCommand.cs
+++ b/DearFTP/Connection/Commands/PassiveCommand.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Net;
namespace DearFTP.Connection.Commands
{
@@ -16,11 +17,43 @@ namespace DearFTP.Connection.Commands
int port = session.DataConnection.Port;
var portBytes = BitConverter.GetBytes((ushort)port).Reverse().Select(x => x.ToString());
- string remote = string.Join(',', session.Configuration.Server.Host.Split('.').Concat(portBytes));
+
+ string remote;
+
+ if (IsInternal(session.RemoteIP))
+ {
+ remote = string.Join(',', session.LocalIP.ToString().Split('.').Concat(portBytes));
+ }
+ else
+ {
+ remote = string.Join(',', session.Configuration.Server.Host.Split('.').Concat(portBytes));
+ }
stream.Send(ResponseCode.PassiveMode, $"Entering Passive Mode ({remote})");
session.DataConnection.AcceptClient();
}
+
+ // Source: https://stackoverflow.com/a/39120248
+ ///
+ /// An extension method to determine if an IP address is internal, as specified in RFC1918
+ ///
+ /// The IP address that will be tested
+ /// Returns true if the IP is internal, false if it is external
+ public bool IsInternal(IPAddress toTest)
+ {
+ byte[] bytes = toTest.GetAddressBytes();
+ switch (bytes[0])
+ {
+ case 10:
+ return true;
+ case 172:
+ return bytes[1] < 32 && bytes[1] >= 16;
+ case 192:
+ return bytes[1] == 168;
+ default:
+ return false;
+ }
+ }
}
}
diff --git a/DearFTP/Connection/Session.cs b/DearFTP/Connection/Session.cs
index 8183045..8ec20d6 100644
--- a/DearFTP/Connection/Session.cs
+++ b/DearFTP/Connection/Session.cs
@@ -23,10 +23,11 @@ namespace DearFTP.Connection
public bool IsTlsProtected { get; private set; }
public string CurrentWorkingDirectory => NavigablePath.CurrentDirectory;
- public string IP => ((IPEndPoint)_client.Client.LocalEndPoint).Address.ToString();
+ public IPAddress LocalIP => ((IPEndPoint)_client.Client.LocalEndPoint).Address;
+ public IPAddress RemoteIP => ((IPEndPoint)_client.Client.RemoteEndPoint).Address;
- private TcpClient _client;
- private NetworkStream _networkStream;
+ private readonly TcpClient _client;
+ private readonly NetworkStream _networkStream;
private SslStream _sslStream;
private bool _isRunning = true;