Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

Bridging a wireless and an ethernet network with OS X 10.8, updated again

I made a modification to the script, because the proxy_all sysctl isn't really needed in my setup.

Below in the drawing is my current home setup. My DSL router 192.168.0.1 ("fritz.box") creates a WIFI network 192.168.0.0/24. I then have another ethernet based network 192.168.1.0/24, with machines, that have no wireless capabilities.

This used to work fine, if one machine with an ethernet card (192.168.1.2) and a wireless card (192.168.0.2) running OS X, provided internet sharing for the wired net. But when I recently added a wireless only machine 192.168.0.3 it became apparent, that this machine was not able to talk to the 192.168.1.0/24 network.

It took me quite a while to figure out how to do it, although the information is available, if you know which keywords to google for.

First things first. Apple's "Internet Sharing" is doing NAT, which in this case is harmful. NAT and bridging can not be used reliably together (says the OpenBSD pf documentation). But I need to use "real" ethernet bridging, which can be done in OS X since 10.8 apparently.

So "Internet Sharing" has to be turned off. This could change the wired interface IP address!

Create a permanent ethernet bridge on OS X

I put this shell script into /usr/local/sbin as mulle-ethernet-bridge.sh (on the machine with the interfaces 192.168.1.2 and 192.168.0.2):

#! /bin/sh
# ######################################
#  coded by Nat!
#  2013 Mulle kybernetiK
#  GPL

command=${1:-start}
shift
proxyarp=${1:-no}
shift

start()
{
        sysctl -w net.inet.ip.forwarding=1
        sysctl -w net.inet.ip.fw.enable=1
        if [ "$proxyarp" != "no" ]
        then
                sysctl -w net.link.ether.inet.proxyall=1
        fi

        ifconfig bridge0 create
        ifconfig bridge0 addm en0
        ifconfig bridge0 addm en1
        ifconfig bridge0 up
        if [ $? -eq 0 ]
        then
                syslog -s "Mulle Ethernet Bridge is up"
        else
                syslog -s "Mulle Ethernet Bridge failure"
        fi
}


stop()
{
        ifconfig bridge0 destroy

        sysctl -w net.inet.ip.forwarding=0
        sysctl -w net.inet.ip.fw.enable=0
        sysctl -w net.link.ether.inet.proxyall=0

        syslog -s "Mulle Ethernet Bridge is down"
}



case "$command" in
        start*) start
                ;;

        stop*)  stop
                ;;
esac
and configured it for executability
chmod 755 /usr/local/sbin/mulle-ethernet-bridge.sh
Then I put the following XML into /Library/LaunchDaemons as com.mulle-kybernetik.admin.ethernet-bridge.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.mulle-kybernetik.admin.ethernet-bridge</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/sbin/mulle-ethernet-bridge.sh</string>
        </array>
        <key>UserName</key>
        <string>root</string>
        <key>GroupName</key>
        <string>wheel</string>
        <key>RunAtLoad</key>
        <true/>
        <key>LaunchOnlyOnce</key>
        <true/>
    </dict>
</plist>
and added it to launchd thusly

sudo chmod 644 /Library/LaunchDaemons/com.mulle-kybernetik.admin.ethernet-bridge.plist
sudo chown root:wheel /Library/LaunchDaemons/com.mulle-kybernetik.admin.ethernet-bridge.plist
sudo launchctl load /Library/LaunchDaemons/com.mulle-kybernetik.admin.ethernet-bridge.plist
Check with ifconfig that the bridge0 device has appeared now:
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        ether ac:dc:18:48:20:13
        Configuration:
                priority 0 hellotime 0 fwddelay 0 maxage 0
                ipfilter disabled flags 0x2
        member: en0 flags=3
                 port 4 priority 0 path cost 0
        member: en1 flags=3
                 port 5 priority 0 path cost 0

Configuring a wired box

I have a manually configured wired box with the address 192.168.1.4. It's network settings are now like this:
IP192.168.1.4
Router(Gateway)192.168.1.2
DNS192.168.0.1

But for ease of use I also run a DHCP server on the bridging machine (192.168.1.2). Jacques Fortier has the neccessary information to set one up on Mac OS X, without having to install any packages.

Adding routes to the wireless boxes

The wired boxes will be able to send pings to the wireless boxes, but the wireless boxes will send the return packets to the fritz.box, because NAT is disabled and any address 192.168.1.0/24 doesn't mean anything for them yet. Conceivably the fritz.box sends those replies then out to the interwebs, because it doesn't know the 192.168.1.0/24 network eiher and the interwebs are the default route.

This information needs to be added to the static routing tables of the router. Thankfully the fritz box allows this in its expert settings. So I added:

NetworkNetmaskGateway
192.168.1.0255.255.255.0192.168.0.2

With that the setup worked albeit not perfectly. I could now ping from the windows box 192.168.0.3 to the debian box 192.168.1.5, but the packets would actually be running through both 192.168.0.1 and 192.168.0.2: one hop too much. This is especially bad, since the extra hop is wireless. Fortunately you can also add static routes in windows (using -p for a permanent route):
route -p add 192.168.1.0 mask 255.255.255.0 192.168.0.2 metric 1

Post a comment

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: