Wednesday, 31 July 2013

Raspbmc as a wireless bridge

I have XBMC installed on a Raspberry Pi using Raspbmc to stream content to my TV over WiFi but I wanted to make use of the Pi’s Ethernet port to give internet access to a Sky+ set top box which only has an Ethernet port.

I started with a Raspberry Pi with Raspbmc installed over WiFi using an Edimax EW-7811UN USB WiFi adapter. My home network uses the 192.168.0.0/24 subnet with my WiFi router using 192.168.0.1 and the Raspberry Pi using a static IP of 192.168.0.51.

Setting up the bridge was based heavily on the following guide which is for Raspian:
http://qcktech.blogspot.dk/2012/08/raspberry-pi-as-router.html

The following post was also helpful in starting things at boot which is an area that Raspbmc differs from the above guide:
http://forum.stmlabs.com/showthread.php?tid=3552&pid=33455#pid33455

Raspbmc doesn’t use /etc/network/interfaces so you need to edit the settings.xml file:
sudo nano /home/pi/.xbmc/userdata/addon_data/script.raspbmc.settings/settings.xml
The WiFi settings were already configured from the install but you need to setup the wired interface. Give it a static IP in the “nm.address” entry (I used 192.168.1.1), set the gateway to the same IP, set an appropriate netmask and make sure DHCP is disabled for the wired interface and finally. I set the DNS to one of Google’s (8.8.8.8) but I’m not sure if this is needed.

My final settings.xml file looked like this:


If you want your Pi to give out IP addresses to devices connected to the wired port using DHCP, you can install isc-dhcp-server using the instructions in the link mentioned earlier, but I decided to use a fixed IP for simplicity.

I found that with both the USB WiFi and wired connections being used, my Pi wasn't reaching the internet any more. I fixed this by creating a script to set the default gateway for the Wifi adapter when the wired adapter comes up:
sudo nano /etc/network/if-up.d/wlan0defgateway
and adding the following:
#!/bin/sh 
if [ "$IFACE" = "eth0" ]; then  
  route add default gw 192.168.0.1 dev wlan0 
fi
then set permissions using:
sudo chmod 755 /etc/network/if-up.d/wlan0defgateway
 Next you need to enable IP forwarding by editing /etc/sysctl.conf using:
sudo nano /etc/sysctl.conf
Uncomment the line “net.ipv4.ip_forward=1” and save the file.

Finally setup iptables using:
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
Then save the iptables rules. I couldn’t save straight to /etc so I saved it in ~ and then moved it to /etc using:
sudo iptables-save > iptables.up.rules
sudo mv iptables.up.rules /etc

Create a script to restore the rules using:
sudo nano /etc/init/iptables.conf
And paste in:
# Restore iptables rules on boot 
start on (started dbus and started mountall) 
stop on (xbmc-do-stop or runlevel [!2345])  
exec iptables-restore < /etc/iptables.up.rules
Now restart the Pi and plug an Ethernet cable into the Pi and the other end into something else (I used a laptop for testing). Then set a static IP in the same range on the something else such as:
IP: 192.168.1.2
Netmask: 255.255.255.0 
Gateway: 192.168.1.1
DNS: 8.8.8.8 

Update:
I've noticed that the Pi doesn't keep its IP address recently (I'm not sure if a change in a recent release of RaspBMC caused this). I was able to fix it by editing the NetworkManager config file for the wired interface:
sudo nano "/etc/NetworkManager/system-connections/Wired connection 1"
And setting the IP address:
[ipv4]
method=manual
dns=8.8.8.8;
addresses1=192.168.1.1;24;192.168.1.1;
I then restarted NetworkManager with:
sudo service network-manager restart