in reply to Re: Compensate for bad inet checksum routine
in thread Compensate for bad inet checksum routine

Just noticed this...
In both the original, and my version, there seems to be some wasted logic. See comments that start with ## below.
if (length($payload)%2) { my $padded = substr $payload, 0, -1; $padded .= "\0"; $padded .= substr $payload, -1; ## above: ok, so the next to the last byte ## is guaranteed to be null since we just ## explicitly set it if (ord(substr $padded, -1) >= 128) { my $end = ord(substr $padded, -2, 1); ## ## above: now we're grabbing the next to the last ## byte, even though we already know it's a null? ## my $endend = ord(substr $padded, -1); $end--; ## now we decrement it, knowing full well it's ## going to be -1? $endend--; ###DEBUG: printf "CMPSAT = %i %i\n", $end, $endend; # if 0 before --, then -1 results in warning to pack below # -1 is in essense \xff or 255 if ($end == -1) { $end = 255 } ## ## above,of course, it's going to == -1, and thus ## at this point, always reset to 255 ## if ($endend == -1) { $endend = 255 } $padded = substr $padded, 0, -2; $padded .= CORE::pack('CC', $end, $endend); } $payload = $padded; }
It would seem then, that you could simplify all of that out, and just decrement the last byte by one?
sub prepchksum { my ($payload) = @_; printf "BEFORE = %s\n", (CORE::unpack "H*", $payload); if (length($payload)%2) { $payload =~ s#(.)$#\0$1#; printf "MID1 = %s\n", (CORE::unpack "H*", $payload); # Compensate off-by-one error if (ord(substr $payload, -1) >= 128) { $payload=~s#(.)$#pack('C',(ord($2)-1)&255)#e; } } printf "AFTER = %s\n", (CORE::unpack "H*", $payload); }
Or perhaps there's a bug somewhere, either in the 'C' implementation you based this on, or your original port?

Replies are listed 'Best First'.
Re^3: Compensate for bad inet checksum routine
by kschwab (Vicar) on Mar 29, 2013 at 17:19 UTC
    Argh. Meant to simplify by decrementing the last byte and explicity setting the the next to last byte to 255
    sub prepchksum { my ($payload) = @_; printf "BEFORE = %s\n", (CORE::unpack "H*", $payload); if (length($payload)%2) { $payload =~ s#(.)$#\0$1#; printf "MID1 = %s\n", (CORE::unpack "H*", $payload); # Compensate off-by-one error if (ord(substr $payload, -1) >= 128) { $payload=~s#(.)(.)$#pack('CC',255, (ord($2)-1)&255)#e; } } printf "AFTER = %s\n", (CORE::unpack "H*", $payload); }
Re^3: Compensate for bad inet checksum routine
by VinsWorldcom (Prior) on Mar 29, 2013 at 17:57 UTC

    You know, I thought about that and wasn't sure I had all the cases. I do appreciate you seeing it also and confirming that the logic was extra and able to be eliminated.