0

每个人。我已经使用 WinDivert 开发了一个 ICMP 数据包发送器。192.168.1.232 是我的机器,192.168.1.158 是远程机器。所有函数都返回成功,但我在使用 Wireshark 的远程机器上看不到 ICMP 数据包。这段代码有什么问题吗?谢谢。

#include <winsock2.h>
#include <divert.h>
#include <stdio.h>

#define MAXBUF  0xFFFF

int main()
{
    HANDLE handle;          // Divert handle
    DIVERT_ADDRESS addr;    // Packet address
    char packet[MAXBUF];    // Packet buffer
    UINT packet_len;
    UINT local_ip;
    UINT remote_ip;

    addr.IfIdx = 0;
    addr.SubIfIdx = 0;
    addr.Direction = DIVERT_DIRECTION_OUTBOUND;

    DivertHelperParseIPv4Address("192.168.1.232", &local_ip);
    DivertHelperParseIPv4Address("192.168.1.158", &remote_ip);

    PDIVERT_IPHDR ip_header = (PDIVERT_IPHDR) packet;
    ip_header->HdrLength = 5;
    ip_header->Version = 4;
    ip_header->TOS = 0;
    ip_header->Length = htons(sizeof(DIVERT_IPHDR) + sizeof(DIVERT_ICMPHDR) + 32);
    ip_header->Id = 0x1234;
    DIVERT_IPHDR_SET_FRAGOFF(ip_header, 0);
    DIVERT_IPHDR_SET_MF(ip_header, 0);
    DIVERT_IPHDR_SET_DF(ip_header, 0);
    DIVERT_IPHDR_SET_RESERVED(ip_header, 0);
    ip_header->TTL = 64;
    ip_header->Protocol = 1; //ICMP
    ip_header->Checksum = 0;
    ip_header->SrcAddr = local_ip;
    ip_header->DstAddr = remote_ip;

    PDIVERT_ICMPHDR icmp_header = (PDIVERT_ICMPHDR) ((PBYTE) ip_header + sizeof(DIVERT_IPHDR));
    icmp_header->Type = 8;
    icmp_header->Code = 0;
    icmp_header->Checksum = 0;
    icmp_header->Body = htonl(0x00010012);

    PBYTE icmp_data = (PBYTE) icmp_header + sizeof(DIVERT_ICMPHDR);
    for (int i = 0; i < 32; i ++)
    {
        *icmp_data = 'a' + i % 23;
        icmp_data ++;
    }

    packet_len = sizeof(DIVERT_IPHDR) + sizeof(DIVERT_ICMPHDR) + 32;
    DivertHelperCalcChecksums((PVOID) packet, packet_len, 0);

    handle = DivertOpen("true", (DIVERT_LAYER)0, 0, 0);   // Open some filter
    if (handle == INVALID_HANDLE_VALUE)
    {
        // Handle error
        exit(1);
    }

//  // Read packet.
//  if (!DivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
//  {
//      fprintf(stderr, "warning: failed to read packet (%d)\n",
//          GetLastError());
//      DivertClose(handle);
//      return 0;
//  }

    // Send packet.
    if (!DivertSend(handle, packet, packet_len, &addr, NULL))
    {
        // Handle send error
        BOOL a = DivertSend(handle, (PVOID) packet, packet_len, &addr, NULL);
        DivertClose(handle);
        DWORD dwError = GetLastError();
        printf("DivertSend Error.\n");
    }
    else
    {
        DivertClose(handle);
        printf("DivertSend Success.\n");
    }

    return 0;
}
4

1 回答 1

1

一个问题是您需要将 DivertHelperParseIPv4Address() 返回的地址转换为网络字节顺序,例如使用 htonl()。

将来您还可以尝试使用WireShark调试出站数据包。

于 2013-10-06T06:18:51.630 回答