how can I split traffic on OSX so that only some certain subnet are routed to ethernet interface and the rest is routed to Wifi?

I've been using this script for more that 1 and a half year but today it stopped working. All it does is it deletes the default gateway and sets the desired one (i.e. en2 = wifi) as default and it adds record for each subnet telling it to route it through desired "tunnel" interface (i.e. en0 = ethernet).

#! /usr/bin/env zsh

if (( EUID != 0 )); then
    echo "Please, run this command with sudo" >&2
    exit 1

if [ "$#" -ne "2" ]; then
    echo "Usage: $0 tunnel_interface default_interface" >&2
    exit 1


GATEWAY=$(netstat -nrf inet | grep default | grep $DEFAULT_INTERFACE | awk '{print $2}')

if [ "$GATEWAY" = "" ]; then
    read "GATEWAY?Enter gateway IP address: "

echo "Resetting routes with gateway => $GATEWAY"

route -n delete default -ifscope $DEFAULT_INTERFACE 1>/dev/null
route -n delete -net default -interface $TUNNEL_INTERFACE 1>/dev/null
route -n add -net default $GATEWAY 1>/dev/null

for subnet in 10.89 10.153 10.162 10.168
    route -n add -net $subnet -interface $TUNNEL_INTERFACE 1>/dev/null 2>&1

echo "google.cz -> $(route get google.cz | grep interface | sed 's/^ *//')"
echo "r5d00 -> $(route get r5d00 | grep interface | sed 's/^ *//')"

I run this script like this

$ sudo tunnel-ips.sh no en0 en2
Resetting routes with gateway =>

google.cz -> interface: en2
r5d00 -> interface: en0

I'm connected via Wifi to my iPhone Personal hotspot, it assigns me IP and mask The r5d00 server has IP set to, which matches with

My routing table looks like this: $ netstat -rn Routing tables

Destination        Gateway            Flags        Refs      Use   Netif Expire
default          UGSc            3        0     en2
10.89/16           link#4             UCSc            1        0     en0
10.153/16          link#4             UCSc            1        0     en0
10.162/21          link#4             UCS             6        0     en0
10.162/16          link#4             UCSc            1        0     en0      link#4             UCS             2        0     en0         0:0:c:9f:f0:1      UHLWIi          2        4     en0   1167       0:20:4a:e6:5c:2c   UHLWIi          1        0     en0   1149       0:20:4a:54:87:a0   UHLWIi          1        0     en0   1079       0:20:4a:d7:d8:3e   UHLWIi          1        0     en0   1132        0:1e:b:ed:21:b8    UHLWIi          1       18     en0   1136    link#4             UCS             1        0     en0
10.167/16          link#4             UCSc            1        0     en0
10.168/16          link#4             UCSc            1        0     en0
10.255/16          link#4             UCSc            1        0     en0
127                UCS             1        0     lo0          UH              5     2329     lo0
169.254            link#4             UCS             1        0     en0
169.254            link#5             UCSI            1        0     en2
172.20.10/28       link#5             UCS             1        0     en2     link#5             UCS             2        0     en2        36:e2:fd:74:7b:64  UHLWIir         5       11     en2   1067     link#5             UCS             1        0     en2
172.24/13          link#4             UCSc            7        0     en0 link#4             UCS             1        0     en0 link#5             UCSI            1        0     en2

Destination                             Gateway                         Flags         Netif Expire
::1                                     ::1                             UHL             lo0
fe80::%lo0/64                           fe80::1%lo0                     UcI             lo0
fe80::1%lo0                             link#1                          UHLI            lo0
fe80::%awdl0/64                         link#7                          UCI           awdl0
fe80::a4a8:81ff:fe02:a44d%awdl0         a6:a8:81:2:a4:4d                UHLI            lo0
fe80::%utun0/64                         fe80::db39:e7b8:6234:7841%utun0 UcI           utun0
fe80::db39:e7b8:6234:7841%utun0         link#9                          UHLI            lo0
ff01::%lo0/32                           ::1                             UmCI            lo0
ff01::%awdl0/32                         link#7                          UmCI          awdl0
ff01::%utun0/32                         fe80::db39:e7b8:6234:7841%utun0 UmCI          utun0
ff02::%lo0/32                           ::1                             UmCI            lo0
ff02::%awdl0/32                         link#7                          UmCI          awdl0
ff02::%utun0/32                         fe80::db39:e7b8:6234:7841%utun0 UmCI          utun0

When I ping r5d00, it says "No route to host"

$ ping r5d00     
PING r5d00.cezdata.corp ( 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
ping: sendto: No route to host
Request timeout for icmp_seq 4
ping: sendto: Host is down
Request timeout for icmp_seq 5
ping: sendto: Host is down
Request timeout for icmp_seq 6
ping: sendto: Host is down
Request timeout for icmp_seq 7
ping: sendto: Host is down
Request timeout for icmp_seq 8
ping: sendto: Host is down
Request timeout for icmp_seq 9
ping: sendto: Host is down
Request timeout for icmp_seq 10

I downloaded Wireshark and I recorded the traffic but the ICMP packets are nowhere to find (when I disable Wifi and reset routing table, it does get recorded and ping is successfull). It seems like the IP isn't matched with the routing table record, but when I check it via route get, it says it's routed through en0 (which is correct).

$ route get r5d00
   route to: r5d00
destination: r5d00
  interface: en0
 recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
       0         0         0         0         0         0      1500      -138 

Like I said, it was working yesterday, but today it's not. I didn't download any update or anything. AFAIK it's problem on my Mac, not on the internal network, since nobody else has a problem.


The single ping: sendto: No route to host message at first suggests that something changed during testing. According to your routing table,, is directly connected off of Link#4, which means reaching that host ought not to need routing, nor even generate that message.

Subsequently, except for the first one, the other messages reflect the routing table. The ping: sendto: Host is down suggests that host is on a network that is directly connected, and that host or its proxy has not replied to an ARP request.

Try having route monitor running in another window when you repeat the test, as well as watching the Console for any interface transitions, or other network changes.

  • Hello, sorry I didn't answer, I must have missed the notification. I was able to alter the script for it to work. Thank you for your help. – Hologos May 5 '17 at 8:56
  • @Hologos Late comment, but happy this worked for you! But if this answer was helpful to you, please be sure to upvote it. And if it’s the answer that solved your question, please check it off as such. – Giacomo1968 Dec 20 '20 at 4:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.