Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the NetPacket CPAN distribution.

Report information
The Basics
Id: 12275
Status: resolved
Priority: 0/
Queue: NetPacket

People
Owner: yanick+cpan [...] babyl.dyndns.org
Requestors: hoagland [...] sourceforge.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: Checksum bug with odd-length packet (e.g., odd-length TCP frame)
For NetPacket::in_cksum(), a special case is made for "packets" that are of odd length. However, what that special case does it not quite correct. This is what is there now: if($count == 1) { $chk += unpack("C", substr($packet, $plen -1, 1)); } However, the odd length packets are padded with zeros *at the end*, so the 16-bit quantity being added here should have the last octet as the upper 8 bits and a zero as the lower 8 bits, instead of the other way around. This should fix that: if($count == 1) { $chk += (unpack("C", substr($packet, $plen -1, 1)) << 8); } There are probably other places where this manifests iteself, but this is apparent when encoding a TCP packet where the payload length is odd.
From: kob <at> newtec dot belgium
For TCP the header will be padded with 00 if an odd number. For IP this is not the case. The current chechsum function is correct. To correct the TCP Checksum problem following needs to be changed: In file TCP.pm. $packet = pack('a4a4nnnnNNnnnna*a*', $src_ip,$dest_ip,$proto,$tcplen, $self->{src_port}, $self->{dest_port}, $self->{seqnum}, $self->{acknum}, $tmp, $self->{winsize}, $zero, $self->{urg}, $self->{options},$self->{data}); $packet .= "\x00" if length($packet) % 2; $self->{cksum} = NetPacket::htons(NetPacket::in_cksum($packet)); On Wed Apr 13 17:50:49 2005, guest wrote: Show quoted text
> For NetPacket::in_cksum(), a special case is made for "packets" that > are of odd length. However, what that special case does it not > quite correct. > > This is what is there now: > if($count == 1) { > $chk += unpack("C", substr($packet, $plen -1, 1)); > } > > However, the odd length packets are padded with zeros *at the end*, so > the 16-bit quantity being added here should have the last octet as > the upper 8 bits and a zero as the lower 8 bits, instead of the > other way around. This should fix that: > if($count == 1) { > $chk += (unpack("C", substr($packet, $plen -1, 1)) << 8); > } > > There are probably other places where this manifests iteself, but this > is apparent when encoding a TCP packet where the payload length is > odd.
From: krisodb [...] gmail.com
I made a simular fix for UDP checksum: @@ -146,14 +146,15 @@ sub checksum { my ($proto); $zero = 0; - $proto = NetPacket::IP::IP_PROTO_UDP; - + $proto = 17; + my $src_ip = gethostbyname($self->{src_ip}); + my $dest_ip = gethostbyname($self->{dest_ip}); # Pack pseudo-header for udp checksum - $packet = pack('a4a4nnnnnna*', - $self->{src_ip},$self->{dest_ip},$proto,$self->{len}, + $packet = pack('a4a4CCnnnnna*', + $src_ip ,$dest_ip,$zero,$proto,$self->{len}, $self->{src_port}, $self->{dest_port}, $self->{len},$zero,$self->{data}); - + $packet .= "\x00" if length($packet) % 2; $self->{cksum} = NetPacket::htons(NetPacket::in_cksum($packet)); } $
fixed in v0.41.1