2013-10-05 17 views
0

每個人。我使用WinDivert開發了一個ICMP數據包發送器。 192.168.1.232是我的機器,192.168.1.158是遠程機器。所有函數都會返回成功,但是我無法使用Wireshark在遠程計算機上看到ICMP數據包。這段代碼有什麼問題嗎?謝謝。WinDivert發送自建的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; 
} 

回答

1

一個問題是,你需要通過DivertHelperParseIPv4Address()返回到網絡字節順序,例如地址轉換與htonl()。

將來,您還可以嘗試使用WireShark調試出站數據包。

+0

是的,這是問題,thx! – hsluoyz