2013-06-04 145 views
1

我想校驗icmp數據包使用tcp和udp相同的技術,但它會得到錯誤的校驗和,你能告訴我我的問題在哪裏嗎?ICMP校驗和錯誤

 ICMP_HEADER *icmpheader = new ICMP_HEADER; 
     memcpy(icmpheader,ICMPHeader,sizeof(ICMP_HEADER)); 
     icmpheader->Checksum = 0; 

     PSEUDO_HEADER *psheader = new PSEUDO_HEADER; 
     memcpy(&psheader->daddr, &IPHeader->DestinationAddress, sizeof(UINT)); 
     memcpy(&psheader->saddr, &IPHeader->SourceAddress, sizeof(UINT)); 
     psheader->protocol = IPHeader->Protocol; 
     psheader->length = htons((USHORT)(sizeof(ICMP_HEADER) + ICMPDataSize)); 
     psheader->zero = 0x0000; 

     UINT packet_size = sizeof(ICMP_HEADER) + ICMPDataSize + sizeof(PSEUDO_HEADER); 
     packet_size = packet_size + ((packet_size%2)*2); 
     UCHAR *icmppacket = (UCHAR*)malloc(packet_size); 

     memset(icmppacket,0, packet_size); 
     memcpy(icmppacket, psheader, sizeof(PSEUDO_HEADER)); 
     memcpy(&icmppacket[sizeof(PSEUDO_HEADER)], icmpheader,sizeof(ICMP_HEADER)); 
     memcpy(&icmppacket[sizeof(PSEUDO_HEADER) + sizeof(ICMP_HEADER)],ICMPData,ICMPDataSize); 


     if (GlobalChecksum((USHORT*)icmppacket,packet_size) != ICMPHeader->Checksum) 
     { 
      isMalformed = true; 
      PacketError = PACKET_ICMP_CHECKSUM; 
     } 

     USHORT cPacket::GlobalChecksum(USHORT *buffer, UINT length) 
{ 
    register int sum = 0; 
    USHORT answer = 0; 
    register USHORT *w = buffer; 
    register int nleft = length; 

    while(nleft > 1){ 
    sum += *w++; 
    nleft -= 2; 
    } 

    sum = (sum >> 16) + (sum & 0xFFFF); 
    sum += (sum >> 16); 
    answer = ~sum; 
    return(answer); 
} 
+0

如果你真的重置'icmpheader->校驗= 0'爲分組校驗? Afaik,只應該清除ICMP校驗和(其中不包含僞頭部) –

+0

您可以嘗試使用unsigned int sum,可能是由於有符號的無符號轉換。但可能還有其他的東西。 – praks411

回答

1

解決它通過消除僞報頭和計算ICMP報頭和ICMP數據僅供

ICMP_HEADER *icmpheader = new ICMP_HEADER; 
memcpy(icmpheader,ICMPHeader,sizeof(ICMP_HEADER)); 
icmpheader->Checksum = 0x0000; 

UINT packet_size = sizeof(ICMP_HEADER) + ICMPDataSize; 
packet_size = packet_size + ((packet_size%2)*2); 
UCHAR *icmppacket = (UCHAR*)malloc(packet_size); 

memset(icmppacket,0, packet_size); 
memcpy(icmppacket, icmpheader,sizeof(ICMP_HEADER)); 
memcpy(&icmppacket[sizeof(ICMP_HEADER)],ICMPData,ICMPDataSize); 

if (GlobalChecksum((USHORT*)icmppacket,packet_size) != ICMPHeader->Checksum) 
{ 
    isMalformed = true; 
    PacketError = PACKET_ICMP_CHECKSUM; 
} 
+0

那個幫了我很多。你知道這是爲什麼嗎?我無法在規格中的任何地方找到它... –

+0

不幸的是:/ –