From 27f0ffa39a24b169b6138f1974c123fa6df2bad2 Mon Sep 17 00:00:00 2001 From: Martin Teichmann <martin.teichmann@gmail.com> Date: Fri, 24 Feb 2023 12:15:05 +0000 Subject: [PATCH] add PacketVar also to XDP proper this is not actually related to the ebpfcat PacketVar, but kinda similar. --- ebpfcat/ebpf.rst | 16 ++++++++++++++++ ebpfcat/ebpf_test.py | 11 +++++++---- ebpfcat/xdp.py | 13 ++++++++++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/ebpfcat/ebpf.rst b/ebpfcat/ebpf.rst index e771183..a09594e 100644 --- a/ebpfcat/ebpf.rst +++ b/ebpfcat/ebpf.rst @@ -141,6 +141,22 @@ is too small (by default ``XDPExitCode.PASS``). So the above example becomes:: with self.pH[12] == 8: self.count += 1 +With the ``PacketVar`` descriptor it is possible to declare certain positions +in the packet as variables. As parameters it takes the position within the +packet, and the data format, following the conventions from the Python +``struct`` package. So the above example simplifies to:: + + class Program(XDP): + minimumPacketSize = 16 + userspace = HashMap() + count = userspace.globalVar() + etherType = PacketVar(12, "H") + + def program(self): + with self.etherType == 8: + self.count += 1 + + Maps ---- diff --git a/ebpfcat/ebpf_test.py b/ebpfcat/ebpf_test.py index 4dea965..b450fe2 100644 --- a/ebpfcat/ebpf_test.py +++ b/ebpfcat/ebpf_test.py @@ -23,7 +23,7 @@ from .ebpf import ( AssembleError, EBPF, FuncId, Opcode, OpcodeFlags, Opcode as O, LocalVar, SubProgram, ktime) from .hashmap import HashMap -from .xdp import XDP +from .xdp import XDP, PacketVar from .bpf import ProgType, prog_test_run @@ -903,8 +903,10 @@ class Tests(TestCase): class P(XDP): minimumPacketSize = 100 + pv = PacketVar(20, "H") + def program(self): - self.r3 = self.pH[22] + self.pv = self.pH[22] p = P(license="GPL") p.assemble() @@ -913,8 +915,9 @@ class Tests(TestCase): Instruction(opcode=O.W+O.LD, dst=0, src=1, off=4, imm=0), Instruction(opcode=O.W+O.LD, dst=2, src=1, off=0, imm=0), Instruction(opcode=O.LONG+O.ADD, dst=2, src=0, off=0, imm=100), - Instruction(opcode=O.JLE+O.REG, dst=0, src=2, off=1, imm=0), - Instruction(opcode=O.REG+O.LD, dst=3, src=9, off=22, imm=0), + Instruction(opcode=O.JLE+O.REG, dst=0, src=2, off=2, imm=0), + Instruction(opcode=O.REG+O.LD, dst=0, src=9, off=22, imm=0), + Instruction(opcode=O.REG+O.STX, dst=9, src=0, off=20, imm=0), Instruction(opcode=O.LONG+O.MOV, dst=0, src=0, off=0, imm=2), Instruction(opcode=O.EXIT, dst=0, src=0, off=0, imm=0), ]) diff --git a/ebpfcat/xdp.py b/ebpfcat/xdp.py index db17388..0d2b518 100644 --- a/ebpfcat/xdp.py +++ b/ebpfcat/xdp.py @@ -24,7 +24,7 @@ from socket import AF_NETLINK, NETLINK_ROUTE, if_nametoindex import socket from struct import pack, unpack -from .ebpf import EBPF +from .ebpf import EBPF, MemoryDesc from .bpf import ProgType from .util import sub @@ -152,6 +152,17 @@ class PacketSize: return self > value - 1 +class PacketVar(MemoryDesc): + base_register = 9 + + def __init__(self, address, fmt): + self.address = address + self.fmt = fmt + + def fmt_addr(self, instance): + return self.fmt, self.address + + class XDP(EBPF): """the base class for XDP programs""" minimumPacketSize = None -- GitLab