1

我正在尝试使用与 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);
}
4

1 回答 1

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;
}
于 2013-06-04T21:06:35.023 回答