diff --git a/ebpfcat/ebpf.rst b/ebpfcat/ebpf.rst index e7711836753388dbd04135d7fa7bda86e4d3bad7..a09594efea4f9149c3b6564e5a67723f2fa48ed3 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 4dea9657d40bb7d6c36d44a53c47195a2fcbb207..b450fe285edc0137e6a780e8e89b2ecbc74b57bb 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 db17388715107a27e14d5c1c68a2abeb13c47e0f..0d2b518ae20a81f787d9e469c9666095b31797a8 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