-> PortScanner added
This commit is contained in:
12
Networking/PortScanner/IScannerManagerSingleton.cs
Normal file
12
Networking/PortScanner/IScannerManagerSingleton.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Networking.Pages;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PortScanner
|
||||
{
|
||||
internal interface IScannerManagerSingleton
|
||||
{
|
||||
void ExecuteOnceAsync(string hostname, int port, int timeout, ScannerManagerSingleton.ScanMode scanMode, WF_PortScanner.ExecuteOnceAsyncCallback callback, CancellationToken ct);
|
||||
void ExecuteRangeAsync(string hostname, int portMin, int portMax, int timeout, ScannerManagerSingleton.ScanMode scanMode, ProgressBar progress, WF_PortScanner.ExecuteOnceAsyncCallback callback, CancellationToken ct);
|
||||
}
|
||||
}
|
||||
67
Networking/PortScanner/InputChecker.cs
Normal file
67
Networking/PortScanner/InputChecker.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PortScanner
|
||||
{
|
||||
static class InputChecker
|
||||
{
|
||||
// Check that a hostname string is valid
|
||||
public static bool IsValidHostname(string hostname)
|
||||
{
|
||||
return hostname != "";
|
||||
}
|
||||
|
||||
// Check that a port is valid - returns -1 if port is invalid
|
||||
public static int ParsePort(string portString)
|
||||
{
|
||||
int port;
|
||||
|
||||
try
|
||||
{
|
||||
port = Int32.Parse(portString);
|
||||
}
|
||||
// If any exception occurs, the string was not a proper port
|
||||
catch (Exception)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (port < 1 || port > 65535)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
// Check that timeout combobox user input is valid...
|
||||
// Accepted formats: [time] ms, [time]ms, [time]
|
||||
public static int ParseTimeout(string timeoutString)
|
||||
{
|
||||
// The regex that is used for matching the input against
|
||||
var regex = new Regex(@"^\d*\s*(ms)?$");
|
||||
|
||||
// Try matching the user input
|
||||
if (!regex.IsMatch(timeoutString))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Slice off the "ms" part of the string
|
||||
timeoutString = Regex.Match(timeoutString, @"\d+").Value;
|
||||
int timeout = Int32.Parse(timeoutString);
|
||||
|
||||
// Doesn't work too well with a very short timeout period
|
||||
if (timeout < 250 || timeout > 20000)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Networking/PortScanner/PortScannerBase.cs
Normal file
28
Networking/PortScanner/PortScannerBase.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// This is the base class for all Port Scanners
|
||||
namespace PortScanner
|
||||
{
|
||||
abstract class PortScannerBase
|
||||
{
|
||||
// Hostname and port properties for scanning
|
||||
public string Hostname { get; set; }
|
||||
public int Port { get; set; }
|
||||
|
||||
// Timeout property that specifies how long to wait for an answer
|
||||
public int Timeout { get; set; }
|
||||
|
||||
// Base construcor - just set up default values for properties
|
||||
public PortScannerBase()
|
||||
{
|
||||
Hostname = "127.0.0.1";
|
||||
Port = 22;
|
||||
Timeout = 1000;
|
||||
}
|
||||
|
||||
// Check that the hostname is listening on the port - asynchronously
|
||||
public abstract Task<bool> CheckOpenAsync(CancellationToken ct);
|
||||
}
|
||||
}
|
||||
111
Networking/PortScanner/ScannerManagerSingleton.cs
Normal file
111
Networking/PortScanner/ScannerManagerSingleton.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using Networking.Pages;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PortScanner
|
||||
{
|
||||
public class ScannerManagerSingleton : IScannerManagerSingleton
|
||||
{
|
||||
// The instance variable - this is a singleton class
|
||||
private static ScannerManagerSingleton _instance;
|
||||
|
||||
// The PortScanner used to scan ports
|
||||
private PortScannerBase portScanner;
|
||||
|
||||
// Enumeration for scanning modes
|
||||
public enum ScanMode
|
||||
{
|
||||
TCP = 1,
|
||||
UDP = 2
|
||||
}
|
||||
|
||||
// Private constructor - this is a singleton class
|
||||
private ScannerManagerSingleton()
|
||||
{
|
||||
}
|
||||
|
||||
// Instance property - this is a singleton class
|
||||
public static ScannerManagerSingleton Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
_instance = new ScannerManagerSingleton();
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate the correct type of PortScanner
|
||||
private void InstantiatePortScanner(ScanMode scanMode)
|
||||
{
|
||||
switch (scanMode)
|
||||
{
|
||||
case ScanMode.TCP:
|
||||
portScanner = new TCPPortScanner();
|
||||
break;
|
||||
|
||||
case ScanMode.UDP:
|
||||
portScanner = new UDPPortScanner();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Scan one port asynchronously
|
||||
public async void ExecuteOnceAsync(string hostname, int port, int timeout, ScanMode scanMode, WF_PortScanner.ExecuteOnceAsyncCallback callback, CancellationToken ct)
|
||||
{
|
||||
// Instantiate a PortScanner
|
||||
InstantiatePortScanner(scanMode);
|
||||
|
||||
// Assign values
|
||||
portScanner.Hostname = hostname;
|
||||
portScanner.Port = port;
|
||||
portScanner.Timeout = timeout;
|
||||
|
||||
// Await for the result of this operation
|
||||
var task = portScanner.CheckOpenAsync(ct);
|
||||
await task;
|
||||
|
||||
// If a cancellation request has been triggered through CancellationToken ct, we must advise the callback function
|
||||
bool cancelled = ct.IsCancellationRequested;
|
||||
|
||||
// Callback with the result and the port
|
||||
callback(port, task.Result, cancelled, true);
|
||||
}
|
||||
|
||||
// Scan a range of ports asynchronously
|
||||
public async void ExecuteRangeAsync(string hostname, int portMin, int portMax, int timeout, ScanMode scanMode, ProgressBar progress, WF_PortScanner.ExecuteOnceAsyncCallback callback, CancellationToken ct)
|
||||
{
|
||||
// Instantiate a PortScanner
|
||||
InstantiatePortScanner(scanMode);
|
||||
|
||||
// Assign first values
|
||||
portScanner.Hostname = hostname;
|
||||
portScanner.Timeout = timeout;
|
||||
|
||||
bool isLast = false;
|
||||
bool cancelled = false;
|
||||
|
||||
for (int i = portMin; i <= portMax && !cancelled; i++)
|
||||
{
|
||||
if (i == portMax)
|
||||
{
|
||||
isLast = true;
|
||||
}
|
||||
|
||||
portScanner.Port = i;
|
||||
int percent = 100 * i / portMax;
|
||||
progress.Value = percent;
|
||||
|
||||
var task = portScanner.CheckOpenAsync(ct);
|
||||
await task;
|
||||
|
||||
cancelled = ct.IsCancellationRequested;
|
||||
|
||||
callback(i, task.Result, cancelled, isLast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
Networking/PortScanner/Settings.cs
Normal file
28
Networking/PortScanner/Settings.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace PortScanner.Properties {
|
||||
|
||||
|
||||
// This class allows you to handle specific events on the settings class:
|
||||
// The SettingChanging event is raised before a setting's value is changed.
|
||||
// The PropertyChanged event is raised after a setting's value is changed.
|
||||
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||
// The SettingsSaving event is raised before the setting values are saved.
|
||||
internal sealed partial class Settings {
|
||||
|
||||
public Settings() {
|
||||
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||
//
|
||||
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||
//
|
||||
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||
//
|
||||
}
|
||||
|
||||
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||
// Add code to handle the SettingChangingEvent event here.
|
||||
}
|
||||
|
||||
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
// Add code to handle the SettingsSaving event here.
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Networking/PortScanner/TCPPortScanner.cs
Normal file
56
Networking/PortScanner/TCPPortScanner.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PortScanner
|
||||
{
|
||||
class TCPPortScanner : PortScannerBase
|
||||
{
|
||||
// The TCP client for port scanning
|
||||
private TcpClient tcpClient;
|
||||
|
||||
// Constructor - uses base class constructor
|
||||
public TCPPortScanner() : base()
|
||||
{
|
||||
}
|
||||
|
||||
// Implementing the base's abstract method CheckOpenAsync(), cancellation token ct passed from MainWindow, triggered in the cancel button click event
|
||||
public override async Task<bool> CheckOpenAsync(CancellationToken ct)
|
||||
{
|
||||
using (tcpClient = new TcpClient())
|
||||
{
|
||||
// connection is the Task returned by ConnectAsync
|
||||
var connection = tcpClient.ConnectAsync(Hostname, Port);
|
||||
|
||||
bool returnValue;
|
||||
|
||||
// In case the ct is triggered, this will act as if delay expired right when the click occurrs
|
||||
if (await Task.WhenAny(connection, Task.Delay(Timeout, ct)) == connection)
|
||||
{
|
||||
// If connection was refused, return false
|
||||
// The exception within the task is a SocketException if the connection failed
|
||||
if (connection.Exception != null)
|
||||
{
|
||||
returnValue = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Timeout occurred, this means that there is no connection and port is closed
|
||||
returnValue = false;
|
||||
}
|
||||
|
||||
tcpClient.Close();
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Networking/PortScanner/TimeoutListItem.cs
Normal file
44
Networking/PortScanner/TimeoutListItem.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// This class represents one item in the list of items that will be
|
||||
// displayed in the timeout time combo box in the MainWindow
|
||||
|
||||
namespace PortScanner
|
||||
{
|
||||
class TimeoutListItem
|
||||
{
|
||||
// DisplayMember: the string that will be displayed in the timeout combo box
|
||||
// ValueMember: the actual ms value attached to that string
|
||||
public string DisplayMember { get; set; }
|
||||
public int ValueMember { get; set; }
|
||||
|
||||
// The array of different values present in the combo box
|
||||
// Add new values right here ......
|
||||
private static int[] _times =
|
||||
{
|
||||
500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000
|
||||
};
|
||||
|
||||
// Returns a list of objects of this class intended to be used
|
||||
// as a datasource for a combo box
|
||||
public static List<TimeoutListItem> CreateTimeoutListItems()
|
||||
{
|
||||
var returnList = new List<TimeoutListItem>();
|
||||
|
||||
for (int i = 0; i < _times.Length; i++)
|
||||
{
|
||||
returnList.Add(new TimeoutListItem
|
||||
{
|
||||
DisplayMember = String.Format("{0} ms", _times[i]),
|
||||
ValueMember = _times[i]
|
||||
});
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Networking/PortScanner/UDPPortScanner.cs
Normal file
94
Networking/PortScanner/UDPPortScanner.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Networking.Pages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PortScanner
|
||||
{
|
||||
class UDPPortScanner : PortScannerBase
|
||||
{
|
||||
// The UDP client used for scanning a port
|
||||
private UdpClient udpClient;
|
||||
|
||||
// Constructor - use base constructor
|
||||
public UDPPortScanner() : base()
|
||||
{
|
||||
}
|
||||
|
||||
// TODO:
|
||||
public async override Task<bool> CheckOpenAsync(CancellationToken ct)
|
||||
{
|
||||
// We are using a UDP client to see whether the port is open or not
|
||||
// Therefore, the absence of a response means that the port is open
|
||||
// If there is any respone, it is closed
|
||||
using (udpClient = new UdpClient())
|
||||
{
|
||||
bool returnVal;
|
||||
try
|
||||
{
|
||||
// Connect to the server
|
||||
udpClient.Connect(Hostname, Port);
|
||||
|
||||
// Set the timeout
|
||||
udpClient.Client.ReceiveTimeout = Timeout;
|
||||
|
||||
// Sends a message over UDP
|
||||
Byte[] sendBytes = Encoding.ASCII.GetBytes("Are you open?");
|
||||
udpClient.Send(sendBytes, sendBytes.Length);
|
||||
|
||||
// IPEndPoint object will allow us to read datagrams sent from any source.
|
||||
// Port 0 means any available port
|
||||
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
|
||||
// Asynchronously begin receiving
|
||||
var result = udpClient.ReceiveAsync();
|
||||
if (await Task.WhenAny(result, Task.Delay(Timeout, ct)) == result)
|
||||
{
|
||||
Console.WriteLine(Encoding.ASCII.GetString(result.Result.Buffer));
|
||||
returnVal = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// There was no response, we will consider this port as open
|
||||
returnVal = true;
|
||||
}
|
||||
udpClient.Close();
|
||||
return returnVal;
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
Console.WriteLine("Error Code: " + e.ErrorCode);
|
||||
|
||||
switch (e.ErrorCode)
|
||||
{
|
||||
case 10054:
|
||||
returnVal = false;
|
||||
break;
|
||||
|
||||
case 11001:
|
||||
returnVal = false;
|
||||
|
||||
// Display an error message on the main thread
|
||||
MessageBox.Show(
|
||||
"Hostname could not be resolved.",
|
||||
"Connection Error",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
break;
|
||||
default:
|
||||
returnVal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
udpClient.Close();
|
||||
return returnVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user