minor checksum changes
main change is checksum of zero buffer is now 0 instead of
the equivalent, but technically incorrect 0xFFFF.
Test: TreeHugger
Bug: 265591307
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I1a8b0ace704009f82d3b7ad1c299bf8a6d8964d8
diff --git a/staticlibs/native/ip_checksum/checksum.c b/staticlibs/native/ip_checksum/checksum.c
index 04217a7..5641fad 100644
--- a/staticlibs/native/ip_checksum/checksum.c
+++ b/staticlibs/native/ip_checksum/checksum.c
@@ -32,20 +32,16 @@
* len - length of data
*/
uint32_t ip_checksum_add(uint32_t current, const void* data, int len) {
- uint32_t checksum = current;
- int left = len;
const uint16_t* data_16 = data;
- while (left > 1) {
- checksum += *data_16;
+ while (len >= 2) {
+ current += *data_16;
data_16++;
- left -= 2;
+ len -= 2;
}
- if (left) {
- checksum += *(uint8_t*)data_16;
- }
+ if (len) current += *(uint8_t*)data_16; // assumes little endian!
- return checksum;
+ return current;
}
/* function: ip_checksum_fold
@@ -54,9 +50,8 @@
* returns: the folded checksum in network byte order
*/
uint16_t ip_checksum_fold(uint32_t temp_sum) {
- while (temp_sum > 0xffff) {
- temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
- }
+ temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
+ temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
return temp_sum;
}
@@ -75,12 +70,7 @@
* len - length of data
*/
uint16_t ip_checksum(const void* data, int len) {
- // TODO: consider starting from 0xffff so the checksum of a buffer entirely consisting of zeros
- // is correctly calculated as 0.
- uint32_t temp_sum;
-
- temp_sum = ip_checksum_add(0, data, len);
- return ip_checksum_finish(temp_sum);
+ return ip_checksum_finish(ip_checksum_add(0xFFFF, data, len));
}
/* function: ipv6_pseudo_header_checksum
@@ -92,7 +82,6 @@
uint32_t ipv6_pseudo_header_checksum(const struct ip6_hdr* ip6, uint32_t len, uint8_t protocol) {
uint32_t checksum_len = htonl(len);
uint32_t checksum_next = htonl(protocol);
-
uint32_t current = 0;
current = ip_checksum_add(current, &(ip6->ip6_src), sizeof(struct in6_addr));
@@ -109,11 +98,8 @@
* len - the transport length (transport header + payload)
*/
uint32_t ipv4_pseudo_header_checksum(const struct iphdr* ip, uint16_t len) {
- uint16_t temp_protocol, temp_length;
-
- temp_protocol = htons(ip->protocol);
- temp_length = htons(len);
-
+ uint16_t temp_protocol = htons(ip->protocol);
+ uint16_t temp_length = htons(len);
uint32_t current = 0;
current = ip_checksum_add(current, &(ip->saddr), sizeof(uint32_t));
@@ -135,7 +121,7 @@
// Algorithm suggested in RFC 1624.
// http://tools.ietf.org/html/rfc1624#section-3
checksum = ~checksum;
- uint16_t folded_sum = ip_checksum_fold(checksum + new_hdr_sum);
+ uint16_t folded_sum = ip_checksum_fold(new_hdr_sum + checksum);
uint16_t folded_old = ip_checksum_fold(old_hdr_sum);
if (folded_sum > folded_old) {
return ~(folded_sum - folded_old);
diff --git a/staticlibs/native/ip_checksum/checksum.h b/staticlibs/native/ip_checksum/checksum.h
index 868217c..87393c9 100644
--- a/staticlibs/native/ip_checksum/checksum.h
+++ b/staticlibs/native/ip_checksum/checksum.h
@@ -12,11 +12,8 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * checksum.h - checksum functions
*/
-#ifndef __CHECKSUM_H__
-#define __CHECKSUM_H__
+#pragma once
#include <netinet/ip.h>
#include <netinet/ip6.h>
@@ -30,5 +27,3 @@
uint32_t ipv4_pseudo_header_checksum(const struct iphdr* ip, uint16_t len);
uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum);
-
-#endif /* __CHECKSUM_H__ */