-> PortScanner added

This commit is contained in:
Kevin Krüger
2022-01-18 09:14:22 +01:00
parent f7b63cb8e1
commit a07655faed
18 changed files with 1301 additions and 9 deletions

View File

@@ -40,8 +40,13 @@
<HintPath>..\packages\PTConverter.Plugin.1.0.3\lib\net472\PTConverter.Plugin.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
@@ -63,15 +68,23 @@
<Compile Include="IPScannerLib\IPTool.cs" />
<Compile Include="IPScannerLib\NetworkScanner.cs" />
<Compile Include="IPScannerLib\ScanStatus.cs" />
<Compile Include="Pages\PortScanner.xaml.cs">
<DependentUpon>PortScanner.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\WF_PortScanner.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Pages\WF_PortScanner.Designer.cs">
<DependentUpon>WF_PortScanner.cs</DependentUpon>
</Compile>
<Compile Include="PortScanner\InputChecker.cs" />
<Compile Include="PortScanner\IScannerManagerSingleton.cs" />
<Compile Include="Pages\IPScanner.xaml.cs">
<DependentUpon>IPScanner.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\IPv4.xaml.cs">
<DependentUpon>IPv4.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\PortScanner.xaml.cs">
<DependentUpon>PortScanner.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\WF_IPScanner.cs">
<SubType>UserControl</SubType>
</Compile>
@@ -79,7 +92,10 @@
<DependentUpon>WF_IPScanner.cs</DependentUpon>
</Compile>
<Compile Include="PluginInfo.cs" />
<Compile Include="PortScanner\PortScannerBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PortScanner\ScannerManagerSingleton.cs" />
<Compile Include="PortScanner\Settings.cs" />
<Compile Include="SmartThreadPool\CallerThreadContext.cs" />
<Compile Include="SmartThreadPool\CanceledWorkItemsGroup.cs" />
<Compile Include="SmartThreadPool\EventWaitHandle.cs" />
@@ -105,6 +121,11 @@
<Compile Include="SmartThreadPool\WorkItemsGroup.cs" />
<Compile Include="SmartThreadPool\WorkItemsGroupBase.cs" />
<Compile Include="SmartThreadPool\WorkItemsQueue.cs" />
<Compile Include="PortScanner\TCPPortScanner.cs" />
<Compile Include="PortScanner\TimeoutListItem.cs" />
<Compile Include="PortScanner\UDPPortScanner.cs" />
<Compile Include="Util\HelperMethods.cs" />
<Compile Include="Util\TimeSpanUtil.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="Pages\IPScanner.xaml">
@@ -130,6 +151,9 @@
<EmbeddedResource Include="Pages\WF_IPScanner.resx">
<DependentUpon>WF_IPScanner.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Pages\WF_PortScanner.resx">
<DependentUpon>WF_PortScanner.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -7,6 +7,8 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Background="White">
<Grid>
</Grid>
<WindowsFormsHost>
<local:WF_PortScanner/>
</WindowsFormsHost>
</Grid>
</UserControl>

View File

@@ -17,7 +17,7 @@ using System.Windows.Shapes;
namespace Networking.Pages
{
/// <summary>
/// Interaktionslogik für Networking.xaml
/// Interaktionslogik für PortScanner.xaml
/// </summary>
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";
}
}

View File

@@ -0,0 +1,281 @@
namespace Networking.Pages
{
partial class WF_PortScanner
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
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;
}
}

View File

@@ -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<TimeoutListItem>)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;
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -25,7 +25,7 @@ namespace Networking
public IEnumerable<IPage> RegisterPages => new List<IPage>()
{
{new IPv4() },
{new PortScanner() },
{new Pages.PortScanner() },
{new Pages.IPScanner() }
};
}

View 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);
}
}

View 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;
}
}
}

View 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);
}
}

View 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);
}
}
}
}

View 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.
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}

View 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;
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -9,7 +9,7 @@
Title="MainWindow" Height="450" Width="800">
<Grid>
<Pages:IPScanner Margin="0,0,34,10"/>
<Pages:PortScanner Margin="0,0,34,10"/>
</Grid>
</Window>