Windows原始套接字以错误的顺序捕获数据包

发布于 2024-12-27 03:31:21 字数 2724 浏览 0 评论 0原文

我正在Windows 7上开发一个基于Windows原始套接字的数据包嗅探器。该程序从IP层捕获数据包。我在这里面临的问题是,程序捕获所有数据包,但其中一些数据包以错误的顺序捕获,例如。对于 TCP 连接建立阶段,我不是按 SYN 、 SYN-ACK 、 ACK 顺序获取数据包,而是将其作为 SYN、ACK、SYN-ACK 获取。 pgm 不是在 SYN-ACK(从远程)之后捕获 ACK,而是在 SYN-ACK 数据包之前获取 ACK。在数据传输阶段也会发生同样的事情。程序在实际数据包之前捕获数据包的ACK 包。如果我并行运行 Wireshark,它会正确显示。我使用 Visual Studio 2005 作为 IDE。

#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "pcap.h"
#include "MSTcpIP.h"

int main(int argc, char **argv)
{
    struct in_addr addr;
    int in, optval=1;
    struct hostent *local;
    WSADATA wsa;
    char *Buffer;

    //Initialise Winsock
    if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
    {
        printf("WSAStartup() failed.\n");
        return 1;
    }

    //Create a RAW Socket
    sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    if (sniffer == INVALID_SOCKET)
    {
        printf("Failed to create raw socket.\n");
        return 1;
    }

    memset(&dest, 0, sizeof(dest));
    memcpy(&dest.sin_addr.s_addr,argv[1], sizeof(argv[1]));
    dest.sin_family = AF_INET;
    dest.sin_port = 0;

    printf("\nBinding socket to local system and port 0 ...");
    if (bind(sniffer,(struct sockaddr *)&dest,sizeof(dest)) == SOCKET_ERROR)
    {
        printf("bind(%s) failed.\n", inet_ntoa(addr));
        return 1;
    }
    printf("Binding successful");

    //Enable this socket with the power to sniff : SIO_RCVALL is the key Receive ALL ;)
    j=1;
    printf("\nSetting socket to sniff...");
    if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD) &in , 0 , 0) == SOCKET_ERROR)
    {
        printf("WSAIoctl() failed.\n");
        wprintf(L"IOCTL failed with error %d\n", WSAGetLastError());
    if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD) &in , 0 , 0) == SOCKET_ERROR) {
            printf("Failed again\n");
            wprintf(L"IOCTL failed again with error %d\n", WSAGetLastError());
        return 1;
    }
    }
    printf("Socket set.");
    if(setsockopt(sniffer, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
    {
        printf("failed to set socket in raw mode.");
        return 0;
    }
    char *Buffer = (char *)malloc(65536); //Its Big!65536
    do
    {
        mangobyte = recvfrom(sniffer , Buffer , 2000 , 0 , 0 , 0); //Eat as much as u can

        if(mangobyte > 0)
        {
            writeCaptofile(Buffer, mangobyte);  //write the captured packet to file in pcap format
        }
        else
        {
            printf( "recvfrom() failed.\n");
        }
    }
    while ((mangobyte > 0) && (!StopSniffing));
    free(Buffer);

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

I am developing a packet sniffer based on windows raw socket on windows 7. The program captures packet from IP layer. The issue i am facing here is, Program captures all packets but some of them are captured in wrong order, for eg. for a tcp connection establishment phase, instead of getting packets in SYN , SYN-ACK, ACK order i get it as SYN, ACK, SYN-ACK. Instead of capturing ACK after SYN-ACK(from remote), pgm gets ACK before SYN-ACK packet. Same thing is happening some times during data transfer phase also. Program captures the ACK packet of a data packet before the actual data packet. If i run a wireshark in parallel, it displays properly. I am using Visual Studio 2005 as the IDE.

#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "pcap.h"
#include "MSTcpIP.h"

int main(int argc, char **argv)
{
    struct in_addr addr;
    int in, optval=1;
    struct hostent *local;
    WSADATA wsa;
    char *Buffer;

    //Initialise Winsock
    if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
    {
        printf("WSAStartup() failed.\n");
        return 1;
    }

    //Create a RAW Socket
    sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    if (sniffer == INVALID_SOCKET)
    {
        printf("Failed to create raw socket.\n");
        return 1;
    }

    memset(&dest, 0, sizeof(dest));
    memcpy(&dest.sin_addr.s_addr,argv[1], sizeof(argv[1]));
    dest.sin_family = AF_INET;
    dest.sin_port = 0;

    printf("\nBinding socket to local system and port 0 ...");
    if (bind(sniffer,(struct sockaddr *)&dest,sizeof(dest)) == SOCKET_ERROR)
    {
        printf("bind(%s) failed.\n", inet_ntoa(addr));
        return 1;
    }
    printf("Binding successful");

    //Enable this socket with the power to sniff : SIO_RCVALL is the key Receive ALL ;)
    j=1;
    printf("\nSetting socket to sniff...");
    if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD) &in , 0 , 0) == SOCKET_ERROR)
    {
        printf("WSAIoctl() failed.\n");
        wprintf(L"IOCTL failed with error %d\n", WSAGetLastError());
    if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD) &in , 0 , 0) == SOCKET_ERROR) {
            printf("Failed again\n");
            wprintf(L"IOCTL failed again with error %d\n", WSAGetLastError());
        return 1;
    }
    }
    printf("Socket set.");
    if(setsockopt(sniffer, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
    {
        printf("failed to set socket in raw mode.");
        return 0;
    }
    char *Buffer = (char *)malloc(65536); //Its Big!65536
    do
    {
        mangobyte = recvfrom(sniffer , Buffer , 2000 , 0 , 0 , 0); //Eat as much as u can

        if(mangobyte > 0)
        {
            writeCaptofile(Buffer, mangobyte);  //write the captured packet to file in pcap format
        }
        else
        {
            printf( "recvfrom() failed.\n");
        }
    }
    while ((mangobyte > 0) && (!StopSniffing));
    free(Buffer);

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

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文