diff --git a/README.md b/README.md new file mode 100644 index 0000000..2143087 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# ebpf-sandbox + +[ebpf-tutorial](https://github.com/dio/ebpf-tutorial) diff --git a/dropworld/dropworld.c b/dropworld/dropworld.c index 1b98ec7..ce391a9 100644 --- a/dropworld/dropworld.c +++ b/dropworld/dropworld.c @@ -3,7 +3,7 @@ SEC("xdp") int xdp_drop(struct xdp_md *ctx) { - return XDP_DROP; // Drop all packets + return XDP_PASS; // Drop all packets } char LICENSE[] SEC("license") = "GPL"; diff --git a/flake.nix b/flake.nix index 4815e96..3ad43a4 100644 --- a/flake.nix +++ b/flake.nix @@ -11,7 +11,11 @@ pkgs = inputs.nixpkgs.legacyPackages.${system}; in { - packages.dropworld = pkgs.callPackage ./dropworld {}; + packages = { + dropworld = pkgs.callPackage ./dropworld {}; + tcpfilter = pkgs.callPackage ./tcpfilter {}; + }; + devShells.default = pkgs.mkShell { buildInputs = with pkgs; [bpftools bpftop]; }; diff --git a/tcpfilter/default.nix b/tcpfilter/default.nix new file mode 100644 index 0000000..93140ea --- /dev/null +++ b/tcpfilter/default.nix @@ -0,0 +1,16 @@ +{clangStdenv, libbpf, ...}: clangStdenv.mkDerivation { + name = "tcpfilter"; + src = ./.; + hardeningDisable = [ "stackprotector" "zerocallusedregs" ]; + dontFixup = true; + buildInputs = [ libbpf ]; + + buildPhase = '' + clang -O2 -target bpf -g -c tcpfilter.c -o tcpfilter.o + ''; + + installPhase = '' + mkdir $out + cp tcpfilter.o $out + ''; +} diff --git a/tcpfilter/tcpfilter.c b/tcpfilter/tcpfilter.c new file mode 100644 index 0000000..28562c7 --- /dev/null +++ b/tcpfilter/tcpfilter.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include +#include + +SEC("xdp") +int isTCP( struct xdp_md *ctx ) { + void *data_end = (void *)(long) ctx->data_end; + void *data_begin = (void *)(long) ctx->data; + struct ethhdr* eth = data_begin; + + // Check packet's size + if(eth + 1 > data_end) + return XDP_PASS; + + // Check if Ethernet frame has IPv4 packet + if (eth->h_proto == bpf_htons( ETH_P_IP )) { + struct iphdr *ipv4 = (struct iphdr *)( ((void*)eth) + ETH_HLEN ); + + if(ipv4 + 1 > data_end) + return XDP_PASS; + + // Check if IPv4 packet contains a TCP segment + if (ipv4->protocol == IPPROTO_TCP) + return XDP_PASS; + } + return XDP_DROP; +} + +char LICENSE[] SEC("license") = "GPL";