【问题标题】:C++ Sockets: Enabling Promiscuous Mode in WindowsC++ 套接字:在 Windows 中启用混杂模式
【发布时间】:2019-04-09 04:39:59
【问题描述】:

我正在尝试修改我当前的套接字程序以捕获混杂的数据包。我目前拥有的是能够正常捕获数据包。我已经看到了如何在 Linux 上执行此操作的其他答案,但我需要找到一种在 Windows 上完成此操作的方法。

这是我的代码:

int main(int argc, char const *argv[])
{
    SOCKET s;                       //The bound socket
    struct sockaddr_in server;
    int recv_len;                   //Size of received data
    char udpbuf[BUFLEN];            //A buffer for the incoming data.
    float data;                     //The data in the packet

//Create a socket
if ((s = socket(AF_INET, SOCK_RAW, 0)) == INVALID_SOCKET)
{
    printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");

//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ADDR);
server.sin_port = htons(PORT);

//Bind socket to address
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
    printf("Bind failed with error code : %d", WSAGetLastError());
    exit(EXIT_FAILURE);
}
puts("Bind done\n");

while (true)
{
    //Block statment. Code will wait until it detect packets.
    if ((recv_len = recvfrom(s, udpbuf, BUFLEN, 0, 0, 0)) == SOCKET_ERROR)
    {
        printf("recvfrom() failed with error code : %d", WSAGetLastError());
        exit(EXIT_FAILURE);
    }

return 0;
}

【问题讨论】:

  • 为什么这个标签是“C++”?这段代码没有任何 C++,它是直接的 C。
  • 对不起。这一切都是从.cpp 文件开始的,我的目标是编写一个 C++ 程序。我会更新标签。

标签: c windows sockets networking


【解决方案1】:

要在 Windows 上将套接字置于混杂模式,您需要调用 WSAIoCtl() 以向套接字发出 SIO_RCVALL control code

int main(int argc, char const *argv[])
{
    WSADATA wsa;
    SOCKET s;                       //The bound socket
    struct sockaddr_in server;
    int recv_len;                   //Size of received data
    char udpbuf[BUFLEN];            //A buffer for the incoming data.

    //Initialize Winsock
    int err = WSAStartup(MAKEWORD(2,0), &wsa);
    if (err != 0)
    {
        printf("Could not initialize Winsock : %d", err);
        exit(EXIT_FAILURE);
    }

    //Create a socket
    if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d", WSAGetLastError());
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    printf("Socket created.\n");

    //Prepare the sockaddr_in structure
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(ADDR);
    server.sin_port = htons(PORT);

    //Bind socket to address
    if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d", WSAGetLastError());
        closesocket(s);
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    puts("Bind done\n");

    // enable promiscuous mode
    DWORD dwValue = RCVALL_ON;
    DWORD dwBytesReturned = 0;
    if (WSAIoctl(s, SIO_RCVALL, &dwValue, sizeof(dwValue), NULL, 0, &dwBytesReturned, NULL, NULL) == SOCKET_ERROR)
    {
        printf("Ioctl failed with error code : %d", WSAGetLastError());
        closesocket(s);
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    puts("Ioctl done\n");

    while (true)
    {
        //Block statment. Code will wait until it detect packets.
        if ((recv_len = recvfrom(s, udpbuf, BUFLEN, 0, 0, 0)) == SOCKET_ERROR)
        {
            printf("recvfrom() failed with error code : %d", WSAGetLastError());
            closesocket(s);
            WSACleanup();
            exit(EXIT_FAILURE);
        }
    }

    closesocket(s);
    WSACleanup();

    return 0;
}

另外,Microsoft 也有一个单独的Network Monitor API,它允许您在完全不使用 Winsock 的情况下监控和捕获网络流量。

【讨论】:

  • 谢谢,我正在尝试测试您的代码,但我不知道如何通过 include 让 Visual Studios 识别 RCVALL_ONSIO_RCVALL。我查看了文档,他们也没有提到它。
  • @CrystalPritzker 是的,确实如此。它位于我链接到的页面底部:“Header Mstcpip.h
【解决方案2】:

我建议您使用 winpcap 库。请参阅 www.winpcap.org。 他们有关于如何做到这一点的综合文档和示例: https://www.winpcap.org/docs/docs_412/html/group__wpcap__tut3.html

例如Wireshark 在 windows 上使用 winpcap。

【讨论】:

  • 谢谢。我能够在 Wireshark 中看到数据包,所以这可能会奏效。
  • 看来pcap.h 使用sys/time.h,这在Windows 中不可用。
  • 嗯。之前已经可以用了,winpcap是专门的windows库。在第一个 ool 上,您的项目中似乎没有定义“WIN32”。导致包含 sys/time.h 的行如下所示: #if defined(WIN32) .... #else /* UNX */ #include #include #endif / WIN32/MSDOS/UN*X */
猜你喜欢
  • 2011-08-29
  • 1970-01-01
  • 2013-09-06
  • 2010-11-22
  • 2014-04-27
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多