diff --git a/src/tunnel.zig b/src/tunnel.zig index b7389f0..d5423be 100644 --- a/src/tunnel.zig +++ b/src/tunnel.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("std"); const os = std.os; const mem = std.mem; @@ -6,18 +7,25 @@ const log = std.log.scoped(.nyotun); const IFF_TUN = 0x0001; // const IFF_NO_PI = 0x1000; // -const TUNSETIFF = 0x400454ca; // write a C program, run and see + +// git -C ~/code/go grep TUNSETIFF +const TUNSETIFF = switch (builtin.target.cpu.arch) { + .x86, .x86_64, .arm, .aarch64 => 0x400454ca, + else => @compileError("unsupported architecture"), +}; dev: [posix.IFNAMESIZE:0]u8, -tunFile: posix.fd_t, +tun_file: posix.fd_t, pub fn init(devname: ?[]const u8) !Tunnel { - const tunFile = try posix.open( + const tun_file = try posix.open( "/dev/net/tun", + // NB: vtun just uses RDWR, tailscale-go adds O_NONBLOCK. + // Not sure why I would add O_NONBLOCK, so just not doing that. posix.O{ .ACCMODE = .RDWR, .CLOEXEC = true }, 0, ); - errdefer posix.close(tunFile); + errdefer posix.close(tun_file); var ifr = mem.zeroInit( posix.ifreq, @@ -29,20 +37,23 @@ pub fn init(devname: ?[]const u8) !Tunnel { @memcpy(ifr.ifrn.name[0..name.len], name); } - const err = posix.system.ioctl(tunFile, TUNSETIFF, @intFromPtr(&ifr)); + const err = posix.system.ioctl(tun_file, TUNSETIFF, @intFromPtr(&ifr)); if (posix.errno(err) != .SUCCESS) { log.err("unable to set TUNSETIFF: {s}", .{@tagName(posix.errno(err))}); return error.OpenDevTun; } - var tunnel = Tunnel{ .dev = .{0} ** posix.IFNAMESIZE, .tunFile = tunFile }; + var tunnel = Tunnel{ + .dev = .{0} ** posix.IFNAMESIZE, + .tun_file = tun_file, + }; const ifname = mem.sliceTo(&ifr.ifrn.name, 0); @memcpy(tunnel.dev[0..ifname.len], ifname); return tunnel; } pub fn close(self: *Tunnel) void { - posix.close(self.tunFile); + posix.close(self.tun_file); } const Tunnel = @This();