ARPの送信部分も面倒だった。
いや、送信自体はそれほど難しくは無かった。WinPcapの威力だけど。
デバイス、パケットを準備して、pcap_open_live()でデバイス(NIC)をオープンしてpcap_sendpacket()でパケットを送信できる。
具体的には
send_fp=pcap_open_live(AdapterName,MAX_RECV_SIZE,0,timeout,ErrorBuf)これだけで、packet_buffの内容がネットワーク上に送信される。
int Ret = pcap_sendpacket(send_fp, (byte *)(&packet_buff), フレーム長);
pcap_close(send_fp);
問題は送信元(つまり自分自身)のMACアドレスをどうやって取得するか?だった。
完全にWinPcapに頼り切っていたので、複数枚NICがある場合はpcap_findalldevs()でデバイス一覧を取得してその中から選択すれば良いと考えていたのだが、WinPcapで取得できるpcap_if構造体の中にはIPアドレス、NPFデバイス名、デスクリプション(Windows上で見えるNICの名称)位しか、有益な情報が無かった。
そこで色々試行錯誤した結果として、(※とりあえず不満はあるが)
1.WinPcapでインターフェースの一覧を取得する
2.複数ある場合は、利用者に使用するインターフェースを選択させる
3.pcap_if構造体からIPアドレスを取得する
4.Winsock2のGetIpAddrTable()を使って、IPアドレスからWinsock上でのインターフェース番号(PMIB_IPADDRTABLEの->table[i].dwIndex)を取得する
5.Winsock2のGetIfTable()を使い、インターフェース番号からMACアドレスを取得
という、えらく面倒な方法を採る事になってしまった。
ともあれ、送信元のMACアドレスも取得する事ができたので、無事ARPリクエストのフレームを作る事ができたし、結果としてARPリクエストの送信まで行う事ができた。
ま、ウソのMACアドレスを送信元にして、受信はプロミスキャスモードを使う事も考えたけど、スニファ検知で見つかる事とか、そもそもウソのMACアドレスを使う事がどうか・・といった事を考えると、やっぱりできるだけ正攻法でいきたい。と言う事で、頑張ってみた。
次、MACアドレスの重複を検出する方法だが、結局受信したARPリプライをもとにMACアドレスを集めたテーブルを作る事にした。別にMACアドレスが100件も集まる事は考えにくい(※重複したIPアドレスという前提なので、、、多くても2〜3件)ので、ARPリプライを受信する度にテーブルと比較して、新規のMACアドレスならテーブルに追加する方法を採った。
ここまでやって、何とかオリジナルのARPingに相当するIPアドレス重複の検出を行う事が出来た。
とは言え、前述の通り、時間の管理がかなりラフなせいで、応答時間を計測する事は出来なかった。
・・・ホント、誰かARPing移植してくれないかなー
arping.exe.zip
とりあえず、そのARPingモドキも置いて見ますけど。(ウイルスチェックとか、色々は自己責任でお願いします。。。)
いちおう、WindowsXP SP2上とWindows 2003 R2上では動きました。あと、WinPcapの4.0.2が必要です。
Visual Studio 2008 Express Editionを使いましたが、msvcr90.dllは不要です。
C:\> arping IPアドレス
で、ARPパケットの送信と、応答の確認が行えます。
コメント