Internet Checksum computation generalized

This commit is contained in:
giomba 2019-12-24 10:36:49 +01:00
parent 3eb51a7442
commit c05386db26
2 changed files with 13 additions and 5 deletions

10
ipv6.h
View File

@ -47,7 +47,15 @@ namespace ipv6 {
/* Note: content of message may be changed */ /* Note: content of message may be changed */
void handleICMP(const char* src, const char* dst, const char* flow, char* message, int len); 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 #endif

View File

@ -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 */ const IPv6Addr ALL_NODES_ADDRESS("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"); /* ff02::1 */
/******** FUNCTIONS *******/ /******** 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]; char buffer[LEN];
uint32_t total; uint32_t total;
uint16_t* ptr; 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, src_addr, 16); i += 16;
memcpy(buffer + i, dst_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 */ 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 */ memset(buffer + i, 0, 3); i += 3; /* zero, as per-standard */
buffer[i] = next_header; i += 1; 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); memcpy(received_checksum, packet + 2, 2);
memset(packet + 2, 0, 2); /* zero-checksum */ 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... */ if (memcmp(&computed_checksum, received_checksum, 2) == 0) { /* if checksum is valid, then... */
/* Build an echo reply: /* 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; *(packet) = ICMP_ECHO_REPLY_TYPE;
memset(packet + 2, 0, 2); /* zero-checksum */ 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); memcpy(packet + 2, &checksum, 2);
IPv6Packet reply_packet; IPv6Packet reply_packet;