#ifndef __IP_HELPER_H__ #define __IP_HELPER_H__ #include #include #include #include #include /** * IP checksum calculation. * Following RFC 1071. * In essence 1's complement of 16-bit groups. * Taken from my own library https://github.com/h3xduck/RawTCP_Lib/blob/master/src/packet.c */ static __always_inline unsigned short checksum(unsigned short *addr, int nbytes){ long sum = 0; unsigned short checksum; while(nbytes>1){ sum += (unsigned short) *addr++; nbytes -= 2; } if(nbytes>0){ sum +=htons((unsigned char)*addr); } while (sum>>16){ sum = (sum & 0xffff) + (sum >> 16); } checksum = ~sum; return checksum; } static __always_inline __u16 csum_fold_helper(__u32 csum) { //return ~((csum & 0xffff) + (csum >> 16)); //The following solves some errors where the last summatory overflows #pragma unroll for (int i = 0; i < 4; i ++) { if (csum >> 16){ csum = (csum & 0xffff) + (csum >> 16); } } return ~csum; } /** * IP checksum calculation. * Following RFC 1071, using BPFs.* */ static __always_inline void ipv4_csum(void *data_start, int data_size, __u32 *csum) { //WITH EBPF HELPERS bpf_printk("csum: %u for data_start %u, data_size %i\n", *csum, data_start, data_size); unsigned char* p = (unsigned char*) data_start; for(int ii = 0; ii<20; ii++){ bpf_printk("B%i: %x\n", ii, p[ii]); } *csum = bpf_csum_diff(0, 0, data_start, data_size, *csum); *csum = csum_fold_helper(*csum); } #endif