Re: answer

#5575

heilong
Participant

Try it. It is universal function.

p – pointer to begin of header.
Size – size of header in words.
Attention: Field Checksum must be = 0 before call function.

function Checksum(p: PWORD; Size: word): WORD;
var
i: Integer;
Sum: DWORD;
begin
Sum := 0;
for i := 0 to Size – 1 do
begin
Sum := Sum + ntohs(p^);
inc(p);
end;
while (Sum shr 16) > 0 do
Sum := (Sum and $FFFF) + (Sum shr 16);
Sum := not Sum;
Result := Sum;
end;

Examples:
1. Calc checksum for IPHeader. For uses without IPOptions.

IPHeader.Checksum := 00;
IPHeader.Checksum := htons(Checksum(Pword(IPHeader), sizeof(IP_HDR) div 2));

2. Calc checksum for ICMPHeader.
IcmpHeader.Checksum := 00;
IcmpHeader.Checksum := htons(Checksum(Pword(IcmpHeader),
(sizeof(ICMP_HDR)+Length(Data)) div 2));

Don`t forget call htons for result of function Checksum.
Sorry for my English.