Захват пакетов в Windows 7 - PullRequest
2 голосов
/ 24 мая 2011

Я пытаюсь перехватить все переданные пакеты на компьютере.Мой код прекрасно работает в 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, которая говорит:

Вызов функции bind с необработанным сокетом для протокола IPPROTO_TCP не разрешен

но я использую IPPROTO_IP, и документация функции связывания также говорит:

Функция связывания может также использоваться для связывания с необработанным сокетом (сокет был создан путем вызовафункция сокета с параметром типа, установленным в SOCK_RAW)

Так что, похоже, это не проблема.Несмотря на это, я не получаю никакой ошибки при вызове bind и других функций в этом коде.Я также пропустил вызов bind функции, которая вызывает recvfrom сделать ошибку 10022 Недопустимый аргумент. Я также заменил IPPROTO_IP на IPPROTO_TCP, но это не помогает ни.

IЯ не уверен, правильно ли я это делаю или нет, но этот код работает без проблем на Windows XP.В любом случае, я ищу способ получения и отправки пакетов, связанных с локальным IP-адресом в Windows XP / 7.

Также:

  • Я запускаю этот код на привилегированном(admin) режим в Windows 7.
  • Winpcap или другие сторонние библиотеки для меня недоступны.

Ответы [ 2 ]

2 голосов
/ 23 марта 2013

У меня была такая же проблема.Оказалось, что это был брандмауэр Windows 7, который не давал снифферу видеть входящие данные.Выключил и, наконец, код работал.

0 голосов
/ 01 июня 2011

Я запускаю ваш код на моей Win7, и он работает.Я вижу следующие строки: Полученные КБ: 20 Полученные КБ: 40 Полученные КБ: 60 Полученные КБ: 80 Полученные КБ: 100

Возможно, проверьте свой брандмауэр?

...