Question

everyone. I have developed an ICMP packet sender using WinDivert. 192.168.1.232 is my machine and 192.168.1.158 is the remote machine. All functions return success, but I can't see the ICMP packet in the remote machine using Wireshark. Is there anything wrong with this code? Thx.

#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;
}
Was it helpful?

Solution

One issue is that you need to convert the addresses returned by DivertHelperParseIPv4Address() into network byte order, e.g. with htonl().

In future you can also try debugging outbound packets using WireShark.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top