如何捕获传入的数据包?

时间:2013-11-24 15:48:07

标签: c tcp ip packet sniffer

我正在尝试编写迷你嗅探器。问题是捕获来自我的地址的数据包。目前,我只打印“来源”和“目的地”地址。如何修复这个程序?对不起我的“英语”:D谢谢

Log:

Source: 172.16.226.207 Destination: 173.194.112.78

Source: 172.16.226.207 Destination: 23.78.81.224

Source: 172.16.226.207 Destination: 69.171.247.29

Source: 172.16.226.207 Destination: 173.194.71.84

Source: 172.16.226.207 Destination: 173.194.71.94
#include <stdio.h>
#include <winsock2.h>
#include <conio.h>

#define SIO_RCVALL      0x98000001
#define MAX_PACKET_SIZE 0x10000

typedef struct _IPHeader
{
  unsigned char  verlen;
  unsigned char  tos;
  unsigned short length;
  unsigned short id;
  unsigned short offset;
  unsigned char  ttl;
  unsigned char  protocol;
  unsigned short xsum;
  unsigned long  src;
  unsigned long  dest;
} IPHeader;

int main(void)
{
    WSADATA     wsaData;
    SOCKET      s;
    HOSTENT*    phe;
    SOCKADDR_IN saClient;
    IN_ADDR     sa;
    char        name[128];

    int error;

    error = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (error)
    {
        printf("WSAStartup failed with error: %d\n", error);
        return 1;
    }
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        printf("Could not find a usable version of Winsock.dll\n");
        WSACleanup();
        return 1;
    }
    else
        printf("The Winsock 2.2 dll was found\n");

    s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

    error = gethostname(name, sizeof(name));
    if (error)
    {
        printf("gethsotname function failed with error: %d\n", error);
        WSACleanup();
        return 1;
    }
    else
        printf("Host name: %s\n", name);

    phe = gethostbyname(name);

    error = WSAGetLastError();
    if (error)
    {
        printf("gethostbyname function failed with error: %d\n", error);
        WSACleanup();
        return 1;
    }

    ZeroMemory(&saClient, sizeof(saClient));

    saClient.sin_family = AF_INET;
    saClient.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[1])->s_addr;

    error = bind(s, (SOCKADDR *)&saClient, sizeof(SOCKADDR));
    if (error == SOCKET_ERROR)
    {
        printf("bind function failed with error: %d\n", error);
        closesocket(s);
        WSACleanup();
        return 1;
    }

    unsigned long flag = 1;
    ioctlsocket(s, SIO_RCVALL, &flag);

    // Packet processing
    char buffer[MAX_PACKET_SIZE];

    printf("\n");

    IPHeader* hdr;
    while (!_kbhit())
    {
        error = recv(s, buffer, sizeof(buffer), 0);
        if (error > sizeof(IPHeader))
        {
            hdr = (IPHeader *)buffer;

            sa.s_addr = hdr->src;
            printf("Source: %s\n", inet_ntoa(sa));

            sa.s_addr = hdr->dest;
            printf("Destination: %s\n\n", inet_ntoa(sa));
        }
        else if (error == 0)
            printf("Connection closed\n");
        else
            printf("recv failed with error: %d\n", error);
    }

    closesocket(s);
    WSACleanup();
    return 0;
}

1 个答案:

答案 0 :(得分:0)

如果我是正确的,您想要嗅探从远程主机传入的数据包。在这种情况下,您可以看到以下链接(对于Linux): link

您需要在混杂模式下使用界面运行程序。