diff --git a/arraymap.py b/arraymap.py index 633b0cb4c994ed8d2c809acd1ea1c2fb2e64992c..20023534cedea9865486ad52ae5b671c8471a65b 100644 --- a/arraymap.py +++ b/arraymap.py @@ -37,7 +37,7 @@ class ArrayGlobalVarDesc: ebpf.__dict__[self.map.name].data[ position : position + self.size] = pack(self.fmt, value) else: - getattr(ebpf, f"m{self.size * 8}")[ebpf.r0 + position] = value + getattr(ebpf, f"m{self.fmt}")[ebpf.r0 + position] = value class ArrayMapAccess: diff --git a/ebpf.py b/ebpf.py index ea7cb474f0b27cc7f31c3abb0298c7963c0d0bb4..826fd61a6ef34a8b23897785cd6a85662ba44f6f 100644 --- a/ebpf.py +++ b/ebpf.py @@ -605,6 +605,10 @@ class IAdd: class Memory(Expression): bits_to_opcode = {32: Opcode.W, 16: Opcode.H, 8: Opcode.B, 64: Opcode.DW} + fmt_to_opcode = {'I': Opcode.W, 'H': Opcode.H, 'B': Opcode.B, 'Q': Opcode.DW, + 'i': Opcode.W, 'h': Opcode.H, 'b': Opcode.B, 'q': Opcode.DW} + fmt_to_size = {'I': 4, 'H': 2, 'B': 1, 'Q': 8, + 'i': 4, 'h': 2, 'b': 1, 'q': 8} def __init__(self, ebpf, bits, address, signed=False): self.ebpf = ebpf @@ -641,9 +645,12 @@ class Memory(Expression): class MemoryDesc: - def __init__(self, bits=32, signed=False): - self.bits = bits - self.signed = signed + def __init__(self, fmt='I'): + self.fmt = fmt + + @property + def signed(self): + return self.fmt.islower() def __get__(self, instance, owner): if instance is None: @@ -652,7 +659,7 @@ class MemoryDesc: ebpf = instance.ebpf else: ebpf = instance - return Memory(ebpf, Memory.bits_to_opcode[self.bits], + return Memory(ebpf, Memory.fmt_to_opcode[self.fmt], ebpf.r[self.base_register] + self.addr(instance), self.signed) @@ -661,7 +668,7 @@ class MemoryDesc: ebpf = instance.ebpf else: ebpf = instance - bits = Memory.bits_to_opcode[self.bits] + bits = Memory.fmt_to_opcode[self.fmt] if isinstance(value, int): ebpf.append(Opcode.ST + bits, self.base_register, 0, self.addr(instance), value) @@ -677,7 +684,7 @@ class MemoryDesc: opcode = Opcode.XADD else: opcode = Opcode.STX - with value.calculate(None, self.bits == 64, self.signed) \ + with value.calculate(None, self.fmt in 'qQ', self.signed) \ as (src, _, _): ebpf.append(opcode + bits, self.base_register, src, self.addr(instance), 0) @@ -687,7 +694,7 @@ class LocalVar(MemoryDesc): base_register = 10 def __set_name__(self, owner, name): - size = int(self.bits // 8) + size = Memory.fmt_to_size[self.fmt] owner.stack -= size owner.stack &= -size self.relative_addr = owner.stack @@ -850,10 +857,10 @@ class EBPF: self.name = name self.loaded = False - self.m8 = MemoryMap(self, Opcode.B) - self.m16 = MemoryMap(self, Opcode.H) - self.m32 = MemoryMap(self, Opcode.W) - self.m64 = MemoryMap(self, Opcode.DW) + self.mB = MemoryMap(self, Opcode.B) + self.mH = MemoryMap(self, Opcode.H) + self.mI = MemoryMap(self, Opcode.W) + self.mQ = MemoryMap(self, Opcode.DW) self.r = RegisterArray(self, True, False) self.sr = RegisterArray(self, True, True) diff --git a/ebpf_test.py b/ebpf_test.py index b3946250abfad852dd3877c225f6448f511dd4a8..4cf0f10854e3b83c944311864b8cb5a94af90546 100644 --- a/ebpf_test.py +++ b/ebpf_test.py @@ -112,18 +112,18 @@ class Tests(TestCase): def test_memory(self): e = EBPF() e.owners = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - e.m8[e.r5] = 7 - e.m16[e.r3 + 2] = 3 - e.m32[7 + e.r8] = 5 - e.m64[e.r3 - 7] = 2 - e.m8[e.r5] = e.r1 - e.m16[e.r3 + 2] = e.r2 - e.m32[7 + e.r8] = e.r3 - e.m64[e.r3 - 7] = e.r4 - e.r2 = e.m8[e.r5] - e.r3 = e.m16[e.r3 + 2] - e.r4 = e.m32[7 + e.r8] - e.r5 = e.m64[e.r3 - 7] + e.mB[e.r5] = 7 + e.mH[e.r3 + 2] = 3 + e.mI[7 + e.r8] = 5 + e.mQ[e.r3 - 7] = 2 + e.mB[e.r5] = e.r1 + e.mH[e.r3 + 2] = e.r2 + e.mI[7 + e.r8] = e.r3 + e.mQ[e.r3 - 7] = e.r4 + e.r2 = e.mB[e.r5] + e.r3 = e.mH[e.r3 + 2] + e.r4 = e.mI[7 + e.r8] + e.r5 = e.mQ[e.r3 - 7] self.assertEqual(e.opcodes, [Instruction(opcode=114, dst=5, src=0, off=0, imm=7), Instruction(opcode=106, dst=3, src=0, off=2, imm=3), @@ -140,10 +140,10 @@ class Tests(TestCase): def test_local(self): class Local(EBPF): - a = LocalVar(8, True) - b = LocalVar(16, False) - c = LocalVar(32, True) - d = LocalVar(64, False) + a = LocalVar('b') + b = LocalVar('H') + c = LocalVar('i') + d = LocalVar('Q') e = Local(ProgType.XDP, "GPL") e.a = 5 @@ -159,10 +159,10 @@ class Tests(TestCase): def test_local_subprog(self): class Local(EBPF): - a = LocalVar(32, False) + a = LocalVar('I') class Sub(SubProgram): - b = LocalVar(32, False) + b = LocalVar('I') def program(self): self.b *= 3 @@ -182,11 +182,11 @@ class Tests(TestCase): def test_lock_add(self): class Local(EBPF): - a = LocalVar(32, False) + a = LocalVar('I') e = Local(ProgType.XDP, "GPL") e.a += 3 - e.m32[e.r1] += e.r1 + e.mI[e.r1] += e.r1 e.a -= 3 self.assertEqual(e.opcodes, [ @@ -473,11 +473,11 @@ class Tests(TestCase): self.maxDiff = None e = EBPF() e.r3 = e.r1 - (2 * e.r10) - e.m16[e.r10 - 10] = 2 * e.r3 - e.m16[e.r10 + e.r3] = 2 * e.r3 - e.r5 = e.m16[e.r10 + e.r3] + e.mH[e.r10 - 10] = 2 * e.r3 + e.mH[e.r10 + e.r3] = 2 * e.r3 + e.r5 = e.mH[e.r10 + e.r3] e.r0 = (e.r1 * e.r3) - (e.r10 * e.r5) - e.r5 = (e.r1 * e.r3) + e.m32[e.r10 + e.r0] + e.r5 = (e.r1 * e.r3) + e.mI[e.r10 + e.r0] e.r5 = e.r3 + e.r5 self.assertEqual(e.opcodes, [ Instruction(opcode=191, dst=3, src=1, off=0, imm=0), @@ -538,7 +538,7 @@ class Tests(TestCase): def test_xdp(self): e = XDP(license="GPL") with e.packetSize > 100 as p: - e.r3 = p.H[22] + e.r3 = p.pH[22] with p.Else(): e.r3 = 77 self.assertEqual(e.opcodes, [ diff --git a/ebpfcat.py b/ebpfcat.py index 10ae6a185b6efaa9e4dfaef1aaebe2075445d8f4..096f0d95922c56f5ccab92bd3f650d429028fff8 100644 --- a/ebpfcat.py +++ b/ebpfcat.py @@ -31,7 +31,7 @@ class TerminalVar(MemoryDesc): base_register = 9 def __init__(self): - super().__init__(bits=16) + super().__init__(fmt="H") def __set__(self, instance, value): if isinstance(value, PacketVar): @@ -146,11 +146,11 @@ class EtherXDP(XDP): def program(self): e = self - with e.packetSize > 24 as p, e.If(p.H[12] == 0xA488), \ - e.If(p.B[16] == 0): + with e.packetSize > 24 as p, e.If(p.pH[12] == 0xA488), \ + e.If(p.pB[16] == 0): e.count += 1 e.r2 = e.get_fd(self.programs) - e.r3 = p.W[18] + e.r3 = p.pI[18] e.call(FuncId.tail_call) e.allcount += 1 e.exit(2) diff --git a/xdp.py b/xdp.py index 138bc12e3ee12a2530b3d8f346eaa55904d0f987..7a5ac7049c22f820d034edd76d2e57299d0275ef 100644 --- a/xdp.py +++ b/xdp.py @@ -79,10 +79,10 @@ class Packet: self.comp = comp self.no = no - self.B = PacketArray(self.ebpf, self.no, self.ebpf.m8) - self.H = PacketArray(self.ebpf, self.no, self.ebpf.m16) - self.W = PacketArray(self.ebpf, self.no, self.ebpf.m32) - self.DW = PacketArray(self.ebpf, self.no, self.ebpf.m64) + self.pB = PacketArray(self.ebpf, self.no, self.ebpf.mB) + self.pH = PacketArray(self.ebpf, self.no, self.ebpf.mH) + self.pI = PacketArray(self.ebpf, self.no, self.ebpf.mI) + self.pQ = PacketArray(self.ebpf, self.no, self.ebpf.mQ) def Else(self): return self.comp.Else() @@ -102,8 +102,8 @@ class PacketSize: @contextmanager def __gt__(self, value): e = self.ebpf - e.r9 = e.m32[e.r1] - with e.If(e.m32[e.r1 + 4] > e.m32[e.r1] + value) as comp: + e.r9 = e.mI[e.r1] + with e.If(e.mI[e.r1 + 4] > e.mI[e.r1] + value) as comp: yield Packet(e, comp, 9) def __le__(self, value):