From c05386db26c46b2b2d265823b3eff852021b4bea Mon Sep 17 00:00:00 2001 From: giomba Date: Tue, 24 Dec 2019 10:36:49 +0100 Subject: [PATCH] Internet Checksum computation generalized --- ipv6.h | 10 +++++++++- ipv6.ino | 8 ++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ipv6.h b/ipv6.h index c035a80..a7c7231 100644 --- a/ipv6.h +++ b/ipv6.h @@ -47,7 +47,15 @@ namespace ipv6 { /* Note: content of message may be changed */ void handleICMP(const char* src, const char* dst, const char* flow, char* message, int len); - uint16_t compute_checksum(const char* src_addr, const char* dst_addr, uint8_t next_header, const char* payload, int len); + /* Compute internet checksum. Actually it is not so straightforward: */ + uint16_t compute_checksum( + const char* src_addr, /* source IPv6 address */ + const char* dst_addr, /* destination IPv6 address */ + uint8_t next_header, /* IPv6 next header number */ + int upper_len, /* length as found in the upper layer protocol */ + const char* payload, /* IPv6 payload */ + int len /* IPv6 payload length */ + ); } #endif diff --git a/ipv6.ino b/ipv6.ino index c4ec3a7..e841aa0 100644 --- a/ipv6.ino +++ b/ipv6.ino @@ -5,7 +5,7 @@ namespace ipv6 { const IPv6Addr ALL_NODES_ADDRESS("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"); /* ff02::1 */ /******** FUNCTIONS *******/ -uint16_t compute_checksum(const char* src_addr, const char* dst_addr, uint8_t next_header, const char* payload, int len) { +uint16_t compute_checksum(const char* src_addr, const char* dst_addr, uint8_t next_header, int upper_len, const char* payload, int len) { char buffer[LEN]; uint32_t total; uint16_t* ptr; @@ -26,7 +26,7 @@ uint16_t compute_checksum(const char* src_addr, const char* dst_addr, uint8_t ne memcpy(buffer + i, src_addr, 16); i += 16; memcpy(buffer + i, dst_addr, 16); i += 16; memset(buffer + i, 0, 3); i+= 3; /* first 3 bytes always 0, because len always < 256 */ - buffer[i] = len & 0xff; i += 1; + buffer[i] = upper_len & 0xff; i += 1; memset(buffer + i, 0, 3); i += 3; /* zero, as per-standard */ buffer[i] = next_header; i += 1; @@ -115,7 +115,7 @@ void handleICMP(const char* src_addr, const char* dst_addr, const char* flow, ch memcpy(received_checksum, packet + 2, 2); memset(packet + 2, 0, 2); /* zero-checksum */ - uint16_t computed_checksum = compute_checksum(src_addr, dst_addr, NH_ICMP, packet, len); + uint16_t computed_checksum = compute_checksum(src_addr, dst_addr, NH_ICMP, len, packet, len); if (memcmp(&computed_checksum, received_checksum, 2) == 0) { /* if checksum is valid, then... */ /* Build an echo reply: @@ -124,7 +124,7 @@ void handleICMP(const char* src_addr, const char* dst_addr, const char* flow, ch *(packet) = ICMP_ECHO_REPLY_TYPE; memset(packet + 2, 0, 2); /* zero-checksum */ - uint16_t checksum = compute_checksum(src_addr, dst_addr, NH_ICMP, packet, len); + uint16_t checksum = compute_checksum(src_addr, dst_addr, NH_ICMP, len, packet, len); memcpy(packet + 2, &checksum, 2); IPv6Packet reply_packet;