これは、ASP(Active Server Pages) & WSH などで利用できる COM コンポーネントです




はじめに
TCP/IP の知識はあるけど、プログラミングの知識が の方に朗報です。
本ツールは、WinPcap というツールを COM ラッピングしました。
よって、VBScript などの ActiveScript や、VisualBASIC などから、WinPcap を呼び出すことが可能です。(WinPCap 自体がネットワーク・デバイスのデバイス・ドライバとして動作しますので、その実行権限は必要)

つまり、上記のような方(私もその中に入っていますが...^^)が、Ethernet レベルでの任意のパケットをネットワーク上に流すことが可能です。

ネットワーク・デバイス(ハードウェア/ソフトウェア)のデバグに C 言語や DDK の知識が不要になります。

...ということです。




使用上の注意点...
というか、解決していない問題点...
というか、誰か教えて


VisualBASIC の CreateObject() 関数の第二引数は、DCOM のリモート・ホスト指定にあるようです。
つまり VisualBASIC から、本 DLL の イベント(パケット・キャプチャ)を受け取ることができない!?
という事で VisualBASIC でイベントの取得の仕方(パケット・キャプチャの仕方)を聞かれても作者である私には答えられだけの知識を持っていませんで〜す。m(_ _)m
一応、調査中なのですが....いつ解決するかは不明だったりします...
ということで、どなたか回避策をご存知の方は、教えてください

ActiveX OCX にしなきゃダメですかぁね〜...
VBScript ではできるのに...




VisualBASIC6.0 の場合
参照設定という機能を使うと CreateObject() で確保したオブジェクトのイベントを取得する事ができる。

  1. VisualBASIC6.0 のメニューの「プロジェクト」「参照設定」を選択
  2. 参照可能なライブラリとして、「sCOMWinPcap 1.0 タイプライブラリ」をチェック
  3. 以上で下準備は終了
  4. コード部分で、オブジェクト変数の宣言時に「WithEvents」を追加するだけだ。
    こんな感じ
    Private WithEvents myObj As sCOMwinPcaplib.Generate

    Private Sub myObj_DataArrival(ByVal data As String)
    ....
    End Sub
  5. オブジェクトの内容は、「オブジェクト・ブラウザ」を使えばいいかも知れないです。


サンプルが、添付していますので、そちらを参照してもいいかも知れないです。




そもそも WinPcap って何?
UNIX/Linux 系には、tcpdump というツールがあります。
LAN 上の通信データを取得して、解析するツールです。
つまり、LAN アナライザ(一般的には、"パケット・キャプチャ" とも、一番有名な製品の名から "スニッファ" とも呼ばれます)です。
その tcpdump では、ネットワーク上のパケットをキャプチャするモジュールが libpcap として分離されています。
その Windows 版が WinPcap です。

本ツールは、その WinPcap を COM ラッピングしました。

いろいろリンク


