From 558f40213b895810a78b2bbcbdbb95e88a301fde Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Sun, 1 Feb 2026 14:29:53 -0500 Subject: Update to Saprus 0.2.1 Handle management messages instead of letting them bubble up through the connection to the consumer. Right now, this just means handling ping messages by sending a pong. Also updated to follow the new handshake flow. The sentinel will mirror the ports instead of matching them. Now filters on the full source and dest ports, which are less likely to have erroneous matches. --- src/RawSocket.zig | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src/RawSocket.zig') diff --git a/src/RawSocket.zig b/src/RawSocket.zig index 5732ce9..e43a8e4 100644 --- a/src/RawSocket.zig +++ b/src/RawSocket.zig @@ -133,7 +133,7 @@ pub fn receive(self: RawSocket, buf: []u8) ![]u8 { return buf[0..len]; } -pub fn attachSaprusPortFilter(self: RawSocket, port: u16) !void { +pub fn attachSaprusPortFilter(self: RawSocket, incoming_src_port: ?u16, incoming_dest_port: u16) !void { const BPF = std.os.linux.BPF; // BPF instruction structure for classic BPF const SockFilter = extern struct { @@ -149,11 +149,26 @@ pub fn attachSaprusPortFilter(self: RawSocket, port: u16) !void { }; // Build the filter program - const filter = [_]SockFilter{ + const filter = if (incoming_src_port) |inc_src| &[_]SockFilter{ // Load 2 bytes at offset 46 (absolute) .{ .code = BPF.LD | BPF.H | BPF.ABS, .jt = 0, .jf = 0, .k = 46 }, + // Jump if equal to port (skip 1 if true, skip 0 if false) + .{ .code = BPF.JMP | BPF.JEQ | BPF.K, .jt = 1, .jf = 0, .k = @as(u32, inc_src) }, + // Return 0x0 (fail) + .{ .code = BPF.RET | BPF.K, .jt = 0, .jf = 0, .k = 0x0 }, + // Load 2 bytes at offset 48 (absolute) + .{ .code = BPF.LD | BPF.H | BPF.ABS, .jt = 0, .jf = 0, .k = 48 }, + // Jump if equal to port (skip 0 if true, skip 1 if false) + .{ .code = BPF.JMP | BPF.JEQ | BPF.K, .jt = 0, .jf = 1, .k = @as(u32, incoming_dest_port) }, + // Return 0xffff (pass) + .{ .code = BPF.RET | BPF.K, .jt = 0, .jf = 0, .k = 0xffff }, + // Return 0x0 (fail) + .{ .code = BPF.RET | BPF.K, .jt = 0, .jf = 0, .k = 0x0 }, + } else &[_]SockFilter{ + // Load 2 bytes at offset 48 (absolute) + .{ .code = BPF.LD | BPF.H | BPF.ABS, .jt = 0, .jf = 0, .k = 48 }, // Jump if equal to port (skip 0 if true, skip 1 if false) - .{ .code = BPF.JMP | BPF.JEQ | BPF.K, .jt = 0, .jf = 1, .k = @as(u32, port) }, + .{ .code = BPF.JMP | BPF.JEQ | BPF.K, .jt = 0, .jf = 1, .k = @as(u32, incoming_dest_port) }, // Return 0xffff (pass) .{ .code = BPF.RET | BPF.K, .jt = 0, .jf = 0, .k = 0xffff }, // Return 0x0 (fail) @@ -161,8 +176,8 @@ pub fn attachSaprusPortFilter(self: RawSocket, port: u16) !void { }; const fprog = SockFprog{ - .len = filter.len, - .filter = &filter, + .len = @intCast(filter.len), + .filter = filter.ptr, }; // Attach filter to socket using setsockopt -- cgit