転送されたすべてのパケットをコンピューターでキャプチャしようとしています。私のコードはWindowsXPで正常に動作しますが、Windows 7でのみ発信パケットをキャプチャし、着信パケットを表示できません。
これは、受信したパケットのサイズを計算するだけのコードのバージョンです(大きいように見えますが、ほとんどは単なる定義です)。このコードはWindowsXPで正しく機能しますが、Windows 7では何も起こりません(スタックしrecvfrom
ます)(コードは完全であり、Win7で試してみることができます):
#include <Winsock2.h>
#include <Mstcpip.h>
#include <iostream>
#include <string>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
struct SIP4HEADER
{
u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
u_char tos; // Type of service
u_short tlen; // Total length
u_short ident; // Identification
u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; // Time to live
u_char proto; // Protocol
u_short crc; // Header checksum
u_long saddr; // Source address
u_long daddr; // Destination address
u_int op_pad; // Option + Padding
};
// Error handling parts is removed for clarity
void main()
{
WSAData wsa={0};
WSAStartup(MAKEWORD(2,2),&wsa);
string strIPAddress;
cout << "Enter a local IP address to monitor: ";
cin >> strIPAddress;
SOCKET ListenSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
sockaddr_in sa_in;
sa_in.sin_family = AF_INET;
sa_in.sin_addr.s_addr = inet_addr( strIPAddress.c_str() ); //My local IP address
sa_in.sin_port = htons(0);
bind(ListenSocket,(SOCKADDR *) &sa_in, sizeof(sa_in));
int rcv=RCVALL_IPLEVEL;
DWORD b=0;
WSAIoctl(ListenSocket,SIO_RCVALL,&rcv,sizeof(rcv),0,0,&b,0,0);
char buf[2000];
SIP4HEADER* ih = (SIP4HEADER*)buf;
DWORD ReceivedKBytes = 0;
DWORD t = 0;
while( recvfrom(ListenSocket,buf,_countof(buf),0,NULL,NULL)!=-1 )
{
if(sa_in.sin_addr.s_addr == ih->daddr)
t += ntohs(ih->tlen) ;
// update each 20KB
if(t > 20*1024)
{
t=0;
ReceivedKBytes += 20;
cout << "Received KBs: " << ReceivedKBytes << endl;
}
}
}
私が疑った唯一のことは、MSDNに関するこの記事でした。
IPPROTO_TCPプロトコルのrawソケットを使用したbind関数の呼び出しは許可されていません
しかし、私はを使用してIPPROTO_IP
おり、バインド関数のドキュメントにも次のように書かれています。
bind関数を使用してrawソケットにバインドすることもできます(ソケットは、typeパラメーターをSOCK_RAWに設定してsocket関数を呼び出すことによって作成されました)。
したがって、これは問題ではないようです。bind
それにもかかわらず、このコードで呼び出しや他の関数からエラーが発生することはありません。また、 makeエラー10022無効な引数bind
を引き起こす関数の呼び出しを省略しました。私も交換しましたが、どちらも役に立ちません。recvfrom
IPPROTO_IP
IPPROTO_TCP
私はそれを正しく行っているかどうかはわかりませんが、このコードはWindowsXPで問題なく動作します。とにかく、私はWindows XP/7でローカルIPアドレスに関連するパケットを送受信する方法を探しています。
また:
- このコードは、Windows 7の特権(管理)モードで実行しています。
- Winpcapまたは他のサードパーティライブラリは私にとって利用可能なオプションではありません。