I've built a VPN app that is based on wireguard on macOS (I have both AppStore ver. and Developer ID ver). I want to achieve split tunneling function without changing the system route table.
Currently, I'm making changes in PacketTunnelProvider: NEPacketTunnelProvider. It has included/excluded routes that function as a split tunnel, just that all changes are immediately reflected on the route table: if I run
netstat -rn
in terminal, I would see all rules/CIDRs I added, displayed all at once. Since I have a CIDR list of ~800 entries, I'd like to avoid changing the route table directly.
I've asked ChatGPT, Claude, DeepSeek, .etc. An idea was to implement an 'interceptor' to
intercept all packets in packetFlow(_:readPacketsWithCompletionHandler:), extract the destination IP from each packet, check if it matches your CIDR list, and either reinject it back to the system interface (for local routing) or process it through your tunnel.
Well, LLMs could have hallucinations and I've pretty new to macOS programming. I'm asking to make sure I'm on the right track, not going delusional with those LLMs :) So the question is, does the above method sounds feasible? If not, is it possible to achieve split tunneling without changing the route table?