/********************************************************** Checksum.h provide checksum functions using 1's complement for both IP header checksum and ICMP checksum ***********************************************************/ #include "sr_checksum.h" /* * Author: Denny Chen Dai * * Compute checksum for outgoing packet, store checksum field * * base: the beginning of the data chunck * checksum: the field for storing 16bit checksum * packet_size: number of bytes (8bit) */ void sr_checksum_send(uint16_t *base, uint16_t *checksum, int packet_size){ /*puts("****sr_checksum_send****");*/ uint16_t *pw = base, *pb = base; uint32_t sum = 0; int i; pw = base; /*first zero out checksum field*/ *checksum = 0x00; /*compute sum*/ for(i=0; i< packet_size / sizeof(uint16_t); i++){ sum = sum + *pw; pw++; } /*even size handling*/ if(packet_size % 2 != 0){ puts("odd numbr length..."); uint8_t *p = (uint8_t *)pw; p++; *p = 0x00; sum = sum + *pw; } /*printf(" Check sum: %08X \n", sum);*/ pb = (uint16_t*)∑ uint16_t high = *pb; pb++; uint16_t low = *pb; uint16_t check = low + high; *checksum = ~check; /* printf("Check sum : %04X \n", *checksum);*/ } /* * Author: Denny Chen Dai * Perform error checksum on receiving packet * * base: the base pointer of the packet field * packet_size: number of bytes * Return: if no error, return 1, else return 0 */ int sr_checksum_receive(uint16_t *base, int packet_size){ /*puts("****sr_checksum_receive****");*/ uint16_t *pw = base, *pb = base; uint32_t sum = 0; int i; pw = base; /*compute sum*/ for(i=0; i< packet_size / sizeof(uint16_t); i++){ sum = sum + *pw; pw++; } /*handle even size*/ if(packet_size % 2 != 0){ puts("odd numbr length..."); uint8_t *p = (uint8_t *)pw; p++; *p = 0x00; sum = sum + *pw; } /*printf(" Check sum: %08X \n", sum);*/ pb = (uint16_t*)∑ uint16_t high = *pb; pb++; uint16_t low = *pb; uint16_t check_sum = low + high; /*printf("Check sum : %04X \n", check_sum);*/ if(check_sum == 0xFFFF) return 1; else return 0; }