2

転送されたすべてのパケットをコンピューターでキャプチャしようとしています。私のコードは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を引き起こす関数の呼び出しを省略しました。私も交換しましたが、どちらも役に立ちません。recvfromIPPROTO_IPIPPROTO_TCP

私はそれを正しく行っているかどうかはわかりませんが、このコードはWindowsXPで問題なく動作します。とにかく、私はWindows XP/7でローカルIPアドレスに関連するパケットを送受信する方法を探しています。

また:

  • このコードは、Windows 7の特権(管理)モードで実行しています。
  • Winpcapまたは他のサードパーティライブラリは私にとって利用可能なオプションではありません。
4

2 に答える 2

2

私も同じ問題を抱えていました。スニファーが受信データを見るのを阻止したのはWindows7ファイアウォールであることが判明しました。それをオフにして、最後に、コードは機能しました。

于 2013-03-22T20:50:18.143 に答える
0

Win7でコードを実行すると、機能します。次の行が印刷されています。受信KB:20受信KB:40受信KB:60受信KB:80受信KB:100

おそらくファイアウォールをチェックしますか?

于 2011-06-01T08:08:57.560 に答える