From 58b2b84f0ae483af17b0cdf9e0ec3a2667fde9ab Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 12 Oct 2019 22:51:50 +0100 Subject: [PATCH] Move remote connection to Devices. --- .../.idea/contentModel.xml | 1 + .../DiscImageChef.Devices.csproj | 1 + DiscImageChef.Devices/Remote/Remote.cs | 124 ++++++++++++++++++ DiscImageChef/Commands/Remote.cs | 110 ++-------------- 4 files changed, 137 insertions(+), 99 deletions(-) create mode 100644 DiscImageChef.Devices/Remote/Remote.cs diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index d25e188b4..993c428c2 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -595,6 +595,7 @@ + diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index f07d25abf..daa5bbef1 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -55,6 +55,7 @@ + diff --git a/DiscImageChef.Devices/Remote/Remote.cs b/DiscImageChef.Devices/Remote/Remote.cs new file mode 100644 index 000000000..26446c974 --- /dev/null +++ b/DiscImageChef.Devices/Remote/Remote.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using DiscImageChef.CommonTypes.Interop; +using DiscImageChef.Console; +using DiscImageChef.Helpers; +using Version = DiscImageChef.CommonTypes.Interop.Version; + +namespace DiscImageChef.Devices.Remote +{ + public class Remote + { + private readonly Socket _socket; + + public Remote(string host) + { + var ipHostEntry = Dns.GetHostEntry(host); + var ipAddress = ipHostEntry.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork); + + if (ipAddress is null) + { + DicConsole.ErrorWriteLine("Host not found"); + throw new SocketException(11001); + } + + var ipEndPoint = new IPEndPoint(ipAddress, 6666); + _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + _socket.Connect(ipEndPoint); + + DicConsole.WriteLine("Connected to {0}", host); + + var hdrBuf = new byte[Marshal.SizeOf()]; + + var len = _socket.Receive(hdrBuf, hdrBuf.Length, SocketFlags.Peek); + + if (len < hdrBuf.Length) + { + DicConsole.ErrorWriteLine("Could not read from the network..."); + throw new IOException(); + } + + var hdr = Marshal.ByteArrayToStructureLittleEndian(hdrBuf); + + if (hdr.id != Consts.PacketId) + { + DicConsole.ErrorWriteLine("Received data is not a DIC Remote Packet..."); + throw new ArgumentException(); + } + + if (hdr.packetType != DicPacketType.Hello) + { + DicConsole.ErrorWriteLine("Expected Hello Packet, got packet type {0}...", hdr.packetType); + throw new ArgumentException(); + } + + if (hdr.version != Consts.PacketVersion) + { + DicConsole.ErrorWriteLine("Unrecognized packet version..."); + throw new ArgumentException(); + } + + var buf = new byte[hdr.len]; + len = _socket.Receive(buf, buf.Length, SocketFlags.None); + + if (len < buf.Length) + { + DicConsole.ErrorWriteLine("Could not read from the network..."); + throw new IOException(); + } + + var serverHello = Marshal.ByteArrayToStructureLittleEndian(buf); + + ServerApplication = serverHello.application; + ServerVersion = serverHello.version; + ServerOperatingSystem = serverHello.sysname; + ServerOperatingSystemVersion = serverHello.release; + ServerArchitecture = serverHello.machine; + ServerProtocolVersion = serverHello.maxProtocol; + + var clientHello = new DicPacketHello + { + application = "DiscImageChef", + version = Version.GetVersion(), + maxProtocol = Consts.MaxProtocol, + sysname = DetectOS.GetPlatformName( + DetectOS.GetRealPlatformID(), DetectOS.GetVersion()), + release = DetectOS.GetVersion(), + machine = "", // TODO: Get architecture + hdr = new DicPacketHeader + { + id = Consts.PacketId, + len = (uint) Marshal.SizeOf(), + version = Consts.PacketVersion, + packetType = DicPacketType.Hello + } + }; + + buf = Marshal.StructureToByteArrayLittleEndian(clientHello); + + len = _socket.Send(buf, SocketFlags.None); + + if (len >= buf.Length) return; + + DicConsole.ErrorWriteLine("Could not write to the network..."); + throw new IOException(); + } + + public string ServerApplication { get; } + public string ServerVersion { get; } + public string ServerOperatingSystem { get; } + public string ServerOperatingSystemVersion { get; } + public string ServerArchitecture { get; } + public int ServerProtocolVersion { get; } + + public void Disconnect() + { + _socket.Shutdown(SocketShutdown.Both); + _socket.Close(); + } + } +} \ No newline at end of file diff --git a/DiscImageChef/Commands/Remote.cs b/DiscImageChef/Commands/Remote.cs index 2a21ec6a8..d99c80e77 100644 --- a/DiscImageChef/Commands/Remote.cs +++ b/DiscImageChef/Commands/Remote.cs @@ -34,15 +34,9 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Sockets; using DiscImageChef.CommonTypes.Enums; -using DiscImageChef.CommonTypes.Interop; -using DiscImageChef.CommonTypes.Structs; using DiscImageChef.Console; using DiscImageChef.Devices.Remote; -using DiscImageChef.Helpers; using Mono.Options; namespace DiscImageChef.Commands @@ -99,105 +93,23 @@ namespace DiscImageChef.Commands DicConsole.DebugWriteLine("Remote command", "--host={0}", host); DicConsole.DebugWriteLine("Remote command", "--verbose={0}", MainClass.Verbose); - var ipHostEntry = Dns.GetHostEntry(host); - var ipAddress = ipHostEntry.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork); - - if (ipAddress is null) - { - DicConsole.ErrorWriteLine("Host not found"); - return (int) Errno.ENODEV; - } - - var ipEndPoint = new IPEndPoint(ipAddress, 6666); - var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - try { - socket.Connect(ipEndPoint); - - DicConsole.WriteLine("Connected to {0}", host); - - var hdrBuf = new byte[Marshal.SizeOf()]; - - var len = socket.Receive(hdrBuf, hdrBuf.Length, SocketFlags.Peek); - - if (len < hdrBuf.Length) - { - DicConsole.ErrorWriteLine("Could not read from the network, exiting..."); - return (int) Errno.EIO; - } - - var hdr = Marshal.ByteArrayToStructureLittleEndian(hdrBuf); - - if (hdr.id != Consts.PacketId) - { - DicConsole.ErrorWriteLine("Received data is not a DIC Remote Packet, exiting..."); - return (int) Errno.EINVAL; - } - - if (hdr.packetType != DicPacketType.Hello) - { - DicConsole.ErrorWriteLine("Expected Hello Packet, got packet type {0}, exiting...", hdr.packetType); - return (int) Errno.EINVAL; - } - - if (hdr.version != Consts.PacketVersion) - { - DicConsole.ErrorWriteLine("Unrecognized packet version, exiting..."); - return (int) Errno.EINVAL; - } - - var buf = new byte[hdr.len]; - len = socket.Receive(buf, buf.Length, SocketFlags.None); - - if (len < buf.Length) - { - DicConsole.ErrorWriteLine("Could not read from the network, exiting..."); - return (int) Errno.EIO; - } - - var serverHello = Marshal.ByteArrayToStructureLittleEndian(buf); - - DicConsole.WriteLine("Server application: {0} {1}", serverHello.application, serverHello.version); - DicConsole.WriteLine("Server operating system: {0} {1} ({2})", serverHello.sysname, serverHello.release, - serverHello.machine); - DicConsole.WriteLine("Server maximum protocol: {0}", serverHello.maxProtocol); - - var clientHello = new DicPacketHello - { - application = MainClass.AssemblyTitle, - version = MainClass.AssemblyVersion?.InformationalVersion, - maxProtocol = Consts.MaxProtocol, - sysname = DetectOS.GetPlatformName( - DetectOS.GetRealPlatformID(), DetectOS.GetVersion()), - release = DetectOS.GetVersion(), - machine = "", // TODO: Get architecture - hdr = new DicPacketHeader - { - id = Consts.PacketId, - len = (uint) Marshal.SizeOf(), - version = Consts.PacketVersion, - packetType = DicPacketType.Hello - } - }; - - buf = Marshal.StructureToByteArrayLittleEndian(clientHello); - - len = socket.Send(buf, SocketFlags.None); - if (len < buf.Length) - { - DicConsole.ErrorWriteLine("Could not write to the network, exiting..."); - return (int) Errno.EIO; - } - - socket.Shutdown(SocketShutdown.Both); - socket.Close(); + var remote = new Remote(host); + DicConsole.WriteLine("Server application: {0} {1}", remote.ServerApplication, remote.ServerVersion); + DicConsole.WriteLine("Server operating system: {0} {1} ({2})", remote.ServerOperatingSystem, + remote.ServerOperatingSystemVersion, + remote.ServerArchitecture); + DicConsole.WriteLine("Server maximum protocol: {0}", remote.ServerProtocolVersion); + remote.Disconnect(); } - catch (Exception e) + catch (Exception) { - DicConsole.Write(e.Message); + DicConsole.ErrorWriteLine("Error connecting to host."); + return (int) ErrorNumber.CannotOpenDevice; } + return (int) ErrorNumber.NoError; } }