pskl.us

IPv4 Checksum Routine in Perl

by 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) )) );

};


3 Comments for this entry

  • jeremy

    Will that make my internets faster?

  • John

    No, you need bigger tubes for the faster internets.

  • Yoram Stern

    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.

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!