diff options
Diffstat (limited to 'src/RawSocket.zig')
| -rw-r--r-- | src/RawSocket.zig | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/src/RawSocket.zig b/src/RawSocket.zig index 71b4e1c..9561dcf 100644 --- a/src/RawSocket.zig +++ b/src/RawSocket.zig @@ -1,3 +1,19 @@ +// Copyright 2026 Robby Zambito +// +// This file is part of zaprus. +// +// Zaprus is free software: you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// Zaprus is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// Zaprus. If not, see <https://www.gnu.org/licenses/>. + const RawSocket = @This(); const is_debug = builtin.mode == .Debug; @@ -16,7 +32,12 @@ const Ifconf = extern struct { }, }; -pub fn init() !RawSocket { +pub fn init() error{ + SocketError, + NicError, + NoInterfaceFound, + BindError, +}!RawSocket { const socket: i32 = std.math.cast(i32, std.os.linux.socket(std.os.linux.AF.PACKET, std.os.linux.SOCK.RAW, 0)) orelse return error.SocketError; if (socket < 0) return error.SocketError; @@ -117,7 +138,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 { @@ -133,11 +154,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) @@ -145,8 +181,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 |
