在 Windows 7 上捕获数据包

发布于 2024-11-09 12:53:21 字数 3036 浏览 0 评论 0原文

我正在尝试捕获计算机上所有传输的数据包。我的代码在 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 上的这篇文章说道:

使用原始数据调用绑定函数 IPPROTO_TCP 协议的套接字是 不允许

,但我正在使用 IPPROTO_IP绑定函数文档还说:

绑定函数也可用于 绑定到原始套接字(该套接字是 通过调用socket函数创建 类型参数设置为 SOCK_RAW)

所以看来这不是问题。尽管如此,我在调用此代码中的 bind 和其他函数时没有收到任何错误。我还省略了调用 bind 函数,该函数会导致 recvfrom make 错误 10022 Invalid argument. 我还用 IPPROTO_IP 替换了 IPPROTO_IP >IPPROTO_TCP 但这也没有帮助。

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

另外:

  • 我在 Windows 7 的特权(管理)模式下运行此代码。Winpcap
  • 或其他第三方库对我来说不是可用的选项。

I am trying to capture all of transferred packets on a computer. My code works fine in Windows XP but it only captures outgoing packets on Windows 7 and cannot see incoming packets.

Here is a version of the code which just calculate the size of received packets (it seems big but most of it is just definitions). This code works correctly on Windows XP but nothing happens on Windows 7 (it stuck at recvfrom) (the code is complete and you could give a try on 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;
        }
    }
}

The only thing made me suspect was this article on MSDN who says:

A call to the bind function with a raw
socket for the IPPROTO_TCP protocol is
not allowed

but i am using IPPROTO_IP, and bind function documentation also says:

The bind function may also be used to
bind to a raw socket (the socket was
created by calling the socket function
with the type parameter set to
SOCK_RAW)

So it seems this is not the problem. Despite this, I don't get any error from calling bind and other functions in this code. I also omitted calling bind function which causes recvfrom make error 10022 Invalid argument. I also replaced IPPROTO_IP with IPPROTO_TCP but it doesn't help neither.

I am not sure whether I am doing it right or not, but this code works without any problem on Windows XP. Anyway, I am looking for a way to get received and sent packets related to a local IP address on Windows XP/7.

Also:

  • I am running this code on privileged (admin) mode in Windows 7.
  • The Winpcap or other third-party libraries is not an available option for me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅笑轻吟梦一曲 2024-11-16 12:53:21

我也有同样的问题。结果是 Windows 7 防火墙阻止了嗅探器查看入站数据。把它关掉,最后,代码工作了。

I had the same problem. Turned out it was Windows 7 Firewall that stopped the sniffer from seeing inbound data. Turned it off and finally, the code worked.

牵你手 2024-11-16 12:53:21

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

可能检查一下您的防火墙?

I run your code on my Win7 and it works. I do see following lines printed out:
Received KBs: 20
Received KBs: 40
Received KBs: 60
Received KBs: 80
Received KBs: 100

Probably check your firewall?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文