| Welcome to SapporoWorks! We create stimulating network programs.
By a demand from user, SapporoWorks evolves. | ||||||||||||
| |||||||||||||
| 開発情報 > ドライバを使用しないパケットダンプ | |||||||||||||
|
●●●●概要 WinSock2.2(Windows2000 WindowsXP)以降 デバイスドライバを使用しないでもRAWソケット扱えるようになりました。 っと言うことで、早速、パケットモニタを作成してみました。 UNIXではあたりまえの事でしたが、遂にWindwosでもA4一枚のプログラムでパケットがダンプできるようになったのでした。(^^) ws2_32.lib のリンクが必要です。 ●●●●ソース
//コンストラクタ
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//Ver2.2 でWinSockを初期化する
WSAStartup(MAKEWORD(2,2),&wsd);
hThread=NULL;
//アダプタのリストをコンボボックに取得
ListAdapter();
}
//デストラクタ
__fastcall TForm1::~TForm1(void)
{
//キャプチャスレッドが走行中の場合ストップする
if(hThread!=NULL)
TerminateThread(hThread,ThreadId);
//WinSockの終了処理
WSACleanup();
}
//アダプタの初期化
int __fastcall TForm1::InitAdapter(void)
{
char TmpBuf[1024];
int i,max;
unsigned int optval;
char buf[4096];
DWORD d;
SOCKET_ADDRESS_LIST *slist;
SOCKADDR_IN addr_in;
//SOCKETの生成
if( INVALID_SOCKET == (sock = WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))){
wsprintf(TmpBuf,"WSASocket(AF_INET,SOCK_RAW) failed");
Memo1->Lines->Add(TmpBuf);
return -1;
}
//アダプタのリスト取得
if(SOCKET_ERROR == WSAIoctl(sock,SIO_ADDRESS_LIST_QUERY,NULL,0,buf,4096,&d,NULL,NULL)){
wsprintf(TmpBuf,"WSAIoctl(SIO_ADDRESS_LIST_QUERY) faild.");
Memo1->Lines->Add(TmpBuf);
return -1;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
//SOCKET のデータセット
addr_in.sin_addr.s_addr=((SOCKADDR_IN *)slist->Address[ComboBox1->ItemIndex].lpSockaddr)->sin_addr.s_addr;
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(0);
//bind
if(bind(sock,(SOCKADDR *)&addr_in,sizeof(addr_in))==SOCKET_ERROR) {
wsprintf(TmpBuf,"bind failed");
Memo1->Lines->Add(TmpBuf);
return -1;
}
optval=1;
if(WSAIoctl(sock,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&d,NULL,NULL)==SOCKET_ERROR){
wsprintf(TmpBuf,"WSAIoCtl(SIO_RCVALL) failed");
Memo1->Lines->Add(TmpBuf);
return -1;
}
return 0;
}
//キャプチャ開始・終了(キャプチャスレッドの生成・破棄)
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(hThread==NULL){ //キャプチャ開始処理
if(-1==InitAdapter())
return;
//キャプチャスレッド生成
if(NULL!=(hThread=CreateThread(NULL,0,CaptureThread,0,0,&ThreadId)))
Button1->Caption="Stop";
}else{ //キャプチャ終了処理
//キャプチャスレッドの破棄
TerminateThread(hThread,ThreadId);
hThread=NULL;
Button1->Caption="Start";
}
}
//キャプチャスレッド本体
unsigned long __stdcall CaptureThread(void *ArgList)
{
unsigned char buf[MAX_IP_SIZE];
WSABUF wsb;
unsigned long len;
DWORD Flags;
while(1){
Sleep(1);
Application->ProcessMessages();
wsb.buf=buf;
wsb.len=MAX_IP_SIZE;
memset(wsb.buf,0x0,MAX_IP_SIZE);
Flags=0;
//パケット取得
if(SOCKET_ERROR==WSARecv(Form1->sock,&wsb,1,&len,&Flags,NULL,NULL)){
wsprintf(buf,"WSARecv failed. Code %d",WSAGetLastError(),Form1->sock);
Form1->Memo1->Lines->Add((char *)buf);
continue;
}
//パケット表示
Form1->Print(buf,len);
}
Form1->hThread=NULL;
return 0;
}
●●●●サンプル サンプルプログラム実行画面
ソースファイルのダウンロード 003-src.LZH 7Kbyte
実行ファイルのダウンロード 003-bin.LZH 207Kbyte
開発者のための実装系Webマガジンへの投稿
WinPcapを使用したパケットモニターの作成方法 パケットドライバー「WinPcap」の利用方法、および取得したデータをプロトコルに従って解析する手法について紹介。 WinSock2を使用したパケットモニターの作成方法 WindowsでRAWソケットを扱う方法の紹介。GUIプログラムを作成する場合に必須となる「非ブロッキングモード」や、すべてのパケットを取得するための「プロミスキャスモード」についても触れています 。 |
| 開発情報 > ドライバを使用しないパケットダンプ | |
copyright(c) 1995- SapporoWorks
当サイトはリンクフリーです。リンク時に連絡などは必要有りません。また、どのページにリンクして頂いても構いません。 | |