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.
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;
}
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.