Add tcpfilter example

This commit is contained in:
Pim Kunis 2024-12-24 21:34:28 +01:00
parent 066d9972cc
commit 6e8387a0a4
5 changed files with 58 additions and 2 deletions

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# ebpf-sandbox
[ebpf-tutorial](https://github.com/dio/ebpf-tutorial)

View file

@ -3,7 +3,7 @@
SEC("xdp") SEC("xdp")
int xdp_drop(struct xdp_md *ctx) { int xdp_drop(struct xdp_md *ctx) {
return XDP_DROP; // Drop all packets return XDP_PASS; // Drop all packets
} }
char LICENSE[] SEC("license") = "GPL"; char LICENSE[] SEC("license") = "GPL";

View file

@ -11,7 +11,11 @@
pkgs = inputs.nixpkgs.legacyPackages.${system}; pkgs = inputs.nixpkgs.legacyPackages.${system};
in in
{ {
packages.dropworld = pkgs.callPackage ./dropworld {}; packages = {
dropworld = pkgs.callPackage ./dropworld {};
tcpfilter = pkgs.callPackage ./tcpfilter {};
};
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [bpftools bpftop]; buildInputs = with pkgs; [bpftools bpftop];
}; };

16
tcpfilter/default.nix Normal file
View file

@ -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
'';
}

33
tcpfilter/tcpfilter.c Normal file
View file

@ -0,0 +1,33 @@
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_endian.h>
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";