You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
File pnet_packet/src/udp.rs contains routines ipv4_chekcsum() and ipv4_checksum_adv(), which are supposed to calculate the correct UDP checksum to the UDP header. Also, there is a unit test function "udp_header_ipv4_test()", which is apparently meant to show the correct use of function ipv4_checksum().
However, if a user calculates UDP checksums as shown in udp_header_ipv4_test(), the result is wrong, with probability of 0.000015. Specifically, routine util::ipv4_checksum() calculates the mathematically correct TCP checksum, which is in range 0..0xFFFE, inclusive. However, RFC768 says that UDP checksum has a special rule that differs from all other checksum calculations: if "the computed checksum is zero, it is transmitted as all ones", so a zero value (whose probability is 1/65535), must be changed to 0xFFFF before storing to UDP header. The algorithm, as shown, fails to do this change.
The result of this bug is hard to reveal, because if the sender sets the checksum to zero (as mentioned, this happens with probability 1/65535), the receiver is unlikely to notice the error, because, for the receiver, zero checksum is an indication that the sender has refused to calculate the checksum, and so the receiver omits the checksum calculation and accepts the UDP packet. So the net result is that transmissions errors, which are meant to be detected with checksum, are not detected.
Also, a similar bug is in documentation of routine pnet::util::ipv4_checksum. That routine is meant for "UDP and TCP", but the user is not warned against the special case of zero checksum.
A fix should be simple:
let mut checksum = ipv4_checksum(. . .);
if checksum == 0 {
// UDP rules require that zero is represented as follows:
checksum = 0xFFFF;
}
udp_header.set_checksum(checksum);
And further, the routines for IPv6 appear to have the same issues.
The text was updated successfully, but these errors were encountered:
File pnet_packet/src/udp.rs contains routines ipv4_chekcsum() and ipv4_checksum_adv(), which are supposed to calculate the correct UDP checksum to the UDP header. Also, there is a unit test function "udp_header_ipv4_test()", which is apparently meant to show the correct use of function ipv4_checksum().
However, if a user calculates UDP checksums as shown in udp_header_ipv4_test(), the result is wrong, with probability of 0.000015. Specifically, routine util::ipv4_checksum() calculates the mathematically correct TCP checksum, which is in range 0..0xFFFE, inclusive. However, RFC768 says that UDP checksum has a special rule that differs from all other checksum calculations: if "the computed checksum is zero, it is transmitted as all ones", so a zero value (whose probability is 1/65535), must be changed to 0xFFFF before storing to UDP header. The algorithm, as shown, fails to do this change.
The result of this bug is hard to reveal, because if the sender sets the checksum to zero (as mentioned, this happens with probability 1/65535), the receiver is unlikely to notice the error, because, for the receiver, zero checksum is an indication that the sender has refused to calculate the checksum, and so the receiver omits the checksum calculation and accepts the UDP packet. So the net result is that transmissions errors, which are meant to be detected with checksum, are not detected.
Also, a similar bug is in documentation of routine pnet::util::ipv4_checksum. That routine is meant for "UDP and TCP", but the user is not warned against the special case of zero checksum.
A fix should be simple:
And further, the routines for IPv6 appear to have the same issues.
The text was updated successfully, but these errors were encountered: