#include #include #include #include #include #include //Partie offset header en commentaire pour économiser les bytes sur la mémoire réservée pour le Kernel /* const unsigned short macLen = 6; //2bytes const unsigned short macSrc = macLen; //2bytes const unsigned short macDest = macLen; //2bytes const unsigned short pktType =2; //2bytes const unsigned short ethHead = macSrc+macDest+pktType; //=14 //Partie offet IP const unsigned short iPVersionAndHeaderLen = 1; const unsigned short DSF = 1; const unsigned short totalLen = 2; const unsigned short id = 2; const unsigned short offsetIP = iPVersionAndHeaderLen + DSF + totalLen + id; //=6 const unsigned short DF_offset = offsetIP + ethHead; //=20 */ #define bpf_printk(fmt, ...) \ ({ \ char ____fmt[] = fmt; \ bpf_trace_printk(____fmt, sizeof(____fmt), \ ##__VA_ARGS__); \ }) static __always_inline int checksum_ipv4(__u16* ipbuf) { // https://tools.ietf.org/html/rfc1071 __u32 sum = 0; for (int i = 0; i < sizeof(struct iphdr)/2; i++) { sum += ipbuf[i]; } sum = (sum & 0xffff) + (sum >> 16); sum = (sum & 0xffff) + (sum >> 16); return ~sum; } // @TODO: Implement https://tools.ietf.org/html/rfc1624 instead SEC("xdp_udp") int xdp_udp_func(struct xdp_md *ctx) { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; struct ethhdr *eth = data; //structure ethernet from if_ether.h struct iphdr *ip = (struct iphdr*)(eth + 1); // Check that our packet ethernet headers is big enough, ie. at least the size of Ethernet's fixed headers if((void*)ip > data_end) { return XDP_PASS; } // Check that the ethernet header declares an IPv4 packet if(eth->h_proto == bpf_htons(ETH_P_IP)) { // Check that the IP packet is big enough, ie. at least the size of IP's fixed headers if ((void*)(ip + 1) > data_end) { return XDP_PASS; } if(ip->protocol == IPPROTO_UDP) { ip->frag_off |= bpf_htons(0x4000); //Set the DF flag to 1 -> 0b 0100 0000 0000 0000 ip->check = 0; ip->check = checksum_ipv4((__u16*)ip); } } return XDP_PASS; } char _license[] SEC("license") = "GPL";