Last active
March 21, 2023 21:06
-
-
Save aidvu/d83bd659fe962c49c7eb510ad5eebcf3 to your computer and use it in GitHub Desktop.
Modify ping reply TTL with XDP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
KDIR ?= /lib/modules/$(shell uname -r) | |
SDIR ?= $(KDIR)/source | |
CLANG ?= clang | |
LLC ?= llc | |
#ARCH := $(subst x86_64,x86,$(shell arch)) | |
ARCH := x86 | |
BIN := modify-ping-ttl.o | |
CLANG_FLAGS = -I. -I$(SDIR)/arch/$(ARCH)/include \ | |
-I$(SDIR)/arch/$(ARCH)/include/generated \ | |
-I$(SDIR)/include \ | |
-I$(SDIR)/arch/$(ARCH)/include/uapi \ | |
-I$(SDIR)/arch/$(ARCH)/include/generated/uapi \ | |
-I$(SDIR)/include/uapi \ | |
-I$(SDIR)/include/generated/uapi \ | |
-I$(SDIR)/tools/testing/selftests/bpf/ \ | |
-include $(SDIR)/include/linux/kconfig.h \ | |
-I $(KDIR)/build/include/ \ | |
-I $(KDIR)/build/arch/$(ARCH)/include/generated/ \ | |
-D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \ | |
-D__TARGET_ARCH_$(ARCH) -Wno-compare-distinct-pointer-types \ | |
-Wno-gnu-variable-sized-type-not-at-end \ | |
-Wno-address-of-packed-member -Wno-tautological-compare \ | |
-Wno-unknown-warning-option \ | |
-O2 -emit-llvm | |
all: $(BIN) | |
clean: | |
rm -f *.o | |
modify-ping-ttl.o: modify-ping-ttl.c | |
$(CLANG) $(CLANG_FLAGS) -c $< -o - | \ | |
$(LLC) -march=bpf -mcpu=$(CPU) -filetype=obj -o $@ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define KBUILD_MODNAME "xdp_main" | |
#include <linux/bpf.h> | |
#include <linux/if_ether.h> | |
#include <linux/in.h> | |
#include <linux/ip.h> | |
#include <linux/udp.h> | |
#include <linux/icmp.h> | |
#include "bpf_helpers.h" | |
#define SEC(NAME) __attribute__((section(NAME), used)) | |
#define bpf_printk(fmt, ...) ({char ____fmt[] = fmt; bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); }) | |
#define proper_htons(x) ((__be16)___constant_swab16((x))) | |
SEC("prog") | |
int xdp_main(struct xdp_md *ctx) | |
{ | |
void *data_end = (void *)(uintptr_t)ctx->data_end; | |
void *data = (void *)(uintptr_t)ctx->data; | |
struct ethhdr *eth = data; | |
uint64_t nh_off = sizeof(*eth); | |
/* sanity check needed by the eBPF verifier */ | |
if (data + nh_off > data_end) { | |
return XDP_PASS; | |
} | |
uint16_t h_proto = eth->h_proto; | |
int i; | |
/* Handle double VLAN tagged packet. See https://en.wikipedia.org/wiki/IEEE_802.1ad */ | |
for (i = 0; i < 2; i++) { | |
if (h_proto == proper_htons(ETH_P_8021Q) || h_proto == proper_htons(ETH_P_8021AD)) { | |
struct vlan_hdr *vhdr; | |
vhdr = data + nh_off; | |
nh_off += sizeof(struct vlan_hdr); | |
if (data + nh_off > data_end) { | |
return XDP_PASS; | |
} | |
h_proto = vhdr->h_vlan_encapsulated_proto; | |
} | |
} | |
if (h_proto == proper_htons(ETH_P_IP)) { | |
struct iphdr *iph = data + nh_off; | |
struct icmphdr *icmph = data + nh_off + sizeof(struct iphdr); | |
if (icmph + 1 > (struct icmphdr*)data_end) { | |
return XDP_PASS; | |
} | |
if (iph->protocol != IPPROTO_ICMP) { | |
return XDP_PASS; | |
} | |
if (icmph->type != ICMP_ECHOREPLY) { | |
return XDP_PASS; | |
} | |
if (iph->ttl) { | |
/* save the old TTL to recalculate the checksum */ | |
uint16_t *ttlproto = (uint16_t *)&iph->ttl; | |
uint16_t old_ttlproto = *ttlproto; | |
/* set the TTL to a pseudorandom number 1 < x < TTL */ | |
iph->ttl = bpf_get_prandom_u32() % iph->ttl + 1; | |
/* recalculate the checksum; otherwise, the IP stack will drop it */ | |
csum_replace2(&iph->check, old_ttlproto, *ttlproto); | |
// Example of logging to /sys/kernel/debug/tracing/trace | |
bpf_printk("Should be new TTL"); | |
} | |
} | |
return XDP_PASS; | |
} | |
char _license[] SEC("license") = "GPL"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment