
高速で拡張可能なネットワークスキャンライブラリ。マルチスレッド、pingプローブ、スキャンフェッチャーを備えています。
Forerunnerライブラリは、高速・軽量・拡張可能なネットワーキングライブラリであり、IPスキャナ、ポートノッカー、クライアント、サーバーなどの堅牢なネットワーク中心のアプリケーション開発を支援するために作成されました。現在の状態では、Forerunnerライブラリは同期および非同期の両方でIPアドレスをスキャンおよびポートノックし、そのエンドポイントにあるデバイスに関する情報(IPがオンラインかどうか、物理MACアドレスなど)を取得できます。このライブラリは完全にオブジェクト指向かつイベントベースであり、スキャンデータは特別に設計された「スキャン」オブジェクトに格納され、結果から例外までのすべてのデータを処理するようになっています。
| メソッド | 説明 | 使用法 |
|---|---|---|
| Scan | 単一のIPをスキャンして情報を取得 | Scan("192.168.1.1"); |
| ScanRange | IPの範囲をスキャンして情報を取得 | ScanRange("192.168.1.1", "192.168.1.255") |
| ScanList | IPのリストをスキャンして情報を取得 | ScanList("192.168.1.1, 192.168.1.2, 192.168.1.3") |
| PortKnock | 単一のIPのすべてのポートにpingを送信 | PortKnock("192.168.1.1"); |
| PortKnockRange | IPの範囲内のすべてのポートにpingを送信 | PortKnockRange("192.168.1.1", "192.168.1.255"); |
| PortKnockList | IPのリストを使用してすべてのポートにpingを送信 | PortKnockList("192.198.1.1, 192.168.1.2, 192.168.1.3"); |
| IsHostAlive | ホストにN回、Xミリ秒間pingを送信 | IsHostAlive("192.168.1.1", 5, 1000); |
| GetAveragePingResponse | ホストの平均ping応答を取得 | GetAveragePingResponse("192.168.1.1", 5, 1000); |
| IsPortOpen | TCPおよびUDPを介して個々のポートにpingを送信 | IsPortOpen("192.168.1.1", 45000, new TimeSpan(1000), false); |
ネットワークのスキャンはデジタル時代において一般的なタスクであり、将来のプログラマが簡単に実行できるように、私はこれを可能な限りシンプルにしました。Forerunnerライブラリは完全にオブジェクト指向であるため、プラグアンドプレイの状況に最適です。IPスキャン用のオブジェクトはIPScanObjectと呼ばれ、実際にはかなりの数のプロパティを含んでいます:
このオブジェクトを念頭に置いて、新しいオブジェクトを作成し、それを使ってスキャンを実行してみましょう。これには複数の方法がありますが、最も簡単な開始方法は、まず新しいScannerオブジェクトを作成してスキャンメソッドにアクセスできるようにすることです。次に、IPScanObjectを作成し、列挙したいIPを指定してScanメソッドに設定します。例:
using System;
using Forerunner; // ライブラリをインポートするのを忘れずに。
namespace Example
{
class Program
{
static void Main(string[] args)
{
// スキャンしたいIP。
string ip = "192.168.1.1";
// 新しいスキャナーオブジェクトを作成。
Scanner s = new Scanner();
// 新しいスキャンオブジェクトを作成してスキャンを実行。
IPScanObject result = s.Scan(ip);
// スキャンが完了したことを出力。
if (result.Errors != null)
Console.WriteLine("[x] スキャン中にエラーが発生しました。");
else
Console.WriteLine("[+] " + ip + " のスキャンに成功しました!")
// ユーザーがいつでも終了できるようにする。
Console.Read();
}
}
}
もう一つの方法は、私が好んで使う方法ですが、Scannerオブジェクトを作成し、ScanAsyncProgressChangedやScanAsyncCompleteなどのイベントハンドラにサブスクライブすることです。そうすることで、非同期メソッドを完全に制御でき、それらの進行状況がアプリケーションにどのように影響するかを制御できます。例:
using System;
using System.Threading.Tasks;
using Forerunner; // ライブラリをインポートするのを忘れずに。
namespace Example
{
class Program
{
static void Main(string[] args)
{
// スキャンしたいIP。
string ip = "192.168.1.1";
// スキャナーオブジェクトを設定。
Scanner s = new Scanner();
s.ScanAsyncProgressChanged += new ScanAsyncProgressChangedHandler(ScanAsyncProgressChanged);
s.ScanAsyncComplete += new ScanAsyncCompleteHandler(ScanAsyncComplete);
// 新しいスキャンタスクを開始。
TaskFactory task = new TaskFactory();
task.StartNew(() => s.ScanAsync(ip));
// ユーザーがいつでも終了できるようにする。
Console.Read();
}
static void ScanAsyncProgressChanged(object sender, ScanAsyncProgressChangedEventArgs e)
{
// e.Progressを使って何かを行うか、このイベントを購読せずに何もしないこともできます。
}
static void ScanAsyncComplete(object sender, ScanAsyncCompleteEventArgs e)
{
// IPScanObject(e.Result)を使って何かを行う。
if (e.Result.Errors != null)
Console.WriteLine("[x] スキャン中にエラーが発生しました。");
else
Console.WriteLine("[+] " + e.Result.IP + " のスキャンに成功しました!")
}
}
}
あなたが何を考えているか分かっています。ポートノッキング?はい、でもいいえ。この用語は、事前に定義された一連のポートを介して接続するという従来の意味でのポートノッキングではなく、単にポートが実際に開いているかどうかをチェックすることです。各ポートに接続してデータを送信することで、文字通りの「ノッキング」を行います。IPスキャンと同様に、ポートノッキングでは「Port Knock Scan Object」、略してPKScanObjectというカスタムオブジェクトを使用します。PKScanObjectは実際にはPKServiceObjectのリストを含んでおり、これらがポートデータを保持します。サービスオブジェクトには次のプロパティがあります:
ポートノッキングはIPスキャンと同様の方法です。まず、Scannerオブジェクトを作成します。次に、新しいPKScanObjectを作成し、選択したIPを指定してPortKnockメソッドに設定し、結果を表示します。例:
using System;
using Forerunner; // ライブラリをインポートするのを忘れずに。
namespace Example
{
class Program
{
static void Main(string[] args)
{
// スキャンしたいIP。
string ip = "192.168.1.1";
// 新しいスキャナーオブジェクトを作成。
Scanner s = new Scanner();
// 新しいスキャンオブジェクトを作成してスキャンを実行。
PKScanObject result = s.PortKnock(ip);
// スキャンが完了したことを出力。
if (result.Errors != null)
Console.WriteLine("[x] スキャン中にエラーが発生しました。");
else
Console.WriteLine("[+] " + ip + " のスキャンに成功しました!")
// 結果を表示。
foreach (PKServiceObject port in result.Services)
{
Console.WriteLine("[+] IP: " + port.IP + " | " +
"Port: " + port.Port.ToString() + " | " +
"Protocol: " + port.Protocol.ToString() + " | " +
"Status: " + port.Status.ToString());
}
// ユーザーがいつでも終了できるようにする。
Console.Read();
}
}
}
最後に、ポートノッキングを非同期で行う簡単な例を示します。本質的には同期の場合と同じですが、イベントを活用できる点が異なります。UIのクラッシュやシステムのロック状態を心配することなく、進行状況を取得できます。例:
using System;
using System.Threading.Tasks;
using Forerunner; // ライブラリをインポートするのを忘れずに。
namespace Example
{
class Program
{
static void Main(string[] args)
{
// スキャンしたいIP。
string ip = "192.168.1.1";
// スキャナーオブジェクトを設定。
Scanner s = new Scanner();
s.PortKnockAsyncProgressChanged += new PortKnockAsyncProgressChangedHandler(PortKnockAsyncProgressChanged);
s.PortKnockAsyncComplete += new PortKnockAsyncCompleteHandler(PortKnockAsyncComplete);
// 新しいスキャンタスクを開始。
TaskFactory task = new TaskFactory();
task.StartNew(() => s.PortKnockAsync(ip));
// ユーザーがいつでも終了できるようにする。
Console.Read();
}
static void PortKnockAsyncProgressChanged(object sender, PortKnockAsyncProgressChangedEventArgs e)
{
// 進行状況を表示してETAを知る。
if (e.Progress == 99)
{
Console.Write(e.Progress.ToString() + "%...");
Console.WriteLine("100%!");
}
else
Console.Write(e.Progress.ToString() + "%...");
}
static void PortKnockAsyncComplete(object sender, PortKnockAsyncCompleteEventArgs e)
{
// ポートノックが完了したことをユーザーに通知。
Console.WriteLine("[+] ポートノック完了!");
// エラーが発生したか確認。
if (e.Result == null)
Console.WriteLine("[X] ポートノックがデータを返しませんでした!");
else
{
// 記録されたポートがあるか確認。
if (e.Result.Services.Count == 0)
Console.WriteLine("[!] ノック中に開いているポートはありませんでした。");
else
{
// ポートとその詳細を表示。
foreach (PKServiceObject port in e.Result.Services)
{
Console.WriteLine("[+] IP: " + port.IP + " | " +
"Port: " + port.Port.ToString() + " | " +
"Protocol: " + port.Protocol.ToString() + " | " +
"Status: " + port.Status.ToString());
}
}
}
}
}
}
アイコン: monkik
https://www.flaticon.com/authors/monkik
Copyright © ∞ Jason Drawdy
All rights reserved.
MIT License(MIT)
ここに、以下の条件に従って、本ソフトウェアおよび関連文書ファイル(以下「ソフトウェア」)の複製を取得するすべての人に対し、ソフトウェアを無制限に扱うことを許可します。これには、ソフトウェアの複製、変更、結合、出版、配布、サブライセンス、および/または販売の権利、およびソフトウェアを提供された者にこれらを許可することを含みますが、これに限定されません。
上記の著作権表示およびこの許可表示は、ソフトウェアのすべての複製または重要な部分に含まれるものとします。
ソフトウェアは「現状のまま」提供され、明示的か黙示的かを問わず、いかなる種類の保証もありません。これには、商品性、特定目的への適合性、および非侵害に関する保証が含まれますが、これに限定されません。いかなる場合も、著作者または著作権所有者は、契約、不法行為、またはその他の行為に基づき、ソフトウェアまたはソフトウェアの使用またはその他の取引に起因または関連するいかなる請求、損害、またはその他の責任も負いません。
本通知に含まれる場合を除き、上記の著作権所有者の名称は、事前の書面による許可なしに、本ソフトウェアの販売、使用、またはその他の取引を宣伝または促進するために使用してはなりません。