在Windows 7上捕获数据包

时间:2011-05-24 09:58:58

标签: winapi windows-7 winsock packet-capture sniffing

我正在尝试捕获计算机上的所有传输数据包。我的代码在Windows XP中运行良好,但它只捕获Windows 7上的传出数据包,无法看到传入的数据包。

这是一个只计算接收数据包大小的代码版本(看起来很大,但大多数只是定义)。此代码在Windows XP上正常运行但在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上的this article谁说:

  

使用raw调用bind函数   IPPROTO_TCP协议的套接字是   不允许

但我使用IPPROTO_IPbind function documentation也说:

  

绑定功能也可用于   绑定到原始套接字(套接字是   通过调用套接字函数创建   将type参数设置为   SOCK_RAW)

所以看来这不是问题。尽管如此,我在调用bind和此代码中的其他函数时也没有任何错误。我也省略了调用bind函数导致recvfrom生成错误 10022无效参数。我还将IPPROTO_IP替换为IPPROTO_TCP但它没有帮助两者都不是。

我不确定我是否做得对,但此代码在Windows XP上没有任何问题。无论如何,我正在寻找一种方法来接收和发送与Windows XP / 7上的本地IP地址相关的数据包。

另外:

  • 我在Windows 7中以特权(管理)模式运行此代码。
  • Winpcap或其他第三方库不适合我。

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。原来是Windows 7防火墙阻止了嗅探器查看入站数据。关闭它,最后,代码工作。

答案 1 :(得分:0)

我在Win7上运行你的代码并且它有效。我确实看到以下行打印出来: 收到的KB:20 收到的KB:40 收到的KB:60 收到的KB:80 收到的KB:100

可能检查防火墙?