使用方法
  1. WinPCap をインストールしてください。
    開発環境は WinPCap 3.0 ですので、3.0 以上をインストールすればいいと思います。
  2. ここで配布されている共通コンポーネント sCOMmon.dll をダウンロードして、システム・ディレクトリ(%SystemRoot%\System32 {Win64 → %SystemRoot%\SysWOW64})にコピーします。
  3. 16進データのエンコード/デコードには、sURLEncoceを使っています。よって、それもインストールしてください。
  4. 本ツールをファイルをダウンロードします。
  5. ダウンロードしたファイルを解凍しします。
    (LHAは、吉崎栄泰氏が、著作権を所有)
  6. sCOMwinPcap.dll を任意のディレクトリにコピー。
  7. コピーされたディレクトリで、regsvr32.exe を実行してレジストリに登録。
  8. (同梱されている regsvr32.bat を sCOMwinPcap.dll と同一ディレクトリにコピーして実行することでも可能。
  9. 以上で、
    VBScript,JScript,VisualBASIC にて、この COM コンポーネントを利用可能。



アンインストール方法
RegSvr32 コマンドの /u オプションを用いて、sCOMwinPcap.dll をレジストリから削除して、sCOMwinPcap.dll を削除すればいいです。
sCOMmon.DLL や sURLEncode.dll も必要なければ、削除する


データ送信の例
Option Explicit

Set obj = WScript.CreateObject("SCOMwinPcap.CreatePacket.1")
Set obj = WScript.CreateObject("SCOMwinPcap.Generate.1")

ret = obj.IsError()
WScript.Echo ret

obj.sendDataHex("000102030405060708090a0b0c0d0e0f1011121314")

ret = obj.IsError()
WScript.Echo ret

Set obj = Nothing
こんな感じ


ヘルパー
ethernet のデータ列を毎回、16進表記で作るのは大変でしょう。
そういう時のためこちらのツールもインストールすると便利かも〜


開発環境など
MS VC++ ver6.0 ATL COM Wizard にて作成。
WinPcap の SDK についているヘッダ・ファイルやライブラリ・ファイルは同梱していませんので、このままでは、コンパイルはできません。
別途、WinPcap の SDK を入手して、source ディレクトリ以下に「winpcap」ディレクトリを作って、その中に以下のファイルを配置してください。



また、バイナリは ReleaseMiniSize モードでコンパイルしています。
その時、プリプロセッサで「_ATL_MIN_CRT」を削除しています。


動作内容 ver1.x 以降のデータ送信、NIC 情報の保持など
  1. 単純にデバイス一覧をオブジェクト内メモリに保持します。
  2. 複数の NIC がある場合は、getInterfacePropaty() で、現在オブジェクト内でアクティブになっている NIC の情報が取得できます。そして、別の NIC をアクティブにしたい場合は、getNextInterface() 関数を使います。
  3. 送信に使いたい NIC のところで setInterface() 関数を用いて、オブジェクトに決定したと伝えます。
    デフォルトでは、先頭の NIC (デバイス情報取得時{winpcap 内の pcap_findalldevs() 関数}に先頭として取得されたデバイスのこと)に指定されています。
  4. 一つしか NIC がない場合は、上記の処理は不要です。
  5. 後は、以下のどれかのメソッドを呼び出せば、引数のデータをネットワーク上に送信できます。



動作内容 ver2 から実装したパケット・キャプチャ
パケット・キャプチャを行うため ver2 以降では内部的にマルチ・スレッド処理を行っています。

なぜ、マルチ・スレッド処理が必要であるかというと、COM クライアントから呼び出されているスレッド内部にパケット・キャプチャの機能を実装すると、メソッド発行後に処理が戻ってこないという事になるからです。
(確か、イベントを記述した方には処理が戻るけどね....)

という事で、(イベント・ドリブン形式にするために)マルチ・スレッド処理が必要なんですけど....なんか、VC 達人以外は、COM 内部でのマルチ・スレッドは実装すべきではないようです。

COM 内部でのマルチ・スレッド処理に煩雑なコーディングが必要な理由は、COM の心臓部であるインターフェイス(またはインターフェイス・ポインタ)は、他のスレッドから直接(メモリ・アドレスを直接叩くイメージ)アクセスできないという事に起因するようです。

しかし、COM 内部でのマルチ・スレッドの実装に方法がないわけではありません。

  1. COM のアパートメント・モデルを、MTA にすると、同一の MTA に所属していれば別スレッドからでもインターフェイス・ポインタを利用する事が可能
  2. VC++ の ATL ウィザードが用意している自動マーシャリング機能を用いる
  3. 手動でマーシャリング/アンマーシャリングを行い、他のスレッドからインターフェイス・ポインタを使用できるようにする
  4. COM のメイン・スレッドにウィンドウを割り当て Windows のメッセージング方式を用いて、メインスレッドにイベントの発生を知らせる


1-3 の方法は、私のような VB で楽したいために VC を使っているようなヘタレなプログラマに理解できるような文献を発見できなかったので、本プログラムのパケット・キャプチャは 4 の方式を採用しています。

4の方式


私の VisualC++ メモ


免責など
著作権はとりあえず保持します。
このソフトを使用したことによって生じた、
いかなる損害についても責任は持ちません。
ソースコードについても、各自の責任において、
自由にいじってくれてもいいです。

DownLoad(sCOMWinPcap.lzh as 119,474byte) (sCOMWinPcap.lzh.base64)
sCOMwinPcap.dll is 77,824byte(ver2.0.0.4)

...なぜか未だに、デバグ情報付のコンパイルをしている...


変更履歴



to do list



メソッド/プロパティ一覧
refreshInterface()
内容 オブジェクト内に保持している(複数の) NIC の一覧を取得しなおす。
引数 なし
戻り値 なし
IsError 値
成功 0
失敗 負数


getInterfacePropaty()
InterfacePropaty() {ver2 より}
内容 現在、オブジェクト内でアクティブになっている NIC についての情報を文字列で返す。
引数 なし
戻り値 現在、オブジェクト内でアクティブになっている NIC についての情報
IsError 値
成功 0
失敗 負数


getNextInterface()
内容 オブジェクト内でアクティブになっている NIC を次のものに変更する
引数 なし
戻り値 なし
IsError 値
成功 0 : 成功しました。
-804 : 登録されているインターフェイスの最後の次ということで先頭のインターフェイスに戻しました
失敗 負数


setInterface()
setSendInterface() {ver2 より}
内容 オブジェクト内で現在アクティブになっているインターフェイスをデータ送信に利用することを決定する事をオブジェクトに通知します
引数 なし
戻り値 なし
IsError 値
とくになしのはず...


sendData()
sendDataBin()
sendDataHex()
内容 入力データをネットワークへ送信します。
引数 sendData(文字列)
sendDataBin(Byte 型配列)
sendDataHex(16進表記の文字列)
戻り値 なし
IsError 値
成功 0 : 成功しました。
失敗 負数


setRecieveInterface()
内容 オブジェクト内で現在アクティブになっているインターフェイスをデータ受信に利用することを決定する事をオブジェクトに通知します
引数 なし
戻り値 なし
IsError 値
とくになしのはず...


StartCapture()
内容 setRecieveInterface() 関数で決定したデバイスでネットワーク上を流れるデータのキャプチャを開始する
データ受信の度に、オブジェクトに対して「DataArrival()」イベントが発生する。
引数 なし
戻り値 なし
IsError 値
とくになしのはず...


StopCapture()
内容 StartCapture() 関数で開始したキャプチャを停止する。
引数 なし
戻り値 なし
IsError 値
とくになしのはず...


IsError()
ErrorNo {ver2 より}
内容 直前のメソッドが成功したかどうか。
引数 なし
戻り値 詳細は、sError.h を参照



pcap_ErrorString
内容 直前の pcap ライブラリからのエラー・メッセージの内容を読み出す
引数 なし
戻り値 pcap からのエラー・メッセージ(文字列、そして多分英語)



イベント一覧
DataArrival(文字列)
内容 受信用デバイスからデータを受信したときに発生する
引数 受信デバイスから渡されたキャプチャしたデータ(既に 16進表示されている状態)
戻り値 なし
IsError 値
とくになし



AllowUserRawAccess
MS-Windows2000 以降!? では、このレジストリを変更することで、管理者以外でも Raw Socket にアクセスできるようになるらしい。
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\AllowUserRawAccess
REG_DWORD
「0」or「1」(デフォルトは 0)
「1」にすると、全てのユーザで、Raw Socket を使えるようになる。

AllowUserRawAccess


なんか、packetVB なるプロジェクトもあるらしいのでリンクしておこうっと


mail to active@window.goukaku.com