IPv4 Checksum Routine in Perl
by Eric on Feb.09, 2008, under Code
Here’s a subroutine that I wrote a few years ago to calculate IPv4 checksums.
sub ipchecksum {
# Calculate the Internet Protocol checksum of the given hex string
# pskl.us January 2006
my $sum=0;
my $i=0;
my $word;
for ($i=0; $i<length($_[0]); $i=$i+4) {
$word=substr($_[0],$i,4);
if ( length($word) eq 2 ) { $word=$word.’00’; };
$sum=$sum + hex $word;
}
return sprintf(“%04X”, 65535 – (( hex substr(sprintf(“%X”, $sum), -4,4) ) +
( hex substr(sprintf(“%X”, $sum), -8,4) )) );
};
February 9th, 2008 on 9:48 am
Will that make my internets faster?
February 19th, 2008 on 12:53 pm
No, you need bigger tubes for the faster internets.
March 1st, 2011 on 9:17 am
Hi.
Thanks for the code BUT you have a bug.
There is the scenario that the sum of the carry is greater than 65535.
In this case your function gives wrong result.
for example assume the header:
my $dw0 = “45ff0034” ;
my $dw1 = “a6199362” ;
my $dw2 = “ff110000” ;
my $dw3 = “0b5097c5” ;
my $dw4 = “7fad5e7c” ;
my $pkt = $dw0 . $dw1. $dw2 . $dw3 . $dw4 ;
my $checksum = ipchecksum( $pkt) ;
printf “ipv4 checksum= $checksum\n” ;
The $sum will be 0x3fffd
Your function will give checksum of 0xffff
while the correct checksum is 0xfffe .
Regards.