From fea89d070d3394594b8d6f8f3df365c4dc658959 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 10 Jun 2026 16:36:15 +0800 Subject: [PATCH 1/2] tests: mctpenv: use argparse for parsing mctpenv commandline We're about to introduce a new option, so switch from manual sys.argv parsing. Signed-off-by: Jeremy Kerr --- tests/mctpenv/__init__.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/mctpenv/__init__.py b/tests/mctpenv/__init__.py index 7478819..712228d 100644 --- a/tests/mctpenv/__init__.py +++ b/tests/mctpenv/__init__.py @@ -1504,15 +1504,21 @@ async def sighandler(): async def main(): import asyncdbus + import argparse - binary = None - args = None - if len(sys.argv) > 1: - binary = sys.argv[1] - args = sys.argv[2:] + parser = argparse.ArgumentParser(description='wrapper for testing mctpd') + parser.add_argument('command', type=str, nargs='*', help='mctpd command') + + args = parser.parse_args() + + mctpd_binary = None + mctpd_args = None + if args.command: + mctpd_binary = args.command[0] + mctpd_args = args.command[1:] async with asyncdbus.MessageBus().connect() as dbus: sysnet = await default_sysnet() - mctpd = MctpdWrapper(dbus, sysnet, binary=binary, args=args) + mctpd = MctpdWrapper(dbus, sysnet, binary=mctpd_binary, args=mctpd_args) async with trio.open_nursery() as nursery: nursery.start_soon(sighandler) await mctpd.start_mctpd(nursery) From cdafb14d5b31a36c4c64e3f50831688fbec09501 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 10 Jun 2026 13:46:57 +0800 Subject: [PATCH 2/2] tests: mctpenv: add pcap capture facility When debugging tests, it's helpful to view the sequence of MCTP commands between the emulated environment and mctpd. Add a small pcap writer, storing the packet data to a file. This is typically enabled by passing a file path to the MctpdWrapper constructor, but pcap output from the mctpenv main() can be enabled with a new --pcap argument too. Signed-off-by: Jeremy Kerr --- tests/mctpenv/__init__.py | 59 +++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/tests/mctpenv/__init__.py b/tests/mctpenv/__init__.py index 712228d..91f5323 100644 --- a/tests/mctpenv/__init__.py +++ b/tests/mctpenv/__init__.py @@ -18,6 +18,7 @@ AF_NETLINK = 16 AF_MCTP = 45 ARPHRD_MCTP = 290 +ETH_P_MCTP = 0x00FA IFLA_MCTP_NET = 1 MAX_SOCKADDR_SIZE = 56 @@ -802,15 +803,44 @@ def __str__(self): class MCTPSocket(BaseSocket): base_addr_fmt = "@HHIIBBBB" ext_addr_fmt = "@HHIIBBBBIBB32s" + pcap_dir_in = 0x00 + pcap_dir_out = 0x04 + pcap_ll_fmt = '>HHHQH' + pcap_pkt_fmt = ' 0: + eid = self.system.addresses[0].eid + if dir == self.pcap_dir_in: + (src, dst) = (eid, addr.eid) + else: + (src, dst) = (addr.eid, eid) + ll_hdr = struct.pack( + self.pcap_ll_fmt, dir, ARPHRD_MCTP, 0, 0, ETH_P_MCTP + ) + # everything is a whole message, so set SOM | EOM + flags_seq_tag = 0xC0 | addr.tag + mctp_hdr = bytes([0x01, dst, src, flags_seq_tag]) + msg_hdr = bytes([addr.type]) + pkt_data = ll_hdr + mctp_hdr + msg_hdr + data + pcap_hdr = struct.pack( + self.pcap_pkt_fmt, 0, 0, len(pkt_data), len(pkt_data) + ) + self.pcap.write(pcap_hdr + pkt_data) async def handle_send(self, addr, data): a = MCTPSockAddr.parse(addr, self.addr_ext) + self._pcap_write(self.pcap_dir_in, a, data) phys = self.system.find_endpoint(a) if phys is None: return @@ -830,6 +860,7 @@ async def handle_bind(self, addr): self.network.register_mctp_socket(self) async def send(self, addr, data): + self._pcap_write(self.pcap_dir_out, addr, data) addrbuf = addr.to_buf() addrlen = len(addrbuf) assert addrlen <= MAX_SOCKADDR_SIZE @@ -1309,10 +1340,19 @@ async def send_fd(sock, fd): class MctpProcessWrapper: - def __init__(self, sysnet): + def __init__(self, sysnet, pcap=None): self.system = sysnet.system self.network = sysnet.network (self.sock_local, self.sock_remote) = self.socketpair() + if pcap: + hdr = struct.pack( + '