diff --git a/ebpfcat/ebpfcat.py b/ebpfcat/ebpfcat.py index a3a3c3d53540ef461bdfc1348a5019426488b240..73721998c163f77335b1342bfe69323e30dd1724 100644 --- a/ebpfcat/ebpfcat.py +++ b/ebpfcat/ebpfcat.py @@ -260,36 +260,36 @@ class EtherXDP(XDP): counters = variables.globalVar("64I") rate = 0 + DATA0 = 26 def program(self): ETHERTYPE = 12 CMD0 = 16 - IDX0 = 17 ADDR0 = 18 with prandom(self.ebpf) & 0xffff < self.rate: self.dropcounter += 1 self.ebpf.exit(XDPExitCode.DROP) - with self.packetSize > 24 as p, p.pH[ETHERTYPE] == 0xA488, \ + with self.packetSize > 30 as p, p.pH[ETHERTYPE] == 0xA488, \ p.pB[CMD0] == 0: self.r3 = p.pI[ADDR0] # use r3 for tail_call with self.counters.get_address(None, False, False) as (dst, _), \ self.r3 < FastEtherCat.MAX_PROGS: self.r[dst] += 4 * self.r3 - self.r4 = self.mB[self.r[dst]] + self.r4 = self.mH[self.r[dst]] # we lost a packet - with p.pB[IDX0] == self.r4 as Else: + with p.pH[self.DATA0] == self.r4 as Else: self.mI[self.r[dst]] += 1 + (self.r4 & 1) # normal case: two packets on the wire - with Else, ((p.pB[IDX0] + 1 & 0xff) == self.r4) \ - | (p.pB[IDX0] == 0) as Else: + with Else, ((p.pH[self.DATA0] + 1 & 0xffff) == self.r4) \ + | (p.pH[self.DATA0] == 0) as Else: self.mI[self.r[dst]] += 1 with self.r4 & 1: # last one was active - p.pB[IDX0] = self.mB[self.r[dst]] + p.pH[self.DATA0] = self.mH[self.r[dst]] self.exit(XDPExitCode.TX) with Else: self.exit(XDPExitCode.PASS) - p.pB[IDX0] = self.mB[self.r[dst]] + p.pH[self.DATA0] = self.mH[self.r[dst]] self.r2 = self.get_fd(self.programs) self.call(FuncId.tail_call) self.exit(XDPExitCode.PASS) @@ -432,7 +432,7 @@ class FastSyncGroup(SyncGroupBase, XDP): await super().run() def update_devices(self, data): - if data[3] & 1: + if data[EtherXDP.DATA0 - Packet.ETHERNET_HEADER] & 1: self.current_data = data elif self.current_data is None: return self.asm_packet diff --git a/ebpfcat/ethercat.py b/ebpfcat/ethercat.py index b37b0a5eb0e2ac50fec1336579cde65b2104e7c4..1e0b5570ba47735e8f142e69880d19b9808af8d1 100644 --- a/ebpfcat/ethercat.py +++ b/ebpfcat/ethercat.py @@ -191,12 +191,13 @@ class Packet: """ MAXSIZE = 1000 # maximum size we use for an EtherCAT packet ETHERNET_HEADER = 14 + PACKET_HEADER = 16 DATAGRAM_HEADER = 10 DATAGRAM_TAIL = 2 def __init__(self): self.data = [] - self.size = 14 + self.size = self.PACKET_HEADER def append(self, cmd, data, idx, *address): """Append a datagram to the packet @@ -220,13 +221,15 @@ class Packet: An implicit empty datagram is added at the beginning of the packet that may be used as an identifier for the packet. """ - ret = [pack("<HBBiHHH", self.size | 0x1000, 0, 0, index, 1 << 15, 0, 0)] + ret = [pack("<HBBiHHHH", (self.size-2) | 0x1000, 0, 0, index, 0x8002, 0, 0, 0)] for i, (cmd, data, *dgram) in enumerate(self.data, start=1): ret.append(pack("<BBhHHH" if len(dgram) == 3 else "<BBiHH", cmd.value, *dgram, len(data) | ((i < len(self.data)) << 15), 0)) ret.append(data) ret.append(b"\0\0") + if self.size < 46: + ret.append(b"3" * (46 - self.size)) return b''.join(ret) def __str__(self): diff --git a/ebpfcat/ethercat_test.py b/ebpfcat/ethercat_test.py index 5c921c4fa139bc5ff2b4f4f8b2fb13d2e595168a..e6b93b4320a1628a0dd95e9e4fb36681cf2ac3d5 100644 --- a/ebpfcat/ethercat_test.py +++ b/ebpfcat/ethercat_test.py @@ -123,30 +123,34 @@ class Tests(TestCase): ec.results = [None, None] await ti.initialize(-1, 4) ai = AnalogInput(ti.channel1.value) - SyncGroup.packet_index = 1000 + SyncGroup.packet_index = 0x66554433 sg = SyncGroup(ec, [ai]) self.task = sg.start() ec.expected = [ H("2a10" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram + "0000334455660280000000000000" # ID datagram # in datagram - "04000400801110000000000000000000000000000000000000000000"), - 1000, # == 0x3e8, see ID datagram + "04000400801110000000000000000000000000000000000000000000" + "3333"), # padding + 0x66554433, # index H("2a10" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram + "0000334455660280000000000000" # ID datagram # in datagram - "04000400801110000000123456780000000000000000000000000000"), - 1000, + "04000400801110000000123456780000000000000000000000000000" + "3333"), # padding + 0x66554433, # index ] ec.results = [ H("2a10" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram + "0000334455660280000000000000" # ID datagram # in datagram - "04000400801110000000123456780000000000000000000000000000"), + "04000400801110000000123456780000000000000000000000000000" + "3333"), # padding H("2a10" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram + "0000334455660280000000000000" # ID datagram # in datagram - "04000400801110000000123456780000000000000000000000000000"), + "04000400801110000000123456780000000000000000000000000000" + "3333"), # padding ] self.future = Future() with self.assertRaises(CancelledError): @@ -169,14 +173,15 @@ class Tests(TestCase): ec.results = [None, None] await ti.initialize(-2, 7) ao = AnalogOutput(ti.ch1_value) - SyncGroup.packet_index = 1000 + SyncGroup.packet_index = 0x55443322 sg = SyncGroup(ec, [ao]) self.task = sg.start() ec.expected = [ H("2210" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram - "0500070000110800000000000000000000000000"), # out datagram - 1000, # == 0x3e8, see ID datagram + "0000223344550280000000000000" # ID datagram + "0500070000110800000000000000000000000000" # out datagram + "33333333333333333333"), # padding + 0x55443322, # index ] ec.results = [ (8, 0), # return state 8, no error @@ -187,14 +192,16 @@ class Tests(TestCase): await gather(self.future, self.task) ec.expected = [ H("2210" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram - "0500070000110800000076980000000000000000"), # out datagram - 1000, + "0000223344550280000000000000" # ID datagram + "0500070000110800000076980000000000000000" # out datagram + "33333333333333333333"), # padding + 0x55443322, # index ] ec.results = [ H("2210" # EtherCAT Header, length & type - "0000e8030000008000000000" # ID datagram - "0500070000110800000076980000000000000000"), # out datagram + "0000223344550280000000000000" # ID datagram + "0500070000110800000076980000000000000000" # out datagram + "33333333333333333333"), # padding ] self.future = Future() with self.assertRaises(CancelledError):