diff --git a/Networking/Networking.csproj b/Networking/Networking.csproj
index 8739f68..732b4cf 100644
--- a/Networking/Networking.csproj
+++ b/Networking/Networking.csproj
@@ -40,8 +40,13 @@
..\packages\PTConverter.Plugin.1.0.3\lib\net472\PTConverter.Plugin.dll
+
+
+
+
+
@@ -63,15 +68,23 @@
+
+ PortScanner.xaml
+
+
+ UserControl
+
+
+ WF_PortScanner.cs
+
+
+
IPScanner.xaml
IPv4.xaml
-
- PortScanner.xaml
-
UserControl
@@ -79,7 +92,10 @@
WF_IPScanner.cs
+
+
+
@@ -105,6 +121,11 @@
+
+
+
+
+
@@ -130,6 +151,9 @@
WF_IPScanner.cs
+
+ WF_PortScanner.cs
+
\ No newline at end of file
diff --git a/Networking/Pages/PortScanner.xaml b/Networking/Pages/PortScanner.xaml
index c466d71..a1348ac 100644
--- a/Networking/Pages/PortScanner.xaml
+++ b/Networking/Pages/PortScanner.xaml
@@ -7,6 +7,8 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Background="White">
-
-
+
+
+
+
diff --git a/Networking/Pages/PortScanner.xaml.cs b/Networking/Pages/PortScanner.xaml.cs
index 5672db3..c66edc1 100644
--- a/Networking/Pages/PortScanner.xaml.cs
+++ b/Networking/Pages/PortScanner.xaml.cs
@@ -17,7 +17,7 @@ using System.Windows.Shapes;
namespace Networking.Pages
{
///
- /// Interaktionslogik für Networking.xaml
+ /// Interaktionslogik für PortScanner.xaml
///
public partial class PortScanner : UserControl, IPage
{
@@ -30,6 +30,6 @@ namespace Networking.Pages
public UserControl GetPage() => new PortScanner();
- public string GetUnderCategory() => "PortScan";
+ public string GetUnderCategory() => "PortScanner";
}
}
diff --git a/Networking/Pages/WF_PortScanner.Designer.cs b/Networking/Pages/WF_PortScanner.Designer.cs
new file mode 100644
index 0000000..d645595
--- /dev/null
+++ b/Networking/Pages/WF_PortScanner.Designer.cs
@@ -0,0 +1,281 @@
+namespace Networking.Pages
+{
+ partial class WF_PortScanner
+ {
+ ///
+ /// Erforderliche Designervariable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Verwendete Ressourcen bereinigen.
+ ///
+ /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Vom Komponenten-Designer generierter Code
+
+ ///
+ /// Erforderliche Methode für die Designerunterstützung.
+ /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
+ ///
+ private void InitializeComponent()
+ {
+ this.hostnameTextBox = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.modeGroupBox = new System.Windows.Forms.GroupBox();
+ this.udpModeRadioButton = new System.Windows.Forms.RadioButton();
+ this.tcpModeRadioButton = new System.Windows.Forms.RadioButton();
+ this.portRangeCheckBox = new System.Windows.Forms.CheckBox();
+ this.portTextBoxMax = new System.Windows.Forms.TextBox();
+ this.dashLabel = new System.Windows.Forms.Label();
+ this.portTextBoxMin = new System.Windows.Forms.TextBox();
+ this.portLabel = new System.Windows.Forms.Label();
+ this.timeoutGroupBox = new System.Windows.Forms.GroupBox();
+ this.timeoutComboBox = new System.Windows.Forms.ComboBox();
+ this.checkPortButton = new System.Windows.Forms.Button();
+ this.listview1 = new System.Windows.Forms.ListView();
+ this.chPort = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.chStatus = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.progressBar1 = new System.Windows.Forms.ProgressBar();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.modeGroupBox.SuspendLayout();
+ this.timeoutGroupBox.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // hostnameTextBox
+ //
+ this.hostnameTextBox.Location = new System.Drawing.Point(38, 24);
+ this.hostnameTextBox.Name = "hostnameTextBox";
+ this.hostnameTextBox.Size = new System.Drawing.Size(251, 20);
+ this.hostnameTextBox.TabIndex = 1;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(5, 27);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(29, 13);
+ this.label3.TabIndex = 5;
+ this.label3.Text = "Host";
+ //
+ // modeGroupBox
+ //
+ this.modeGroupBox.Controls.Add(this.udpModeRadioButton);
+ this.modeGroupBox.Controls.Add(this.tcpModeRadioButton);
+ this.modeGroupBox.Location = new System.Drawing.Point(296, 19);
+ this.modeGroupBox.Name = "modeGroupBox";
+ this.modeGroupBox.Size = new System.Drawing.Size(111, 57);
+ this.modeGroupBox.TabIndex = 13;
+ this.modeGroupBox.TabStop = false;
+ this.modeGroupBox.Text = "Mode";
+ //
+ // udpModeRadioButton
+ //
+ this.udpModeRadioButton.AutoSize = true;
+ this.udpModeRadioButton.Location = new System.Drawing.Point(13, 35);
+ this.udpModeRadioButton.Name = "udpModeRadioButton";
+ this.udpModeRadioButton.Size = new System.Drawing.Size(48, 17);
+ this.udpModeRadioButton.TabIndex = 11;
+ this.udpModeRadioButton.Text = "UDP";
+ this.udpModeRadioButton.UseVisualStyleBackColor = true;
+ //
+ // tcpModeRadioButton
+ //
+ this.tcpModeRadioButton.AutoSize = true;
+ this.tcpModeRadioButton.Checked = true;
+ this.tcpModeRadioButton.Location = new System.Drawing.Point(13, 16);
+ this.tcpModeRadioButton.Name = "tcpModeRadioButton";
+ this.tcpModeRadioButton.Size = new System.Drawing.Size(46, 17);
+ this.tcpModeRadioButton.TabIndex = 10;
+ this.tcpModeRadioButton.TabStop = true;
+ this.tcpModeRadioButton.Text = "TCP";
+ this.tcpModeRadioButton.UseVisualStyleBackColor = true;
+ //
+ // portRangeCheckBox
+ //
+ this.portRangeCheckBox.AutoSize = true;
+ this.portRangeCheckBox.Location = new System.Drawing.Point(156, 57);
+ this.portRangeCheckBox.Name = "portRangeCheckBox";
+ this.portRangeCheckBox.Size = new System.Drawing.Size(80, 17);
+ this.portRangeCheckBox.TabIndex = 19;
+ this.portRangeCheckBox.Text = "Port Range";
+ this.portRangeCheckBox.UseVisualStyleBackColor = true;
+ this.portRangeCheckBox.CheckedChanged += new System.EventHandler(this.portRangeCheckBox_CheckedChanged);
+ //
+ // portTextBoxMax
+ //
+ this.portTextBoxMax.Enabled = false;
+ this.portTextBoxMax.Location = new System.Drawing.Point(98, 55);
+ this.portTextBoxMax.MaxLength = 5;
+ this.portTextBoxMax.Name = "portTextBoxMax";
+ this.portTextBoxMax.Size = new System.Drawing.Size(38, 20);
+ this.portTextBoxMax.TabIndex = 18;
+ //
+ // dashLabel
+ //
+ this.dashLabel.AutoSize = true;
+ this.dashLabel.Location = new System.Drawing.Point(82, 58);
+ this.dashLabel.Name = "dashLabel";
+ this.dashLabel.Size = new System.Drawing.Size(10, 13);
+ this.dashLabel.TabIndex = 17;
+ this.dashLabel.Text = "-";
+ //
+ // portTextBoxMin
+ //
+ this.portTextBoxMin.Location = new System.Drawing.Point(38, 55);
+ this.portTextBoxMin.MaxLength = 5;
+ this.portTextBoxMin.Name = "portTextBoxMin";
+ this.portTextBoxMin.Size = new System.Drawing.Size(38, 20);
+ this.portTextBoxMin.TabIndex = 16;
+ //
+ // portLabel
+ //
+ this.portLabel.AutoSize = true;
+ this.portLabel.Location = new System.Drawing.Point(3, 58);
+ this.portLabel.Name = "portLabel";
+ this.portLabel.Size = new System.Drawing.Size(31, 13);
+ this.portLabel.TabIndex = 15;
+ this.portLabel.Text = "Ports";
+ //
+ // timeoutGroupBox
+ //
+ this.timeoutGroupBox.Controls.Add(this.timeoutComboBox);
+ this.timeoutGroupBox.Location = new System.Drawing.Point(413, 24);
+ this.timeoutGroupBox.Name = "timeoutGroupBox";
+ this.timeoutGroupBox.Size = new System.Drawing.Size(110, 52);
+ this.timeoutGroupBox.TabIndex = 20;
+ this.timeoutGroupBox.TabStop = false;
+ this.timeoutGroupBox.Text = "Timeout";
+ //
+ // timeoutComboBox
+ //
+ this.timeoutComboBox.AccessibleRole = System.Windows.Forms.AccessibleRole.None;
+ this.timeoutComboBox.FormattingEnabled = true;
+ this.timeoutComboBox.Items.AddRange(new object[] {
+ "500 ms",
+ "1000 ms",
+ "1500 ms",
+ "2000 ms"});
+ this.timeoutComboBox.Location = new System.Drawing.Point(6, 21);
+ this.timeoutComboBox.Name = "timeoutComboBox";
+ this.timeoutComboBox.Size = new System.Drawing.Size(98, 21);
+ this.timeoutComboBox.TabIndex = 0;
+ //
+ // checkPortButton
+ //
+ this.checkPortButton.Location = new System.Drawing.Point(529, 21);
+ this.checkPortButton.Name = "checkPortButton";
+ this.checkPortButton.Size = new System.Drawing.Size(105, 31);
+ this.checkPortButton.TabIndex = 5;
+ this.checkPortButton.Text = "Scan";
+ this.checkPortButton.UseVisualStyleBackColor = true;
+ this.checkPortButton.Click += new System.EventHandler(this.checkPortButton_Click);
+ //
+ // listview1
+ //
+ this.listview1.Activation = System.Windows.Forms.ItemActivation.OneClick;
+ this.listview1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.listview1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.chPort,
+ this.chStatus});
+ this.listview1.FullRowSelect = true;
+ this.listview1.GridLines = true;
+ this.listview1.HideSelection = false;
+ this.listview1.HoverSelection = true;
+ this.listview1.Location = new System.Drawing.Point(0, 89);
+ this.listview1.MultiSelect = false;
+ this.listview1.Name = "listview1";
+ this.listview1.RightToLeft = System.Windows.Forms.RightToLeft.No;
+ this.listview1.Size = new System.Drawing.Size(800, 361);
+ this.listview1.TabIndex = 21;
+ this.listview1.UseCompatibleStateImageBehavior = false;
+ this.listview1.View = System.Windows.Forms.View.Details;
+ //
+ // chPort
+ //
+ this.chPort.Text = "Port";
+ this.chPort.Width = 191;
+ //
+ // chStatus
+ //
+ this.chStatus.Text = "Status";
+ this.chStatus.Width = 296;
+ //
+ // progressBar1
+ //
+ this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.progressBar1.Location = new System.Drawing.Point(0, 79);
+ this.progressBar1.Name = "progressBar1";
+ this.progressBar1.Size = new System.Drawing.Size(800, 10);
+ this.progressBar1.TabIndex = 22;
+ //
+ // cancelButton
+ //
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point(529, 52);
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size(105, 23);
+ this.cancelButton.TabIndex = 23;
+ this.cancelButton.Text = "Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+ //
+ // WF_PortScanner
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.cancelButton);
+ this.Controls.Add(this.progressBar1);
+ this.Controls.Add(this.listview1);
+ this.Controls.Add(this.checkPortButton);
+ this.Controls.Add(this.timeoutGroupBox);
+ this.Controls.Add(this.portRangeCheckBox);
+ this.Controls.Add(this.portTextBoxMax);
+ this.Controls.Add(this.dashLabel);
+ this.Controls.Add(this.portTextBoxMin);
+ this.Controls.Add(this.portLabel);
+ this.Controls.Add(this.modeGroupBox);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.hostnameTextBox);
+ this.Name = "WF_PortScanner";
+ this.Size = new System.Drawing.Size(800, 450);
+ this.modeGroupBox.ResumeLayout(false);
+ this.modeGroupBox.PerformLayout();
+ this.timeoutGroupBox.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+ private System.Windows.Forms.TextBox hostnameTextBox;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.GroupBox modeGroupBox;
+ private System.Windows.Forms.RadioButton udpModeRadioButton;
+ private System.Windows.Forms.RadioButton tcpModeRadioButton;
+ private System.Windows.Forms.CheckBox portRangeCheckBox;
+ private System.Windows.Forms.TextBox portTextBoxMax;
+ private System.Windows.Forms.Label dashLabel;
+ private System.Windows.Forms.TextBox portTextBoxMin;
+ private System.Windows.Forms.Label portLabel;
+ private System.Windows.Forms.GroupBox timeoutGroupBox;
+ private System.Windows.Forms.ComboBox timeoutComboBox;
+ private System.Windows.Forms.Button checkPortButton;
+ private System.Windows.Forms.ListView listview1;
+ private System.Windows.Forms.ColumnHeader chPort;
+ private System.Windows.Forms.ColumnHeader chStatus;
+ private System.Windows.Forms.ProgressBar progressBar1;
+ private System.Windows.Forms.Button cancelButton;
+ }
+}
diff --git a/Networking/Pages/WF_PortScanner.cs b/Networking/Pages/WF_PortScanner.cs
new file mode 100644
index 0000000..4cc8bf8
--- /dev/null
+++ b/Networking/Pages/WF_PortScanner.cs
@@ -0,0 +1,271 @@
+using PortScanner;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Networking.Pages
+{
+ public partial class WF_PortScanner : UserControl
+ {
+ // Delegate to report back with one open port
+ public delegate void ExecuteOnceCallback(int openPort);
+
+ // Delegate to report back with one open port (Async)
+ public delegate void ExecuteOnceAsyncCallback(int port, bool isOpen, bool isCancelled, bool isLast);
+
+ // The manager instance
+ IScannerManagerSingleton smc;
+
+ // Cancellation token source for the cancel button
+ private CancellationTokenSource cts;
+
+ // Current mode of operation
+ private ScannerManagerSingleton.ScanMode currentScanMode;
+
+ public WF_PortScanner()
+ {
+ InitializeComponent();
+ this.Load += WF_PortScanner_Load;
+ }
+
+ private void WF_PortScanner_Load(object sender, EventArgs e)
+ {
+ // Get the ScannerManagerSingleton instance
+ smc = ScannerManagerSingleton.Instance;
+
+ // Populate the timeout times list box
+ PopulateTimeoutListBox();
+ }
+
+ private void PopulateTimeoutListBox()
+ {
+ // Assign the list to the ComboBox's DataSource property
+ timeoutComboBox.DataSource = TimeoutListItem.CreateTimeoutListItems();
+ timeoutComboBox.DisplayMember = "DisplayMember";
+ timeoutComboBox.ValueMember = "ValueMember";
+
+ // Set default value
+ timeoutComboBox.SelectedValue = 2000;
+ }
+
+ // This method is used as a callback for portscanning - writes to the log box (text box)
+ public void PortResult(int port, bool isOpen, bool isCancelled, bool isLast)
+ {
+ string status;
+
+ // The operation has been cancelled by MainWindow
+ if (isCancelled)
+ {
+ status = "Operation cancelled." + Environment.NewLine;
+ }
+
+ // The port is open
+ else if (isOpen)
+ {
+ //status = String.Format("{0}, {1} port {2} is open.{3}", hostnameTextBox.Text, currentScanMode.ToString(), port, Environment.NewLine);
+ var item = new ListViewItem(new[] { port.ToString(), "Open" });
+ listview1.Items.Add(item);
+ }
+
+ // The port is closed
+ else
+ {
+ status = String.Format("{0}, {1} port {2} is closed.{3}", hostnameTextBox.Text, currentScanMode.ToString(), port, Environment.NewLine);
+
+ }
+
+
+ if (isLast || isCancelled)
+ ToggleInputs(true);
+ }
+
+ // Checks whether the timeout combo box has user input or not
+ private bool IsTimeoutComboBoxUserInput()
+ {
+ var inputText = timeoutComboBox.Text;
+
+ foreach (var displayMemberText in (List)timeoutComboBox.DataSource)
+ {
+ if (displayMemberText.DisplayMember == inputText)
+ {
+ // Select the one that's in the box's list to prevent some problems
+ // This will return because the user input IS in the combo box's DataSource
+ // However it is still user input and does not have a ValueMember. Exception
+ // will be thrown.
+ timeoutComboBox.SelectedItem = displayMemberText;
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Executed when the Check Port button is clicked
+ private void checkPortButton_Click(object sender, EventArgs e)
+ {
+ listview1.Items.Clear();
+
+ // Get user inputs
+ string hostname = hostnameTextBox.Text;
+ if (hostname == "")
+ {
+ MessageBox.Show("Please enter a valid hostname.",
+ "Input Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ hostnameTextBox.Focus();
+ return;
+ }
+
+ // Check port
+ int portMin = InputChecker.ParsePort(portTextBoxMin.Text);
+ if (portMin == -1)
+ {
+ MessageBox.Show((portRangeCheckBox.Checked ? "Lower limit of port range" : "Port") + " invalid.",
+ "Input Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ portTextBoxMin.Focus();
+ return;
+ }
+
+ // Get scan mode
+ ScannerManagerSingleton.ScanMode scanMode = ReadScanMode();
+
+ // If custom timeout time, verify correct user input
+ int timeout;
+ if (IsTimeoutComboBoxUserInput())
+ {
+ // If valid, proceed with that input as timeout
+ timeout = InputChecker.ParseTimeout(timeoutComboBox.Text);
+ if (timeout == -1)
+ {
+ MessageBox.Show("Timeout format: [time], [time]ms or [time] ms.\nTimeout must be between 250 ms and 20000 ms.",
+ "Timeout Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ return;
+ }
+ }
+ else
+ {
+ // Else, use the ValueMember of the selected Member
+ timeout = (int)timeoutComboBox.SelectedValue;
+ }
+
+ // Instantiate CTS
+ cts = new CancellationTokenSource();
+
+ // Simple one port check
+ if (!portRangeCheckBox.Checked)
+ {
+ // The callback for scan result
+ var callback = new ExecuteOnceAsyncCallback(PortResult);
+
+ // Send one check request and toggle user inputs
+ ToggleInputs(false);
+ smc.ExecuteOnceAsync(hostname, portMin, timeout, scanMode, callback, cts.Token);
+ }
+
+ // Port range check
+ else
+ {
+ // Verify input
+ int portMax = InputChecker.ParsePort(portTextBoxMax.Text);
+ if (portMax == -1)
+ {
+ MessageBox.Show("Upper limit of port range invalid.",
+ "Input Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ portTextBoxMax.Focus();
+ return;
+ }
+
+ if (portMax < portMin)
+ {
+ MessageBox.Show("Port range invalid.",
+ "Input Error",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
+ portTextBoxMax.Focus();
+ return;
+ }
+
+ // The callback for scan result
+ var callback = new ExecuteOnceAsyncCallback(PortResult);
+
+ // Set status box text
+ //var connectionText = String.Format("Connecting to {0}, port {1}...{2}", hostname, portMin,
+ // Environment.NewLine);
+ //statusTextBox.AppendText(connectionText);
+ //Logger.Info(connectionText);
+ // Toggle inputs and begin operation
+ ToggleInputs(false);
+ smc.ExecuteRangeAsync(hostname, portMin, portMax, timeout, scanMode,progressBar1, callback, cts.Token);
+ }
+ }
+ // Read scan mode radio button selection
+ private ScannerManagerSingleton.ScanMode ReadScanMode()
+ {
+ if (tcpModeRadioButton.Checked)
+ {
+ currentScanMode = ScannerManagerSingleton.ScanMode.TCP;
+ }
+ else
+ {
+ currentScanMode = ScannerManagerSingleton.ScanMode.UDP;
+ }
+ return currentScanMode;
+ }
+
+ private void portRangeCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ // This enables or disables the max. port input box
+ if (portRangeCheckBox.Checked)
+ {
+ portTextBoxMax.Enabled = true;
+ }
+ else
+ {
+ portTextBoxMax.Enabled = false;
+ }
+ }
+
+ // Toggle all inputs
+ private void ToggleInputs(bool setting)
+ {
+ hostnameTextBox.Enabled = setting;
+ portTextBoxMin.Enabled = setting;
+ checkPortButton.Enabled = setting;
+ portTextBoxMax.Enabled = setting;
+ portRangeCheckBox.Enabled = setting;
+
+ // Re-disable the portMax text box
+ if (!portRangeCheckBox.Checked)
+ {
+ portTextBoxMax.Enabled = false;
+ }
+
+ // Set focus to hostnameTextBox
+ if (setting)
+ hostnameTextBox.Focus();
+ }
+ private void cancelButton_Click(object sender, EventArgs e)
+ {
+ // If cts is instantiated (i.e. the scanning operation is in progress, request cancellation
+ if (cts != null)
+ {
+ cts.Cancel();
+ progressBar1.Value = 0;
+ }
+ }
+ }
+}
diff --git a/Networking/Pages/WF_PortScanner.resx b/Networking/Pages/WF_PortScanner.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Networking/Pages/WF_PortScanner.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Networking/PluginInfo.cs b/Networking/PluginInfo.cs
index e70ed7f..2e00660 100644
--- a/Networking/PluginInfo.cs
+++ b/Networking/PluginInfo.cs
@@ -25,7 +25,7 @@ namespace Networking
public IEnumerable RegisterPages => new List()
{
{new IPv4() },
- {new PortScanner() },
+ {new Pages.PortScanner() },
{new Pages.IPScanner() }
};
}
diff --git a/Networking/PortScanner/IScannerManagerSingleton.cs b/Networking/PortScanner/IScannerManagerSingleton.cs
new file mode 100644
index 0000000..e6a1032
--- /dev/null
+++ b/Networking/PortScanner/IScannerManagerSingleton.cs
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/Networking/PortScanner/InputChecker.cs b/Networking/PortScanner/InputChecker.cs
new file mode 100644
index 0000000..1a276ee
--- /dev/null
+++ b/Networking/PortScanner/InputChecker.cs
@@ -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;
+ }
+ }
+}
diff --git a/Networking/PortScanner/PortScannerBase.cs b/Networking/PortScanner/PortScannerBase.cs
new file mode 100644
index 0000000..16fbc64
--- /dev/null
+++ b/Networking/PortScanner/PortScannerBase.cs
@@ -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 CheckOpenAsync(CancellationToken ct);
+ }
+}
\ No newline at end of file
diff --git a/Networking/PortScanner/ScannerManagerSingleton.cs b/Networking/PortScanner/ScannerManagerSingleton.cs
new file mode 100644
index 0000000..7d8428f
--- /dev/null
+++ b/Networking/PortScanner/ScannerManagerSingleton.cs
@@ -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);
+ }
+ }
+ }
+}
+
diff --git a/Networking/PortScanner/Settings.cs b/Networking/PortScanner/Settings.cs
new file mode 100644
index 0000000..2fac4b8
--- /dev/null
+++ b/Networking/PortScanner/Settings.cs
@@ -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.
+ }
+ }
+}
diff --git a/Networking/PortScanner/TCPPortScanner.cs b/Networking/PortScanner/TCPPortScanner.cs
new file mode 100644
index 0000000..a7c9658
--- /dev/null
+++ b/Networking/PortScanner/TCPPortScanner.cs
@@ -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 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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Networking/PortScanner/TimeoutListItem.cs b/Networking/PortScanner/TimeoutListItem.cs
new file mode 100644
index 0000000..1468d17
--- /dev/null
+++ b/Networking/PortScanner/TimeoutListItem.cs
@@ -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 CreateTimeoutListItems()
+ {
+ var returnList = new List();
+
+ for (int i = 0; i < _times.Length; i++)
+ {
+ returnList.Add(new TimeoutListItem
+ {
+ DisplayMember = String.Format("{0} ms", _times[i]),
+ ValueMember = _times[i]
+ });
+ }
+
+ return returnList;
+ }
+ }
+}
diff --git a/Networking/PortScanner/UDPPortScanner.cs b/Networking/PortScanner/UDPPortScanner.cs
new file mode 100644
index 0000000..9ab8378
--- /dev/null
+++ b/Networking/PortScanner/UDPPortScanner.cs
@@ -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 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;
+ }
+ }
+ }
+}
diff --git a/Networking/Util/HelperMethods.cs b/Networking/Util/HelperMethods.cs
new file mode 100644
index 0000000..a096dc3
--- /dev/null
+++ b/Networking/Util/HelperMethods.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PortScanner.Util
+{
+ public static class HelperMethods
+ {
+ public static void PauseForXSeconds(int secondsPaused)
+ {
+ secondsPaused = (int)TimeSpanUtil.ConvertMillisecondsToSeconds(secondsPaused);
+ System.Threading.Thread.Sleep(secondsPaused);
+ }
+
+ public static void PauseForXMinutes(int minutesPaused)
+ {
+ minutesPaused = (int)TimeSpanUtil.ConvertMinutesToMilliseconds(minutesPaused);
+ System.Threading.Thread.Sleep(minutesPaused);
+ }
+ }
+}
diff --git a/Networking/Util/TimeSpanUtil.cs b/Networking/Util/TimeSpanUtil.cs
new file mode 100644
index 0000000..930874d
--- /dev/null
+++ b/Networking/Util/TimeSpanUtil.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PortScanner.Util
+{
+ public static class TimeSpanUtil
+ {
+ #region To days
+
+ public static double ConvertMillisecondsToDays(double milliseconds)
+ {
+ return TimeSpan.FromMilliseconds(milliseconds).TotalDays;
+ }
+
+ public static double ConvertSecondsToDays(double seconds)
+ {
+ return TimeSpan.FromSeconds(seconds).TotalDays;
+ }
+
+ public static double ConvertMinutesToDays(double minutes)
+ {
+ return TimeSpan.FromMinutes(minutes).TotalDays;
+ }
+
+ public static double ConvertHoursToDays(double hours)
+ {
+ return TimeSpan.FromHours(hours).TotalDays;
+ }
+
+ #endregion To days
+
+ #region To hours
+
+ public static double ConvertMillisecondsToHours(double milliseconds)
+ {
+ return TimeSpan.FromMilliseconds(milliseconds).TotalHours;
+ }
+
+ public static double ConvertSecondsToHours(double seconds)
+ {
+ return TimeSpan.FromSeconds(seconds).TotalHours;
+ }
+
+ public static double ConvertMinutesToHours(double minutes)
+ {
+ return TimeSpan.FromMinutes(minutes).TotalHours;
+ }
+
+ public static double ConvertDaysToHours(double days)
+ {
+ return TimeSpan.FromHours(days).TotalHours;
+ }
+
+ #endregion To hours
+
+ #region To minutes
+
+ public static double ConvertMillisecondsToMinutes(double milliseconds)
+ {
+ return TimeSpan.FromMilliseconds(milliseconds).TotalMinutes;
+ }
+
+ public static double ConvertSecondsToMinutes(double seconds)
+ {
+ return TimeSpan.FromSeconds(seconds).TotalMinutes;
+ }
+
+ public static double ConvertHoursToMinutes(double hours)
+ {
+ return TimeSpan.FromHours(hours).TotalMinutes;
+ }
+
+ public static double ConvertDaysToMinutes(double days)
+ {
+ return TimeSpan.FromDays(days).TotalMinutes;
+ }
+
+ #endregion To minutes
+
+ #region To seconds
+
+ public static double ConvertMillisecondsToSeconds(double milliseconds)
+ {
+ return TimeSpan.FromMilliseconds(milliseconds).TotalSeconds;
+ }
+
+ public static double ConvertMinutesToSeconds(double minutes)
+ {
+ return TimeSpan.FromMinutes(minutes).TotalSeconds;
+ }
+
+ public static double ConvertHoursToSeconds(double hours)
+ {
+ return TimeSpan.FromHours(hours).TotalSeconds;
+ }
+
+ public static double ConvertDaysToSeconds(double days)
+ {
+ return TimeSpan.FromDays(days).TotalSeconds;
+ }
+
+ #endregion To seconds
+
+ #region To milliseconds
+
+ public static double ConvertSecondsToMilliseconds(double seconds)
+ {
+ return TimeSpan.FromSeconds(seconds).TotalMilliseconds;
+ }
+
+ public static double ConvertMinutesToMilliseconds(double minutes)
+ {
+ return TimeSpan.FromMinutes(minutes).TotalMilliseconds;
+ }
+
+ public static double ConvertHoursToMilliseconds(double hours)
+ {
+ return TimeSpan.FromHours(hours).TotalMilliseconds;
+ }
+
+ public static double ConvertDaysToMilliseconds(double days)
+ {
+ return TimeSpan.FromDays(days).TotalMilliseconds;
+ }
+
+ #endregion To milliseconds
+ }
+}
diff --git a/WpfApp1/MainWindow.xaml b/WpfApp1/MainWindow.xaml
index 46cd2c2..38796c7 100644
--- a/WpfApp1/MainWindow.xaml
+++ b/WpfApp1/MainWindow.xaml
@@ -9,7 +9,7 @@
Title="MainWindow" Height="450" Width="800">
-
+