class TincFeth < Formula desc "Virtual Private Network (VPN) tool with feth-based TAP support for macOS" homepage "https://www.tinc-vpn.org/" url "https://www.tinc-vpn.org/packages/tinc-1.0.37.tar.gz" sha256 "f63b7e21c32c4c637576d85f36bdd28ea678b5aa17fad02427645dea30e52ac7" license "GPL-2.0-or-later" => { with: "OpenSSL-exception" } conflicts_with "tinc", because: "tinc-feth is a patched version of tinc with macOS feth device support" depends_on "lzo" depends_on "openssl@3" def patches_dir # Resolve patches relative to the tap root File.expand_path("../patches", __dir__) end def install # Apply patches: macOS struct ifreq fixes + feth device support system "patch", "-p1", "-i", "#{patches_dir}/net-socket-fix.patch" system "patch", "-p1", "-i", "#{patches_dir}/raw-socket-fix.patch" system "patch", "-p1", "-i", "#{patches_dir}/feth-device.patch" system "./configure", "--prefix=#{prefix}", "--sysconfdir=#{etc}", "--with-openssl=#{Formula["openssl@3"].opt_prefix}", "--with-lzo=#{Formula["lzo"].opt_prefix}" system "make", "install" # Install wrapper script that auto-detects the network name (bin/"tinc-feth-start").write <<~SH #!/bin/sh TINC_DIR="#{etc}/tinc" if [ -n "$1" ]; then NETWORK="$1" else NETWORK=$(find "$TINC_DIR" -mindepth 1 -maxdepth 1 -type d ! -name '.*' -exec basename {} \\; | head -1) fi if [ -z "$NETWORK" ]; then echo "No tinc network found in $TINC_DIR" >&2 exit 1 fi exec #{opt_sbin}/tincd -n "$NETWORK" -D SH end def caveats <<~EOS tinc-feth adds macOS feth (fake ethernet) device support for Layer 2 / switch mode. To use feth mode, set in your tinc.conf: DeviceType = feth Mode = switch Optionally specify a device number (default is feth0): Device = feth0 This creates a feth interface pair: feth0 - primary interface (configure IPs in tinc-up) feth5000 - peer interface (used internally for packet I/O) Requires root privileges to create feth interfaces and open BPF devices. Example tinc-up script: #!/bin/sh ifconfig $INTERFACE 10.0.0.1 netmask 255.255.255.0 up Configuration directory: #{etc}/tinc/ EOS end service do run [opt_bin/"tinc-feth-start"] require_root true keep_alive true log_path var/"log/tinc/tinc.log" error_log_path var/"log/tinc/tinc.log" end test do assert_match version.to_s, shell_output("#{sbin}/tincd --version") end end